diff --git a/mozilla/editor/composer/src/nsEditorShell.cpp b/mozilla/editor/composer/src/nsEditorShell.cpp index 01a8d57c6e8..ce68d151585 100644 --- a/mozilla/editor/composer/src/nsEditorShell.cpp +++ b/mozilla/editor/composer/src/nsEditorShell.cpp @@ -237,7 +237,6 @@ GetTreeOwner(nsIDocShell* aDocShell, nsIBaseWindow** aBaseWindow) nsEditorShell::nsEditorShell() : mMailCompose(PR_FALSE) -, mDisplayMode(eDisplayModeNormal) , mHTMLSourceMode(PR_FALSE) , mWebShellWindow(nsnull) , mContentWindow(nsnull) @@ -321,32 +320,6 @@ nsEditorShell::ResetEditingState() editor->PreDestroy(); } - // Unload existing stylesheets - nsCOMPtr styleSheets = do_QueryInterface(mEditor); - if (styleSheets) - { - if (mBaseStyleSheet) - { - styleSheets->RemoveOverrideStyleSheet(mBaseStyleSheet); - mBaseStyleSheet = 0; - } - if (mEditModeStyleSheet) - { - styleSheets->RemoveOverrideStyleSheet(mEditModeStyleSheet); - mEditModeStyleSheet = 0; - } - if (mAllTagsModeStyleSheet) - { - styleSheets->RemoveOverrideStyleSheet(mAllTagsModeStyleSheet); - mAllTagsModeStyleSheet = 0; - } - if (mParagraphMarksStyleSheet) - { - styleSheets->RemoveOverrideStyleSheet(mParagraphMarksStyleSheet); - mParagraphMarksStyleSheet = 0; - } - } - nsresult rv; // now, unregister the selection listener, if there was one if (mStateMaintainer) @@ -519,20 +492,6 @@ nsEditorShell::PrepareDocumentForEditing(nsIDOMWindow* aDOMWindow, nsIURI *aUrl) UpdateWindowTitleAndRecentMenu(PR_TRUE); } - nsCOMPtr styleSheets = do_QueryInterface(mEditor); - if (!styleSheets) - return NS_NOINTERFACE; - - // Load style sheet with settings that should never - // change, even in "Browser" mode - // We won't unload this, so we don't need to be returned the style sheet pointer - - - styleSheets->ApplyOverrideStyleSheet(NS_LITERAL_STRING("chrome://editor/content/EditorOverride.css"), - getter_AddRefs(mBaseStyleSheet)); - - SetDisplayMode(mDisplayMode); - #ifdef DEBUG // Activate the debug menu only in debug builds // by removing the "hidden" attribute set "true" in XUL @@ -1298,130 +1257,14 @@ nsEditorShell::ApplyStyleSheet(const PRUnichar *url) nsCOMPtr styleSheets = do_QueryInterface(mEditor); if (styleSheets) - result = styleSheets->ApplyStyleSheet(aURL, nsnull); + result = styleSheets->ReplaceStyleSheet(aURL); return result; } -// Note: This is not undoable action (on purpose!) -NS_IMETHODIMP -nsEditorShell::SetDisplayMode(PRInt32 aDisplayMode) -{ - if (aDisplayMode == eDisplayModeSource) - { - // We track only display modes that involve style sheet changes - // with mDisplayMode, so use a separate bool for source mode - mHTMLSourceMode = PR_TRUE; - // The HTML Source display mode is handled in editor.js - return NS_OK; - } - mHTMLSourceMode = PR_FALSE; - - nsCOMPtr styleSheets = do_QueryInterface(mEditor); - if (!styleSheets) return NS_NOINTERFACE; - - nsCOMPtr nsISheet; - nsresult res = NS_OK; - - // Extra style sheets to explain optimization testing: - // eDisplayModePreview: No extra style sheets - // eDisplayModePreview: 1 extra sheet: mEditModeStyleSheet - // eDisplayModeAllTags: 2 extra sheets: mEditModeStyleSheet and mAllTagsModeStyleSheet - - if (aDisplayMode == eDisplayModePreview) - { - // Disable all extra "edit mode" style sheets - if (mEditModeStyleSheet) - { - nsISheet = do_QueryInterface(mEditModeStyleSheet); - res = nsISheet->SetEnabled(PR_FALSE); - if (NS_FAILED(res)) return res; - } - // Disable ShowAllTags mode if that was the previous mode - if (mDisplayMode == eDisplayModeAllTags && mAllTagsModeStyleSheet) - { - nsISheet = do_QueryInterface(mAllTagsModeStyleSheet); - res = nsISheet->SetEnabled(PR_FALSE); - } - } - else if (aDisplayMode == eDisplayModeNormal) - { - // Don't need to activate if AllTags was last mode - if (mDisplayMode != eDisplayModeAllTags) - { - // If loaded before, enable the sheet - if (mEditModeStyleSheet) - { - nsISheet = do_QueryInterface(mEditModeStyleSheet); - res = nsISheet->SetEnabled(PR_TRUE); - } - else - { - - //Load the editmode style sheet - res = styleSheets->ApplyOverrideStyleSheet(NS_LITERAL_STRING("chrome://editor/content/EditorContent.css"), - getter_AddRefs(mEditModeStyleSheet)); - } - if (NS_FAILED(res)) return res; - } - - // Disable ShowAllTags mode if that was the previous mode - if (mDisplayMode == eDisplayModeAllTags && mAllTagsModeStyleSheet) - { - nsISheet = do_QueryInterface(mAllTagsModeStyleSheet); - res = nsISheet->SetEnabled(PR_FALSE); - } - } - else if (aDisplayMode == eDisplayModeAllTags) - { - // If loaded before, enable the sheet - if (mAllTagsModeStyleSheet) - { - nsISheet = do_QueryInterface(mAllTagsModeStyleSheet); - res = nsISheet->SetEnabled(PR_TRUE); - } - else - { - // else load it - res = styleSheets->ApplyOverrideStyleSheet(NS_LITERAL_STRING("chrome://editor/content/EditorAllTags.css"), - getter_AddRefs(mAllTagsModeStyleSheet)); - } - if (NS_FAILED(res)) return res; - - // We don't need to activate "normal" mode if that was the previous mode - if (mDisplayMode != eDisplayModeNormal) - { - if (mEditModeStyleSheet) - { - nsISheet = do_QueryInterface(mEditModeStyleSheet); - res = nsISheet->SetEnabled(PR_TRUE); - } - else - { - res = styleSheets->ApplyOverrideStyleSheet(NS_LITERAL_STRING("chrome://editor/content/EditorContent.css"), - getter_AddRefs(mEditModeStyleSheet)); - } - } - } - - // Remember the new mode - if (NS_SUCCEEDED(res)) mDisplayMode = aDisplayMode; - return res; -} - -NS_IMETHODIMP -nsEditorShell::GetEditMode(PRInt32 *_retval) -{ - if (mHTMLSourceMode) - *_retval = eDisplayModeSource; - else - *_retval = mDisplayMode; - - return NS_OK; -} NS_IMETHODIMP -nsEditorShell::IsHTMLSourceMode(PRBool *_retval) +nsEditorShell::GetHTMLSourceMode(PRBool *_retval) { *_retval = mHTMLSourceMode; @@ -1429,48 +1272,13 @@ nsEditorShell::IsHTMLSourceMode(PRBool *_retval) } NS_IMETHODIMP -nsEditorShell::FinishHTMLSource(void) +nsEditorShell::SetHTMLSourceMode(const PRBool aSourceMode) { - if (mHTMLSourceMode) - { - // Call the JS command to convert and switch to previous edit mode - return DoControllerCommand("cmd_FinishHTMLSource"); - } + mHTMLSourceMode = aSourceMode; + return NS_OK; } - -NS_IMETHODIMP -nsEditorShell::DisplayParagraphMarks(PRBool aShowMarks) -{ - nsresult res = NS_OK; - - nsCOMPtr styleSheets = do_QueryInterface(mEditor); - if (!styleSheets) return NS_NOINTERFACE; - nsCOMPtr nsISheet; - if (aShowMarks) - { - // Check if style sheet is already loaded -- just enable it - if (mParagraphMarksStyleSheet) - { - nsISheet = do_QueryInterface(mParagraphMarksStyleSheet); - return nsISheet->SetEnabled(PR_TRUE); - } - //First time used -- load the style sheet - nsCOMPtr styleSheet; - res = styleSheets->ApplyOverrideStyleSheet(NS_LITERAL_STRING("chrome://editor/content/EditorParagraphMarks.css"), - getter_AddRefs(mParagraphMarksStyleSheet)); - } - else if (mParagraphMarksStyleSheet) - { - // Disable the style sheet - nsISheet = do_QueryInterface(mParagraphMarksStyleSheet); - res = nsISheet->SetEnabled(PR_FALSE); - } - - return res; -} - NS_IMETHODIMP nsEditorShell::SetBodyAttribute(const PRUnichar *attr, const PRUnichar *value) { diff --git a/mozilla/editor/composer/src/nsEditorShell.h b/mozilla/editor/composer/src/nsEditorShell.h index 0989b9857c1..19bacfbfcea 100644 --- a/mozilla/editor/composer/src/nsEditorShell.h +++ b/mozilla/editor/composer/src/nsEditorShell.h @@ -218,20 +218,6 @@ class nsEditorShell : public nsIEditorShell, // Pointer to localized strings used for UI nsCOMPtr mStringBundle; - // Pointer to extra style sheets we load/unload - // for various Edit Modes or for Paragraph Marks - nsCOMPtr mEditModeStyleSheet; - nsCOMPtr mAllTagsModeStyleSheet; - nsCOMPtr mParagraphMarksStyleSheet; - - // The override style sheet that we never unload while editing - nsCOMPtr mBaseStyleSheet; - - // Saves the current display mode to reload style sheets - // after loading a url - PRInt32 mDisplayMode; - // We don't store the HTMLSource mode in mDisplayMode, - // so we need to track it separately PRBool mHTMLSourceMode; nsIDOMWindowInternal *mWebShellWindow; // weak reference diff --git a/mozilla/editor/idl/nsIEditorShell.idl b/mozilla/editor/idl/nsIEditorShell.idl index a029c5aa40f..a8a02bfc3e5 100644 --- a/mozilla/editor/idl/nsIEditorShell.idl +++ b/mozilla/editor/idl/nsIEditorShell.idl @@ -67,6 +67,11 @@ interface nsIEditorShell : nsISupports attribute nsIDOMWindowInternal contentWindow; attribute wstring editorType; attribute string contentsMIMEType; + + /** XXX Temporary: editorShell must know when we are in HTML Source mode + * for proper command disabling in nsComposerCommands.cpp + */ + attribute boolean HTMLSourceMode; readonly attribute nsIEditor editor; @@ -76,13 +81,6 @@ interface nsIEditorShell : nsISupports eDocumentStatusUnmodified, eDocumentStatusModified }; - - enum { - eDisplayModePreview, - eDisplayModeNormal, - eDisplayModeAllTags, - eDisplayModeSource - }; %} readonly attribute boolean documentModified; readonly attribute boolean documentIsEmpty; @@ -507,44 +505,6 @@ interface nsIEditorShell : nsISupports void ApplyStyleSheet(in wstring url); - /** Set the display mode for editing - * displayMode - * 0 (eDisplayModeWYSIWIG) Preview mode - * that looks exactly like the browser display except - * for certain behaviors like cursor style over links, etc. - * 1 (eDisplayModeNormal) Use minimal extra CSS style - * (from override styles in EditorContent.css) - * to show named anchors, table borders, etc for editing - * 2 (eDisplayModeAllTags) Use maximum extra CSS style - * (from override styles in EditorAllTags.css) - * to show icon for every HTML tag - */ - void SetDisplayMode(in PRInt32 displayMode); - - /** Get current mode for editing - * Returns: - * 0 (eDisplayModePreview,) - * 1 (eDisplayModeNormal) - * 2 (eDisplayModeAllTags) - * 3 (eDisplayModeSource) - */ - PRInt32 GetEditMode(); - - /** For quicker test if we are in HTML Source mode - */ - boolean IsHTMLSourceMode(); - - /** Save the current HTML source edit session - * by inserting it into the document, - * replacing existing DOM - */ - void FinishHTMLSource(); - - /** Add/remove an overridestyle sheet to show paragraph marks - * - */ - void DisplayParagraphMarks(in PRBool showMarks); - /* Output. * format is mime type, e.g. text/html; * See nsIEditor.h for legal flag values. diff --git a/mozilla/editor/idl/nsIEditorStyleSheets.idl b/mozilla/editor/idl/nsIEditorStyleSheets.idl index 22189579c10..cf4c4b8a1d3 100644 --- a/mozilla/editor/idl/nsIEditorStyleSheets.idl +++ b/mozilla/editor/idl/nsIEditorStyleSheets.idl @@ -49,45 +49,76 @@ class nsICSSStyleSheet; interface nsIEditorStyleSheets : nsISupports { - /** load and apply the style sheet, specified by aURL, to - * the editor's document. This can involve asynchronous - * network I/O + /** load and apply the style sheet, specified by aURL, to the + * editor's document, replacing the last style sheet added (if any). + * This can involve asynchronous network I/O. + * * @param aURL The style sheet to be loaded and applied. - * @return the style sheet created from aURL */ - [noscript] nsICSSStyleSheet applyStyleSheet(in AString aURL); + void replaceStyleSheet(in AString aURL); + + /** Add the given Style Sheet to the editor's document, + * on top of any that are already there. + * This is always synchronous. + * + * @param aURL The style sheet to be applied. + */ + void addStyleSheet(in AString aURL); + + /** load and apply the style sheet, specified by aURL, to the + * editor's document, replacing the last style sheet added (if any). + * This is always synchronous. + * + * @param aURL The style sheet to be loaded and applied. + */ + void replaceOverrideStyleSheet(in AString aURL); /** load and apply an Override style sheet, specified by aURL, to - * the editor's document. + * the editor's document, on top of any that are already there. * IMPORTANT: This is assumed to be synchronous: * URL is a local file with no @import used * This action is not undoable. * It is not intended for use by "user", only editor developers * to change display behavior for editing (like showing special cursors) * that will not be affected by loading other "document" style sheets - * loaded using ApplyStyleSheet. + * loaded using addStyleSheet or replaceStyleSheet. * * @param aURL The style sheet to be loaded and applied. - * @return the style sheet created from aURL */ - [noscript] nsICSSStyleSheet applyOverrideStyleSheet(in AString aURL); - - /** Add the given Style Sheet to the editor's document - * This is always synchronous - * @param aSheet The style sheet to be applied. - */ - [noscript] void addStyleSheet(in nsICSSStyleSheet aSheet); + void addOverrideStyleSheet(in AString aURL); /** Remove the given Style Sheet from the editor's document * This is always synchronous - * @param aSheet The style sheet to be removed + * + * @param aURL The style sheet to be removed */ - [noscript] void removeStyleSheet(in nsICSSStyleSheet aSheet); + void removeStyleSheet(in AString aURL); /** Remove the given Override Style Sheet from the editor's document * This is always synchronous - * @param aSheet The style sheet to be removed. + * + * @param aURL The style sheet to be removed. */ - [noscript] void removeOverrideStyleSheet(in nsICSSStyleSheet aSheet); + void removeOverrideStyleSheet(in AString aURL); + /** Enable or disable the given Style Sheet from the editor's document + * This is always synchronous + * + * @param aURL The style sheet to be removed + */ + void enableStyleSheet(in AString aURL, in PRBool aEnable); + + /** Get the nsICSSStyleSheet associated with the given URL. + * + * @param aURL The style sheet's URL + * @return the style sheet + */ + [noscript] nsICSSStyleSheet getStyleSheetForURL(in AString aURL); + + /** Get the URL associated with the given nsICSSStyleSheet. + * + * @param aStyleSheet The style sheet + * @return the style sheet's URL + */ + [noscript] AString getURLForStyleSheet(in nsICSSStyleSheet aStyleSheet); }; diff --git a/mozilla/editor/libeditor/base/nsEditor.h b/mozilla/editor/libeditor/base/nsEditor.h index eae2525acae..fe6ed3ec9f1 100644 --- a/mozilla/editor/libeditor/base/nsEditor.h +++ b/mozilla/editor/libeditor/base/nsEditor.h @@ -541,7 +541,6 @@ protected: nsIViewManager *mViewManager; PRInt32 mUpdateCount; nsCOMPtr mTxnMgr; - nsCOMPtr mLastStyleSheet; // is owning this dangerous? nsWeakPtr mPlaceHolderTxn; // weak reference to placeholder for begin/end batch purposes nsIAtom *mPlaceHolderName; // name of placeholder transaction PRInt32 mPlaceHolderBatch; // nesting count for batching diff --git a/mozilla/editor/libeditor/html/nsHTMLEditor.cpp b/mozilla/editor/libeditor/html/nsHTMLEditor.cpp index 0825bf51d5c..a5db2133db5 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditor.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLEditor.cpp @@ -3397,20 +3397,88 @@ nsHTMLEditor::GetLinkedObjects(nsISupportsArray** aNodeList) #pragma mark - #endif +NS_IMETHODIMP +nsHTMLEditor::AddStyleSheet(const nsAString &aURL) +{ + // Enable existing sheet if already loaded. + if (EnableExistingStyleSheet(aURL)) + return NS_OK; + + // Lose the previously-loaded sheet so there's nothing to replace + // This pattern is different from Override methods because + // we must wait to remove mLastStyleSheetURL and add new sheet + // at the same time (in StyleSheetLoaded callback) so they are undoable together + mLastStyleSheetURL.Truncate(); + return ReplaceStyleSheet(aURL); +} NS_IMETHODIMP -nsHTMLEditor::AddStyleSheet(nsICSSStyleSheet* aSheet) +nsHTMLEditor::ReplaceStyleSheet(const nsAString& aURL) { - AddStyleSheetTxn* txn; - nsresult rv = CreateTxnForAddStyleSheet(aSheet, &txn); + // Enable existing sheet if already loaded. + if (EnableExistingStyleSheet(aURL)) + { + // Disable last sheet if not the same as new one + if (!mLastStyleSheetURL.IsEmpty() && mLastStyleSheetURL.Equals(aURL)) + return EnableStyleSheet(mLastStyleSheetURL, PR_FALSE); + + return NS_OK; + } + + nsCOMPtr cssLoader; + nsresult rv = GetCSSLoader(aURL, getter_AddRefs(cssLoader)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr document; + if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED; + nsCOMPtr ps = do_QueryReferent(mPresShellWeak); + if (!ps) return NS_ERROR_NOT_INITIALIZED; + rv = ps->GetDocument(getter_AddRefs(document)); + NS_ENSURE_SUCCESS(rv, rv);; + if (!document) return NS_ERROR_NULL_POINTER; + + nsCOMPtr uaURI; + rv = NS_NewURI(getter_AddRefs(uaURI), aURL); + NS_ENSURE_SUCCESS(rv, rv); + + PRBool complete; + nsCOMPtr sheet; + rv = cssLoader->LoadAgentSheet(uaURI, *getter_AddRefs(sheet), + complete, this); + NS_ENSURE_SUCCESS(rv, rv); + + if (complete) + StyleSheetLoaded(sheet, PR_FALSE); + + // + // If not complete, we will be notified later + // with a call to StyleSheetLoaded() + // + + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLEditor::RemoveStyleSheet(const nsAString &aURL) +{ + nsCOMPtr sheet; + nsresult rv = GetStyleSheetForURL(aURL, getter_AddRefs(sheet)); + NS_ENSURE_SUCCESS(rv, rv); + if (!sheet) + return NS_ERROR_UNEXPECTED; + + RemoveStyleSheetTxn* txn; + rv = CreateTxnForRemoveStyleSheet(sheet, &txn); if (!txn) rv = NS_ERROR_NULL_POINTER; if (NS_SUCCEEDED(rv)) { rv = Do(txn); if (NS_SUCCEEDED(rv)) - { - mLastStyleSheet = do_QueryInterface(aSheet); // save it so we can remove before applying the next one - } + mLastStyleSheetURL.Truncate(); // forget it + + // Remove it from our internal list + rv = RemoveStyleSheetFromList(aURL); + NS_ENSURE_SUCCESS(rv, rv); } // The transaction system (if any) has taken ownwership of txns NS_IF_RELEASE(txn); @@ -3419,146 +3487,285 @@ nsHTMLEditor::AddStyleSheet(nsICSSStyleSheet* aSheet) } -NS_IMETHODIMP -nsHTMLEditor::RemoveStyleSheet(nsICSSStyleSheet* aSheet) +NS_IMETHODIMP +nsHTMLEditor::AddOverrideStyleSheet(const nsAString& aURL) { - RemoveStyleSheetTxn* txn; - nsresult rv = CreateTxnForRemoveStyleSheet(aSheet, &txn); - if (!txn) rv = NS_ERROR_NULL_POINTER; - if (NS_SUCCEEDED(rv)) + // Enable existing sheet if already loaded. + if (EnableExistingStyleSheet(aURL)) + return NS_OK; + + nsCOMPtr cssLoader; + nsresult rv = GetCSSLoader(aURL, getter_AddRefs(cssLoader)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr uaURI; + rv = NS_NewURI(getter_AddRefs(uaURI), aURL); + NS_ENSURE_SUCCESS(rv, rv); + + // We use null for the callback and data pointer because + // we MUST ONLY load synchronous local files (no @import) + PRBool complete; + nsCOMPtr sheet; + rv = cssLoader->LoadAgentSheet(uaURI, *getter_AddRefs(sheet), + complete, nsnull); + + // Synchronous loads should ALWAYS return completed + if (!complete || !sheet) + return NS_ERROR_NULL_POINTER; + + nsCOMPtr styleSheet; + styleSheet = do_QueryInterface(sheet); + nsCOMPtr styleSet; + + nsCOMPtr ps = do_QueryReferent(mPresShellWeak); + if (!ps) + return NS_ERROR_NOT_INITIALIZED; + rv = ps->GetStyleSet(getter_AddRefs(styleSet)); + NS_ENSURE_SUCCESS(rv, rv); + if (!styleSet) + return NS_ERROR_NULL_POINTER; + + // Add the override style sheet + // (This checks if already exists) + styleSet->AppendOverrideStyleSheet(styleSheet); + + // Save doc pointer to be able to use nsIStyleSheet::SetEnabled() + nsCOMPtr document; + rv = ps->GetDocument(getter_AddRefs(document)); + if (NS_FAILED(rv)) + return rv; + if (!document) + return NS_ERROR_NULL_POINTER; + styleSheet->SetOwningDocument(document); + + // This notifies document observers to rebuild all frames + // (this doesn't affect style sheet because it is not a doc sheet) + document->SetStyleSheetDisabledState(styleSheet, PR_FALSE); + + // Save as the last-loaded sheet + mLastOverrideStyleSheetURL = aURL; + + //Add URL and style sheet to our lists + return AddNewStyleSheetToList(aURL, sheet); +} + +NS_IMETHODIMP +nsHTMLEditor::ReplaceOverrideStyleSheet(const nsAString& aURL) +{ + // Enable existing sheet if already loaded. + if (EnableExistingStyleSheet(aURL)) { - rv = Do(txn); - if (NS_SUCCEEDED(rv)) - { - mLastStyleSheet = nsnull; // forget it - } + // Disable last sheet if not the same as new one + if (!mLastOverrideStyleSheetURL.IsEmpty() && !mLastOverrideStyleSheetURL.Equals(aURL)) + return EnableStyleSheet(mLastOverrideStyleSheetURL, PR_FALSE); + + return NS_OK; } - // The transaction system (if any) has taken ownwership of txns - NS_IF_RELEASE(txn); - - return rv; + // Remove the previous sheet + if (!mLastOverrideStyleSheetURL.IsEmpty()) + RemoveOverrideStyleSheet(mLastOverrideStyleSheetURL); + + return AddOverrideStyleSheet(aURL); } // Do NOT use transaction system for override style sheets NS_IMETHODIMP -nsHTMLEditor::RemoveOverrideStyleSheet(nsICSSStyleSheet* aSheet) +nsHTMLEditor::RemoveOverrideStyleSheet(const nsAString &aURL) { + nsCOMPtr sheet; + nsresult rv = GetStyleSheetForURL(aURL, getter_AddRefs(sheet)); + NS_ENSURE_SUCCESS(rv, rv); + if (!sheet) + return NS_OK; /// Don't fail if sheet not found + if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED; nsCOMPtr ps = do_QueryReferent(mPresShellWeak); if (!ps) return NS_ERROR_NOT_INITIALIZED; nsCOMPtr document; - nsresult rv = ps->GetDocument(getter_AddRefs(document)); - if (NS_FAILED(rv)) return rv; + rv = ps->GetDocument(getter_AddRefs(document)); + NS_ENSURE_SUCCESS(rv, rv);; if (!document) return NS_ERROR_NULL_POINTER; nsCOMPtr styleSet; rv = ps->GetStyleSet(getter_AddRefs(styleSet)); - - if (NS_FAILED(rv)) return rv; + NS_ENSURE_SUCCESS(rv, rv); if (!styleSet) return NS_ERROR_NULL_POINTER; - nsCOMPtr styleSheet = do_QueryInterface(aSheet); + + nsCOMPtr styleSheet = do_QueryInterface(sheet); if (!styleSheet) return NS_ERROR_NULL_POINTER; + styleSet->RemoveOverrideStyleSheet(styleSheet); // This notifies document observers to rebuild all frames // (this doesn't affect style sheet because it is not a doc sheet) document->SetStyleSheetDisabledState(styleSheet, PR_FALSE); + // Remove it from our internal list + return RemoveStyleSheetFromList(aURL); +} + +NS_IMETHODIMP +nsHTMLEditor::EnableStyleSheet(const nsAString &aURL, PRBool aEnable) +{ + nsCOMPtr sheet; + nsresult rv = GetStyleSheetForURL(aURL, getter_AddRefs(sheet)); + NS_ENSURE_SUCCESS(rv, rv); + if (!sheet) + return NS_OK; // Don't fail if sheet not found + + nsCOMPtr nsISheet = do_QueryInterface(sheet); + return nsISheet->SetEnabled(aEnable); +} + + +PRBool +nsHTMLEditor::EnableExistingStyleSheet(const nsAString &aURL) +{ + nsCOMPtr sheet; + nsresult rv = GetStyleSheetForURL(aURL, getter_AddRefs(sheet)); + NS_ENSURE_SUCCESS(rv, rv); + + // Enable sheet if already loaded. + if (sheet) + { + nsCOMPtr nsISheet = do_QueryInterface(sheet); + nsISheet->SetEnabled(PR_TRUE); + return PR_TRUE; + } + return PR_FALSE; +} + +nsresult +nsHTMLEditor::EnsureStyleSheetArrays() +{ + nsresult rv = NS_OK; + if (!mStyleSheets) + rv = NS_NewISupportsArray(getter_AddRefs(mStyleSheets)); + + return rv; +} + +nsresult +nsHTMLEditor::AddNewStyleSheetToList(const nsAString &aURL, + nsICSSStyleSheet *aStyleSheet) +{ + PRUint32 countSS; + nsresult rv = mStyleSheets->Count(&countSS); + NS_ENSURE_SUCCESS(rv, rv); + + PRInt32 countU = mStyleSheetURLs.Count(); + + if (countU < 0 || countSS != (PRUint32)countU) + return NS_ERROR_UNEXPECTED; + + if (!mStyleSheetURLs.AppendString(aURL)) + return NS_ERROR_UNEXPECTED; + + return mStyleSheets->AppendElement(aStyleSheet); +} + +nsresult +nsHTMLEditor::RemoveStyleSheetFromList(const nsAString &aURL) +{ + nsresult rv = EnsureStyleSheetArrays(); + NS_ENSURE_SUCCESS(rv, rv); + + // is it already in the list? + PRInt32 foundIndex; + foundIndex = mStyleSheetURLs.IndexOf(aURL); + if (foundIndex < 0) + return NS_ERROR_FAILURE; + + // Attempt both removals; if one fails there's not much we can do. + if (!mStyleSheets->RemoveElementAt(foundIndex)) + rv = NS_ERROR_FAILURE; + if (!mStyleSheetURLs.RemoveStringAt(foundIndex)) + rv = NS_ERROR_FAILURE; + + return rv; +} + +NS_IMETHODIMP +nsHTMLEditor::GetStyleSheetForURL(const nsAString &aURL, + nsICSSStyleSheet **aStyleSheet) +{ + NS_ENSURE_ARG_POINTER(aStyleSheet); + *aStyleSheet = 0; + nsresult rv = EnsureStyleSheetArrays(); + NS_ENSURE_SUCCESS(rv, rv); + + // is it already in the list? + PRInt32 foundIndex; + foundIndex = mStyleSheetURLs.IndexOf(aURL); + if (foundIndex < 0) + return NS_OK; //No sheet -- don't fail! + + *aStyleSheet = (nsICSSStyleSheet*)mStyleSheets->ElementAt(foundIndex); + if (!*aStyleSheet) + return NS_ERROR_FAILURE; + + NS_ADDREF(*aStyleSheet); return NS_OK; } -NS_IMETHODIMP -nsHTMLEditor::ApplyOverrideStyleSheet(const nsAString& aURL, nsICSSStyleSheet **aStyleSheet) +NS_IMETHODIMP +nsHTMLEditor::GetURLForStyleSheet(nsICSSStyleSheet *aStyleSheet, + nsAString &aURL) { - return ApplyDocumentOrOverrideStyleSheet(aURL, PR_TRUE, aStyleSheet); + nsresult rv = EnsureStyleSheetArrays(); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr iSupports = do_QueryInterface(aStyleSheet, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + // is it already in the list? + PRInt32 foundIndex; + rv = mStyleSheets->GetIndexOf(iSupports, &foundIndex); + NS_ENSURE_SUCCESS(rv, rv); + + // Don't fail if we don't find it in our list + if (foundIndex == -1) + return NS_OK; + + // Found it in the list! + nsAString* strp = mStyleSheetURLs.StringAt(foundIndex); + if (!strp) + return NS_ERROR_UNEXPECTED; + aURL = *strp; + return NS_OK; } -NS_IMETHODIMP -nsHTMLEditor::ApplyStyleSheet(const nsAString& aURL, nsICSSStyleSheet **aStyleSheet) +nsresult +nsHTMLEditor::GetCSSLoader(const nsAString& aURL, nsICSSLoader** aCSSLoader) { - return ApplyDocumentOrOverrideStyleSheet(aURL, PR_FALSE, aStyleSheet); -} + if (!aCSSLoader) + return NS_ERROR_NULL_POINTER; + *aCSSLoader = 0; -//Note: Loading a document style sheet is undoable, loading an override sheet is not -nsresult -nsHTMLEditor::ApplyDocumentOrOverrideStyleSheet(const nsAString& aURL, PRBool aOverride, nsICSSStyleSheet **aStyleSheet) -{ - nsresult rv = NS_OK; - nsCOMPtr uaURL; + nsresult rv; - rv = NS_NewURI(getter_AddRefs(uaURL), aURL); + nsCOMPtr document; - if (NS_SUCCEEDED(rv)) { - nsCOMPtr document; + if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED; + nsCOMPtr ps = do_QueryReferent(mPresShellWeak); + if (!ps) return NS_ERROR_NOT_INITIALIZED; + rv = ps->GetDocument(getter_AddRefs(document)); + NS_ENSURE_SUCCESS(rv, rv);; + if (!document) return NS_ERROR_NULL_POINTER; - if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED; - nsCOMPtr ps = do_QueryReferent(mPresShellWeak); - if (!ps) return NS_ERROR_NOT_INITIALIZED; - rv = ps->GetDocument(getter_AddRefs(document)); - if (NS_FAILED(rv)) return rv; - if (!document) return NS_ERROR_NULL_POINTER; - - nsCOMPtr container = do_QueryInterface(document); - if (!container) return NS_ERROR_NULL_POINTER; + nsCOMPtr container = do_QueryInterface(document); + if (!container) return NS_ERROR_NULL_POINTER; - nsCOMPtr cssLoader; - nsCOMPtr cssStyleSheet; + nsCOMPtr cssLoader; + nsCOMPtr cssStyleSheet; - rv = container->GetCSSLoader(*getter_AddRefs(cssLoader)); - if (NS_FAILED(rv)) return rv; - if (!cssLoader) return NS_ERROR_NULL_POINTER; - - PRBool complete; - - if (aOverride) - { - // We use null for the callback and data pointer because - // we MUST ONLY load synchronous local files (no @import) - rv = cssLoader->LoadAgentSheet(uaURL, *getter_AddRefs(cssStyleSheet), complete, - nsnull); - - // Synchronous loads should ALWAYS return completed - if (!complete || !cssStyleSheet) - return NS_ERROR_NULL_POINTER; - - nsCOMPtr styleSheet; - styleSheet = do_QueryInterface(cssStyleSheet); - nsCOMPtr styleSet; - rv = ps->GetStyleSet(getter_AddRefs(styleSet)); - if (NS_FAILED(rv)) return rv; - if (!styleSet) return NS_ERROR_NULL_POINTER; - - // Add the override style sheet - // (This checks if already exists) - styleSet->AppendOverrideStyleSheet(styleSheet); - // Save doc pointer to be able to use nsIStyleSheet::SetEnabled() - styleSheet->SetOwningDocument(document); - - // This notifies document observers to rebuild all frames - // (this doesn't affect style sheet because it is not a doc sheet) - document->SetStyleSheetDisabledState(styleSheet, PR_FALSE); - } - else - { - rv = cssLoader->LoadAgentSheet(uaURL, *getter_AddRefs(cssStyleSheet), complete, - this); - if (NS_FAILED(rv)) return rv; - if (complete) - ApplyStyleSheetToPresShellDocument(cssStyleSheet,this); - - // - // If not complete, we will be notified later - // with a call to ApplyStyleSheetToPresShellDocument(). - // - } - if (aStyleSheet) - { - *aStyleSheet = cssStyleSheet; - NS_ADDREF(*aStyleSheet); - } - } - return rv; + rv = container->GetCSSLoader(*getter_AddRefs(cssLoader)); + NS_ENSURE_SUCCESS(rv, rv);; + if (!cssLoader) return NS_ERROR_NULL_POINTER; + *aCSSLoader = cssLoader; + NS_ADDREF(*aCSSLoader); + return NS_OK; } #ifdef XP_MAC @@ -3901,44 +4108,47 @@ nsHTMLEditor::GetReconversionString(nsReconversionEventReply* aReply) #endif -NS_IMETHODIMP -nsHTMLEditor::ReplaceStyleSheet(nsICSSStyleSheet *aNewSheet) -{ - nsresult rv = NS_OK; - - nsAutoEditBatch batchIt(this); - - if (mLastStyleSheet) - { - rv = RemoveStyleSheet(mLastStyleSheet); - //XXX: rv is ignored here, why? - } - - rv = AddStyleSheet(aNewSheet); - - return rv; -} - NS_IMETHODIMP -nsHTMLEditor::StyleSheetLoaded(nsICSSStyleSheet*aSheet, PRBool aNotify) -{ - ApplyStyleSheetToPresShellDocument(aSheet, this); - return NS_OK; -} - -/* static callback */ -void nsHTMLEditor::ApplyStyleSheetToPresShellDocument(nsICSSStyleSheet* aSheet, void *aData) +nsHTMLEditor::StyleSheetLoaded(nsICSSStyleSheet* aSheet, PRBool aNotify) { nsresult rv = NS_OK; + nsAutoEditBatch batchIt(this); - nsHTMLEditor *editor = NS_STATIC_CAST(nsHTMLEditor*, aData); - if (editor) + if (!mLastStyleSheetURL.IsEmpty()) + RemoveStyleSheet(mLastStyleSheetURL); + + AddStyleSheetTxn* txn; + rv = CreateTxnForAddStyleSheet(aSheet, &txn); + if (!txn) rv = NS_ERROR_NULL_POINTER; + if (NS_SUCCEEDED(rv)) { - rv = editor->ReplaceStyleSheet(aSheet); - } - // XXX: we lose the return value here. Set a flag in the editor? -} + rv = Do(txn); + if (NS_SUCCEEDED(rv)) + { + // Get the URI, then url spec from the sheet + nsCOMPtr sheet = do_QueryInterface(aSheet); + nsCOMPtr uri; + rv = sheet->GetURL(*getter_AddRefs(uri)); + if (NS_FAILED(rv)) + return rv; + nsCAutoString spec; + rv = uri->GetSpec(spec); + if (NS_FAILED(rv)) + return rv; + + // Save it so we can remove before applying the next one + mLastStyleSheetURL.AssignWithConversion(spec.get()); + + // Also save in our arrays of urls and sheets + AddNewStyleSheetToList(mLastStyleSheetURL, aSheet); + } + } + // The transaction system (if any) has taken ownwership of txns + NS_IF_RELEASE(txn); + + return NS_OK; +} #ifdef XP_MAC #pragma mark - diff --git a/mozilla/editor/libeditor/html/nsHTMLEditor.h b/mozilla/editor/libeditor/html/nsHTMLEditor.h index 75a86dcce77..d385e2e6d3e 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditor.h +++ b/mozilla/editor/libeditor/html/nsHTMLEditor.h @@ -63,6 +63,8 @@ #include "nsHTMLCSSUtils.h" #include "nsIParserService.h" +#include "nsVoidArray.h" + class nsIDOMKeyEvent; class nsITransferable; class nsIDOMEventReceiver; @@ -206,15 +208,15 @@ public: /* ------------ nsIEditorStyleSheets methods -------------- */ - NS_IMETHOD ApplyStyleSheet(const nsAString & aURL, nsICSSStyleSheet **aStyleSheet); - NS_IMETHOD ApplyOverrideStyleSheet(const nsAString & aURL, nsICSSStyleSheet **aStyleSheet); - /* Above 2 methods call this with appropriate aOverride value - * Not exposed to IDL interface - */ - nsresult ApplyDocumentOrOverrideStyleSheet(const nsAString & aURL, PRBool aOverride, nsICSSStyleSheet **aStyleSheet); - NS_IMETHOD AddStyleSheet(nsICSSStyleSheet* aSheet); - NS_IMETHOD RemoveStyleSheet(nsICSSStyleSheet* aSheet); - NS_IMETHOD RemoveOverrideStyleSheet(nsICSSStyleSheet* aSheet); + NS_IMETHOD AddStyleSheet(const nsAString & aURL); + NS_IMETHOD ReplaceStyleSheet(const nsAString& aURL); + NS_IMETHOD RemoveStyleSheet(const nsAString &aURL); + + NS_IMETHOD AddOverrideStyleSheet(const nsAString & aURL); + NS_IMETHOD ReplaceOverrideStyleSheet(const nsAString& aURL); + NS_IMETHOD RemoveOverrideStyleSheet(const nsAString &aURL); + + NS_IMETHOD EnableStyleSheet(const nsAString& aURL, PRBool aEnable); /* ------------ nsIEditorMailSupport methods -------------- */ @@ -451,6 +453,25 @@ public: PRBool aListOrCellNotEmpty, PRBool aSafeToAskFrames, PRBool *aSeenBR); + + // Stylesheet-related methods that aren't part of nsIEditorStyleSheets. + nsresult AddCSSStyleSheet(nsICSSStyleSheet* aSheet); + nsresult GetCSSLoader(const nsAString& aURL, nsICSSLoader** aCSSLoader); + + // Returns TRUE if sheet was loaded, false if it wasn't + PRBool EnableExistingStyleSheet(const nsAString& aURL); + + // Dealing with the internal style sheet lists: + nsresult EnsureStyleSheetArrays(); + NS_IMETHOD GetStyleSheetForURL(const nsAString &aURL, + nsICSSStyleSheet **_retval); + NS_IMETHOD GetURLForStyleSheet(nsICSSStyleSheet *aStyleSheet, nsAString &aURL); + + // Add a url + known style sheet to the internal lists: + nsresult AddNewStyleSheetToList(const nsAString &aURL, + nsICSSStyleSheet *aStyleSheet); + + nsresult RemoveStyleSheetFromList(const nsAString &aURL); protected: @@ -471,13 +492,6 @@ protected: */ NS_IMETHOD GetLayoutObject(nsIDOMNode *aInNode, nsISupports **aOutLayoutObject); - /* StyleSheet load callback */ - static void ApplyStyleSheetToPresShellDocument(nsICSSStyleSheet* aSheet, void *aData); - - /* remove the old style sheet, and apply the supplied one */ - NS_IMETHOD ReplaceStyleSheet(nsICSSStyleSheet *aNewSheet); - - // Return TRUE if aElement is a table-related elemet and caret was set PRBool SetCaretInTableCell(nsIDOMElement* aElement); PRBool IsElementInBody(nsIDOMElement* aElement); @@ -767,14 +781,25 @@ protected: PRBool mCachedUnderlineStyle; nsString mCachedFontName; + // Used to disable HTML formatting commands during HTML source editing + PRBool mCanEditHTML; + // Used by GetFirstSelectedCell and GetNextSelectedCell PRInt32 mSelectedCellIndex; nsCOMPtr mRangeHelper; + nsString mLastStyleSheetURL; + nsString mLastOverrideStyleSheetURL; + PRBool mCSSAware; nsHTMLCSSUtils *mHTMLCSSUtils; + // Maintain a list of associated style sheets and their urls. + nsStringArray mStyleSheetURLs; + nsCOMPtr mStyleSheets; + PRInt32 mNumStyleSheets; + // Maintain a static parser service ... static nsCOMPtr sParserService; // ... which means that we need an instance count to know when to delete it diff --git a/mozilla/editor/ui/composer/content/ComposerCommands.js b/mozilla/editor/ui/composer/content/ComposerCommands.js index 740ffff065c..ddca01b4a9a 100644 --- a/mozilla/editor/ui/composer/content/ComposerCommands.js +++ b/mozilla/editor/ui/composer/content/ComposerCommands.js @@ -2121,7 +2121,7 @@ var nsRevertCommand = // Reload page if first button (Revert) was pressed if(result == 0) { - SetEditMode(PreviousNonSourceDisplayMode); + SetEditMode(gPreviousNonSourceDisplayMode); window.editorShell.LoadUrl(GetDocumentUrl()); } } @@ -3222,7 +3222,7 @@ var nsHTMLSourceModeCommand = { isCommandEnabled: function(aCommand, dummy) { - return (window.editorShell && window.editorShell.documentEditable && gIsHTMLEditor); + return (window.editorShell && window.editorShell.documentEditable && isHTMLEditor()); }, getCommandStateParams: function(aCommand, aParams, aRefCon) {}, @@ -3230,8 +3230,8 @@ var nsHTMLSourceModeCommand = doCommand: function(aCommand) { - if (gEditorDisplayMode != DisplayModeSource) - SetEditMode(DisplayModeSource); + if (gEditorDisplayMode != gDisplayModeSource) + SetEditMode(gDisplayModeSource); } }; @@ -3239,7 +3239,7 @@ var nsPreviewModeCommand = { isCommandEnabled: function(aCommand, dummy) { - return (window.editorShell && window.editorShell.documentEditable && gIsHTMLEditor); + return (window.editorShell && window.editorShell.documentEditable && isHTMLEditor()); }, getCommandStateParams: function(aCommand, aParams, aRefCon) {}, @@ -3248,8 +3248,8 @@ var nsPreviewModeCommand = doCommand: function(aCommand) { FinishHTMLSource(); - if (gEditorDisplayMode != DisplayModePreview) - SetEditMode(DisplayModePreview); + if (gEditorDisplayMode != gDisplayModePreview) + SetEditMode(gDisplayModePreview); } }; diff --git a/mozilla/editor/ui/composer/content/editor.js b/mozilla/editor/ui/composer/content/editor.js index d707e37f773..e06243f3543 100644 --- a/mozilla/editor/ui/composer/content/editor.js +++ b/mozilla/editor/ui/composer/content/editor.js @@ -46,15 +46,18 @@ var gEditor; var editorShell; // XXX THIS NEEDS TO DIE var documentModified; var prefAuthorString = ""; -var NormalMode = 1; -var PreviewMode = 2; + // These must match enums in nsIEditorShell.idl: -var DisplayModePreview = 0; -var DisplayModeNormal = 1; -var DisplayModeAllTags = 2; -var DisplayModeSource = 3; -var PreviousNonSourceDisplayMode = 1; -var gEditorDisplayMode = 1; // Normal Editor mode +const gDisplayModePreview = 0; +const gDisplayModeNormal = 1; +const gDisplayModeAllTags = 2; +const gDisplayModeSource = 3; +const gNormalStyleSheet = "chrome://editor/content/EditorContent.css"; +const gAllTagsStyleSheet = "chrome://editor/content/EditorAllTags.css"; +const gParagraphMarksStyleSheet = "chrome://editor/content/EditorParagraphMarks.css"; + +var gPreviousNonSourceDisplayMode = 1; +var gEditorDisplayMode = -1; var WebCompose = false; // Set true for Web Composer, leave false for Messenger Composer var docWasModified = false; // Check if clean document, if clean then unload when user "Opens" var gContentWindow = 0; @@ -195,7 +198,7 @@ function PageIsEmptyAndUntouched() function IsInHTMLSourceMode() { - return (gEditorDisplayMode == DisplayModeSource); + return (gEditorDisplayMode == gDisplayModeSource); } // are we editing HTML (i.e. neither in HTML source mode, nor editing a text file) @@ -347,6 +350,9 @@ var DocumentStateListener = // Add mouse click watcher if right type of editor if (isHTMLEditor()) addEditorClickEventListener(); + + // Start in "Normal" edit mode + SetDisplayMode(gDisplayModeNormal); }, // note that the editor seems to be gone at this point @@ -1429,7 +1435,7 @@ function EditorClick(event) // In Show All Tags Mode, // single click selects entire element, // except for body and table elements - if (event.target && isHTMLEditor() && gEditorDisplayMode == DisplayModeAllTags) + if (event.target && isHTMLEditor() && gEditorDisplayMode == gDisplayModeAllTags) { try { @@ -1517,7 +1523,7 @@ function SetEditMode(mode) if (!SetDisplayMode(mode)) return; - if (mode == DisplayModeSource) + if (mode == gDisplayModeSource) { // Display the DOCTYPE as a non-editable string above edit area var domdoc; @@ -1564,7 +1570,7 @@ function SetEditMode(mode) gSourceContentWindow.addEventListener("input", oninputHTMLSource, false); gHTMLSourceChanged = false; } - else if (previousMode == DisplayModeSource) + else if (previousMode == gDisplayModeSource) { // Only rebuild document if a change was made in source window if (gHTMLSourceChanged) @@ -1650,7 +1656,7 @@ function CancelHTMLSource() // Don't convert source text back into the DOM document gSourceContentWindow.value = ""; gHTMLSourceChanged = false; - SetDisplayMode(PreviousNonSourceDisplayMode); + SetDisplayMode(gPreviousNonSourceDisplayMode); } function FinishHTMLSource() @@ -1667,8 +1673,8 @@ function FinishHTMLSource() { AlertWithTitle(GetString("Alert"), GetString("NoHeadTag")); //cheat to force back to Source Mode - gEditorDisplayMode = DisplayModePreview; - SetDisplayMode(DisplayModeSource); + gEditorDisplayMode = gDisplayModePreview; + SetDisplayMode(gDisplayModeSource); throw Components.results.NS_ERROR_FAILURE; } @@ -1677,15 +1683,15 @@ function FinishHTMLSource() { AlertWithTitle(GetString("Alert"), GetString("NoBodyTag")); //cheat to force back to Source Mode - gEditorDisplayMode = DisplayModePreview; - SetDisplayMode(DisplayModeSource); + gEditorDisplayMode = gDisplayModePreview; + SetDisplayMode(gDisplayModeSource); throw Components.results.NS_ERROR_FAILURE; } } } // Switch edit modes -- converts source back into DOM document - SetEditMode(PreviousNonSourceDisplayMode); + SetEditMode(gPreviousNonSourceDisplayMode); } function CollapseItem(id, collapse) @@ -1710,23 +1716,49 @@ function SetDisplayMode(mode) gEditorDisplayMode = mode; - // Save the last non-source mode so we can cancel source editing easily - if (mode != DisplayModeSource) - PreviousNonSourceDisplayMode = mode; + // Load/unload appropriate override style sheet + try { + var editor = GetCurrentEditor(); - // Editorshell does the style sheet loading/unloading - editorShell.SetDisplayMode(mode); + if (mode == gDisplayModePreview) + { + // Disable all extra "edit mode" style sheets + editor.enableStyleSheet(gNormalStyleSheet, false); + editor.enableStyleSheet(gAllTagsStyleSheet, false); + } + else if (mode == gDisplayModeNormal) + { + editor.addOverrideStyleSheet(gNormalStyleSheet); + + // Disable ShowAllTags mode if that was the previous mode + if (gPreviousNonSourceDisplayMode == gDisplayModeAllTags) + editor.enableStyleSheet(gAllTagsStyleSheet, false); + } + else if (mode == gDisplayModeAllTags) + { + editor.addOverrideStyleSheet(gNormalStyleSheet); + editor.addOverrideStyleSheet(gAllTagsStyleSheet); + } + } catch(e) {} + + //XXX We still have to tell editorShell if we are in HTMLSource mode + // because commands in nsComposerCommands.cpp can't access JS command results yet + editorShell.HTMLSourceMode = (mode == gDisplayModeSource); + + // Save the last non-source mode so we can cancel source editing easily + if (mode != gDisplayModeSource) + gPreviousNonSourceDisplayMode = mode; // Set the UI states var selectedTab = null; - if (mode == DisplayModePreview) selectedTab = gPreviewModeButton; - if (mode == DisplayModeNormal) selectedTab = gNormalModeButton; - if (mode == DisplayModeAllTags) selectedTab = gTagModeButton; - if (mode == DisplayModeSource) selectedTab = gSourceModeButton; + if (mode == gDisplayModePreview) selectedTab = gPreviewModeButton; + if (mode == gDisplayModeNormal) selectedTab = gNormalModeButton; + if (mode == gDisplayModeAllTags) selectedTab = gTagModeButton; + if (mode == gDisplayModeSource) selectedTab = gSourceModeButton; if (selectedTab) document.getElementById("EditModeTabs").selectedItem = selectedTab; - if (mode == DisplayModeSource) + if (mode == gDisplayModeSource) { // Switch to the sourceWindow (second in the deck) gContentWindowDeck.setAttribute("selectedIndex","1"); @@ -1766,16 +1798,16 @@ function SetDisplayMode(mode) var menuID; switch(mode) { - case DisplayModePreview: + case gDisplayModePreview: menuID = "viewPreviewMode"; break; - case DisplayModeNormal: + case gDisplayModeNormal: menuID = "viewNormalMode"; break; - case DisplayModeAllTags: + case gDisplayModeAllTags: menuID = "viewAllTagsMode"; break; - case DisplayModeSource: + case gDisplayModeSource: menuID = "viewSourceMode"; break; } @@ -1795,8 +1827,10 @@ function EditorToggleParagraphMarks() // so if "checked" is true now, it was just switched to that mode var checked = menuItem.getAttribute("checked"); try { - // XXX There's no non-editorshell equivalent yet for this: - editorShell.DisplayParagraphMarks(checked == "true"); + if (checked == "true") + GetCurrentEditor().addOverrideStyleSheet(gParagraphMarksStyleSheet); + else + GetCurrentEditor().enableStyleSheet(gParagraphMarksStyleSheet, false); } catch(e) { return; } }