From dad19047d2d187ec1b9736c947c44131088dcf2d Mon Sep 17 00:00:00 2001 From: flyingrub Date: Thu, 10 Aug 2017 18:45:19 +0200 Subject: [PATCH 01/87] Bug 1389030 - Go to home when section has no data in about:telemetry r=chutten When switching to a ping that hasn't data for the current section go to home section. MozReview-Commit-ID: 2zTZUiyHe0M --HG-- extra : rebase_source : 2abe235c99cf2b0b6579c9fbac940b5bc8a0a532 --- toolkit/content/aboutTelemetry.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/toolkit/content/aboutTelemetry.js b/toolkit/content/aboutTelemetry.js index d0c4171d0414..97fc72eeb4e2 100644 --- a/toolkit/content/aboutTelemetry.js +++ b/toolkit/content/aboutTelemetry.js @@ -1899,6 +1899,13 @@ function adjustSearchState() { } } +function adjustSection() { + let selectedCategory = document.querySelector(".category.selected"); + if (!selectedCategory.classList.contains("has-data")) { + PingPicker._showStructuredPingData(); + } +} + /** * Change the url according to the current section displayed * e.g about:telemetry#general-data @@ -2360,11 +2367,12 @@ function displayPingData(ping, updatePayloadList = false) { try { PingPicker.render(); displayRichPingData(ping, updatePayloadList); + adjustSearchState(); + adjustSection(); } catch (err) { console.log(err); PingPicker._showRawPingData(); } - adjustSearchState(); } function displayRichPingData(ping, updatePayloadList) { From cb7421f53115e15bce09d7c5ad12dd5d97cbba1d Mon Sep 17 00:00:00 2001 From: flyingrub Date: Tue, 15 Aug 2017 14:22:39 +0200 Subject: [PATCH 02/87] Bug 1389255 - Fix the styling of multitable section in about:telemetry r=chutten r?chutten Also some minor css fixes to keyed histogram section. MozReview-Commit-ID: LkRUBREkGwa --HG-- extra : rebase_source : 0bf9ae1ae81562f85c4b9437fc0b698db982bc62 --- toolkit/content/aboutTelemetry.css | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/toolkit/content/aboutTelemetry.css b/toolkit/content/aboutTelemetry.css index 2459c2028cd5..fe53f52abe08 100644 --- a/toolkit/content/aboutTelemetry.css +++ b/toolkit/content/aboutTelemetry.css @@ -207,7 +207,6 @@ body[dir="rtl"] .histogram { .keyed-histogram { white-space: nowrap; - padding: 15px; position: relative; /* required for position:absolute of the contained .copy-node */ overflow: hidden; } @@ -215,7 +214,7 @@ body[dir="rtl"] .histogram { .keyed-histogram-title { text-overflow: ellipsis; width: 100%; - margin: 10px; + margin: 12px 0; font-weight: bold; font-size: 120%; white-space: nowrap; @@ -274,10 +273,9 @@ body[dir="rtl"] th { } caption { - font-weight: bold; - white-space: nowrap; text-align: left; - font-size: large; + font-size: xx-large; + margin: 1em 0 0.5em 0; } body[dir="rtl"] caption { @@ -302,8 +300,3 @@ body[dir="rtl"] .copy-node { #raw-ping-data { font-size: 15px; } - -caption { - font-size: larger; - margin: 5px 0; -} \ No newline at end of file From 163ee806174a5824bbbcbb55c518eca742115cc3 Mon Sep 17 00:00:00 2001 From: Gijs Kruitbosch Date: Tue, 15 Aug 2017 12:02:11 +0100 Subject: [PATCH 03/87] Bug 1390260 - make customize mode work in popup windows, r=mkaply MozReview-Commit-ID: 7lokGRuqNHv --HG-- extra : rebase_source : 0015e3c60e97f117ddf3a72410f455e648a1138e --- .../components/customizableui/CustomizeMode.jsm | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/browser/components/customizableui/CustomizeMode.jsm b/browser/components/customizableui/CustomizeMode.jsm index bb46beb9c453..18e397b174c5 100644 --- a/browser/components/customizableui/CustomizeMode.jsm +++ b/browser/components/customizableui/CustomizeMode.jsm @@ -203,6 +203,21 @@ CustomizeMode.prototype = { }, enter() { + if (!this.window.toolbar.visible) { + let w = this.window.getTopWin(true); + if (w) { + w.gCustomizeMode.enter(); + return; + } + let obs = () => { + Services.obs.removeObserver(obs, "browser-delayed-startup-finished"); + w = this.window.getTopWin(true); + w.gCustomizeMode.enter(); + }; + Services.obs.addObserver(obs, "browser-delayed-startup-finished"); + this.window.openUILinkIn("about:newtab", "window"); + return; + } this._wantToBeInCustomizeMode = true; if (this._customizing || this._handler.isEnteringCustomizeMode) { From d0f97efd430a96fe0f07abbe7d1033a1d1507565 Mon Sep 17 00:00:00 2001 From: Gijs Kruitbosch Date: Tue, 15 Aug 2017 17:42:16 +0100 Subject: [PATCH 04/87] Bug 1390260 - remove old customize test, add test that checks it works in main window, r=mkaply MozReview-Commit-ID: 9Tm8kLjxukB --HG-- extra : rebase_source : a8d599d6e67151abdc2b65297b5cb5fcbc2dbea7 --- browser/base/content/test/general/browser.ini | 2 - .../content/test/general/browser_bug422590.js | 59 ------------------- .../customizableui/test/browser.ini | 1 + .../test/browser_open_from_popup.js | 19 ++++++ 4 files changed, 20 insertions(+), 61 deletions(-) delete mode 100644 browser/base/content/test/general/browser_bug422590.js create mode 100644 browser/components/customizableui/test/browser_open_from_popup.js diff --git a/browser/base/content/test/general/browser.ini b/browser/base/content/test/general/browser.ini index 1b22c092a039..5bc26d6643f1 100644 --- a/browser/base/content/test/general/browser.ini +++ b/browser/base/content/test/general/browser.ini @@ -131,8 +131,6 @@ skip-if = true # browser_bug321000.js is disabled because newline handling is sh # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD. [browser_bug419612.js] # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD. -[browser_bug422590.js] -# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD. [browser_bug423833.js] skip-if = true # bug 428712 # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD. diff --git a/browser/base/content/test/general/browser_bug422590.js b/browser/base/content/test/general/browser_bug422590.js deleted file mode 100644 index 4be14c54ccf7..000000000000 --- a/browser/base/content/test/general/browser_bug422590.js +++ /dev/null @@ -1,59 +0,0 @@ -function test() { - waitForExplicitFinish(); - - // test a normal browser window - var newWin = openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no", "about:blank"); - ok(newWin, "got new normal window"); - - whenDelayedStartupFinished(newWin, function() { - testCustomize(newWin, function() { - newWin.close(); - testChromeless(); - }); - }); -} - -function testChromeless() { - // test a chromeless window - var newWin = openDialog(getBrowserURL(), "_blank", - "chrome,dialog=no,location=yes,toolbar=no", "about:blank"); - ok(newWin, "got new window"); - - whenDelayedStartupFinished(newWin, function() { - // Check that the search bar is hidden - var searchBar = newWin.BrowserSearch.searchBar; - ok(searchBar, "got search bar"); - - var searchBarBO = searchBar.boxObject; - is(searchBarBO.width, 0, "search bar hidden"); - is(searchBarBO.height, 0, "search bar hidden"); - - testCustomize(newWin, function() { - newWin.close(); - finish(); - }); - }); -} - -function testCustomize(aWindow, aCallback) { - var fileMenu = aWindow.document.getElementById("file-menu"); - ok(fileMenu, "got file menu"); - is(fileMenu.disabled, false, "file menu initially enabled"); - - openToolbarCustomizationUI(function() { - // Can't use the property, since the binding may have since been removed - // if the element is hidden (see bug 422590) - is(fileMenu.getAttribute("disabled"), "true", - "file menu is disabled during toolbar customization"); - - closeToolbarCustomizationUI(onClose, aWindow); - }, aWindow); - - function onClose() { - is(fileMenu.getAttribute("disabled"), "false", - "file menu is enabled after toolbar customization"); - - if (aCallback) - aCallback(); - } -} diff --git a/browser/components/customizableui/test/browser.ini b/browser/components/customizableui/test/browser.ini index d3ff34012010..6edeb8c8930b 100644 --- a/browser/components/customizableui/test/browser.ini +++ b/browser/components/customizableui/test/browser.ini @@ -156,5 +156,6 @@ tags = fullscreen [browser_editcontrols_update.js] subsuite = clipboard [browser_customization_context_menus.js] +[browser_open_from_popup.js] [browser_sidebar_toggle.js] [browser_remote_tabs_button.js] diff --git a/browser/components/customizableui/test/browser_open_from_popup.js b/browser/components/customizableui/test/browser_open_from_popup.js new file mode 100644 index 000000000000..744c0201c624 --- /dev/null +++ b/browser/components/customizableui/test/browser_open_from_popup.js @@ -0,0 +1,19 @@ +"use strict"; + +/** + * Check that opening customize mode in a popup opens it in the main window. + */ +add_task(async function open_customize_mode_from_popup() { + let promiseWindow = BrowserTestUtils.waitForNewWindow(true); + ContentTask.spawn(gBrowser.selectedBrowser, null, function() { + content.window.open("about:blank", "_blank", "height=300,toolbar=no"); + }); + let win = await promiseWindow; + let customizePromise = BrowserTestUtils.waitForEvent(gNavToolbox, "customizationready"); + win.gCustomizeMode.enter(); + await customizePromise; + ok(document.documentElement.hasAttribute("customizing"), + "Should have opened customize mode in the parent window"); + await endCustomizing(); + await BrowserTestUtils.closeWindow(win); +}); From 3afc31df222bd9bd4a088b69971ceb9d141cf574 Mon Sep 17 00:00:00 2001 From: Masatoshi Kimura Date: Mon, 14 Aug 2017 20:38:59 +0900 Subject: [PATCH 05/87] Bug 1390106 - Stop using versioned scripts in addon-sdk. r=mossop MozReview-Commit-ID: C5122oYHTWx --HG-- extra : rebase_source : 90f0846b9d9ca3543a16b28f8ae9bd00d56e4173 --- addon-sdk/source/lib/sdk/deprecated/window-utils.js | 4 ++-- addon-sdk/source/lib/sdk/lang/weak-set.js | 4 ++-- addon-sdk/source/lib/sdk/util/collection.js | 2 +- addon-sdk/source/lib/sdk/util/list.js | 13 ------------- 4 files changed, 5 insertions(+), 18 deletions(-) diff --git a/addon-sdk/source/lib/sdk/deprecated/window-utils.js b/addon-sdk/source/lib/sdk/deprecated/window-utils.js index 93c0ab7b8e86..962314bc8737 100644 --- a/addon-sdk/source/lib/sdk/deprecated/window-utils.js +++ b/addon-sdk/source/lib/sdk/deprecated/window-utils.js @@ -31,7 +31,7 @@ function getWindows() { * @return A generator that yields XUL windows exposing the * nsIDOMWindow interface. */ -function windowIterator() { +function* windowIterator() { // Bug 752631: We only pass already loaded window in order to avoid // breaking XUL windows DOM. DOM is broken when some JS code try // to access DOM during "uninitialized" state of the related document. @@ -48,7 +48,7 @@ exports.windowIterator = windowIterator; * A generator that yields browser windows exposing the `nsIDOMWindow` * interface. */ -function browserWindowIterator() { +function* browserWindowIterator() { for (let window of windowIterator()) { if (isBrowser(window)) yield window; diff --git a/addon-sdk/source/lib/sdk/lang/weak-set.js b/addon-sdk/source/lib/sdk/lang/weak-set.js index 8972602a50c1..6adc9b11216f 100644 --- a/addon-sdk/source/lib/sdk/lang/weak-set.js +++ b/addon-sdk/source/lib/sdk/lang/weak-set.js @@ -54,7 +54,7 @@ function clear(target) { } exports.clear = clear; -function iterator(target) { +function* iterator(target) { let refs = getRefsFor(target); for (let ref of refs) { @@ -72,4 +72,4 @@ function iterator(target) { refs.delete(ref); } } -exports.iterator = iterator; +exports[Symbol.iterator] = iterator; diff --git a/addon-sdk/source/lib/sdk/util/collection.js b/addon-sdk/source/lib/sdk/util/collection.js index 194a2947087d..9af07c4e9629 100644 --- a/addon-sdk/source/lib/sdk/util/collection.js +++ b/addon-sdk/source/lib/sdk/util/collection.js @@ -57,7 +57,7 @@ function Collection(array) { * Provides iteration over the collection. Items are yielded in the order * they were added. */ - this.__iterator__ = function Collection___iterator__() { + this[Symbol.iterator] = function* Collection___iterator__() { let items = array.slice(); for (let i = 0; i < items.length; i++) yield items[i]; diff --git a/addon-sdk/source/lib/sdk/util/list.js b/addon-sdk/source/lib/sdk/util/list.js index 6d7d2dea9d92..e8afe50eac25 100644 --- a/addon-sdk/source/lib/sdk/util/list.js +++ b/addon-sdk/source/lib/sdk/util/list.js @@ -37,19 +37,6 @@ const listOptions = { toString: function toString() { return 'List(' + listNS(this).keyValueMap + ')'; }, - /** - * Custom iterator providing `List`s enumeration behavior. - * We cant reuse `_iterator` that is defined by `Iterable` since it provides - * iteration in an arbitrary order. - * @see https://developer.mozilla.org/en/JavaScript/Reference/Statements/for...in - * @param {Boolean} onKeys - */ - __iterator__: function __iterator__(onKeys, onKeyValue) { - let array = listNS(this).keyValueMap.slice(0), - i = -1; - for (let element of array) - yield onKeyValue ? [++i, element] : onKeys ? ++i : element; - }, }; listOptions[Symbol.iterator] = function iterator() { return listNS(this).keyValueMap.slice(0)[Symbol.iterator](); From 38894511bc41c37b974645822ee0511c0cfe2d25 Mon Sep 17 00:00:00 2001 From: Masatoshi Kimura Date: Mon, 14 Aug 2017 20:42:55 +0900 Subject: [PATCH 06/87] Bug 1390106 - Stop using versioned scripts in dom. r=mrbkap MozReview-Commit-ID: 89KvCoTAg3I --HG-- extra : rebase_source : 24831fa454a1cc6fff70a9b1eb509d0f5aeb800a --- dom/base/nsFrameMessageManager.cpp | 4 ++-- dom/security/test/cors/browser_CORS-console-warnings.js | 2 +- dom/workers/RuntimeService.cpp | 2 +- dom/workers/ScriptLoader.cpp | 2 +- dom/xbl/nsXBLProtoImplField.cpp | 2 +- dom/xbl/nsXBLProtoImplMethod.cpp | 2 +- dom/xbl/nsXBLProtoImplProperty.cpp | 4 ++-- dom/xbl/nsXBLPrototypeHandler.cpp | 2 +- dom/xul/nsXULContentSink.cpp | 6 +++--- 9 files changed, 13 insertions(+), 13 deletions(-) diff --git a/dom/base/nsFrameMessageManager.cpp b/dom/base/nsFrameMessageManager.cpp index 15c40ee21996..ebf6ddf6872f 100644 --- a/dom/base/nsFrameMessageManager.cpp +++ b/dom/base/nsFrameMessageManager.cpp @@ -1662,7 +1662,7 @@ nsMessageManagerScriptExecutor::TryCacheLoadAndCompileScript( return; } - JS::CompileOptions options(cx, JSVERSION_LATEST); + JS::CompileOptions options(cx, JSVERSION_DEFAULT); options.setFileAndLine(url.get(), 1); options.setNoScriptRval(true); @@ -1728,7 +1728,7 @@ nsMessageManagerScriptExecutor::InitChildGlobalInternal( JS::CompartmentOptions options; options.creationOptions().setSystemZone(); - options.behaviors().setVersion(JSVERSION_LATEST); + options.behaviors().setVersion(JSVERSION_DEFAULT); if (xpc::SharedMemoryEnabled()) { options.creationOptions().setSharedMemoryAndAtomicsEnabled(true); diff --git a/dom/security/test/cors/browser_CORS-console-warnings.js b/dom/security/test/cors/browser_CORS-console-warnings.js index 451d3a59410a..b4b90e3f058c 100644 --- a/dom/security/test/cors/browser_CORS-console-warnings.js +++ b/dom/security/test/cors/browser_CORS-console-warnings.js @@ -27,7 +27,7 @@ function on_new_message(event, new_messages) { } } -function do_cleanup() { +function* do_cleanup() { if (webconsole) { webconsole.ui.off("new-messages", on_new_message); } diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp index fdbdca8a31aa..ff1e7319614c 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp @@ -2020,7 +2020,7 @@ RuntimeService::Init() if (!sDefaultJSSettings.gcSettings[0].IsSet()) { sDefaultJSSettings.contextOptions = JS::ContextOptions(); sDefaultJSSettings.chrome.maxScriptRuntime = -1; - sDefaultJSSettings.chrome.compartmentOptions.behaviors().setVersion(JSVERSION_LATEST); + sDefaultJSSettings.chrome.compartmentOptions.behaviors().setVersion(JSVERSION_DEFAULT); sDefaultJSSettings.content.maxScriptRuntime = MAX_SCRIPT_RUN_TIME_SEC; #ifdef JS_GC_ZEAL sDefaultJSSettings.gcZealFrequency = JS_DEFAULT_ZEAL_FREQ; diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp index 582a2131ceb1..0948e8b1f860 100644 --- a/dom/workers/ScriptLoader.cpp +++ b/dom/workers/ScriptLoader.cpp @@ -1961,7 +1961,7 @@ ScriptExecutorRunnable::WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) .setNoScriptRval(true); if (mScriptLoader.mWorkerScriptType == DebuggerScript) { - options.setVersion(JSVERSION_LATEST); + options.setVersion(JSVERSION_DEFAULT); } MOZ_ASSERT(loadInfo.mMutedErrorFlag.isSome()); diff --git a/dom/xbl/nsXBLProtoImplField.cpp b/dom/xbl/nsXBLProtoImplField.cpp index 28da50e03b52..cca6a83d9cb7 100644 --- a/dom/xbl/nsXBLProtoImplField.cpp +++ b/dom/xbl/nsXBLProtoImplField.cpp @@ -434,7 +434,7 @@ nsXBLProtoImplField::InstallField(JS::Handle aBoundNode, JS::Rooted result(cx); JS::CompileOptions options(cx); options.setFileAndLine(uriSpec.get(), mLineNumber) - .setVersion(JSVERSION_LATEST); + .setVersion(JSVERSION_DEFAULT); JS::AutoObjectVector scopeChain(cx); if (!nsJSUtils::GetScopeChainForElement(cx, boundElement, scopeChain)) { return NS_ERROR_OUT_OF_MEMORY; diff --git a/dom/xbl/nsXBLProtoImplMethod.cpp b/dom/xbl/nsXBLProtoImplMethod.cpp index 31b215ab37cc..39a51a70b0ba 100644 --- a/dom/xbl/nsXBLProtoImplMethod.cpp +++ b/dom/xbl/nsXBLProtoImplMethod.cpp @@ -193,7 +193,7 @@ nsXBLProtoImplMethod::CompileMember(AutoJSAPI& jsapi, const nsString& aClassStr, JS::CompileOptions options(cx); options.setFileAndLine(functionUri.get(), uncompiledMethod->mBodyText.GetLineNumber()) - .setVersion(JSVERSION_LATEST); + .setVersion(JSVERSION_DEFAULT); JS::Rooted methodObject(cx); JS::AutoObjectVector emptyVector(cx); nsresult rv = nsJSUtils::CompileFunction(jsapi, emptyVector, options, cname, diff --git a/dom/xbl/nsXBLProtoImplProperty.cpp b/dom/xbl/nsXBLProtoImplProperty.cpp index a821ee0f1bdc..9a366ce9ab8b 100644 --- a/dom/xbl/nsXBLProtoImplProperty.cpp +++ b/dom/xbl/nsXBLProtoImplProperty.cpp @@ -199,7 +199,7 @@ nsXBLProtoImplProperty::CompileMember(AutoJSAPI& jsapi, const nsString& aClassSt JSAutoCompartment ac(cx, aClassObject); JS::CompileOptions options(cx); options.setFileAndLine(functionUri.get(), getterText->GetLineNumber()) - .setVersion(JSVERSION_LATEST); + .setVersion(JSVERSION_DEFAULT); nsCString name = NS_LITERAL_CSTRING("get_") + NS_ConvertUTF16toUTF8(mName); JS::Rooted getterObject(cx); JS::AutoObjectVector emptyVector(cx); @@ -245,7 +245,7 @@ nsXBLProtoImplProperty::CompileMember(AutoJSAPI& jsapi, const nsString& aClassSt JSAutoCompartment ac(cx, aClassObject); JS::CompileOptions options(cx); options.setFileAndLine(functionUri.get(), setterText->GetLineNumber()) - .setVersion(JSVERSION_LATEST); + .setVersion(JSVERSION_DEFAULT); nsCString name = NS_LITERAL_CSTRING("set_") + NS_ConvertUTF16toUTF8(mName); JS::Rooted setterObject(cx); JS::AutoObjectVector emptyVector(cx); diff --git a/dom/xbl/nsXBLPrototypeHandler.cpp b/dom/xbl/nsXBLPrototypeHandler.cpp index 88e0b8a468d7..968089af3abd 100644 --- a/dom/xbl/nsXBLPrototypeHandler.cpp +++ b/dom/xbl/nsXBLPrototypeHandler.cpp @@ -435,7 +435,7 @@ nsXBLPrototypeHandler::EnsureEventHandler(AutoJSAPI& jsapi, nsIAtom* aName, JSAutoCompartment ac(cx, scopeObject); JS::CompileOptions options(cx); options.setFileAndLine(bindingURI.get(), mLineNumber) - .setVersion(JSVERSION_LATEST); + .setVersion(JSVERSION_DEFAULT); JS::Rooted handlerFun(cx); JS::AutoObjectVector emptyVector(cx); diff --git a/dom/xul/nsXULContentSink.cpp b/dom/xul/nsXULContentSink.cpp index 8e68b7907be1..1cbe4d5ada31 100644 --- a/dom/xul/nsXULContentSink.cpp +++ b/dom/xul/nsXULContentSink.cpp @@ -835,7 +835,7 @@ XULContentSinkImpl::OpenScript(const char16_t** aAttributes, const uint32_t aLineNumber) { bool isJavaScript = true; - uint32_t version = JSVERSION_LATEST; + uint32_t version = JSVERSION_DEFAULT; nsresult rv; // Look for SRC attribute and look for a LANGUAGE attribute @@ -861,14 +861,14 @@ XULContentSinkImpl::OpenScript(const char16_t** aAttributes, if (nsContentUtils::IsJavascriptMIMEType(mimeType)) { isJavaScript = true; - version = JSVERSION_LATEST; + version = JSVERSION_DEFAULT; // Get the version string, and ensure that JavaScript supports it. nsAutoString versionName; rv = parser.GetParameter("version", versionName); if (NS_SUCCEEDED(rv)) { - version = nsContentUtils::ParseJavascriptVersion(versionName); + version = JSVERSION_UNKNOWN; } else if (rv != NS_ERROR_INVALID_ARG) { return rv; } From 6b248fe3cdfc183808f602776e671047e7705a41 Mon Sep 17 00:00:00 2001 From: Masatoshi Kimura Date: Mon, 14 Aug 2017 20:43:47 +0900 Subject: [PATCH 07/87] Bug 1390106 - Stop using versioned scripts in js/src. r=luke MozReview-Commit-ID: IfPBaEr62Mi --HG-- extra : rebase_source : 0dc69e03fead2713091cfd553d45dd9d1c485d27 --- js/src/gdb/gdb-tests.cpp | 2 +- js/src/jsapi-tests/testPreserveJitCode.cpp | 2 +- js/src/jsapi-tests/testWeakMap.cpp | 2 +- js/src/jsapi-tests/tests.cpp | 2 +- js/src/shell/js.cpp | 2 +- js/src/vm/SelfHosting.cpp | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/js/src/gdb/gdb-tests.cpp b/js/src/gdb/gdb-tests.cpp index f5737e13b8f8..edb81c838224 100644 --- a/js/src/gdb/gdb-tests.cpp +++ b/js/src/gdb/gdb-tests.cpp @@ -79,7 +79,7 @@ main(int argc, const char** argv) /* Create the global object. */ JS::CompartmentOptions options; - options.behaviors().setVersion(JSVERSION_LATEST); + options.behaviors().setVersion(JSVERSION_DEFAULT); RootedObject global(cx, checkPtr(JS_NewGlobalObject(cx, &global_class, nullptr, JS::FireOnNewGlobalHook, options))); diff --git a/js/src/jsapi-tests/testPreserveJitCode.cpp b/js/src/jsapi-tests/testPreserveJitCode.cpp index ad2716cbf88e..583f3ef0e8dc 100644 --- a/js/src/jsapi-tests/testPreserveJitCode.cpp +++ b/js/src/jsapi-tests/testPreserveJitCode.cpp @@ -91,7 +91,7 @@ createTestGlobal(bool preserveJitCode) { JS::CompartmentOptions options; options.creationOptions().setPreserveJitCode(preserveJitCode); - options.behaviors().setVersion(JSVERSION_LATEST); + options.behaviors().setVersion(JSVERSION_DEFAULT); return JS_NewGlobalObject(cx, getGlobalClass(), nullptr, JS::FireOnNewGlobalHook, options); } END_TEST(test_PreserveJitCode) diff --git a/js/src/jsapi-tests/testWeakMap.cpp b/js/src/jsapi-tests/testWeakMap.cpp index 5cecea1b02f1..7376a66a891b 100644 --- a/js/src/jsapi-tests/testWeakMap.cpp +++ b/js/src/jsapi-tests/testWeakMap.cpp @@ -237,7 +237,7 @@ JSObject* newDelegate() /* Create the global object. */ JS::CompartmentOptions options; - options.behaviors().setVersion(JSVERSION_LATEST); + options.behaviors().setVersion(JSVERSION_DEFAULT); JS::RootedObject global(cx, JS_NewGlobalObject(cx, Jsvalify(&delegateClass), nullptr, JS::FireOnNewGlobalHook, options)); diff --git a/js/src/jsapi-tests/tests.cpp b/js/src/jsapi-tests/tests.cpp index 7a11a4d3de0a..cfd29c429702 100644 --- a/js/src/jsapi-tests/tests.cpp +++ b/js/src/jsapi-tests/tests.cpp @@ -87,7 +87,7 @@ JSObject* JSAPITest::createGlobal(JSPrincipals* principals) options.creationOptions().setStreamsEnabled(true); #endif printf("enabled\n"); - options.behaviors().setVersion(JSVERSION_LATEST); + options.behaviors().setVersion(JSVERSION_DEFAULT); newGlobal = JS_NewGlobalObject(cx, getGlobalClass(), principals, JS::FireOnNewGlobalHook, options); if (!newGlobal) diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 16889ef5a7d4..c8c73b24ea9f 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -631,7 +631,7 @@ InitModuleLoader(JSContext* cx) options.setFileAndLine("shell/ModuleLoader.js", 1); options.setSelfHostingMode(false); options.setCanLazilyParse(false); - options.setVersion(JSVERSION_LATEST); + options.setVersion(JSVERSION_DEFAULT); options.werrorOption = true; options.strictOption = true; diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index dd9e7861fcf8..43fcb9acc18c 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -2604,7 +2604,7 @@ js::FillSelfHostingCompileOptions(CompileOptions& options) options.setFileAndLine("self-hosted", 1); options.setSelfHostingMode(true); options.setCanLazilyParse(false); - options.setVersion(JSVERSION_LATEST); + options.setVersion(JSVERSION_DEFAULT); options.werrorOption = true; options.strictOption = true; From 43dd1b22aff26a4a0209e6078dd723e60224a5de Mon Sep 17 00:00:00 2001 From: Masatoshi Kimura Date: Mon, 14 Aug 2017 20:45:14 +0900 Subject: [PATCH 08/87] Bug 1390106 - Stop using versioned scripts in js/xpconnect. r=mccr8 MozReview-Commit-ID: LP7bXQd7ahD --HG-- extra : rebase_source : b0d3b9052d333698dbb1e6e6a0da9556fe60a91b --- js/xpconnect/loader/ScriptPreloader.cpp | 2 +- js/xpconnect/loader/mozJSComponentLoader.cpp | 4 ++-- js/xpconnect/loader/mozJSSubScriptLoader.cpp | 2 +- js/xpconnect/src/XPCComponents.cpp | 12 ++++-------- js/xpconnect/src/XPCShellImpl.cpp | 2 +- js/xpconnect/tests/chrome/test_bug596580.xul | 2 +- js/xpconnect/tests/unit/test_xrayed_iterator.js | 10 +++++----- 7 files changed, 15 insertions(+), 19 deletions(-) diff --git a/js/xpconnect/loader/ScriptPreloader.cpp b/js/xpconnect/loader/ScriptPreloader.cpp index e12976805a52..437c11bc48b8 100644 --- a/js/xpconnect/loader/ScriptPreloader.cpp +++ b/js/xpconnect/loader/ScriptPreloader.cpp @@ -998,7 +998,7 @@ ScriptPreloader::DecodeNextBatch(size_t chunkSize) MOZ_RELEASE_ASSERT(jsapi.Init(xpc::CompilationScope())); JSContext* cx = jsapi.cx(); - JS::CompileOptions options(cx, JSVERSION_LATEST); + JS::CompileOptions options(cx, JSVERSION_DEFAULT); options.setNoScriptRval(true) .setSourceIsLazy(true); diff --git a/js/xpconnect/loader/mozJSComponentLoader.cpp b/js/xpconnect/loader/mozJSComponentLoader.cpp index e9723c1f7ef5..7fac937a982a 100644 --- a/js/xpconnect/loader/mozJSComponentLoader.cpp +++ b/js/xpconnect/loader/mozJSComponentLoader.cpp @@ -472,7 +472,7 @@ mozJSComponentLoader::CreateLoaderGlobal(JSContext* aCx, .setSystemZone() .setAddonId(aAddonID); - options.behaviors().setVersion(JSVERSION_LATEST); + options.behaviors().setVersion(JSVERSION_DEFAULT); if (xpc::SharedMemoryEnabled()) options.creationOptions().setSharedMemoryAndAtomicsEnabled(true); @@ -650,7 +650,7 @@ mozJSComponentLoader::ObjectForLocation(ComponentLoaderInfo& aInfo, // See bug 1303754. CompileOptions options(cx); options.setNoScriptRval(true) - .setVersion(JSVERSION_LATEST) + .setVersion(JSVERSION_DEFAULT) .setFileAndLine(nativePath.get(), 1) .setSourceIsLazy(cache || ScriptPreloader::GetSingleton().Active()); diff --git a/js/xpconnect/loader/mozJSSubScriptLoader.cpp b/js/xpconnect/loader/mozJSSubScriptLoader.cpp index 9e610b92f2df..563830262ef5 100644 --- a/js/xpconnect/loader/mozJSSubScriptLoader.cpp +++ b/js/xpconnect/loader/mozJSSubScriptLoader.cpp @@ -138,7 +138,7 @@ PrepareScript(nsIURI* uri, { JS::CompileOptions options(cx); options.setFileAndLine(uriStr, 1) - .setVersion(JSVERSION_LATEST) + .setVersion(JSVERSION_DEFAULT) .setNoScriptRval(!wantReturnValue); if (!charset.IsVoid()) { char16_t* scriptBuf = nullptr; diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp index e3f1c01c4f60..c677bcdfc24a 100644 --- a/js/xpconnect/src/XPCComponents.cpp +++ b/js/xpconnect/src/XPCComponents.cpp @@ -2402,16 +2402,12 @@ nsXPCComponents_Utils::EvalInSandbox(const nsAString& source, if (!bytes) return NS_ERROR_INVALID_ARG; - jsVersion = JS_StringToVersion(bytes.ptr()); - // Explicitly check for "latest", which we support for sandboxes but - // isn't in the set of web-exposed version strings. - if (jsVersion == JSVERSION_UNKNOWN && - !strcmp(bytes.ptr(), "latest")) + // Treat non-default version designation as default. + if (JS_StringToVersion(bytes.ptr()) == JSVERSION_UNKNOWN && + strcmp(bytes.ptr(), "latest")) { - jsVersion = JSVERSION_LATEST; - } - if (jsVersion == JSVERSION_UNKNOWN) return NS_ERROR_INVALID_ARG; + } } // Optional fourth and fifth arguments: filename and line number. diff --git a/js/xpconnect/src/XPCShellImpl.cpp b/js/xpconnect/src/XPCShellImpl.cpp index 46439c23ba85..ae5b64563779 100644 --- a/js/xpconnect/src/XPCShellImpl.cpp +++ b/js/xpconnect/src/XPCShellImpl.cpp @@ -1433,7 +1433,7 @@ XRE_XPCShellMain(int argc, char** argv, char** envp, options.creationOptions().setNewZoneInSystemZoneGroup(); if (xpc::SharedMemoryEnabled()) options.creationOptions().setSharedMemoryAndAtomicsEnabled(true); - options.behaviors().setVersion(JSVERSION_LATEST); + options.behaviors().setVersion(JSVERSION_DEFAULT); nsCOMPtr holder; rv = nsXPConnect::XPConnect()-> InitClassesWithNewWrappedGlobal(cx, diff --git a/js/xpconnect/tests/chrome/test_bug596580.xul b/js/xpconnect/tests/chrome/test_bug596580.xul index fab7058ac14d..9bd8354590ae 100644 --- a/js/xpconnect/tests/chrome/test_bug596580.xul +++ b/js/xpconnect/tests/chrome/test_bug596580.xul @@ -14,7 +14,7 @@ - + + + + + + + + + + + diff --git a/mobile/android/themes/core/aboutAddons.css b/mobile/android/themes/core/aboutAddons.css index 58be73456efb..e9b394d17754 100644 --- a/mobile/android/themes/core/aboutAddons.css +++ b/mobile/android/themes/core/aboutAddons.css @@ -49,6 +49,9 @@ a:active { .warn-unsigned { border-top: 1px solid var(--color_about_item_border); + border-bottom: 1px solid var(--color_about_item_border); + margin-top: 1em; + margin-bottom: 1em; padding: 1em; padding-inline-start: calc(var(--icon-size) + var(--icon-margin) * 2); background-image: url("chrome://browser/skin/images/grey-caution.svg"); From d22502054f5a0a5ea294ecea8e996c8f6d2ca30f Mon Sep 17 00:00:00 2001 From: Luke Chang Date: Mon, 14 Aug 2017 11:01:33 +0800 Subject: [PATCH 33/87] Bug 1389998 - Flip "dom.forms.autocomplete.formautofill" when running web-platform-tests r=MattN MozReview-Commit-ID: 78Iph0Xmg42 --HG-- extra : rebase_source : 8ffc6a42483196d076d914ba958a01d51a935d45 --- testing/web-platform/meta/html/dom/interfaces.html.ini | 2 +- .../semantics/forms/the-form-element/form-autocomplete.html.ini | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/testing/web-platform/meta/html/dom/interfaces.html.ini b/testing/web-platform/meta/html/dom/interfaces.html.ini index 91fceb4fea6e..b933a90a06e3 100644 --- a/testing/web-platform/meta/html/dom/interfaces.html.ini +++ b/testing/web-platform/meta/html/dom/interfaces.html.ini @@ -1,6 +1,6 @@ [interfaces.html] type: testharness - prefs: [dom.forms.inputmode:true, dom.dialog_element.enabled:true] + prefs: [dom.forms.inputmode:true, dom.dialog_element.enabled:true, dom.forms.autocomplete.formautofill:true] [Document interface: attribute domain] expected: FAIL diff --git a/testing/web-platform/meta/html/semantics/forms/the-form-element/form-autocomplete.html.ini b/testing/web-platform/meta/html/semantics/forms/the-form-element/form-autocomplete.html.ini index 6103ffd19b1c..4ed983584fa6 100644 --- a/testing/web-platform/meta/html/semantics/forms/the-form-element/form-autocomplete.html.ini +++ b/testing/web-platform/meta/html/semantics/forms/the-form-element/form-autocomplete.html.ini @@ -1,5 +1,6 @@ [form-autocomplete.html] type: testharness + prefs: [dom.forms.autocomplete.formautofill:true] [form autocomplete attribute missing] expected: FAIL From 2e9da9004eb2170ad2f77261e54f6a8fb098bbeb Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Tue, 15 Aug 2017 17:07:20 -0500 Subject: [PATCH 34/87] servo: Merge #18094 - Avoid leaving stale ANCESTOR_WAS_RECONSTRUCTED bits in the tree (from bholley:ancestor_reconstruct); r=emilio https://bugzilla.mozilla.org/show_bug.cgi?id=1390179 Source-Repo: https://github.com/servo/servo Source-Revision: 99b4b7e9602ea1440d2d2ae6c32be30bd0c4f721 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 81f873ffd15c3cf538c5450eff5530fe49cd3c44 --- servo/components/style/data.rs | 12 ++++--- servo/components/style/dom.rs | 7 ++++ servo/components/style/gecko/wrapper.rs | 7 ++++ servo/components/style/traversal.rs | 43 +++++++++++++------------ 4 files changed, 45 insertions(+), 24 deletions(-) diff --git a/servo/components/style/data.rs b/servo/components/style/data.rs index 096f09f00def..35f75b10b3dd 100644 --- a/servo/components/style/data.rs +++ b/servo/components/style/data.rs @@ -106,10 +106,14 @@ impl RestyleData { } /// Sets the flag that tells us whether we've reconstructed an ancestor. - pub fn set_reconstructed_ancestor(&mut self) { - // If it weren't for animation-only traversals, we could assert - // `!self.reconstructed_ancestor()` here. - self.flags.insert(ANCESTOR_WAS_RECONSTRUCTED); + pub fn set_reconstructed_ancestor(&mut self, reconstructed: bool) { + if reconstructed { + // If it weren't for animation-only traversals, we could assert + // `!self.reconstructed_ancestor()` here. + self.flags.insert(ANCESTOR_WAS_RECONSTRUCTED); + } else { + self.flags.remove(ANCESTOR_WAS_RECONSTRUCTED); + } } /// Mark this element as restyled, which is useful to know whether we need diff --git a/servo/components/style/dom.rs b/servo/components/style/dom.rs index 7df9c850fd42..8673a50e2033 100644 --- a/servo/components/style/dom.rs +++ b/servo/components/style/dom.rs @@ -513,6 +513,13 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone + unsafe fn unset_animation_only_dirty_descendants(&self) { } + /// Clear all bits related to dirty descendant. + /// + /// In Gecko, this corresponds to the regular dirty descendants bit, the + /// animation-only dirty descendants bit, and the lazy frame construction + /// descendants bit. + unsafe fn clear_descendants_bits(&self) { self.unset_dirty_descendants(); } + /// Returns true if this element is a visited link. /// /// Servo doesn't support visited styles yet. diff --git a/servo/components/style/gecko/wrapper.rs b/servo/components/style/gecko/wrapper.rs index 80ab02ae5185..e4ccac1a2ba4 100644 --- a/servo/components/style/gecko/wrapper.rs +++ b/servo/components/style/gecko/wrapper.rs @@ -61,6 +61,7 @@ use gecko_bindings::structs::ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SE use gecko_bindings::structs::ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO; use gecko_bindings::structs::ELEMENT_HAS_SNAPSHOT; use gecko_bindings::structs::EffectCompositor_CascadeLevel as CascadeLevel; +use gecko_bindings::structs::NODE_DESCENDANTS_NEED_FRAMES; use gecko_bindings::structs::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE; use gecko_bindings::structs::NODE_IS_NATIVE_ANONYMOUS; use gecko_bindings::structs::nsChangeHint; @@ -1052,6 +1053,12 @@ impl<'le> TElement for GeckoElement<'le> { self.unset_flags(ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO as u32) } + unsafe fn clear_descendants_bits(&self) { + self.unset_flags(ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO as u32 | + ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO as u32 | + NODE_DESCENDANTS_NEED_FRAMES as u32) + } + fn is_visited_link(&self) -> bool { use element_state::IN_VISITED_STATE; self.get_state().intersects(IN_VISITED_STATE) diff --git a/servo/components/style/traversal.rs b/servo/components/style/traversal.rs index 546e254adf42..37abedfc2375 100644 --- a/servo/components/style/traversal.rs +++ b/servo/components/style/traversal.rs @@ -170,6 +170,12 @@ pub trait DomTraversal : Sync { // Invalidate our style, and the one of our siblings and descendants // as needed. data.invalidate_style_if_needed(root, shared_context); + + // Make sure we don't have any stale RECONSTRUCTED_ANCESTOR bits from + // the last traversal (at a potentially-higher root). From the + // perspective of this traversal, the root cannot have reconstructed + // ancestors. + data.restyle.set_reconstructed_ancestor(false); }; let parent = root.traversal_parent(); @@ -591,18 +597,10 @@ where data.clear_restyle_flags_and_damage(); } - // Optionally clear the descendants bit for the traversal type we're in. - if flags.for_animation_only() { - if flags.contains(ClearAnimationOnlyDirtyDescendants) { - unsafe { element.unset_animation_only_dirty_descendants(); } - } - } else { - // There are two cases when we want to clear the dity descendants bit here - // after styling this element. The first case is when we were explicitly - // asked to clear the bit by the caller. - // - // The second case is when this element is the root of a display:none - // subtree, even if the style didn't change (since, if the style did change, + // Optionally clear the descendants bits. + if data.styles.is_display_none() { + // When this element is the root of a display:none subtree, we want to clear + // the bits even if the style didn't change (since, if the style did change, // we'd have already cleared it above). // // This keeps the tree in a valid state without requiring the DOM to check @@ -610,10 +608,18 @@ where // moderately expensive). Instead, DOM implementations can unconditionally // set the dirty descendants bit on any styled parent, and let the traversal // sort it out. - if flags.contains(ClearDirtyDescendants) || - data.styles.is_display_none() { - unsafe { element.unset_dirty_descendants(); } + // + // Note that the NODE_DESCENDANTS_NEED_FRAMES bit should generally only be set + // when appending content beneath an element with a frame (i.e. not + // display:none), so clearing it here isn't strictly necessary, but good + // belt-and-suspenders. + unsafe { element.clear_descendants_bits(); } + } else if flags.for_animation_only() { + if flags.contains(ClearAnimationOnlyDirtyDescendants) { + unsafe { element.unset_animation_only_dirty_descendants(); } } + } else if flags.contains(ClearDirtyDescendants) { + unsafe { element.unset_dirty_descendants(); } } context.thread_local.end_element(element); @@ -793,9 +799,7 @@ where if let Some(ref mut child_data) = child_data { // Propagate the parent restyle hint, that may make us restyle the whole // subtree. - if reconstructed_ancestor { - child_data.restyle.set_reconstructed_ancestor(); - } + child_data.restyle.set_reconstructed_ancestor(reconstructed_ancestor); child_data.restyle.hint.insert(propagated_hint); @@ -845,7 +849,6 @@ where } unsafe { - el.unset_dirty_descendants(); - el.unset_animation_only_dirty_descendants(); + el.clear_descendants_bits(); } } From 01de69cccbe77a7b0e289597529a0568daf32e9b Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Tue, 15 Aug 2017 19:35:04 -0400 Subject: [PATCH 35/87] Backed out changeset 02f07f0cb11d (bug 1388238) because comment 11 wasn't addressed before landing. --- .../formautofill/MasterPassword.jsm | 89 -------------- .../test/unit/test_masterPassword.js | 115 ------------------ .../formautofill/test/unit/xpcshell.ini | 1 - 3 files changed, 205 deletions(-) delete mode 100644 browser/extensions/formautofill/test/unit/test_masterPassword.js diff --git a/browser/extensions/formautofill/MasterPassword.jsm b/browser/extensions/formautofill/MasterPassword.jsm index f3ca2104616e..1186e79c1234 100644 --- a/browser/extensions/formautofill/MasterPassword.jsm +++ b/browser/extensions/formautofill/MasterPassword.jsm @@ -18,97 +18,8 @@ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -XPCOMUtils.defineLazyServiceGetter(this, "cryptoSDR", - "@mozilla.org/login-manager/crypto/SDR;1", - Ci.nsILoginManagerCrypto); this.MasterPassword = { - get _token() { - let tokendb = Cc["@mozilla.org/security/pk11tokendb;1"].createInstance(Ci.nsIPK11TokenDB); - return tokendb.getInternalKeyToken(); - }, - - /** - * @returns {boolean} True if a master password is set and false otherwise. - */ - get isEnabled() { - return this._token.hasPassword; - }, - - /** - * Display the master password login prompt no matter it's logged in or not. - * If an existing MP prompt is already open, the result from it will be used instead. - * - * @returns {Promise} True if it's logged in or no password is set and false - * if it's still not logged in (prompt canceled or other error). - */ - async prompt() { - if (!this.isEnabled) { - return true; - } - - // If a prompt is already showing then wait for and focus it. - if (Services.logins.uiBusy) { - return this.waitForExistingDialog(); - } - - let token = this._token; - try { - // 'true' means always prompt for token password. User will be prompted until - // clicking 'Cancel' or entering the correct password. - token.login(true); - } catch (e) { - // An exception will be thrown if the user cancels the login prompt dialog. - // User is also logged out. - } - - // If we triggered a master password prompt, notify observers. - if (token.isLoggedIn()) { - Services.obs.notifyObservers(null, "passwordmgr-crypto-login"); - } else { - Services.obs.notifyObservers(null, "passwordmgr-crypto-loginCanceled"); - } - - return token.isLoggedIn(); - }, - - /** - * Decrypts cipherText. - * - * @param {string} cipherText Encrypted string including the algorithm details. - * @param {boolean} reauth True if we want to force the prompt to show up - * even if the user is already logged in. - * @returns {Promise} resolves to the decrypted string, or rejects otherwise. - */ - async decrypt(cipherText, reauth = false) { - let loggedIn = false; - if (reauth) { - loggedIn = await this.prompt(); - } else { - loggedIn = await this.waitForExistingDialog(); - } - - if (!loggedIn) { - throw Components.Exception("User canceled master password entry", Cr.NS_ERROR_ABORT); - } - - return cryptoSDR.decrypt(cipherText); - }, - - /** - * Encrypts a string and returns cipher text containing algorithm information used for decryption. - * - * @param {string} plainText Original string without encryption. - * @returns {Promise} resolves to the encrypted string (with algorithm), otherwise rejects. - */ - async encrypt(plainText) { - if (Services.logins.uiBusy && !await this.waitForExistingDialog()) { - throw Components.Exception("User canceled master password entry", Cr.NS_ERROR_ABORT); - } - - return cryptoSDR.encrypt(plainText); - }, - /** * Resolve when master password dialogs are closed, immediately if none are open. * diff --git a/browser/extensions/formautofill/test/unit/test_masterPassword.js b/browser/extensions/formautofill/test/unit/test_masterPassword.js deleted file mode 100644 index 9783250274eb..000000000000 --- a/browser/extensions/formautofill/test/unit/test_masterPassword.js +++ /dev/null @@ -1,115 +0,0 @@ -/** - * Tests of MasterPassword.jsm - */ - -"use strict"; -const {MockRegistrar} = - Cu.import("resource://testing-common/MockRegistrar.jsm", {}); -let {MasterPassword} = Cu.import("resource://formautofill/MasterPassword.jsm", {}); - -const TESTCASES = [{ - description: "With master password set", - masterPassword: "fakemp", - mpEnabled: true, -}, -{ - description: "Without master password set", - masterPassword: "", // "" means no master password - mpEnabled: false, -}]; - - -// Tests that PSM can successfully ask for a password from the user and relay it -// back to NSS. Does so by mocking out the actual dialog and "filling in" the -// password. Also tests that providing an incorrect password will fail (well, -// technically the user will just get prompted again, but if they then cancel -// the dialog the overall operation will fail). - -let gMockPrompter = { - passwordToTry: null, - numPrompts: 0, - - // This intentionally does not use arrow function syntax to avoid an issue - // where in the context of the arrow function, |this != gMockPrompter| due to - // how objects get wrapped when going across xpcom boundaries. - promptPassword(dialogTitle, text, password, checkMsg, checkValue) { - this.numPrompts++; - if (this.numPrompts > 1) { // don't keep retrying a bad password - return false; - } - equal(text, - "Please enter the master password for the Software Security Device.", - "password prompt text should be as expected"); - equal(checkMsg, null, "checkMsg should be null"); - ok(this.passwordToTry, "passwordToTry should be non-null"); - password.value = this.passwordToTry; - return true; - }, - - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPrompt]), -}; - -// Mock nsIWindowWatcher. PSM calls getNewPrompter on this to get an nsIPrompt -// to call promptPassword. We return the mock one, above. -let gWindowWatcher = { - getNewPrompter: () => gMockPrompter, - QueryInterface: XPCOMUtils.generateQI([Ci.nsIWindowWatcher]), -}; - -// Ensure that the appropriate initialization has happened. -do_get_profile(); - -let windowWatcherCID = - MockRegistrar.register("@mozilla.org/embedcomp/window-watcher;1", - gWindowWatcher); -do_register_cleanup(() => { - MockRegistrar.unregister(windowWatcherCID); -}); - -TESTCASES.forEach(testcase => { - let token = MasterPassword._token; - - add_task(async function test_encrypt_decrypt() { - do_print("Starting testcase: " + testcase.description); - token.initPassword(testcase.masterPassword); - - // Test only: Force the token login without asking for master password - token.login(/* force */ false); - Assert.equal(testcase.mpEnabled, token.isLoggedIn(), "Token should now be logged into"); - Assert.equal(MasterPassword.isEnabled, testcase.mpEnabled); - - let testText = "test string"; - let cipherText = await MasterPassword.encrypt(testText); - Assert.notEqual(testText, cipherText); - let plainText = await MasterPassword.decrypt(cipherText); - Assert.equal(testText, plainText); - if (token.isLoggedIn()) { - // Reset state. - gMockPrompter.numPrompts = 0; - token.logoutSimple(); - - ok(!token.isLoggedIn(), - "Token should be logged out after calling logoutSimple()"); - - // Try with the correct password. - gMockPrompter.passwordToTry = testcase.masterPassword; - await MasterPassword.encrypt(testText); - Assert.equal(gMockPrompter.numPrompts, 1, "should have prompted for encryption"); - - // Reset state. - gMockPrompter.numPrompts = 0; - token.logoutSimple(); - - try { - // Try with the incorrect password. - gMockPrompter.passwordToTry = "XXX"; - await MasterPassword.decrypt(cipherText); - throw new Error("Not receiving canceled master password error"); - } catch (e) { - Assert.equal(e.message, "User canceled master password entry"); - } - } - - token.reset(); - }); -}); diff --git a/browser/extensions/formautofill/test/unit/xpcshell.ini b/browser/extensions/formautofill/test/unit/xpcshell.ini index da6e2e2818b6..ffa8a4dcf93c 100644 --- a/browser/extensions/formautofill/test/unit/xpcshell.ini +++ b/browser/extensions/formautofill/test/unit/xpcshell.ini @@ -32,7 +32,6 @@ support-files = [test_isCJKName.js] [test_isFieldEligibleForAutofill.js] [test_markAsAutofillField.js] -[test_masterPassword.js] [test_migrateRecords.js] [test_nameUtils.js] [test_onFormSubmitted.js] From 5a58ca2a390fb23baa1c0cec7a4fff47ef72b21d Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Wed, 16 Aug 2017 09:14:18 +0900 Subject: [PATCH 36/87] Bug 1387946 - Set/reset transition-property to cancel/create transition properly. r=birtles These test cases rely on the behavior that different lengths repeated list can not be transitioned on Gecko. But it's not clear the behavior is reasonable or not. The test cases here should not depend on the behavior. MozReview-Commit-ID: 19vI0TFMzfN --- .../test/test_transitions_per_property.html | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/layout/style/test/test_transitions_per_property.html b/layout/style/test/test_transitions_per_property.html index 990b2c599751..970c98224235 100644 --- a/layout/style/test/test_transitions_per_property.html +++ b/layout/style/test/test_transitions_per_property.html @@ -63,14 +63,6 @@ const isServo = SpecialPowers.DOMWindowUtils.isStyledByServo; // The following properties will be skipped while using Servo backend. var skippedProperties = { - "background-position": true, // Bug 1387946 - "background-position-x": true, // Bug 1387946 - "background-position-y": true, // Bug 1387946 - "background-size": true, // Bug 1387946 - "mask-position": true, // Bug 1387946 - "mask-position-x": true, // Bug 1387946 - "mask-position-y": true, // Bug 1387946 - "mask-size": true, // Bug 1387946 "box-shadow": true, // Bug 1387973 "stroke-dasharray": true, // Bug 1387986 "stroke-dashoffset": true, // Bug 1369614 @@ -2338,36 +2330,47 @@ function test_background_position_coord_transition(prop) { "calc(-5px + 80%)", "calc(40px + 20%)"); + div.style.setProperty("transition-property", "none", ""); div.style.setProperty(prop, "10px, 50px, 30px", ""); is(cs.getPropertyValue(prop), "10px, 50px, 30px", "property " + prop + ": computed value before transition"); + div.style.setProperty("transition-property", prop, ""); div.style.setProperty(prop, "50px, 70px, 30px", ""); is(cs.getPropertyValue(prop), "20px, 55px, 30px", "property " + prop + ": interpolation of lists of lengths"); check_distance(prop, "10px, 50px, 30px", "20px, 55px, 30px", "50px, 70px, 30px"); + + div.style.setProperty("transition-property", "none", ""); div.style.setProperty(prop, "10px, 50%, 30%, 5px", ""); is(cs.getPropertyValue(prop), "10px, 50%, 30%, 5px", "property " + prop + ": computed value before transition"); + div.style.setProperty("transition-property", prop, ""); div.style.setProperty(prop, "50px, 70%, 30%, 25px", ""); is(cs.getPropertyValue(prop), "20px, 55%, 30%, 10px", "property " + prop + ": interpolation of lists of lengths and percents"); check_distance(prop, "10px, 50%, 30%, 5px", "20px, 55%, 30%, 10px", "50px, 70%, 30%, 25px"); + + div.style.setProperty("transition-property", "none", ""); div.style.setProperty(prop, "20%, 8px", ""); is(cs.getPropertyValue(prop), "20%, 8px", "property " + prop + ": computed value before transition"); + div.style.setProperty("transition-property", prop, ""); div.style.setProperty(prop, "12px, 40%", ""); is(cs.getPropertyValue(prop), "calc(3px + 15%), calc(6px + 10%)", "property " + prop + ": interpolation that computes to calc()"); check_distance(prop, "20%, 8px", "calc(3px + 15%), calc(6px + 10%)", "12px, 40%"); + + div.style.setProperty("transition-property", "none", ""); div.style.setProperty(prop, "calc(20% + 40px), 8px, calc(20px + 12%)", ""); is(cs.getPropertyValue(prop), "calc(40px + 20%), 8px, calc(20px + 12%)", "property " + prop + ": computed value before transition"); + div.style.setProperty("transition-property", prop, ""); div.style.setProperty(prop, "12px, calc(20%), calc(8px + 20%)", ""); is(cs.getPropertyValue(prop), "calc(33px + 15%), calc(6px + 5%), calc(17px + 14%)", "property " + prop + ": interpolation that computes to calc()"); @@ -2472,9 +2475,11 @@ function test_background_position_size_common(prop, doesPropTakeListValues, // Test list values, if appropriate if (doesPropTakeListValues) { + div.style.setProperty("transition-property", "none", ""); div.style.setProperty(prop, "10px 40px, 50px 50px, 30px 20px", ""); is(cs.getPropertyValue(prop), "10px 40px, 50px 50px, 30px 20px", "property " + prop + ": computed value before transition"); + div.style.setProperty("transition-property", prop, ""); div.style.setProperty(prop, "50px 20px, 70px 50px, 30px 40px", ""); is(cs.getPropertyValue(prop), "20px 35px, 55px 50px, 30px 25px", "property " + prop + ": interpolation of lists of lengths"); @@ -2483,9 +2488,11 @@ function test_background_position_size_common(prop, doesPropTakeListValues, "20px 35px, 55px 50px, 30px 25px", "50px 20px, 70px 50px, 30px 40px"); } + div.style.setProperty("transition-property", "none", ""); div.style.setProperty(prop, "10px 40%, 50% 50px, 30% 20%, 5px 10px", ""); is(cs.getPropertyValue(prop), "10px 40%, 50% 50px, 30% 20%, 5px 10px", "property " + prop + ": computed value before transition"); + div.style.setProperty("transition-property", prop, ""); div.style.setProperty(prop, "50px 20%, 70% 50px, 30% 40%, 25px 50px", ""); is(cs.getPropertyValue(prop), "20px 35%, 55% 50px, 30% 25%, 10px 20px", "property " + prop + ": interpolation of lists of lengths and percents"); @@ -2494,9 +2501,11 @@ function test_background_position_size_common(prop, doesPropTakeListValues, "20px 35%, 55% 50px, 30% 25%, 10px 20px", "50px 20%, 70% 50px, 30% 40%, 25px 50px"); } + div.style.setProperty("transition-property", "none", ""); div.style.setProperty(prop, "20% 40%, 8px 12px", ""); is(cs.getPropertyValue(prop), "20% 40%, 8px 12px", "property " + prop + ": computed value before transition"); + div.style.setProperty("transition-property", prop, ""); div.style.setProperty(prop, "12px 20px, 40% 16%", ""); is(cs.getPropertyValue(prop), "calc(3px + 15%) calc(5px + 30%), calc(6px + 10%) calc(9px + 4%)", "property " + prop + ": interpolation that computes to calc()"); @@ -2505,9 +2514,11 @@ function test_background_position_size_common(prop, doesPropTakeListValues, "calc(3px + 15%) calc(5px + 30%), calc(6px + 10%) calc(9px + 4%)", "12px 20px, 40% 16%"); } + div.style.setProperty("transition-property", "none", ""); div.style.setProperty(prop, "calc(20% + 40px) calc(40px + 40%), 8px 12%, calc(20px + 12%) calc(24px + 8%)", ""); is(cs.getPropertyValue(prop), "calc(40px + 20%) calc(40px + 40%), 8px 12%, calc(20px + 12%) calc(24px + 8%)", "property " + prop + ": computed value before transition"); + div.style.setProperty("transition-property", prop, ""); div.style.setProperty(prop, "12px 20%, calc(20%) calc(16px + 60%), calc(8px + 20%) calc(40px + 16%)", ""); is(cs.getPropertyValue(prop), "calc(33px + 15%) calc(30px + 35%), calc(6px + 5%) calc(4px + 24%), calc(17px + 14%) calc(28px + 10%)", "property " + prop + ": interpolation that computes to calc()"); From 54b4843fe0606fef8567600df17f45365372e961 Mon Sep 17 00:00:00 2001 From: Jared Wein Date: Tue, 15 Aug 2017 16:51:40 -0400 Subject: [PATCH 37/87] Bug 1390283 - Fix the color of the Pocket icon. r=sfoster MozReview-Commit-ID: KUQgjp8sfbE --HG-- extra : rebase_source : f482044047b0cd5f1e3ce7d660764df5e2cff88e --- browser/extensions/pocket/skin/shared/pocket.css | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/browser/extensions/pocket/skin/shared/pocket.css b/browser/extensions/pocket/skin/shared/pocket.css index 9ff7c3752631..9e4740678d96 100644 --- a/browser/extensions/pocket/skin/shared/pocket.css +++ b/browser/extensions/pocket/skin/shared/pocket.css @@ -23,7 +23,7 @@ panelmultiview[mainViewId=PanelUI-pocketView] > .panel-viewcontainer > .panel-vi } #pocket-button-box[open="true"] > #pocket-button { - fill: rgb(213,32,20); + fill: #ef4056; fill-opacity: 1; } @@ -99,7 +99,7 @@ panelmultiview[mainViewId=PanelUI-pocketView] > .panel-viewcontainer > .panel-vi animation-timing-function: steps(12); animation-duration: 200ms; background-image: url("chrome://pocket-shared/skin/pocket-animation.svg"); - fill: rgb(213,32,20); + fill: #ef4056; -moz-context-properties: fill; width: 260px; } @@ -122,11 +122,11 @@ panelmultiview[mainViewId=PanelUI-pocketView] > .panel-viewcontainer > .panel-vi fill: inherit; } 50% { - fill: rgb(213,32,20); + fill: #ef4056; } to { transform: translateX(-1056px); - fill: rgb(213,32,20); + fill: #ef4056; } } @@ -139,11 +139,11 @@ panelmultiview[mainViewId=PanelUI-pocketView] > .panel-viewcontainer > .panel-vi fill: inherit; } 50% { - fill: rgb(213,32,20); + fill: #ef4056; } to { transform: scaleX(-1) translateX(-1056px); - fill: rgb(213,32,20); + fill: #ef4056; } } @@ -162,7 +162,7 @@ panelmultiview[mainViewId=PanelUI-pocketView] > .panel-viewcontainer > .panel-vi then no transition will occur and thus no transitionend event. */ @keyframes library-pocket-fade { from { - fill: rgb(213,32,20); + fill: #ef4056; } to { fill: inherit; @@ -218,7 +218,7 @@ panelmultiview[mainViewId=PanelUI-pocketView] > .panel-viewcontainer > .panel-vi } #pocket-button[cui-areatype="toolbar"][open] { - fill: rgb(213,32,20); + fill: #ef4056; } @media not all and (min-resolution: 1.1dppx) { From 93e68c316b5643cee6befd287e2885e8c9aa7f63 Mon Sep 17 00:00:00 2001 From: Alex Touchet Date: Tue, 15 Aug 2017 18:21:51 -0500 Subject: [PATCH 38/87] servo: Merge #18040 - Update Firefox version in user agent (from atouchet:user-agent); r=jdm GitHub has started throwing warnings about using an outdated version of Firefox when loaded with Servo. I am assuming that this is due to Servo using Firefox 37.0 in its user agent which was set in 2015 and hasn't been updated since then. I don't know if updating this should cause any site compatibility issues or not. --- - [ ] `./mach build -d` does not report any errors - [ ] `./mach test-tidy` does not report any errors - [ ] These changes fix #__ (github issue number if applicable). - [ ] There are tests for these changes OR - [ ] These changes do not require tests because _____ Source-Repo: https://github.com/servo/servo Source-Revision: 1c4076a75993001eba1f467b1fe0576f62238c36 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : fc24d21e2585f07c1fd7b1203a751bf983505426 --- servo/components/config/opts.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/servo/components/config/opts.rs b/servo/components/config/opts.rs index e94eef2772c8..96ac781fff0b 100644 --- a/servo/components/config/opts.rs +++ b/servo/components/config/opts.rs @@ -453,22 +453,22 @@ enum UserAgent { fn default_user_agent_string(agent: UserAgent) -> &'static str { #[cfg(all(target_os = "linux", target_arch = "x86_64"))] const DESKTOP_UA_STRING: &'static str = - "Mozilla/5.0 (X11; Linux x86_64; rv:37.0) Servo/1.0 Firefox/37.0"; + "Mozilla/5.0 (X11; Linux x86_64; rv:55.0) Servo/1.0 Firefox/55.0"; #[cfg(all(target_os = "linux", not(target_arch = "x86_64")))] const DESKTOP_UA_STRING: &'static str = - "Mozilla/5.0 (X11; Linux i686; rv:37.0) Servo/1.0 Firefox/37.0"; + "Mozilla/5.0 (X11; Linux i686; rv:55.0) Servo/1.0 Firefox/55.0"; #[cfg(all(target_os = "windows", target_arch = "x86_64"))] const DESKTOP_UA_STRING: &'static str = - "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:37.0) Servo/1.0 Firefox/37.0"; + "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:55.0) Servo/1.0 Firefox/55.0"; #[cfg(all(target_os = "windows", not(target_arch = "x86_64")))] const DESKTOP_UA_STRING: &'static str = - "Mozilla/5.0 (Windows NT 6.1; rv:37.0) Servo/1.0 Firefox/37.0"; + "Mozilla/5.0 (Windows NT 6.1; rv:55.0) Servo/1.0 Firefox/55.0"; #[cfg(not(any(target_os = "linux", target_os = "windows")))] // Neither Linux nor Windows, so maybe OS X, and if not then OS X is an okay fallback. const DESKTOP_UA_STRING: &'static str = - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:37.0) Servo/1.0 Firefox/37.0"; + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:55.0) Servo/1.0 Firefox/55.0"; match agent { @@ -476,7 +476,7 @@ fn default_user_agent_string(agent: UserAgent) -> &'static str { DESKTOP_UA_STRING } UserAgent::Android => { - "Mozilla/5.0 (Android; Mobile; rv:37.0) Servo/1.0 Firefox/37.0" + "Mozilla/5.0 (Android; Mobile; rv:55.0) Servo/1.0 Firefox/55.0" } } } From 075f82ba4d9355ae721df183b51044e124625aad Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Fri, 11 Aug 2017 09:18:04 -0700 Subject: [PATCH 39/87] Bug 1389417 - Disable problematic extensions when running `hg update`; r=ted We correctly worked around problems for `hg pull` but not for `hg update`. Make the workaround consistent. MozReview-Commit-ID: 7A4dgANO0ip --HG-- extra : rebase_source : fd4b90200ab3ce07a3921a02ae28f5a7a0c3d83c --- python/mozboot/mozboot/bootstrap.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/python/mozboot/mozboot/bootstrap.py b/python/mozboot/mozboot/bootstrap.py index 47adc1033b15..409cadb2028c 100644 --- a/python/mozboot/mozboot/bootstrap.py +++ b/python/mozboot/mozboot/bootstrap.py @@ -353,8 +353,6 @@ def configure_mercurial(hg, root_state_dir): def update_mercurial_repo(hg, url, dest, revision): """Perform a clone/pull + update of a Mercurial repository.""" - args = [hg] - # Disable common extensions whose older versions may cause `hg` # invocations to abort. disable_exts = [ @@ -368,22 +366,31 @@ def update_mercurial_repo(hg, url, dest, revision): 'push-to-try', 'reviewboard', ] - for ext in disable_exts: - args.extend(['--config', 'extensions.%s=!' % ext]) + + def disable_extensions(args): + for ext in disable_exts: + args.extend(['--config', 'extensions.%s=!' % ext]) + + pull_args = [hg] + disable_extensions(pull_args) if os.path.exists(dest): - args.extend(['pull', url]) + pull_args.extend(['pull', url]) cwd = dest else: - args.extend(['clone', '--noupdate', url, dest]) + pull_args.extend(['clone', '--noupdate', url, dest]) cwd = '/' + update_args = [hg] + disable_extensions(update_args) + update_args.extend(['update', '-r', revision]) + print('=' * 80) print('Ensuring %s is up to date at %s' % (url, dest)) try: - subprocess.check_call(args, cwd=cwd) - subprocess.check_call([hg, 'update', '-r', revision], cwd=dest) + subprocess.check_call(pull_args, cwd=cwd) + subprocess.check_call(update_args, cwd=dest) finally: print('=' * 80) From 671b0d46aac57c6def96c935b4e4605c63513502 Mon Sep 17 00:00:00 2001 From: Ethan Lin Date: Mon, 14 Aug 2017 16:10:21 +0800 Subject: [PATCH 40/87] Bug 1389433 - Fix the offset of the fallback image for layers-free. r=mtseng Originally we use the nsDisplayItem::ToReferenceFrame() to get the offset. But the function doesn't consider some style effects. We should take the top-left corner of the display item bounds as the offset. MozReview-Commit-ID: LiPcA0vjoD7 --HG-- extra : rebase_source : 2711ca3d1b05c3f0aae6943f959b9ab41b273200 --- gfx/layers/wr/WebRenderLayerManager.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gfx/layers/wr/WebRenderLayerManager.cpp b/gfx/layers/wr/WebRenderLayerManager.cpp index d456926c24c1..83f072875b28 100644 --- a/gfx/layers/wr/WebRenderLayerManager.cpp +++ b/gfx/layers/wr/WebRenderLayerManager.cpp @@ -437,9 +437,8 @@ WebRenderLayerManager::GenerateFallbackData(nsDisplayItem* aItem, return nullptr; } - nsPoint shift = clippedBounds.TopLeft() - itemBounds.TopLeft(); aOffset = ViewAs( - LayoutDevicePoint::FromAppUnits(aItem->ToReferenceFrame() + shift, appUnitsPerDevPixel), + LayoutDevicePoint::FromAppUnits(clippedBounds.TopLeft(), appUnitsPerDevPixel), PixelCastJustification::WebRenderHasUnitResolution); nsRegion invalidRegion; From 945b0e20e24e8efe20cf0f39d742f0a44cb1c342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 15 Aug 2017 19:29:45 -0500 Subject: [PATCH 41/87] servo: Merge #18095 - stylo: Remove some unused FFI functions (from emilio:unused); r=bholley Bug: 1390650 Reviewed-by: bholley MozReview-Commit-ID: K9fXGRmgkr4 Source-Repo: https://github.com/servo/servo Source-Revision: eba896157edf3ba4f0d65b68eb63dd9cd40cdce4 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 3086d90effa80d2ed08fad7d1196e5ebca04c888 --- .../style/gecko/generated/bindings.rs | 23 ------------------- .../components/style/gecko/restyle_damage.rs | 9 -------- .../components/style/servo/restyle_damage.rs | 5 ---- 3 files changed, 37 deletions(-) diff --git a/servo/components/style/gecko/generated/bindings.rs b/servo/components/style/gecko/generated/bindings.rs index 368623c3dd5e..bd7d263e1593 100644 --- a/servo/components/style/gecko/generated/bindings.rs +++ b/servo/components/style/gecko/generated/bindings.rs @@ -511,12 +511,6 @@ extern "C" { extern "C" { pub fn Servo_StyleSet_Drop(ptr: RawServoStyleSetOwned); } -extern "C" { - pub fn Gecko_ChildrenCount(node: RawGeckoNodeBorrowed) -> u32; -} -extern "C" { - pub fn Gecko_NodeIsElement(node: RawGeckoNodeBorrowed) -> bool; -} extern "C" { pub fn Gecko_IsInDocument(node: RawGeckoNodeBorrowed) -> bool; } @@ -595,9 +589,6 @@ extern "C" { extern "C" { pub fn Gecko_DocumentState(aDocument: *const nsIDocument) -> u64; } -extern "C" { - pub fn Gecko_IsTextNode(node: RawGeckoNodeBorrowed) -> bool; -} extern "C" { pub fn Gecko_IsRootElement(element: RawGeckoElementBorrowed) -> bool; } @@ -605,16 +596,9 @@ extern "C" { pub fn Gecko_MatchesElement(type_: CSSPseudoClassType, element: RawGeckoElementBorrowed) -> bool; } -extern "C" { - pub fn Gecko_LocalName(element: RawGeckoElementBorrowed) -> *mut nsIAtom; -} extern "C" { pub fn Gecko_Namespace(element: RawGeckoElementBorrowed) -> *mut nsIAtom; } -extern "C" { - pub fn Gecko_GetElementId(element: RawGeckoElementBorrowed) - -> *mut nsIAtom; -} extern "C" { pub fn Gecko_MatchLang(element: RawGeckoElementBorrowed, override_lang: *mut nsIAtom, @@ -1073,9 +1057,6 @@ extern "C" { type_: nsStyleContentType) -> *mut nsStyleContentData_CounterFunction; } -extern "C" { - pub fn Gecko_GetNodeFlags(node: RawGeckoNodeBorrowed) -> u32; -} extern "C" { pub fn Gecko_SetNodeFlags(node: RawGeckoNodeBorrowed, flags: u32); } @@ -1105,10 +1086,6 @@ extern "C" { any_style_changed: *mut bool) -> nsChangeHint; } -extern "C" { - pub fn Gecko_HintsHandledForDescendants(aHint: nsChangeHint) - -> nsChangeHint; -} extern "C" { pub fn Gecko_GetElementSnapshot(table: *const ServoElementSnapshotTable, element: RawGeckoElementBorrowed) diff --git a/servo/components/style/gecko/restyle_damage.rs b/servo/components/style/gecko/restyle_damage.rs index b0f606630678..c5b10737d8e9 100644 --- a/servo/components/style/gecko/restyle_damage.rs +++ b/servo/components/style/gecko/restyle_damage.rs @@ -100,15 +100,6 @@ impl GeckoRestyleDamage { pub fn reconstruct() -> Self { GeckoRestyleDamage(structs::nsChangeHint_nsChangeHint_ReconstructFrame) } - - /// Assuming |self| is applied to an element, returns the set of damage that - /// would be superfluous to apply for descendants. - pub fn handled_for_descendants(self) -> Self { - let hint = unsafe { - bindings::Gecko_HintsHandledForDescendants(self.0) - }; - GeckoRestyleDamage(hint) - } } impl Default for GeckoRestyleDamage { diff --git a/servo/components/style/servo/restyle_damage.rs b/servo/components/style/servo/restyle_damage.rs index 0be480a24247..1b7e4636e130 100644 --- a/servo/components/style/servo/restyle_damage.rs +++ b/servo/components/style/servo/restyle_damage.rs @@ -135,11 +135,6 @@ impl ServoRestyleDamage { } } } - - /// Servo doesn't implement this optimization. - pub fn handled_for_descendants(self) -> Self { - Self::empty() - } } impl Default for ServoRestyleDamage { From 44eb96d1816f8ca3461e9b297bbaff082a13f9a4 Mon Sep 17 00:00:00 2001 From: Wes Kocher Date: Tue, 15 Aug 2017 18:42:01 -0700 Subject: [PATCH 42/87] Backed out changeset 5b4b8c71b9fb (bug 1388238) because the other half of the bug got backed out a=backout MozReview-Commit-ID: EgCYWjELSQA --- .../formautofill/MasterPassword.jsm | 83 ------------------- .../components/prompts/src/CommonDialog.jsm | 4 - 2 files changed, 87 deletions(-) delete mode 100644 browser/extensions/formautofill/MasterPassword.jsm diff --git a/browser/extensions/formautofill/MasterPassword.jsm b/browser/extensions/formautofill/MasterPassword.jsm deleted file mode 100644 index 1186e79c1234..000000000000 --- a/browser/extensions/formautofill/MasterPassword.jsm +++ /dev/null @@ -1,83 +0,0 @@ -/* 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/. */ - -/** - * Helpers for the Master Password Dialog. - * In the future the Master Password implementation may move here. - */ - -"use strict"; - -this.EXPORTED_SYMBOLS = [ - "MasterPassword", -]; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - - -this.MasterPassword = { - /** - * Resolve when master password dialogs are closed, immediately if none are open. - * - * An existing MP dialog will be focused and will request attention. - * - * @returns {Promise} - * Resolves with whether the user is logged in to MP. - */ - async waitForExistingDialog() { - if (!Services.logins.uiBusy) { - log.debug("waitForExistingDialog: Dialog isn't showing. isLoggedIn:", - Services.logins.isLoggedIn); - return Services.logins.isLoggedIn; - } - - return new Promise((resolve) => { - log.debug("waitForExistingDialog: Observing the open dialog"); - let observer = { - QueryInterface: XPCOMUtils.generateQI([ - Ci.nsIObserver, - Ci.nsISupportsWeakReference, - ]), - - observe(subject, topic, data) { - log.debug("waitForExistingDialog: Got notification:", topic); - // Only run observer once. - Services.obs.removeObserver(this, "passwordmgr-crypto-login"); - Services.obs.removeObserver(this, "passwordmgr-crypto-loginCanceled"); - if (topic == "passwordmgr-crypto-loginCanceled") { - resolve(false); - return; - } - - resolve(true); - }, - }; - - // Possible leak: it's possible that neither of these notifications - // will fire, and if that happens, we'll leak the observer (and - // never return). We should guarantee that at least one of these - // will fire. - // See bug XXX. - Services.obs.addObserver(observer, "passwordmgr-crypto-login"); - Services.obs.addObserver(observer, "passwordmgr-crypto-loginCanceled"); - - // Focus and draw attention to the existing master password dialog for the - // occassions where it's not attached to the current window. - let promptWin = Services.wm.getMostRecentWindow("prompt:promptPassword"); - promptWin.focus(); - promptWin.getAttention(); - }); - }, -}; - -XPCOMUtils.defineLazyGetter(this, "log", () => { - let ConsoleAPI = Cu.import("resource://gre/modules/Console.jsm", {}).ConsoleAPI; - return new ConsoleAPI({ - maxLogLevelPref: "masterPassword.loglevel", - prefix: "Master Password", - }); -}); diff --git a/toolkit/components/prompts/src/CommonDialog.jsm b/toolkit/components/prompts/src/CommonDialog.jsm index ab66a5ce3782..7db9f6076076 100644 --- a/toolkit/components/prompts/src/CommonDialog.jsm +++ b/toolkit/components/prompts/src/CommonDialog.jsm @@ -91,10 +91,6 @@ CommonDialog.prototype = { throw "unknown dialog type"; } - if (xulDialog) { - xulDialog.setAttribute("windowtype", "prompt:" + this.args.promptType); - } - // set the document title let title = this.args.title; // OS X doesn't have a title on modal dialogs, this is hidden on other platforms. From 2a0da07c9063972063cbd27f20aa1d817d1d3037 Mon Sep 17 00:00:00 2001 From: gasolin Date: Mon, 14 Aug 2017 15:38:35 +0800 Subject: [PATCH 43/87] Bug 1390042 - [Onboarding] The complete sign is not shown at first time when set the performance tour as the first item;r=rexboy MozReview-Commit-ID: AVv4pcBfTbf --HG-- extra : rebase_source : 9473bdec0897f284838433b3072cf31ff057fa14 --- .../extensions/onboarding/content/onboarding.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/browser/extensions/onboarding/content/onboarding.js b/browser/extensions/onboarding/content/onboarding.js index 450438c5b4e8..8e33bee413c1 100644 --- a/browser/extensions/onboarding/content/onboarding.js +++ b/browser/extensions/onboarding/content/onboarding.js @@ -492,12 +492,6 @@ class Onboarding { this.gotoPage(tourId); this._removeTourFromNotificationQueue(tourId); break; - // These tours are tagged completed instantly upon showing. - case "onboarding-tour-default-browser": - case "onboarding-tour-sync": - case "onboarding-tour-performance": - this.setToursCompleted([ evt.target.id ]); - break; } let classList = evt.target.classList; if (classList.contains("onboarding-tour-item")) { @@ -557,6 +551,15 @@ class Onboarding { li.classList.remove("onboarding-active"); } } + + switch (tourId) { + // These tours should tagged completed instantly upon showing. + case "onboarding-tour-default-browser": + case "onboarding-tour-sync": + case "onboarding-tour-performance": + this.setToursCompleted([tourId]); + break; + } } isTourCompleted(tourId) { From 5fa9ec9b19539a0a8f6c679af76aab35a9358912 Mon Sep 17 00:00:00 2001 From: Mantaroh Yoshinaga Date: Wed, 16 Aug 2017 08:56:59 +0900 Subject: [PATCH 44/87] Bug 1390357 - Switch test result for clamping RGBA on stylo and gecko by using preference. r=birtles MozReview-Commit-ID: I12SQwmqtr0 --HG-- extra : rebase_source : 63eba3dcdbe6b507047cc97828bdb4afbfda965d --- dom/smil/test/db_smilCSSFromBy.js | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/dom/smil/test/db_smilCSSFromBy.js b/dom/smil/test/db_smilCSSFromBy.js index f8b36e70adaa..0a0c4699d418 100644 --- a/dom/smil/test/db_smilCSSFromBy.js +++ b/dom/smil/test/db_smilCSSFromBy.js @@ -8,6 +8,8 @@ // NOTE: This js file requires db_smilCSSPropertyList.js +const isServoEnabled = SpecialPowers.DOMWindowUtils.isStyledByServo; + // Lists of testcases for re-use across multiple properties of the same type var _fromByTestLists = { @@ -24,17 +26,30 @@ var _fromByTestLists = { midComp: "rgba(45, 48, 52, 0.6)", // (rgb(10, 20, 30) * 0.2 + rgb(50, 50, 50) * 1) / 1.0 toComp: "rgb(52, 54, 56)"}), - // Note: technically, the "from" and "by" values in the test case below - // would overflow the maxium color-channel values when added together. + + // The "from" and "by" values in the test case below overflow the maxium + // color-channel values when added together. // (e.g. for red [ignoring alpha for now], 100 + 240 = 340 which is > 255) // The SVG Animation spec says we should clamp color values "as late as - // possible," i.e. allow the channel overflow and clamp at paint-time. - // But for now, we instead clamp the implicit "to" value for the animation - // and interpolate up to that clamped result. + // possible" i.e. allow the channel overflow and clamp at paint-time. + // + // Servo does this, and gives us: + // + // to-value = (rgb(100, 100, 100) * 0.6 + rgb(240, 240, 240) * 1.0)) * 1 + // = rgb(300, 300, 300) + // midComp = (rgb(100, 100, 100) * 0.6 * 0.5 + rgb(300, 300, 300) * 1.0 * 0.5) * (1 / 0.8) + // = rgb(225, 225, 225) + // + // Gecko, however, clamps the "to" value and interpolates up to that + // clamped result giving: + // + // midComp = (rgb(100, 100, 100) * 0.6 * 0.5 + rgb(255, 255, 255) * 1.0 * 0.5) * (1 / 0.8) + // = rgb(197, 197, 197) + // new AnimTestcaseFromBy("rgba(100, 100, 100, 0.6)", "rgba(240, 240, 240, 1)", - // (rgb(100, 100, 100) * 0.6 * 0.5 + rgb(255, 255, 255) * 1.0 * 0.5) * (1 / 0.8) - { midComp: "rgba(197, 197, 197, 0.8)", - // (rgb(100, 100, 100) * 0.6 + rgb(240, 240, 240) is overflowed + { midComp: + isServoEnabled ? "rgba(225, 225, 225, 0.8)" + : "rgba(197, 197, 197, 0.8)", toComp: "rgb(255, 255, 255)"}), ], lengthNoUnits: [ From 56f78822365d31465399355f8be675d218d17a59 Mon Sep 17 00:00:00 2001 From: gasolin Date: Fri, 11 Aug 2017 17:11:24 +0800 Subject: [PATCH 45/87] Bug 1387969 - show scrollbar when onboarding tour description is longer;r=rexboy MozReview-Commit-ID: 12uhcn9EWJZ --HG-- extra : rebase_source : 4ce0e7c35ee6003a508e9aa008ef5441e6692d4a --- browser/extensions/onboarding/content/onboarding.css | 2 ++ 1 file changed, 2 insertions(+) diff --git a/browser/extensions/onboarding/content/onboarding.css b/browser/extensions/onboarding/content/onboarding.css index 0bdd3f220805..85423a58877f 100644 --- a/browser/extensions/onboarding/content/onboarding.css +++ b/browser/extensions/onboarding/content/onboarding.css @@ -251,6 +251,8 @@ line-height: 22px; padding-inline-start: 40px; padding-inline-end: 28px; + max-height: 360px; + overflow: auto; } .onboarding-tour-description > h1 { From f781f0b3c5bf9b532c8e5ab533527d199a7274f4 Mon Sep 17 00:00:00 2001 From: Henry Chang Date: Fri, 11 Aug 2017 17:16:25 +0800 Subject: [PATCH 46/87] Bug 1388494 - Fix incomplete advisory info issue in about:blocked page. r=francois MozReview-Commit-ID: 55umwAegujo --HG-- extra : rebase_source : 8be8daa3f453b3ca20c29b2c1cce8486c4253361 --- browser/base/content/blockedSite.xhtml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/browser/base/content/blockedSite.xhtml b/browser/base/content/blockedSite.xhtml index 062f40ef7c06..f74f51ce2b40 100644 --- a/browser/base/content/blockedSite.xhtml +++ b/browser/base/content/blockedSite.xhtml @@ -134,8 +134,12 @@ el.remove(); } - // Set sitename - document.getElementById(error + "_sitename").textContent = getHostString(); + // Set sitename if necessary. + let sitenameElem = document.getElementById(error + "_sitename"); + if (sitenameElem) { + sitenameElem.textContent = getHostString(); + } + document.title = document.getElementById("errorTitleText_" + error) .innerHTML; From 58f0bcb1a0264188f3ab6d35d21ae660274f33c6 Mon Sep 17 00:00:00 2001 From: Henry Chang Date: Fri, 11 Aug 2017 17:18:58 +0800 Subject: [PATCH 47/87] Bug 1388494 - Fix 'undefined' text issue after you clicked "Ignore this warning". r=francois MozReview-Commit-ID: CLb1lVsybEg --HG-- extra : rebase_source : b302d8da0c26fecc3a6b7afab676b762f62f08fc --- browser/base/content/browser.js | 4 ++++ browser/locales/en-US/chrome/browser/browser.properties | 1 + 2 files changed, 5 insertions(+) diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 127be82f3f24..e07631a41efb 100755 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -3193,6 +3193,10 @@ var BrowserOnClick = { title = gNavigatorBundle.getString("safebrowsing.reportedUnwantedSite"); // There is no button for reporting errors since Google doesn't currently // provide a URL endpoint for these reports. + } else if (reason === "harmful") { + title = gNavigatorBundle.getString("safebrowsing.reportedHarmfulSite"); + // There is no button for reporting errors since Google doesn't currently + // provide a URL endpoint for these reports. } let notificationBox = gBrowser.getNotificationBox(); diff --git a/browser/locales/en-US/chrome/browser/browser.properties b/browser/locales/en-US/chrome/browser/browser.properties index 91f3955f39d4..ad3d56486085 100644 --- a/browser/locales/en-US/chrome/browser/browser.properties +++ b/browser/locales/en-US/chrome/browser/browser.properties @@ -549,6 +549,7 @@ safebrowsing.reportedAttackSite=Reported Attack Site! safebrowsing.notAnAttackButton.label=This isn’t an attack site… safebrowsing.notAnAttackButton.accessKey=A safebrowsing.reportedUnwantedSite=Reported Unwanted Software Site! +safebrowsing.reportedHarmfulSite=Reported Harmful Site! # Ctrl-Tab # LOCALIZATION NOTE (ctrlTab.listAllTabs.label): #1 represents the number From d42f0733ac859f78f9544c5e057f763406618fe8 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Mon, 14 Aug 2017 19:50:28 -0700 Subject: [PATCH 48/87] Bug 1389300 - Inherit style backend into NS_NewDOMDocument. r=smaug,r=heycam Our current machinery for enabling stylo requires a docshell - if there isn't one, we default to the Gecko style system. When getComputedStyle operates on an element without a presshell, it uses the caller's presshell instead. If the element has previously been styled with one style system (but no longer has a presshell), and the caller uses a different style backend, using the caller's style system can cause crashes when we pull bits of cached data off the DOM (like cached style attributes). So we want to throw when window.getComputedStyle(element) is called for a (window, element) pair with different style backends (which is what the next patch in this bug does). However, that causes a few failures where stylo-backed documents try to do getComputedStyle on an XHR document (which, without a docshell, will use the gecko style system). So this patch does some work to propagate the creator's style backend into various docshell-less documents. This should allow both chrome (which uses gecko) and content (which uses stylo) to use getComputedStyle on the response document for XHRs they create. Note that the second patch in this bug will make chromeWin.getComputedStyle(contentObj) throw. If we discover code that does that, we can just make it invoke the content's getComputedStyle method over Xrays. MozReview-Commit-ID: 5OsmHJKq5Ui --- dom/base/DOMImplementation.cpp | 6 ++++-- dom/base/DOMParser.cpp | 10 +++++++++- dom/base/nsContentUtils.cpp | 3 ++- dom/base/nsDocument.cpp | 12 ++++++++++-- dom/base/nsIDocument.h | 6 ++++-- dom/xbl/nsXBLDocumentInfo.cpp | 9 +++------ dom/xhr/XMLHttpRequestMainThread.cpp | 4 +++- dom/xhr/XMLHttpRequestMainThread.h | 11 +++++++++-- dom/xml/XMLDocument.cpp | 15 ++++++++++++--- gfx/thebes/gfxSVGGlyphs.cpp | 5 ++++- parser/html/nsParserUtils.cpp | 3 ++- 11 files changed, 62 insertions(+), 22 deletions(-) diff --git a/dom/base/DOMImplementation.cpp b/dom/base/DOMImplementation.cpp index 1baf44d63d49..65fd8a5cbdda 100644 --- a/dom/base/DOMImplementation.cpp +++ b/dom/base/DOMImplementation.cpp @@ -123,7 +123,8 @@ DOMImplementation::CreateDocument(const nsAString& aNamespaceURI, mDocumentURI, mBaseURI, mOwner->NodePrincipal(), true, scriptHandlingObject, - DocumentFlavorLegacyGuess); + DocumentFlavorLegacyGuess, + mOwner->GetStyleBackendType()); NS_ENSURE_SUCCESS(rv, rv); // When DOMImplementation's createDocument method is invoked with @@ -202,7 +203,8 @@ DOMImplementation::CreateHTMLDocument(const nsAString& aTitle, doctype, mDocumentURI, mBaseURI, mOwner->NodePrincipal(), true, scriptHandlingObject, - DocumentFlavorLegacyGuess); + DocumentFlavorLegacyGuess, + mOwner->GetStyleBackendType()); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr doc = do_QueryInterface(document); diff --git a/dom/base/DOMParser.cpp b/dom/base/DOMParser.cpp index eff41cdc32d6..625856c8f411 100644 --- a/dom/base/DOMParser.cpp +++ b/dom/base/DOMParser.cpp @@ -461,6 +461,13 @@ DOMParser::SetUpDocument(DocumentFlavor aFlavor, nsIDOMDocument** aResult) NS_ENSURE_SUCCESS(rv, rv); } + // Try to inherit a style backend. + auto styleBackend = StyleBackendType::None; + nsCOMPtr window = do_QueryInterface(mScriptHandlingObject); + if (window && window->GetExtantDoc()) { + styleBackend = window->GetExtantDoc()->GetStyleBackendType(); + } + NS_ASSERTION(mPrincipal, "Must have principal by now"); NS_ASSERTION(mDocumentURI, "Must have document URI by now"); @@ -469,5 +476,6 @@ DOMParser::SetUpDocument(DocumentFlavor aFlavor, nsIDOMDocument** aResult) mPrincipal, true, scriptHandlingObject, - aFlavor); + aFlavor, + styleBackend); } diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 47527ece2319..0a58e61f0001 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -5200,7 +5200,8 @@ nsContentUtils::ConvertToPlainText(const nsAString& aSourceBuffer, principal, true, nullptr, - DocumentFlavorHTML); + DocumentFlavorHTML, + StyleBackendType::None); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr document = do_QueryInterface(domDocument); diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 66a860ff3257..9ab2a6689b48 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -9938,7 +9938,8 @@ nsDocument::GetTemplateContentsOwner() NodePrincipal(), true, // aLoadedAsData scriptObject, // aEventObject - DocumentFlavorHTML); + DocumentFlavorHTML, + mStyleBackendType); NS_ENSURE_SUCCESS(rv, nullptr); mTemplateContentsOwner = do_QueryInterface(domDocument); @@ -12585,6 +12586,12 @@ nsIDocument::Constructor(const GlobalObject& aGlobal, return nullptr; } + auto styleBackend = StyleBackendType::None; + nsCOMPtr window = do_QueryInterface(global); + if (window && window->GetExtantDoc()) { + styleBackend = window->GetExtantDoc()->GetStyleBackendType(); + } + nsCOMPtr prin = do_QueryInterface(aGlobal.GetAsSupports()); if (!prin) { rv.Throw(NS_ERROR_UNEXPECTED); @@ -12609,7 +12616,8 @@ nsIDocument::Constructor(const GlobalObject& aGlobal, prin->GetPrincipal(), true, global, - DocumentFlavorPlain); + DocumentFlavorPlain, + styleBackend); if (NS_FAILED(res)) { rv.Throw(res); return nullptr; diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h index f942b0c15e7e..349f766247b8 100644 --- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -3634,7 +3634,8 @@ NS_NewDOMDocument(nsIDOMDocument** aInstancePtrResult, nsIPrincipal* aPrincipal, bool aLoadedAsData, nsIGlobalObject* aEventObject, - DocumentFlavor aFlavor); + DocumentFlavor aFlavor, + mozilla::StyleBackendType aStyleBackend); // This is used only for xbl documents created from the startup cache. // Non-cached documents are created in the same manner as xml documents. @@ -3642,7 +3643,8 @@ nsresult NS_NewXBLDocument(nsIDOMDocument** aInstancePtrResult, nsIURI* aDocumentURI, nsIURI* aBaseURI, - nsIPrincipal* aPrincipal); + nsIPrincipal* aPrincipal, + mozilla::StyleBackendType aStyleBackend); nsresult NS_NewPluginDocument(nsIDocument** aInstancePtrResult); diff --git a/dom/xbl/nsXBLDocumentInfo.cpp b/dom/xbl/nsXBLDocumentInfo.cpp index 127fd791d7f1..0f35d31040f7 100644 --- a/dom/xbl/nsXBLDocumentInfo.cpp +++ b/dom/xbl/nsXBLDocumentInfo.cpp @@ -226,18 +226,15 @@ nsXBLDocumentInfo::ReadPrototypeBindings(nsIURI* aURI, nsXBLDocumentInfo** aDocI nsContentUtils::GetSecurityManager()-> GetSystemPrincipal(getter_AddRefs(principal)); + auto styleBackend = aBoundDocument ? aBoundDocument->GetStyleBackendType() + : StyleBackendType::Gecko; nsCOMPtr domdoc; - rv = NS_NewXBLDocument(getter_AddRefs(domdoc), aURI, nullptr, principal); + rv = NS_NewXBLDocument(getter_AddRefs(domdoc), aURI, nullptr, principal, styleBackend); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr doc = do_QueryInterface(domdoc); NS_ASSERTION(doc, "Must have a document!"); - // Set the style backend type immediately after creating the XBL document. - // Assume gecko if there's no bound document. - doc->SetStyleBackendType(aBoundDocument ? aBoundDocument->GetStyleBackendType() - : StyleBackendType::Gecko); - RefPtr docInfo = new nsXBLDocumentInfo(doc); while (1) { diff --git a/dom/xhr/XMLHttpRequestMainThread.cpp b/dom/xhr/XMLHttpRequestMainThread.cpp index f3815a9a6684..43bb751a0d15 100644 --- a/dom/xhr/XMLHttpRequestMainThread.cpp +++ b/dom/xhr/XMLHttpRequestMainThread.cpp @@ -186,6 +186,7 @@ XMLHttpRequestMainThread::XMLHttpRequestMainThread() mResponseType(XMLHttpRequestResponseType::_empty), mRequestObserver(nullptr), mState(State::unsent), + mStyleBackend(StyleBackendType::None), mFlagSynchronous(false), mFlagAborted(false), mFlagParseBody(false), mFlagSyncLooping(false), mFlagBackgroundRequest(false), mFlagHadUploadListenersOnSend(false), mFlagACwithCredentials(false), @@ -2162,7 +2163,8 @@ XMLHttpRequestMainThread::OnStartRequest(nsIRequest *request, nsISupports *ctxt) emptyStr, emptyStr, nullptr, docURI, baseURI, requestingPrincipal, true, global, mIsHtml ? DocumentFlavorHTML : - DocumentFlavorLegacyGuess); + DocumentFlavorLegacyGuess, + mStyleBackend); NS_ENSURE_SUCCESS(rv, rv); mResponseXML = do_QueryInterface(responseDoc); mResponseXML->SetChromeXHRDocURI(chromeXHRDocURI); diff --git a/dom/xhr/XMLHttpRequestMainThread.h b/dom/xhr/XMLHttpRequestMainThread.h index 21ed1fcf617a..be45cc022730 100644 --- a/dom/xhr/XMLHttpRequestMainThread.h +++ b/dom/xhr/XMLHttpRequestMainThread.h @@ -200,8 +200,13 @@ public: nsILoadGroup* aLoadGroup = nullptr) { MOZ_ASSERT(aPrincipal); - MOZ_ASSERT_IF(nsCOMPtr win = do_QueryInterface( - aGlobalObject), win->IsInnerWindow()); + nsCOMPtr win = do_QueryInterface(aGlobalObject); + if (win) { + MOZ_ASSERT(win->IsInnerWindow()); + if (win->GetExtantDoc()) { + mStyleBackend = win->GetExtantDoc()->GetStyleBackendType(); + } + } mPrincipal = aPrincipal; BindToOwner(aGlobalObject); mBaseURI = aBaseURI; @@ -743,6 +748,8 @@ protected: State mState; + StyleBackendType mStyleBackend; + bool mFlagSynchronous; bool mFlagAborted; bool mFlagParseBody; diff --git a/dom/xml/XMLDocument.cpp b/dom/xml/XMLDocument.cpp index dd20b50d7454..496ea9fb9523 100644 --- a/dom/xml/XMLDocument.cpp +++ b/dom/xml/XMLDocument.cpp @@ -69,7 +69,8 @@ NS_NewDOMDocument(nsIDOMDocument** aInstancePtrResult, nsIPrincipal* aPrincipal, bool aLoadedAsData, nsIGlobalObject* aEventObject, - DocumentFlavor aFlavor) + DocumentFlavor aFlavor, + StyleBackendType aStyleBackend) { // Note: can't require that aDocumentURI/aBaseURI/aPrincipal be non-null, // since at least one caller (XMLHttpRequest) doesn't have decent args to @@ -128,6 +129,12 @@ NS_NewDOMDocument(nsIDOMDocument** aInstancePtrResult, return rv; } + // If we were passed an explicit style backend for this document set it + // immediately after creation, before any content is inserted. + if (aStyleBackend != StyleBackendType::None) { + d->SetStyleBackendType(aStyleBackend); + } + if (isHTML) { nsCOMPtr htmlDoc = do_QueryInterface(d); NS_ASSERTION(htmlDoc, "HTML Document doesn't implement nsIHTMLDocument?"); @@ -209,13 +216,15 @@ nsresult NS_NewXBLDocument(nsIDOMDocument** aInstancePtrResult, nsIURI* aDocumentURI, nsIURI* aBaseURI, - nsIPrincipal* aPrincipal) + nsIPrincipal* aPrincipal, + StyleBackendType aStyleBackend) { nsresult rv = NS_NewDOMDocument(aInstancePtrResult, NS_LITERAL_STRING("http://www.mozilla.org/xbl"), NS_LITERAL_STRING("bindings"), nullptr, aDocumentURI, aBaseURI, aPrincipal, false, - nullptr, DocumentFlavorLegacyGuess); + nullptr, DocumentFlavorLegacyGuess, + aStyleBackend); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr idoc = do_QueryInterface(*aInstancePtrResult); diff --git a/gfx/thebes/gfxSVGGlyphs.cpp b/gfx/thebes/gfxSVGGlyphs.cpp index f582277ab00b..a3245276b40d 100644 --- a/gfx/thebes/gfxSVGGlyphs.cpp +++ b/gfx/thebes/gfxSVGGlyphs.cpp @@ -361,6 +361,8 @@ gfxSVGGlyphsDocument::ParseDocument(const uint8_t *aBuffer, uint32_t aBufLen) nsCOMPtr principal = NullPrincipal::Create(); + auto styleBackend = nsLayoutUtils::StyloEnabled() ? StyleBackendType::Servo + : StyleBackendType::Gecko; nsCOMPtr domDoc; rv = NS_NewDOMDocument(getter_AddRefs(domDoc), EmptyString(), // aNamespaceURI @@ -369,7 +371,8 @@ gfxSVGGlyphsDocument::ParseDocument(const uint8_t *aBuffer, uint32_t aBufLen) uri, uri, principal, false, // aLoadedAsData nullptr, // aEventObject - DocumentFlavorSVG); + DocumentFlavorSVG, + styleBackend); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr document(do_QueryInterface(domDoc)); diff --git a/parser/html/nsParserUtils.cpp b/parser/html/nsParserUtils.cpp index 353340734a2e..186b057deeb1 100644 --- a/parser/html/nsParserUtils.cpp +++ b/parser/html/nsParserUtils.cpp @@ -87,7 +87,8 @@ nsParserUtils::Sanitize(const nsAString& aFromStr, principal, true, nullptr, - DocumentFlavorHTML); + DocumentFlavorHTML, + mozilla::StyleBackendType::None); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr document = do_QueryInterface(domDocument); From 4a7d72d9bceae7811a21d693def758dd6cdfc1b9 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Mon, 14 Aug 2017 11:41:23 -0700 Subject: [PATCH 49/87] Bug 1389300 - Don't mix style backend types in nsComputedDOMStyle. r=heycam MozReview-Commit-ID: 8Decj2cxySY --- layout/style/nsComputedDOMStyle.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index 7f19fc69b8ad..a2de16068c89 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -586,6 +586,16 @@ nsComputedDOMStyle::DoGetStyleContextNoFlush(Element* aElement, presShell = aPresShell; if (!presShell) return nullptr; + + // In some edge cases, the caller document might be using a different style + // backend than the callee. This causes problems because the cached parsed + // style attributes in the callee document will be a different format than + // the caller expects. Supporting this would be a pain, and we're already + // in edge-case-squared, so we just return. + if (presShell->GetDocument()->GetStyleBackendType() != + aElement->OwnerDoc()->GetStyleBackendType()) { + return nullptr; + } } // We do this check to avoid having to add too much special casing of From 00f1cbdf08f81ed5d50403d2fc57e42c61465c18 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Mon, 14 Aug 2017 13:04:37 +0900 Subject: [PATCH 50/87] Bug 1388269 - part1: mozInlineSpellChecker should store editor as strong pointer instead of weak pointer r=smaug mozInlineSpellChecker is a cycle collectable class. Therefore, with including mEditor to the cycle, we can make it nsCOMPtr instead of nsWeakPtr. MozReview-Commit-ID: DAK02zbksvy --HG-- extra : rebase_source : 5914f37a2f339a1a39b7bd2e9065a2f7d2a1ed9c --- .../spellcheck/src/mozInlineSpellChecker.cpp | 120 ++++++++++-------- .../spellcheck/src/mozInlineSpellChecker.h | 19 +-- .../spellcheck/src/mozInlineSpellWordUtil.cpp | 16 +-- .../spellcheck/src/mozInlineSpellWordUtil.h | 3 +- 4 files changed, 82 insertions(+), 76 deletions(-) diff --git a/extensions/spellcheck/src/mozInlineSpellChecker.cpp b/extensions/spellcheck/src/mozInlineSpellChecker.cpp index c5b0e8dae811..4e825630f4f9 100644 --- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp +++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp @@ -35,6 +35,7 @@ #include "mozilla/EditorBase.h" #include "mozilla/EditorUtils.h" #include "mozilla/Services.h" +#include "mozilla/TextEditor.h" #include "mozilla/dom/Selection.h" #include "mozInlineSpellChecker.h" #include "mozInlineSpellWordUtil.h" @@ -217,17 +218,18 @@ mozInlineSpellStatus::InitForNavigation( nsIDOMNode* aNewAnchorNode, int32_t aNewAnchorOffset, bool* aContinue) { - nsresult rv; mOp = eOpNavigation; mForceNavigationWordCheck = aForceCheck; mNewNavigationPositionOffset = aNewPositionOffset; // get the root node for checking - nsCOMPtr editor = do_QueryReferent(mSpellChecker->mEditor, &rv); - NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr editor = mSpellChecker->mEditor; + if (NS_WARN_IF(!editor)) { + return NS_ERROR_FAILURE; + } nsCOMPtr rootElt; - rv = editor->GetRootElement(getter_AddRefs(rootElt)); + nsresult rv = editor->GetRootElement(getter_AddRefs(rootElt)); NS_ENSURE_SUCCESS(rv, rv); // the anchor node might not be in the DOM anymore, check @@ -346,7 +348,7 @@ mozInlineSpellStatus::FinishInitOnEvent(mozInlineSpellWordUtil& aWordUtil) nsresult mozInlineSpellStatus::FinishNavigationEvent(mozInlineSpellWordUtil& aWordUtil) { - nsCOMPtr editor = do_QueryReferent(mSpellChecker->mEditor); + nsCOMPtr editor = mSpellChecker->mEditor; if (! editor) return NS_ERROR_FAILURE; // editor is gone @@ -368,9 +370,9 @@ mozInlineSpellStatus::FinishNavigationEvent(mozInlineSpellWordUtil& aWordUtil) NS_ENSURE_SUCCESS(rv, rv); // aWordUtil.GetRangeForWord flushes pending notifications, check editor again. - editor = do_QueryReferent(mSpellChecker->mEditor); - if (! editor) + if (!mSpellChecker->mEditor) { return NS_ERROR_FAILURE; // editor is gone + } // get the DOM position of the new caret, the range should be collapsed rv = mAnchorRange->GetStartContainer(getter_AddRefs(newAnchorNode)); @@ -431,16 +433,17 @@ mozInlineSpellStatus::FillNoCheckRangeFromAnchor( nsresult mozInlineSpellStatus::GetDocument(nsIDOMDocument** aDocument) { - nsresult rv; *aDocument = nullptr; if (! mSpellChecker->mEditor) return NS_ERROR_UNEXPECTED; - nsCOMPtr editor = do_QueryReferent(mSpellChecker->mEditor, &rv); - NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr editor = mSpellChecker->mEditor; + if (NS_WARN_IF(!editor)) { + return NS_ERROR_FAILURE; + } nsCOMPtr domDoc; - rv = editor->GetDocument(getter_AddRefs(domDoc)); + nsresult rv = editor->GetDocument(getter_AddRefs(domDoc)); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(domDoc, NS_ERROR_NULL_POINTER); domDoc.forget(aDocument); @@ -546,6 +549,7 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(mozInlineSpellChecker) NS_IMPL_CYCLE_COLLECTING_RELEASE(mozInlineSpellChecker) NS_IMPL_CYCLE_COLLECTION(mozInlineSpellChecker, + mEditor, mSpellCheck, mTreeWalker, mCurrentSelectionAnchorNode) @@ -584,7 +588,7 @@ mozInlineSpellChecker::GetSpellChecker(nsIEditorSpellCheck **aSpellCheck) NS_IMETHODIMP mozInlineSpellChecker::Init(nsIEditor *aEditor) { - mEditor = do_GetWeakReference(aEditor); + mEditor = aEditor; return NS_OK; } @@ -622,7 +626,7 @@ nsresult mozInlineSpellChecker::Cleanup(bool aDestroyingFrames) // observers. They may receive two consecutive STARTED notifications for // example, which we guarantee will not happen. - nsCOMPtr editor = do_QueryReferent(mEditor); + nsCOMPtr editor = mEditor.forget(); if (mPendingSpellCheck) { // Cancel the pending editor spell checker initialization. mPendingSpellCheck = nullptr; @@ -646,7 +650,6 @@ nsresult mozInlineSpellChecker::Cleanup(bool aDestroyingFrames) ChangeNumPendingSpellChecks(-mNumPendingSpellChecks, editor); } - mEditor = nullptr; mFullSpellCheckScheduled = false; return rv; @@ -701,13 +704,14 @@ mozInlineSpellChecker::UpdateCanEnableInlineSpellChecking() nsresult mozInlineSpellChecker::RegisterEventListeners() { - nsCOMPtr editor (do_QueryReferent(mEditor)); - NS_ENSURE_TRUE(editor, NS_ERROR_NULL_POINTER); + if (NS_WARN_IF(!mEditor)) { + return NS_ERROR_FAILURE; + } - editor->AddEditActionListener(this); + mEditor->AddEditActionListener(this); nsCOMPtr doc; - nsresult rv = editor->GetDocument(getter_AddRefs(doc)); + nsresult rv = mEditor->GetDocument(getter_AddRefs(doc)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr piTarget = do_QueryInterface(doc, &rv); @@ -727,13 +731,14 @@ mozInlineSpellChecker::RegisterEventListeners() nsresult mozInlineSpellChecker::UnregisterEventListeners() { - nsCOMPtr editor (do_QueryReferent(mEditor)); - NS_ENSURE_TRUE(editor, NS_ERROR_NULL_POINTER); + if (NS_WARN_IF(!mEditor)) { + return NS_ERROR_FAILURE; + } - editor->RemoveEditActionListener(this); + mEditor->RemoveEditActionListener(this); nsCOMPtr doc; - editor->GetDocument(getter_AddRefs(doc)); + mEditor->GetDocument(getter_AddRefs(doc)); NS_ENSURE_TRUE(doc, NS_ERROR_NULL_POINTER); nsCOMPtr piTarget = do_QueryInterface(doc); @@ -796,9 +801,8 @@ mozInlineSpellChecker::SetEnableRealTimeSpell(bool aEnabled) NS_ENSURE_STATE(mPendingInitEditorSpellCheckCallback); } - nsCOMPtr editor = do_QueryReferent(mEditor); nsresult rv = mPendingSpellCheck->InitSpellChecker( - editor, false, mPendingInitEditorSpellCheckCallback); + mEditor, false, mPendingInitEditorSpellCheckCallback); if (NS_FAILED(rv)) { mPendingSpellCheck = nullptr; mPendingInitEditorSpellCheckCallback = nullptr; @@ -857,10 +861,9 @@ mozInlineSpellChecker::NotifyObservers(const char* aTopic, nsIEditor* aEditor) nsCOMPtr os = mozilla::services::GetObserverService(); if (!os) return; - nsCOMPtr editor = aEditor; - if (!editor) { - editor = do_QueryReferent(mEditor); - } + // XXX Do we need to grab the editor here? If it's necessary, each observer + // should do it instead. + nsCOMPtr editor = aEditor ? aEditor : mEditor.get(); os->NotifyObservers(editor, aTopic, nullptr); } @@ -955,9 +958,9 @@ NS_IMETHODIMP mozInlineSpellChecker::ReplaceWord(nsIDOMNode *aNode, int32_t aOffset, const nsAString &newword) { - nsCOMPtr editor (do_QueryReferent(mEditor)); - NS_ENSURE_TRUE(editor, NS_ERROR_NULL_POINTER); - NS_ENSURE_TRUE(newword.Length() != 0, NS_ERROR_FAILURE); + if (NS_WARN_IF(!mEditor) || NS_WARN_IF(newword.IsEmpty())) { + return NS_ERROR_FAILURE; + } nsCOMPtr range; nsresult res = GetMisspelledWord(aNode, aOffset, getter_AddRefs(range)); @@ -972,17 +975,18 @@ mozInlineSpellChecker::ReplaceWord(nsIDOMNode *aNode, int32_t aOffset, res = range->CloneRange(getter_AddRefs(editorRange)); NS_ENSURE_SUCCESS(res, res); - AutoPlaceHolderBatch phb(editor, nullptr); + AutoPlaceHolderBatch phb(mEditor, nullptr); nsCOMPtr selection; - res = editor->GetSelection(getter_AddRefs(selection)); + res = mEditor->GetSelection(getter_AddRefs(selection)); NS_ENSURE_SUCCESS(res, res); selection->RemoveAllRanges(); selection->AddRange(editorRange); - nsCOMPtr textEditor(do_QueryReferent(mEditor)); - if (textEditor) - textEditor->InsertText(newword); + MOZ_ASSERT(mEditor); + RefPtr textEditor = mEditor->AsTextEditor(); + MOZ_ASSERT(textEditor); + textEditor->InsertText(newword); } return NS_OK; @@ -1165,11 +1169,12 @@ mozInlineSpellChecker::MakeSpellCheckRange( nsresult rv; *aRange = nullptr; - nsCOMPtr editor (do_QueryReferent(mEditor)); - NS_ENSURE_TRUE(editor, NS_ERROR_NULL_POINTER); + if (NS_WARN_IF(!mEditor)) { + return NS_ERROR_FAILURE; + } nsCOMPtr doc; - rv = editor->GetDocument(getter_AddRefs(doc)); + rv = mEditor->GetDocument(getter_AddRefs(doc)); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE); @@ -1179,7 +1184,7 @@ mozInlineSpellChecker::MakeSpellCheckRange( // possibly use full range of the editor nsCOMPtr rootElem; if (! aStartNode || ! aEndNode) { - rv = editor->GetRootElement(getter_AddRefs(rootElem)); + rv = mEditor->GetRootElement(getter_AddRefs(rootElem)); NS_ENSURE_SUCCESS(rv, rv); aStartNode = rootElem; @@ -1464,7 +1469,7 @@ nsresult mozInlineSpellChecker::DoSpellCheck(mozInlineSpellWordUtil& aWordUtil, // get the editor for ShouldSpellCheckNode, this may fail in reasonable // circumstances since the editor could have gone away - nsCOMPtr editor (do_QueryReferent(mEditor)); + nsCOMPtr editor = mEditor; if (! editor) return NS_ERROR_FAILURE; @@ -1499,10 +1504,9 @@ nsresult mozInlineSpellChecker::DoSpellCheck(mozInlineSpellWordUtil& aWordUtil, } // aWordUtil.SetPosition flushes pending notifications, check editor again. - // XXX Uhhh, *we're* holding a strong ref to the editor. - editor = do_QueryReferent(mEditor); - if (! editor) + if (!mEditor) { return NS_ERROR_FAILURE; + } int32_t wordsChecked = 0; PRTime beginTime = PR_Now(); @@ -1657,9 +1661,9 @@ mozInlineSpellChecker::ResumeCheck(UniquePtr&& aStatus) if (! mSpellCheck) return NS_OK; // spell checking has been turned off - nsCOMPtr editor = do_QueryReferent(mEditor); - if (! editor) - return NS_OK; // editor is gone + if (!mEditor) { + return NS_OK; + } mozInlineSpellWordUtil wordUtil; nsresult rv = wordUtil.Init(mEditor); @@ -1815,26 +1819,30 @@ mozInlineSpellChecker::AddRange(nsISelection* aSpellCheckSelection, return rv; } -nsresult mozInlineSpellChecker::GetSpellCheckSelection(nsISelection ** aSpellCheckSelection) +nsresult +mozInlineSpellChecker::GetSpellCheckSelection( + nsISelection** aSpellCheckSelection) { - nsCOMPtr editor (do_QueryReferent(mEditor)); - NS_ENSURE_TRUE(editor, NS_ERROR_NULL_POINTER); - + if (NS_WARN_IF(!mEditor)) { + return NS_ERROR_FAILURE; + } nsCOMPtr selcon; - nsresult rv = editor->GetSelectionController(getter_AddRefs(selcon)); + nsresult rv = mEditor->GetSelectionController(getter_AddRefs(selcon)); NS_ENSURE_SUCCESS(rv, rv); return selcon->GetSelection(nsISelectionController::SELECTION_SPELLCHECK, aSpellCheckSelection); } -nsresult mozInlineSpellChecker::SaveCurrentSelectionPosition() +nsresult +mozInlineSpellChecker::SaveCurrentSelectionPosition() { - nsCOMPtr editor (do_QueryReferent(mEditor)); - NS_ENSURE_TRUE(editor, NS_OK); + if (NS_WARN_IF(!mEditor)) { + return NS_OK; // XXX Why NS_OK? + } // figure out the old caret position based on the current selection nsCOMPtr selection; - nsresult rv = editor->GetSelection(getter_AddRefs(selection)); + nsresult rv = mEditor->GetSelection(getter_AddRefs(selection)); NS_ENSURE_SUCCESS(rv, rv); rv = selection->GetFocusNode(getter_AddRefs(mCurrentSelectionAnchorNode)); diff --git a/extensions/spellcheck/src/mozInlineSpellChecker.h b/extensions/spellcheck/src/mozInlineSpellChecker.h index 4ce4bb981fb4..850154eff9ca 100644 --- a/extensions/spellcheck/src/mozInlineSpellChecker.h +++ b/extensions/spellcheck/src/mozInlineSpellChecker.h @@ -7,16 +7,17 @@ #define __mozinlinespellchecker_h__ #include "mozilla/EditorBase.h" -#include "nsRange.h" -#include "nsIEditorSpellCheck.h" -#include "nsIEditActionListener.h" -#include "nsIInlineSpellChecker.h" -#include "nsIDOMTreeWalker.h" -#include "nsWeakReference.h" -#include "nsIDOMEventListener.h" -#include "nsWeakReference.h" + #include "mozISpellI18NUtil.h" + #include "nsCycleCollectionParticipant.h" +#include "nsIDOMEventListener.h" +#include "nsIDOMTreeWalker.h" +#include "nsIEditActionListener.h" +#include "nsIEditorSpellCheck.h" +#include "nsIInlineSpellChecker.h" +#include "nsRange.h" +#include "nsWeakReference.h" // X.h defines KeyPress #ifdef KeyPress @@ -132,7 +133,7 @@ private: SpellCheck_Available = 1}; static SpellCheckingState gCanEnableSpellChecking; - nsWeakPtr mEditor; + nsCOMPtr mEditor; nsCOMPtr mSpellCheck; nsCOMPtr mPendingSpellCheck; nsCOMPtr mTreeWalker; diff --git a/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp b/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp index 196f8f66e1a8..6d873878d439 100644 --- a/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp +++ b/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp @@ -50,18 +50,14 @@ inline bool IsConditionalPunctuation(char16_t ch) // mozInlineSpellWordUtil::Init nsresult -mozInlineSpellWordUtil::Init(const nsWeakPtr& aWeakEditor) +mozInlineSpellWordUtil::Init(nsIEditor* aEditor) { - nsresult rv; - - // getting the editor can fail commonly because the editor was detached, so - // don't assert - nsCOMPtr editor = do_QueryReferent(aWeakEditor, &rv); - if (NS_FAILED(rv)) - return rv; + if (NS_WARN_IF(!aEditor)) { + return NS_ERROR_FAILURE; + } nsCOMPtr domDoc; - rv = editor->GetDocument(getter_AddRefs(domDoc)); + nsresult rv = aEditor->GetDocument(getter_AddRefs(domDoc)); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(domDoc, NS_ERROR_NULL_POINTER); @@ -71,7 +67,7 @@ mozInlineSpellWordUtil::Init(const nsWeakPtr& aWeakEditor) // Find the root node for the editor. For contenteditable we'll need something // cleverer here. nsCOMPtr rootElt; - rv = editor->GetRootElement(getter_AddRefs(rootElt)); + rv = aEditor->GetRootElement(getter_AddRefs(rootElt)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr rootNode = do_QueryInterface(rootElt); diff --git a/extensions/spellcheck/src/mozInlineSpellWordUtil.h b/extensions/spellcheck/src/mozInlineSpellWordUtil.h index 63dd4c240e4d..b69ab857135c 100644 --- a/extensions/spellcheck/src/mozInlineSpellWordUtil.h +++ b/extensions/spellcheck/src/mozInlineSpellWordUtil.h @@ -15,6 +15,7 @@ //#define DEBUG_SPELLCHECK class nsRange; +class nsIEditor; class nsINode; /** @@ -61,7 +62,7 @@ public: mSoftBegin(nullptr, 0), mSoftEnd(nullptr, 0), mNextWordIndex(-1), mSoftTextValid(false) {} - nsresult Init(const nsWeakPtr& aWeakEditor); + nsresult Init(nsIEditor* aEditor); nsresult SetEnd(nsINode* aEndNode, int32_t aEndOffset); From 2ead4e24a4b25f350cedae4a4d79bd6607469b57 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Mon, 14 Aug 2017 13:36:25 +0900 Subject: [PATCH 51/87] Bug 1388269 - part2: Make mozInlineSpellChecker store TextEditor instead of nsIEditor r=m_kato Then, can reduce a lot of unnecessary virtual calls and QI. MozReview-Commit-ID: 28JS4q2L1Vj --HG-- extra : rebase_source : 3f7dc379a80777f05f6b4e2d2ed1e7787de03d69 --- .../spellcheck/src/mozInlineSpellChecker.cpp | 188 +++++++++--------- .../spellcheck/src/mozInlineSpellChecker.h | 4 +- 2 files changed, 91 insertions(+), 101 deletions(-) diff --git a/extensions/spellcheck/src/mozInlineSpellChecker.cpp b/extensions/spellcheck/src/mozInlineSpellChecker.cpp index 4e825630f4f9..7d6984c94337 100644 --- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp +++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp @@ -224,17 +224,16 @@ mozInlineSpellStatus::InitForNavigation( mNewNavigationPositionOffset = aNewPositionOffset; // get the root node for checking - nsCOMPtr editor = mSpellChecker->mEditor; - if (NS_WARN_IF(!editor)) { + TextEditor* textEditor = mSpellChecker->mTextEditor; + if (NS_WARN_IF(!textEditor)) { + return NS_ERROR_FAILURE; + } + nsCOMPtr root = textEditor->GetRoot(); + if (NS_WARN_IF(!root)) { return NS_ERROR_FAILURE; } - nsCOMPtr rootElt; - nsresult rv = editor->GetRootElement(getter_AddRefs(rootElt)); - NS_ENSURE_SUCCESS(rv, rv); - // the anchor node might not be in the DOM anymore, check - nsCOMPtr root = do_QueryInterface(rootElt, &rv); - NS_ENSURE_SUCCESS(rv, rv); + nsresult rv = NS_ERROR_FAILURE; nsCOMPtr currentAnchor = do_QueryInterface(aOldAnchorNode, &rv); NS_ENSURE_SUCCESS(rv, rv); if (root && currentAnchor && ! ContentIsDescendantOf(currentAnchor, root)) { @@ -348,9 +347,10 @@ mozInlineSpellStatus::FinishInitOnEvent(mozInlineSpellWordUtil& aWordUtil) nsresult mozInlineSpellStatus::FinishNavigationEvent(mozInlineSpellWordUtil& aWordUtil) { - nsCOMPtr editor = mSpellChecker->mEditor; - if (! editor) + RefPtr textEditor = mSpellChecker->mTextEditor; + if (!textEditor) { return NS_ERROR_FAILURE; // editor is gone + } NS_ASSERTION(mAnchorRange, "No anchor for navigation!"); nsCOMPtr newAnchorNode, oldAnchorNode; @@ -370,7 +370,7 @@ mozInlineSpellStatus::FinishNavigationEvent(mozInlineSpellWordUtil& aWordUtil) NS_ENSURE_SUCCESS(rv, rv); // aWordUtil.GetRangeForWord flushes pending notifications, check editor again. - if (!mSpellChecker->mEditor) { + if (!mSpellChecker->mTextEditor) { return NS_ERROR_FAILURE; // editor is gone } @@ -434,18 +434,15 @@ nsresult mozInlineSpellStatus::GetDocument(nsIDOMDocument** aDocument) { *aDocument = nullptr; - if (! mSpellChecker->mEditor) + if (!mSpellChecker->mTextEditor) { return NS_ERROR_UNEXPECTED; - - nsCOMPtr editor = mSpellChecker->mEditor; - if (NS_WARN_IF(!editor)) { - return NS_ERROR_FAILURE; } - nsCOMPtr domDoc; - nsresult rv = editor->GetDocument(getter_AddRefs(domDoc)); - NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_TRUE(domDoc, NS_ERROR_NULL_POINTER); + nsCOMPtr domDoc = + mSpellChecker->mTextEditor->GetDOMDocument(); + if (NS_WARN_IF(!domDoc)) { + return NS_ERROR_NULL_POINTER; + } domDoc.forget(aDocument); return NS_OK; } @@ -549,7 +546,7 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(mozInlineSpellChecker) NS_IMPL_CYCLE_COLLECTING_RELEASE(mozInlineSpellChecker) NS_IMPL_CYCLE_COLLECTION(mozInlineSpellChecker, - mEditor, + mTextEditor, mSpellCheck, mTreeWalker, mCurrentSelectionAnchorNode) @@ -586,9 +583,9 @@ mozInlineSpellChecker::GetSpellChecker(nsIEditorSpellCheck **aSpellCheck) } NS_IMETHODIMP -mozInlineSpellChecker::Init(nsIEditor *aEditor) +mozInlineSpellChecker::Init(nsIEditor* aEditor) { - mEditor = aEditor; + mTextEditor = aEditor ? aEditor->AsTextEditor() : nullptr; return NS_OK; } @@ -626,13 +623,13 @@ nsresult mozInlineSpellChecker::Cleanup(bool aDestroyingFrames) // observers. They may receive two consecutive STARTED notifications for // example, which we guarantee will not happen. - nsCOMPtr editor = mEditor.forget(); + RefPtr textEditor = mTextEditor.forget(); if (mPendingSpellCheck) { // Cancel the pending editor spell checker initialization. mPendingSpellCheck = nullptr; mPendingInitEditorSpellCheckCallback->Cancel(); mPendingInitEditorSpellCheckCallback = nullptr; - ChangeNumPendingSpellChecks(-1, editor); + ChangeNumPendingSpellChecks(-1, textEditor); } // Increment this token so that pending UpdateCurrentDictionary calls and @@ -641,13 +638,14 @@ nsresult mozInlineSpellChecker::Cleanup(bool aDestroyingFrames) if (mNumPendingUpdateCurrentDictionary > 0) { // Account for pending UpdateCurrentDictionary calls. - ChangeNumPendingSpellChecks(-mNumPendingUpdateCurrentDictionary, editor); + ChangeNumPendingSpellChecks(-mNumPendingUpdateCurrentDictionary, + textEditor); mNumPendingUpdateCurrentDictionary = 0; } if (mNumPendingSpellChecks > 0) { // If mNumPendingSpellChecks is still > 0 at this point, the remainder is // pending scheduled spell checks. - ChangeNumPendingSpellChecks(-mNumPendingSpellChecks, editor); + ChangeNumPendingSpellChecks(-mNumPendingSpellChecks, textEditor); } mFullSpellCheckScheduled = false; @@ -704,25 +702,19 @@ mozInlineSpellChecker::UpdateCanEnableInlineSpellChecking() nsresult mozInlineSpellChecker::RegisterEventListeners() { - if (NS_WARN_IF(!mEditor)) { + if (NS_WARN_IF(!mTextEditor)) { return NS_ERROR_FAILURE; } - mEditor->AddEditActionListener(this); + mTextEditor->AddEditActionListener(this); - nsCOMPtr doc; - nsresult rv = mEditor->GetDocument(getter_AddRefs(doc)); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr piTarget = do_QueryInterface(doc, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - piTarget->AddEventListener(NS_LITERAL_STRING("blur"), this, - true, false); - piTarget->AddEventListener(NS_LITERAL_STRING("click"), this, - false, false); - piTarget->AddEventListener(NS_LITERAL_STRING("keypress"), this, - false, false); + nsCOMPtr doc = mTextEditor->GetDocument(); + if (NS_WARN_IF(!doc)) { + return NS_ERROR_FAILURE; + } + doc->AddEventListener(NS_LITERAL_STRING("blur"), this, true, false); + doc->AddEventListener(NS_LITERAL_STRING("click"), this, false, false); + doc->AddEventListener(NS_LITERAL_STRING("keypress"), this, false, false); return NS_OK; } @@ -731,22 +723,19 @@ mozInlineSpellChecker::RegisterEventListeners() nsresult mozInlineSpellChecker::UnregisterEventListeners() { - if (NS_WARN_IF(!mEditor)) { + if (NS_WARN_IF(!mTextEditor)) { return NS_ERROR_FAILURE; } - mEditor->RemoveEditActionListener(this); + mTextEditor->RemoveEditActionListener(this); - nsCOMPtr doc; - mEditor->GetDocument(getter_AddRefs(doc)); - NS_ENSURE_TRUE(doc, NS_ERROR_NULL_POINTER); - - nsCOMPtr piTarget = do_QueryInterface(doc); - NS_ENSURE_TRUE(piTarget, NS_ERROR_NULL_POINTER); - - piTarget->RemoveEventListener(NS_LITERAL_STRING("blur"), this, true); - piTarget->RemoveEventListener(NS_LITERAL_STRING("click"), this, false); - piTarget->RemoveEventListener(NS_LITERAL_STRING("keypress"), this, false); + nsCOMPtr doc = mTextEditor->GetDocument(); + if (NS_WARN_IF(!doc)) { + return NS_ERROR_FAILURE; + } + doc->RemoveEventListener(NS_LITERAL_STRING("blur"), this, true); + doc->RemoveEventListener(NS_LITERAL_STRING("click"), this, false); + doc->RemoveEventListener(NS_LITERAL_STRING("keypress"), this, false); return NS_OK; } @@ -802,7 +791,7 @@ mozInlineSpellChecker::SetEnableRealTimeSpell(bool aEnabled) } nsresult rv = mPendingSpellCheck->InitSpellChecker( - mEditor, false, mPendingInitEditorSpellCheckCallback); + mTextEditor, false, mPendingInitEditorSpellCheckCallback); if (NS_FAILED(rv)) { mPendingSpellCheck = nullptr; mPendingInitEditorSpellCheckCallback = nullptr; @@ -854,7 +843,7 @@ mozInlineSpellChecker::ChangeNumPendingSpellChecks(int32_t aDelta, } // Broadcasts the given topic to observers. aEditor is passed to observers if -// nonnull; otherwise mEditor is passed. +// nonnull; otherwise mTextEditor is passed. void mozInlineSpellChecker::NotifyObservers(const char* aTopic, nsIEditor* aEditor) { @@ -863,8 +852,10 @@ mozInlineSpellChecker::NotifyObservers(const char* aTopic, nsIEditor* aEditor) return; // XXX Do we need to grab the editor here? If it's necessary, each observer // should do it instead. - nsCOMPtr editor = aEditor ? aEditor : mEditor.get(); - os->NotifyObservers(editor, aTopic, nullptr); + RefPtr textEditor = + aEditor ? aEditor->AsTextEditor() : mTextEditor.get(); + os->NotifyObservers(static_cast(textEditor.get()), + aTopic, nullptr); } // mozInlineSpellChecker::SpellCheckAfterEditorChange @@ -958,7 +949,7 @@ NS_IMETHODIMP mozInlineSpellChecker::ReplaceWord(nsIDOMNode *aNode, int32_t aOffset, const nsAString &newword) { - if (NS_WARN_IF(!mEditor) || NS_WARN_IF(newword.IsEmpty())) { + if (NS_WARN_IF(!mTextEditor) || NS_WARN_IF(newword.IsEmpty())) { return NS_ERROR_FAILURE; } @@ -975,18 +966,16 @@ mozInlineSpellChecker::ReplaceWord(nsIDOMNode *aNode, int32_t aOffset, res = range->CloneRange(getter_AddRefs(editorRange)); NS_ENSURE_SUCCESS(res, res); - AutoPlaceHolderBatch phb(mEditor, nullptr); + AutoPlaceHolderBatch phb(mTextEditor, nullptr); nsCOMPtr selection; - res = mEditor->GetSelection(getter_AddRefs(selection)); + res = mTextEditor->GetSelection(getter_AddRefs(selection)); NS_ENSURE_SUCCESS(res, res); selection->RemoveAllRanges(); selection->AddRange(editorRange); - MOZ_ASSERT(mEditor); - RefPtr textEditor = mEditor->AsTextEditor(); - MOZ_ASSERT(textEditor); - textEditor->InsertText(newword); + MOZ_ASSERT(mTextEditor); + mTextEditor->InsertText(newword); } return NS_OK; @@ -1169,28 +1158,26 @@ mozInlineSpellChecker::MakeSpellCheckRange( nsresult rv; *aRange = nullptr; - if (NS_WARN_IF(!mEditor)) { + if (NS_WARN_IF(!mTextEditor)) { return NS_ERROR_FAILURE; } - nsCOMPtr doc; - rv = mEditor->GetDocument(getter_AddRefs(doc)); - NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE); + nsCOMPtr doc = mTextEditor->GetDocument(); + if (NS_WARN_IF(!doc)) { + return NS_ERROR_FAILURE; + } - nsCOMPtr documentNode = do_QueryInterface(doc); - RefPtr range = new nsRange(documentNode); + RefPtr range = new nsRange(doc); // possibly use full range of the editor - nsCOMPtr rootElem; if (! aStartNode || ! aEndNode) { - rv = mEditor->GetRootElement(getter_AddRefs(rootElem)); - NS_ENSURE_SUCCESS(rv, rv); - - aStartNode = rootElem; + nsCOMPtr domRootElement = + do_QueryInterface(mTextEditor->GetRoot()); + if (NS_WARN_IF(!domRootElement)) { + return NS_ERROR_FAILURE; + } + aStartNode = aEndNode = domRootElement; aStartOffset = 0; - - aEndNode = rootElem; aEndOffset = -1; } @@ -1469,9 +1456,10 @@ nsresult mozInlineSpellChecker::DoSpellCheck(mozInlineSpellWordUtil& aWordUtil, // get the editor for ShouldSpellCheckNode, this may fail in reasonable // circumstances since the editor could have gone away - nsCOMPtr editor = mEditor; - if (! editor) + RefPtr textEditor = mTextEditor; + if (!textEditor) { return NS_ERROR_FAILURE; + } if (aStatus->mRange->Collapsed()) return NS_OK; @@ -1504,7 +1492,7 @@ nsresult mozInlineSpellChecker::DoSpellCheck(mozInlineSpellWordUtil& aWordUtil, } // aWordUtil.SetPosition flushes pending notifications, check editor again. - if (!mEditor) { + if (!mTextEditor) { return NS_ERROR_FAILURE; } @@ -1578,8 +1566,9 @@ nsresult mozInlineSpellChecker::DoSpellCheck(mozInlineSpellWordUtil& aWordUtil, continue; // some nodes we don't spellcheck - if (!ShouldSpellCheckNode(editor, beginNode)) + if (!ShouldSpellCheckNode(textEditor, beginNode)) { continue; + } // Don't check spelling if we're inside the noCheckRange. This needs to // be done after we clear any old selection because the excluded word @@ -1661,12 +1650,12 @@ mozInlineSpellChecker::ResumeCheck(UniquePtr&& aStatus) if (! mSpellCheck) return NS_OK; // spell checking has been turned off - if (!mEditor) { + if (!mTextEditor) { return NS_OK; } mozInlineSpellWordUtil wordUtil; - nsresult rv = wordUtil.Init(mEditor); + nsresult rv = wordUtil.Init(mTextEditor); if (NS_FAILED(rv)) return NS_OK; // editor doesn't like us, don't assert @@ -1823,32 +1812,33 @@ nsresult mozInlineSpellChecker::GetSpellCheckSelection( nsISelection** aSpellCheckSelection) { - if (NS_WARN_IF(!mEditor)) { + if (NS_WARN_IF(!mTextEditor)) { return NS_ERROR_FAILURE; } - nsCOMPtr selcon; - nsresult rv = mEditor->GetSelectionController(getter_AddRefs(selcon)); - NS_ENSURE_SUCCESS(rv, rv); - - return selcon->GetSelection(nsISelectionController::SELECTION_SPELLCHECK, aSpellCheckSelection); + RefPtr selection = + mTextEditor->GetSelection(SelectionType::eSpellCheck); + if (!selection) { + return NS_ERROR_NULL_POINTER; + } + selection.forget(aSpellCheckSelection); + return NS_OK; } nsresult mozInlineSpellChecker::SaveCurrentSelectionPosition() { - if (NS_WARN_IF(!mEditor)) { + if (NS_WARN_IF(!mTextEditor)) { return NS_OK; // XXX Why NS_OK? } // figure out the old caret position based on the current selection - nsCOMPtr selection; - nsresult rv = mEditor->GetSelection(getter_AddRefs(selection)); - NS_ENSURE_SUCCESS(rv, rv); + RefPtr selection = mTextEditor->GetSelection(); + if (NS_WARN_IF(!selection)) { + return NS_ERROR_FAILURE; + } - rv = selection->GetFocusNode(getter_AddRefs(mCurrentSelectionAnchorNode)); - NS_ENSURE_SUCCESS(rv, rv); - - selection->GetFocusOffset(&mCurrentSelectionOffset); + mCurrentSelectionAnchorNode = do_QueryInterface(selection->GetFocusNode()); + mCurrentSelectionOffset = selection->FocusOffset(); return NS_OK; } diff --git a/extensions/spellcheck/src/mozInlineSpellChecker.h b/extensions/spellcheck/src/mozInlineSpellChecker.h index 850154eff9ca..6f4e3e1cdcef 100644 --- a/extensions/spellcheck/src/mozInlineSpellChecker.h +++ b/extensions/spellcheck/src/mozInlineSpellChecker.h @@ -6,7 +6,7 @@ #ifndef __mozinlinespellchecker_h__ #define __mozinlinespellchecker_h__ -#include "mozilla/EditorBase.h" +#include "mozilla/TextEditor.h" #include "mozISpellI18NUtil.h" @@ -133,7 +133,7 @@ private: SpellCheck_Available = 1}; static SpellCheckingState gCanEnableSpellChecking; - nsCOMPtr mEditor; + RefPtr mTextEditor; nsCOMPtr mSpellCheck; nsCOMPtr mPendingSpellCheck; nsCOMPtr mTreeWalker; From 310515ea064dfba0c6bb1866691797f440662740 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Mon, 14 Aug 2017 13:48:00 +0900 Subject: [PATCH 52/87] Bug 1388269 - part3: spellchecker should use TextEditor instead of nsIEditor r=m_kato MozReview-Commit-ID: 37npmisPqR2 --HG-- extra : rebase_source : 1732cd953fc79fce5b444644ec2838652db768a9 --- .../spellcheck/src/mozInlineSpellChecker.cpp | 17 +++++----- .../spellcheck/src/mozInlineSpellChecker.h | 6 ++-- .../spellcheck/src/mozInlineSpellWordUtil.cpp | 34 +++++++++---------- .../spellcheck/src/mozInlineSpellWordUtil.h | 7 ++-- 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/extensions/spellcheck/src/mozInlineSpellChecker.cpp b/extensions/spellcheck/src/mozInlineSpellChecker.cpp index 7d6984c94337..2d8a05db9fee 100644 --- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp +++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp @@ -829,23 +829,24 @@ mozInlineSpellChecker::EditorSpellCheckInited() // info on the aEditor parameter. void mozInlineSpellChecker::ChangeNumPendingSpellChecks(int32_t aDelta, - nsIEditor* aEditor) + TextEditor* aTextEditor) { int8_t oldNumPending = mNumPendingSpellChecks; mNumPendingSpellChecks += aDelta; NS_ASSERTION(mNumPendingSpellChecks >= 0, "Unbalanced ChangeNumPendingSpellChecks calls!"); if (oldNumPending == 0 && mNumPendingSpellChecks > 0) { - NotifyObservers(INLINESPELL_STARTED_TOPIC, aEditor); + NotifyObservers(INLINESPELL_STARTED_TOPIC, aTextEditor); } else if (oldNumPending > 0 && mNumPendingSpellChecks == 0) { - NotifyObservers(INLINESPELL_ENDED_TOPIC, aEditor); + NotifyObservers(INLINESPELL_ENDED_TOPIC, aTextEditor); } } // Broadcasts the given topic to observers. aEditor is passed to observers if // nonnull; otherwise mTextEditor is passed. void -mozInlineSpellChecker::NotifyObservers(const char* aTopic, nsIEditor* aEditor) +mozInlineSpellChecker::NotifyObservers(const char* aTopic, + TextEditor* aTextEditor) { nsCOMPtr os = mozilla::services::GetObserverService(); if (!os) @@ -853,7 +854,7 @@ mozInlineSpellChecker::NotifyObservers(const char* aTopic, nsIEditor* aEditor) // XXX Do we need to grab the editor here? If it's necessary, each observer // should do it instead. RefPtr textEditor = - aEditor ? aEditor->AsTextEditor() : mTextEditor.get(); + aTextEditor ? aTextEditor : mTextEditor.get(); os->NotifyObservers(static_cast(textEditor.get()), aTopic, nullptr); } @@ -1246,7 +1247,7 @@ mozInlineSpellChecker::SpellCheckBetweenNodes(nsIDOMNode *aStartNode, // for these cases. bool -mozInlineSpellChecker::ShouldSpellCheckNode(nsIEditor* aEditor, +mozInlineSpellChecker::ShouldSpellCheckNode(TextEditor* aTextEditor, nsINode *aNode) { MOZ_ASSERT(aNode); @@ -1255,9 +1256,7 @@ mozInlineSpellChecker::ShouldSpellCheckNode(nsIEditor* aEditor, nsIContent *content = aNode->AsContent(); - uint32_t flags; - aEditor->GetFlags(&flags); - if (flags & nsIPlaintextEditor::eEditorMailMask) { + if (aTextEditor->IsMailEditor()) { nsIContent *parent = content->GetParent(); while (parent) { if (parent->IsHTMLElement(nsGkAtoms::blockquote) && diff --git a/extensions/spellcheck/src/mozInlineSpellChecker.h b/extensions/spellcheck/src/mozInlineSpellChecker.h index 6f4e3e1cdcef..efbd02a2dcf9 100644 --- a/extensions/spellcheck/src/mozInlineSpellChecker.h +++ b/extensions/spellcheck/src/mozInlineSpellChecker.h @@ -208,7 +208,7 @@ public: // examines the dom node in question and returns true if the inline spell // checker should skip the node (i.e. the text is inside of a block quote // or an e-mail signature...) - bool ShouldSpellCheckNode(nsIEditor* aEditor, nsINode *aNode); + bool ShouldSpellCheckNode(mozilla::TextEditor* aTextEditor, nsINode *aNode); nsresult SpellCheckAfterChange(nsIDOMNode* aCursorNode, int32_t aCursorOffset, nsIDOMNode* aPreviousNode, int32_t aPreviousOffset, @@ -262,8 +262,8 @@ protected: // track the number of pending spell checks and async operations that may lead // to spell checks, notifying observers accordingly void ChangeNumPendingSpellChecks(int32_t aDelta, - nsIEditor* aEditor = nullptr); - void NotifyObservers(const char* aTopic, nsIEditor* aEditor); + mozilla::TextEditor* aTextEditor = nullptr); + void NotifyObservers(const char* aTopic, mozilla::TextEditor* aTextEditor); }; #endif /* __mozinlinespellchecker_h__ */ diff --git a/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp b/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp index 6d873878d439..30e59cb57641 100644 --- a/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp +++ b/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp @@ -4,6 +4,11 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozInlineSpellWordUtil.h" + +#include "mozilla/BinarySearch.h" +#include "mozilla/TextEditor.h" +#include "mozilla/dom/Element.h" + #include "nsDebug.h" #include "nsIAtom.h" #include "nsComponentManagerUtils.h" @@ -16,12 +21,10 @@ #include "nsServiceManagerUtils.h" #include "nsIContent.h" #include "nsTextFragment.h" -#include "mozilla/dom/Element.h" #include "nsRange.h" #include "nsContentUtils.h" #include "nsIFrame.h" #include -#include "mozilla/BinarySearch.h" using namespace mozilla; @@ -50,29 +53,24 @@ inline bool IsConditionalPunctuation(char16_t ch) // mozInlineSpellWordUtil::Init nsresult -mozInlineSpellWordUtil::Init(nsIEditor* aEditor) +mozInlineSpellWordUtil::Init(TextEditor* aTextEditor) { - if (NS_WARN_IF(!aEditor)) { + if (NS_WARN_IF(!aTextEditor)) { return NS_ERROR_FAILURE; } - nsCOMPtr domDoc; - nsresult rv = aEditor->GetDocument(getter_AddRefs(domDoc)); - NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_TRUE(domDoc, NS_ERROR_NULL_POINTER); - - mDOMDocument = domDoc; - mDocument = do_QueryInterface(domDoc); + mDocument = aTextEditor->GetDocument(); + if (NS_WARN_IF(!mDocument)) { + return NS_ERROR_FAILURE; + } + mDOMDocument = do_QueryInterface(mDocument); // Find the root node for the editor. For contenteditable we'll need something // cleverer here. - nsCOMPtr rootElt; - rv = aEditor->GetRootElement(getter_AddRefs(rootElt)); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr rootNode = do_QueryInterface(rootElt); - mRootNode = rootNode; - NS_ASSERTION(mRootNode, "GetRootElement returned null *and* claimed to suceed!"); + mRootNode = aTextEditor->GetRoot(); + if (NS_WARN_IF(!mRootNode)) { + return NS_ERROR_FAILURE; + } return NS_OK; } diff --git a/extensions/spellcheck/src/mozInlineSpellWordUtil.h b/extensions/spellcheck/src/mozInlineSpellWordUtil.h index b69ab857135c..ac0b6bdcfbfa 100644 --- a/extensions/spellcheck/src/mozInlineSpellWordUtil.h +++ b/extensions/spellcheck/src/mozInlineSpellWordUtil.h @@ -15,9 +15,12 @@ //#define DEBUG_SPELLCHECK class nsRange; -class nsIEditor; class nsINode; +namespace mozilla { +class TextEditor; +} // namespace mozilla + /** * This class extracts text from the DOM and builds it into a single string. * The string includes whitespace breaks whereever non-inline elements begin @@ -62,7 +65,7 @@ public: mSoftBegin(nullptr, 0), mSoftEnd(nullptr, 0), mNextWordIndex(-1), mSoftTextValid(false) {} - nsresult Init(nsIEditor* aEditor); + nsresult Init(mozilla::TextEditor* aTextEditor); nsresult SetEnd(nsINode* aEndNode, int32_t aEndOffset); From 1f7edc42cef5d9fe9f59a2b83b990417b96ffb04 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Mon, 14 Aug 2017 14:03:44 +0900 Subject: [PATCH 53/87] Bug 1388269 - part4: Make mozInlineSpellChecker::GetSpellCheckSelection() return Selection instead of nsISelection r=m_kato Although, this is not necessary for bug 1388269, we should fix this here since this change is really similar to what bug 1388269 tries to fix and enough simple and safe. MozReview-Commit-ID: H68pYTBmurf --HG-- extra : rebase_source : dfa47370232ad44e1523c94929cf50e5539b787d --- .../spellcheck/src/mozInlineSpellChecker.cpp | 41 +++++++++---------- .../spellcheck/src/mozInlineSpellChecker.h | 2 +- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/extensions/spellcheck/src/mozInlineSpellChecker.cpp b/extensions/spellcheck/src/mozInlineSpellChecker.cpp index 2d8a05db9fee..92860aeafe45 100644 --- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp +++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp @@ -602,11 +602,12 @@ mozInlineSpellChecker::Init(nsIEditor* aEditor) nsresult mozInlineSpellChecker::Cleanup(bool aDestroyingFrames) { mNumWordsInSpellSelection = 0; - nsCOMPtr spellCheckSelection; - nsresult rv = GetSpellCheckSelection(getter_AddRefs(spellCheckSelection)); - if (NS_FAILED(rv)) { + RefPtr spellCheckSelection = GetSpellCheckSelection(); + nsresult rv = NS_OK; + if (!spellCheckSelection) { // Ensure we still unregister event listeners (but return a failure code) UnregisterEventListeners(); + rv = NS_ERROR_FAILURE; } else { if (!aDestroyingFrames) { spellCheckSelection->RemoveAllRanges(); @@ -936,11 +937,13 @@ NS_IMETHODIMP mozInlineSpellChecker::GetMisspelledWord(nsIDOMNode *aNode, int32_t aOffset, nsIDOMRange **newword) { - NS_ENSURE_ARG_POINTER(aNode); - nsCOMPtr spellCheckSelection; - nsresult res = GetSpellCheckSelection(getter_AddRefs(spellCheckSelection)); - NS_ENSURE_SUCCESS(res, res); - + if (NS_WARN_IF(!aNode)) { + return NS_ERROR_INVALID_ARG; + } + RefPtr spellCheckSelection = GetSpellCheckSelection(); + if (NS_WARN_IF(!spellCheckSelection)) { + return NS_ERROR_FAILURE; + } return IsPointInSelection(spellCheckSelection, aNode, aOffset, newword); } @@ -1658,12 +1661,10 @@ mozInlineSpellChecker::ResumeCheck(UniquePtr&& aStatus) if (NS_FAILED(rv)) return NS_OK; // editor doesn't like us, don't assert - nsCOMPtr spellCheckSelectionRef; - rv = GetSpellCheckSelection(getter_AddRefs(spellCheckSelectionRef)); - NS_ENSURE_SUCCESS(rv, rv); - - auto spellCheckSelection = - static_cast(spellCheckSelectionRef.get()); + RefPtr spellCheckSelection = GetSpellCheckSelection(); + if (NS_WARN_IF(!spellCheckSelection)) { + return NS_ERROR_FAILURE; + } nsAutoString currentDictionary; rv = mSpellCheck->GetCurrentDictionary(currentDictionary); @@ -1807,20 +1808,18 @@ mozInlineSpellChecker::AddRange(nsISelection* aSpellCheckSelection, return rv; } -nsresult -mozInlineSpellChecker::GetSpellCheckSelection( - nsISelection** aSpellCheckSelection) +already_AddRefed +mozInlineSpellChecker::GetSpellCheckSelection() { if (NS_WARN_IF(!mTextEditor)) { - return NS_ERROR_FAILURE; + return nullptr; } RefPtr selection = mTextEditor->GetSelection(SelectionType::eSpellCheck); if (!selection) { - return NS_ERROR_NULL_POINTER; + return nullptr; } - selection.forget(aSpellCheckSelection); - return NS_OK; + return selection.forget(); } nsresult diff --git a/extensions/spellcheck/src/mozInlineSpellChecker.h b/extensions/spellcheck/src/mozInlineSpellChecker.h index efbd02a2dcf9..22971a88950f 100644 --- a/extensions/spellcheck/src/mozInlineSpellChecker.h +++ b/extensions/spellcheck/src/mozInlineSpellChecker.h @@ -247,7 +247,7 @@ public: nsresult UnregisterEventListeners(); nsresult HandleNavigationEvent(bool aForceWordSpellCheck, int32_t aNewPositionOffset = 0); - nsresult GetSpellCheckSelection(nsISelection ** aSpellCheckSelection); + already_AddRefed GetSpellCheckSelection(); nsresult SaveCurrentSelectionPosition(); nsresult ResumeCheck(mozilla::UniquePtr&& aStatus); From 20fc8ab4773746b49693a12d373633e01e03f2e1 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 8 Aug 2017 10:57:19 +0900 Subject: [PATCH 54/87] Bug 1387317 - part1: Make AutoSelectionSetterAfterTableEdit use HTMLEditor instead of nsITableEditor r=m_kato nsITableEditor is now a builtin class. So, it's implemented only by HTMLEditor. Therefore, AutoSelectionSetterAfterTableEdit can use HTMLEditor. Then, nsITableEditor.setSelectionAfterTableEdit() can be removed from nsITableEditor and moved to HTMLEditor as non-virtual method since nobody uses it from JS. MozReview-Commit-ID: KnN6Fw4TYyn --HG-- extra : rebase_source : 48412a5f81f30d9ada47550fdb4d1ee0d88de6f4 --- editor/libeditor/HTMLEditor.h | 27 +++++- editor/libeditor/HTMLTableEditor.cpp | 128 +++++++++++++-------------- editor/nsITableEditor.idl | 21 ----- 3 files changed, 89 insertions(+), 87 deletions(-) diff --git a/editor/libeditor/HTMLEditor.h b/editor/libeditor/HTMLEditor.h index 121dfc55b551..c9be8cce0626 100644 --- a/editor/libeditor/HTMLEditor.h +++ b/editor/libeditor/HTMLEditor.h @@ -46,7 +46,7 @@ class nsIDOMRange; class nsRange; namespace mozilla { - +class AutoSelectionSetterAfterTableEdit; class HTMLEditorEventListener; class HTMLEditRules; class TextEditRules; @@ -836,6 +836,30 @@ protected: void SetElementPosition(Element& aElement, int32_t aX, int32_t aY); + /** + * Reset a selected cell or collapsed selection (the caret) after table + * editing. + * + * @param aTable A table in the document. + * @param aRow The row ... + * @param aCol ... and column defining the cell where we will try to + * place the caret. + * @param aSelected If true, we select the whole cell instead of setting + * caret. + * @param aDirection If cell at (aCol, aRow) is not found, search for + * previous cell in the same column (aPreviousColumn) or + * row (ePreviousRow) or don't search for another cell + * (aNoSearch). If no cell is found, caret is place just + * before table; and if that fails, at beginning of + * document. Thus we generally don't worry about the + * return value and can use the + * AutoSelectionSetterAfterTableEdit stack-based object to + * insure we reset the caret in a table-editing method. + */ + void SetSelectionAfterTableEdit(nsIDOMElement* aTable, + int32_t aRow, int32_t aCol, + int32_t aDirection, bool aSelected); + protected: nsTArray> mContentFilters; @@ -1022,6 +1046,7 @@ protected: ParagraphSeparator mDefaultParagraphSeparator; public: + friend class AutoSelectionSetterAfterTableEdit; friend class HTMLEditorEventListener; friend class HTMLEditRules; friend class TextEditRules; diff --git a/editor/libeditor/HTMLTableEditor.cpp b/editor/libeditor/HTMLTableEditor.cpp index 16fb549ea270..f1bec30d67b4 100644 --- a/editor/libeditor/HTMLTableEditor.cpp +++ b/editor/libeditor/HTMLTableEditor.cpp @@ -28,7 +28,6 @@ #include "nsIPresShell.h" #include "nsISupportsUtils.h" #include "nsITableCellLayout.h" // For efficient access to table cell -#include "nsITableEditor.h" #include "nsLiteralString.h" #include "nsQueryFrame.h" #include "nsRange.h" @@ -49,18 +48,18 @@ using namespace dom; class MOZ_STACK_CLASS AutoSelectionSetterAfterTableEdit final { private: - nsCOMPtr mTableEditor; + RefPtr mHTMLEditor; nsCOMPtr mTable; int32_t mCol, mRow, mDirection, mSelected; public: - AutoSelectionSetterAfterTableEdit(nsITableEditor* aTableEditor, + AutoSelectionSetterAfterTableEdit(HTMLEditor& aHTMLEditor, nsIDOMElement* aTable, int32_t aRow, int32_t aCol, int32_t aDirection, bool aSelected) - : mTableEditor(aTableEditor) + : mHTMLEditor(&aHTMLEditor) , mTable(aTable) , mCol(aCol) , mRow(aRow) @@ -71,9 +70,9 @@ public: ~AutoSelectionSetterAfterTableEdit() { - if (mTableEditor) { - mTableEditor->SetSelectionAfterTableEdit(mTable, mRow, mCol, mDirection, - mSelected); + if (mHTMLEditor) { + mHTMLEditor->SetSelectionAfterTableEdit(mTable, mRow, mCol, mDirection, + mSelected); } } @@ -81,7 +80,7 @@ public: // when one method yields control to another void CancelSetCaret() { - mTableEditor = nullptr; + mHTMLEditor = nullptr; mTable = nullptr; } }; @@ -193,7 +192,7 @@ HTMLEditor::InsertTableCell(int32_t aNumber, NS_ENSURE_TRUE(curCell, NS_ERROR_FAILURE); int32_t newCellIndex = aAfter ? (startColIndex+colSpan) : startColIndex; //We control selection resetting after the insert... - AutoSelectionSetterAfterTableEdit setCaret(this, table, startRowIndex, + AutoSelectionSetterAfterTableEdit setCaret(*this, table, startRowIndex, newCellIndex, ePreviousColumn, false); //...so suppress Rules System selection munging @@ -437,7 +436,7 @@ HTMLEditor::InsertTableColumn(int32_t aNumber, NS_ENSURE_SUCCESS(rv, rv); //We reset caret in destructor... - AutoSelectionSetterAfterTableEdit setCaret(this, table, startRowIndex, + AutoSelectionSetterAfterTableEdit setCaret(*this, table, startRowIndex, startColIndex, ePreviousRow, false); //.. so suppress Rules System selection munging @@ -569,7 +568,7 @@ HTMLEditor::InsertTableRow(int32_t aNumber, } //We control selection resetting after the insert... - AutoSelectionSetterAfterTableEdit setCaret(this, table, startRowIndex, + AutoSelectionSetterAfterTableEdit setCaret(*this, table, startRowIndex, startColIndex, ePreviousColumn, false); //...so suppress Rules System selection munging @@ -784,7 +783,7 @@ HTMLEditor::DeleteTableCell(int32_t aNumber) // The setCaret object will call AutoSelectionSetterAfterTableEdit in its // destructor - AutoSelectionSetterAfterTableEdit setCaret(this, table, startRowIndex, + AutoSelectionSetterAfterTableEdit setCaret(*this, table, startRowIndex, startColIndex, ePreviousColumn, false); AutoTransactionsConserveSelection dontChangeSelection(this); @@ -914,7 +913,7 @@ HTMLEditor::DeleteTableCell(int32_t aNumber) // The setCaret object will call AutoSelectionSetterAfterTableEdit in its // destructor - AutoSelectionSetterAfterTableEdit setCaret(this, table, startRowIndex, + AutoSelectionSetterAfterTableEdit setCaret(*this, table, startRowIndex, startColIndex, ePreviousColumn, false); AutoTransactionsConserveSelection dontChangeSelection(this); @@ -964,7 +963,7 @@ HTMLEditor::DeleteTableCellContents() NS_ENSURE_SUCCESS(rv, rv); } - AutoSelectionSetterAfterTableEdit setCaret(this, table, startRowIndex, + AutoSelectionSetterAfterTableEdit setCaret(*this, table, startRowIndex, startColIndex, ePreviousColumn, false); @@ -1049,7 +1048,7 @@ HTMLEditor::DeleteTableColumn(int32_t aNumber) NS_ENSURE_SUCCESS(rv, rv); } //We control selection resetting after the insert... - AutoSelectionSetterAfterTableEdit setCaret(this, table, startRowIndex, + AutoSelectionSetterAfterTableEdit setCaret(*this, table, startRowIndex, startColIndex, ePreviousRow, false); @@ -1215,7 +1214,7 @@ HTMLEditor::DeleteTableRow(int32_t aNumber) } //We control selection resetting after the insert... - AutoSelectionSetterAfterTableEdit setCaret(this, table, startRowIndex, + AutoSelectionSetterAfterTableEdit setCaret(*this, table, startRowIndex, startColIndex, ePreviousRow, false); // Don't change selection during deletions @@ -1740,7 +1739,7 @@ HTMLEditor::SplitTableCell() AutoRules beginRulesSniffing(this, EditAction::insertNode, nsIEditor::eNext); // We reset selection - AutoSelectionSetterAfterTableEdit setCaret(this, table, startRowIndex, + AutoSelectionSetterAfterTableEdit setCaret(*this, table, startRowIndex, startColIndex, ePreviousColumn, false); //...so suppress Rules System selection munging @@ -3097,23 +3096,20 @@ HTMLEditor::GetFirstSelectedCellInTable(int32_t* aRowIndex, return NS_OK; } -NS_IMETHODIMP +void HTMLEditor::SetSelectionAfterTableEdit(nsIDOMElement* aTable, int32_t aRow, int32_t aCol, int32_t aDirection, bool aSelected) { - NS_ENSURE_TRUE(aTable, NS_ERROR_NOT_INITIALIZED); - - if (Destroyed()) { - return NS_ERROR_FAILURE; + if (NS_WARN_IF(!aTable) || Destroyed()) { + return; } RefPtr selection = GetSelection(); - if (!selection) { - return NS_ERROR_FAILURE; + return; } nsCOMPtr cell; @@ -3127,48 +3123,49 @@ HTMLEditor::SetSelectionAfterTableEdit(nsIDOMElement* aTable, if (cell) { if (aSelected) { // Reselect the cell - return SelectElement(cell); - } else { - // Set the caret to deepest first child - // but don't go into nested tables - // TODO: Should we really be placing the caret at the END - // of the cell content? - nsCOMPtr cellNode = do_QueryInterface(cell); - if (cellNode) { - CollapseSelectionToDeepestNonTableFirstChild(selection, cellNode); - } - return NS_OK; + SelectElement(cell); + return; } - } else { - // Setup index to find another cell in the - // direction requested, but move in - // other direction if already at beginning of row or column - switch (aDirection) { - case ePreviousColumn: - if (!aCol) { - if (aRow > 0) { - aRow--; - } else { - done = true; - } - } else { - aCol--; - } - break; - case ePreviousRow: - if (!aRow) { - if (aCol > 0) { - aCol--; - } else { - done = true; - } - } else { + + // Set the caret to deepest first child + // but don't go into nested tables + // TODO: Should we really be placing the caret at the END + // of the cell content? + nsCOMPtr cellNode = do_QueryInterface(cell); + if (cellNode) { + CollapseSelectionToDeepestNonTableFirstChild(selection, cellNode); + } + return; + } + + // Setup index to find another cell in the + // direction requested, but move in other direction if already at + // beginning of row or column + switch (aDirection) { + case ePreviousColumn: + if (!aCol) { + if (aRow > 0) { aRow--; + } else { + done = true; } - break; - default: - done = true; - } + } else { + aCol--; + } + break; + case ePreviousRow: + if (!aRow) { + if (aCol > 0) { + aCol--; + } else { + done = true; + } + } else { + aRow--; + } + break; + default: + done = true; } } while (!done); @@ -3178,11 +3175,12 @@ HTMLEditor::SetSelectionAfterTableEdit(nsIDOMElement* aTable, nsresult rv = aTable->GetParentNode(getter_AddRefs(tableParent)); if (NS_SUCCEEDED(rv) && tableParent) { int32_t tableOffset = GetChildOffset(aTable, tableParent); - return selection->Collapse(tableParent, tableOffset); + selection->Collapse(tableParent, tableOffset); + return; } // Last resort: Set selection to start of doc // (it's very bad to not have a valid selection!) - return SetSelectionAtDocumentStart(selection); + SetSelectionAtDocumentStart(selection); } NS_IMETHODIMP diff --git a/editor/nsITableEditor.idl b/editor/nsITableEditor.idl index 7dcbc8c434f0..e4546f246d81 100644 --- a/editor/nsITableEditor.idl +++ b/editor/nsITableEditor.idl @@ -231,27 +231,6 @@ interface nsITableEditor : nsISupports * Used for aDirection param in SetSelectionAfterTableEdit */ - /** Reset a selected cell or collapsed selection (the caret) after table editing - * - * @param aTable A table in the document - * @param aRow The row ... - * @param aCol ... and column defining the cell - * where we will try to place the caret - * @param aSelected If true, we select the whole cell instead of setting caret - * @param aDirection If cell at (aCol, aRow) is not found, - * search for previous cell in the same - * column (aPreviousColumn) or row (ePreviousRow) - * or don't search for another cell (aNoSearch) - * If no cell is found, caret is place just before table; - * and if that fails, at beginning of document. - * Thus we generally don't worry about the return value - * and can use the nsSetSelectionAfterTableEdit stack-based - * object to insure we reset the caret in a table-editing method. - */ - void setSelectionAfterTableEdit(in nsIDOMElement aTable, - in long aRow, in long aCol, - in long aDirection, in boolean aSelected); - /** Examine the current selection and find * a selected TABLE, TD or TH, or TR element. * or return the parent TD or TH if selection is inside a table cell From 7c54bc878b63db1dfab836e3d28848b5e80967be Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 8 Aug 2017 11:25:36 +0900 Subject: [PATCH 55/87] Bug 1387317 - part2: EditorEventListener should stop using interface methods as far as possible r=m_kato MozReview-Commit-ID: EPQeBez2tJh --HG-- extra : rebase_source : b18b3399f703d3cdcb6f26cec3fcb8f707fb9519 --- dom/html/nsTextEditorState.cpp | 2 +- editor/libeditor/EditorBase.cpp | 12 +++--- editor/libeditor/EditorBase.h | 44 ++++++++++++++++++++ editor/libeditor/EditorEventListener.cpp | 34 ++++++--------- editor/libeditor/HTMLEditor.cpp | 10 ++--- editor/libeditor/HTMLEditorDataTransfer.cpp | 6 +-- editor/libeditor/HTMLEditorEventListener.cpp | 2 - editor/libeditor/HTMLEditorEventListener.h | 1 - editor/libeditor/HTMLStyleEditor.cpp | 6 +-- editor/libeditor/TextEditor.cpp | 6 +-- editor/libeditor/TextEditorDataTransfer.cpp | 2 +- 11 files changed, 80 insertions(+), 45 deletions(-) diff --git a/dom/html/nsTextEditorState.cpp b/dom/html/nsTextEditorState.cpp index 7ca68c37d395..15b45c451a22 100644 --- a/dom/html/nsTextEditorState.cpp +++ b/dom/html/nsTextEditorState.cpp @@ -2572,7 +2572,7 @@ nsTextEditorState::SetValue(const nsAString& aValue, const nsAString* aOldValue, mValueBeingSet = aValue; mIsCommittingComposition = true; RefPtr textEditor = mTextEditor; - nsresult rv = textEditor->ForceCompositionEnd(); + nsresult rv = textEditor->CommitComposition(); if (!self.get()) { return true; } diff --git a/editor/libeditor/EditorBase.cpp b/editor/libeditor/EditorBase.cpp index 2dfa6f23656d..b9276f780be9 100644 --- a/editor/libeditor/EditorBase.cpp +++ b/editor/libeditor/EditorBase.cpp @@ -2193,11 +2193,13 @@ EditorBase::EndIMEComposition() NS_IMETHODIMP EditorBase::ForceCompositionEnd() { - nsCOMPtr ps = GetPresShell(); - if (!ps) { - return NS_ERROR_NOT_AVAILABLE; - } - nsPresContext* pc = ps->GetPresContext(); + return CommitComposition(); +} + +nsresult +EditorBase::CommitComposition() +{ + nsPresContext* pc = GetPresContext(); if (!pc) { return NS_ERROR_NOT_AVAILABLE; } diff --git a/editor/libeditor/EditorBase.h b/editor/libeditor/EditorBase.h index ea66940d9a52..5621763c9568 100644 --- a/editor/libeditor/EditorBase.h +++ b/editor/libeditor/EditorBase.h @@ -251,6 +251,11 @@ public: already_AddRefed GetDOMDocument(); already_AddRefed GetDocument(); already_AddRefed GetPresShell(); + nsPresContext* GetPresContext() + { + RefPtr presShell = GetPresShell(); + return presShell ? presShell->GetPresContext() : nullptr; + } already_AddRefed GetWidget(); nsISelectionController* GetSelectionController() const { @@ -351,6 +356,15 @@ public: WidgetCompositionEvent* aCompositionChangeEvet) = 0; void EndIMEComposition(); + /** + * Commit composition if there is. + * Note that when there is a composition, this requests to commit composition + * to native IME. Therefore, when there is composition, this can do anything. + * For example, the editor instance, the widget or the process itself may + * be destroyed. + */ + nsresult CommitComposition(); + void SwitchTextDirectionTo(uint32_t aDirection); protected: @@ -947,6 +961,36 @@ public: */ uint32_t Flags() const { return mFlags; } + nsresult AddFlags(uint32_t aFlags) + { + const uint32_t kOldFlags = Flags(); + const uint32_t kNewFlags = (kOldFlags | aFlags); + if (kNewFlags == kOldFlags) { + return NS_OK; + } + return SetFlags(kNewFlags); // virtual call and may be expensive. + } + nsresult RemoveFlags(uint32_t aFlags) + { + const uint32_t kOldFlags = Flags(); + const uint32_t kNewFlags = (kOldFlags & ~aFlags); + if (kNewFlags == kOldFlags) { + return NS_OK; + } + return SetFlags(kNewFlags); // virtual call and may be expensive. + } + nsresult AddAndRemoveFlags(uint32_t aAddingFlags, uint32_t aRemovingFlags) + { + MOZ_ASSERT(!(aAddingFlags & aRemovingFlags), + "Same flags are specified both adding and removing"); + const uint32_t kOldFlags = Flags(); + const uint32_t kNewFlags = ((kOldFlags | aAddingFlags) & ~aRemovingFlags); + if (kNewFlags == kOldFlags) { + return NS_OK; + } + return SetFlags(kNewFlags); // virtual call and may be expensive. + } + bool IsPlaintextEditor() const { return (mFlags & nsIPlaintextEditor::eEditorPlaintextMask) != 0; diff --git a/editor/libeditor/EditorEventListener.cpp b/editor/libeditor/EditorEventListener.cpp index 9c3f88ade975..4554a9ff16c2 100644 --- a/editor/libeditor/EditorEventListener.cpp +++ b/editor/libeditor/EditorEventListener.cpp @@ -12,6 +12,7 @@ #include "mozilla/EventListenerManager.h" // for EventListenerManager #include "mozilla/IMEStateManager.h" // for IMEStateManager #include "mozilla/Preferences.h" // for Preferences +#include "mozilla/TextEditor.h" // for TextEditor #include "mozilla/TextEvents.h" // for WidgetCompositionEvent #include "mozilla/dom/Element.h" // for Element #include "mozilla/dom/Event.h" // for Event @@ -36,11 +37,8 @@ #include "nsIDOMMouseEvent.h" // for nsIDOMMouseEvent #include "nsIDOMNode.h" // for nsIDOMNode #include "nsIDocument.h" // for nsIDocument -#include "nsIEditor.h" // for EditorBase::GetSelection, etc. -#include "nsIEditorMailSupport.h" // for nsIEditorMailSupport #include "nsIFocusManager.h" // for nsIFocusManager #include "nsIFormControl.h" // for nsIFormControl, etc. -#include "nsIHTMLEditor.h" // for nsIHTMLEditor #include "nsINode.h" // for nsINode, ::NODE_IS_EDITABLE, etc. #include "nsIPlaintextEditor.h" // for nsIPlaintextEditor, etc. #include "nsIPresShell.h" // for nsIPresShell @@ -366,7 +364,7 @@ EditorEventListener::EnsureCommitCompoisition() { MOZ_ASSERT(!DetachedFromEditor()); RefPtr editorBase(mEditorBase); - editorBase->ForceCompositionEnd(); + editorBase->CommitComposition(); return !DetachedFromEditor(); } @@ -711,19 +709,14 @@ EditorEventListener::HandleMiddleClickPaste(nsIDOMMouseEvent* aMouseEvent) return NS_ERROR_NULL_POINTER; } - RefPtr editorBase(mEditorBase); - RefPtr selection = editorBase->GetSelection(); + RefPtr textEditor = mEditorBase->AsTextEditor(); + MOZ_ASSERT(textEditor); + + RefPtr selection = textEditor->GetSelection(); if (selection) { selection->Collapse(parent, offset); } - // If the ctrl key is pressed, we'll do paste as quotation. - // Would've used the alt key, but the kde wmgr treats alt-middle specially. - nsCOMPtr mailEditor; - if (clickEvent->IsControl()) { - mailEditor = do_QueryObject(editorBase); - } - nsresult rv; int32_t clipboard = nsIClipboard::kGlobalClipboard; nsCOMPtr clipboardService = @@ -736,10 +729,12 @@ EditorEventListener::HandleMiddleClickPaste(nsIDOMMouseEvent* aMouseEvent) } } - if (mailEditor) { - mailEditor->PasteAsQuotation(clipboard); + // If the ctrl key is pressed, we'll do paste as quotation. + // Would've used the alt key, but the kde wmgr treats alt-middle specially. + if (clickEvent->IsControl()) { + textEditor->PasteAsQuotation(clipboard); } else { - editorBase->Paste(clipboard); + textEditor->Paste(clipboard); } // Prevent the event from propagating up to be possibly handled @@ -1191,11 +1186,8 @@ EditorEventListener::SpellCheckIfNeeded() // If the spell check skip flag is still enabled from creation time, // disable it because focused editors are allowed to spell check. RefPtr editorBase(mEditorBase); - uint32_t currentFlags = 0; - editorBase->GetFlags(¤tFlags); - if(currentFlags & nsIPlaintextEditor::eEditorSkipSpellCheck) { - currentFlags ^= nsIPlaintextEditor::eEditorSkipSpellCheck; - editorBase->SetFlags(currentFlags); + if(editorBase->ShouldSkipSpellCheck()) { + editorBase->RemoveFlags(nsIPlaintextEditor::eEditorSkipSpellCheck); } } diff --git a/editor/libeditor/HTMLEditor.cpp b/editor/libeditor/HTMLEditor.cpp index 74923eda14f4..4d5ce3340e9b 100644 --- a/editor/libeditor/HTMLEditor.cpp +++ b/editor/libeditor/HTMLEditor.cpp @@ -1203,7 +1203,7 @@ HTMLEditor::ReplaceHeadContentsWithHTML(const nsAString& aSourceToInsert) RefPtr selection = GetSelection(); NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER); - ForceCompositionEnd(); + CommitComposition(); // Do not use AutoRules -- rules code won't let us insert in . Use // the head node as a parent and delete/insert directly. @@ -1273,7 +1273,7 @@ HTMLEditor::ReplaceHeadContentsWithHTML(const nsAString& aSourceToInsert) NS_IMETHODIMP HTMLEditor::RebuildDocumentFromSource(const nsAString& aSourceString) { - ForceCompositionEnd(); + CommitComposition(); RefPtr selection = GetSelection(); NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER); @@ -1537,7 +1537,7 @@ HTMLEditor::InsertElementAtSelection(nsIDOMElement* aElement, nsCOMPtr node = do_QueryInterface(aElement); - ForceCompositionEnd(); + CommitComposition(); AutoEditBatch beginBatching(this); AutoRules beginRulesSniffing(this, EditAction::insertElement, nsIEditor::eNext); @@ -3580,7 +3580,7 @@ HTMLEditor::SelectEntireDocument(Selection* aSelection) NS_IMETHODIMP HTMLEditor::SelectAll() { - ForceCompositionEnd(); + CommitComposition(); RefPtr selection = GetSelection(); NS_ENSURE_STATE(selection); @@ -4519,7 +4519,7 @@ nsresult HTMLEditor::SetCSSBackgroundColor(const nsAString& aColor) { NS_ENSURE_TRUE(mRules, NS_ERROR_NOT_INITIALIZED); - ForceCompositionEnd(); + CommitComposition(); // Protect the edit rules object from dying nsCOMPtr rules(mRules); diff --git a/editor/libeditor/HTMLEditorDataTransfer.cpp b/editor/libeditor/HTMLEditorDataTransfer.cpp index c238cb5b1e0a..b3704163f7ec 100644 --- a/editor/libeditor/HTMLEditorDataTransfer.cpp +++ b/editor/libeditor/HTMLEditorDataTransfer.cpp @@ -102,7 +102,7 @@ HTMLEditor::LoadHTML(const nsAString& aInputString) NS_ENSURE_TRUE(mRules, NS_ERROR_NOT_INITIALIZED); // force IME commit; set up rules sniffing and batching - ForceCompositionEnd(); + CommitComposition(); AutoEditBatch beginBatching(this); AutoRules beginRulesSniffing(this, EditAction::loadHTML, nsIEditor::eNext); @@ -197,7 +197,7 @@ HTMLEditor::DoInsertHTMLWithContext(const nsAString& aInputString, nsCOMPtr rules(mRules); // force IME commit; set up rules sniffing and batching - ForceCompositionEnd(); + CommitComposition(); AutoEditBatch beginBatching(this); AutoRules beginRulesSniffing(this, EditAction::htmlPaste, nsIEditor::eNext); @@ -1494,7 +1494,7 @@ HTMLEditor::PasteNoFormatting(int32_t aSelectionType) return NS_OK; } - ForceCompositionEnd(); + CommitComposition(); // Get Clipboard Service nsresult rv; diff --git a/editor/libeditor/HTMLEditorEventListener.cpp b/editor/libeditor/HTMLEditorEventListener.cpp index 4acd7020f5c6..2ca00b26db8c 100644 --- a/editor/libeditor/HTMLEditorEventListener.cpp +++ b/editor/libeditor/HTMLEditorEventListener.cpp @@ -18,8 +18,6 @@ #include "nsIDOMEventTarget.h" #include "nsIDOMMouseEvent.h" #include "nsIDOMNode.h" -#include "nsIHTMLInlineTableEditor.h" -#include "nsIHTMLObjectResizer.h" #include "nsISupportsImpl.h" #include "nsLiteralString.h" #include "nsQueryObject.h" diff --git a/editor/libeditor/HTMLEditorEventListener.h b/editor/libeditor/HTMLEditorEventListener.h index b5083aa45b0a..6020e2edbe36 100644 --- a/editor/libeditor/HTMLEditorEventListener.h +++ b/editor/libeditor/HTMLEditorEventListener.h @@ -12,7 +12,6 @@ namespace mozilla { class EditorBase; -class HTMLEditor; class HTMLEditorEventListener final : public EditorEventListener { diff --git a/editor/libeditor/HTMLStyleEditor.cpp b/editor/libeditor/HTMLStyleEditor.cpp index 024c356f0b23..15de87d233d8 100644 --- a/editor/libeditor/HTMLStyleEditor.cpp +++ b/editor/libeditor/HTMLStyleEditor.cpp @@ -110,7 +110,7 @@ HTMLEditor::SetInlineProperty(nsIAtom* aProperty, NS_ENSURE_TRUE(aProperty, NS_ERROR_NULL_POINTER); NS_ENSURE_TRUE(mRules, NS_ERROR_NOT_INITIALIZED); nsCOMPtr rules(mRules); - ForceCompositionEnd(); + CommitComposition(); RefPtr selection = GetSelection(); NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER); @@ -1202,7 +1202,7 @@ HTMLEditor::RemoveInlinePropertyImpl(nsIAtom* aProperty, { MOZ_ASSERT_IF(aProperty, aAttribute); NS_ENSURE_TRUE(mRules, NS_ERROR_NOT_INITIALIZED); - ForceCompositionEnd(); + CommitComposition(); RefPtr selection = GetSelection(); NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER); @@ -1351,7 +1351,7 @@ HTMLEditor::DecreaseFontSize() nsresult HTMLEditor::RelativeFontChange(FontSize aDir) { - ForceCompositionEnd(); + CommitComposition(); // Get the selection RefPtr selection = GetSelection(); diff --git a/editor/libeditor/TextEditor.cpp b/editor/libeditor/TextEditor.cpp index 5b1e7be270e8..db1271e1e73e 100644 --- a/editor/libeditor/TextEditor.cpp +++ b/editor/libeditor/TextEditor.cpp @@ -1080,7 +1080,7 @@ TextEditor::Undo(uint32_t aCount) AutoUpdateViewBatch beginViewBatching(this); - ForceCompositionEnd(); + CommitComposition(); NotifyEditorObservers(eNotifyEditorObserversOfBefore); @@ -1108,7 +1108,7 @@ TextEditor::Redo(uint32_t aCount) AutoUpdateViewBatch beginViewBatching(this); - ForceCompositionEnd(); + CommitComposition(); NotifyEditorObservers(eNotifyEditorObserversOfBefore); @@ -1150,7 +1150,7 @@ TextEditor::FireClipboardEvent(EventMessage aEventMessage, bool* aActionTaken) { if (aEventMessage == ePaste) { - ForceCompositionEnd(); + CommitComposition(); } nsCOMPtr presShell = GetPresShell(); diff --git a/editor/libeditor/TextEditorDataTransfer.cpp b/editor/libeditor/TextEditorDataTransfer.cpp index 568ae6e7c2d7..02cd9741c4c6 100644 --- a/editor/libeditor/TextEditorDataTransfer.cpp +++ b/editor/libeditor/TextEditorDataTransfer.cpp @@ -163,7 +163,7 @@ TextEditor::InsertFromDataTransfer(DataTransfer* aDataTransfer, nsresult TextEditor::InsertFromDrop(nsIDOMEvent* aDropEvent) { - ForceCompositionEnd(); + CommitComposition(); nsCOMPtr dragEvent(do_QueryInterface(aDropEvent)); NS_ENSURE_TRUE(dragEvent, NS_ERROR_FAILURE); From 8437aa287b77fa37c173c7feb277ccb13b3b85b7 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 8 Aug 2017 12:06:10 +0900 Subject: [PATCH 56/87] Bug 1387317 - part3: HTMLEditor should use RefPtr rather than nsCOMPtr for kungFuDeathGrip r=m_kato MozReview-Commit-ID: 1F6wwjvdD8H --HG-- extra : rebase_source : 23c2fefa67e11b584868d349bd043148c4b91770 --- editor/libeditor/HTMLEditor.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/editor/libeditor/HTMLEditor.cpp b/editor/libeditor/HTMLEditor.cpp index 4d5ce3340e9b..1fdada3e1f18 100644 --- a/editor/libeditor/HTMLEditor.cpp +++ b/editor/libeditor/HTMLEditor.cpp @@ -3272,7 +3272,10 @@ HTMLEditor::DoContentInserted(nsIDocument* aDocument, return; } - nsCOMPtr kungFuDeathGrip(this); + // XXX Why do we need this? This method is a helper of mutation observer. + // So, the callers of mutation observer should guarantee that this won't + // be deleted at least during the call. + RefPtr kungFuDeathGrip(this); if (ShouldReplaceRootElement()) { nsContentUtils::AddScriptRunner( @@ -3322,7 +3325,10 @@ HTMLEditor::ContentRemoved(nsIDocument* aDocument, return; } - nsCOMPtr kungFuDeathGrip(this); + // XXX Why do we need to do this? This method is a mutation observer's + // method. Therefore, the caller should guarantee that this won't be + // deleted during the call. + RefPtr kungFuDeathGrip(this); if (SameCOMIdentity(aChild, mRootElement)) { nsContentUtils::AddScriptRunner( From 1bbc0d5920dfa55dc9b50d0dc9f0b4bfb3344e6a Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 8 Aug 2017 12:36:29 +0900 Subject: [PATCH 57/87] Bug 1387317 - part4: Make editor flag setters use new AddFlags() or RemoveFlags() if useful r=m_kato MozReview-Commit-ID: EMDeGfK37Lx --HG-- extra : rebase_source : 8a2b4e809c608649fbb41edd32d2165db7e77516 --- dom/html/nsTextEditorState.cpp | 3 ++- .../composer/nsComposerDocumentCommands.cpp | 13 +++-------- editor/libeditor/EditorBase.cpp | 22 +++++++++---------- layout/forms/nsTextControlFrame.cpp | 20 ++++++++--------- 4 files changed, 25 insertions(+), 33 deletions(-) diff --git a/dom/html/nsTextEditorState.cpp b/dom/html/nsTextEditorState.cpp index 15b45c451a22..785f9b14ed0b 100644 --- a/dom/html/nsTextEditorState.cpp +++ b/dom/html/nsTextEditorState.cpp @@ -1568,8 +1568,9 @@ nsTextEditorState::PrepareEditor(const nsAString *aValue) editorFlags |= nsIPlaintextEditor::eEditorDisabledMask; // Disable the selection if necessary. - if (editorFlags & nsIPlaintextEditor::eEditorDisabledMask) + if (newTextEditor->IsDisabled()) { mSelCon->SetDisplaySelection(nsISelectionController::SELECTION_OFF); + } newTextEditor->SetFlags(editorFlags); } diff --git a/editor/composer/nsComposerDocumentCommands.cpp b/editor/composer/nsComposerDocumentCommands.cpp index b9de8550bc74..7ceb780f771d 100644 --- a/editor/composer/nsComposerDocumentCommands.cpp +++ b/editor/composer/nsComposerDocumentCommands.cpp @@ -232,16 +232,9 @@ nsSetDocumentStateCommand::DoCommandParams(const char *aCommandName, bool isReadOnly; nsresult rvRO = aParams->GetBooleanValue(STATE_ATTRIBUTE, &isReadOnly); NS_ENSURE_SUCCESS(rvRO, rvRO); - - uint32_t flags; - textEditor->GetFlags(&flags); - if (isReadOnly) { - flags |= nsIPlaintextEditor::eEditorReadonlyMask; - } else { - flags &= ~(nsIPlaintextEditor::eEditorReadonlyMask); - } - - return textEditor->SetFlags(flags); + return isReadOnly ? + textEditor->AddFlags(nsIPlaintextEditor::eEditorReadonlyMask) : + textEditor->RemoveFlags(nsIPlaintextEditor::eEditorReadonlyMask); } if (!nsCRT::strcmp(aCommandName, "cmd_setDocumentUseCSS")) { diff --git a/editor/libeditor/EditorBase.cpp b/editor/libeditor/EditorBase.cpp index b9276f780be9..8192a6f79b0a 100644 --- a/editor/libeditor/EditorBase.cpp +++ b/editor/libeditor/EditorBase.cpp @@ -1335,10 +1335,9 @@ EditorBase::RemoveAttribute(Element* aElement, bool EditorBase::OutputsMozDirty() { - // Return true for Composer (!eEditorAllowInteraction) or mail - // (eEditorMailMask), but false for webpages. - return !(mFlags & nsIPlaintextEditor::eEditorAllowInteraction) || - (mFlags & nsIPlaintextEditor::eEditorMailMask); + // Return true for Composer (!IsInteractionAllowed()) or mail + // (IsMailEditor()), but false for webpages. + return !IsInteractionAllowed() || IsMailEditor(); } NS_IMETHODIMP @@ -5004,8 +5003,7 @@ EditorBase::DetermineCurrentDirection() // If we don't have an explicit direction, determine our direction // from the content's direction - if (!(mFlags & (nsIPlaintextEditor::eEditorLeftToRight | - nsIPlaintextEditor::eEditorRightToLeft))) { + if (!IsRightToLeft() && !IsLeftToRight()) { nsIFrame* frame = rootElement->GetPrimaryFrame(); NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE); @@ -5031,14 +5029,14 @@ EditorBase::SwitchTextDirection() NS_ENSURE_SUCCESS(rv, rv); // Apply the opposite direction - if (mFlags & nsIPlaintextEditor::eEditorRightToLeft) { - NS_ASSERTION(!(mFlags & nsIPlaintextEditor::eEditorLeftToRight), + if (IsRightToLeft()) { + NS_ASSERTION(!IsLeftToRight(), "Unexpected mutually exclusive flag"); mFlags &= ~nsIPlaintextEditor::eEditorRightToLeft; mFlags |= nsIPlaintextEditor::eEditorLeftToRight; rv = rootElement->SetAttr(kNameSpaceID_None, nsGkAtoms::dir, NS_LITERAL_STRING("ltr"), true); - } else if (mFlags & nsIPlaintextEditor::eEditorLeftToRight) { - NS_ASSERTION(!(mFlags & nsIPlaintextEditor::eEditorRightToLeft), + } else if (IsLeftToRight()) { + NS_ASSERTION(!IsRightToLeft(), "Unexpected mutually exclusive flag"); mFlags |= nsIPlaintextEditor::eEditorRightToLeft; mFlags &= ~nsIPlaintextEditor::eEditorLeftToRight; @@ -5063,14 +5061,14 @@ EditorBase::SwitchTextDirectionTo(uint32_t aDirection) // Apply the requested direction if (aDirection == nsIPlaintextEditor::eEditorLeftToRight && - (mFlags & nsIPlaintextEditor::eEditorRightToLeft)) { + IsRightToLeft()) { NS_ASSERTION(!(mFlags & nsIPlaintextEditor::eEditorLeftToRight), "Unexpected mutually exclusive flag"); mFlags &= ~nsIPlaintextEditor::eEditorRightToLeft; mFlags |= nsIPlaintextEditor::eEditorLeftToRight; rv = rootElement->SetAttr(kNameSpaceID_None, nsGkAtoms::dir, NS_LITERAL_STRING("ltr"), true); } else if (aDirection == nsIPlaintextEditor::eEditorRightToLeft && - (mFlags & nsIPlaintextEditor::eEditorLeftToRight)) { + IsLeftToRight()) { NS_ASSERTION(!(mFlags & nsIPlaintextEditor::eEditorRightToLeft), "Unexpected mutually exclusive flag"); mFlags |= nsIPlaintextEditor::eEditorRightToLeft; diff --git a/layout/forms/nsTextControlFrame.cpp b/layout/forms/nsTextControlFrame.cpp index 0bf3d71ae988..20be4cabf4bc 100644 --- a/layout/forms/nsTextControlFrame.cpp +++ b/layout/forms/nsTextControlFrame.cpp @@ -1005,34 +1005,30 @@ nsTextControlFrame::AttributeChanged(int32_t aNameSpaceID, } if (nsGkAtoms::readonly == aAttribute) { - uint32_t flags; - textEditor->GetFlags(&flags); if (AttributeExists(nsGkAtoms::readonly)) { // set readonly - flags |= nsIPlaintextEditor::eEditorReadonlyMask; if (nsContentUtils::IsFocusedContent(mContent)) { selCon->SetCaretEnabled(false); } + textEditor->AddFlags(nsIPlaintextEditor::eEditorReadonlyMask); } else { // unset readonly - flags &= ~(nsIPlaintextEditor::eEditorReadonlyMask); if (!textEditor->IsDisabled() && nsContentUtils::IsFocusedContent(mContent)) { selCon->SetCaretEnabled(true); } + textEditor->RemoveFlags(nsIPlaintextEditor::eEditorReadonlyMask); } - textEditor->SetFlags(flags); return NS_OK; } if (nsGkAtoms::disabled == aAttribute) { - uint32_t flags; - textEditor->GetFlags(&flags); int16_t displaySelection = nsISelectionController::SELECTION_OFF; const bool focused = nsContentUtils::IsFocusedContent(mContent); const bool hasAttr = AttributeExists(nsGkAtoms::disabled); + bool disable; if (hasAttr) { // set disabled - flags |= nsIPlaintextEditor::eEditorDisabledMask; + disable = true; } else { // unset disabled - flags &= ~(nsIPlaintextEditor::eEditorDisabledMask); + disable = false; displaySelection = focused ? nsISelectionController::SELECTION_ON : nsISelectionController::SELECTION_HIDDEN; } @@ -1040,7 +1036,11 @@ nsTextControlFrame::AttributeChanged(int32_t aNameSpaceID, if (focused) { selCon->SetCaretEnabled(!hasAttr); } - textEditor->SetFlags(flags); + if (disable) { + textEditor->AddFlags(nsIPlaintextEditor::eEditorDisabledMask); + } else { + textEditor->RemoveFlags(nsIPlaintextEditor::eEditorDisabledMask); + } return NS_OK; } From e1a21d5a3ec0441ea798c06fc5418ac88c049e7b Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Mon, 14 Aug 2017 14:56:39 +0900 Subject: [PATCH 58/87] Bug 1387317 - part5: AutoPlaceHolderBatch should take EditorBase instead of nsIEditor r=m_kato AutoPlaceHolderBatch can take EditorBase class and its inherited class, AutoEditBatch, can be removed if we implement other constructor which doesn't take transaction name. Additionally, nsIEditor::(Begin|End)PlaceHolderTransaction() are referred only by AutoPlaceHolderBatch. Therefore, they can be non-public methods and removed from nsIEditor interface. Note that this patch also repalces "PlaceHolder" with "Placeholder" since it's a word. MozReview-Commit-ID: 5dw3kcX3bOx --HG-- extra : rebase_source : e926cc1c2ebea70eb08e43778a8b52912b559b7b --- editor/libeditor/EditorBase.cpp | 24 +++------ editor/libeditor/EditorBase.h | 13 +++++ editor/libeditor/EditorUtils.h | 49 ++++++++----------- editor/libeditor/HTMLAbsPositionEditor.cpp | 10 ++-- editor/libeditor/HTMLEditor.cpp | 26 +++++----- editor/libeditor/HTMLEditorDataTransfer.cpp | 26 +++++----- editor/libeditor/HTMLEditorObjectResizer.cpp | 2 +- editor/libeditor/HTMLStyleEditor.cpp | 8 +-- editor/libeditor/HTMLTableEditor.cpp | 22 ++++----- editor/libeditor/TextEditor.cpp | 20 ++++---- editor/libeditor/TextEditorDataTransfer.cpp | 6 +-- editor/nsIEditor.idl | 2 - .../spellcheck/src/mozInlineSpellChecker.cpp | 2 +- 13 files changed, 100 insertions(+), 110 deletions(-) diff --git a/editor/libeditor/EditorBase.cpp b/editor/libeditor/EditorBase.cpp index 8192a6f79b0a..503fb585425e 100644 --- a/editor/libeditor/EditorBase.cpp +++ b/editor/libeditor/EditorBase.cpp @@ -956,16 +956,8 @@ EditorBase::EndTransaction() return NS_OK; } - -// These two routines are similar to the above, but do not use -// the transaction managers batching feature. Instead we use -// a placeholder transaction to wrap up any further transaction -// while the batch is open. The advantage of this is that -// placeholder transactions can later merge, if needed. Merging -// is unavailable between transaction manager batches. - -NS_IMETHODIMP -EditorBase::BeginPlaceHolderTransaction(nsIAtom* aName) +void +EditorBase::BeginPlaceholderTransaction(nsIAtom* aTransactionName) { MOZ_ASSERT(mPlaceholderBatch >= 0, "negative placeholder batch count!"); if (!mPlaceholderBatch) { @@ -973,7 +965,7 @@ EditorBase::BeginPlaceHolderTransaction(nsIAtom* aName) // time to turn on the batch BeginUpdateViewBatch(); mPlaceholderTransaction = nullptr; - mPlaceholderName = aName; + mPlaceholderName = aTransactionName; RefPtr selection = GetSelection(); if (selection) { mSelState.emplace(); @@ -989,12 +981,10 @@ EditorBase::BeginPlaceHolderTransaction(nsIAtom* aName) } } mPlaceholderBatch++; - - return NS_OK; } -NS_IMETHODIMP -EditorBase::EndPlaceHolderTransaction() +void +EditorBase::EndPlaceholderTransaction() { MOZ_ASSERT(mPlaceholderBatch > 0, "zero or negative placeholder batch count when ending batch!"); @@ -1057,8 +1047,6 @@ EditorBase::EndPlaceHolderTransaction() } } mPlaceholderBatch--; - - return NS_OK; } NS_IMETHODIMP @@ -2343,7 +2331,7 @@ EditorBase::CloneAttributes(Element* aDest, { MOZ_ASSERT(aDest && aSource); - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); // Use transaction system for undo only if destination is already in the // document diff --git a/editor/libeditor/EditorBase.h b/editor/libeditor/EditorBase.h index 5621763c9568..a5ac7aa95c01 100644 --- a/editor/libeditor/EditorBase.h +++ b/editor/libeditor/EditorBase.h @@ -594,6 +594,18 @@ protected: nsresult GetSelection(SelectionType aSelectionType, nsISelection** aSelection); + /** + * (Begin|End)PlaceholderTransaction() are called by AutoPlaceholderBatch. + * This set of methods are similar to the (Begin|End)Transaction(), but do + * not use the transaction managers batching feature. Instead we use a + * placeholder transaction to wrap up any further transaction while the + * batch is open. The advantage of this is that placeholder transactions + * can later merge, if needed. Merging is unavailable between transaction + * manager batches. + */ + void BeginPlaceholderTransaction(nsIAtom* aTransactionName); + void EndPlaceholderTransaction(); + public: /** * All editor operations which alter the doc should be prefaced @@ -1294,6 +1306,7 @@ protected: bool mIsHTMLEditorClass; friend bool NSCanUnload(nsISupports* serviceMgr); + friend class AutoPlaceholderBatch; friend class AutoRules; friend class AutoSelectionRestorer; friend class AutoTransactionsConserveSelection; diff --git a/editor/libeditor/EditorUtils.h b/editor/libeditor/EditorUtils.h index 6b041a105560..ba39e2428adb 100644 --- a/editor/libeditor/EditorUtils.h +++ b/editor/libeditor/EditorUtils.h @@ -143,52 +143,43 @@ EditActionCanceled(nsresult aRv = NS_OK) /*************************************************************************** * stack based helper class for batching a collection of transactions inside a * placeholder transaction. - * XXX This is used by mozInlineSpellChecker. Therefore, cannot use concrete - * editor class. */ -class MOZ_RAII AutoPlaceHolderBatch +class MOZ_RAII AutoPlaceholderBatch final { private: - nsCOMPtr mEditor; + RefPtr mEditorBase; MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER public: - AutoPlaceHolderBatch(nsIEditor* aEditor, - nsIAtom* aAtom + explicit AutoPlaceholderBatch(EditorBase* aEditorBase + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : mEditorBase(aEditorBase) + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + BeginPlaceholderTransaction(nullptr); + } + AutoPlaceholderBatch(EditorBase* aEditorBase, + nsIAtom* aTransactionName MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mEditor(aEditor) + : mEditorBase(aEditorBase) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; - if (mEditor) { - mEditor->BeginPlaceHolderTransaction(aAtom); - } + BeginPlaceholderTransaction(aTransactionName); } - ~AutoPlaceHolderBatch() + ~AutoPlaceholderBatch() { - if (mEditor) { - mEditor->EndPlaceHolderTransaction(); + if (mEditorBase) { + mEditorBase->EndPlaceholderTransaction(); } } -}; -/*************************************************************************** - * stack based helper class for batching a collection of txns. - * Note: I changed this to use placeholder batching so that we get - * proper selection save/restore across undo/redo. - */ -class MOZ_RAII AutoEditBatch final : public AutoPlaceHolderBatch -{ private: - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER - -public: - explicit AutoEditBatch(nsIEditor* aEditor - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoPlaceHolderBatch(aEditor, nullptr) + void BeginPlaceholderTransaction(nsIAtom* aTransactionName) { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; + if (mEditorBase) { + mEditorBase->BeginPlaceholderTransaction(aTransactionName); + } } - ~AutoEditBatch() {} }; /*************************************************************************** diff --git a/editor/libeditor/HTMLAbsPositionEditor.cpp b/editor/libeditor/HTMLAbsPositionEditor.cpp index 953d69e065f0..5f290874798d 100644 --- a/editor/libeditor/HTMLAbsPositionEditor.cpp +++ b/editor/libeditor/HTMLAbsPositionEditor.cpp @@ -53,7 +53,7 @@ using namespace dom; NS_IMETHODIMP HTMLEditor::AbsolutePositionSelection(bool aEnabled) { - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); AutoRules beginRulesSniffing(this, aEnabled ? EditAction::setAbsolutePosition : EditAction::removeAbsolutePosition, @@ -180,7 +180,7 @@ HTMLEditor::SetElementZIndex(nsIDOMElement* aElement, NS_IMETHODIMP HTMLEditor::RelativeChangeZIndex(int32_t aChange) { - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); AutoRules beginRulesSniffing(this, (aChange < 0) ? EditAction::decreaseZIndex : EditAction::increaseZIndex, @@ -466,7 +466,7 @@ HTMLEditor::SetFinalPosition(int32_t aX, y.AppendInt(newY); // we want one transaction only from a user's point of view - AutoEditBatch batchIt(this); + AutoPlaceholderBatch batchIt(this); nsCOMPtr absolutelyPositionedObject = do_QueryInterface(mAbsolutelyPositionedObject); @@ -510,7 +510,7 @@ HTMLEditor::AbsolutelyPositionElement(nsIDOMElement* aElement, if (isPositioned == aEnabled) return NS_OK; - AutoEditBatch batchIt(this); + AutoPlaceholderBatch batchIt(this); if (aEnabled) { int32_t x, y; @@ -613,7 +613,7 @@ HTMLEditor::SetElementPosition(Element& aElement, int32_t aX, int32_t aY) { - AutoEditBatch batchIt(this); + AutoPlaceholderBatch batchIt(this); mCSSEditUtils->SetCSSPropertyPixels(aElement, *nsGkAtoms::left, aX); mCSSEditUtils->SetCSSPropertyPixels(aElement, *nsGkAtoms::top, aY); } diff --git a/editor/libeditor/HTMLEditor.cpp b/editor/libeditor/HTMLEditor.cpp index 1fdada3e1f18..361d28d55a5e 100644 --- a/editor/libeditor/HTMLEditor.cpp +++ b/editor/libeditor/HTMLEditor.cpp @@ -1016,7 +1016,7 @@ HTMLEditor::TypedText(const nsAString& aString, { MOZ_ASSERT(!aString.IsEmpty() || aAction != eTypedText); - AutoPlaceHolderBatch batch(this, nsGkAtoms::TypingTxnName); + AutoPlaceholderBatch batch(this, nsGkAtoms::TypingTxnName); if (aAction == eTypedBR) { // only inserts a br node @@ -1230,7 +1230,7 @@ HTMLEditor::ReplaceHeadContentsWithHTML(const nsAString& aSourceToInsert) // Mac linebreaks: Map any remaining CR to LF: inputString.ReplaceSubstring(u"\r", u"\n"); - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); // Get the first range in the selection, for context: RefPtr range = selection->GetRangeAt(0); @@ -1318,7 +1318,7 @@ HTMLEditor::RebuildDocumentFromSource(const nsAString& aSourceString) } // Time to change the document - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); nsReadingIterator endtotal; aSourceString.EndReading(endtotal); @@ -1538,7 +1538,7 @@ HTMLEditor::InsertElementAtSelection(nsIDOMElement* aElement, nsCOMPtr node = do_QueryInterface(aElement); CommitComposition(); - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); AutoRules beginRulesSniffing(this, EditAction::insertElement, nsIEditor::eNext); @@ -1997,7 +1997,7 @@ HTMLEditor::MakeOrChangeList(const nsAString& aListType, bool cancel, handled; - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); AutoRules beginRulesSniffing(this, EditAction::makeList, nsIEditor::eNext); // pre-process @@ -2068,7 +2068,7 @@ HTMLEditor::RemoveList(const nsAString& aListType) bool cancel, handled; - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); AutoRules beginRulesSniffing(this, EditAction::removeList, nsIEditor::eNext); // pre-process @@ -2103,7 +2103,7 @@ HTMLEditor::MakeDefinitionItem(const nsAString& aItemType) bool cancel, handled; - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); AutoRules beginRulesSniffing(this, EditAction::makeDefListItem, nsIEditor::eNext); @@ -2136,7 +2136,7 @@ HTMLEditor::InsertBasicBlock(const nsAString& aBlockType) bool cancel, handled; - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); AutoRules beginRulesSniffing(this, EditAction::makeBasicBlock, nsIEditor::eNext); @@ -2208,7 +2208,7 @@ HTMLEditor::Indent(const nsAString& aIndent) if (aIndent.LowerCaseEqualsLiteral("outdent")) { opID = EditAction::outdent; } - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); AutoRules beginRulesSniffing(this, opID, nsIEditor::eNext); // pre-process @@ -2277,7 +2277,7 @@ HTMLEditor::Align(const nsAString& aAlignType) // Protect the edit rules object from dying nsCOMPtr rules(mRules); - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); AutoRules beginRulesSniffing(this, EditAction::align, nsIEditor::eNext); bool cancel, handled; @@ -2689,7 +2689,7 @@ HTMLEditor::InsertLinkAroundSelection(nsIDOMElement* aAnchorElement) return NS_OK; } - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); // Set all attributes found on the supplied anchor element nsCOMPtr attrMap; @@ -3452,7 +3452,7 @@ HTMLEditor::StyleSheetLoaded(StyleSheet* aSheet, bool aWasAlternate, nsresult aStatus) { - AutoEditBatch batchIt(this); + AutoPlaceholderBatch batchIt(this); if (!mLastStyleSheetURL.IsEmpty()) RemoveStyleSheet(mLastStyleSheetURL); @@ -4535,7 +4535,7 @@ HTMLEditor::SetCSSBackgroundColor(const nsAString& aColor) bool isCollapsed = selection->Collapsed(); - AutoEditBatch batchIt(this); + AutoPlaceholderBatch batchIt(this); AutoRules beginRulesSniffing(this, EditAction::insertElement, nsIEditor::eNext); AutoSelectionRestorer selectionRestorer(selection, this); diff --git a/editor/libeditor/HTMLEditorDataTransfer.cpp b/editor/libeditor/HTMLEditorDataTransfer.cpp index b3704163f7ec..018dbd0556f9 100644 --- a/editor/libeditor/HTMLEditorDataTransfer.cpp +++ b/editor/libeditor/HTMLEditorDataTransfer.cpp @@ -103,7 +103,7 @@ HTMLEditor::LoadHTML(const nsAString& aInputString) // force IME commit; set up rules sniffing and batching CommitComposition(); - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); AutoRules beginRulesSniffing(this, EditAction::loadHTML, nsIEditor::eNext); // Get selection @@ -198,7 +198,7 @@ HTMLEditor::DoInsertHTMLWithContext(const nsAString& aInputString, // force IME commit; set up rules sniffing and batching CommitComposition(); - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); AutoRules beginRulesSniffing(this, EditAction::htmlPaste, nsIEditor::eNext); // Get selection @@ -1024,7 +1024,7 @@ HTMLEditor::BlobReader::OnResult(const nsACString& aResult) nsresult rv = ImgFromData(type, aResult, stuffToPaste); NS_ENSURE_SUCCESS(rv, rv); - AutoEditBatch beginBatching(mHTMLEditor); + AutoPlaceholderBatch beginBatching(mHTMLEditor); rv = mHTMLEditor->DoInsertHTMLWithContext(stuffToPaste, EmptyString(), EmptyString(), NS_LITERAL_STRING(kFileMime), @@ -1120,7 +1120,7 @@ HTMLEditor::InsertObject(const nsACString& aType, rv = ImgFromData(type, imageData, stuffToPaste); NS_ENSURE_SUCCESS(rv, rv); - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); rv = DoInsertHTMLWithContext(stuffToPaste, EmptyString(), EmptyString(), NS_LITERAL_STRING(kFileMime), aSourceDoc, @@ -1174,7 +1174,7 @@ HTMLEditor::InsertFromTransferable(nsITransferable* transferable, rv = ParseCFHTML(cfhtml, getter_Copies(cffragment), getter_Copies(cfcontext)); if (NS_SUCCEEDED(rv) && !cffragment.IsEmpty()) { - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); // If we have our private HTML flavor, we will only use the fragment // from the CF_HTML. The rest comes from the clipboard. if (havePrivateHTMLFlavor) { @@ -1224,7 +1224,7 @@ HTMLEditor::InsertFromTransferable(nsITransferable* transferable, } if (!stuffToPaste.IsEmpty()) { - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); if (bestFlavor.EqualsLiteral(kHTMLMime)) { rv = DoInsertHTMLWithContext(stuffToPaste, aContextStr, aInfoStr, flavor, @@ -1308,7 +1308,7 @@ HTMLEditor::InsertFromDataTransfer(DataTransfer* aDataTransfer, nsresult rv = ParseCFHTML(cfhtml, getter_Copies(cffragment), getter_Copies(cfcontext)); if (NS_SUCCEEDED(rv) && !cffragment.IsEmpty()) { - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); if (hasPrivateHTMLFlavor) { // If we have our private HTML flavor, we will only use the fragment @@ -1337,7 +1337,7 @@ HTMLEditor::InsertFromDataTransfer(DataTransfer* aDataTransfer, GetStringFromDataTransfer(aDataTransfer, NS_LITERAL_STRING(kHTMLContext), aIndex, contextString); GetStringFromDataTransfer(aDataTransfer, NS_LITERAL_STRING(kHTMLInfo), aIndex, infoString); - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); if (type.EqualsLiteral(kHTMLMime)) { return DoInsertHTMLWithContext(text, contextString, infoString, type, @@ -1354,7 +1354,7 @@ HTMLEditor::InsertFromDataTransfer(DataTransfer* aDataTransfer, nsAutoString text; GetStringFromDataTransfer(aDataTransfer, type, aIndex, text); - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); return InsertTextAt(text, aDestinationNode, aDestOffset, aDoDeleteSelection); } } @@ -1632,7 +1632,7 @@ NS_IMETHODIMP HTMLEditor::PasteAsCitedQuotation(const nsAString& aCitation, int32_t aSelectionType) { - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); AutoRules beginRulesSniffing(this, EditAction::insertQuotation, nsIEditor::eNext); @@ -1708,7 +1708,7 @@ HTMLEditor::PasteAsPlaintextQuotation(int32_t aSelectionType) nsAutoString stuffToPaste; textDataObj->GetData(stuffToPaste); NS_ASSERTION(stuffToPaste.Length() <= (len/2), "Invalid length!"); - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); rv = InsertAsPlaintextQuotation(stuffToPaste, true, 0); } } @@ -1835,7 +1835,7 @@ HTMLEditor::InsertAsPlaintextQuotation(const nsAString& aQuotedText, RefPtr selection = GetSelection(); NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER); - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); AutoRules beginRulesSniffing(this, EditAction::insertQuotation, nsIEditor::eNext); @@ -1935,7 +1935,7 @@ HTMLEditor::InsertAsCitedQuotation(const nsAString& aQuotedText, RefPtr selection = GetSelection(); NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER); - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); AutoRules beginRulesSniffing(this, EditAction::insertQuotation, nsIEditor::eNext); diff --git a/editor/libeditor/HTMLEditorObjectResizer.cpp b/editor/libeditor/HTMLEditorObjectResizer.cpp index f297d8840dfc..56b94e2b444f 100644 --- a/editor/libeditor/HTMLEditorObjectResizer.cpp +++ b/editor/libeditor/HTMLEditorObjectResizer.cpp @@ -906,7 +906,7 @@ HTMLEditor::SetFinalSize(int32_t aX, y = top - ((mResizedObjectIsAbsolutelyPositioned) ? mResizedObjectBorderTop+mResizedObjectMarginTop : 0); // we want one transaction only from a user's point of view - AutoEditBatch batchIt(this); + AutoPlaceholderBatch batchIt(this); if (mResizedObjectIsAbsolutelyPositioned) { if (setHeight) { diff --git a/editor/libeditor/HTMLStyleEditor.cpp b/editor/libeditor/HTMLStyleEditor.cpp index 15de87d233d8..b18dcc6156f3 100644 --- a/editor/libeditor/HTMLStyleEditor.cpp +++ b/editor/libeditor/HTMLStyleEditor.cpp @@ -122,7 +122,7 @@ HTMLEditor::SetInlineProperty(nsIAtom* aProperty, return NS_OK; } - AutoEditBatch batchIt(this); + AutoPlaceholderBatch batchIt(this); AutoRules beginRulesSniffing(this, EditAction::insertElement, nsIEditor::eNext); AutoSelectionRestorer selectionRestorer(selection, this); @@ -1180,7 +1180,7 @@ HTMLEditor::GetInlinePropertyWithAttrValue(nsIAtom* aProperty, NS_IMETHODIMP HTMLEditor::RemoveAllInlineProperties() { - AutoEditBatch batchIt(this); + AutoPlaceholderBatch batchIt(this); AutoRules beginRulesSniffing(this, EditAction::resetTextProperties, nsIEditor::eNext); @@ -1224,7 +1224,7 @@ HTMLEditor::RemoveInlinePropertyImpl(nsIAtom* aProperty, return NS_OK; } - AutoEditBatch batchIt(this); + AutoPlaceholderBatch batchIt(this); AutoRules beginRulesSniffing(this, EditAction::removeTextProperty, nsIEditor::eNext); AutoSelectionRestorer selectionRestorer(selection, this); @@ -1381,7 +1381,7 @@ HTMLEditor::RelativeFontChange(FontSize aDir) } // Wrap with txn batching, rules sniffing, and selection preservation code - AutoEditBatch batchIt(this); + AutoPlaceholderBatch batchIt(this); AutoRules beginRulesSniffing(this, EditAction::setTextProperty, nsIEditor::eNext); AutoSelectionRestorer selectionRestorer(selection, this); diff --git a/editor/libeditor/HTMLTableEditor.cpp b/editor/libeditor/HTMLTableEditor.cpp index f1bec30d67b4..97311c7b7585 100644 --- a/editor/libeditor/HTMLTableEditor.cpp +++ b/editor/libeditor/HTMLTableEditor.cpp @@ -415,7 +415,7 @@ HTMLEditor::InsertTableColumn(int32_t aNumber, NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(curCell, NS_ERROR_FAILURE); - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); // Prevent auto insertion of BR in new cell until we're done AutoRules beginRulesSniffing(this, EditAction::insertNode, nsIEditor::eNext); @@ -550,7 +550,7 @@ HTMLEditor::InsertTableRow(int32_t aNumber, rv = GetTableSize(table, &rowCount, &colCount); NS_ENSURE_SUCCESS(rv, rv); - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); // Prevent auto insertion of BR in new cell until we're done AutoRules beginRulesSniffing(this, EditAction::insertNode, nsIEditor::eNext); @@ -732,7 +732,7 @@ HTMLEditor::DeleteTable() nullptr, nullptr, nullptr, nullptr, nullptr); NS_ENSURE_SUCCESS(rv, rv); - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); return DeleteTable2(table, selection); } @@ -755,7 +755,7 @@ HTMLEditor::DeleteTableCell(int32_t aNumber) // Don't fail if we didn't find a table or cell NS_ENSURE_TRUE(table && cell, NS_SUCCESS_EDITOR_ELEMENT_NOT_FOUND); - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); // Prevent rules testing until we're done AutoRules beginRulesSniffing(this, EditAction::deleteNode, nsIEditor::eNext); @@ -944,7 +944,7 @@ HTMLEditor::DeleteTableCellContents() NS_ENSURE_TRUE(cell, NS_SUCCESS_EDITOR_ELEMENT_NOT_FOUND); - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); // Prevent rules testing until we're done AutoRules beginRulesSniffing(this, EditAction::deleteNode, nsIEditor::eNext); //Don't let Rules System change the selection @@ -1028,7 +1028,7 @@ HTMLEditor::DeleteTableColumn(int32_t aNumber) // Check for counts too high aNumber = std::min(aNumber,(colCount-startColIndex)); - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); // Prevent rules testing until we're done AutoRules beginRulesSniffing(this, EditAction::deleteNode, nsIEditor::eNext); @@ -1194,7 +1194,7 @@ HTMLEditor::DeleteTableRow(int32_t aNumber) return DeleteTable2(table, selection); } - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); // Prevent rules testing until we're done AutoRules beginRulesSniffing(this, EditAction::deleteNode, nsIEditor::eNext); @@ -1734,7 +1734,7 @@ HTMLEditor::SplitTableCell() return NS_OK; } - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); // Prevent auto insertion of BR in new cell until we're done AutoRules beginRulesSniffing(this, EditAction::insertNode, nsIEditor::eNext); @@ -1962,7 +1962,7 @@ HTMLEditor::SwitchTableCellHeaderType(nsIDOMElement* aSourceCell, nsCOMPtr sourceCell = do_QueryInterface(aSourceCell); NS_ENSURE_TRUE(sourceCell, NS_ERROR_NULL_POINTER); - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); // Prevent auto insertion of BR in new cell created by ReplaceContainer AutoRules beginRulesSniffing(this, EditAction::insertNode, nsIEditor::eNext); @@ -2015,7 +2015,7 @@ HTMLEditor::JoinTableCells(bool aMergeNonContiguousContents) return NS_SUCCESS_EDITOR_ELEMENT_NOT_FOUND; } - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); //Don't let Rules System change the selection AutoTransactionsConserveSelection dontChangeSelection(this); @@ -2510,7 +2510,7 @@ HTMLEditor::NormalizeTable(nsIDOMElement* aTable) // Save current selection AutoSelectionRestorer selectionRestorer(selection, this); - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); // Prevent auto insertion of BR in new cell until we're done AutoRules beginRulesSniffing(this, EditAction::insertNode, nsIEditor::eNext); diff --git a/editor/libeditor/TextEditor.cpp b/editor/libeditor/TextEditor.cpp index db1271e1e73e..5fcd52a9f832 100644 --- a/editor/libeditor/TextEditor.cpp +++ b/editor/libeditor/TextEditor.cpp @@ -9,7 +9,7 @@ #include "TextEditUtils.h" #include "gfxFontUtils.h" #include "mozilla/Assertions.h" -#include "mozilla/EditorUtils.h" // AutoEditBatch, AutoRules +#include "mozilla/EditorUtils.h" // AutoPlaceholderBatch, AutoRules #include "mozilla/HTMLEditor.h" #include "mozilla/mozalloc.h" #include "mozilla/Preferences.h" @@ -400,7 +400,7 @@ TextEditor::HandleKeyPressEvent(WidgetKeyboardEvent* aKeyboardEvent) NS_IMETHODIMP TextEditor::TypedText(const nsAString& aString, ETypingAction aAction) { - AutoPlaceHolderBatch batch(this, nsGkAtoms::TypingTxnName); + AutoPlaceholderBatch batch(this, nsGkAtoms::TypingTxnName); switch (aAction) { case eTypedText: @@ -596,7 +596,7 @@ TextEditor::DeleteSelection(EDirection aAction, nsCOMPtr rules(mRules); // delete placeholder txns merge. - AutoPlaceHolderBatch batch(this, nsGkAtoms::DeleteTxnName); + AutoPlaceholderBatch batch(this, nsGkAtoms::DeleteTxnName); AutoRules beginRulesSniffing(this, EditAction::deleteSelection, aAction); // pre-process @@ -649,7 +649,7 @@ TextEditor::InsertText(const nsAString& aStringToInsert) if (ShouldHandleIMEComposition()) { opID = EditAction::insertIMEText; } - AutoPlaceHolderBatch batch(this, nullptr); + AutoPlaceholderBatch batch(this, nullptr); AutoRules beginRulesSniffing(this, opID, nsIEditor::eNext); // pre-process @@ -687,7 +687,7 @@ TextEditor::InsertLineBreak() // Protect the edit rules object from dying nsCOMPtr rules(mRules); - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); AutoRules beginRulesSniffing(this, EditAction::insertBreak, nsIEditor::eNext); // pre-process @@ -765,7 +765,7 @@ TextEditor::SetText(const nsAString& aString) nsCOMPtr rules(mRules); // delete placeholder txns merge. - AutoPlaceHolderBatch batch(this, nullptr); + AutoPlaceholderBatch batch(this, nullptr); AutoRules beginRulesSniffing(this, EditAction::setText, nsIEditor::eNext); // pre-process @@ -869,10 +869,10 @@ TextEditor::UpdateIMEComposition(WidgetCompositionEvent* aCompsitionChangeEvent) nsresult rv; { - AutoPlaceHolderBatch batch(this, nsGkAtoms::IMETxnName); + AutoPlaceholderBatch batch(this, nsGkAtoms::IMETxnName); MOZ_ASSERT(mIsInEditAction, - "AutoPlaceHolderBatch should've notified the observes of before-edit"); + "AutoPlaceholderBatch should've notified the observes of before-edit"); rv = InsertText(aCompsitionChangeEvent->mData); if (caretP) { @@ -1404,7 +1404,7 @@ TextEditor::PasteAsQuotation(int32_t aSelectionType) if (textDataObj && len > 0) { nsAutoString stuffToPaste; textDataObj->GetData ( stuffToPaste ); - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); rv = InsertAsQuotation(stuffToPaste, 0); } } @@ -1435,7 +1435,7 @@ TextEditor::InsertAsQuotation(const nsAString& aQuotedText, RefPtr selection = GetSelection(); NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER); - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); AutoRules beginRulesSniffing(this, EditAction::insertText, nsIEditor::eNext); // give rules a chance to handle or cancel diff --git a/editor/libeditor/TextEditorDataTransfer.cpp b/editor/libeditor/TextEditorDataTransfer.cpp index 02cd9741c4c6..7695248f758e 100644 --- a/editor/libeditor/TextEditorDataTransfer.cpp +++ b/editor/libeditor/TextEditorDataTransfer.cpp @@ -123,7 +123,7 @@ TextEditor::InsertTextFromTransferable(nsITransferable* aTransferable, // Sanitize possible carriage returns in the string to be inserted nsContentUtils::PlatformToDOMLineBreaks(stuffToPaste); - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); rv = InsertTextAt(stuffToPaste, aDestinationNode, aDestOffset, aDoDeleteSelection); } } @@ -153,7 +153,7 @@ TextEditor::InsertFromDataTransfer(DataTransfer* aDataTransfer, data->GetAsAString(insertText); nsContentUtils::PlatformToDOMLineBreaks(insertText); - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); return InsertTextAt(insertText, aDestinationNode, aDestOffset, aDoDeleteSelection); } @@ -206,7 +206,7 @@ TextEditor::InsertFromDrop(nsIDOMEvent* aDropEvent) } // Combine any deletion and drop insertion into one transaction - AutoEditBatch beginBatching(this); + AutoPlaceholderBatch beginBatching(this); bool deleteSelection = false; diff --git a/editor/nsIEditor.idl b/editor/nsIEditor.idl index 4dbb29a66711..cf88efe098f7 100644 --- a/editor/nsIEditor.idl +++ b/editor/nsIEditor.idl @@ -265,8 +265,6 @@ interface nsIEditor : nsISupports */ void endTransaction(); - void beginPlaceHolderTransaction(in nsIAtom name); - void endPlaceHolderTransaction(); boolean shouldTxnSetSelection(); /** Set the flag that prevents insertElementTxn from changing the selection diff --git a/extensions/spellcheck/src/mozInlineSpellChecker.cpp b/extensions/spellcheck/src/mozInlineSpellChecker.cpp index 92860aeafe45..16941f42f98b 100644 --- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp +++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp @@ -970,7 +970,7 @@ mozInlineSpellChecker::ReplaceWord(nsIDOMNode *aNode, int32_t aOffset, res = range->CloneRange(getter_AddRefs(editorRange)); NS_ENSURE_SUCCESS(res, res); - AutoPlaceHolderBatch phb(mTextEditor, nullptr); + AutoPlaceholderBatch phb(mTextEditor, nullptr); nsCOMPtr selection; res = mTextEditor->GetSelection(getter_AddRefs(selection)); From c063aa0150413f37c731aa8a833018ad9a7635b5 Mon Sep 17 00:00:00 2001 From: Ricky Chien Date: Wed, 26 Jul 2017 15:00:55 +0800 Subject: [PATCH 59/87] Bug 1377174 - Tweak margin to match the spec r=jaws MozReview-Commit-ID: GKZb427Ahum --HG-- extra : rebase_source : bb8ce568d831db17964578ed21afa4168c149f2f --- .../preferences/in-content-new/main.xul | 6 +- .../preferences/in-content-new/privacy.xul | 2 + .../preferences/in-content-new/search.xul | 11 +- .../in-content-new/searchResults.xul | 2 +- .../preferences/in-content-new/sync.xul | 26 +- .../in-content-new/preferences.css | 11 +- .../themes/osx/preferences/preferences.css | 5 - .../shared/incontentprefs/preferences.inc.css | 246 +++++++++++------- .../themes/shared/in-content/common.inc.css | 56 ++-- 9 files changed, 214 insertions(+), 151 deletions(-) diff --git a/browser/components/preferences/in-content-new/main.xul b/browser/components/preferences/in-content-new/main.xul index 6bc05eee8d71..45360f50a1b1 100644 --- a/browser/components/preferences/in-content-new/main.xul +++ b/browser/components/preferences/in-content-new/main.xul @@ -349,7 +349,7 @@ - + @@ -365,7 +365,7 @@ preference="browser.startup.homepage"/> - + - - - - - - + + + &signedOut.description; - + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - -