Bug 1470361: Remove nsIEditorStyleSheets.addStyleSheet / removeStyleSheet / replaceStyleSheet. r=m_kato

These are effectively equivalent to appending a <link> element to the body, are
not unused, and bring in a fair amount of complexity because even though they're
owned by the document and stored in the document's mStyleSheets, they're not
owned by it per se, which causes confusion.

Unless I've missed something, both bluegriffon and common-central use the
*Override APIs, which this patch leaves untouched.

MozReview-Commit-ID: EOSMOHj3A95
This commit is contained in:
Emilio Cobos Álvarez 2018-06-22 05:41:22 +02:00
parent 27ef769d59
commit 6a2e3606ae
10 changed files with 1 additions and 461 deletions

View file

@ -25,7 +25,6 @@
#include "JoinNodeTransaction.h" // for JoinNodeTransaction
#include "PlaceholderTransaction.h" // for PlaceholderTransaction
#include "SplitNodeTransaction.h" // for SplitNodeTransaction
#include "StyleSheetTransactions.h" // for AddStyleSheetTransaction, etc.
#include "TextEditUtils.h" // for TextEditUtils
#include "mozilla/CheckedInt.h" // for CheckedInt
#include "mozilla/ComputedStyle.h" // for ComputedStyle

View file

@ -51,7 +51,6 @@ class nsIWidget;
class nsRange;
namespace mozilla {
class AddStyleSheetTransaction;
class AutoSelectionRestorer;
class AutoTopLevelEditSubActionNotifier;
class AutoTransactionsConserveSelection;
@ -73,7 +72,6 @@ class InsertNodeTransaction;
class InsertTextTransaction;
class JoinNodeTransaction;
class PlaceholderTransaction;
class RemoveStyleSheetTransaction;
class SplitNodeResult;
class SplitNodeTransaction;
class TextComposition;

View file

@ -22,7 +22,6 @@
#include "HTMLEditRules.h"
#include "HTMLEditUtils.h"
#include "HTMLURIRefObject.h"
#include "StyleSheetTransactions.h"
#include "TextEditUtils.h"
#include "TypeInState.h"
@ -270,7 +269,6 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(HTMLEditor)
NS_INTERFACE_MAP_ENTRY(nsIHTMLInlineTableEditor)
NS_INTERFACE_MAP_ENTRY(nsITableEditor)
NS_INTERFACE_MAP_ENTRY(nsIEditorStyleSheets)
NS_INTERFACE_MAP_ENTRY(nsICSSLoaderObserver)
NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
NS_INTERFACE_MAP_END_INHERITING(TextEditor)
@ -2915,74 +2913,6 @@ HTMLEditor::GetLinkedObjects(nsIArray** aNodeList)
}
NS_IMETHODIMP
HTMLEditor::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
HTMLEditor::ReplaceStyleSheet(const nsAString& aURL)
{
// 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, false);
}
return NS_OK;
}
// Make sure the pres shell doesn't disappear during the load.
if (NS_WARN_IF(!IsInitialized())) {
return NS_ERROR_NOT_INITIALIZED;
}
nsCOMPtr<nsIPresShell> ps = GetPresShell();
NS_ENSURE_TRUE(ps, NS_ERROR_NOT_INITIALIZED);
nsCOMPtr<nsIURI> uaURI;
nsresult rv = NS_NewURI(getter_AddRefs(uaURI), aURL);
NS_ENSURE_SUCCESS(rv, rv);
return ps->GetDocument()->CSSLoader()->LoadSheet(
uaURI, false, nullptr, nullptr, this);
}
NS_IMETHODIMP
HTMLEditor::RemoveStyleSheet(const nsAString& aURL)
{
return RemoveStyleSheetWithTransaction(aURL);
}
nsresult
HTMLEditor::RemoveStyleSheetWithTransaction(const nsAString& aURL)
{
RefPtr<StyleSheet> sheet = GetStyleSheetForURL(aURL);
if (NS_WARN_IF(!sheet)) {
return NS_ERROR_UNEXPECTED;
}
RefPtr<RemoveStyleSheetTransaction> transaction =
RemoveStyleSheetTransaction::Create(*this, *sheet);
nsresult rv = DoTransaction(transaction);
if (NS_SUCCEEDED(rv)) {
mLastStyleSheetURL.Truncate(); // forget it
}
// Remove it from our internal list
return RemoveStyleSheetFromList(aURL);
}
NS_IMETHODIMP
HTMLEditor::AddOverrideStyleSheet(const nsAString& aURL)
{
@ -3068,8 +2998,7 @@ HTMLEditor::RemoveOverrideStyleSheet(const nsAString& aURL)
}
NS_IMETHODIMP
HTMLEditor::EnableStyleSheet(const nsAString& aURL,
bool aEnable)
HTMLEditor::EnableStyleSheet(const nsAString& aURL, bool aEnable)
{
RefPtr<StyleSheet> sheet = GetStyleSheetForURL(aURL);
NS_ENSURE_TRUE(sheet, NS_OK); // Don't fail if sheet not found
@ -3466,37 +3395,6 @@ HTMLEditor::DebugUnitTests(int32_t* outNumTests,
#endif
}
NS_IMETHODIMP
HTMLEditor::StyleSheetLoaded(StyleSheet* aSheet,
bool aWasDeferred,
nsresult aStatus)
{
AutoPlaceholderBatch batchIt(this);
if (!mLastStyleSheetURL.IsEmpty()) {
RemoveStyleSheetWithTransaction(mLastStyleSheetURL);
}
RefPtr<AddStyleSheetTransaction> transaction =
AddStyleSheetTransaction::Create(*this, *aSheet);
nsresult rv = DoTransaction(transaction);
if (NS_SUCCEEDED(rv)) {
// Get the URI, then url spec from the sheet
nsAutoCString spec;
rv = aSheet->GetSheetURI()->GetSpec(spec);
if (NS_SUCCEEDED(rv)) {
// Save it so we can remove before applying the next one
CopyASCIItoUTF16(spec, mLastStyleSheetURL);
// Also save in our arrays of urls and sheets
AddNewStyleSheetToList(mLastStyleSheetURL, aSheet);
}
}
return NS_OK;
}
void
HTMLEditor::OnStartToHandleTopLevelEditSubAction(
EditSubAction aEditSubAction,

View file

@ -70,7 +70,6 @@ class HTMLEditor final : public TextEditor
, public nsITableEditor
, public nsIHTMLInlineTableEditor
, public nsIEditorStyleSheets
, public nsICSSLoaderObserver
, public nsStubMutationObserver
{
public:
@ -116,10 +115,6 @@ public:
// nsISelectionListener overrides
NS_DECL_NSISELECTIONLISTENER
// nsICSSLoaderObserver
NS_IMETHOD StyleSheetLoaded(StyleSheet* aSheet,
bool aWasAlternate, nsresult aStatus) override;
HTMLEditor();
nsHTMLDocument* GetHTMLDocument() const;
@ -782,12 +777,6 @@ protected: // Shouldn't be used by friend classes
*/
nsresult InsertBrElementAtSelectionWithTransaction();
/**
* RemoveStyleSheetWithTransaction() removes the given URL stylesheet
* from mStyleSheets and mStyleSheetURLs.
*/
nsresult RemoveStyleSheetWithTransaction(const nsAString& aURL);
nsresult LoadHTML(const nsAString& aInputString);
nsresult GetCSSBackgroundColorState(bool* aMixed, nsAString& aOutColor,

View file

@ -1,115 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "StyleSheetTransactions.h"
#include <stddef.h> // for nullptr
#include "nsAString.h"
#include "nsCOMPtr.h" // for nsCOMPtr, do_QueryInterface, etc.
#include "mozilla/StyleSheet.h" // for mozilla::StyleSheet
#include "mozilla/StyleSheetInlines.h"
#include "nsDebug.h" // for NS_ENSURE_TRUE
#include "nsError.h" // for NS_OK, etc.
#include "nsIDocument.h" // for nsIDocument
namespace mozilla {
static void
AddStyleSheet(EditorBase& aEditor, StyleSheet* aSheet)
{
if (nsCOMPtr<nsIDocument> doc = aEditor.GetDocument()) {
doc->AddStyleSheet(aSheet);
}
}
static void
RemoveStyleSheet(EditorBase& aEditor, StyleSheet* aSheet)
{
if (nsCOMPtr<nsIDocument> doc = aEditor.GetDocument()) {
doc->RemoveStyleSheet(aSheet);
}
}
/******************************************************************************
* AddStyleSheetTransaction
******************************************************************************/
AddStyleSheetTransaction::AddStyleSheetTransaction(EditorBase& aEditorBase,
StyleSheet& aStyleSheet)
: mEditorBase(&aEditorBase)
, mSheet(&aStyleSheet)
{
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(AddStyleSheetTransaction,
EditTransactionBase,
mEditorBase,
mSheet)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AddStyleSheetTransaction)
NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase)
NS_IMETHODIMP
AddStyleSheetTransaction::DoTransaction()
{
if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mSheet)) {
return NS_ERROR_NOT_INITIALIZED;
}
AddStyleSheet(*mEditorBase, mSheet);
return NS_OK;
}
NS_IMETHODIMP
AddStyleSheetTransaction::UndoTransaction()
{
if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mSheet)) {
return NS_ERROR_NOT_INITIALIZED;
}
RemoveStyleSheet(*mEditorBase, mSheet);
return NS_OK;
}
/******************************************************************************
* RemoveStyleSheetTransaction
******************************************************************************/
RemoveStyleSheetTransaction::RemoveStyleSheetTransaction(
EditorBase& aEditorBase,
StyleSheet& aStyleSheet)
: mEditorBase(&aEditorBase)
, mSheet(&aStyleSheet)
{
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(RemoveStyleSheetTransaction,
EditTransactionBase,
mEditorBase,
mSheet)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(RemoveStyleSheetTransaction)
NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase)
NS_IMETHODIMP
RemoveStyleSheetTransaction::DoTransaction()
{
if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mSheet)) {
return NS_ERROR_NOT_INITIALIZED;
}
RemoveStyleSheet(*mEditorBase, mSheet);
return NS_OK;
}
NS_IMETHODIMP
RemoveStyleSheetTransaction::UndoTransaction()
{
if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mSheet)) {
return NS_ERROR_NOT_INITIALIZED;
}
AddStyleSheet(*mEditorBase, mSheet);
return NS_OK;
}
} // namespace mozilla

View file

@ -1,87 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef StylesheetTransactions_h
#define StylesheetTransactions_h
#include "mozilla/EditorBase.h" // mEditor
#include "mozilla/EditTransactionBase.h" // for EditTransactionBase, etc.
#include "mozilla/StyleSheet.h" // for mozilla::StyleSheet
#include "nsCycleCollectionParticipant.h"
#include "nsID.h" // for REFNSIID
#include "nscore.h" // for NS_IMETHOD
namespace mozilla {
class AddStyleSheetTransaction final : public EditTransactionBase
{
protected:
AddStyleSheetTransaction(EditorBase& aEditor, StyleSheet& aStyleSheet);
public:
/**
* Creates an add style sheet transaction. This never returns nullptr.
*
* @param aEditorBase The editor.
* @param aSheet The style sheet to add.
*/
static already_AddRefed<AddStyleSheetTransaction>
Create(EditorBase& aEditorBase, StyleSheet& aStyleSheet)
{
RefPtr<AddStyleSheetTransaction> transaction =
new AddStyleSheetTransaction(aEditorBase, aStyleSheet);
return transaction.forget();
}
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AddStyleSheetTransaction,
EditTransactionBase)
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
NS_DECL_EDITTRANSACTIONBASE
protected:
// The editor that created this transaction.
RefPtr<EditorBase> mEditorBase;
// The style sheet to add.
RefPtr<mozilla::StyleSheet> mSheet;
};
class RemoveStyleSheetTransaction final : public EditTransactionBase
{
protected:
RemoveStyleSheetTransaction(EditorBase& aEditor, StyleSheet& aStyleSheet);
public:
/**
* Creates a remove style sheet transaction. This never returns nullptr.
*
* @param aEditor The object providing core editing operations.
* @param aSheet The stylesheet to remove.
*/
static already_AddRefed<RemoveStyleSheetTransaction>
Create(EditorBase& aEditorBase, StyleSheet& aStyleSheet)
{
RefPtr<RemoveStyleSheetTransaction> transaction =
new RemoveStyleSheetTransaction(aEditorBase, aStyleSheet);
return transaction.forget();
}
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(RemoveStyleSheetTransaction,
EditTransactionBase)
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
NS_DECL_EDITTRANSACTIONBASE
protected:
// The editor that created this transaction.
RefPtr<EditorBase> mEditorBase;
// The style sheet to remove.
RefPtr<StyleSheet> mSheet;
};
} // namespace mozilla
#endif // #ifndef StylesheetTransactions_h

View file

@ -69,7 +69,6 @@ UNIFIED_SOURCES += [
'PlaceholderTransaction.cpp',
'SelectionState.cpp',
'SplitNodeTransaction.cpp',
'StyleSheetTransactions.cpp',
'TextEditor.cpp',
'TextEditorDataTransfer.cpp',
'TextEditorTest.cpp',

View file

@ -56,7 +56,6 @@ skip-if = toolkit == 'android'
[test_bug455992.html]
[test_bug456244.html]
[test_bug460740.html]
[test_bug468353.html]
[test_bug471319.html]
[test_bug471722.html]
[test_bug478725.html]

View file

@ -1,117 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=468353
-->
<head>
<title>Test for Bug 468353</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=468353">Mozilla Bug 468353</a>
<p id="display"></p>
<div id="content">
<iframe></iframe>
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
var styleSheets = null;
function checkStylesheets() {
// Evidently RemoveStyleSheet is the only method in nsIEditorStyleSheets
// that would throw. RemoveOverrideStyleSheet returns NS_OK even if the
// sheet is not there
var removed = 0;
try
{
styleSheets.removeStyleSheet("resource://gre/res/designmode.css");
removed++;
}
catch (ex) { }
try {
styleSheets.removeStyleSheet("resource://gre/res/contenteditable.css");
removed++;
}
catch (ex) { }
is(removed, 0, "Should have thrown if stylesheet was not there");
}
function runTest() {
const Ci = SpecialPowers.Ci;
/** Found while fixing bug 440614 **/
var editframe = window.frames[0];
var editdoc = editframe.document;
var editor = null;
editdoc.write('');
editdoc.close();
editdoc.designMode='on';
// Hold the reference to the editor
editor = SpecialPowers.wrap(editframe)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIEditingSession)
.getEditorForWindow(editframe);
styleSheets = editor.QueryInterface(Ci.nsIEditorStyleSheets);
editdoc.designMode='off';
checkStylesheets();
// Let go
editor = null;
styleSheets = null;
editdoc.body.contentEditable = true;
// Hold the reference to the editor
editor = SpecialPowers.wrap(editframe)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIEditingSession)
.getEditorForWindow(editframe);
styleSheets = editor.QueryInterface(Ci.nsIEditorStyleSheets);
editdoc.body.contentEditable = false;
checkStylesheets();
editdoc.designMode = "on";
editdoc.body.contentEditable = true;
editdoc.designMode = "off";
// Hold the reference to the editor
editor = SpecialPowers.wrap(editframe)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIEditingSession)
.getEditorForWindow(editframe);
styleSheets = editor.QueryInterface(Ci.nsIEditorStyleSheets);
editdoc.body.contentEditable = false;
checkStylesheets();
SimpleTest.finish();
}
//XXX I don't know if this is necessary, but we're dealing with iframes...
SimpleTest.waitForExplicitFinish();
addLoadEvent(runTest);
</script>
</pre>
</body>
</html>

View file

@ -9,22 +9,6 @@
interface nsIEditorStyleSheets : nsISupports
{
/** 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 asynchronous, and may cause network I/O.
*
* @param aURL The style sheet to be loaded and applied.
*/
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 asynchronous, and may cause network I/O.
*
* @param aURL The style sheet to be loaded and applied.
*/
void addStyleSheet(in AString aURL);
/** Load and apply the override style sheet, specified by aURL, to the
* editor's document, replacing the last override style sheet added (if any).
* This is always synchronous, so aURL should be a local file with only
@ -47,13 +31,6 @@ interface nsIEditorStyleSheets : nsISupports
*/
void addOverrideStyleSheet(in AString aURL);
/** Remove the given style sheet from the editor's document
* This is always synchronous
*
* @param aURL The style sheet to be removed
*/
void removeStyleSheet(in AString aURL);
/** Remove the given override style sheet from the editor's document
* This is always synchronous
*