michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsISupports.idl" michael@0: #include "domstubs.idl" michael@0: michael@0: interface nsIURI; michael@0: interface nsIAtom; michael@0: interface nsIContent; michael@0: interface nsISelection; michael@0: interface nsISelectionController; michael@0: interface nsIDocumentStateListener; michael@0: interface nsIOutputStream; michael@0: interface nsITransactionManager; michael@0: interface nsITransaction; michael@0: interface nsIEditorObserver; michael@0: interface nsIEditActionListener; michael@0: interface nsIInlineSpellChecker; michael@0: interface nsITransferable; michael@0: michael@0: [scriptable, uuid(65523eab-db1f-44aa-893e-dfe57ad306f0)] michael@0: michael@0: interface nsIEditor : nsISupports michael@0: { michael@0: %{C++ michael@0: typedef short EDirection; michael@0: typedef short EStripWrappers; michael@0: %} michael@0: const short eNone = 0; michael@0: const short eNext = 1; michael@0: const short ePrevious = 2; michael@0: const short eNextWord = 3; michael@0: const short ePreviousWord = 4; michael@0: const short eToBeginningOfLine = 5; michael@0: const short eToEndOfLine = 6; michael@0: michael@0: const short eStrip = 0; michael@0: const short eNoStrip = 1; michael@0: michael@0: readonly attribute nsISelection selection; michael@0: michael@0: /** michael@0: * Init is to tell the implementation of nsIEditor to begin its services michael@0: * @param aDoc The dom document interface being observed michael@0: * @param aRoot This is the root of the editable section of this michael@0: * document. If it is null then we get root michael@0: * from document body. michael@0: * @param aSelCon this should be used to get the selection location michael@0: * (will be null for HTML editors) michael@0: * @param aFlags A bitmask of flags for specifying the behavior michael@0: * of the editor. michael@0: */ michael@0: [noscript] void init(in nsIDOMDocument doc, michael@0: in nsIContent aRoot, michael@0: in nsISelectionController aSelCon, michael@0: in unsigned long aFlags, michael@0: in AString initialValue); michael@0: michael@0: void setAttributeOrEquivalent(in nsIDOMElement element, michael@0: in AString sourceAttrName, michael@0: in AString sourceAttrValue, michael@0: in boolean aSuppressTransaction); michael@0: void removeAttributeOrEquivalent(in nsIDOMElement element, michael@0: in DOMString sourceAttrName, michael@0: in boolean aSuppressTransaction); michael@0: michael@0: /** michael@0: * postCreate should be called after Init, and is the time that the editor michael@0: * tells its documentStateObservers that the document has been created. michael@0: */ michael@0: void postCreate(); michael@0: michael@0: /** michael@0: * preDestroy is called before the editor goes away, and gives the editor a michael@0: * chance to tell its documentStateObservers that the document is going away. michael@0: * @param aDestroyingFrames set to true when the frames being edited michael@0: * are being destroyed (so there is no need to modify any nsISelections, michael@0: * nor is it safe to do so) michael@0: */ michael@0: void preDestroy(in boolean aDestroyingFrames); michael@0: michael@0: /** edit flags for this editor. May be set at any time. */ michael@0: attribute unsigned long flags; michael@0: michael@0: /** michael@0: * the MimeType of the document michael@0: */ michael@0: attribute string contentsMIMEType; michael@0: michael@0: /** Returns true if we have a document that is not marked read-only */ michael@0: readonly attribute boolean isDocumentEditable; michael@0: michael@0: /** Returns true if the current selection anchor is editable */ michael@0: readonly attribute boolean isSelectionEditable; michael@0: michael@0: /** michael@0: * the DOM Document this editor is associated with, refcounted. michael@0: */ michael@0: readonly attribute nsIDOMDocument document; michael@0: michael@0: /** the body element, i.e. the root of the editable document. michael@0: */ michael@0: readonly attribute nsIDOMElement rootElement; michael@0: michael@0: /** michael@0: * the selection controller for the current presentation, refcounted. michael@0: */ michael@0: readonly attribute nsISelectionController selectionController; michael@0: michael@0: michael@0: /* ------------ Selected content removal -------------- */ michael@0: michael@0: /** michael@0: * DeleteSelection removes all nodes in the current selection. michael@0: * @param aDir if eNext, delete to the right (for example, the DEL key) michael@0: * if ePrevious, delete to the left (for example, the BACKSPACE key) michael@0: * @param stripWrappers If eStrip, strip any empty inline elements left michael@0: * behind after the deletion; if eNoStrip, don't. If in michael@0: * doubt, pass eStrip -- eNoStrip is only for if you're michael@0: * about to insert text or similar right after. michael@0: */ michael@0: void deleteSelection(in short action, in short stripWrappers); michael@0: michael@0: michael@0: /* ------------ Document info and file methods -------------- */ michael@0: michael@0: /** Returns true if the document has no *meaningful* content */ michael@0: readonly attribute boolean documentIsEmpty; michael@0: michael@0: /** Returns true if the document is modifed and needs saving */ michael@0: readonly attribute boolean documentModified; michael@0: michael@0: /** Sets the current 'Save' document character set */ michael@0: attribute ACString documentCharacterSet; michael@0: michael@0: /** to be used ONLY when we need to override the doc's modification michael@0: * state (such as when it's saved). michael@0: */ michael@0: void resetModificationCount(); michael@0: michael@0: /** Gets the modification count of the document we are editing. michael@0: * @return the modification count of the document being edited. michael@0: * Zero means unchanged. michael@0: */ michael@0: long getModificationCount(); michael@0: michael@0: /** called each time we modify the document. michael@0: * Increments the modification count of the document. michael@0: * @param aModCount the number of modifications by which michael@0: * to increase or decrease the count michael@0: */ michael@0: void incrementModificationCount(in long aModCount); michael@0: michael@0: /* ------------ Transaction methods -------------- */ michael@0: michael@0: /** transactionManager Get the transaction manager the editor is using. michael@0: */ michael@0: attribute nsITransactionManager transactionManager; michael@0: michael@0: /** doTransaction() fires a transaction. michael@0: * It is provided here so clients can create their own transactions. michael@0: * If a transaction manager is present, it is used. michael@0: * Otherwise, the transaction is just executed directly. michael@0: * michael@0: * @param aTxn the transaction to execute michael@0: */ michael@0: void doTransaction(in nsITransaction txn); michael@0: michael@0: michael@0: /** turn the undo system on or off michael@0: * @param aEnable if PR_TRUE, the undo system is turned on if available michael@0: * if PR_FALSE the undo system is turned off if it michael@0: * was previously on michael@0: * @return if aEnable is PR_TRUE, returns NS_OK if michael@0: * the undo system could be initialized properly michael@0: * if aEnable is PR_FALSE, returns NS_OK. michael@0: */ michael@0: void enableUndo(in boolean enable); michael@0: michael@0: /** michael@0: * The number of items on the undo stack. michael@0: */ michael@0: readonly attribute long numberOfUndoItems; michael@0: michael@0: /** michael@0: * The number of items on the redo stack. michael@0: */ michael@0: readonly attribute long numberOfRedoItems; michael@0: michael@0: /** undo reverses the effects of the last Do operation, michael@0: * if Undo is enabled in the editor. michael@0: * It is provided here so clients need no knowledge of whether michael@0: * the editor has a transaction manager or not. michael@0: * If a transaction manager is present, it is told to undo, michael@0: * and the result of that undo is returned. michael@0: * Otherwise, the Undo request is ignored and an michael@0: * error NS_ERROR_NOT_AVAILABLE is returned. michael@0: * michael@0: */ michael@0: void undo(in unsigned long count); michael@0: michael@0: /** returns state information about the undo system. michael@0: * @param aIsEnabled [OUT] PR_TRUE if undo is enabled michael@0: * @param aCanUndo [OUT] PR_TRUE if at least one transaction is michael@0: * currently ready to be undone. michael@0: */ michael@0: void canUndo(out boolean isEnabled, out boolean canUndo); michael@0: michael@0: /** redo reverses the effects of the last Undo operation michael@0: * It is provided here so clients need no knowledge of whether michael@0: * the editor has a transaction manager or not. michael@0: * If a transaction manager is present, it is told to redo and the michael@0: * result of the previously undone transaction is reapplied to the document. michael@0: * If no transaction is available for Redo, or if the document michael@0: * has no transaction manager, the Redo request is ignored and an michael@0: * error NS_ERROR_NOT_AVAILABLE is returned. michael@0: * michael@0: */ michael@0: void redo(in unsigned long count); michael@0: michael@0: /** returns state information about the redo system. michael@0: * @param aIsEnabled [OUT] PR_TRUE if redo is enabled michael@0: * @param aCanRedo [OUT] PR_TRUE if at least one transaction is michael@0: currently ready to be redone. michael@0: */ michael@0: void canRedo(out boolean isEnabled, out boolean canRedo); michael@0: michael@0: /** beginTransaction is a signal from the caller to the editor that michael@0: * the caller will execute multiple updates to the content tree michael@0: * that should be treated as a single logical operation, michael@0: * in the most efficient way possible.
michael@0: * All transactions executed between a call to beginTransaction and michael@0: * endTransaction will be undoable as an atomic action.
michael@0: * endTransaction must be called after beginTransaction.
michael@0: * Calls to beginTransaction can be nested, as long as endTransaction michael@0: * is called once per beginUpdate. michael@0: */ michael@0: void beginTransaction(); michael@0: michael@0: /** endTransaction is a signal to the editor that the caller is michael@0: * finished updating the content model.
michael@0: * beginUpdate must be called before endTransaction is called.
michael@0: * Calls to beginTransaction can be nested, as long as endTransaction michael@0: * is called once per beginTransaction. michael@0: */ michael@0: void endTransaction(); michael@0: michael@0: void beginPlaceHolderTransaction(in nsIAtom name); michael@0: void endPlaceHolderTransaction(); michael@0: boolean shouldTxnSetSelection(); michael@0: michael@0: /** Set the flag that prevents insertElementTxn from changing the selection michael@0: * @param should Set false to suppress changing the selection; michael@0: * i.e., before using InsertElement() to insert michael@0: * under element michael@0: * WARNING: You must be very careful to reset back to PR_TRUE after michael@0: * setting PR_FALSE, else selection/caret is trashed michael@0: * for further editing. michael@0: */ michael@0: void setShouldTxnSetSelection(in boolean should); michael@0: michael@0: /* ------------ Inline Spell Checking methods -------------- */ michael@0: michael@0: /** Returns the inline spell checker associated with this object. The spell michael@0: * checker is lazily created, so this function may create the object for michael@0: * you during this call. michael@0: * @param autoCreate If true, this will create a spell checker object michael@0: * if one does not exist yet for this editor. If false michael@0: * and the object has not been created, this function michael@0: * WILL RETURN NULL. michael@0: */ michael@0: nsIInlineSpellChecker getInlineSpellChecker(in boolean autoCreate); michael@0: michael@0: /** Resyncs spellchecking state (enabled/disabled). This should be called michael@0: * when anything that affects spellchecking state changes, such as the michael@0: * spellcheck attribute value. michael@0: */ michael@0: void syncRealTimeSpell(); michael@0: michael@0: /** Called when the user manually overrides the spellchecking state for this michael@0: * editor. michael@0: * @param enable The new state of spellchecking in this editor, as michael@0: * requested by the user. michael@0: */ michael@0: void setSpellcheckUserOverride(in boolean enable); michael@0: michael@0: /* ------------ Clipboard methods -------------- */ michael@0: michael@0: /** cut the currently selected text, putting it into the OS clipboard michael@0: * What if no text is selected? michael@0: * What about mixed selections? michael@0: * What are the clipboard formats? michael@0: */ michael@0: void cut(); michael@0: michael@0: /** Can we cut? True if the doc is modifiable, and we have a non- michael@0: * collapsed selection. michael@0: */ michael@0: boolean canCut(); michael@0: michael@0: /** copy the currently selected text, putting it into the OS clipboard michael@0: * What if no text is selected? michael@0: * What about mixed selections? michael@0: * What are the clipboard formats? michael@0: */ michael@0: void copy(); michael@0: michael@0: /** Can we copy? True if we have a non-collapsed selection. michael@0: */ michael@0: boolean canCopy(); michael@0: michael@0: /** paste the text in the OS clipboard at the cursor position, replacing michael@0: * the selected text (if any) michael@0: */ michael@0: void paste(in long aSelectionType); michael@0: michael@0: /** Paste the text in |aTransferable| at the cursor position, replacing the michael@0: * selected text (if any). michael@0: */ michael@0: void pasteTransferable(in nsITransferable aTransferable); michael@0: michael@0: /** Can we paste? True if the doc is modifiable, and we have michael@0: * pasteable data in the clipboard. michael@0: */ michael@0: boolean canPaste(in long aSelectionType); michael@0: michael@0: /** Can we paste |aTransferable| or, if |aTransferable| is null, will a call michael@0: * to pasteTransferable later possibly succeed if given an instance of michael@0: * nsITransferable then? True if the doc is modifiable, and, if michael@0: * |aTransfeable| is non-null, we have pasteable data in |aTransfeable|. michael@0: */ michael@0: boolean canPasteTransferable([optional] in nsITransferable aTransferable); michael@0: michael@0: /* ------------ Selection methods -------------- */ michael@0: michael@0: /** sets the document selection to the entire contents of the document */ michael@0: void selectAll(); michael@0: michael@0: /** sets the document selection to the beginning of the document */ michael@0: void beginningOfDocument(); michael@0: michael@0: /** sets the document selection to the end of the document */ michael@0: void endOfDocument(); michael@0: michael@0: /* ------------ Node manipulation methods -------------- */ michael@0: michael@0: /** michael@0: * setAttribute() sets the attribute of aElement. michael@0: * No checking is done to see if aAttribute is a legal attribute of the node, michael@0: * or if aValue is a legal value of aAttribute. michael@0: * michael@0: * @param aElement the content element to operate on michael@0: * @param aAttribute the string representation of the attribute to set michael@0: * @param aValue the value to set aAttribute to michael@0: */ michael@0: void setAttribute(in nsIDOMElement aElement, in AString attributestr, michael@0: in AString attvalue); michael@0: michael@0: /** michael@0: * getAttributeValue() retrieves the attribute's value for aElement. michael@0: * michael@0: * @param aElement the content element to operate on michael@0: * @param aAttribute the string representation of the attribute to get michael@0: * @param aResultValue [OUT] the value of aAttribute. michael@0: * Only valid if aResultIsSet is PR_TRUE michael@0: * @return PR_TRUE if aAttribute is set on the current node, michael@0: * PR_FALSE if it is not. michael@0: */ michael@0: boolean getAttributeValue(in nsIDOMElement aElement, michael@0: in AString attributestr, michael@0: out AString resultValue); michael@0: michael@0: /** michael@0: * removeAttribute() deletes aAttribute from the attribute list of aElement. michael@0: * If aAttribute is not an attribute of aElement, nothing is done. michael@0: * michael@0: * @param aElement the content element to operate on michael@0: * @param aAttribute the string representation of the attribute to get michael@0: */ michael@0: void removeAttribute(in nsIDOMElement aElement, michael@0: in AString aAttribute); michael@0: michael@0: /** michael@0: * cloneAttribute() copies the attribute from the source node to michael@0: * the destination node and delete those not in the source. michael@0: * michael@0: * The supplied nodes MUST BE ELEMENTS (most callers are working with nodes) michael@0: * @param aAttribute the name of the attribute to copy michael@0: * @param aDestNode the destination element to operate on michael@0: * @param aSourceNode the source element to copy attributes from michael@0: * @exception NS_ERROR_NULL_POINTER at least one of the nodes is null michael@0: * @exception NS_ERROR_NO_INTERFACE at least one of the nodes is not an michael@0: * element michael@0: */ michael@0: void cloneAttribute(in AString aAttribute, michael@0: in nsIDOMNode aDestNode, in nsIDOMNode aSourceNode); michael@0: michael@0: /** michael@0: * cloneAttributes() is similar to nsIDOMNode::cloneNode(), michael@0: * it assures the attribute nodes of the destination are identical michael@0: * with the source node by copying all existing attributes from the michael@0: * source and deleting those not in the source. michael@0: * This is used when the destination node (element) already exists michael@0: * michael@0: * The supplied nodes MUST BE ELEMENTS (most callers are working with nodes) michael@0: * @param aDestNode the destination element to operate on michael@0: * @param aSourceNode the source element to copy attributes from michael@0: */ michael@0: void cloneAttributes(in nsIDOMNode destNode, in nsIDOMNode sourceNode); michael@0: michael@0: /** michael@0: * createNode instantiates a new element of type aTag and inserts it michael@0: * into aParent at aPosition. michael@0: * @param aTag The type of object to create michael@0: * @param aParent The node to insert the new object into michael@0: * @param aPosition The place in aParent to insert the new node michael@0: * @return The node created. Caller must release aNewNode. michael@0: */ michael@0: nsIDOMNode createNode(in AString tag, michael@0: in nsIDOMNode parent, michael@0: in long position); michael@0: michael@0: /** michael@0: * insertNode inserts aNode into aParent at aPosition. michael@0: * No checking is done to verify the legality of the insertion. michael@0: * That is the responsibility of the caller. michael@0: * @param aNode The DOM Node to insert. michael@0: * @param aParent The node to insert the new object into michael@0: * @param aPosition The place in aParent to insert the new node michael@0: * 0=first child, 1=second child, etc. michael@0: * any number > number of current children = last child michael@0: */ michael@0: void insertNode(in nsIDOMNode node, michael@0: in nsIDOMNode parent, michael@0: in long aPosition); michael@0: michael@0: michael@0: /** michael@0: * splitNode() creates a new node identical to an existing node, michael@0: * and split the contents between the two nodes michael@0: * @param aExistingRightNode the node to split. michael@0: * It will become the new node's next sibling. michael@0: * @param aOffset the offset of aExistingRightNode's michael@0: * content|children to do the split at michael@0: * @param aNewLeftNode [OUT] the new node resulting from the split, michael@0: * becomes aExistingRightNode's previous sibling. michael@0: */ michael@0: void splitNode(in nsIDOMNode existingRightNode, michael@0: in long offset, michael@0: out nsIDOMNode newLeftNode); michael@0: michael@0: /** michael@0: * joinNodes() takes 2 nodes and merge their content|children. michael@0: * @param aLeftNode The left node. It will be deleted. michael@0: * @param aRightNode The right node. It will remain after the join. michael@0: * @param aParent The parent of aExistingRightNode michael@0: * michael@0: * There is no requirement that the two nodes be michael@0: * of the same type. However, a text node can be michael@0: * merged only with another text node. michael@0: */ michael@0: void joinNodes(in nsIDOMNode leftNode, michael@0: in nsIDOMNode rightNode, michael@0: in nsIDOMNode parent); michael@0: michael@0: /** michael@0: * deleteNode removes aChild from aParent. michael@0: * @param aChild The node to delete michael@0: */ michael@0: void deleteNode(in nsIDOMNode child); michael@0: michael@0: /** michael@0: * Returns true if markNodeDirty() has any effect. Returns false if michael@0: * markNodeDirty() is a no-op. michael@0: */ michael@0: [notxpcom] boolean outputsMozDirty(); michael@0: michael@0: /** michael@0: * markNodeDirty() sets a special dirty attribute on the node. michael@0: * Usually this will be called immediately after creating a new node. michael@0: * @param aNode The node for which to insert formatting. michael@0: */ michael@0: void markNodeDirty(in nsIDOMNode node); michael@0: michael@0: /* ---------- direction controller ---------- */ michael@0: michael@0: /** michael@0: * Switches the editor element direction; from "Left-to-Right" to michael@0: * "Right-to-Left", and vice versa. michael@0: */ michael@0: void switchTextDirection(); michael@0: michael@0: /* ------------ Output methods -------------- */ michael@0: michael@0: /** michael@0: * Output methods: michael@0: * aFormatType is a mime type, like text/plain. michael@0: */ michael@0: AString outputToString(in AString formatType, michael@0: in unsigned long flags); michael@0: void outputToStream(in nsIOutputStream aStream, michael@0: in AString formatType, michael@0: in ACString charsetOverride, michael@0: in unsigned long flags); michael@0: michael@0: michael@0: /* ------------ Various listeners methods -------------- michael@0: * nsIEditor holds strong references to the editor observers, action listeners michael@0: * and document state listeners. michael@0: */ michael@0: michael@0: /** add an EditorObserver to the editors list of observers. */ michael@0: void addEditorObserver(in nsIEditorObserver observer); michael@0: michael@0: /** Remove an EditorObserver from the editor's list of observers. */ michael@0: void removeEditorObserver(in nsIEditorObserver observer); michael@0: michael@0: /** add an EditActionListener to the editors list of listeners. */ michael@0: void addEditActionListener(in nsIEditActionListener listener); michael@0: michael@0: /** Remove an EditActionListener from the editor's list of listeners. */ michael@0: void removeEditActionListener(in nsIEditActionListener listener); michael@0: michael@0: /** Add a DocumentStateListener to the editors list of doc state listeners. */ michael@0: void addDocumentStateListener(in nsIDocumentStateListener listener); michael@0: michael@0: /** Remove a DocumentStateListener to the editors list of doc state listeners. */ michael@0: void removeDocumentStateListener(in nsIDocumentStateListener listener); michael@0: michael@0: michael@0: /* ------------ Debug methods -------------- */ michael@0: michael@0: /** michael@0: * And a debug method -- show us what the tree looks like right now michael@0: */ michael@0: void dumpContentTree(); michael@0: michael@0: /** Dumps a text representation of the content tree to standard out */ michael@0: void debugDumpContent() ; michael@0: michael@0: /* Run unit tests. Noop in optimized builds */ michael@0: void debugUnitTests(out long outNumTests, out long outNumTestsFailed); michael@0: michael@0: /* checks if a node is read-only or not */ michael@0: [notxpcom] boolean isModifiableNode(in nsIDOMNode aNode); michael@0: michael@0: /* Set true if you want to suppress dispatching input event. */ michael@0: attribute boolean suppressDispatchingInputEvent; michael@0: };