From fd702be66b640f3be08ac738f02f45c89242841a Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Tue, 13 Nov 2018 02:23:41 +0000 Subject: [PATCH 01/33] Bug 1506676. blob-inval: handle the parent item being removed. r=mattwoodrow If the parent item is removed our assertions will be wrong because the parent item's bounds will not be added to the invalid rect until after we've traversed all of the items. Further, the new unbounded rect for the child item won't be added to the invalid rect unless we do it ourselves. This makes sure we add the old and new rects to the invalid rect. Differential Revision: https://phabricator.services.mozilla.com/D11724 --HG-- extra : moz-landing-system : lando --- gfx/layers/wr/WebRenderCommandBuilder.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/gfx/layers/wr/WebRenderCommandBuilder.cpp b/gfx/layers/wr/WebRenderCommandBuilder.cpp index 3a29ef4c62f7..6fe60b5a7831 100644 --- a/gfx/layers/wr/WebRenderCommandBuilder.cpp +++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp @@ -554,10 +554,10 @@ struct DIGroup combined = clip.ApplyNonRoundedIntersection(geometry->ComputeInvalidationRegion()); IntRect transformedRect = ToDeviceSpace(combined.GetBounds(), aMatrix, appUnitsPerDevPixel, mLayerBounds.TopLeft()); // The invalid rect should contain the old rect and the new rect - // because the parent should have invalidated this area - MOZ_RELEASE_ASSERT(mInvalidRect.Contains(aData->mRect)); + // but may not because the parent may have been removed. + InvalidateRect(aData->mRect); aData->mRect = transformedRect.Intersect(mImageBounds); - MOZ_RELEASE_ASSERT(mInvalidRect.Contains(aData->mRect)); + InvalidateRect(aData->mRect); GP("ContainerLayer image rect bounds change\n"); } else { // XXX: this code can eventually be deleted/made debug only @@ -574,10 +574,10 @@ struct DIGroup combined = clip.ApplyNonRoundedIntersection(geometry->ComputeInvalidationRegion()); IntRect transformedRect = ToDeviceSpace(combined.GetBounds(), aMatrix, appUnitsPerDevPixel, mLayerBounds.TopLeft()); // The invalid rect should contain the old rect and the new rect - // because the parent should have invalidated this area - MOZ_RELEASE_ASSERT(mInvalidRect.Contains(aData->mRect)); + // but may not because the parent may have been removed. + InvalidateRect(aData->mRect); aData->mRect = transformedRect.Intersect(mImageBounds); - MOZ_RELEASE_ASSERT(mInvalidRect.Contains(aData->mRect)); + InvalidateRect(aData->mRect); GP("image rect bounds change\n"); } else { // XXX: this code can eventually be deleted/made debug only From 478074e691f222a3756df0dbf00d02386c514c3c Mon Sep 17 00:00:00 2001 From: Matt Woodrow Date: Tue, 13 Nov 2018 03:15:51 +0000 Subject: [PATCH 02/33] Bug 1506492 - Report WebRender swap-chain memory usage. r=bholley Differential Revision: https://phabricator.services.mozilla.com/D11594 --HG-- extra : moz-landing-system : lando --- gfx/thebes/gfxPlatform.cpp | 1 + gfx/webrender_bindings/RenderThread.cpp | 7 ++++--- gfx/webrender_bindings/RendererOGL.cpp | 17 +++++++++++++++++ gfx/webrender_bindings/RendererOGL.h | 2 ++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index 575e653c6aae..7caf63ccd788 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -747,6 +747,7 @@ WebRenderMemoryReporter::CollectReports(nsIHandleReportCallback* aHandleReport, helper.ReportTexture(aReport.render_target_textures, "render-targets"); helper.ReportTexture(aReport.texture_cache_textures, "texture-cache"); helper.ReportTexture(aReport.depth_target_textures, "depth-targets"); + helper.ReportTexture(aReport.swap_chain, "swap-chains"); // Total GPU bytes, for sanity-checking the above. helper.ReportTotalGPUBytes(aReport.total_gpu_bytes_allocated); diff --git a/gfx/webrender_bindings/RenderThread.cpp b/gfx/webrender_bindings/RenderThread.cpp index 9269387eca66..f1d22eaea36a 100644 --- a/gfx/webrender_bindings/RenderThread.cpp +++ b/gfx/webrender_bindings/RenderThread.cpp @@ -147,13 +147,14 @@ void RenderThread::DoAccumulateMemoryReport(MemoryReport aReport, const RefPtr& aPromise) { MOZ_ASSERT(IsInRenderThread()); + MOZ_ASSERT(aReport.total_gpu_bytes_allocated == 0); + for (auto& r: mRenderers) { - wr_renderer_accumulate_memory_report(r.second->GetRenderer(), &aReport); + r.second->AccumulateMemoryReport(&aReport); } // Note total gpu bytes allocated across all WR instances. - MOZ_ASSERT(aReport.total_gpu_bytes_allocated == 0); - aReport.total_gpu_bytes_allocated = wr_total_gpu_bytes_allocated(); + aReport.total_gpu_bytes_allocated += wr_total_gpu_bytes_allocated(); aPromise->Resolve(aReport, __func__); } diff --git a/gfx/webrender_bindings/RendererOGL.cpp b/gfx/webrender_bindings/RendererOGL.cpp index 1a15d68ac1c3..043486fd75d4 100644 --- a/gfx/webrender_bindings/RendererOGL.cpp +++ b/gfx/webrender_bindings/RendererOGL.cpp @@ -8,6 +8,7 @@ #include "GLContext.h" #include "mozilla/gfx/Logging.h" #include "mozilla/gfx/gfxVars.h" +#include "mozilla/gfx/Types.h" #include "mozilla/layers/CompositorBridgeParent.h" #include "mozilla/layers/CompositorThread.h" #include "mozilla/layers/LayersTypes.h" @@ -248,6 +249,22 @@ RendererOGL::GetRenderTexture(wr::WrExternalImageId aExternalImageId) return mThread->GetRenderTexture(aExternalImageId); } +void +RendererOGL::AccumulateMemoryReport(MemoryReport* aReport) +{ + wr_renderer_accumulate_memory_report(GetRenderer(), aReport); + + LayoutDeviceIntSize size = mCompositor->GetBufferSize(); + + // Assume BGRA8 for the format since it's not exposed anywhere, + // and all compositor backends should be using that. + uintptr_t swapChainSize = size.width * size.height * + BytesPerPixel(SurfaceFormat::B8G8R8A8) * + (mCompositor->UseTripleBuffering() ? 3 : 2); + aReport->swap_chain += swapChainSize; + aReport->total_gpu_bytes_allocated += swapChainSize; +} + static void DoNotifyWebRenderError(layers::CompositorBridgeParent* aBridge, WebRenderError aError) { diff --git a/gfx/webrender_bindings/RendererOGL.h b/gfx/webrender_bindings/RendererOGL.h index ea2c94d541da..0bcf98acb7b3 100644 --- a/gfx/webrender_bindings/RendererOGL.h +++ b/gfx/webrender_bindings/RendererOGL.h @@ -95,6 +95,8 @@ public: RenderTextureHost* GetRenderTexture(wr::WrExternalImageId aExternalImageId); + void AccumulateMemoryReport(MemoryReport* aReport); + wr::Renderer* GetRenderer() { return mRenderer; } gl::GLContext* gl() const; From b6884c792045694f99c4469b85a685490f7320f3 Mon Sep 17 00:00:00 2001 From: Drew Willcoxon Date: Mon, 12 Nov 2018 15:45:39 +0000 Subject: [PATCH 03/33] Bug 1504854 - Autofilled search shortcuts should show a single "Search with Engine" heuristic result in the popup r=mak All we need to do is set `_searchEngineAliasMatch` with an empty query so that we don't try to add any more results. That hits the existing case where the user types out a full @ alias and we show only the "search with engine" heuristic result. Differential Revision: https://phabricator.services.mozilla.com/D11547 --HG-- extra : moz-landing-system : lando --- toolkit/components/places/UnifiedComplete.js | 15 +++++++++++++-- .../test_autofill_search_engine_aliases.js | 16 ++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/toolkit/components/places/UnifiedComplete.js b/toolkit/components/places/UnifiedComplete.js index 8bdd63858515..e7f74f0b8228 100644 --- a/toolkit/components/places/UnifiedComplete.js +++ b/toolkit/components/places/UnifiedComplete.js @@ -1114,7 +1114,7 @@ Search.prototype = { return true; }, - async _matchSearchEngineTokenAlias() { + async _matchSearchEngineTokenAliasForAutofill() { // We need a single "@engine" search token. if (this._searchTokens.length != 1) { return false; @@ -1152,6 +1152,17 @@ Search.prototype = { icon: engine.iconURI ? engine.iconURI.spec : null, }); this._result.setDefaultIndex(0); + + // Set _searchEngineAliasMatch with an empty query so that we don't + // attempt to add any more matches. When a token alias is autofilled, + // the only match should be the one we just added. + this._searchEngineAliasMatch = { + engine, + alias: aliasPreservingUserCase, + query: "", + isTokenAlias: true, + }; + return true; } } @@ -1224,7 +1235,7 @@ Search.prototype = { } if (this.pending && shouldAutofill) { - let matched = await this._matchSearchEngineTokenAlias(); + let matched = await this._matchSearchEngineTokenAliasForAutofill(); if (matched) { return true; } diff --git a/toolkit/components/places/tests/unifiedcomplete/test_autofill_search_engine_aliases.js b/toolkit/components/places/tests/unifiedcomplete/test_autofill_search_engine_aliases.js index d67326f3a686..883d0ed8a7ff 100644 --- a/toolkit/components/places/tests/unifiedcomplete/test_autofill_search_engine_aliases.js +++ b/toolkit/components/places/tests/unifiedcomplete/test_autofill_search_engine_aliases.js @@ -24,6 +24,14 @@ add_task(async function init() { // Searching for @autofi should autofill to @autofilltest. add_task(async function basic() { + // Add a history visit that should normally match but for the fact that the + // search uses an @ alias. When an @ alias is autofilled, there should be no + // other matches except the autofill heuristic match. + await PlacesTestUtils.addVisits({ + uri: "http://example.com/", + title: TEST_ENGINE_ALIAS, + }); + let autofilledValue = TEST_ENGINE_ALIAS + " "; let completedURL = PlacesUtils.mozActionURI("searchengine", { engineName: TEST_ENGINE_NAME, @@ -49,6 +57,14 @@ add_task(async function basic() { // Searching for @AUTOFI should autofill to @AUTOFIlltest, preserving the case // in the search string. add_task(async function preserveCase() { + // Add a history visit that should normally match but for the fact that the + // search uses an @ alias. When an @ alias is autofilled, there should be no + // other matches except the autofill heuristic match. + await PlacesTestUtils.addVisits({ + uri: "http://example.com/", + title: TEST_ENGINE_ALIAS, + }); + let search = TEST_ENGINE_ALIAS.toUpperCase() .substr(0, Math.round(TEST_ENGINE_ALIAS.length / 2)); From 5902f4631a6e7c0c278ff92fc0b1c30262c820dd Mon Sep 17 00:00:00 2001 From: Jan Henning Date: Tue, 13 Nov 2018 06:55:01 +0000 Subject: [PATCH 04/33] Bug 1506689 - Wait for JNI_READY before getting profiler time stamp from Gecko. r=snorp Differential Revision: https://phabricator.services.mozilla.com/D11692 --HG-- extra : moz-landing-system : lando --- .../android/base/java/org/mozilla/gecko/GeckoJavaSampler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mobile/android/base/java/org/mozilla/gecko/GeckoJavaSampler.java b/mobile/android/base/java/org/mozilla/gecko/GeckoJavaSampler.java index fc8860899b00..3c13457d1851 100644 --- a/mobile/android/base/java/org/mozilla/gecko/GeckoJavaSampler.java +++ b/mobile/android/base/java/org/mozilla/gecko/GeckoJavaSampler.java @@ -32,7 +32,7 @@ public class GeckoJavaSampler { public long mJavaTime; // non-zero if Android system time is used public Sample(StackTraceElement[] aStack) { mFrames = new Frame[aStack.length]; - if (GeckoThread.isStateAtLeast(GeckoThread.State.LIBS_READY)) { + if (GeckoThread.isStateAtLeast(GeckoThread.State.JNI_READY)) { mTime = getProfilerTime(); } if (mTime == 0.0d) { From 0b3117868137d8cc3aba149b2294b8aa6dbb0e05 Mon Sep 17 00:00:00 2001 From: Jan Henning Date: Tue, 13 Nov 2018 06:55:03 +0000 Subject: [PATCH 05/33] Bug 1506699 - Make dumping a profile to disk easier when using MOZ_PROFILER_SHUTDOWN. r=snorp We're already have some special handling in the Android UI when detecting MOZ_PROFILER_STARTUP, so we might as well handle MOZ_PROFILER_SHUTDOWN, too. This means two things: 1. In order to actually quit the app, the "Quit" button needs to be enabled. 2. We need to wait until we're sure that the profile has been dumped to disk before finishing the activity (and thereby possibly killing our process). Differential Revision: https://phabricator.services.mozilla.com/D11696 --HG-- extra : moz-landing-system : lando --- .../base/java/org/mozilla/gecko/BrowserApp.java | 16 ++++++++++++---- .../base/java/org/mozilla/gecko/GeckoApp.java | 12 +++++++++--- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java index b4417d85138e..5c4fd5989f97 100644 --- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java +++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java @@ -1867,9 +1867,16 @@ public class BrowserApp extends GeckoApp case "Sanitize:Finished": if (message.getBoolean("shutdown", false)) { - // Gecko is shutting down and has called our sanitize handlers, - // so we can start exiting, too. - finishAndShutdown(/* restart */ false); + // Gecko is shutting down and has called our sanitize handlers, so to make us + // appear more responsive, we can start shutting down the UI as well, even if + // that means that Android might kill our process before Gecko has fully exited. + + // There is at least one exception, though: If we want to dump a captured + // profile to disk, Gecko must be able to fully shutdown, so we only kill the UI + // later on, in response to the Gecko thread exiting. + if (!mDumpProfileOnShutdown) { + finishAndShutdown(/* restart */ false); + } } break; @@ -3144,12 +3151,13 @@ public class BrowserApp extends GeckoApp final MenuItem enterGuestMode = aMenu.findItem(R.id.new_guest_session); final MenuItem exitGuestMode = aMenu.findItem(R.id.exit_guest_session); - // Only show the "Quit" menu item on pre-ICS, television devices, + // Only show the "Quit" menu when capturing a profile, on television devices, // or if the user has explicitly enabled the clear on shutdown pref. // (We check the pref last to save the pref read.) // In ICS+, it's easy to kill an app through the task switcher. final SharedPreferences prefs = GeckoSharedPrefs.forProfile(this); final boolean visible = HardwareUtils.isTelevision() || + mDumpProfileOnShutdown || prefs.getBoolean(GeckoPreferences.PREFS_SHOW_QUIT_MENU, false) || !PrefUtils.getStringSet(prefs, ClearOnShutdownPref.PREF, diff --git a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java index ae08a9a88745..76b0e1fcb786 100644 --- a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java +++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java @@ -178,6 +178,8 @@ public abstract class GeckoApp extends GeckoActivity /** Tells if we're aborting app launch, e.g. if this is an unsupported device configuration. */ protected boolean mIsAbortingAppLaunch; + protected boolean mDumpProfileOnShutdown; + private PromptService mPromptService; protected TextSelection mTextSelection; @@ -923,8 +925,9 @@ public abstract class GeckoApp extends GeckoActivity /** * Check and start the Java profiler if MOZ_PROFILER_STARTUP env var is specified. + * Also check whether we want to dump the captured profile on shutdown. **/ - protected static void earlyStartJavaSampler(SafeIntent intent) { + protected void handleGeckoProfilerOptions(SafeIntent intent) { String env = intent.getStringExtra("env0"); for (int i = 1; env != null; i++) { if (env.startsWith("MOZ_PROFILER_STARTUP=")) { @@ -932,7 +935,10 @@ public abstract class GeckoApp extends GeckoActivity GeckoJavaSampler.start(10, 1000); Log.d(LOGTAG, "Profiling Java on startup"); } - break; + } else if (env.startsWith("MOZ_PROFILER_SHUTDOWN=")) { + if (!env.endsWith("=")) { + mDumpProfileOnShutdown = true; + } } env = intent.getStringExtra("env" + i); } @@ -977,7 +983,7 @@ public abstract class GeckoApp extends GeckoActivity final SafeIntent intent = new SafeIntent(getIntent()); - earlyStartJavaSampler(intent); + handleGeckoProfilerOptions(intent); // Workaround for . try { From cb4aa814b8d46253c33c3dee27b857691ea0ea60 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Tue, 13 Nov 2018 08:22:25 +0000 Subject: [PATCH 06/33] Bug 1506756 - Remove the use of real_path added in bug 1501903. r=andi In the first part of bug 1501903, paths were canonicalized in inThirdPartyPath. For some reason, this seems to add a non-negligible overhead on Windows. OTOH, most include paths handed by the build system are absolute, and most paths that contains .. are for system headers, which don't matter for the inThirdPartyPath test. Considering the inThirdPartyPath has been using non-canonicalized paths for the longest, we'll assume it's fine to come back to that mode. Differential Revision: https://phabricator.services.mozilla.com/D11725 --HG-- extra : moz-landing-system : lando --- build/clang-plugin/Utils.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/build/clang-plugin/Utils.h b/build/clang-plugin/Utils.h index 24af9248e209..65196b9e6319 100644 --- a/build/clang-plugin/Utils.h +++ b/build/clang-plugin/Utils.h @@ -356,10 +356,8 @@ inline bool inThirdPartyPath(SourceLocation Loc, const SourceManager &SM) { return pair->second; } - SmallString<1024> RawFileName = SM.getFilename(Loc); - llvm::sys::fs::make_absolute(RawFileName); - SmallString<1024> FileName; - llvm::sys::fs::real_path(RawFileName, FileName); + SmallString<1024> FileName = SM.getFilename(Loc); + llvm::sys::fs::make_absolute(FileName); for (uint32_t i = 0; i < MOZ_THIRD_PARTY_PATHS_COUNT; ++i) { auto PathB = sys::path::begin(FileName); From 8d34d6b733e0bf35c399065d4a77187c3dc706f3 Mon Sep 17 00:00:00 2001 From: Qinghao_Jack_Song Date: Mon, 12 Nov 2018 19:34:21 +0000 Subject: [PATCH 07/33] Bug 1498451 - Migrate Device Manager Dialog of Preferences Section to use Fluent for localization r=Gijs,flod,zbraniecki Differential Revision: https://phabricator.services.mozilla.com/D7978 --HG-- extra : moz-landing-system : lando --- .../preferences/in-content/preferences.xul | 3 +- .../preferences/in-content/privacy.xul | 20 +- .../bug_1498451_deviceManager.py | 182 ++++++++++++++++++ .../en-US/chrome/pipnss/pipnss.properties | 3 - .../en-US/chrome/pippki/deviceManager.dtd | 36 ---- .../en-US/chrome/pippki/pippki.properties | 24 --- .../security/certificates/deviceManager.ftl | 130 +++++++++++++ security/manager/locales/jar.mn | 3 +- .../pki/resources/content/device_manager.js | 113 ++++------- .../pki/resources/content/device_manager.xul | 44 ++--- .../pki/resources/content/load_device.js | 20 +- .../pki/resources/content/load_device.xul | 28 ++- 12 files changed, 408 insertions(+), 198 deletions(-) create mode 100644 python/l10n/fluent_migrations/bug_1498451_deviceManager.py delete mode 100644 security/manager/locales/en-US/chrome/pippki/deviceManager.dtd create mode 100644 security/manager/locales/en-US/security/certificates/deviceManager.ftl diff --git a/browser/components/preferences/in-content/preferences.xul b/browser/components/preferences/in-content/preferences.xul index ff2ced7d0984..dd8c8a0258eb 100644 --- a/browser/components/preferences/in-content/preferences.xul +++ b/browser/components/preferences/in-content/preferences.xul @@ -19,11 +19,9 @@ - %brandDTD; %certManagerDTD; -%deviceManangerDTD; %sanitizeDTD; ]> @@ -50,6 +48,7 @@ + + search-l10n-ids=" + devmgr.title, + devmgr-devlist.label, + devmgr-header-details.label, + devmgr-header-value.label, + devmgr-button-login.label, + devmgr-button-logout.label, + devmgr-button-changepw.label, + devmgr-button-load.label, + devmgr-button-unload.label + "/> diff --git a/python/l10n/fluent_migrations/bug_1498451_deviceManager.py b/python/l10n/fluent_migrations/bug_1498451_deviceManager.py new file mode 100644 index 000000000000..6ee3d4f55740 --- /dev/null +++ b/python/l10n/fluent_migrations/bug_1498451_deviceManager.py @@ -0,0 +1,182 @@ +# coding=utf8 + +# Any copyright is dedicated to the Public Domain. +# http://creativecommons.org/publicdomain/zero/1.0/ + +from __future__ import absolute_import +import fluent.syntax.ast as FTL +from fluent.migrate.helpers import transforms_from +from fluent.migrate import COPY +from fluent.migrate import REPLACE +from fluent.migrate import CONCAT +from fluent.migrate.helpers import VARIABLE_REFERENCE + +def migrate(ctx): + """Bug 1498451 - Migrate Device Manager Dialog of Preferences Section to use Fluent for localization, part {index}.""" + + ctx.add_transforms( + "security/manager/security/certificates/deviceManager.ftl", + "security/manager/security/certificates/deviceManager.ftl", + transforms_from( +""" +devmgr = + .title = { COPY("security/manager/chrome/pippki/deviceManager.dtd", "devmgr.title") } + .style = { COPY("security/manager/chrome/pippki/deviceManager.dtd", "devmgr.style2") } + +devmgr-devlist = + .label = { COPY("security/manager/chrome/pippki/deviceManager.dtd", "devmgr.devlist.label") } + +devmgr-header-details = + .label = { COPY("security/manager/chrome/pippki/deviceManager.dtd", "devmgr.details.title") } + +devmgr-header-value = + .label = { COPY("security/manager/chrome/pippki/deviceManager.dtd", "devmgr.details.title2") } + +devmgr-button-login = + .label = { COPY("security/manager/chrome/pippki/deviceManager.dtd", "devmgr.button.login.label") } + .accesskey = { COPY("security/manager/chrome/pippki/deviceManager.dtd", "devmgr.button.login.accesskey") } + +devmgr-button-logout = + .label = { COPY("security/manager/chrome/pippki/deviceManager.dtd", "devmgr.button.logout.label") } + .accesskey = { COPY("security/manager/chrome/pippki/deviceManager.dtd", "devmgr.button.logout.accesskey") } + +devmgr-button-changepw = + .label = { COPY("security/manager/chrome/pippki/deviceManager.dtd", "devmgr.button.changepw.label") } + .accesskey = { COPY("security/manager/chrome/pippki/deviceManager.dtd", "devmgr.button.changepw.accesskey") } + +devmgr-button-load = + .label = { COPY("security/manager/chrome/pippki/deviceManager.dtd", "devmgr.button.load.label") } + .accesskey = { COPY("security/manager/chrome/pippki/deviceManager.dtd", "devmgr.button.load.accesskey") } + +devmgr-button-unload = + .label = { COPY("security/manager/chrome/pippki/deviceManager.dtd", "devmgr.button.unload.label") } + .accesskey = { COPY("security/manager/chrome/pippki/deviceManager.dtd", "devmgr.button.unload.accesskey") } + +load-device = + .title = { COPY("security/manager/chrome/pippki/deviceManager.dtd", "loaddevice.title2") } + +load-device-info = { COPY("security/manager/chrome/pippki/deviceManager.dtd", "loaddevice.info") } + +load-device-modname = + .value = { COPY("security/manager/chrome/pippki/deviceManager.dtd", "loaddevice.modname2") } + .accesskey = { COPY("security/manager/chrome/pippki/deviceManager.dtd", "loaddevice.modname2.accesskey") } + +load-device-modname-default = + .value = { COPY("security/manager/chrome/pippki/deviceManager.dtd", "loaddevice.modname.default") } + +load-device-filename = + .value = { COPY("security/manager/chrome/pippki/deviceManager.dtd", "loaddevice.filename2") } + .accesskey = { COPY("security/manager/chrome/pippki/deviceManager.dtd", "loaddevice.filename2.accesskey") } + +load-device-browse = + .label = { COPY("security/manager/chrome/pippki/deviceManager.dtd", "loaddevice.browse") } + .accesskey = { COPY("security/manager/chrome/pippki/deviceManager.dtd", "loaddevice.browse.accesskey") } + +devinfo-status = + .label = { COPY("security/manager/chrome/pippki/pippki.properties", "devinfo_status") } + +devinfo-status-disabled = + .label = { COPY("security/manager/chrome/pippki/pippki.properties", "devinfo_stat_disabled") } + +devinfo-status-not-present = + .label = { COPY("security/manager/chrome/pippki/pippki.properties", "devinfo_stat_notpresent") } + +devinfo-status-uninitialized = + .label = { COPY("security/manager/chrome/pippki/pippki.properties", "devinfo_stat_uninitialized") } + +devinfo-status-not-logged-in = + .label = { COPY("security/manager/chrome/pippki/pippki.properties", "devinfo_stat_notloggedin") } + +devinfo-status-logged-in + .label = { COPY("security/manager/chrome/pippki/pippki.properties", "devinfo_stat_loggedin") } + +devinfo-status-ready = + .label = { COPY("security/manager/chrome/pippki/pippki.properties", "devinfo_stat_ready") } + +devinfo-desc = + .label = { COPY("security/manager/chrome/pippki/pippki.properties", "devinfo_desc") } + +devinfo-man-id = + .label = { COPY("security/manager/chrome/pippki/pippki.properties", "devinfo_manID") } + +devinfo-hwversion = + .label = { COPY("security/manager/chrome/pippki/pippki.properties", "devinfo_hwversion") } + +devinfo-fwversion = + .label = { COPY("security/manager/chrome/pippki/pippki.properties", "devinfo_fwversion") } + +devinfo-modname = + .label = { COPY("security/manager/chrome/pippki/pippki.properties", "devinfo_modname") } + +devinfo-modpath = + .label = { COPY("security/manager/chrome/pippki/pippki.properties", "devinfo_modpath") } + +login-failed = { COPY("security/manager/chrome/pippki/pippki.properties", "login_failed") } + +devinfo-label = + .label = { COPY("security/manager/chrome/pippki/pippki.properties", "devinfo_label") } + +devinfo-serialnum = + .label = { COPY("security/manager/chrome/pippki/pippki.properties", "devinfo_serialnum") } + +fips-nonempty-password-required = { COPY("security/manager/chrome/pippki/pippki.properties", "fips_nonempty_password_required") } +unable-to-toggle-fips = { COPY("security/manager/chrome/pippki/pippki.properties", "unable_to_toggle_fips") } +load-pk11-module-file-picker-title = { COPY("security/manager/chrome/pippki/pippki.properties", "loadPK11ModuleFilePickerTitle") } + +load-module-help-empty-module-name = + .value = { COPY("security/manager/chrome/pippki/pippki.properties", "loadModuleHelp_emptyModuleName") } + +load-module-help-root-certs-module-name = + .value = { COPY("security/manager/chrome/pippki/pippki.properties", "loadModuleHelp_rootCertsModuleName") } + +add-module-failure = { COPY("security/manager/chrome/pipnss/pipnss.properties", "AddModuleFailure") } +del-module-warning = { COPY("security/manager/chrome/pipnss/pipnss.properties", "DelModuleWarning") } +del-module-error = { COPY("security/manager/chrome/pipnss/pipnss.properties", "DelModuleError") } +""") +) + + ctx.add_transforms( + "security/manager/security/certificates/deviceManager.ftl", + "security/manager/security/certificates/deviceManager.ftl", + [ + FTL.Message( + id=FTL.Identifier("devmgr-button-enable-fips"), + attributes=[ + FTL.Attribute( + id=FTL.Identifier("label"), + value=COPY( + "security/manager/chrome/pippki/pippki.properties", + "enable_fips", + ) + ), + FTL.Attribute( + id=FTL.Identifier("accesskey"), + value=COPY( + "security/manager/chrome/pippki/deviceManager.dtd", + "devmgr.button.fips.accesskey", + ) + ) + ] + ), + FTL.Message( + id=FTL.Identifier("devmgr-button-disable-fips"), + attributes=[ + FTL.Attribute( + id=FTL.Identifier("label"), + value=COPY( + "security/manager/chrome/pippki/pippki.properties", + "disable_fips", + ) + ), + FTL.Attribute( + id=FTL.Identifier("accesskey"), + value=COPY( + "security/manager/chrome/pippki/deviceManager.dtd", + "devmgr.button.fips.accesskey", + ) + ) + ] + ), + ] + ) + diff --git a/security/manager/locales/en-US/chrome/pipnss/pipnss.properties b/security/manager/locales/en-US/chrome/pipnss/pipnss.properties index 277842cf6756..b051688c5e42 100755 --- a/security/manager/locales/en-US/chrome/pipnss/pipnss.properties +++ b/security/manager/locales/en-US/chrome/pipnss/pipnss.properties @@ -260,9 +260,6 @@ PKCS12UnknownErrBackup=Failed to create the PKCS #12 backup file for unknown rea PKCS12UnknownErr=The PKCS #12 operation failed for unknown reasons. PKCS12InfoNoSmartcardBackup=It is not possible to back up certificates from a hardware security device such as a smart card. PKCS12DupData=The certificate and private key already exist on the security device. -AddModuleFailure=Unable to add module -DelModuleWarning=Are you sure you want to delete this security module? -DelModuleError=Unable to delete module AVATemplate=%S = %S PSMERR_SSL_Disabled=Can’t connect securely because the SSL protocol has been disabled. diff --git a/security/manager/locales/en-US/chrome/pippki/deviceManager.dtd b/security/manager/locales/en-US/chrome/pippki/deviceManager.dtd deleted file mode 100644 index 82bf74bac284..000000000000 --- a/security/manager/locales/en-US/chrome/pippki/deviceManager.dtd +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/security/manager/locales/en-US/chrome/pippki/pippki.properties b/security/manager/locales/en-US/chrome/pippki/pippki.properties index ed3b867ed260..abac0e8b5695 100644 --- a/security/manager/locales/en-US/chrome/pippki/pippki.properties +++ b/security/manager/locales/en-US/chrome/pippki/pippki.properties @@ -123,27 +123,8 @@ pw_erased_ok=Warning! You have deleted your Master Password. pw_not_wanted=Warning! You have decided not to use a Master Password. pw_empty_warning=Your stored web and email passwords, form data, and private keys will not be protected. pw_change2empty_in_fips_mode=You are currently in FIPS mode. FIPS requires a non-empty Master Password. -login_failed=Failed to Login -loadPK11ModuleFilePickerTitle=Choose a PKCS#11 device driver to load -devinfo_modname=Module -devinfo_modpath=Path -devinfo_label=Label -devinfo_manID=Manufacturer -devinfo_serialnum=Serial Number -devinfo_hwversion=HW Version -devinfo_fwversion=FW Version -devinfo_status=Status -devinfo_desc=Description -devinfo_stat_disabled=Disabled -devinfo_stat_notpresent=Not Present -devinfo_stat_uninitialized=Uninitialized -devinfo_stat_notloggedin=Not Logged In -devinfo_stat_loggedin=Logged In -devinfo_stat_ready=Ready enable_fips=Enable FIPS disable_fips=Disable FIPS -fips_nonempty_password_required=FIPS mode requires that you have a Master Password set for each security device. Please set the password before trying to enable FIPS mode. -unable_to_toggle_fips=Unable to change the FIPS mode for the security device. It is recommended that you exit and restart this application. resetPasswordConfirmationTitle=Reset Master Password resetPasswordConfirmationMessage=Your password has been reset. @@ -182,8 +163,3 @@ addExceptionCheckingShort=Checking Information addExceptionCheckingLong2=Attempting to identify this site… addExceptionNoCertShort=No Information Available addExceptionNoCertLong2=Unable to obtain identification status for this site. - -# Load Module Dialog -loadModuleHelp_emptyModuleName=The module name cannot be empty. -# LOCALIZATION NOTE(loadModuleHelp_rootCertsModuleName): Do not translate 'Root Certs' -loadModuleHelp_rootCertsModuleName=‘Root Certs‘ is reserved and cannot be used as the module name. diff --git a/security/manager/locales/en-US/security/certificates/deviceManager.ftl b/security/manager/locales/en-US/security/certificates/deviceManager.ftl new file mode 100644 index 000000000000..f82a13f05b24 --- /dev/null +++ b/security/manager/locales/en-US/security/certificates/deviceManager.ftl @@ -0,0 +1,130 @@ +# 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/. + +## Strings used for device manager +devmgr = + .title = Device Manager + .style = width: 67em; height: 32em; + +devmgr-devlist = + .label = Security Modules and Devices + +devmgr-header-details = + .label = Details + +devmgr-header-value = + .label = Value + +devmgr-button-login = + .label = Log In + .accesskey = n + +devmgr-button-logout = + .label = Log Out + .accesskey = O + +devmgr-button-changepw = + .label = Change Password + .accesskey = P + +devmgr-button-load = + .label = Load + .accesskey = L + +devmgr-button-unload = + .label = Unload + .accesskey = U + +devmgr-button-enable-fips = + .label = Enable FIPS + .accesskey = F + +devmgr-button-disable-fips = + .label = Disable FIPS + .accesskey = F + +## Strings used for load device +load-device = + .title = Load PKCS#11 Device Driver + +load-device-info = Enter the information for the module you want to add. + +load-device-modname = + .value = Module Name + .accesskey = M + +load-device-modname-default = + .value = New PKCS#11 Module + +load-device-filename = + .value = Module filename + .accesskey = f + +load-device-browse = + .label = Browse… + .accesskey = B + +## Token Manager + +devinfo-status = + .label = Status + +devinfo-status-disabled = + .label = Disabled + +devinfo-status-not-present = + .label = Not Present + +devinfo-status-uninitialized = + .label = Uninitialized + +devinfo-status-not-logged-in = + .label = Not Logged In + +devinfo-status-logged-in = + .label = Logged In + +devinfo-status-ready = + .label = Ready + +devinfo-desc = + .label = Description + +devinfo-man-id = + .label = Manufacturer + +devinfo-hwversion = + .label = HW Version +devinfo-fwversion = + .label = FW Version + +devinfo-modname = + .label = Module + +devinfo-modpath = + .label = Path + +login-failed = Failed to Login + +devinfo-label = + .label = Label + +devinfo-serialnum = + .label = Serial Number + +fips-nonempty-password-required = FIPS mode requires that you have a Master Password set for each security device. Please set the password before trying to enable FIPS mode. +unable-to-toggle-fips = Unable to change the FIPS mode for the security device. It is recommended that you exit and restart this application. +load-pk11-module-file-picker-title = Choose a PKCS#11 device driver to load + +# Load Module Dialog +load-module-help-empty-module-name = + .value = The module name cannot be empty. + +# Do not translate 'Root Certs' +load-module-help-root-certs-module-name = + .value = ‘Root Certs‘ is reserved and cannot be used as the module name. + +add-module-failure = Unable to add module +del-module-warning = Are you sure you want to delete this security module? +del-module-error = Unable to delete module diff --git a/security/manager/locales/jar.mn b/security/manager/locales/jar.mn index 9b5c2da4461d..e86f5ed6ae8f 100644 --- a/security/manager/locales/jar.mn +++ b/security/manager/locales/jar.mn @@ -3,6 +3,8 @@ # 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/. +[localization] @AB_CD@.jar: + security (%security/**/*.ftl) @AB_CD@.jar: % locale pipnss @AB_CD@ %locale/@AB_CD@/pipnss/ @@ -12,4 +14,3 @@ locale/@AB_CD@/pippki/pippki.dtd (%chrome/pippki/pippki.dtd) locale/@AB_CD@/pippki/pippki.properties (%chrome/pippki/pippki.properties) locale/@AB_CD@/pippki/certManager.dtd (%chrome/pippki/certManager.dtd) - locale/@AB_CD@/pippki/deviceManager.dtd (%chrome/pippki/deviceManager.dtd) diff --git a/security/manager/pki/resources/content/device_manager.js b/security/manager/pki/resources/content/device_manager.js index 6784b6436fb4..83a6e5e9145e 100644 --- a/security/manager/pki/resources/content/device_manager.js +++ b/security/manager/pki/resources/content/device_manager.js @@ -16,26 +16,22 @@ const nsIPK11TokenDB = Ci.nsIPK11TokenDB; const nsIDialogParamBlock = Ci.nsIDialogParamBlock; const nsDialogParamBlock = "@mozilla.org/embedcomp/dialogparam;1"; -var bundle; var secmoddb; var skip_enable_buttons = false; /* Do the initial load of all PKCS# modules and list them. */ function LoadModules() { - bundle = document.getElementById("pippki_bundle"); secmoddb = Cc[nsPKCS11ModuleDB].getService(nsIPKCS11ModuleDB); RefreshDeviceList(); } -function getNSSString(name) { - return document.getElementById("pipnss_bundle").getString(name); -} - -function doPrompt(msg) { +async function doPrompt(l10n_id) { + let [msg] = await document.l10n.formatValues([{id: l10n_id}]); Services.prompt.alert(window, null, msg); } -function doConfirm(msg) { +async function doConfirm(l10n_id) { + let [msg] = await document.l10n.formatValues([{id: l10n_id}]); return Services.prompt.confirm(window, null, msg); } @@ -51,13 +47,11 @@ function RefreshDeviceList() { function SetFIPSButton() { var fipsButton = document.getElementById("fipsbutton"); - var label; if (secmoddb.isFIPSEnabled) { - label = bundle.getString("disable_fips"); + document.l10n.setAttributes(fipsButton, "devmgr-button-disable-fips"); } else { - label = bundle.getString("enable_fips"); + document.l10n.setAttributes(fipsButton, "devmgr-button-enable-fips"); } - fipsButton.setAttribute("label", label); var can_toggle = secmoddb.canToggleFIPS; if (can_toggle) { @@ -199,48 +193,32 @@ function showSlotInfo() { ClearInfoList(); switch (selected_slot.status) { case nsIPKCS11Slot.SLOT_DISABLED: - AddInfoRow(bundle.getString("devinfo_status"), - bundle.getString("devinfo_stat_disabled"), - "tok_status"); + AddInfoRow("devinfo-status", {l10nID: "devinfo-status-disabled"}, "tok_status"); present = false; break; case nsIPKCS11Slot.SLOT_NOT_PRESENT: - AddInfoRow(bundle.getString("devinfo_status"), - bundle.getString("devinfo_stat_notpresent"), - "tok_status"); + AddInfoRow("devinfo-status", {l10nID: "devinfo-status-not-present"}, "tok_status"); present = false; break; case nsIPKCS11Slot.SLOT_UNINITIALIZED: - AddInfoRow(bundle.getString("devinfo_status"), - bundle.getString("devinfo_stat_uninitialized"), - "tok_status"); + AddInfoRow("devinfo-status", {l10nID: "devinfo-status-uninitialized"}, "tok_status"); break; case nsIPKCS11Slot.SLOT_NOT_LOGGED_IN: - AddInfoRow(bundle.getString("devinfo_status"), - bundle.getString("devinfo_stat_notloggedin"), - "tok_status"); + AddInfoRow("devinfo-status", {l10nID: "devinfo-status-not-logged-in"}, "tok_status"); break; case nsIPKCS11Slot.SLOT_LOGGED_IN: - AddInfoRow(bundle.getString("devinfo_status"), - bundle.getString("devinfo_stat_loggedin"), - "tok_status"); + AddInfoRow("devinfo-status", {l10nID: "devinfo-status-logged-in"}, "tok_status"); break; case nsIPKCS11Slot.SLOT_READY: - AddInfoRow(bundle.getString("devinfo_status"), - bundle.getString("devinfo_stat_ready"), - "tok_status"); + AddInfoRow("devinfo-status", {l10nID: "devinfo-status-ready"}, "tok_status"); break; default: return; } - AddInfoRow(bundle.getString("devinfo_desc"), - selected_slot.desc, "slot_desc"); - AddInfoRow(bundle.getString("devinfo_manID"), - selected_slot.manID, "slot_manID"); - AddInfoRow(bundle.getString("devinfo_hwversion"), - selected_slot.HWVersion, "slot_hwv"); - AddInfoRow(bundle.getString("devinfo_fwversion"), - selected_slot.FWVersion, "slot_fwv"); + AddInfoRow("devinfo-desc", {label: selected_slot.desc}, "slot_desc"); + AddInfoRow("devinfo-man-id", {label: selected_slot.manID}, "slot_manID"); + AddInfoRow("devinfo-hwversion", {label: selected_slot.HWVersion}, "slot_hwv"); + AddInfoRow("devinfo-fwversion", {label: selected_slot.FWVersion}, "slot_fwv"); if (present) { showTokenInfo(); } @@ -248,23 +226,25 @@ function showSlotInfo() { function showModuleInfo() { ClearInfoList(); - AddInfoRow(bundle.getString("devinfo_modname"), - selected_module.name, "module_name"); - AddInfoRow(bundle.getString("devinfo_modpath"), - selected_module.libName, "module_path"); + AddInfoRow("devinfo-modname", {label: selected_module.name}, "module_name"); + AddInfoRow("devinfo-modpath", {label: selected_module.libName}, "module_path"); } // add a row to the info list, as [col1 col2] (ex.: ["status" "logged in"]) -function AddInfoRow(col1, col2, cell_id) { +function AddInfoRow(l10nID, col2, cell_id) { var tree = document.getElementById("info_list"); var item = document.createXULElement("treeitem"); var row = document.createXULElement("treerow"); var cell1 = document.createXULElement("treecell"); - cell1.setAttribute("label", col1); + document.l10n.setAttributes(cell1, l10nID); cell1.setAttribute("crop", "never"); row.appendChild(cell1); var cell2 = document.createXULElement("treecell"); - cell2.setAttribute("label", col2); + if (col2.l10nID) { + document.l10n.setAttributes(cell2, col2.l10nID); + } else { + cell2.setAttribute("label", col2.label); + } cell2.setAttribute("crop", "never"); cell2.setAttribute("id", cell_id); row.appendChild(cell2); @@ -281,14 +261,12 @@ function doLogin() { selected_token.login(false); var tok_status = document.getElementById("tok_status"); if (selected_token.isLoggedIn()) { - tok_status.setAttribute("label", - bundle.getString("devinfo_stat_loggedin")); + document.l10n.setAttributes(tok_status, "devinfo-status-logged-in"); } else { - tok_status.setAttribute("label", - bundle.getString("devinfo_stat_notloggedin")); + document.l10n.setAttributes(tok_status, "devinfo-status-not-logged-in"); } } catch (e) { - doPrompt(bundle.getString("login_failed")); + doPrompt("login-failed"); } enableButtons(); } @@ -302,11 +280,9 @@ function doLogout() { selected_token.logoutAndDropAuthenticatedResources(); var tok_status = document.getElementById("tok_status"); if (selected_token.isLoggedIn()) { - tok_status.setAttribute("label", - bundle.getString("devinfo_stat_loggedin")); + document.l10n.setAttributes(tok_status, "devinfo-status-logged-in"); } else { - tok_status.setAttribute("label", - bundle.getString("devinfo_stat_notloggedin")); + document.l10n.setAttributes(tok_status, "devinfo-status-not-logged-in"); } } catch (e) { } @@ -320,14 +296,14 @@ function doLoad() { RefreshDeviceList(); } -function deleteSelected() { +async function deleteSelected() { getSelectedItem(); if (selected_module && - doConfirm(getNSSString("DelModuleWarning"))) { + (await doConfirm("del-module-warning"))) { try { secmoddb.deleteModule(selected_module.name); } catch (e) { - doPrompt(getNSSString("DelModuleError")); + doPrompt("del-module-error"); return false; } selected_module = null; @@ -336,8 +312,8 @@ function deleteSelected() { return false; } -function doUnload() { - if (deleteSelected()) { +async function doUnload() { + if (await deleteSelected()) { ClearDeviceList(); RefreshDeviceList(); } @@ -360,16 +336,11 @@ function changePassword() { function showTokenInfo() { var selected_token = selected_slot.getToken(); - AddInfoRow(bundle.getString("devinfo_label"), - selected_token.tokenName, "tok_label"); - AddInfoRow(bundle.getString("devinfo_manID"), - selected_token.tokenManID, "tok_manID"); - AddInfoRow(bundle.getString("devinfo_serialnum"), - selected_token.tokenSerialNumber, "tok_sNum"); - AddInfoRow(bundle.getString("devinfo_hwversion"), - selected_token.tokenHWVersion, "tok_hwv"); - AddInfoRow(bundle.getString("devinfo_fwversion"), - selected_token.tokenFWVersion, "tok_fwv"); + AddInfoRow("devinfo-label", {label: selected_token.tokenName}, "tok_label"); + AddInfoRow("devinfo-man-id", {label: selected_token.tokenManID}, "tok_manID"); + AddInfoRow("devinfo-serialnum", {label: selected_token.tokenSerialNumber}, "tok_sNum"); + AddInfoRow("devinfo-hwversion", {label: selected_token.tokenHWVersion}, "tok_hwv"); + AddInfoRow("devinfo-fwversion", {label: selected_token.tokenFWVersion}, "tok_fwv"); } function toggleFIPS() { @@ -382,7 +353,7 @@ function toggleFIPS() { var internal_token = tokendb.getInternalKeyToken(); // nsIPK11Token if (!internal_token.hasPassword) { // Token has either no or an empty password. - doPrompt(bundle.getString("fips_nonempty_password_required")); + doPrompt("fips-nonempty-password-required"); return; } } @@ -390,7 +361,7 @@ function toggleFIPS() { try { secmoddb.toggleFIPSMode(); } catch (e) { - doPrompt(bundle.getString("unable_to_toggle_fips")); + doPrompt("unable-to-toggle-fips"); return; } diff --git a/security/manager/pki/resources/content/device_manager.xul b/security/manager/pki/resources/content/device_manager.xul index 2e59b08db99a..f0f97ecaf289 100644 --- a/security/manager/pki/resources/content/device_manager.xul +++ b/security/manager/pki/resources/content/device_manager.xul @@ -5,26 +5,20 @@ - -%deviceManangerDTD; - -%pippkiDTD; -]> + - - - - + + + diff --git a/layout/reftests/transform-3d/animate-preserve3d-child.html b/layout/reftests/transform-3d/animate-preserve3d-child.html index bf2aea4585b4..fcf77f9756a3 100644 --- a/layout/reftests/transform-3d/animate-preserve3d-child.html +++ b/layout/reftests/transform-3d/animate-preserve3d-child.html @@ -1,5 +1,5 @@ - + Testcase, bug 1176969 @@ -43,8 +40,6 @@ body { padding: 50px } diff --git a/layout/reftests/transform-3d/animate-preserve3d-parent.html b/layout/reftests/transform-3d/animate-preserve3d-parent.html index 9aa8816d3f89..0131d33e6f15 100644 --- a/layout/reftests/transform-3d/animate-preserve3d-parent.html +++ b/layout/reftests/transform-3d/animate-preserve3d-parent.html @@ -1,5 +1,5 @@ - + Testcase, bug 1176969 + + \ No newline at end of file diff --git a/gfx/tests/crashtests/crashtests.list b/gfx/tests/crashtests/crashtests.list index 1f9345b96fc5..09cea82c65b5 100644 --- a/gfx/tests/crashtests/crashtests.list +++ b/gfx/tests/crashtests/crashtests.list @@ -167,6 +167,7 @@ load 1408078-1.html load 1464243.html load 1467847-1.html load 1468020.html +load 1470437.html load 1470440.html load 1478035.html load 1490704-1.html diff --git a/layout/generic/TextDrawTarget.h b/layout/generic/TextDrawTarget.h index 1f20f0f4eba6..ec6730335098 100644 --- a/layout/generic/TextDrawTarget.h +++ b/layout/generic/TextDrawTarget.h @@ -569,6 +569,12 @@ public: return nullptr; } + bool + CanCreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const override { + MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); + return false; + } + already_AddRefed CreatePathBuilder(FillRule aFillRule) const override { MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); return nullptr; From 76cb4247d3c393d6efe9c57fbd4c993b94baa2f4 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Tue, 13 Nov 2018 10:39:27 +0000 Subject: [PATCH 25/33] Bug 1466613 - Prevent creation of DynamicImage instances that are excessively large. r=mstange Differential Revision: https://phabricator.services.mozilla.com/D11528 --HG-- extra : moz-landing-system : lando --- layout/painting/nsImageRenderer.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/layout/painting/nsImageRenderer.cpp b/layout/painting/nsImageRenderer.cpp index 785767ab55de..eec6c3a77481 100644 --- a/layout/painting/nsImageRenderer.cpp +++ b/layout/painting/nsImageRenderer.cpp @@ -732,8 +732,13 @@ nsImageRenderer::DrawableForElement(const nsRect& aImageRect, nsRect destRect = aImageRect - aImageRect.TopLeft(); nsIntSize roundedOut = destRect.ToOutsidePixels(appUnitsPerDevPixel).Size(); IntSize imageSize(roundedOut.width, roundedOut.height); - RefPtr drawable = - nsSVGIntegrationUtils::DrawableFromPaintServer( + + RefPtr drawable; + + SurfaceFormat format = aContext.GetDrawTarget()->GetFormat(); + // Don't allow creating images that are too big + if (aContext.GetDrawTarget()->CanCreateSimilarDrawTarget(imageSize, format)) { + drawable = nsSVGIntegrationUtils::DrawableFromPaintServer( mPaintServerFrame, mForFrame, mSize, @@ -741,6 +746,7 @@ nsImageRenderer::DrawableForElement(const nsRect& aImageRect, aContext.GetDrawTarget(), aContext.CurrentMatrixDouble(), nsSVGIntegrationUtils::FLAG_SYNC_DECODE_IMAGES); + } return drawable.forget(); } From 8e1f58b955c06aecaf2dd6c8f040903423ea4aa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 13 Nov 2018 10:55:59 +0000 Subject: [PATCH 26/33] Bug 1506592 - Make sure to only display the broken image icon if there's a request at all. r=bzbarsky This is enough to fix the devtools regression and matches what other browsers do in the no-attribute case. Also, I think this change over all makes sense: it doesn't make any sense to display the broken image icon if there's no request, and we already assume in EnsureIntrinsicSizeAndRatio() that we don't paint the icon for those (and make the intrinsic size 0x0). We still show the border, which matches other UAs (note that devtools effectively masks the border away with mask-image). This technically also can change behavior of and , but I think it's better to be consistent, since EnsureIntrinsicSizeAndRatio also doesn't special-case either. Differential Revision: https://phabricator.services.mozilla.com/D11659 --HG-- extra : moz-landing-system : lando --- dom/base/nsIImageLoadingContent.idl | 2 +- layout/generic/nsImageFrame.cpp | 57 +++++++++---------- layout/generic/nsImageFrame.h | 1 + .../reftests/image-element/broken-icon.html | 9 +++ layout/reftests/image-element/empty-src.html | 9 +++ .../reftests/image-element/invalid-src-2.html | 9 +++ .../reftests/image-element/invalid-src.html | 9 +++ layout/reftests/image-element/no-src.html | 9 +++ layout/reftests/image-element/reftest.list | 5 ++ 9 files changed, 78 insertions(+), 32 deletions(-) create mode 100644 layout/reftests/image-element/broken-icon.html create mode 100644 layout/reftests/image-element/empty-src.html create mode 100644 layout/reftests/image-element/invalid-src-2.html create mode 100644 layout/reftests/image-element/invalid-src.html create mode 100644 layout/reftests/image-element/no-src.html diff --git a/dom/base/nsIImageLoadingContent.idl b/dom/base/nsIImageLoadingContent.idl index 6e6fb3cf6cdf..8b7d326eab46 100644 --- a/dom/base/nsIImageLoadingContent.idl +++ b/dom/base/nsIImageLoadingContent.idl @@ -71,7 +71,7 @@ interface nsIImageLoadingContent : imgINotificationObserver * the image was blocked. This status always refers to the * CURRENT_REQUEST load. */ - [noscript] readonly attribute short imageBlockingStatus; + [noscript, infallible] readonly attribute short imageBlockingStatus; /** * Used to register an image decoder observer. Typically, this will diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index 85ed4083ba21..db3b8edef982 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -151,6 +151,29 @@ NS_NewImageFrameForGeneratedContentIndex(nsIPresShell* aPresShell, aStyle, nsImageFrame::Kind::ContentPropertyAtIndex); } +bool +nsImageFrame::ShouldShowBrokenImageIcon() const +{ + // NOTE(emilio, https://github.com/w3c/csswg-drafts/issues/2832): WebKit and + // Blink behave differently here for content: url(..), for now adapt to + // Blink's behavior. + if (mKind != Kind::ImageElement) { + return false; + } + + // check for broken images. valid null images (eg. img src="") are + // not considered broken because they have no image requests + if (nsCOMPtr currentRequest = GetCurrentRequest()) { + uint32_t imageStatus; + return NS_SUCCEEDED(currentRequest->GetImageStatus(&imageStatus)) && + (imageStatus & imgIRequest::STATUS_ERROR); + } + + nsCOMPtr loader = do_QueryInterface(mContent); + MOZ_ASSERT(loader); + return loader->GetImageBlockingStatus() != nsIContentPolicy::ACCEPT; +} + nsImageFrame* nsImageFrame::CreateContinuingFrame(nsIPresShell* aPresShell, ComputedStyle* aStyle) const @@ -936,37 +959,8 @@ nsImageFrame::EnsureIntrinsicSizeAndRatio() return; } - // NOTE(emilio, https://github.com/w3c/csswg-drafts/issues/2832): WebKit - // and Blink behave differently here for content: url(..), for now adapt to - // Blink's behavior. - const bool mayDisplayBrokenIcon = mKind == Kind::ImageElement; - if (!mayDisplayBrokenIcon) { - return; - } - // image request is null or image size not known, probably an - // invalid image specified - bool imageInvalid = false; - - // check for broken images. valid null images (eg. img src="") are - // not considered broken because they have no image requests - if (nsCOMPtr currentRequest = GetCurrentRequest()) { - uint32_t imageStatus; - imageInvalid = - NS_SUCCEEDED(currentRequest->GetImageStatus(&imageStatus)) && - (imageStatus & imgIRequest::STATUS_ERROR); - } else { - MOZ_ASSERT(mKind == Kind::ImageElement); - - nsCOMPtr loader = do_QueryInterface(mContent); - MOZ_ASSERT(loader); - // check if images are user-disabled (or blocked for other reasons) - int16_t imageBlockingStatus; - loader->GetImageBlockingStatus(&imageBlockingStatus); - imageInvalid = imageBlockingStatus != nsIContentPolicy::ACCEPT; - } - // invalid image specified. make the image big enough for the "broken" icon - if (imageInvalid) { + if (ShouldShowBrokenImageIcon()) { nscoord edgeLengthToUse = nsPresContext::CSSPixelsToAppUnits( ICON_SIZE + (2 * (ICON_PADDING + ALT_BORDER_WIDTH))); @@ -1494,7 +1488,8 @@ nsImageFrame::DisplayAltFeedback(gfxContext& aRenderingContext, ImgDrawResult result = ImgDrawResult::NOT_READY; // Check if we should display image placeholders - if (!gIconLoad->mPrefShowPlaceholders || + if (!ShouldShowBrokenImageIcon() || + !gIconLoad->mPrefShowPlaceholders || (isLoading && !gIconLoad->mPrefShowLoadingPlaceholder)) { result = ImgDrawResult::SUCCESS; } else { diff --git a/layout/generic/nsImageFrame.h b/layout/generic/nsImageFrame.h index a9887c21c74a..b65fbb6aef03 100644 --- a/layout/generic/nsImageFrame.h +++ b/layout/generic/nsImageFrame.h @@ -107,6 +107,7 @@ public: void ResponsiveContentDensityChanged(); void SetupForContentURLRequest(); + bool ShouldShowBrokenImageIcon() const; #ifdef ACCESSIBILITY virtual mozilla::a11y::AccType AccessibleType() override; diff --git a/layout/reftests/image-element/broken-icon.html b/layout/reftests/image-element/broken-icon.html new file mode 100644 index 000000000000..f2f6b7c451c6 --- /dev/null +++ b/layout/reftests/image-element/broken-icon.html @@ -0,0 +1,9 @@ + + + diff --git a/layout/reftests/image-element/empty-src.html b/layout/reftests/image-element/empty-src.html new file mode 100644 index 000000000000..36091cdc1909 --- /dev/null +++ b/layout/reftests/image-element/empty-src.html @@ -0,0 +1,9 @@ + + + diff --git a/layout/reftests/image-element/invalid-src-2.html b/layout/reftests/image-element/invalid-src-2.html new file mode 100644 index 000000000000..c385acca6dd0 --- /dev/null +++ b/layout/reftests/image-element/invalid-src-2.html @@ -0,0 +1,9 @@ + + + diff --git a/layout/reftests/image-element/invalid-src.html b/layout/reftests/image-element/invalid-src.html new file mode 100644 index 000000000000..26821d39b2ae --- /dev/null +++ b/layout/reftests/image-element/invalid-src.html @@ -0,0 +1,9 @@ + + + diff --git a/layout/reftests/image-element/no-src.html b/layout/reftests/image-element/no-src.html new file mode 100644 index 000000000000..6cc51078c020 --- /dev/null +++ b/layout/reftests/image-element/no-src.html @@ -0,0 +1,9 @@ + + + diff --git a/layout/reftests/image-element/reftest.list b/layout/reftests/image-element/reftest.list index 2d6923cb6e25..eff23b9b4290 100644 --- a/layout/reftests/image-element/reftest.list +++ b/layout/reftests/image-element/reftest.list @@ -45,5 +45,10 @@ HTTP == invalidate-1.html invalidate-1-ref.html == pattern-html-01.html pattern-html-01-ref.svg == pattern-html-02.html pattern-html-02-ref.svg == referenced-from-binding-01.html referenced-from-binding-01-ref.html +!= broken-icon.html no-src.html +!= broken-icon.html empty-src.html +== empty-src.html no-src.html +== broken-icon.html invalid-src.html +fails == invalid-src.html invalid-src-2.html # bug 1506804 fuzzy-if(skiaContent,0-1,0-30000) == mask-image-element.html mask-image-element-ref.html From 6f80f44f249dc670f4e06a2fe0bf0b4080e6595a Mon Sep 17 00:00:00 2001 From: Henrik Skupin Date: Tue, 13 Nov 2018 10:23:58 +0000 Subject: [PATCH 27/33] Bug 1495667 - Re-enable js/xpconnect/tests/marionette/test_loader_global_sharing.py on Windows. r=jgraham Previously disabled via bug 1433905 to allow a refactoring of Marionette, this test can be re-enabled now given that bug 1433873 also got landed. Differential Revision: https://phabricator.services.mozilla.com/D11744 --HG-- extra : moz-landing-system : lando --- js/xpconnect/tests/marionette/manifest.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/xpconnect/tests/marionette/manifest.ini b/js/xpconnect/tests/marionette/manifest.ini index 6611a3c205c7..3f76a6c653f6 100644 --- a/js/xpconnect/tests/marionette/manifest.ini +++ b/js/xpconnect/tests/marionette/manifest.ini @@ -1,3 +1,3 @@ [test_loader_global_sharing.py] -skip-if = !manage_instance || appname == 'fennec' || (os == "win" && !(debug || asan)) # Bug 1495667 +skip-if = !manage_instance || appname == 'fennec' From ca4ca8e8042a6592f229551a72aa3cc4510878e5 Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Tue, 13 Nov 2018 10:39:00 +0000 Subject: [PATCH 28/33] Bug 1506774 - Discard TypeScripts whenever we discard JIT code. r=jonco Bug 1506479 started unifying discarding of TypeScript and JIT code. This patch removes the JIT_SCRIPT_RELEASE_TYPES_PERIOD heuristic so we now use the same preserve-code heuristics for both. Differential Revision: https://phabricator.services.mozilla.com/D11737 --HG-- extra : moz-landing-system : lando --- js/src/gc/GC.cpp | 44 +++++-------------------------------------- js/src/gc/GCRuntime.h | 4 ---- 2 files changed, 5 insertions(+), 43 deletions(-) diff --git a/js/src/gc/GC.cpp b/js/src/gc/GC.cpp index b0b43d999eba..6c3e7510bea0 100644 --- a/js/src/gc/GC.cpp +++ b/js/src/gc/GC.cpp @@ -993,7 +993,6 @@ GCRuntime::GCRuntime(JSRuntime* rt) : fullGCForAtomsRequested_(false), minorGCNumber(0), majorGCNumber(0), - jitReleaseNumber(0), number(0), isFull(false), incrementalState(gc::State::NotActive), @@ -1341,12 +1340,6 @@ js::gc::DumpArenaInfo() #endif // JS_GC_ZEAL -/* - * Lifetime in number of major GCs for type sets attached to scripts containing - * observed types. - */ -static const unsigned JIT_SCRIPT_RELEASE_TYPES_PERIOD = 20; - bool GCRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes) { @@ -1364,8 +1357,6 @@ GCRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes) setMarkStackLimit(atoi(size), lock); } - jitReleaseNumber = majorGCNumber + JIT_SCRIPT_RELEASE_TYPES_PERIOD; - if (!nursery().init(maxNurseryBytes, lock)) { return false; } @@ -3961,33 +3952,6 @@ GCRuntime::waitBackgroundSweepEnd() } } -bool -GCRuntime::shouldReleaseObservedTypes() -{ - bool releaseTypes = false; - - if (cleanUpEverything) { - releaseTypes = true; - } - -#ifdef JS_GC_ZEAL - if (zealModeBits != 0) { - releaseTypes = true; - } -#endif - - /* We may miss the exact target GC due to resets. */ - if (majorGCNumber >= jitReleaseNumber) { - releaseTypes = true; - } - - if (releaseTypes) { - jitReleaseNumber = majorGCNumber + JIT_SCRIPT_RELEASE_TYPES_PERIOD; - } - - return releaseTypes; -} - struct IsAboutToBeFinalizedFunctor { template bool operator()(Cell** t) { mozilla::DebugOnly prior = *t; @@ -4559,12 +4523,14 @@ GCRuntime::prepareZonesForCollection(JS::gcreason::Reason reason, bool* isFullOu } static void -DiscardJITCodeForGC(JSRuntime* rt, bool releaseTypes) +DiscardJITCodeForGC(JSRuntime* rt) { js::CancelOffThreadIonCompile(rt, JS::Zone::Mark); for (GCZonesIter zone(rt); !zone.done(); zone.next()) { gcstats::AutoPhase ap(rt->gc.stats(), gcstats::PhaseKind::MARK_DISCARD_CODE); - zone->discardJitCode(rt->defaultFreeOp(), /* discardBaselineCode = */ true, releaseTypes); + zone->discardJitCode(rt->defaultFreeOp(), + /* discardBaselineCode = */ true, + /* releaseTypes = */ true); } } @@ -4671,7 +4637,7 @@ GCRuntime::beginMarkPhase(JS::gcreason::Reason reason, AutoGCSession& session) // Discard JIT code. For incremental collections, the sweep phase will // also discard JIT code. - DiscardJITCodeForGC(rt, shouldReleaseObservedTypes()); + DiscardJITCodeForGC(rt); /* * Relazify functions after discarding JIT code (we can't relazify diff --git a/js/src/gc/GCRuntime.h b/js/src/gc/GCRuntime.h index f855278393dd..2104bed0730d 100644 --- a/js/src/gc/GCRuntime.h +++ b/js/src/gc/GCRuntime.h @@ -632,7 +632,6 @@ class GCRuntime IncrementalProgress endMarkingSweepGroup(FreeOp* fop, SliceBudget& budget); void markIncomingCrossCompartmentPointers(MarkColor color); IncrementalProgress beginSweepingSweepGroup(FreeOp* fop, SliceBudget& budget); - bool shouldReleaseObservedTypes(); void sweepDebuggerOnMainThread(FreeOp* fop); void sweepJitDataOnMainThread(FreeOp* fop); IncrementalProgress endSweepingSweepGroup(FreeOp* fop, SliceBudget& budget); @@ -816,9 +815,6 @@ class GCRuntime /* Incremented at the start of every major GC. */ MainThreadData majorGCNumber; - /* The major GC number at which to release observed type information. */ - MainThreadData jitReleaseNumber; - /* Incremented on every GC slice. */ MainThreadData number; From 5207710f6bb761c1f40445310734e98d5e8d0990 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 13 Nov 2018 11:00:46 +0000 Subject: [PATCH 29/33] Bug 1506580 - Remove useless pointer-chase + function call in nsPresContext::AppUnitsPerDevPixel. r=miko We already keep a cached version of the up-to-date value in nsPresContext, there's no need to go through nsDeviceContext at all. I don't expect this to fix bug 1424968 entirely, but it should make it a bit better. Differential Revision: https://phabricator.services.mozilla.com/D11639 --HG-- extra : moz-landing-system : lando --- layout/base/nsPresContext.cpp | 27 +++++++++++---------------- layout/base/nsPresContext.h | 5 ++++- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp index 25e709a6877f..af6d0b4bdf71 100644 --- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -638,7 +638,7 @@ nsPresContext::AppUnitsPerDevPixelChanged() MediaFeatureChangeReason::ResolutionChange }); - mCurAppUnitsPerDevPixel = AppUnitsPerDevPixel(); + mCurAppUnitsPerDevPixel = mDeviceContext->AppUnitsPerDevPixel(); } void @@ -648,7 +648,7 @@ nsPresContext::PreferenceChanged(const char* aPrefName) if (prefName.EqualsLiteral("layout.css.dpi") || prefName.EqualsLiteral("layout.css.devPixelsPerPx")) { - int32_t oldAppUnitsPerDevPixel = AppUnitsPerDevPixel(); + int32_t oldAppUnitsPerDevPixel = mDeviceContext->AppUnitsPerDevPixel(); if (mDeviceContext->CheckDPIChange() && mShell) { nsCOMPtr shell = mShell; // Re-fetch the view manager's window dimensions in case there's a deferred @@ -662,11 +662,11 @@ nsPresContext::PreferenceChanged(const char* aPrefName) float oldWidthDevPixels = oldWidthAppUnits/oldAppUnitsPerDevPixel; float oldHeightDevPixels = oldHeightAppUnits/oldAppUnitsPerDevPixel; - nscoord width = NSToCoordRound(oldWidthDevPixels*AppUnitsPerDevPixel()); - nscoord height = NSToCoordRound(oldHeightDevPixels*AppUnitsPerDevPixel()); - vm->SetWindowDimensions(width, height); - AppUnitsPerDevPixelChanged(); + + nscoord width = NSToCoordRound(oldWidthDevPixels * AppUnitsPerDevPixel()); + nscoord height = NSToCoordRound(oldHeightDevPixels * AppUnitsPerDevPixel()); + vm->SetWindowDimensions(width, height); } return; } @@ -803,7 +803,7 @@ nsPresContext::Init(nsDeviceContext* aDeviceContext) if (mDeviceContext->SetFullZoom(mFullZoom)) mDeviceContext->FlushFontCache(); - mCurAppUnitsPerDevPixel = AppUnitsPerDevPixel(); + mCurAppUnitsPerDevPixel = mDeviceContext->AppUnitsPerDevPixel(); mEventManager = new mozilla::EventStateManager(); @@ -1280,12 +1280,13 @@ nsPresContext::SetFullZoom(float aZoom) mSuppressResizeReflow = true; mFullZoom = aZoom; + + AppUnitsPerDevPixelChanged(); + mShell->GetViewManager()-> SetWindowDimensions(NSToCoordRound(oldWidthDevPixels * AppUnitsPerDevPixel()), NSToCoordRound(oldHeightDevPixels * AppUnitsPerDevPixel())); - AppUnitsPerDevPixelChanged(); - mSuppressResizeReflow = false; } @@ -1831,7 +1832,7 @@ nsPresContext::UIResolutionChangedInternalScale(double aScale) mPendingUIResolutionChanged = false; mDeviceContext->CheckDPIChange(&aScale); - if (mCurAppUnitsPerDevPixel != AppUnitsPerDevPixel()) { + if (mCurAppUnitsPerDevPixel != mDeviceContext->AppUnitsPerDevPixel()) { AppUnitsPerDevPixelChanged(); } @@ -2916,12 +2917,6 @@ bool nsPresContext::GetPaintFlashing() const return mPaintFlashing; } -int32_t -nsPresContext::AppUnitsPerDevPixel() const -{ - return mDeviceContext->AppUnitsPerDevPixel(); -} - nscoord nsPresContext::GfxUnitsToAppUnits(gfxFloat aGfxUnits) const { diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h index 1841492b659f..c9a181b6749b 100644 --- a/layout/base/nsPresContext.h +++ b/layout/base/nsPresContext.h @@ -658,7 +658,10 @@ public: */ gfxSize ScreenSizeInchesForFontInflation(bool* aChanged = nullptr); - int32_t AppUnitsPerDevPixel() const; + int32_t AppUnitsPerDevPixel() const + { + return mCurAppUnitsPerDevPixel; + } static nscoord CSSPixelsToAppUnits(int32_t aPixels) { return NSToCoordRoundWithClamp(float(aPixels) * From 2c0c506ad0bd00abe2487d5c1cef62feae9d61bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A3o=20Gottwald?= Date: Mon, 12 Nov 2018 12:14:30 +0000 Subject: [PATCH 30/33] Bug 1504205 - Enable Ctrl+Shift+D shortcut on Linux. r=stransky Differential Revision: https://phabricator.services.mozilla.com/D11549 --HG-- extra : moz-landing-system : lando --- browser/base/content/browser-sets.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/base/content/browser-sets.inc b/browser/base/content/browser-sets.inc index 4f7539458461..486ca34346d5 100644 --- a/browser/base/content/browser-sets.inc +++ b/browser/base/content/browser-sets.inc @@ -231,9 +231,9 @@ + # Accel+Shift+A-F are reserved on GTK #ifndef MOZ_WIDGET_GTK - #else From f6061f385fd9d0284ee16c79ca5782fddd5e1b3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A3o=20Gottwald?= Date: Tue, 13 Nov 2018 11:53:32 +0000 Subject: [PATCH 31/33] Bug 1506341 - Let the autohiding menu bar match the tab bar's height. r=stransky Differential Revision: https://phabricator.services.mozilla.com/D11550 --HG-- extra : moz-landing-system : lando --- browser/themes/linux/browser.css | 9 +++++++++ browser/themes/shared/tabs.inc.css | 9 +++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/browser/themes/linux/browser.css b/browser/themes/linux/browser.css index 7424fcfa16b3..81d7b19551fa 100644 --- a/browser/themes/linux/browser.css +++ b/browser/themes/linux/browser.css @@ -646,6 +646,15 @@ notification[value="translation"] menulist > .menulist-dropmarker { visibility: visible; } + /* When temporarily showing the menu bar, make it at least as tall as the tab + * bar such that the window controls don't appear to move up. */ + :root[tabsintitlebar] #toolbar-menubar[autohide="true"] { + height: var(--tab-min-height); + } + :root[tabsintitlebar][sizemode="normal"] #toolbar-menubar[autohide="true"] { + height: calc(var(--tab-min-height) + var(--space-above-tabbar)); + } + /* Add extra space to titlebar for dragging */ :root[sizemode="normal"][chromehidden~="menubar"] #TabsToolbar, :root[sizemode="normal"] #toolbar-menubar[autohide="true"][inactive] + #TabsToolbar { diff --git a/browser/themes/shared/tabs.inc.css b/browser/themes/shared/tabs.inc.css index 52b8167e0d00..0197e6714184 100644 --- a/browser/themes/shared/tabs.inc.css +++ b/browser/themes/shared/tabs.inc.css @@ -6,18 +6,15 @@ %filter substitution %define horizontalTabPadding 9px -#titlebar, -#tabbrowser-tabs { +:root { --tab-min-height: 33px; } -:root[uidensity=compact] #titlebar, -:root[uidensity=compact] #tabbrowser-tabs { +:root[uidensity=compact] { --tab-min-height: 29px; } -:root[uidensity=touch] #titlebar, -:root[uidensity=touch] #tabbrowser-tabs { +:root[uidensity=touch] { --tab-min-height: 41px; } From 601e1dfa28f121bd0dbc4df570da92e9666b754b Mon Sep 17 00:00:00 2001 From: reimu Date: Tue, 13 Nov 2018 12:01:38 +0000 Subject: [PATCH 32/33] Bug 1504522 - Remove gBrowser.serializationHelper getter because it's unused r=dao Differential Revision: https://phabricator.services.mozilla.com/D11660 --HG-- extra : moz-landing-system : lando --- browser/base/content/tabbrowser.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/browser/base/content/tabbrowser.js b/browser/base/content/tabbrowser.js index 1a45c850f050..e075d3c4564f 100644 --- a/browser/base/content/tabbrowser.js +++ b/browser/base/content/tabbrowser.js @@ -23,10 +23,6 @@ window._gBrowser = { ChromeUtils.defineModuleGetter(this, "UrlbarProviderOpenTabs", "resource:///modules/UrlbarProviderOpenTabs.jsm"); - XPCOMUtils.defineLazyServiceGetters(this, { - serializationHelper: ["@mozilla.org/network/serialization-helper;1", "nsISerializationHelper"], - }); - Services.obs.addObserver(this, "contextual-identity-updated"); Services.els.addSystemEventListener(document, "keydown", this, false); From 6ca25ecbe69edd09cd011594383149c45f473de7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 13 Nov 2018 12:47:40 +0000 Subject: [PATCH 33/33] Bug 1499170 - Add an atom bit to know whether we're ascii lowercase. r=njn And thus massively speed up ascii-case-insensitive atom comparisons when both atoms are lowercase (which is the common case by far). This removes almost all the slow selector-matching in this page, and it seems an easier fix than storing the lowercased version of all class-names in quirks mode in elements and selectors... Differential Revision: https://phabricator.services.mozilla.com/D10945 --HG-- extra : moz-landing-system : lando --- dom/base/nsAttrValue.cpp | 14 +-- dom/base/nsContentUtils.h | 19 ++++ servo/components/style/gecko/regen_atoms.py | 4 +- .../style/gecko_string_cache/mod.rs | 78 +++++++++------- xpcom/ds/Atom.py | 10 ++ xpcom/ds/StaticAtoms.py | 6 +- xpcom/ds/nsAtom.h | 31 ++++--- xpcom/ds/nsAtomTable.cpp | 93 ++++++++----------- xpcom/ds/nsGkAtoms.cpp | 6 +- xpcom/ds/nsGkAtoms.h | 11 ++- 10 files changed, 148 insertions(+), 124 deletions(-) diff --git a/dom/base/nsAttrValue.cpp b/dom/base/nsAttrValue.cpp index ed9f2ee54a8c..7edbef56b491 100644 --- a/dom/base/nsAttrValue.cpp +++ b/dom/base/nsAttrValue.cpp @@ -1169,16 +1169,13 @@ nsAttrValue::Contains(nsAtom* aValue, nsCaseTreatment aCaseSensitive) const case eAtomBase: { nsAtom* atom = GetAtomValue(); - if (aCaseSensitive == eCaseMatters) { return aValue == atom; } // For performance reasons, don't do a full on unicode case insensitive // string comparison. This is only used for quirks mode anyway. - return - nsContentUtils::EqualsIgnoreASCIICase(nsDependentAtomString(aValue), - nsDependentAtomString(atom)); + return nsContentUtils::EqualsIgnoreASCIICase(aValue, atom); } default: { @@ -1188,16 +1185,11 @@ nsAttrValue::Contains(nsAtom* aValue, nsCaseTreatment aCaseSensitive) const return array->Contains(aValue); } - nsDependentAtomString val1(aValue); - - for (RefPtr *cur = array->Elements(), - *end = cur + array->Length(); - cur != end; ++cur) { + for (RefPtr& cur : *array) { // For performance reasons, don't do a full on unicode case // insensitive string comparison. This is only used for quirks mode // anyway. - if (nsContentUtils::EqualsIgnoreASCIICase(val1, - nsDependentAtomString(*cur))) { + if (nsContentUtils::EqualsIgnoreASCIICase(aValue, cur)) { return true; } } diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 5275e0c79ffb..934b94aa8018 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -2058,6 +2058,25 @@ public: static JSContext *GetCurrentJSContext(); + /** + * Case insensitive comparison between two atoms. + */ + static bool EqualsIgnoreASCIICase(nsAtom* aAtom1, nsAtom* aAtom2) + { + if (aAtom1 == aAtom2) { + return true; + } + + // If both are ascii lowercase already, we know that the slow comparison + // below is going to return false. + if (aAtom1->IsAsciiLowercase() && aAtom2->IsAsciiLowercase()) { + return false; + } + + return EqualsIgnoreASCIICase(nsDependentAtomString(aAtom1), + nsDependentAtomString(aAtom2)); + } + /** * Case insensitive comparison between two strings. However it only ignores * case for ASCII characters a-z. diff --git a/servo/components/style/gecko/regen_atoms.py b/servo/components/style/gecko/regen_atoms.py index 36ec0f704344..18c28a13b495 100755 --- a/servo/components/style/gecko/regen_atoms.py +++ b/servo/components/style/gecko/regen_atoms.py @@ -16,8 +16,8 @@ sys.path.insert(0, os.path.join(os.path.dirname(GECKO_DIR), "properties")) import build -# Matches lines like `GK_ATOM(foo, "foo", 0x12345678, nsStaticAtom, PseudoElementAtom)`. -PATTERN = re.compile('^GK_ATOM\(([^,]*),[^"]*"([^"]*)",\s*(0x[0-9a-f]+),\s*([^,]*),\s*([^)]*)\)', +# Matches lines like `GK_ATOM(foo, "foo", 0x12345678, true, nsStaticAtom, PseudoElementAtom)`. +PATTERN = re.compile('^GK_ATOM\(([^,]*),[^"]*"([^"]*)",\s*(0x[0-9a-f]+),\s*[^,]*,\s*([^,]*),\s*([^)]*)\)', re.MULTILINE) FILE = "include/nsGkAtomList.h" diff --git a/servo/components/style/gecko_string_cache/mod.rs b/servo/components/style/gecko_string_cache/mod.rs index 6d9e5c60f806..ed0cc19dae27 100644 --- a/servo/components/style/gecko_string_cache/mod.rs +++ b/servo/components/style/gecko_string_cache/mod.rs @@ -175,13 +175,19 @@ impl WeakAtom { /// Returns whether this atom is static. #[inline] pub fn is_static(&self) -> bool { - unsafe { (*self.as_ptr()).mIsStatic() != 0 } + self.0.mIsStatic() != 0 + } + + /// Returns whether this atom is ascii lowercase. + #[inline] + fn is_ascii_lowercase(&self) -> bool { + self.0.mIsAsciiLowercase() != 0 } /// Returns the length of the atom string. #[inline] pub fn len(&self) -> u32 { - unsafe { (*self.as_ptr()).mLength() } + self.0.mLength() } /// Returns whether this atom is the empty string. @@ -199,41 +205,54 @@ impl WeakAtom { /// Convert this atom to ASCII lower-case pub fn to_ascii_lowercase(&self) -> Atom { - let slice = self.as_slice(); - match slice - .iter() - .position(|&char16| (b'A' as u16) <= char16 && char16 <= (b'Z' as u16)) - { - None => self.clone(), - Some(i) => { - let mut buffer: [u16; 64] = unsafe { mem::uninitialized() }; - let mut vec; - let mutable_slice = if let Some(buffer_prefix) = buffer.get_mut(..slice.len()) { - buffer_prefix.copy_from_slice(slice); - buffer_prefix - } else { - vec = slice.to_vec(); - &mut vec - }; - for char16 in &mut mutable_slice[i..] { - if *char16 <= 0x7F { - *char16 = (*char16 as u8).to_ascii_lowercase() as u16 - } - } - Atom::from(&*mutable_slice) - }, + if self.is_ascii_lowercase() { + return self.clone(); } + + let slice = self.as_slice(); + let mut buffer: [u16; 64] = unsafe { mem::uninitialized() }; + let mut vec; + let mutable_slice = if let Some(buffer_prefix) = buffer.get_mut(..slice.len()) { + buffer_prefix.copy_from_slice(slice); + buffer_prefix + } else { + vec = slice.to_vec(); + &mut vec + }; + for char16 in &mut *mutable_slice { + if *char16 <= 0x7F { + *char16 = (*char16 as u8).to_ascii_lowercase() as u16 + } + } + Atom::from(&*mutable_slice) } /// Return whether two atoms are ASCII-case-insensitive matches + #[inline] pub fn eq_ignore_ascii_case(&self, other: &Self) -> bool { if self == other { return true; } + // If we know both atoms are ascii-lowercase, then we can stick with + // pointer equality. + if self.is_ascii_lowercase() && other.is_ascii_lowercase() { + debug_assert!(!self.eq_ignore_ascii_case_slow(other)); + return false; + } + + self.eq_ignore_ascii_case_slow(other) + } + + fn eq_ignore_ascii_case_slow(&self, other: &Self) -> bool { let a = self.as_slice(); let b = other.as_slice(); - a.len() == b.len() && a.iter().zip(b).all(|(&a16, &b16)| { + + if a.len() != b.len() { + return false; + } + + a.iter().zip(b).all(|(&a16, &b16)| { if a16 <= 0x7F && b16 <= 0x7F { (a16 as u8).eq_ignore_ascii_case(&(b16 as u8)) } else { @@ -241,13 +260,6 @@ impl WeakAtom { } }) } - - /// Return whether this atom is an ASCII-case-insensitive match for the given string - pub fn eq_str_ignore_ascii_case(&self, other: &str) -> bool { - self.chars() - .map(|r| r.map(|c: char| c.to_ascii_lowercase())) - .eq(other.chars().map(|c: char| Ok(c.to_ascii_lowercase()))) - } } impl fmt::Debug for WeakAtom { diff --git a/xpcom/ds/Atom.py b/xpcom/ds/Atom.py index f88c1e927e7e..1c9bcb7795bf 100644 --- a/xpcom/ds/Atom.py +++ b/xpcom/ds/Atom.py @@ -10,6 +10,7 @@ class Atom(): self.ty = ty self.atom_type = self.__class__.__name__ self.hash = hash_string(string) + self.is_ascii_lowercase = is_ascii_lowercase(string) class PseudoElementAtom(Atom): @@ -52,3 +53,12 @@ def hash_string(s): for c in s: h = wrapping_multiply(GOLDEN_RATIO_U32, rotate_left_5(h) ^ ord(c)) return h + + +# Returns true if lowercasing this string in an ascii-case-insensitive way +# would leave the string unchanged. +def is_ascii_lowercase(s): + for c in s: + if c >= 'A' and c <= 'Z': + return False + return True diff --git a/xpcom/ds/StaticAtoms.py b/xpcom/ds/StaticAtoms.py index 89bdabf38d37..ef2ac3449fa8 100644 --- a/xpcom/ds/StaticAtoms.py +++ b/xpcom/ds/StaticAtoms.py @@ -2355,9 +2355,9 @@ def generate_nsgkatomlist_h(output, *ignore): "#ifdef small\n" "#undef small\n" "#endif\n\n" - "// GK_ATOM(identifier, string, hash, gecko_type, atom_type)\n" + - "".join(["GK_ATOM(%s, \"%s\", 0x%08x, %s, %s)\n" % - (a.ident, a.string, a.hash, a.ty, a.atom_type) + "// GK_ATOM(identifier, string, hash, is_ascii_lower, gecko_type, atom_type)\n" + + "".join(["GK_ATOM(%s, \"%s\", 0x%08x, %s, %s, %s)\n" % + (a.ident, a.string, a.hash, str(a.is_ascii_lowercase).lower(), a.ty, a.atom_type) for a in STATIC_ATOMS])) diff --git a/xpcom/ds/nsAtom.h b/xpcom/ds/nsAtom.h index a9f80c77c452..f8d173fb5222 100644 --- a/xpcom/ds/nsAtom.h +++ b/xpcom/ds/nsAtom.h @@ -21,9 +21,7 @@ class nsDynamicAtom; // This class encompasses both static and dynamic atoms. // // - In places where static and dynamic atoms can be used, use RefPtr. -// This is by far the most common case. (The exception to this is the HTML5 -// parser, which does its own weird thing, and uses non-refcounted dynamic -// atoms.) +// This is by far the most common case. // // - In places where only static atoms can appear, use nsStaticAtom* to avoid // unnecessary refcounting. This is a moderately common case. @@ -75,6 +73,13 @@ public: // uint32_t hash() const { return mHash; } + // This function returns true if ToLowercaseASCII would return the string + // unchanged. + bool IsAsciiLowercase() const + { + return mIsAsciiLowercase; + } + // We can't use NS_INLINE_DECL_THREADSAFE_REFCOUNTING because the refcounting // of this type is special. MozExternalRefCountType AddRef(); @@ -84,16 +89,20 @@ public: protected: // Used by nsStaticAtom. - constexpr nsAtom(uint32_t aLength, uint32_t aHash) + constexpr nsAtom(uint32_t aLength, uint32_t aHash, bool aIsAsciiLowercase) : mLength(aLength) , mIsStatic(true) + , mIsAsciiLowercase(aIsAsciiLowercase) , mHash(aHash) {} // Used by nsDynamicAtom. - nsAtom(const nsAString& aString, uint32_t aHash) + nsAtom(const nsAString& aString, + uint32_t aHash, + bool aIsAsciiLowercase) : mLength(aString.Length()) , mIsStatic(false) + , mIsAsciiLowercase(aIsAsciiLowercase) , mHash(aHash) { } @@ -101,8 +110,8 @@ protected: ~nsAtom() = default; const uint32_t mLength:30; - // NOTE: There's one free bit here. const uint32_t mIsStatic:1; + const uint32_t mIsAsciiLowercase:1; const uint32_t mHash; }; @@ -123,8 +132,8 @@ public: // Atom.py and assert in nsAtomTable::RegisterStaticAtoms that the two // hashes match. constexpr nsStaticAtom(uint32_t aLength, uint32_t aHash, - uint32_t aStringOffset) - : nsAtom(aLength, aHash) + uint32_t aStringOffset, bool aIsAsciiLowercase) + : nsAtom(aLength, aHash, aIsAsciiLowercase) , mStringOffset(aStringOffset) {} @@ -167,14 +176,10 @@ private: // These shouldn't be used directly, even by friend classes. The // Create()/Destroy() methods use them. - static nsDynamicAtom* CreateInner(const nsAString& aString, uint32_t aHash); - nsDynamicAtom(const nsAString& aString, uint32_t aHash); + nsDynamicAtom(const nsAString& aString, uint32_t aHash, bool aIsAsciiLowercase); ~nsDynamicAtom() {} - // Creation/destruction is done by friend classes. The first Create() is for - // dynamic normal atoms, the second is for dynamic HTML5 atoms. static nsDynamicAtom* Create(const nsAString& aString, uint32_t aHash); - static nsDynamicAtom* Create(const nsAString& aString); static void Destroy(nsDynamicAtom* aAtom); mozilla::ThreadSafeAutoRefCnt mRefCnt; diff --git a/xpcom/ds/nsAtomTable.cpp b/xpcom/ds/nsAtomTable.cpp index 16f33d10b024..6a3aaa3e62cc 100644 --- a/xpcom/ds/nsAtomTable.cpp +++ b/xpcom/ds/nsAtomTable.cpp @@ -66,42 +66,45 @@ enum class GCKind { // replaying. static Atomic gUnusedAtomCount(0); -nsDynamicAtom::nsDynamicAtom(const nsAString& aString, uint32_t aHash) - : nsAtom(aString, aHash) +nsDynamicAtom::nsDynamicAtom(const nsAString& aString, uint32_t aHash, bool aIsAsciiLowercase) + : nsAtom(aString, aHash, aIsAsciiLowercase) , mRefCnt(1) { } -nsDynamicAtom* -nsDynamicAtom::CreateInner(const nsAString& aString, uint32_t aHash) +// Returns true if ToLowercaseASCII would return the string unchanged. +static bool +IsAsciiLowercase(const char16_t* aString, const uint32_t aLength) { - // We tack the chars onto the end of the nsDynamicAtom object. - size_t numCharBytes = (aString.Length() + 1) * sizeof(char16_t); - size_t numTotalBytes = sizeof(nsDynamicAtom) + numCharBytes; + for (uint32_t i = 0; i < aLength; ++i) { + if (IS_ASCII_UPPER(aString[i])) { + return false; + } + } - nsDynamicAtom* atom = (nsDynamicAtom*)moz_xmalloc(numTotalBytes); - new (atom) nsDynamicAtom(aString, aHash); - memcpy(const_cast(atom->String()), - PromiseFlatString(aString).get(), numCharBytes); - - MOZ_ASSERT(atom->String()[atom->GetLength()] == char16_t(0)); - MOZ_ASSERT(atom->Equals(aString)); - - return atom; + return true; } nsDynamicAtom* nsDynamicAtom::Create(const nsAString& aString, uint32_t aHash) { - nsDynamicAtom* atom = CreateInner(aString, aHash); - MOZ_ASSERT(atom->mHash == HashString(atom->String(), atom->GetLength())); - return atom; -} + // We tack the chars onto the end of the nsDynamicAtom object. + size_t numCharBytes = (aString.Length() + 1) * sizeof(char16_t); + size_t numTotalBytes = sizeof(nsDynamicAtom) + numCharBytes; -nsDynamicAtom* -nsDynamicAtom::Create(const nsAString& aString) -{ - return CreateInner(aString, /* hash */ 0); + bool isAsciiLower = ::IsAsciiLowercase(aString.Data(), aString.Length()); + + nsDynamicAtom* atom = (nsDynamicAtom*)moz_xmalloc(numTotalBytes); + new (atom) nsDynamicAtom(aString, aHash, isAsciiLower); + memcpy(const_cast(atom->String()), + PromiseFlatString(aString).get(), numCharBytes); + + MOZ_ASSERT(atom->String()[atom->GetLength()] == char16_t(0)); + MOZ_ASSERT(atom->Equals(aString)); + MOZ_ASSERT(atom->mHash == HashString(atom->String(), atom->GetLength())); + MOZ_ASSERT(atom->mIsAsciiLowercase == isAsciiLower); + + return atom; } void @@ -181,26 +184,22 @@ struct AtomTableKey MOZ_ASSERT(HashString(mUTF16String, mLength) == mHash); } - AtomTableKey(const char16_t* aUTF16String, uint32_t aLength, - uint32_t* aHashOut) + AtomTableKey(const char16_t* aUTF16String, uint32_t aLength) : mUTF16String(aUTF16String) , mUTF8String(nullptr) , mLength(aLength) { mHash = HashString(mUTF16String, mLength); - *aHashOut = mHash; } AtomTableKey(const char* aUTF8String, uint32_t aLength, - uint32_t* aHashOut, bool* aErr) : mUTF16String(nullptr) , mUTF8String(aUTF8String) , mLength(aLength) { mHash = HashUTF8AsUTF16(mUTF8String, mLength, aErr); - *aHashOut = mHash; } const char16_t* mUTF16String; @@ -641,6 +640,7 @@ nsAtomTable::RegisterStaticAtoms(const nsStaticAtom* aAtoms, size_t aAtomsLen) const nsStaticAtom* atom = &aAtoms[i]; MOZ_ASSERT(nsCRT::IsAscii(atom->String())); MOZ_ASSERT(NS_strlen(atom->String()) == atom->GetLength()); + MOZ_ASSERT(atom->IsAsciiLowercase() == ::IsAsciiLowercase(atom->String(), atom->GetLength())); // This assertion ensures the static atom's precomputed hash value matches // what would be computed by mozilla::HashString(aStr), which is what we use @@ -677,9 +677,8 @@ NS_Atomize(const char* aUTF8String) already_AddRefed nsAtomTable::Atomize(const nsACString& aUTF8String) { - uint32_t hash; bool err; - AtomTableKey key(aUTF8String.Data(), aUTF8String.Length(), &hash, &err); + AtomTableKey key(aUTF8String.Data(), aUTF8String.Length(), &err); if (MOZ_UNLIKELY(err)) { MOZ_ASSERT_UNREACHABLE("Tried to atomize invalid UTF-8."); // The input was invalid UTF-8. Let's replace the errors with U+FFFD @@ -694,13 +693,12 @@ nsAtomTable::Atomize(const nsACString& aUTF8String) if (he->mAtom) { RefPtr atom = he->mAtom; - return atom.forget(); } nsString str; CopyUTF8toUTF16(aUTF8String, str); - RefPtr atom = dont_AddRef(nsDynamicAtom::Create(str, hash)); + RefPtr atom = dont_AddRef(nsDynamicAtom::Create(str, key.mHash)); he->mAtom = atom; @@ -724,19 +722,18 @@ NS_Atomize(const char16_t* aUTF16String) already_AddRefed nsAtomTable::Atomize(const nsAString& aUTF16String) { - uint32_t hash; - AtomTableKey key(aUTF16String.Data(), aUTF16String.Length(), &hash); + AtomTableKey key(aUTF16String.Data(), aUTF16String.Length()); nsAtomSubTable& table = SelectSubTable(key); MutexAutoLock lock(table.mLock); AtomTableEntry* he = table.Add(key); if (he->mAtom) { RefPtr atom = he->mAtom; - return atom.forget(); } - RefPtr atom = dont_AddRef(nsDynamicAtom::Create(aUTF16String, hash)); + RefPtr atom = + dont_AddRef(nsDynamicAtom::Create(aUTF16String, key.mHash)); he->mAtom = atom; return atom.forget(); @@ -754,8 +751,7 @@ nsAtomTable::AtomizeMainThread(const nsAString& aUTF16String) { MOZ_ASSERT(NS_IsMainThread()); RefPtr retVal; - uint32_t hash; - AtomTableKey key(aUTF16String.Data(), aUTF16String.Length(), &hash); + AtomTableKey key(aUTF16String.Data(), aUTF16String.Length()); auto p = sRecentlyUsedMainThreadAtoms.Lookup(key); if (p) { retVal = p.Data(); @@ -770,7 +766,7 @@ nsAtomTable::AtomizeMainThread(const nsAString& aUTF16String) retVal = he->mAtom; } else { RefPtr newAtom = - dont_AddRef(nsDynamicAtom::Create(aUTF16String, hash)); + dont_AddRef(nsDynamicAtom::Create(aUTF16String, key.mHash)); he->mAtom = newAtom; retVal = newAtom.forget(); } @@ -810,8 +806,7 @@ NS_GetStaticAtom(const nsAString& aUTF16String) nsStaticAtom* nsAtomTable::GetStaticAtom(const nsAString& aUTF16String) { - uint32_t hash; - AtomTableKey key(aUTF16String.Data(), aUTF16String.Length(), &hash); + AtomTableKey key(aUTF16String.Data(), aUTF16String.Length()); nsAtomSubTable& table = SelectSubTable(key); MutexAutoLock lock(table.mLock); AtomTableEntry* he = table.Search(key); @@ -823,21 +818,11 @@ nsAtomTable::GetStaticAtom(const nsAString& aUTF16String) void ToLowerCaseASCII(RefPtr& aAtom) { // Assume the common case is that the atom is already ASCII lowercase. - bool reAtomize = false; - const nsDependentString existing(aAtom->GetUTF16String(), aAtom->GetLength()); - for (size_t i = 0; i < existing.Length(); ++i) { - if (IS_ASCII_UPPER(existing[i])) { - reAtomize = true; - break; - } - } - - // If the string was already lowercase, we're done. - if (!reAtomize) { + if (aAtom->IsAsciiLowercase()) { return; } nsAutoString lowercased; - ToLowerCaseASCII(existing, lowercased); + ToLowerCaseASCII(nsDependentAtomString(aAtom), lowercased); aAtom = NS_Atomize(lowercased); } diff --git a/xpcom/ds/nsGkAtoms.cpp b/xpcom/ds/nsGkAtoms.cpp index 24b04e58b8e8..0ad57d46adab 100644 --- a/xpcom/ds/nsGkAtoms.cpp +++ b/xpcom/ds/nsGkAtoms.cpp @@ -20,7 +20,7 @@ extern constexpr GkAtoms gGkAtoms = { // u"bb", // u"ccc", // - #define GK_ATOM(name_, value_, hash_, type_, atom_type_) \ + #define GK_ATOM(name_, value_, hash_, is_ascii_lower_, type_, atom_type_) \ u"" value_, #include "nsGkAtomList.h" #undef GK_ATOM @@ -48,12 +48,12 @@ extern constexpr GkAtoms gGkAtoms = { // offsetof(GkAtoms, mAtoms[static_cast(GkAtoms::Atoms::ccc)]) - // offsetof(GkAtoms, ccc_string)), // - #define GK_ATOM(name_, value_, hash_, type_, atom_type_) \ + #define GK_ATOM(name_, value_, hash_, is_ascii_lower_, type_, atom_type_) \ nsStaticAtom( \ sizeof(value_) - 1, hash_, \ offsetof(GkAtoms, \ mAtoms[static_cast(GkAtoms::Atoms::name_)]) - \ - offsetof(GkAtoms, name_##_string)), + offsetof(GkAtoms, name_##_string), is_ascii_lower_), #include "nsGkAtomList.h" #undef GK_ATOM } diff --git a/xpcom/ds/nsGkAtoms.h b/xpcom/ds/nsGkAtoms.h index 7c7669456d55..95beb73918d0 100644 --- a/xpcom/ds/nsGkAtoms.h +++ b/xpcom/ds/nsGkAtoms.h @@ -58,8 +58,9 @@ class name_ : public nsStaticAtom \ { \ public: \ - constexpr name_(uint32_t aLength, uint32_t aHash, uint32_t aOffset) \ - : nsStaticAtom(aLength, aHash, aOffset) {} \ + constexpr name_(uint32_t aLength, uint32_t aHash, uint32_t aOffset, \ + bool aIsAsciiLowercase) \ + : nsStaticAtom(aLength, aHash, aOffset, aIsAsciiLowercase) {} \ }; DEFINE_STATIC_ATOM_SUBCLASS(nsCSSAnonBoxPseudoStaticAtom) @@ -86,7 +87,7 @@ struct GkAtoms // const char16_t bb_string[sizeof("bb")]; // const char16_t ccc_string[sizeof("ccc")]; // - #define GK_ATOM(name_, value_, hash_, type_, atom_type_) \ + #define GK_ATOM(name_, value_, hash_, is_ascii_lower_, type_, atom_type_) \ const char16_t name_##_string[sizeof(value_)]; #include "nsGkAtomList.h" #undef GK_ATOM @@ -99,7 +100,7 @@ struct GkAtoms // bb, // ccc, // - #define GK_ATOM(name_, value_, hash_, type_, atom_type_) \ + #define GK_ATOM(name_, value_, hash_, is_ascii_lower_, type_, atom_type_) \ name_, #include "nsGkAtomList.h" #undef GK_ATOM @@ -166,7 +167,7 @@ public: // &mozilla::detail::gGkAtoms.mAtoms[ // static_cast(mozilla::detail::GkAtoms::Atoms::ccc)]); // - #define GK_ATOM(name_, value_, hash_, type_, atom_type_) \ + #define GK_ATOM(name_, value_, hash_, is_ascii_lower_, type_, atom_type_) \ static constexpr nsStaticAtom* name_ = \ const_cast( \ &mozilla::detail::gGkAtoms.mAtoms[ \