From ced498ab2c1f9379dfc0bb19b139587212c96005 Mon Sep 17 00:00:00 2001 From: "akkana%netscape.com" Date: Tue, 7 Aug 2001 21:39:07 +0000 Subject: [PATCH] 54726: Add link to W3C Validator 90550: Need to rewrite URLs for publishing and for save as 91388: Link checker, Work in progress (doesn't work yet) r=brade, sr=kin --- editor/base/nsEditorShell.cpp | 35 +- editor/base/nsHTMLEditor.cpp | 67 ++- editor/base/nsHTMLEditor.h | 3 +- editor/composer/src/nsEditorShell.cpp | 35 +- editor/idl/nsIEditorShell.idl | 5 +- editor/idl/nsIHTMLEditor.idl | 9 + editor/libeditor/html/nsHTMLEditor.cpp | 67 ++- editor/libeditor/html/nsHTMLEditor.h | 3 +- editor/public/nsIEditorMailSupport.h | 1 - editor/public/nsIHTMLEditor.h | 396 ------------------ .../ui/composer/content/ComposerCommands.js | 154 ++++++- .../composer/content/EditorCommandsDebug.js | 49 +-- editor/ui/composer/content/editorOverlay.xul | 10 +- .../composer/locale/en-US/editor.properties | 1 + .../composer/locale/en-US/editorOverlay.dtd | 2 + 15 files changed, 350 insertions(+), 487 deletions(-) diff --git a/editor/base/nsEditorShell.cpp b/editor/base/nsEditorShell.cpp index f9d9b3b5b77..3f710f9475c 100644 --- a/editor/base/nsEditorShell.cpp +++ b/editor/base/nsEditorShell.cpp @@ -138,6 +138,7 @@ #include "nsWidgetsCID.h" #include "nsIClipboard.h" #include "nsITransferable.h" + #include "nsISupportsArray.h" /* Define Class IDs */ @@ -4434,28 +4435,32 @@ nsEditorShell::GetSelectedCellsType(nsIDOMElement *aElement, PRUint32 *_retval) /* end of table editing */ +NS_IMETHODIMP +nsEditorShell::GetLinkedObjects(nsISupportsArray **aObjectArray) +{ + if (!aObjectArray) + return NS_ERROR_NULL_POINTER; + + if (mEditorType == eHTMLTextEditorType) + return mEditor->GetLinkedObjects(aObjectArray); + + return NS_ERROR_NOT_IMPLEMENTED; +} + NS_IMETHODIMP nsEditorShell::GetEmbeddedObjects(nsISupportsArray **aObjectArray) { if (!aObjectArray) return NS_ERROR_NULL_POINTER; - nsresult result = NS_NOINTERFACE; - - switch (mEditorType) + if (mEditorType == eHTMLTextEditorType) { - case eHTMLTextEditorType: - { - nsCOMPtr mailEditor = do_QueryInterface(mEditor); - if (mailEditor) - result = mailEditor->GetEmbeddedObjects(aObjectArray); - } - break; - - default: - result = NS_NOINTERFACE; + nsCOMPtr mailEditor = do_QueryInterface(mEditor); + if (mailEditor) + return mailEditor->GetEmbeddedObjects(aObjectArray); } - return result; + + return NS_NOINTERFACE; } NS_IMETHODIMP @@ -5054,8 +5059,6 @@ nsEditorShell::OnStateChange(nsIWebProgress *aProgress, PRInt32 aStateFlags, nsresult aStatus) { - nsresult rv = NS_OK; - // // A Request has started... // diff --git a/editor/base/nsHTMLEditor.cpp b/editor/base/nsHTMLEditor.cpp index 4feb7bf32f7..47e312899b8 100644 --- a/editor/base/nsHTMLEditor.cpp +++ b/editor/base/nsHTMLEditor.cpp @@ -31,6 +31,8 @@ #include "nsEditorEventListeners.h" #include "TypeInState.h" +#include "nsHTMLURIRefObject.h" + #include "nsIDOMText.h" #include "nsIDOMNodeList.h" #include "nsIDOMDocument.h" @@ -44,7 +46,6 @@ #include "nsISelection.h" #include "nsISelectionPrivate.h" #include "nsIDOMHTMLAnchorElement.h" -#include "nsIDOMHTMLImageElement.h" #include "nsISelectionController.h" #include "TransactionFactory.h" @@ -3048,6 +3049,68 @@ NS_IMETHODIMP nsHTMLEditor::SetBodyAttribute(const nsAReadableString& aAttribute return res; } +NS_IMETHODIMP +nsHTMLEditor::GetLinkedObjects(nsISupportsArray** aNodeList) +{ + if (!aNodeList) + return NS_ERROR_NULL_POINTER; + + nsresult res; + + res = NS_NewISupportsArray(aNodeList); + if (NS_FAILED(res)) return res; + if (!*aNodeList) return NS_ERROR_NULL_POINTER; + + nsCOMPtr iter; + res = nsComponentManager::CreateInstance(kCContentIteratorCID, nsnull, + NS_GET_IID(nsIContentIterator), + getter_AddRefs(iter)); + if (!iter) return NS_ERROR_NULL_POINTER; + if ((NS_SUCCEEDED(res))) + { + // get the root content + nsCOMPtr rootContent; + + nsCOMPtr domdoc; + nsEditor::GetDocument(getter_AddRefs(domdoc)); + if (!domdoc) + return NS_ERROR_UNEXPECTED; + + nsCOMPtr doc (do_QueryInterface(domdoc)); + if (!doc) + return NS_ERROR_UNEXPECTED; + + doc->GetRootContent(getter_AddRefs(rootContent)); + + iter->Init(rootContent); + + // loop through the content iterator for each content node + while (NS_ENUMERATOR_FALSE == iter->IsDone()) + { + nsCOMPtr content; + res = iter->CurrentNode(getter_AddRefs(content)); + if (NS_FAILED(res)) + break; + nsCOMPtr node (do_QueryInterface(content)); + if (node) + { + // Let nsURIRefObject make the hard decisions: + nsCOMPtr refObject; + res = NS_NewHTMLURIRefObject(getter_AddRefs(refObject), node); + if (NS_SUCCEEDED(res)) + { + nsCOMPtr isupp (do_QueryInterface(refObject)); + if (isupp) + (*aNodeList)->AppendElement(isupp); + } + } + iter->Next(); + } + } + + return NS_OK; +} + #ifdef XP_MAC #pragma mark - #pragma mark nsIEditorStyleSheets methods @@ -3278,7 +3341,7 @@ nsHTMLEditor::GetEmbeddedObjects(nsISupportsArray** aNodeList) (*aNodeList)->AppendElement(node); else if (tagName.EqualsWithConversion("a")) { - // XXX Only include links if they're links to file: URLs + // Only include links if they're links to file: URLs nsCOMPtr anchor (do_QueryInterface(content)); if (anchor) { diff --git a/editor/base/nsHTMLEditor.h b/editor/base/nsHTMLEditor.h index f2170f28695..d244a254222 100644 --- a/editor/base/nsHTMLEditor.h +++ b/editor/base/nsHTMLEditor.h @@ -156,6 +156,8 @@ public: NS_IMETHOD InsertLinkAroundSelection(nsIDOMElement* aAnchorElement); + NS_IMETHOD GetLinkedObjects(nsISupportsArray** aNodeList); + /* ------------ nsIEditorIMESupport overrides -------------- */ NS_IMETHOD SetCompositionString(const nsAReadableString& aCompositionString, nsIPrivateTextRangeList* aTextRangeList,nsTextEventReply* aReply); @@ -186,7 +188,6 @@ public: nsIDOMNode **aNodeInserted); NS_IMETHOD GetEmbeddedObjects(nsISupportsArray** aNodeList); - /* ------------ nsITableEditor methods -------------- */ NS_IMETHOD InsertTableCell(PRInt32 aNumber, PRBool aAfter); diff --git a/editor/composer/src/nsEditorShell.cpp b/editor/composer/src/nsEditorShell.cpp index f9d9b3b5b77..3f710f9475c 100644 --- a/editor/composer/src/nsEditorShell.cpp +++ b/editor/composer/src/nsEditorShell.cpp @@ -138,6 +138,7 @@ #include "nsWidgetsCID.h" #include "nsIClipboard.h" #include "nsITransferable.h" + #include "nsISupportsArray.h" /* Define Class IDs */ @@ -4434,28 +4435,32 @@ nsEditorShell::GetSelectedCellsType(nsIDOMElement *aElement, PRUint32 *_retval) /* end of table editing */ +NS_IMETHODIMP +nsEditorShell::GetLinkedObjects(nsISupportsArray **aObjectArray) +{ + if (!aObjectArray) + return NS_ERROR_NULL_POINTER; + + if (mEditorType == eHTMLTextEditorType) + return mEditor->GetLinkedObjects(aObjectArray); + + return NS_ERROR_NOT_IMPLEMENTED; +} + NS_IMETHODIMP nsEditorShell::GetEmbeddedObjects(nsISupportsArray **aObjectArray) { if (!aObjectArray) return NS_ERROR_NULL_POINTER; - nsresult result = NS_NOINTERFACE; - - switch (mEditorType) + if (mEditorType == eHTMLTextEditorType) { - case eHTMLTextEditorType: - { - nsCOMPtr mailEditor = do_QueryInterface(mEditor); - if (mailEditor) - result = mailEditor->GetEmbeddedObjects(aObjectArray); - } - break; - - default: - result = NS_NOINTERFACE; + nsCOMPtr mailEditor = do_QueryInterface(mEditor); + if (mailEditor) + return mailEditor->GetEmbeddedObjects(aObjectArray); } - return result; + + return NS_NOINTERFACE; } NS_IMETHODIMP @@ -5054,8 +5059,6 @@ nsEditorShell::OnStateChange(nsIWebProgress *aProgress, PRInt32 aStateFlags, nsresult aStatus) { - nsresult rv = NS_OK; - // // A Request has started... // diff --git a/editor/idl/nsIEditorShell.idl b/editor/idl/nsIEditorShell.idl index 7f73e03cda8..576dc7adbaa 100644 --- a/editor/idl/nsIEditorShell.idl +++ b/editor/idl/nsIEditorShell.idl @@ -23,7 +23,6 @@ #include "nsISupports.idl" interface nsIFile; -interface nsISupportsArray; interface nsIDocumentStateListener; interface nsISelectionController; interface nsITransactionManager; @@ -33,6 +32,7 @@ interface nsISelection; interface nsIDOMElement; interface nsIDOMNode; interface nsIEditor; +interface nsISupportsArray; [scriptable, uuid(9afff72b-ca9a-11d2-96c9-0060b0fb9956)] interface nsIEditorShell : nsISupports @@ -501,6 +501,9 @@ interface nsIEditorShell : nsISupports /* Get list of embedded objects, e.g. for mail compose */ nsISupportsArray GetEmbeddedObjects(); + /* Get list of objects which refer to external URIs */ + nsISupportsArray GetLinkedObjects(); + /* Formatting */ void SetAttribute(in nsIDOMElement element, in wstring attr, in wstring value); void RemoveAttribute(in nsIDOMElement element, in wstring attr); diff --git a/editor/idl/nsIHTMLEditor.idl b/editor/idl/nsIHTMLEditor.idl index e57afde8c0d..68c2c5858b3 100644 --- a/editor/idl/nsIHTMLEditor.idl +++ b/editor/idl/nsIHTMLEditor.idl @@ -26,6 +26,7 @@ #include "domstubs.idl" #include "nsIAtom.idl" +interface nsISupportsArray; %{C++ #define NS_EDITOR_ELEMENT_NOT_FOUND \ @@ -405,5 +406,13 @@ interface nsIHTMLEditor : nsISupports // Don't use this method! It will go away after first release! void IgnoreSpuriousDragEvent(in boolean aIgnoreSpuriousDragEvent); + /** + * Find all the nodes in the document which contain references + * to outside URIs (e.g. a href, img src, script src, etc.) + * The objects in the array will be type nsIURIRefObject. + * + * @return aNodeList the linked nodes found + */ + nsISupportsArray GetLinkedObjects(); }; diff --git a/editor/libeditor/html/nsHTMLEditor.cpp b/editor/libeditor/html/nsHTMLEditor.cpp index 4feb7bf32f7..47e312899b8 100644 --- a/editor/libeditor/html/nsHTMLEditor.cpp +++ b/editor/libeditor/html/nsHTMLEditor.cpp @@ -31,6 +31,8 @@ #include "nsEditorEventListeners.h" #include "TypeInState.h" +#include "nsHTMLURIRefObject.h" + #include "nsIDOMText.h" #include "nsIDOMNodeList.h" #include "nsIDOMDocument.h" @@ -44,7 +46,6 @@ #include "nsISelection.h" #include "nsISelectionPrivate.h" #include "nsIDOMHTMLAnchorElement.h" -#include "nsIDOMHTMLImageElement.h" #include "nsISelectionController.h" #include "TransactionFactory.h" @@ -3048,6 +3049,68 @@ NS_IMETHODIMP nsHTMLEditor::SetBodyAttribute(const nsAReadableString& aAttribute return res; } +NS_IMETHODIMP +nsHTMLEditor::GetLinkedObjects(nsISupportsArray** aNodeList) +{ + if (!aNodeList) + return NS_ERROR_NULL_POINTER; + + nsresult res; + + res = NS_NewISupportsArray(aNodeList); + if (NS_FAILED(res)) return res; + if (!*aNodeList) return NS_ERROR_NULL_POINTER; + + nsCOMPtr iter; + res = nsComponentManager::CreateInstance(kCContentIteratorCID, nsnull, + NS_GET_IID(nsIContentIterator), + getter_AddRefs(iter)); + if (!iter) return NS_ERROR_NULL_POINTER; + if ((NS_SUCCEEDED(res))) + { + // get the root content + nsCOMPtr rootContent; + + nsCOMPtr domdoc; + nsEditor::GetDocument(getter_AddRefs(domdoc)); + if (!domdoc) + return NS_ERROR_UNEXPECTED; + + nsCOMPtr doc (do_QueryInterface(domdoc)); + if (!doc) + return NS_ERROR_UNEXPECTED; + + doc->GetRootContent(getter_AddRefs(rootContent)); + + iter->Init(rootContent); + + // loop through the content iterator for each content node + while (NS_ENUMERATOR_FALSE == iter->IsDone()) + { + nsCOMPtr content; + res = iter->CurrentNode(getter_AddRefs(content)); + if (NS_FAILED(res)) + break; + nsCOMPtr node (do_QueryInterface(content)); + if (node) + { + // Let nsURIRefObject make the hard decisions: + nsCOMPtr refObject; + res = NS_NewHTMLURIRefObject(getter_AddRefs(refObject), node); + if (NS_SUCCEEDED(res)) + { + nsCOMPtr isupp (do_QueryInterface(refObject)); + if (isupp) + (*aNodeList)->AppendElement(isupp); + } + } + iter->Next(); + } + } + + return NS_OK; +} + #ifdef XP_MAC #pragma mark - #pragma mark nsIEditorStyleSheets methods @@ -3278,7 +3341,7 @@ nsHTMLEditor::GetEmbeddedObjects(nsISupportsArray** aNodeList) (*aNodeList)->AppendElement(node); else if (tagName.EqualsWithConversion("a")) { - // XXX Only include links if they're links to file: URLs + // Only include links if they're links to file: URLs nsCOMPtr anchor (do_QueryInterface(content)); if (anchor) { diff --git a/editor/libeditor/html/nsHTMLEditor.h b/editor/libeditor/html/nsHTMLEditor.h index f2170f28695..d244a254222 100644 --- a/editor/libeditor/html/nsHTMLEditor.h +++ b/editor/libeditor/html/nsHTMLEditor.h @@ -156,6 +156,8 @@ public: NS_IMETHOD InsertLinkAroundSelection(nsIDOMElement* aAnchorElement); + NS_IMETHOD GetLinkedObjects(nsISupportsArray** aNodeList); + /* ------------ nsIEditorIMESupport overrides -------------- */ NS_IMETHOD SetCompositionString(const nsAReadableString& aCompositionString, nsIPrivateTextRangeList* aTextRangeList,nsTextEventReply* aReply); @@ -186,7 +188,6 @@ public: nsIDOMNode **aNodeInserted); NS_IMETHOD GetEmbeddedObjects(nsISupportsArray** aNodeList); - /* ------------ nsITableEditor methods -------------- */ NS_IMETHOD InsertTableCell(PRInt32 aNumber, PRBool aAfter); diff --git a/editor/public/nsIEditorMailSupport.h b/editor/public/nsIEditorMailSupport.h index e65d57d0e2a..ab1bfd08e63 100644 --- a/editor/public/nsIEditorMailSupport.h +++ b/editor/public/nsIEditorMailSupport.h @@ -29,7 +29,6 @@ 0xfdf23301, 0x4a94, 0x11d3, \ { 0x9c, 0xe4, 0x99, 0x60, 0x49, 0x6c, 0x41, 0xbc } } -class nsString; class nsISupportsArray; class nsIDOMNode; diff --git a/editor/public/nsIHTMLEditor.h b/editor/public/nsIHTMLEditor.h index defe80e23b6..e69de29bb2d 100644 --- a/editor/public/nsIHTMLEditor.h +++ b/editor/public/nsIHTMLEditor.h @@ -1,396 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - */ - - -#ifndef nsIHTMLEditor_h__ -#define nsIHTMLEditor_h__ - - -#define NS_IHTMLEDITOR_IID \ -{ /* 4805e683-49b9-11d3-9ce4-ed60bd6cb5bc} */ \ -0x4805e683, 0x49b9, 0x11d3, \ -{ 0x9c, 0xe4, 0xed, 0x60, 0xbd, 0x6c, 0xb5, 0xbc } } - -#define NS_EDITOR_ELEMENT_NOT_FOUND \ - NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_EDITOR, 1) - -class nsString; -class nsStringArray; - -class nsIAtom; -class nsIDOMNode; -class nsIDOMElement; - -class nsIHTMLEditor : public nsISupports -{ -public: - static const nsIID& GetIID() { static nsIID iid = NS_IHTMLEDITOR_IID; return iid; } - - // used by GetAlignment() - typedef enum { - eLeft, - eCenter, - eRight, - eJustify - } EAlignment; - - /* ------------ Inline property methods -------------- */ - - - /** - * SetInlineProperty() sets the aggregate properties on the current selection - * - * @param aProperty the property to set on the selection - * @param aAttribute the attribute of the property, if applicable. May be null. - * Example: aProperty="font", aAttribute="color" - * @param aValue if aAttribute is not null, the value of the attribute. May be null. - * Example: aProperty="font", aAttribute="color", aValue="0x00FFFF" - */ - NS_IMETHOD SetInlineProperty(nsIAtom *aProperty, - const nsString *aAttribute, - const nsString *aValue)=0; - - /** - * GetInlineProperty() gets the aggregate properties of the current selection. - * All object in the current selection are scanned and their attributes are - * represented in a list of Property object. - * - * @param aProperty the property to get on the selection - * @param aAttribute the attribute of the property, if applicable. May be null. - * Example: aProperty="font", aAttribute="color" - * @param aValue if aAttribute is not null, the value of the attribute. May be null. - * Example: aProperty="font", aAttribute="color", aValue="0x00FFFF" - * @param aFirst [OUT] PR_TRUE if the first text node in the selection has the property - * @param aAny [OUT] PR_TRUE if any of the text nodes in the selection have the property - * @param aAll [OUT] PR_TRUE if all of the text nodes in the selection have the property - */ - NS_IMETHOD GetInlineProperty(nsIAtom *aProperty, - const nsString *aAttribute, - const nsString *aValue, - PRBool &aFirst, PRBool &aAny, PRBool &aAll)=0; - - NS_IMETHOD GetInlinePropertyWithAttrValue(nsIAtom *aProperty, - const nsString *aAttribute, - const nsString *aValue, - PRBool &aFirst, PRBool &aAny, PRBool &aAll, - nsString *outValue)=0; - - /** - * RemoveAllInlineProperties() deletes all the inline properties from all - * text in the current selection. - */ - NS_IMETHOD RemoveAllInlineProperties()=0; - - - /** - * RemoveInlineProperty() deletes the properties from all text in the current selection. - * If aProperty is not set on the selection, nothing is done. - * - * @param aProperty the property to remove from the selection - * All atoms are for normal HTML tags (e.g.: nsIEditorProptery::font) - * except when you want to remove just links and not named anchors - * For that, use nsIEditorProperty::href - * @param aAttribute the attribute of the property, if applicable. May be null. - * Example: aProperty=nsIEditorProptery::font, aAttribute="color" - * nsIEditProperty::allAttributes is special. It indicates that - * all content-based text properties are to be removed from the selection. - */ - NS_IMETHOD RemoveInlineProperty(nsIAtom *aProperty, const nsString *aAttribute)=0; - - /** - * Increase font size for text in selection by 1 HTML unit - * All existing text is scanned for existing attributes - * so they will be incremented instead of inserting new tag - */ - NS_IMETHOD IncreaseFontSize()=0; - - /** - * Decrease font size for text in selection by 1 HTML unit - * All existing text is scanned for existing attributes - * so they will be decreased instead of inserting new tag - */ - NS_IMETHOD DecreaseFontSize()=0; - - /* ------------ HTML content methods -------------- */ - - /** - * Tests if a node is a BLOCK element according the the HTML 4.0 DTD - * This does NOT consider CSS effect on display type - * - * @param aNode the node to test - */ - NS_IMETHOD NodeIsBlock(nsIDOMNode *aNode, PRBool &aIsBlock)=0; - - /** - * Insert some HTML source at the current location - * - * @param aInputString the string to be inserted - */ - NS_IMETHOD InsertHTML(const nsString &aInputString)=0; - - - /** Rebuild the entire document from source HTML - * Needed to be able to edit HEAD and other outside-of-BODY content - * - * @param aSourceString HTML source string of the entire new document - */ - NS_IMETHOD RebuildDocumentFromSource(const nsString& aSourceString)=0; - - /** - * Insert some HTML source, interpreting - * the string argument according to the given charset. - * - * @param aInputString the string to be inserted - * @param aCharset Charset of string - * @param aParentNode Parent to insert under. - * If null, insert at the current location. - */ - NS_IMETHOD InsertHTMLWithCharset(const nsString &aInputString, - const nsString& aCharset)=0; - - - /** Insert an element, which may have child nodes, at the selection - * Used primarily to insert a new element for various insert element dialogs, - * but it enforces the HTML 4.0 DTD "CanContain" rules, so it should - * be useful for other elements. - * - * @param aElement The element to insert - * @param aDeleteSelection Delete the selection before inserting - * If aDeleteSelection is PR_FALSE, then the element is inserted - * after the end of the selection for all element except - * Named Anchors, which insert before the selection - */ - NS_IMETHOD InsertElementAtSelection(nsIDOMElement* aElement, PRBool aDeleteSelection)=0; - - /** Set the documents title. - */ - NS_IMETHOD SetDocumentTitle(const PRUnichar *aTitle)=0; - - /* ------------ Selection manipulation -------------- */ - /* Should these be moved to nsISelection? */ - - /** Set the selection at the suppled element - * - * @param aElement An element in the document - */ - NS_IMETHOD SelectElement(nsIDOMElement* aElement)=0; - - /** Create a collapsed selection just after aElement - * - * XXX could we parameterize SelectElement(before/select/after>? - * - * The selection is set to parent-of-aElement with an - * offset 1 greater than aElement's offset - * but it enforces the HTML 4.0 DTD "CanContain" rules, so it should - * be useful for other elements. - * - * @param aElement An element in the document - */ - NS_IMETHOD SetCaretAfterElement(nsIDOMElement* aElement)=0; - - /** - * SetParagraphFormat Insert a block paragraph tag around selection - * @param aParagraphFormat "p", "h1" to "h6", "address", "pre", or "blockquote" - */ - NS_IMETHOD SetParagraphFormat(const nsString& aParagraphFormat)=0; - - /** - * GetParagraphState returns what block tag paragraph format is in the selection. - * @param aMixed True if there is more than one format - * @param outState Name of block tag. "" is returned for none. - */ - NS_IMETHOD GetParagraphState(PRBool &aMixed, nsString &outState)=0; - - /** - * GetFontFaceState returns what font face is in the selection. - * @param aMixed True if there is more than one font face - * @param outFace Name of face. Note: "tt" is returned for - * tt tag. "" is returned for none. - */ - NS_IMETHOD GetFontFaceState(PRBool &aMixed, nsString &outFont)=0; - - /** - * GetFontColorState returns what font face is in the selection. - * @param aMixed True if there is more than one font color - * @param outColor Color string. "" is returned for none. - */ - NS_IMETHOD GetFontColorState(PRBool &aMixed, nsString &outColor)=0; - - /** - * GetFontColorState returns what font face is in the selection. - * @param aMixed True if there is more than one font color - * @param outColor Color string. "" is returned for none. - */ - NS_IMETHOD GetBackgroundColorState(PRBool &aMixed, nsString &outColor)=0; - - /** - * GetListState returns what list type is in the selection. - * @param aMixed True if there is more than one type of list, or - * if there is some list and non-list - * @param aOL The company that employs me. No, really, it's - * true if an "ol" list is selected. - * @param aUL true if an "ul" list is selected. - * @param aDL true if a "dl" list is selected. - */ - NS_IMETHOD GetListState(PRBool &aMixed, PRBool &aOL, PRBool &aUL, PRBool &aDL)=0; - - /** - * GetListItemState returns what list item type is in the selection. - * @param aMixed True if there is more than one type of list item, or - * if there is some list and non-list - * @param aLI true if "li" list items are selected. - * @param aDT true if "dt" list items are selected. - * @param aDD true if "dd" list items are selected. - */ - NS_IMETHOD GetListItemState(PRBool &aMixed, PRBool &aLI, PRBool &aDT, PRBool &aDD)=0; - - /** - * GetAlignment returns what alignment is in the selection. - * @param aMixed True if there is more than one type of list item, or - * if there is some list and non-list - * @param aAlign enum value for first encountered alignment (left/center/right) - */ - NS_IMETHOD GetAlignment(PRBool &aMixed, EAlignment &aAlign)=0; - - /** - * Document me! - * - */ - NS_IMETHOD GetIndentState(PRBool &aCanIndent, PRBool &aCanOutdent)=0; - - /** - * Document me! - * - */ - NS_IMETHOD MakeOrChangeList(const nsString& aListType, PRBool entireList)=0; - - /** - * Document me! - * - */ - NS_IMETHOD RemoveList(const nsString& aListType)=0; - - /** - * Document me! - * - */ - NS_IMETHOD Indent(const nsString& aIndent)=0; - - /** - * Document me! - * - */ - NS_IMETHOD Align(const nsString& aAlign)=0; - - /** Return the input node or a parent matching the given aTagName, - * starting the search at the supplied node. - * An example of use is for testing if a node is in a table cell - * given a selection anchor node. - * - * @param aTagName The HTML tagname - * Special input values: - * Use "href" to get a link node - * (an "A" tag with the "href" attribute set) - * Use "anchor" or "namedanchor" to get a named anchor node - * (an "A" tag with the "name" attribute set) - * Use "list" to get an OL, UL, or DL list node - * Use "td" to get either a TD or TH cell node - * - * @param aNode The node in the document to start the search - * If it is null, the anchor node of the current selection is used - * Returns NS_EDITOR_ELEMENT_NOT_FOUND if an element is not found (passes NS_SUCCEEDED macro) - */ - NS_IMETHOD GetElementOrParentByTagName(const nsAReadableString& aTagName, nsIDOMNode *aNode, nsIDOMElement** aReturn)=0; - - /** Return an element only if it is the only node selected, - * such as an image, horizontal rule, etc. - * The exception is a link, which is more like a text attribute: - * The Anchor tag is returned if the selection is within the textnode(s) - * that are children of the "A" node. - * This could be a collapsed selection, i.e., a caret within the link text. - * - * @param aTagName The HTML tagname or and empty string - * to get any element (but only if it is the only element selected) - * Special input values for Links and Named anchors: - * Use "href" to get a link node - * (an "A" tag with the "href" attribute set) - * Use "anchor" or "namedanchor" to get a named anchor node - * (an "A" tag with the "name" attribute set) - * Returns NS_EDITOR_ELEMENT_NOT_FOUND if an element is not found (passes NS_SUCCEEDED macro) - */ - NS_IMETHOD GetSelectedElement(const nsString& aTagName, nsIDOMElement** aReturn)=0; - - /** Output the contents of the section as text/HTML format - */ - NS_IMETHOD GetHeadContentsAsHTML(nsString& aOutputString)=0; - - /** Replace all children of with string of HTML source - */ - NS_IMETHOD ReplaceHeadContentsWithHTML(const nsString &aSourceToInsert)=0; - - /** Return a new element with default attribute values - * - * This does not rely on the selection, and is not sensitive to context. - * - * Used primarily to supply new element for various insert element dialogs - * (Image, Link, NamedAnchor, Table, and HorizontalRule - * are the only returned elements as of 7/25/99) - * - * @param aTagName The HTML tagname - * Special input values for Links and Named anchors: - * Use "href" to get a link node - * (an "A" tag with the "href" attribute set) - * Use "anchor" or "namedanchor" to get a named anchor node - * (an "A" tag with the "name" attribute set) - */ - NS_IMETHOD CreateElementWithDefaults(const nsAReadableString& aTagName, nsIDOMElement** aReturn)=0; - - /** Insert an link element as the parent of the current selection - * - * @param aElement An "A" element with a non-empty "href" attribute - */ - NS_IMETHOD InsertLinkAroundSelection(nsIDOMElement* aAnchorElement)=0; - - /** Set the value of the "bgcolor" attribute on the document's element - * - * @param aColor The HTML color string, such as "#ffccff" or "yellow" - */ - NS_IMETHOD SetBackgroundColor(const nsString& aColor)=0; - - - /** Set an attribute on the document's element - * such as text, link, background colors - * - * 8/31/00 THIS ISN'T BEING USED? SHOULD WE DROP IT? - * - * @param aAttr The attribute to be set - * @param aValue The value of the attribute - */ - NS_IMETHOD SetBodyAttribute(const nsString& aAttr, const nsString& aValue)=0; - - //XXX Used to suppress spurious drag/drop events to workaround bug 50703 - // Don't use this method! It will go away after first release! - NS_IMETHOD IgnoreSpuriousDragEvent(PRBool aIgnoreSpuriousDragEvent)=0; - -}; - -#endif // nsIHTMLEditor_h__ diff --git a/editor/ui/composer/content/ComposerCommands.js b/editor/ui/composer/content/ComposerCommands.js index 50e8f517872..c033164aa74 100644 --- a/editor/ui/composer/content/ComposerCommands.js +++ b/editor/ui/composer/content/ComposerCommands.js @@ -96,6 +96,8 @@ function SetupTextEditorCommands() controller.registerCommand("cmd_find", nsFindCommand); controller.registerCommand("cmd_findNext", nsFindNextCommand); controller.registerCommand("cmd_spelling", nsSpellingCommand); + controller.registerCommand("cmd_validate", nsValidateCommand); + controller.registerCommand("cmd_checkLinks", nsCheckLinksCommand); controller.registerCommand("cmd_insertChars", nsInsertCharsCommand); } @@ -618,6 +620,157 @@ var nsSpellingCommand = } }; +// Validate using http://validator.w3.org/file-upload.html +var URL2Validate; +var nsValidateCommand = +{ + isCommandEnabled: function(aCommand, dummy) + { + return (window.editorShell != null); + }, + + doCommand: function(aCommand) + { + // If the document hasn't been modified, + // then just validate the current url. + if (editorShell.documentModified || gHTMLSourceChanged) + { + if (!CheckAndSaveDocument(window.editorShell.GetString("BeforeValidate"), + false)) + return; + + // Check if we saved again just in case? + if (!DocumentHasBeenSaved()) // user hit cancel? + return; + } + + URL2Validate = window.editorShell.editorDocument.location; + // XXX This should use SchemeIs instead of comparing against file: + if (URL2Validate.toString().indexOf("file://") >= 0) + { + URL2Validate = window.editorShell.editorDocument.location.pathname; + var vwin = window.open("http://validator.w3.org/file-upload.html", + "EditorValidate"); + // Window loads asynchronously, so pass control to the load listener: + vwin.addEventListener("load", this.validateFilePageLoaded, false); + } + else + { + var vwin = window.open("http://validator.w3.org/", + "EditorValidate"); + // Window loads asynchronously, so pass control to the load listener: + vwin.addEventListener("load", this.validateWebPageLoaded, false); + } + }, + validateFilePageLoaded: function(event) + { + event.target.forms[0].uploaded_file.value = URL2Validate; + }, + validateWebPageLoaded: function(event) + { + event.target.forms[0].uri.value = URL2Validate; + } +}; + +// Link checking. +// XXX THIS CODE IS WORK IN PROGRESS (only exposed in the debug menu). + +const kIOSERVICE_CONTRACTID = "@mozilla.org/network/io-service;1"; +const nsIIOService = Components.interfaces['nsIIOService']; + +var nsLinkChecker = +{ + uri : null, + linkCheckDone : true, + ios : Components.classes[kIOSERVICE_CONTRACTID].getService(nsIIOService), + linkCheckURI : "", + + LoadFromURI: function(aURI, ioService) { + this.done = false; + this.uri = aURI; + dump("LoadFromURI(" + this.uri + ")\n"); + var theURI = this.ios.newURI(this.uri, null); + //pacURL = uri.spec; + + var channel = this.ios.newChannelFromURI(theURI); + // Don't load for cache, that would be cheating: + //channel.loadFlags |= nsIRequest::LOAD_BYPASS_CACHE; + try { + var httpChannel = channel.QueryInterface(Components.interfaces.nsIHttpChannel); + if (httpChannel) { + httpChannel.requestMethod = "HEAD"; + } + } catch(e) { } + try { + channel.asyncOpen(this, null); + } + catch (ex) { + dump("asyncOpen failed for " + this.uri + "\n"); + } + }, + + // nsIStreamListener interface + onStartRequest: function(request, ctxt) { + dump("onStartRequest(" + this.uri + ", status = " + request.status + + ")\n"); + try { + var httpChannel = request.QueryInterface(Components.interfaces.nsIHttpChannel); + if (httpChannel) { + var stat = httpChannel.responseStatus/100; + dump("Response status was " + stat + "\n"); + } + } catch(e) { } + // Probably don't actually need this stream if we're not going to read: + this.sis = + Components.Constructor('@mozilla.org/scriptableinputstream;1', + 'nsIScriptableInputStream', + 'init'); + throw(Components.results.NS_ERROR_FAILURE); + }, + + onStopRequest: function(request, ctxt, status, errorMsg) { + dump("onStopRequest(" + this.uri + ", status = " + status + ")\n"); + this.done = true; + }, + + onDataAvailable: function(request, ctxt, inStream, sourceOffset, count) { + dump("onDataAvailable(" + this.uri + ")\n"); + var ins = new this.sis(inStream); + pac += ins.read(count); + + // Now check the error code and cancel the request. + // This should pass NS_BINDING_ABORTED, according to nsIRequest.idl, + // but it doesn't seem to be available from JS. + // ((nsresult) (((PRUint32)(NS_ERROR_SEVERITY_ERROR)<<31) | ((PRUint32)(module+ + // NS_ERROR_MODULE_BASE_OFFSET)<<16) | ((PRUint32)(code)) + //request.cancel(0x80000001); + } +}; + +var nsCheckLinksCommand = +{ + isCommandEnabled: function(aCommand, dummy) + { + return (window.editorShell != null); + }, + + doCommand: function(aCommand) + { + objects = window.editorShell.GetLinkedObjects(); + // Objects is an nsISupportsArray. + var uri; + dump("Checking links in " + objects.Count() + " items ...\n"); + for (var i = 0; i < objects.Count(); ++i) + { + var refobj = objects.GetElementAt(i).QueryInterface(Components.interfaces.nsIURIRefObject); + uri = refobj.GetNextURI(); + dump(i + ": '" + uri + "'\n"); + } + // Check only the last link, for now: + nsLinkChecker.LoadFromURI(uri); + } +}; + //----------------------------------------------------------------------------------- var nsImageCommand = { @@ -1458,7 +1611,6 @@ var nsTableOrCellColorCommand = } }; - //----------------------------------------------------------------------------------- var nsPreferencesCommand = { diff --git a/editor/ui/composer/content/EditorCommandsDebug.js b/editor/ui/composer/content/EditorCommandsDebug.js index aee2fa194da..077f77a1ed5 100644 --- a/editor/ui/composer/content/EditorCommandsDebug.js +++ b/editor/ui/composer/content/EditorCommandsDebug.js @@ -25,12 +25,6 @@ // --------------------------- Output --------------------------- -function EditorSerialize() -{ - var s = new XMLSerializer(); - dump(s.serializeToString(editorShell.editorDocument) + "\n"); -} - function EditorGetText() { if (editorShell) { @@ -74,7 +68,9 @@ function EditorTestSelection() dump("Selection contains:\n"); // 3rd param = column to wrap - dump(selection.toString("text/plain", gOutputFormatted & gOutputSelectionOnly, 0) + "\n"); + dump(selection.toStringWithFormat("text/plain", + gOutputFormatted & gOutputSelectionOnly, + 0) + "\n"); var output; @@ -346,45 +342,6 @@ function EditorRunLog() window._content.focus(); } -function EditorTableize() -{ - // 1 = OutputSelectionOnly, 1024 = OutputLFLineBreak - // 256 = OutputEncodeEntities - var str = editorShell.GetContentsAs("text/html", 1+1024); - var newstr; - - //dump("String to tableize is '" + str + "'\n"); - - // Replace nbsp with spaces: - newstr = str.replace(/\u00a0/g, " "); - - // Trim trailing

or
- str = newstr.replace(/\s*
\s*$/, ""); - newstr = str.replace(/\s*

\s*$/, ""); - - // Trim leading and trailing spaces - str = newstr.replace(/^\s+/, ""); - newstr = str.replace(/\s+$/, ""); - // Trim whitespace adjacent to

and
tags - str = newstr.replace(/\s+

\s+/g, "
"); - newstr = str.replace(/\s+
\s+/g, "
"); - - // Put wherever we see whitespace - str = newstr.replace(/ +/g, " "); - - // End table row and start another for each br or p - newstr = str.replace(/\s*
\s*/g, "\n"); - - // Add the table tags and the opening and closing tr/td tags - str = "\n\n
" + newstr + "
\n"; - - //dump("Trying to insert '" + str + "'\n"); - - window.editorShell.InsertSource(str); - - window._content.focus(); -} - // --------------------------- TransactionManager --------------------------- diff --git a/editor/ui/composer/content/editorOverlay.xul b/editor/ui/composer/content/editorOverlay.xul index c2d5632e20f..a9af66db601 100644 --- a/editor/ui/composer/content/editorOverlay.xul +++ b/editor/ui/composer/content/editorOverlay.xul @@ -156,6 +156,8 @@ + + @@ -338,6 +340,8 @@ + @@ -812,8 +816,6 @@ oncommand="EditorGetText()"/> - - + diff --git a/editor/ui/composer/locale/en-US/editor.properties b/editor/ui/composer/locale/en-US/editor.properties index 55c8e97b0bb..0fb88c46aeb 100644 --- a/editor/ui/composer/locale/en-US/editor.properties +++ b/editor/ui/composer/locale/en-US/editor.properties @@ -45,6 +45,7 @@ TextFiles=Text Files AllFiles=All Files BeforeClosing=before closing BeforePreview=before viewing in Navigator +BeforeValidate=before validating the document # LOCALIZATION NOTE (SaveFilePrompt): Don't translate %title% and %reason% (this is the reason for asking user to close, such as "before closing") SaveFilePrompt=Save changes to "%title%" %reason%? SaveFileFailed=Saving file failed! diff --git a/editor/ui/composer/locale/en-US/editorOverlay.dtd b/editor/ui/composer/locale/en-US/editorOverlay.dtd index a33ecafdefe..30b719727f5 100644 --- a/editor/ui/composer/locale/en-US/editorOverlay.dtd +++ b/editor/ui/composer/locale/en-US/editorOverlay.dtd @@ -108,6 +108,8 @@ + +