From 63484d1fbad135fbeab20a2f77233ada70bf98f0 Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Fri, 29 Mar 2019 05:58:25 +0000 Subject: [PATCH 001/100] Bug 1141387 - Set image.animation_mode=none to avoid the animated GIF is advanced to the next frame. r=heycam The animated GIF in background-blending-image-color-gif.html has two animation frames, the one is a red rectangle, the other is a green rectangle. The reftest is supposed to take the snapshot during the time where the animation frame is the red rectangle (the first frame) and the frame duration is 1000ms. So if we take over 1000ms there for some reasons, say on slow platforms, before taking the snapshot, the reftet fails. Differential Revision: https://phabricator.services.mozilla.com/D24843 --HG-- extra : moz-landing-system : lando --- layout/reftests/css-blending/reftest.list | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/reftests/css-blending/reftest.list b/layout/reftests/css-blending/reftest.list index b88aaea282d7..c2020a20f047 100644 --- a/layout/reftests/css-blending/reftest.list +++ b/layout/reftests/css-blending/reftest.list @@ -55,7 +55,7 @@ fuzzy(0-1,0-6800) == clipped-opacity-containing-unclipped-mixblendmode.html clip # Test 9 == background-blending-image-color-svg-as-data-uri.html background-blending-image-color-ref.html # Test 10 -== background-blending-image-color-gif.html background-blending-image-color-gif-ref.html +test-pref(image.animation_mode,"none") == background-blending-image-color-gif.html background-blending-image-color-gif-ref.html == background-blending-image-color-transform3d.html background-blending-image-color-ref.html # Test plan 5.3.2 Background layers do not blend with content outside the background (or behind the element) - tests 2 and 3 From 06e92e2f2b37ea2f5ad1ea6d6662c7a4951cfd26 Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Thu, 28 Mar 2019 22:13:38 +0000 Subject: [PATCH 002/100] Bug 1539552 - XHR must bind itself to valid nsIGlobalObject in workers, r=smaug Differential Revision: https://phabricator.services.mozilla.com/D25099 --HG-- extra : moz-landing-system : lando --- dom/xhr/XMLHttpRequestWorker.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dom/xhr/XMLHttpRequestWorker.cpp b/dom/xhr/XMLHttpRequestWorker.cpp index e03e4ec80848..62fbcc11272c 100644 --- a/dom/xhr/XMLHttpRequestWorker.cpp +++ b/dom/xhr/XMLHttpRequestWorker.cpp @@ -1474,7 +1474,14 @@ already_AddRefed XMLHttpRequestWorker::Construct( WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx); MOZ_ASSERT(workerPrivate); + nsCOMPtr global = do_QueryInterface(aGlobal.GetAsSupports()); + if (NS_WARN_IF(!global)) { + aRv.Throw(NS_ERROR_FAILURE); + return nullptr; + } + RefPtr xhr = new XMLHttpRequestWorker(workerPrivate); + xhr->BindToOwner(global); if (workerPrivate->XHRParamsAllowed()) { if (aParams.mMozSystem) From cf18d7063058d7f327d67d9dd4664e0f2bf1db4d Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Thu, 28 Mar 2019 22:06:29 +0000 Subject: [PATCH 003/100] Bug 1539532 - EventSource must bind itself to valid nsIGlobalObject in workers, r=smaug Differential Revision: https://phabricator.services.mozilla.com/D25092 --HG-- extra : moz-landing-system : lando --- dom/base/EventSource.cpp | 29 +++++++++++++---------------- dom/base/EventSource.h | 6 +++--- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/dom/base/EventSource.cpp b/dom/base/EventSource.cpp index 73b2803cca3f..e0218d1f6a9a 100644 --- a/dom/base/EventSource.cpp +++ b/dom/base/EventSource.cpp @@ -1376,16 +1376,10 @@ void EventSourceImpl::DispatchAllMessageEvents() { } AutoJSAPI jsapi; - if (mIsMainThread) { - if (NS_WARN_IF(!jsapi.Init(mEventSource->GetOwner()))) { - return; - } - } else { - MOZ_ASSERT(mWorkerRef); - if (NS_WARN_IF(!jsapi.Init(mWorkerRef->Private()->GlobalScope()))) { - return; - } + if (NS_WARN_IF(!jsapi.Init(mEventSource->GetOwnerGlobal()))) { + return; } + JSContext* cx = jsapi.cx(); while (mMessagesToDispatch.GetSize() > 0) { @@ -1783,13 +1777,14 @@ EventSourceImpl::CheckListenerChain() { // EventSource //////////////////////////////////////////////////////////////////////////////// -EventSource::EventSource(nsPIDOMWindowInner* aOwnerWindow, +EventSource::EventSource(nsIGlobalObject* aGlobal, nsICookieSettings* aCookieSettings, bool aWithCredentials) - : DOMEventTargetHelper(aOwnerWindow), + : DOMEventTargetHelper(aGlobal), mWithCredentials(aWithCredentials), mIsMainThread(true), mKeepingAlive(false) { + MOZ_ASSERT(aGlobal); MOZ_ASSERT(aCookieSettings); mImpl = new EventSourceImpl(this, aCookieSettings); } @@ -1810,12 +1805,14 @@ nsresult EventSource::CreateAndDispatchSimpleEvent(const nsAString& aName) { already_AddRefed EventSource::Constructor( const GlobalObject& aGlobal, const nsAString& aURL, const EventSourceInit& aEventSourceInitDict, ErrorResult& aRv) { - nsCOMPtr ownerWindow = - do_QueryInterface(aGlobal.GetAsSupports()); - - MOZ_ASSERT(!NS_IsMainThread() || ownerWindow); + nsCOMPtr global = do_QueryInterface(aGlobal.GetAsSupports()); + if (NS_WARN_IF(!global)) { + aRv.Throw(NS_ERROR_FAILURE); + return nullptr; + } nsCOMPtr cookieSettings; + nsCOMPtr ownerWindow = do_QueryInterface(global); if (ownerWindow) { Document* doc = ownerWindow->GetExtantDoc(); if (NS_WARN_IF(!doc)) { @@ -1832,7 +1829,7 @@ already_AddRefed EventSource::Constructor( } RefPtr eventSource = new EventSource( - ownerWindow, cookieSettings, aEventSourceInitDict.mWithCredentials); + global, cookieSettings, aEventSourceInitDict.mWithCredentials); RefPtr eventSourceImp = eventSource->mImpl; if (NS_IsMainThread()) { diff --git a/dom/base/EventSource.h b/dom/base/EventSource.h index 216f16ff46ef..a9f89cfe7adc 100644 --- a/dom/base/EventSource.h +++ b/dom/base/EventSource.h @@ -24,7 +24,7 @@ #include "nsIHttpChannel.h" #include "nsDeque.h" -class nsPIDOMWindowInner; +class nsIGlobalObject; class nsICookieSettings; namespace mozilla { @@ -81,8 +81,8 @@ class EventSource final : public DOMEventTargetHelper { void Close(); private: - EventSource(nsPIDOMWindowInner* aOwnerWindow, - nsICookieSettings* aCookieSettings, bool aWithCredentials); + EventSource(nsIGlobalObject* aGlobal, nsICookieSettings* aCookieSettings, + bool aWithCredentials); virtual ~EventSource(); // prevent bad usage EventSource(const EventSource& x) = delete; From e93691e85b2e384be8ec3bec59b1004cbd1e736d Mon Sep 17 00:00:00 2001 From: violet Date: Fri, 29 Mar 2019 07:01:10 +0000 Subject: [PATCH 004/100] Bug 1370646 - Honor the maxTextRunSize if it's within reasonable range r=heycam If the maximal and minimal font-size in a SVGTextFrame have a huge difference, previously we chose mFontSizeScaleFactor to satisfy the minimal one. That's problematic, because the maximal one might be a reasonable size, while the minimal one is extremely small. We should honor the maximal one if this is the case. Differential Revision: https://phabricator.services.mozilla.com/D24494 --HG-- extra : moz-landing-system : lando --- layout/svg/SVGTextFrame.cpp | 17 +++++++++--- layout/svg/tests/mochitest.ini | 1 + layout/svg/tests/test_multiple_font_size.html | 26 +++++++++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 layout/svg/tests/test_multiple_font_size.html diff --git a/layout/svg/SVGTextFrame.cpp b/layout/svg/SVGTextFrame.cpp index 54e77a991775..38e4935bb818 100644 --- a/layout/svg/SVGTextFrame.cpp +++ b/layout/svg/SVGTextFrame.cpp @@ -5223,9 +5223,20 @@ bool SVGTextFrame::UpdateFontSizeScaleFactor() { mFontSizeScaleFactor = contextScale; } else if (maxSize / minSize > CLAMP_MAX_SIZE / CLAMP_MIN_SIZE) { // We can't scale the font sizes so that all of the text frames lie - // within our ideal font size range, so we treat the minimum as more - // important and just scale so that minSize = CLAMP_MIN_SIZE. - mFontSizeScaleFactor = CLAMP_MIN_SIZE / minSize; + // within our ideal font size range. + // Heuristically, if the maxTextRunSize is within the CLAMP_MAX_SIZE + // as a reasonable value, it's likely to be the user's intent to + // get a valid font for the maxTextRunSize one, we should honor it. + // The same for minTextRunSize. + if (maxTextRunSize <= CLAMP_MAX_SIZE) { + mFontSizeScaleFactor = CLAMP_MAX_SIZE / maxSize; + } else if (minTextRunSize >= CLAMP_MIN_SIZE) { + mFontSizeScaleFactor = CLAMP_MIN_SIZE / minSize; + } else { + // So maxTextRunSize is too big, minTextRunSize is too small, + // we can't really do anything for this case, just leave it as is. + mFontSizeScaleFactor = contextScale; + } } else if (minTextRunSize < CLAMP_MIN_SIZE) { mFontSizeScaleFactor = CLAMP_MIN_SIZE / minSize; } else { diff --git a/layout/svg/tests/mochitest.ini b/layout/svg/tests/mochitest.ini index b8fcde88973f..935f5e8566c0 100644 --- a/layout/svg/tests/mochitest.ini +++ b/layout/svg/tests/mochitest.ini @@ -11,4 +11,5 @@ support-files = file_yellow_black.svg [test_hover_near_text.html] +[test_multiple_font_size.html] [test_use_tree_cycle.html] diff --git a/layout/svg/tests/test_multiple_font_size.html b/layout/svg/tests/test_multiple_font_size.html new file mode 100644 index 000000000000..77683f90512e --- /dev/null +++ b/layout/svg/tests/test_multiple_font_size.html @@ -0,0 +1,26 @@ + + + +Mozilla Bug 1370646 + + + + 3 + + + 3 + 0 + + + + + From 2104ef436624ae834d32804c4ee7d722caa188fb Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Thu, 28 Mar 2019 22:09:21 +0000 Subject: [PATCH 005/100] Bug 1539528 - WebSocket must bind itself to valid nsIGlobalObject in workers, r=smaug Differential Revision: https://phabricator.services.mozilla.com/D25088 --HG-- extra : moz-landing-system : lando --- dom/websocket/WebSocket.cpp | 37 +++++++++++++++---------------------- dom/websocket/WebSocket.h | 4 +--- 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/dom/websocket/WebSocket.cpp b/dom/websocket/WebSocket.cpp index 96cd8f98fe1e..cc2502e72397 100644 --- a/dom/websocket/WebSocket.cpp +++ b/dom/websocket/WebSocket.cpp @@ -870,8 +870,8 @@ WebSocketImpl::GetInterface(const nsIID& aIID, void** aResult) { // WebSocket //////////////////////////////////////////////////////////////////////////////// -WebSocket::WebSocket(nsPIDOMWindowInner* aOwnerWindow) - : DOMEventTargetHelper(aOwnerWindow), +WebSocket::WebSocket(nsIGlobalObject* aGlobal) + : DOMEventTargetHelper(aGlobal), mIsMainThread(true), mKeepingAlive(false), mCheckMustKeepAlive(true), @@ -879,6 +879,8 @@ WebSocket::WebSocket(nsPIDOMWindowInner* aOwnerWindow) mBinaryType(dom::BinaryType::Blob), mMutex("WebSocket::mMutex"), mReadyState(CONNECTING) { + MOZ_ASSERT(aGlobal); + mImpl = new WebSocketImpl(this); mIsMainThread = mImpl->mIsMainThread; } @@ -1180,7 +1182,12 @@ already_AddRefed WebSocket::ConstructorCommon( const nsACString& aNegotiatedExtensions, ErrorResult& aRv) { MOZ_ASSERT_IF(!aTransportProvider, aNegotiatedExtensions.IsEmpty()); nsCOMPtr principal; - nsCOMPtr ownerWindow; + + nsCOMPtr global = do_QueryInterface(aGlobal.GetAsSupports()); + if (NS_WARN_IF(!global)) { + aRv.Throw(NS_ERROR_FAILURE); + return nullptr; + } if (NS_IsMainThread()) { nsCOMPtr scriptPrincipal = @@ -1202,12 +1209,6 @@ already_AddRefed WebSocket::ConstructorCommon( aRv.Throw(NS_ERROR_FAILURE); return nullptr; } - - ownerWindow = do_QueryInterface(aGlobal.GetAsSupports()); - if (!ownerWindow) { - aRv.Throw(NS_ERROR_FAILURE); - return nullptr; - } } nsTArray protocolArray; @@ -1231,7 +1232,7 @@ already_AddRefed WebSocket::ConstructorCommon( protocolArray.AppendElement(protocolElement); } - RefPtr webSocket = new WebSocket(ownerWindow); + RefPtr webSocket = new WebSocket(global); RefPtr webSocketImpl = webSocket->mImpl; bool connectionFailed = true; @@ -1349,6 +1350,7 @@ already_AddRefed WebSocket::ConstructorCommon( if (NS_IsMainThread()) { MOZ_ASSERT(principal); + nsCOMPtr ownerWindow = do_QueryInterface(global); nsPIDOMWindowOuter* outerWindow = ownerWindow->GetOuterWindow(); uint64_t windowID = 0; @@ -1800,17 +1802,8 @@ nsresult WebSocket::CreateAndDispatchMessageEvent(const nsACString& aData, AssertIsOnTargetThread(); AutoJSAPI jsapi; - - if (NS_IsMainThread()) { - if (NS_WARN_IF(!jsapi.Init(GetOwner()))) { - return NS_ERROR_FAILURE; - } - } else { - MOZ_ASSERT(!mIsMainThread); - MOZ_ASSERT(mImpl->mWorkerRef); - if (NS_WARN_IF(!jsapi.Init(mImpl->mWorkerRef->Private()->GlobalScope()))) { - return NS_ERROR_FAILURE; - } + if (NS_WARN_IF(!jsapi.Init(GetOwnerGlobal()))) { + return NS_ERROR_FAILURE; } JSContext* cx = jsapi.cx(); @@ -1829,7 +1822,7 @@ nsresult WebSocket::CreateAndDispatchMessageEvent(const nsACString& aData, messageType = nsIWebSocketEventListener::TYPE_BLOB; RefPtr blob = - Blob::CreateStringBlob(GetOwner(), aData, EmptyString()); + Blob::CreateStringBlob(GetOwnerGlobal(), aData, EmptyString()); MOZ_ASSERT(blob); if (!ToJSValue(cx, blob, &jsData)) { diff --git a/dom/websocket/WebSocket.h b/dom/websocket/WebSocket.h index a43fe3d995b9..c25b350ec3c7 100644 --- a/dom/websocket/WebSocket.h +++ b/dom/websocket/WebSocket.h @@ -55,8 +55,6 @@ class WebSocket final : public DOMEventTargetHelper { virtual void DisconnectFromOwner() override; // nsWrapperCache - nsPIDOMWindowInner* GetParentObject() { return GetOwner(); } - virtual JSObject* WrapObject(JSContext* cx, JS::Handle aGivenProto) override; @@ -138,7 +136,7 @@ class WebSocket final : public DOMEventTargetHelper { void Send(const ArrayBufferView& aData, ErrorResult& aRv); private: // constructor && destructor - explicit WebSocket(nsPIDOMWindowInner* aOwnerWindow); + explicit WebSocket(nsIGlobalObject* aGlobal); virtual ~WebSocket(); void SetReadyState(uint16_t aReadyState); From df4f2bc26442ee2b2d9e84348fa3a5cf95f94a06 Mon Sep 17 00:00:00 2001 From: "Francesco Lodolo (:flod)" Date: Thu, 28 Mar 2019 15:06:35 +0000 Subject: [PATCH 006/100] Bug 1539794 - Add installer font configuration for Bengali (bn), remove bn-IN and bn-BD r=mhowell Differential Revision: https://phabricator.services.mozilla.com/D25220 --HG-- extra : moz-landing-system : lando --- toolkit/mozapps/installer/windows/nsis/locale-fonts.nsh | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/toolkit/mozapps/installer/windows/nsis/locale-fonts.nsh b/toolkit/mozapps/installer/windows/nsis/locale-fonts.nsh index 1e20b80bd695..77203f81d403 100644 --- a/toolkit/mozapps/installer/windows/nsis/locale-fonts.nsh +++ b/toolkit/mozapps/installer/windows/nsis/locale-fonts.nsh @@ -63,13 +63,7 @@ !endif ; Bengali -!if "${AB_CD}" == "bn-BD" -!define FONT_NAME1 "Nirmala UI" -!define FONT_FILE1 "Nirmala.ttf" -!endif - -; Bengali - India -!if "${AB_CD}" == "bn-IN" +!if "${AB_CD}" == "bn" !define FONT_NAME1 "Nirmala UI" !define FONT_FILE1 "Nirmala.ttf" !endif From 3eb9182bd356ea3dabcff85591ab072c169adc7c Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Thu, 28 Mar 2019 22:12:27 +0000 Subject: [PATCH 007/100] Bug 1539524 - BroadcastChannel must bind itself to valid nsIGlobalObject in workers, r=smaug Differential Revision: https://phabricator.services.mozilla.com/D25082 --HG-- extra : moz-landing-system : lando --- dom/broadcastchannel/BroadcastChannel.cpp | 23 +++++++++++++++-------- dom/broadcastchannel/BroadcastChannel.h | 4 ++-- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/dom/broadcastchannel/BroadcastChannel.cpp b/dom/broadcastchannel/BroadcastChannel.cpp index 6cfbfb71c9a4..230088b80480 100644 --- a/dom/broadcastchannel/BroadcastChannel.cpp +++ b/dom/broadcastchannel/BroadcastChannel.cpp @@ -198,11 +198,10 @@ class TeardownRunnableOnWorker final : public WorkerControlRunnable, } // namespace -BroadcastChannel::BroadcastChannel(nsPIDOMWindowInner* aWindow, +BroadcastChannel::BroadcastChannel(nsIGlobalObject* aGlobal, const nsAString& aChannel) - : DOMEventTargetHelper(aWindow), mChannel(aChannel), mState(StateActive) { - // Window can be null in workers - + : DOMEventTargetHelper(aGlobal), mChannel(aChannel), mState(StateActive) { + MOZ_ASSERT(aGlobal); KeepAliveIfHasListenersFor(NS_LITERAL_STRING("message")); } @@ -219,16 +218,24 @@ JSObject* BroadcastChannel::WrapObject(JSContext* aCx, /* static */ already_AddRefed BroadcastChannel::Constructor( const GlobalObject& aGlobal, const nsAString& aChannel, ErrorResult& aRv) { - nsCOMPtr window = - do_QueryInterface(aGlobal.GetAsSupports()); - // Window is null in workers. + nsCOMPtr global = do_QueryInterface(aGlobal.GetAsSupports()); + if (NS_WARN_IF(!global)) { + aRv.Throw(NS_ERROR_FAILURE); + return nullptr; + } - RefPtr bc = new BroadcastChannel(window, aChannel); + RefPtr bc = new BroadcastChannel(global, aChannel); nsAutoCString origin; PrincipalInfo principalInfo; if (NS_IsMainThread()) { + nsCOMPtr window = do_QueryInterface(global); + if (NS_WARN_IF(!window)) { + aRv.Throw(NS_ERROR_FAILURE); + return nullptr; + } + nsCOMPtr incumbent = mozilla::dom::GetIncumbentGlobal(); if (!incumbent) { diff --git a/dom/broadcastchannel/BroadcastChannel.h b/dom/broadcastchannel/BroadcastChannel.h index 7f44278389cc..e625097a0aef 100644 --- a/dom/broadcastchannel/BroadcastChannel.h +++ b/dom/broadcastchannel/BroadcastChannel.h @@ -13,7 +13,7 @@ #include "nsTArray.h" #include "mozilla/RefPtr.h" -class nsPIDOMWindowInner; +class nsIGlobalObject; namespace mozilla { @@ -57,7 +57,7 @@ class BroadcastChannel final : public DOMEventTargetHelper { void Shutdown(); private: - BroadcastChannel(nsPIDOMWindowInner* aWindow, const nsAString& aChannel); + BroadcastChannel(nsIGlobalObject* aGlobal, const nsAString& aChannel); ~BroadcastChannel(); From 118fc8a930e4a91ae6f1c23da7bd1a9202139949 Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Thu, 28 Mar 2019 19:20:00 +0000 Subject: [PATCH 008/100] Bug 1529893: Set correct CSP within nsWindowWatcher. r=bzbarsky Differential Revision: https://phabricator.services.mozilla.com/D25260 --HG-- extra : moz-landing-system : lando --- .../test/csp/file_windowwatcher_frameA.html | 17 ++++++++++ .../csp/file_windowwatcher_subframeB.html | 12 +++++++ .../csp/file_windowwatcher_subframeC.html | 9 ++++++ .../csp/file_windowwatcher_subframeD.html | 6 ++++ .../test/csp/file_windowwatcher_win_open.html | 15 +++++++++ dom/security/test/csp/mochitest.ini | 7 +++++ .../test/csp/test_uir_windowwatcher.html | 31 +++++++++++++++++++ .../windowwatcher/nsWindowWatcher.cpp | 29 +++++++++++------ 8 files changed, 116 insertions(+), 10 deletions(-) create mode 100644 dom/security/test/csp/file_windowwatcher_frameA.html create mode 100644 dom/security/test/csp/file_windowwatcher_subframeB.html create mode 100644 dom/security/test/csp/file_windowwatcher_subframeC.html create mode 100644 dom/security/test/csp/file_windowwatcher_subframeD.html create mode 100644 dom/security/test/csp/file_windowwatcher_win_open.html create mode 100644 dom/security/test/csp/test_uir_windowwatcher.html diff --git a/dom/security/test/csp/file_windowwatcher_frameA.html b/dom/security/test/csp/file_windowwatcher_frameA.html new file mode 100644 index 000000000000..9e544142cec1 --- /dev/null +++ b/dom/security/test/csp/file_windowwatcher_frameA.html @@ -0,0 +1,17 @@ + + + +frame A
+ + + + + + + diff --git a/dom/security/test/csp/file_windowwatcher_subframeB.html b/dom/security/test/csp/file_windowwatcher_subframeB.html new file mode 100644 index 000000000000..e7ef422313a5 --- /dev/null +++ b/dom/security/test/csp/file_windowwatcher_subframeB.html @@ -0,0 +1,12 @@ + + + +subFrame B + + + + diff --git a/dom/security/test/csp/file_windowwatcher_subframeC.html b/dom/security/test/csp/file_windowwatcher_subframeC.html new file mode 100644 index 000000000000..b97c40432e21 --- /dev/null +++ b/dom/security/test/csp/file_windowwatcher_subframeC.html @@ -0,0 +1,9 @@ + + + + + + +subFrame C + + diff --git a/dom/security/test/csp/file_windowwatcher_subframeD.html b/dom/security/test/csp/file_windowwatcher_subframeD.html new file mode 100644 index 000000000000..2f778ea4cd6a --- /dev/null +++ b/dom/security/test/csp/file_windowwatcher_subframeD.html @@ -0,0 +1,6 @@ + + + +subFrame D + + diff --git a/dom/security/test/csp/file_windowwatcher_win_open.html b/dom/security/test/csp/file_windowwatcher_win_open.html new file mode 100644 index 000000000000..0237e49377c5 --- /dev/null +++ b/dom/security/test/csp/file_windowwatcher_win_open.html @@ -0,0 +1,15 @@ + + + +Opened Window
+ + + + diff --git a/dom/security/test/csp/mochitest.ini b/dom/security/test/csp/mochitest.ini index 885beae01b76..bf1173ac9f2d 100644 --- a/dom/security/test/csp/mochitest.ini +++ b/dom/security/test/csp/mochitest.ini @@ -368,3 +368,10 @@ support-files = [test_nonce_snapshot.html] support-files = file_nonce_snapshot.sjs +[test_uir_windowwatcher.html] +support-files = + file_windowwatcher_frameA.html + file_windowwatcher_subframeB.html + file_windowwatcher_subframeC.html + file_windowwatcher_subframeD.html + file_windowwatcher_win_open.html diff --git a/dom/security/test/csp/test_uir_windowwatcher.html b/dom/security/test/csp/test_uir_windowwatcher.html new file mode 100644 index 000000000000..e7636010b7f3 --- /dev/null +++ b/dom/security/test/csp/test_uir_windowwatcher.html @@ -0,0 +1,31 @@ + + + + + Bug 1529893 - Test upgrade-insecure-requests for opening window through nsWindowWatcher + + + + + + + + + + diff --git a/toolkit/components/windowwatcher/nsWindowWatcher.cpp b/toolkit/components/windowwatcher/nsWindowWatcher.cpp index 9e1d263c4d8c..c79b5bb02acf 100644 --- a/toolkit/components/windowwatcher/nsWindowWatcher.cpp +++ b/toolkit/components/windowwatcher/nsWindowWatcher.cpp @@ -967,10 +967,10 @@ nsresult nsWindowWatcher::OpenWindowInternal( // It's just designed to preserve old semantics during a mass-conversion // patch. // Bug 1498605 verify usages of systemPrincipal here + JSContext* cx = nsContentUtils::GetCurrentJSContext(); nsCOMPtr subjectPrincipal = - nsContentUtils::GetCurrentJSContext() - ? nsContentUtils::SubjectPrincipal() - : nsContentUtils::GetSystemPrincipal(); + cx ? nsContentUtils::SubjectPrincipal() + : nsContentUtils::GetSystemPrincipal(); bool isPrivateBrowsingWindow = false; @@ -1086,13 +1086,22 @@ nsresult nsWindowWatcher::OpenWindowInternal( } } - // Currently we query the CSP from the subjectPrincipal. After Bug 965637 - // we should query the CSP from the doc, similar to the referrerInfo above. - if (subjectPrincipal && loadState) { - nsCOMPtr csp; - rv = subjectPrincipal->GetCsp(getter_AddRefs(csp)); - NS_ENSURE_SUCCESS(rv, rv); - loadState->SetCsp(csp); + // Currently we query the CSP from the principal of the inner window. + // After Bug 965637 we can query the CSP directly from the inner window. + // Further, if the JS context is null, then the subjectPrincipal falls + // back to being the SystemPrincipal (see above) and the SystemPrincipal + // can currently not hold a CSP. We use the same semantics here. + if (loadState && cx) { + nsGlobalWindowInner* win = xpc::CurrentWindowOrNull(cx); + if (win) { + nsCOMPtr principal = win->GetPrincipal(); + if (principal) { + nsCOMPtr csp; + rv = principal->GetCsp(getter_AddRefs(csp)); + NS_ENSURE_SUCCESS(rv, rv); + loadState->SetCsp(csp); + } + } } if (isNewToplevelWindow) { From 6685c3a7a7d1a3b803e2fae2871db8bc48e780ea Mon Sep 17 00:00:00 2001 From: Nicolas Chevobbe Date: Fri, 29 Mar 2019 08:03:15 +0000 Subject: [PATCH 009/100] Bug 1524276 - Expose `category` and `innerWindowID` properties in ConsoleMessage. r=bgrins. This will be used to group similar messages together. Stubs are updated. Differential Revision: https://phabricator.services.mozilla.com/D23549 --HG-- extra : moz-landing-system : lando --- .../test/fixtures/stub-generators/head.js | 7 +- .../test/fixtures/stubs/consoleApi.js | 275 ++++++++++++++---- .../test/fixtures/stubs/cssMessage.js | 6 + .../test/fixtures/stubs/evaluationResult.js | 18 ++ .../test/fixtures/stubs/pageError.js | 15 + devtools/client/webconsole/types.js | 2 + devtools/client/webconsole/utils/messages.js | 2 + devtools/server/actors/webconsole.js | 2 + 8 files changed, 271 insertions(+), 56 deletions(-) diff --git a/devtools/client/webconsole/test/fixtures/stub-generators/head.js b/devtools/client/webconsole/test/fixtures/stub-generators/head.js index 9f5f9ee0cbdc..bfc091ddc1ac 100644 --- a/devtools/client/webconsole/test/fixtures/stub-generators/head.js +++ b/devtools/client/webconsole/test/fixtures/stub-generators/head.js @@ -62,6 +62,10 @@ function getCleanedPacket(key, packet) { res.timeStamp = existingPacket.timeStamp; } + if (res.innerWindowID) { + res.innerWindowID = existingPacket.innerWindowID; + } + if (res.startedDateTime) { res.startedDateTime = existingPacket.startedDateTime; } @@ -171,8 +175,9 @@ function getCleanedPacket(key, packet) { } if (res.pageError) { - // Clean timeStamp on pageError messages. + // Clean timeStamp and innerWindowID on pageError messages. res.pageError.timeStamp = existingPacket.pageError.timeStamp; + res.pageError.innerWindowID = existingPacket.pageError.innerWindowID; if ( typeof res.pageError.errorMessage === "object" diff --git a/devtools/client/webconsole/test/fixtures/stubs/consoleApi.js b/devtools/client/webconsole/test/fixtures/stubs/consoleApi.js index 57306760fef5..b54b0a58434a 100644 --- a/devtools/client/webconsole/test/fixtures/stubs/consoleApi.js +++ b/devtools/client/webconsole/test/fixtures/stubs/consoleApi.js @@ -15,12 +15,14 @@ const stubPreparedMessages = new Map(); const stubPackets = new Map(); stubPreparedMessages.set(`console.log('foobar', 'test')`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924471, "type": "log", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ "foobar", @@ -46,12 +48,14 @@ stubPreparedMessages.set(`console.log('foobar', 'test')`, new ConsoleMessage({ stubPreparedMessages.set(`console.log(undefined)`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924479, "type": "log", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ { @@ -78,12 +82,14 @@ stubPreparedMessages.set(`console.log(undefined)`, new ConsoleMessage({ stubPreparedMessages.set(`console.warn('danger, will robinson!')`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924487, "type": "warn", "helperType": null, "level": "warn", + "category": null, "messageText": null, "parameters": [ "danger, will robinson!" @@ -108,12 +114,14 @@ stubPreparedMessages.set(`console.warn('danger, will robinson!')`, new ConsoleMe stubPreparedMessages.set(`console.log(NaN)`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924495, "type": "log", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ { @@ -140,12 +148,14 @@ stubPreparedMessages.set(`console.log(NaN)`, new ConsoleMessage({ stubPreparedMessages.set(`console.log(null)`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924501, "type": "log", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ { @@ -172,12 +182,14 @@ stubPreparedMessages.set(`console.log(null)`, new ConsoleMessage({ stubPreparedMessages.set(`console.log('鼬')`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924506, "type": "log", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ "鼬" @@ -202,12 +214,14 @@ stubPreparedMessages.set(`console.log('鼬')`, new ConsoleMessage({ stubPreparedMessages.set(`console.clear()`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924512, "type": "clear", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ "Console was cleared." @@ -232,12 +246,14 @@ stubPreparedMessages.set(`console.clear()`, new ConsoleMessage({ stubPreparedMessages.set(`console.count('bar')`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924515, "type": "log", "helperType": null, "level": "log", + "category": null, "messageText": "bar: 1", "parameters": null, "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source25\",\"line\":1,\"column\":35},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"bar: 1\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}", @@ -260,12 +276,14 @@ stubPreparedMessages.set(`console.count('bar')`, new ConsoleMessage({ stubPreparedMessages.set(`console.assert(false, {message: 'foobar'})`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924521, "type": "assert", "helperType": null, "level": "error", + "category": null, "messageText": null, "parameters": [ { @@ -321,12 +339,14 @@ stubPreparedMessages.set(`console.assert(false, {message: 'foobar'})`, new Conso stubPreparedMessages.set(`console.log('hello \nfrom \rthe \"string world!')`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924528, "type": "log", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ "hello \nfrom \rthe \"string world!" @@ -351,12 +371,14 @@ stubPreparedMessages.set(`console.log('hello \nfrom \rthe \"string world!')`, ne stubPreparedMessages.set(`console.log('úṇĩçödê țĕșť')`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924586, "type": "log", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ "úṇĩçödê țĕșť" @@ -381,12 +403,14 @@ stubPreparedMessages.set(`console.log('úṇĩçödê țĕșť')`, new ConsoleMe stubPreparedMessages.set(`console.dirxml(window)`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924596, "type": "log", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ { @@ -423,12 +447,14 @@ stubPreparedMessages.set(`console.dirxml(window)`, new ConsoleMessage({ stubPreparedMessages.set(`console.log('myarray', ['red', 'green', 'blue'])`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924604, "type": "log", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ "myarray", @@ -471,12 +497,14 @@ stubPreparedMessages.set(`console.log('myarray', ['red', 'green', 'blue'])`, new stubPreparedMessages.set(`console.log('myregex', /a.b.c/)`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924610, "type": "log", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ "myregex", @@ -511,12 +539,14 @@ stubPreparedMessages.set(`console.log('myregex', /a.b.c/)`, new ConsoleMessage({ stubPreparedMessages.set(`console.table(['red', 'green', 'blue']);`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924612, "type": "table", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ { @@ -558,12 +588,14 @@ stubPreparedMessages.set(`console.table(['red', 'green', 'blue']);`, new Console stubPreparedMessages.set(`console.log('myobject', {red: 'redValue', green: 'greenValue', blue: 'blueValue'});`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924614, "type": "log", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ "myobject", @@ -624,12 +656,14 @@ stubPreparedMessages.set(`console.log('myobject', {red: 'redValue', green: 'gree stubPreparedMessages.set(`console.debug('debug message');`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924621, "type": "debug", "helperType": null, "level": "debug", + "category": null, "messageText": null, "parameters": [ "debug message" @@ -654,12 +688,14 @@ stubPreparedMessages.set(`console.debug('debug message');`, new ConsoleMessage({ stubPreparedMessages.set(`console.info('info message');`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924625, "type": "info", "helperType": null, "level": "info", + "category": null, "messageText": null, "parameters": [ "info message" @@ -684,12 +720,14 @@ stubPreparedMessages.set(`console.info('info message');`, new ConsoleMessage({ stubPreparedMessages.set(`console.error('error message');`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924628, "type": "error", "helperType": null, "level": "error", + "category": null, "messageText": null, "parameters": [ "error message" @@ -722,12 +760,14 @@ stubPreparedMessages.set(`console.error('error message');`, new ConsoleMessage({ stubPreparedMessages.set(`console.log('mymap')`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924631, "type": "log", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ "mymap", @@ -775,12 +815,14 @@ stubPreparedMessages.set(`console.log('mymap')`, new ConsoleMessage({ stubPreparedMessages.set(`console.log('myset')`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924746, "type": "log", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ "myset", @@ -822,12 +864,14 @@ stubPreparedMessages.set(`console.log('myset')`, new ConsoleMessage({ stubPreparedMessages.set(`console.trace()`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924752, "type": "trace", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [], "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source55\",\"line\":3,\"column\":11},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":[],\"source\":\"console-api\",\"type\":\"trace\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":[{\"columnNumber\":11,\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"functionName\":\"testStacktraceFiltering\",\"lineNumber\":3,\"sourceId\":193},{\"columnNumber\":3,\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"functionName\":\"foo\",\"lineNumber\":6,\"sourceId\":193},{\"columnNumber\":1,\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"functionName\":\"triggerPacket\",\"lineNumber\":9,\"sourceId\":193}]}", @@ -872,12 +916,14 @@ stubPreparedMessages.set(`console.trace()`, new ConsoleMessage({ stubPreparedMessages.set(`console.trace('bar', {'foo': 'bar'}, [1,2,3])`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1538037986659, "type": "trace", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ "bar", @@ -966,12 +1012,14 @@ stubPreparedMessages.set(`console.trace('bar', {'foo': 'bar'}, [1,2,3])`, new Co stubPreparedMessages.set(`console.time('bar')`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924757, "type": "nullMessage", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": null, "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source52\",\"line\":2,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"source\":\"console-api\",\"type\":\"nullMessage\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}", @@ -994,12 +1042,14 @@ stubPreparedMessages.set(`console.time('bar')`, new ConsoleMessage({ stubPreparedMessages.set(`timerAlreadyExists`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924758, "type": "time", "helperType": null, "level": "warn", + "category": null, "messageText": "Timer “bar” already exists.", "parameters": null, "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source59\",\"line\":3,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"warn\",\"messageText\":\"Timer “bar” already exists.\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"time\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}", @@ -1022,12 +1072,14 @@ stubPreparedMessages.set(`timerAlreadyExists`, new ConsoleMessage({ stubPreparedMessages.set(`console.timeLog('bar') - 1`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1526920999996, "type": "timeLog", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ "bar: 1ms" @@ -1052,12 +1104,14 @@ stubPreparedMessages.set(`console.timeLog('bar') - 1`, new ConsoleMessage({ stubPreparedMessages.set(`console.timeLog('bar') - 2`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1526920999996, "type": "timeLog", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ "bar: 1ms", @@ -1107,12 +1161,14 @@ stubPreparedMessages.set(`console.timeLog('bar') - 2`, new ConsoleMessage({ stubPreparedMessages.set(`console.timeEnd('bar')`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924759, "type": "timeEnd", "helperType": null, "level": "log", + "category": null, "messageText": "bar: 1.21ms - timer ended", "parameters": null, "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source59\",\"line\":6,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"bar: 1.21ms - timer ended\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"timeEnd\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}", @@ -1135,12 +1191,14 @@ stubPreparedMessages.set(`console.timeEnd('bar')`, new ConsoleMessage({ stubPreparedMessages.set(`timeEnd.timerDoesntExist`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1526920999998, "type": "timeEnd", "helperType": null, "level": "warn", + "category": null, "messageText": "Timer “bar” doesn’t exist.", "parameters": null, "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source59\",\"line\":7,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"warn\",\"messageText\":\"Timer “bar” doesn’t exist.\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"timeEnd\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}", @@ -1163,12 +1221,14 @@ stubPreparedMessages.set(`timeEnd.timerDoesntExist`, new ConsoleMessage({ stubPreparedMessages.set(`timeLog.timerDoesntExist`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1526920999999, "type": "timeLog", "helperType": null, "level": "warn", + "category": null, "messageText": "Timer “bar” doesn’t exist.", "parameters": null, "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source59\",\"line\":8,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"warn\",\"messageText\":\"Timer “bar” doesn’t exist.\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"timeLog\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}", @@ -1191,12 +1251,14 @@ stubPreparedMessages.set(`timeLog.timerDoesntExist`, new ConsoleMessage({ stubPreparedMessages.set(`console.table('bar')`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924801, "type": "log", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ "bar" @@ -1221,12 +1283,14 @@ stubPreparedMessages.set(`console.table('bar')`, new ConsoleMessage({ stubPreparedMessages.set(`console.table(['a', 'b', 'c'])`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924859, "type": "table", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ { @@ -1268,12 +1332,14 @@ stubPreparedMessages.set(`console.table(['a', 'b', 'c'])`, new ConsoleMessage({ stubPreparedMessages.set(`console.group('bar')`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924863, "type": "startGroup", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ "bar" @@ -1298,12 +1364,14 @@ stubPreparedMessages.set(`console.group('bar')`, new ConsoleMessage({ stubPreparedMessages.set(`console.groupEnd('bar')`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924864, "type": "endGroup", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": null, "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source59\",\"line\":3,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"source\":\"console-api\",\"type\":\"endGroup\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}", @@ -1326,12 +1394,14 @@ stubPreparedMessages.set(`console.groupEnd('bar')`, new ConsoleMessage({ stubPreparedMessages.set(`console.groupCollapsed('foo')`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924870, "type": "startGroupCollapsed", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ "foo" @@ -1356,12 +1426,14 @@ stubPreparedMessages.set(`console.groupCollapsed('foo')`, new ConsoleMessage({ stubPreparedMessages.set(`console.groupEnd('foo')`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924871, "type": "endGroup", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": null, "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source59\",\"line\":3,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"source\":\"console-api\",\"type\":\"endGroup\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}", @@ -1384,12 +1456,14 @@ stubPreparedMessages.set(`console.groupEnd('foo')`, new ConsoleMessage({ stubPreparedMessages.set(`console.group()`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924878, "type": "startGroup", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ "" @@ -1414,12 +1488,14 @@ stubPreparedMessages.set(`console.group()`, new ConsoleMessage({ stubPreparedMessages.set(`console.groupEnd()`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924879, "type": "endGroup", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": null, "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source59\",\"line\":3,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"source\":\"console-api\",\"type\":\"endGroup\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}", @@ -1442,12 +1518,14 @@ stubPreparedMessages.set(`console.groupEnd()`, new ConsoleMessage({ stubPreparedMessages.set(`console.log(%cfoobar)`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924883, "type": "log", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ "foo", @@ -1476,12 +1554,14 @@ stubPreparedMessages.set(`console.log(%cfoobar)`, new ConsoleMessage({ stubPreparedMessages.set(`console.log("%cHello%c|%cWorld")`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1518681614352, "type": "log", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ "Hello", @@ -1512,12 +1592,14 @@ stubPreparedMessages.set(`console.log("%cHello%c|%cWorld")`, new ConsoleMessage( stubPreparedMessages.set(`console.group(%cfoo%cbar)`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924887, "type": "startGroup", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ "foo", @@ -1546,12 +1628,14 @@ stubPreparedMessages.set(`console.group(%cfoo%cbar)`, new ConsoleMessage({ stubPreparedMessages.set(`console.groupEnd(%cfoo%cbar)`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924887, "type": "endGroup", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": null, "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source59\",\"line\":6,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"source\":\"console-api\",\"type\":\"endGroup\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}", @@ -1574,12 +1658,14 @@ stubPreparedMessages.set(`console.groupEnd(%cfoo%cbar)`, new ConsoleMessage({ stubPreparedMessages.set(`console.groupCollapsed(%cfoo%cbaz)`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924892, "type": "startGroupCollapsed", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ "foo", @@ -1608,12 +1694,14 @@ stubPreparedMessages.set(`console.groupCollapsed(%cfoo%cbaz)`, new ConsoleMessag stubPreparedMessages.set(`console.groupEnd(%cfoo%cbaz)`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924893, "type": "endGroup", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": null, "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source59\",\"line\":6,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"source\":\"console-api\",\"type\":\"endGroup\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}", @@ -1636,12 +1724,14 @@ stubPreparedMessages.set(`console.groupEnd(%cfoo%cbaz)`, new ConsoleMessage({ stubPreparedMessages.set(`console.dir({C, M, Y, K})`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1502884924899, "type": "dir", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ { @@ -1707,12 +1797,14 @@ stubPreparedMessages.set(`console.dir({C, M, Y, K})`, new ConsoleMessage({ stubPreparedMessages.set(`console.count | default: 1`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1511365913333, "type": "log", "helperType": null, "level": "log", + "category": null, "messageText": "default: 1", "parameters": null, "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source73\",\"line\":2,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"default: 1\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}", @@ -1735,12 +1827,14 @@ stubPreparedMessages.set(`console.count | default: 1`, new ConsoleMessage({ stubPreparedMessages.set(`console.count | default: 2`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1511365913334, "type": "log", "helperType": null, "level": "log", + "category": null, "messageText": "default: 2", "parameters": null, "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source73\",\"line\":3,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"default: 2\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}", @@ -1763,12 +1857,14 @@ stubPreparedMessages.set(`console.count | default: 2`, new ConsoleMessage({ stubPreparedMessages.set(`console.count | test counter: 1`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1511365913334, "type": "log", "helperType": null, "level": "log", + "category": null, "messageText": "test counter: 1", "parameters": null, "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source73\",\"line\":4,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"test counter: 1\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}", @@ -1791,12 +1887,14 @@ stubPreparedMessages.set(`console.count | test counter: 1`, new ConsoleMessage({ stubPreparedMessages.set(`console.count | test counter: 2`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1511365913334, "type": "log", "helperType": null, "level": "log", + "category": null, "messageText": "test counter: 2", "parameters": null, "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source73\",\"line\":5,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"test counter: 2\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}", @@ -1819,12 +1917,14 @@ stubPreparedMessages.set(`console.count | test counter: 2`, new ConsoleMessage({ stubPreparedMessages.set(`console.count | default: 3`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1511365913334, "type": "log", "helperType": null, "level": "log", + "category": null, "messageText": "default: 3", "parameters": null, "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source73\",\"line\":6,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"default: 3\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}", @@ -1847,12 +1947,14 @@ stubPreparedMessages.set(`console.count | default: 3`, new ConsoleMessage({ stubPreparedMessages.set(`console.count | clear`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1511365913334, "type": "clear", "helperType": null, "level": "log", + "category": null, "messageText": null, "parameters": [ "Console was cleared." @@ -1877,12 +1979,14 @@ stubPreparedMessages.set(`console.count | clear`, new ConsoleMessage({ stubPreparedMessages.set(`console.count | default: 4`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1511365913335, "type": "log", "helperType": null, "level": "log", + "category": null, "messageText": "default: 4", "parameters": null, "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source73\",\"line\":8,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"default: 4\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}", @@ -1905,12 +2009,14 @@ stubPreparedMessages.set(`console.count | default: 4`, new ConsoleMessage({ stubPreparedMessages.set(`console.count | test counter: 3`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1511365913335, "type": "log", "helperType": null, "level": "log", + "category": null, "messageText": "test counter: 3", "parameters": null, "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source73\",\"line\":9,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"test counter: 3\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}", @@ -1933,12 +2039,14 @@ stubPreparedMessages.set(`console.count | test counter: 3`, new ConsoleMessage({ stubPreparedMessages.set(`console.countReset | test counter: 0`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1526920412190, "type": "log", "helperType": null, "level": "log", + "category": null, "messageText": "test counter: 0", "parameters": null, "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source73\",\"line\":10,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"log\",\"messageText\":\"test counter: 0\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}", @@ -1961,12 +2069,14 @@ stubPreparedMessages.set(`console.countReset | test counter: 0`, new ConsoleMess stubPreparedMessages.set(`console.countReset | counterDoesntExist`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "console-api", "timeStamp": 1526920412191, "type": "log", "helperType": null, "level": "warn", + "category": null, "messageText": "Counter “test counter” doesn’t exist.", "parameters": null, "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source73\",\"line\":11,\"column\":13},\"groupId\":null,\"indent\":0,\"level\":\"warn\",\"messageText\":\"Counter “test counter” doesn’t exist.\",\"parameters\":null,\"source\":\"console-api\",\"type\":\"log\",\"userProvidedStyles\":[],\"private\":false,\"stacktrace\":null}", @@ -2008,7 +2118,8 @@ stubPackets.set(`console.log('foobar', 'test')`, { "timeStamp": 1502884924471, "timer": null, "workerType": "none", - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2036,7 +2147,8 @@ stubPackets.set(`console.log(undefined)`, { "timeStamp": 1502884924479, "timer": null, "workerType": "none", - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2062,7 +2174,8 @@ stubPackets.set(`console.warn('danger, will robinson!')`, { "timeStamp": 1502884924487, "timer": null, "workerType": "none", - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2090,7 +2203,8 @@ stubPackets.set(`console.log(NaN)`, { "timeStamp": 1502884924495, "timer": null, "workerType": "none", - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2118,7 +2232,8 @@ stubPackets.set(`console.log(null)`, { "timeStamp": 1502884924501, "timer": null, "workerType": "none", - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2144,7 +2259,8 @@ stubPackets.set(`console.log('鼬')`, { "timeStamp": 1502884924506, "timer": null, "workerType": "none", - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2168,7 +2284,8 @@ stubPackets.set(`console.clear()`, { "timer": null, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2197,7 +2314,8 @@ stubPackets.set(`console.count('bar')`, { "timer": null, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2255,7 +2373,8 @@ stubPackets.set(`console.assert(false, {message: 'foobar'})`, { } ], "workerType": "none", - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2281,7 +2400,8 @@ stubPackets.set(`console.log('hello \nfrom \rthe \"string world!')`, { "timeStamp": 1502884924528, "timer": null, "workerType": "none", - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2307,7 +2427,8 @@ stubPackets.set(`console.log('úṇĩçödê țĕșť')`, { "timeStamp": 1502884924586, "timer": null, "workerType": "none", - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2345,7 +2466,8 @@ stubPackets.set(`console.dirxml(window)`, { "timer": null, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2389,7 +2511,8 @@ stubPackets.set(`console.log('myarray', ['red', 'green', 'blue'])`, { "timeStamp": 1502884924604, "timer": null, "workerType": "none", - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2425,7 +2548,8 @@ stubPackets.set(`console.log('myregex', /a.b.c/)`, { "timeStamp": 1502884924610, "timer": null, "workerType": "none", - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2468,7 +2592,8 @@ stubPackets.set(`console.table(['red', 'green', 'blue']);`, { "timer": null, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2530,7 +2655,8 @@ stubPackets.set(`console.log('myobject', {red: 'redValue', green: 'greenValue', "timeStamp": 1502884924614, "timer": null, "workerType": "none", - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2556,7 +2682,8 @@ stubPackets.set(`console.debug('debug message');`, { "timeStamp": 1502884924621, "timer": null, "workerType": "none", - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2582,7 +2709,8 @@ stubPackets.set(`console.info('info message');`, { "timeStamp": 1502884924625, "timer": null, "workerType": "none", - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2617,7 +2745,8 @@ stubPackets.set(`console.error('error message');`, { } ], "workerType": "none", - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2666,7 +2795,8 @@ stubPackets.set(`console.log('mymap')`, { "timeStamp": 1502884924631, "timer": null, "workerType": "none", - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2709,7 +2839,8 @@ stubPackets.set(`console.log('myset')`, { "timeStamp": 1502884924746, "timer": null, "workerType": "none", - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2756,7 +2887,8 @@ stubPackets.set(`console.trace()`, { ], "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2847,7 +2979,8 @@ stubPackets.set(`console.trace('bar', {'foo': 'bar'}, [1,2,3])`, { ], "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2875,7 +3008,8 @@ stubPackets.set(`console.time('bar')`, { }, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2904,7 +3038,8 @@ stubPackets.set(`timerAlreadyExists`, { }, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2933,7 +3068,8 @@ stubPackets.set(`console.timeLog('bar') - 1`, { }, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -2987,7 +3123,8 @@ stubPackets.set(`console.timeLog('bar') - 2`, { }, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3016,7 +3153,8 @@ stubPackets.set(`console.timeEnd('bar')`, { }, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3045,7 +3183,8 @@ stubPackets.set(`timeEnd.timerDoesntExist`, { }, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3074,7 +3213,8 @@ stubPackets.set(`timeLog.timerDoesntExist`, { }, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3100,7 +3240,8 @@ stubPackets.set(`console.table('bar')`, { "timer": null, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3143,7 +3284,8 @@ stubPackets.set(`console.table(['a', 'b', 'c'])`, { "timer": null, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3169,7 +3311,8 @@ stubPackets.set(`console.group('bar')`, { "timeStamp": 1502884924863, "timer": null, "workerType": "none", - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3193,7 +3336,8 @@ stubPackets.set(`console.groupEnd('bar')`, { "timer": null, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3219,7 +3363,8 @@ stubPackets.set(`console.groupCollapsed('foo')`, { "timeStamp": 1502884924870, "timer": null, "workerType": "none", - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3243,7 +3388,8 @@ stubPackets.set(`console.groupEnd('foo')`, { "timer": null, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3267,7 +3413,8 @@ stubPackets.set(`console.group()`, { "timeStamp": 1502884924878, "timer": null, "workerType": "none", - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3291,7 +3438,8 @@ stubPackets.set(`console.groupEnd()`, { "timer": null, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3321,7 +3469,8 @@ stubPackets.set(`console.log(%cfoobar)`, { "timeStamp": 1502884924883, "timer": null, "workerType": "none", - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3353,7 +3502,8 @@ stubPackets.set(`console.log("%cHello%c|%cWorld")`, { "timeStamp": 1518681614352, "timer": null, "workerType": "none", - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3383,7 +3533,8 @@ stubPackets.set(`console.group(%cfoo%cbar)`, { "timeStamp": 1502884924887, "timer": null, "workerType": "none", - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3407,7 +3558,8 @@ stubPackets.set(`console.groupEnd(%cfoo%cbar)`, { "timer": null, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3437,7 +3589,8 @@ stubPackets.set(`console.groupCollapsed(%cfoo%cbaz)`, { "timeStamp": 1502884924892, "timer": null, "workerType": "none", - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3461,7 +3614,8 @@ stubPackets.set(`console.groupEnd(%cfoo%cbaz)`, { "timer": null, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3528,7 +3682,8 @@ stubPackets.set(`console.dir({C, M, Y, K})`, { "timer": null, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3557,7 +3712,8 @@ stubPackets.set(`console.count | default: 1`, { "timer": null, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3586,7 +3742,8 @@ stubPackets.set(`console.count | default: 2`, { "timer": null, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3615,7 +3772,8 @@ stubPackets.set(`console.count | test counter: 1`, { "timer": null, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3644,7 +3802,8 @@ stubPackets.set(`console.count | test counter: 2`, { "timer": null, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3673,7 +3832,8 @@ stubPackets.set(`console.count | default: 3`, { "timer": null, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3697,7 +3857,8 @@ stubPackets.set(`console.count | clear`, { "timer": null, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3726,7 +3887,8 @@ stubPackets.set(`console.count | default: 4`, { "timer": null, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3755,7 +3917,8 @@ stubPackets.set(`console.count | test counter: 3`, { "timer": null, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3784,7 +3947,8 @@ stubPackets.set(`console.countReset | test counter: 0`, { "timer": null, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" @@ -3813,7 +3977,8 @@ stubPackets.set(`console.countReset | counterDoesntExist`, { "timer": null, "workerType": "none", "styles": [], - "category": "webdev" + "category": "webdev", + "innerWindowID": 10737418243 }, "type": "consoleAPICall", "from": "server1.conn0.child1/consoleActor2" diff --git a/devtools/client/webconsole/test/fixtures/stubs/cssMessage.js b/devtools/client/webconsole/test/fixtures/stubs/cssMessage.js index 74b48d40f939..8e50a1e3e273 100644 --- a/devtools/client/webconsole/test/fixtures/stubs/cssMessage.js +++ b/devtools/client/webconsole/test/fixtures/stubs/cssMessage.js @@ -15,12 +15,14 @@ const stubPreparedMessages = new Map(); const stubPackets = new Map(); stubPreparedMessages.set(`Unknown property ‘such-unknown-property’. Declaration dropped.`, new ConsoleMessage({ "id": "1", + "innerWindowID": 15032385539, "allowRepeating": true, "source": "css", "timeStamp": 1479159920406, "type": "log", "helperType": null, "level": "warn", + "category": "CSS Parser", "messageText": "Unknown property ‘such-unknown-property’. Declaration dropped.", "parameters": null, "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-css-message.html\",\"sourceId\":null,\"line\":3,\"column\":25},\"groupId\":null,\"indent\":0,\"level\":\"warn\",\"messageText\":\"Unknown property ‘such-unknown-property’. Declaration dropped.\",\"parameters\":null,\"source\":\"css\",\"type\":\"log\",\"userProvidedStyles\":null,\"private\":false,\"stacktrace\":null}", @@ -42,12 +44,14 @@ stubPreparedMessages.set(`Unknown property ‘such-unknown-property’. Declara stubPreparedMessages.set(`Error in parsing value for ‘padding-top’. Declaration dropped.`, new ConsoleMessage({ "id": "1", + "innerWindowID": 15032385539, "allowRepeating": true, "source": "css", "timeStamp": 1479159920465, "type": "log", "helperType": null, "level": "warn", + "category": "CSS Parser", "messageText": "Error in parsing value for ‘padding-top’. Declaration dropped.", "parameters": null, "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-css-message.html\",\"sourceId\":null,\"line\":3,\"column\":16},\"groupId\":null,\"indent\":0,\"level\":\"warn\",\"messageText\":\"Error in parsing value for ‘padding-top’. Declaration dropped.\",\"parameters\":null,\"source\":\"css\",\"type\":\"log\",\"userProvidedStyles\":null,\"private\":false,\"stacktrace\":null}", @@ -77,6 +81,7 @@ stubPackets.set(`Unknown property ‘such-unknown-property’. Declaration drop "lineNumber": 3, "columnNumber": 25, "category": "CSS Parser", + "innerWindowID": 15032385539, "timeStamp": 1479159920406, "warning": true, "error": false, @@ -101,6 +106,7 @@ stubPackets.set(`Error in parsing value for ‘padding-top’. Declaration drop "lineNumber": 3, "columnNumber": 16, "category": "CSS Parser", + "innerWindowID": 15032385539, "timeStamp": 1479159920465, "warning": true, "error": false, diff --git a/devtools/client/webconsole/test/fixtures/stubs/evaluationResult.js b/devtools/client/webconsole/test/fixtures/stubs/evaluationResult.js index ef038a37a450..9b8c34029c51 100644 --- a/devtools/client/webconsole/test/fixtures/stubs/evaluationResult.js +++ b/devtools/client/webconsole/test/fixtures/stubs/evaluationResult.js @@ -15,12 +15,14 @@ const stubPreparedMessages = new Map(); const stubPackets = new Map(); stubPreparedMessages.set(`new Date(0)`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "javascript", "timeStamp": 1479159921364, "type": "result", "helperType": null, "level": "log", + "category": null, "parameters": [ { "type": "object", @@ -47,12 +49,14 @@ stubPreparedMessages.set(`new Date(0)`, new ConsoleMessage({ stubPreparedMessages.set(`asdf()`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "javascript", "timeStamp": 1479159921377, "type": "result", "helperType": null, "level": "error", + "category": null, "messageText": "ReferenceError: asdf is not defined", "parameters": [ { @@ -77,12 +81,14 @@ stubPreparedMessages.set(`asdf()`, new ConsoleMessage({ stubPreparedMessages.set(`1 + @`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "javascript", "timeStamp": 1479159921399, "type": "result", "helperType": null, "level": "error", + "category": null, "messageText": "SyntaxError: illegal character", "parameters": [ { @@ -107,12 +113,14 @@ stubPreparedMessages.set(`1 + @`, new ConsoleMessage({ stubPreparedMessages.set(`inspect({a: 1})`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "javascript", "timeStamp": 1499776070751, "type": "result", "helperType": "inspectObject", "level": "log", + "category": null, "parameters": [ { "type": "object", @@ -151,12 +159,14 @@ stubPreparedMessages.set(`inspect({a: 1})`, new ConsoleMessage({ stubPreparedMessages.set(`cd(document)`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "javascript", "timeStamp": 1510650094657, "type": "result", "helperType": "error", "level": "error", + "category": null, "messageText": "Cannot cd() to the given window. Invalid argument.", "parameters": [ { @@ -175,12 +185,14 @@ stubPreparedMessages.set(`cd(document)`, new ConsoleMessage({ stubPreparedMessages.set(`undefined`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "javascript", "timeStamp": 1518606917356, "type": "result", "helperType": null, "level": "log", + "category": null, "parameters": [ { "type": "undefined" @@ -198,12 +210,14 @@ stubPreparedMessages.set(`undefined`, new ConsoleMessage({ stubPreparedMessages.set(`longString message Error`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "javascript", "timeStamp": 1493108241073, "type": "result", "helperType": null, "level": "error", + "category": null, "messageText": { "type": "longString", "initial": "Error: Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Lon", @@ -227,12 +241,14 @@ stubPreparedMessages.set(`longString message Error`, new ConsoleMessage({ stubPreparedMessages.set(`eval throw ""`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "javascript", "timeStamp": 1517990289517, "type": "result", "helperType": null, "level": "error", + "category": null, "messageText": "Error", "parameters": [ { @@ -251,12 +267,14 @@ stubPreparedMessages.set(`eval throw ""`, new ConsoleMessage({ stubPreparedMessages.set(`eval throw "tomato"`, new ConsoleMessage({ "id": "1", + "innerWindowID": null, "allowRepeating": true, "source": "javascript", "timeStamp": 1517990289520, "type": "result", "helperType": null, "level": "error", + "category": null, "messageText": "Error: tomato", "parameters": [ { diff --git a/devtools/client/webconsole/test/fixtures/stubs/pageError.js b/devtools/client/webconsole/test/fixtures/stubs/pageError.js index cf9a24a316c8..52f258123a68 100644 --- a/devtools/client/webconsole/test/fixtures/stubs/pageError.js +++ b/devtools/client/webconsole/test/fixtures/stubs/pageError.js @@ -15,12 +15,14 @@ const stubPreparedMessages = new Map(); const stubPackets = new Map(); stubPreparedMessages.set(`ReferenceError: asdf is not defined`, new ConsoleMessage({ "id": "1", + "innerWindowID": 6442450949, "allowRepeating": true, "source": "javascript", "timeStamp": 1476573167137, "type": "log", "helperType": null, "level": "error", + "category": "content javascript", "messageText": "ReferenceError: asdf is not defined", "parameters": null, "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":null,\"line\":3,\"column\":5},\"groupId\":null,\"indent\":0,\"level\":\"error\",\"messageText\":\"ReferenceError: asdf is not defined\",\"parameters\":null,\"source\":\"javascript\",\"type\":\"log\",\"userProvidedStyles\":null,\"private\":false,\"stacktrace\":[{\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source25\",\"lineNumber\":3,\"columnNumber\":5,\"functionName\":\"bar\"},{\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source25\",\"lineNumber\":6,\"columnNumber\":5,\"functionName\":\"foo\"},{\"filename\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":\"server1.conn0.child1/source25\",\"lineNumber\":9,\"columnNumber\":3,\"functionName\":null},{\"filename\":\"resource://testing-common/content-task.js line 59 > eval\",\"sourceId\":null,\"lineNumber\":7,\"columnNumber\":31,\"functionName\":null},{\"filename\":\"resource://testing-common/content-task.js\",\"sourceId\":null,\"lineNumber\":60,\"columnNumber\":29,\"functionName\":null}]}", @@ -79,12 +81,14 @@ stubPreparedMessages.set(`ReferenceError: asdf is not defined`, new ConsoleMessa stubPreparedMessages.set(`SyntaxError: redeclaration of let a`, new ConsoleMessage({ "id": "1", + "innerWindowID": 6442450949, "allowRepeating": true, "source": "javascript", "timeStamp": 1487992945524, "type": "log", "helperType": null, "level": "error", + "category": "content javascript", "messageText": "SyntaxError: redeclaration of let a", "parameters": null, "repeatId": "{\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/test-console-api.html\",\"sourceId\":null,\"line\":2,\"column\":9},\"groupId\":null,\"indent\":0,\"level\":\"error\",\"messageText\":\"SyntaxError: redeclaration of let a\",\"parameters\":null,\"source\":\"javascript\",\"type\":\"log\",\"userProvidedStyles\":null,\"private\":false,\"stacktrace\":[{\"filename\":\"resource://testing-common/content-task.js line 59 > eval\",\"sourceId\":null,\"lineNumber\":7,\"columnNumber\":31,\"functionName\":null},{\"filename\":\"resource://testing-common/content-task.js\",\"sourceId\":null,\"lineNumber\":60,\"columnNumber\":29,\"functionName\":null}]}", @@ -132,12 +136,14 @@ stubPreparedMessages.set(`SyntaxError: redeclaration of let a`, new ConsoleMessa stubPreparedMessages.set(`TypeError longString message`, new ConsoleMessage({ "id": "1", + "innerWindowID": 6442450949, "allowRepeating": true, "source": "javascript", "timeStamp": 1493109507061, "type": "log", "helperType": null, "level": "error", + "category": "content javascript", "messageText": { "type": "longString", "initial": "Error: Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Lon", @@ -186,12 +192,14 @@ stubPreparedMessages.set(`TypeError longString message`, new ConsoleMessage({ stubPreparedMessages.set(`throw ""`, new ConsoleMessage({ "id": "1", + "innerWindowID": 6442450949, "allowRepeating": true, "source": "javascript", "timeStamp": 1517942398629, "type": "log", "helperType": null, "level": "error", + "category": "content javascript", "messageText": "uncaught exception: ", "parameters": null, "repeatId": "{\"frame\":null,\"groupId\":null,\"indent\":0,\"level\":\"error\",\"messageText\":\"uncaught exception: \",\"parameters\":null,\"source\":\"javascript\",\"type\":\"log\",\"userProvidedStyles\":null,\"private\":false,\"stacktrace\":null}", @@ -208,12 +216,14 @@ stubPreparedMessages.set(`throw ""`, new ConsoleMessage({ stubPreparedMessages.set(`throw "tomato"`, new ConsoleMessage({ "id": "1", + "innerWindowID": 6442450949, "allowRepeating": true, "source": "javascript", "timeStamp": 1517942398637, "type": "log", "helperType": null, "level": "error", + "category": "content javascript", "messageText": "uncaught exception: tomato", "parameters": null, "repeatId": "{\"frame\":null,\"groupId\":null,\"indent\":0,\"level\":\"error\",\"messageText\":\"uncaught exception: tomato\",\"parameters\":null,\"source\":\"javascript\",\"type\":\"log\",\"userProvidedStyles\":null,\"private\":false,\"stacktrace\":null}", @@ -239,6 +249,7 @@ stubPackets.set(`ReferenceError: asdf is not defined`, { "lineNumber": 3, "columnNumber": 5, "category": "content javascript", + "innerWindowID": 6442450949, "timeStamp": 1476573167137, "warning": false, "error": false, @@ -300,6 +311,7 @@ stubPackets.set(`SyntaxError: redeclaration of let a`, { "lineNumber": 2, "columnNumber": 9, "category": "content javascript", + "innerWindowID": 6442450949, "timeStamp": 1487992945524, "warning": false, "error": false, @@ -354,6 +366,7 @@ stubPackets.set(`TypeError longString message`, { "lineNumber": 1, "columnNumber": 7, "category": "content javascript", + "innerWindowID": 6442450949, "timeStamp": 1493109507061, "warning": false, "error": false, @@ -400,6 +413,7 @@ stubPackets.set(`throw ""`, { "lineNumber": 0, "columnNumber": 0, "category": "content javascript", + "innerWindowID": 6442450949, "timeStamp": 1517942398629, "warning": false, "error": false, @@ -424,6 +438,7 @@ stubPackets.set(`throw "tomato"`, { "lineNumber": 0, "columnNumber": 0, "category": "content javascript", + "innerWindowID": 6442450949, "timeStamp": 1517942398637, "warning": false, "error": false, diff --git a/devtools/client/webconsole/types.js b/devtools/client/webconsole/types.js index f4dd16216a4c..c3b69c9fd1bd 100644 --- a/devtools/client/webconsole/types.js +++ b/devtools/client/webconsole/types.js @@ -29,12 +29,14 @@ exports.ConsoleCommand = function(props) { exports.ConsoleMessage = function(props) { return Object.assign({ id: null, + innerWindowID: null, allowRepeating: true, source: null, timeStamp: null, type: null, helperType: null, level: null, + category: null, messageText: null, parameters: null, repeatId: null, diff --git a/devtools/client/webconsole/utils/messages.js b/devtools/client/webconsole/utils/messages.js index e8c269d6ce17..c4c729396344 100644 --- a/devtools/client/webconsole/utils/messages.js +++ b/devtools/client/webconsole/utils/messages.js @@ -245,9 +245,11 @@ function transformPageErrorPacket(packet) { const messageSource = matchesCSS ? MESSAGE_SOURCE.CSS : MESSAGE_SOURCE.JAVASCRIPT; return new ConsoleMessage({ + innerWindowID: pageError.innerWindowID, source: messageSource, type: MESSAGE_TYPE.LOG, level, + category: pageError.category, messageText: pageError.errorMessage, stacktrace: pageError.stacktrace ? pageError.stacktrace : null, frame, diff --git a/devtools/server/actors/webconsole.js b/devtools/server/actors/webconsole.js index dbfc5f206478..7356c61d4383 100644 --- a/devtools/server/actors/webconsole.js +++ b/devtools/server/actors/webconsole.js @@ -1519,6 +1519,7 @@ WebConsoleActor.prototype = lineNumber: pageError.lineNumber, columnNumber: pageError.columnNumber, category: pageError.category, + innerWindowID: pageError.innerWindowID, timeStamp: pageError.timeStamp, warning: !!(pageError.flags & pageError.warningFlag), error: !!(pageError.flags & pageError.errorFlag), @@ -1717,6 +1718,7 @@ WebConsoleActor.prototype = }); result.category = message.category || "webdev"; + result.innerWindowID = message.innerID; return result; }, From b2556ed8a4bf11b145c135e5de4f341a664afe31 Mon Sep 17 00:00:00 2001 From: Nicolas Chevobbe Date: Fri, 29 Mar 2019 08:03:34 +0000 Subject: [PATCH 010/100] Bug 1524276 - Add groupWarnings preference in console redux state. r=bgrins. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will be used to enable groups of warning messages (Tracking Protection, CSP, CORS, …). Differential Revision: https://phabricator.services.mozilla.com/D23550 --HG-- extra : moz-landing-system : lando --- devtools/client/webconsole/constants.js | 1 + devtools/client/webconsole/reducers/prefs.js | 1 + devtools/client/webconsole/store.js | 2 ++ devtools/client/webconsole/test/mocha-test-setup.js | 2 ++ 4 files changed, 6 insertions(+) diff --git a/devtools/client/webconsole/constants.js b/devtools/client/webconsole/constants.js index 29cbffdc5f07..14b1b523360a 100644 --- a/devtools/client/webconsole/constants.js +++ b/devtools/client/webconsole/constants.js @@ -73,6 +73,7 @@ const prefs = { SIDEBAR_TOGGLE: "devtools.webconsole.sidebarToggle", JSTERM_CODE_MIRROR: "devtools.webconsole.jsterm.codeMirror", AUTOCOMPLETE: "devtools.webconsole.input.autocomplete", + GROUP_WARNINGS: "devtools.webconsole.groupWarningMessages", }, }, }; diff --git a/devtools/client/webconsole/reducers/prefs.js b/devtools/client/webconsole/reducers/prefs.js index 796d8185bf26..28998bac08e0 100644 --- a/devtools/client/webconsole/reducers/prefs.js +++ b/devtools/client/webconsole/reducers/prefs.js @@ -9,6 +9,7 @@ const PrefState = (overrides) => Object.freeze(Object.assign({ logLimit: 1000, sidebarToggle: false, jstermCodeMirror: false, + groupWarnings: false, historyCount: 50, }, overrides)); diff --git a/devtools/client/webconsole/store.js b/devtools/client/webconsole/store.js index 62d5b2c4aa87..09b8acf399b7 100644 --- a/devtools/client/webconsole/store.js +++ b/devtools/client/webconsole/store.js @@ -50,6 +50,7 @@ function configureStore(webConsoleUI, options = {}) { const sidebarToggle = getBoolPref(PREFS.FEATURES.SIDEBAR_TOGGLE); const jstermCodeMirror = getBoolPref(PREFS.FEATURES.JSTERM_CODE_MIRROR); const autocomplete = getBoolPref(PREFS.FEATURES.AUTOCOMPLETE); + const groupWarnings = getBoolPref(PREFS.FEATURES.GROUP_WARNINGS); const historyCount = getIntPref(PREFS.UI.INPUT_HISTORY_COUNT); const initialState = { @@ -59,6 +60,7 @@ function configureStore(webConsoleUI, options = {}) { jstermCodeMirror, autocomplete, historyCount, + groupWarnings, }), filters: FilterState({ error: getBoolPref(PREFS.FILTER.ERROR), diff --git a/devtools/client/webconsole/test/mocha-test-setup.js b/devtools/client/webconsole/test/mocha-test-setup.js index c6eeb70621d8..2f45c8ad08d6 100644 --- a/devtools/client/webconsole/test/mocha-test-setup.js +++ b/devtools/client/webconsole/test/mocha-test-setup.js @@ -24,6 +24,8 @@ pref("devtools.webconsole.persistlog", false); pref("devtools.webconsole.timestampMessages", false); pref("devtools.webconsole.sidebarToggle", true); pref("devtools.webconsole.jsterm.codeMirror", true); +pref("devtools.webconsole.groupWarningMessages", false); +pref("devtools.webconsole.input.editor", false); global.loader = { lazyServiceGetter: () => {}, From 48e44d1ff17a81c17e3c27f9b8f84117e941076c Mon Sep 17 00:00:00 2001 From: Nicolas Chevobbe Date: Fri, 29 Mar 2019 08:03:59 +0000 Subject: [PATCH 011/100] Bug 1524276 - Add WarningGroup message component. r=bgrins. This component will be used to render warning groups messages. We also add a `inWarningGroup` prop to the `Message` component so warnings that will be displayed in such warningGroup can be styled differently (no warning icon, a different color for the indent). Add some utils functions and constants to check if a message should be a warning group. Differential Revision: https://phabricator.services.mozilla.com/D23551 --HG-- extra : moz-landing-system : lando --- devtools/client/themes/webconsole.css | 21 +++++- .../client/webconsole/components/Message.js | 21 +++++- .../webconsole/components/MessageContainer.js | 11 +++ .../webconsole/components/MessageIndent.js | 15 ++-- .../components/message-types/PageError.js | 6 +- .../components/message-types/WarningGroup.js | 73 +++++++++++++++++++ .../components/message-types/moz.build | 1 + devtools/client/webconsole/constants.js | 6 ++ .../test/components/warning-group.test.js | 56 ++++++++++++++ devtools/client/webconsole/utils/messages.js | 12 +++ 10 files changed, 209 insertions(+), 13 deletions(-) create mode 100644 devtools/client/webconsole/components/message-types/WarningGroup.js create mode 100644 devtools/client/webconsole/test/components/warning-group.test.js diff --git a/devtools/client/themes/webconsole.css b/devtools/client/themes/webconsole.css index aee8d37566a4..a88d5e927b54 100644 --- a/devtools/client/themes/webconsole.css +++ b/devtools/client/themes/webconsole.css @@ -160,6 +160,10 @@ a { border-inline-end: solid 1px var(--console-output-indent-border-color); } +.message > .indent.warning-indent { + border-inline-end-color: var(--warning-color); +} + .message > .indent[data-indent="0"] { display: none; } @@ -249,23 +253,34 @@ a { } /* The bubble that shows the number of times a message is repeated */ -.message-repeats { +.message-repeats, +.warning-group-badge { flex-shrink: 0; margin: 2px 5px 0 5px; padding: 0 6px; height: 1.25em; - color: white; - background-color: var(--repeat-bubble-background-color); border-radius: 40px; font: message-box; font-size: 0.8em; font-weight: normal; } +.message-repeats { + display: inline-block; + color: white; + background-color: var(--repeat-bubble-background-color); +} + .message-repeats[value="1"] { display: none; } +.warning-group-badge { + display: inline-block; + color: var(--warning-background-color); + background-color: var(--warning-color); +} + .message-location { max-width: 40vw; flex-shrink: 0; diff --git a/devtools/client/webconsole/components/Message.js b/devtools/client/webconsole/components/Message.js index 86d7854aff1d..003dc8651857 100644 --- a/devtools/client/webconsole/components/Message.js +++ b/devtools/client/webconsole/components/Message.js @@ -31,6 +31,7 @@ class Message extends Component { type: PropTypes.string.isRequired, level: PropTypes.string.isRequired, indent: PropTypes.number.isRequired, + inWarningGroup: PropTypes.bool, topLevelClasses: PropTypes.array.isRequired, messageBody: PropTypes.any.isRequired, repeat: PropTypes.any, @@ -131,7 +132,17 @@ class Message extends Component { } renderIcon() { - const { level, messageId, executionPoint, serviceContainer } = this.props; + const { + level, + messageId, + executionPoint, + serviceContainer, + inWarningGroup, + } = this.props; + + if (inWarningGroup) { + return undefined; + } return MessageIcon({ level, @@ -151,6 +162,7 @@ class Message extends Component { isPaused, level, indent, + inWarningGroup, topLevelClasses, messageBody, frame, @@ -301,7 +313,10 @@ class Message extends Component { "aria-live": type === MESSAGE_TYPE.COMMAND ? "off" : "polite", }, timestampEl, - MessageIndent({indent}), + MessageIndent({ + indent, + inWarningGroup, + }), icon, collapse, dom.span({ className: "message-body-wrapper" }, @@ -313,7 +328,7 @@ class Message extends Component { timestampEl ? " " : null, dom.span({ className: "message-body devtools-monospace" }, ...bodyElements, - learnMore + learnMore, ), repeat ? " " : null, repeat, diff --git a/devtools/client/webconsole/components/MessageContainer.js b/devtools/client/webconsole/components/MessageContainer.js index 42a59f296ba6..b220984897a0 100644 --- a/devtools/client/webconsole/components/MessageContainer.js +++ b/devtools/client/webconsole/components/MessageContainer.js @@ -9,6 +9,7 @@ // React & Redux const { Component } = require("devtools/client/shared/vendor/react"); loader.lazyRequireGetter(this, "PropTypes", "devtools/client/shared/vendor/react-prop-types"); +loader.lazyRequireGetter(this, "isWarningGroup", "devtools/client/webconsole/utils/messages", true); const { MESSAGE_SOURCE, @@ -22,6 +23,7 @@ const componentMap = new Map([ ["EvaluationResult", require("./message-types/EvaluationResult")], ["NetworkEventMessage", require("./message-types/NetworkEventMessage")], ["PageError", require("./message-types/PageError")], + ["WarningGroup", require("./message-types/WarningGroup")], ]); class MessageContainer extends Component { @@ -33,6 +35,8 @@ class MessageContainer extends Component { tableData: PropTypes.object, timestampsVisible: PropTypes.bool.isRequired, repeat: PropTypes.number, + badge: PropTypes.number, + indent: PropTypes.number, networkMessageUpdate: PropTypes.object, getMessage: PropTypes.func.isRequired, isPaused: PropTypes.bool.isRequired, @@ -57,8 +61,10 @@ class MessageContainer extends Component { const pausedChanged = this.props.isPaused !== nextProps.isPaused; const executionPointChanged = this.props.pausedExecutionPoint !== nextProps.pausedExecutionPoint; + const badgeChanged = this.props.badge !== nextProps.badge; return repeatChanged + || badgeChanged || openChanged || tableDataChanged || timestampVisibleChanged @@ -101,6 +107,11 @@ function getMessageComponent(message) { default: return componentMap.get("DefaultRenderer"); } + case MESSAGE_SOURCE.CONSOLE_FRONTEND: + if (isWarningGroup(message)) { + return componentMap.get("WarningGroup"); + } + break; } return componentMap.get("DefaultRenderer"); diff --git a/devtools/client/webconsole/components/MessageIndent.js b/devtools/client/webconsole/components/MessageIndent.js index c070ced474d7..2c208776e616 100644 --- a/devtools/client/webconsole/components/MessageIndent.js +++ b/devtools/client/webconsole/components/MessageIndent.js @@ -10,14 +10,14 @@ const dom = require("devtools/client/shared/vendor/react-dom-factories"); const INDENT_WIDTH = 12; -// Store common indents so they can be used without recreating the element -// during render. +// Store common indents so they can be used without recreating the element during render. const CONSTANT_INDENTS = [getIndentElement(0), getIndentElement(1)]; +const IN_WARNING_GROUP_INDENT = getIndentElement(1, "warning-indent"); -function getIndentElement(indent) { +function getIndentElement(indent, className) { return dom.span({ "data-indent": indent, - className: "indent", + className: `indent${className ? " " + className : ""}`, style: { "width": indent * INDENT_WIDTH, }, @@ -25,7 +25,12 @@ function getIndentElement(indent) { } function MessageIndent(props) { - const { indent } = props; + const { indent, inWarningGroup } = props; + + if (inWarningGroup) { + return IN_WARNING_GROUP_INDENT; + } + return CONSTANT_INDENTS[indent] || getIndentElement(indent); } diff --git a/devtools/client/webconsole/components/message-types/PageError.js b/devtools/client/webconsole/components/message-types/PageError.js index 71dfed37f4fb..ee75558b23e6 100644 --- a/devtools/client/webconsole/components/message-types/PageError.js +++ b/devtools/client/webconsole/components/message-types/PageError.js @@ -19,6 +19,7 @@ PageError.propTypes = { timestampsVisible: PropTypes.bool.isRequired, serviceContainer: PropTypes.object, maybeScrollToBottom: PropTypes.func, + inWarningGroup: PropTypes.bool.isRequired, }; PageError.defaultProps = { @@ -35,11 +36,11 @@ function PageError(props) { timestampsVisible, isPaused, maybeScrollToBottom, + inWarningGroup, } = props; const { id: messageId, executionPoint, - indent, source, type, level, @@ -69,7 +70,8 @@ function PageError(props) { type, level, topLevelClasses: [], - indent, + indent: message.indent, + inWarningGroup, messageBody, repeat, frame, diff --git a/devtools/client/webconsole/components/message-types/WarningGroup.js b/devtools/client/webconsole/components/message-types/WarningGroup.js new file mode 100644 index 000000000000..24ddce25e2a8 --- /dev/null +++ b/devtools/client/webconsole/components/message-types/WarningGroup.js @@ -0,0 +1,73 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* 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/. */ + +"use strict"; + +// React & Redux +const { createFactory } = require("devtools/client/shared/vendor/react"); +const dom = require("devtools/client/shared/vendor/react-dom-factories"); + +const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); +const Message = createFactory(require("devtools/client/webconsole/components/Message")); + +WarningGroup.displayName = "WarningGroup"; + +WarningGroup.propTypes = { + dispatch: PropTypes.func.isRequired, + message: PropTypes.object.isRequired, + timestampsVisible: PropTypes.bool.isRequired, + serviceContainer: PropTypes.object, + badge: PropTypes.number.isRequired, +}; + +function WarningGroup(props) { + const { + dispatch, + message, + serviceContainer, + timestampsVisible, + badge, + open, + } = props; + + const { + source, + type, + level, + id: messageId, + indent, + timeStamp, + } = message; + + const messageBody = [ + message.messageText, + " ", + dom.span({ + className: "warning-group-badge", + title: `${badge} messages`, + }, badge), + ]; + const topLevelClasses = ["cm-s-mozilla"]; + + return Message({ + badge, + collapsible: true, + dispatch, + indent, + level, + messageBody, + messageId, + open, + serviceContainer, + source, + timeStamp, + timestampsVisible, + topLevelClasses, + type, + }); +} + +module.exports = WarningGroup; diff --git a/devtools/client/webconsole/components/message-types/moz.build b/devtools/client/webconsole/components/message-types/moz.build index fd82d99333d1..6ce7ae7dc6b1 100644 --- a/devtools/client/webconsole/components/message-types/moz.build +++ b/devtools/client/webconsole/components/message-types/moz.build @@ -10,4 +10,5 @@ DevToolsModules( 'EvaluationResult.js', 'NetworkEventMessage.js', 'PageError.js', + 'WarningGroup.js', ) diff --git a/devtools/client/webconsole/constants.js b/devtools/client/webconsole/constants.js index 14b1b523360a..4622ca9c4879 100644 --- a/devtools/client/webconsole/constants.js +++ b/devtools/client/webconsole/constants.js @@ -112,6 +112,9 @@ const chromeRDPEnums = { JAVASCRIPT: "javascript", NETWORK: "network", CONSOLE_API: "console-api", + // Messages emitted by the console frontend itself (i.e. similar messages grouping + // header). + CONSOLE_FRONTEND: "console-frontend", STORAGE: "storage", APPCACHE: "appcache", RENDERING: "rendering", @@ -128,6 +131,9 @@ const chromeRDPEnums = { START_GROUP: "startGroup", START_GROUP_COLLAPSED: "startGroupCollapsed", END_GROUP: "endGroup", + CONTENT_BLOCKING_GROUP: "contentBlockingWarningGroup", + CORS_GROUP: "CORSWarningGroup", + CSP_GROUP: "CSPWarningGroup", ASSERT: "assert", DEBUG: "debug", PROFILE: "profile", diff --git a/devtools/client/webconsole/test/components/warning-group.test.js b/devtools/client/webconsole/test/components/warning-group.test.js new file mode 100644 index 000000000000..3bae02c68624 --- /dev/null +++ b/devtools/client/webconsole/test/components/warning-group.test.js @@ -0,0 +1,56 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +// Test utils. +const expect = require("expect"); +const { render } = require("enzyme"); + +// Components under test. +const WarningGroup = require("devtools/client/webconsole/components/message-types/WarningGroup"); +const { MESSAGE_SOURCE } = require("devtools/client/webconsole/constants"); +const { ConsoleMessage } = require("devtools/client/webconsole/types"); + +// Test fakes. +const serviceContainer = require("devtools/client/webconsole/test/fixtures/serviceContainer"); +const message = ConsoleMessage({ + messageText: "this is a warning group", + source: MESSAGE_SOURCE.CONSOLE_FRONTEND, + timeStamp: Date.now(), +}); + +describe("WarningGroup component:", () => { + it("renders", () => { + const wrapper = render(WarningGroup({ + message, + serviceContainer, + timestampsVisible: true, + badge: 42, + })); + + const { timestampString } = require("devtools/client/webconsole/webconsole-l10n"); + expect(wrapper.find(".timestamp").text()).toBe(timestampString(message.timeStamp)); + expect(wrapper.find(".message-body").text()).toBe("this is a warning group 42"); + expect(wrapper.find(".arrow[aria-expanded=false]")).toExist(); + }); + + it("does have an expanded arrow when `open` prop is true", () => { + const wrapper = render(WarningGroup({ + message, + serviceContainer, + open: true, + })); + + expect(wrapper.find(".arrow[aria-expanded=true]")).toExist(); + }); + + it("does not have a timestamp when timestampsVisible prop is falsy", () => { + const wrapper = render(WarningGroup({ + message, + serviceContainer, + timestampsVisible: false, + })); + + expect(wrapper.find(".timestamp").length).toBe(0); + }); +}); diff --git a/devtools/client/webconsole/utils/messages.js b/devtools/client/webconsole/utils/messages.js index c4c729396344..f1c74a82a247 100644 --- a/devtools/client/webconsole/utils/messages.js +++ b/devtools/client/webconsole/utils/messages.js @@ -430,10 +430,22 @@ function isPacketPrivate(packet) { ); } +/** + * Returns true if the message is a warningGroup message (i.e. the "Header"). + * @param {ConsoleMessage} message + * @returns {Boolean} + */ +function isWarningGroup(message) { + return message.type === MESSAGE_TYPE.TRACKING_PROTECTION_GROUP + || message.type === MESSAGE_TYPE.CORS_GROUP + || message.type === MESSAGE_TYPE.CSP_GROUP; +} + module.exports = { getInitialMessageCountForViewport, isGroupType, isPacketPrivate, + isWarningGroup, l10n, prepareMessage, // Export for use in testing. From 8997da599c8e66da37046a1fad6259b3437994c8 Mon Sep 17 00:00:00 2001 From: Nicolas Chevobbe Date: Fri, 29 Mar 2019 08:04:24 +0000 Subject: [PATCH 012/100] Bug 1524276 - Group content blocking messages. r=bgrins,Honza. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If there's at least 2 content blocking messages displayed for a given page navigation, we display a warning group containing the messages, collapsed by default. This means we need to move or insert those warning messages at the right position in visibleMessages, either when they're added, or when we expand a group. Two mochitest are added to make sure this works as expected, one for generic warningGroup features (expanding, group per navigation session, …), and another one specifically for content blocking warning group, where we check that every type of content blocking message can be grouped. The grouping won't occur unless the groupWarnings preferences is on. Differential Revision: https://phabricator.services.mozilla.com/D23552 --HG-- extra : moz-landing-system : lando --- .../locales/en-US/webconsole.properties | 5 + .../webconsole/components/ConsoleOutput.js | 14 + .../client/webconsole/reducers/messages.js | 192 ++++++++++++-- .../client/webconsole/selectors/messages.js | 17 ++ .../test/components/warning-group.test.js | 31 ++- .../client/webconsole/test/fixtures/L10n.js | 2 + .../webconsole/test/mochitest/browser.ini | 3 + ...er_webconsole_trackingprotection_errors.js | 8 - ...bconsole_warning_group_content_blocking.js | 194 ++++++++++++++ .../browser_webconsole_warning_groups.js | 241 ++++++++++++++++++ .../client/webconsole/test/mochitest/head.js | 57 +++++ .../test/mochitest/test-warning-groups.html | 28 ++ devtools/client/webconsole/utils/messages.js | 59 ++++- 13 files changed, 812 insertions(+), 39 deletions(-) create mode 100644 devtools/client/webconsole/test/mochitest/browser_webconsole_warning_group_content_blocking.js create mode 100644 devtools/client/webconsole/test/mochitest/browser_webconsole_warning_groups.js create mode 100644 devtools/client/webconsole/test/mochitest/test-warning-groups.html diff --git a/devtools/client/locales/en-US/webconsole.properties b/devtools/client/locales/en-US/webconsole.properties index ed7c4d5d4279..5fab7f88f480 100644 --- a/devtools/client/locales/en-US/webconsole.properties +++ b/devtools/client/locales/en-US/webconsole.properties @@ -344,3 +344,8 @@ webconsole.confirmDialog.getter.label=Invoke getter %S to retrieve the property # Label used for the confirm button in the "invoke getter" dialog that appears in the # console when a user tries to autocomplete a property with a getter. webconsole.confirmDialog.getter.invokeButtonLabel=Invoke + +# LOCALIZATION NOTE (webconsole.group.contentBlocked) +# Label used as the group header in the console output when content blocking is enabled +# and that we have several warning messages about resources being blocked. +webconsole.group.contentBlocked=Content blocked messages diff --git a/devtools/client/webconsole/components/ConsoleOutput.js b/devtools/client/webconsole/components/ConsoleOutput.js index 939aedb0769d..def9d464717e 100644 --- a/devtools/client/webconsole/components/ConsoleOutput.js +++ b/devtools/client/webconsole/components/ConsoleOutput.js @@ -16,6 +16,8 @@ const { getVisibleMessages, getPausedExecutionPoint, getAllRepeatById, + getAllWarningGroupsById, + isMessageInWarningGroup, } = require("devtools/client/webconsole/selectors/messages"); loader.lazyRequireGetter(this, "PropTypes", "devtools/client/shared/vendor/react-prop-types"); @@ -58,6 +60,8 @@ class ConsoleOutput extends Component { timestampsVisible: PropTypes.bool, messagesTableData: PropTypes.object.isRequired, messagesRepeat: PropTypes.object.isRequired, + warningGroups: PropTypes.object.isRequired, + isInWarningGroup: PropTypes.isRequired, networkMessagesUpdate: PropTypes.object.isRequired, visibleMessages: PropTypes.array.isRequired, networkMessageActiveTabId: PropTypes.string.isRequired, @@ -171,6 +175,8 @@ class ConsoleOutput extends Component { messagesUi, messagesTableData, messagesRepeat, + warningGroups, + isInWarningGroup, networkMessagesUpdate, networkMessageActiveTabId, serviceContainer, @@ -200,6 +206,10 @@ class ConsoleOutput extends Component { tableData: messagesTableData.get(messageId), timestampsVisible, repeat: messagesRepeat[messageId], + badge: warningGroups.has(messageId) ? warningGroups.get(messageId).length : null, + inWarningGroup: isInWarningGroup + ? isInWarningGroup(messages.get(messageId)) + : false, networkMessageUpdate: networkMessagesUpdate[messageId], networkMessageActiveTabId, pausedExecutionPoint, @@ -244,6 +254,10 @@ function mapStateToProps(state, props) { messagesUi: getAllMessagesUiById(state), messagesTableData: getAllMessagesTableDataById(state), messagesRepeat: getAllRepeatById(state), + warningGroups: getAllWarningGroupsById(state), + isInWarningGroup: state.prefs.groupWarnings + ? message => isMessageInWarningGroup(state, message) + : null, networkMessagesUpdate: getAllNetworkMessagesUpdateById(state), timestampsVisible: state.ui.timestampsVisible, networkMessageActiveTabId: state.ui.networkMessageActiveTabId, diff --git a/devtools/client/webconsole/reducers/messages.js b/devtools/client/webconsole/reducers/messages.js index be7553667534..2993483c17eb 100644 --- a/devtools/client/webconsole/reducers/messages.js +++ b/devtools/client/webconsole/reducers/messages.js @@ -21,6 +21,10 @@ const { loader.lazyRequireGetter(this, "getGripPreviewItems", "devtools/client/shared/components/reps/reps", true); loader.lazyRequireGetter(this, "getUnicodeUrlPath", "devtools/client/shared/unicode-url", true); loader.lazyRequireGetter(this, "getSourceNames", "devtools/client/shared/source-utils", true); +loader.lazyRequireGetter(this, "createWarningGroupMessage", "devtools/client/webconsole/utils/messages", true); +loader.lazyRequireGetter(this, "isWarningGroup", "devtools/client/webconsole/utils/messages", true); +loader.lazyRequireGetter(this, "getWarningGroupType", "devtools/client/webconsole/utils/messages", true); +loader.lazyRequireGetter(this, "getParentWarningGroupMessageId", "devtools/client/webconsole/utils/messages", true); const { UPDATE_REQUEST, @@ -46,9 +50,12 @@ const MessageState = overrides => Object.freeze(Object.assign({ messagesTableDataById: new Map(), // Map of the form {groupMessageId : groupArray}, // where groupArray is the list of of all the parent groups' ids of the groupMessageId. + // This handles console API groups. groupsById: new Map(), - // Message id of the current group (no corresponding console.groupEnd yet). + // Message id of the current console API group (no corresponding console.groupEnd yet). currentGroup: null, + // This group handles "warning groups" (Content Blocking, CORS, CSP, …) + warningGroupsById: new Map(), // Array of removed actors (i.e. actors logged in removed messages) we keep track of // in order to properly release them. // This array is not supposed to be consumed by any UI component. @@ -78,10 +85,20 @@ function cloneState(state) { networkMessagesUpdateById: {...state.networkMessagesUpdateById}, removedLogpointIds: new Set(state.removedLogpointIds), pausedExecutionPoint: state.pausedExecutionPoint, + warningGroupsById: new Map(state.warningGroupsById), }; } -function addMessage(state, filtersState, prefsState, newMessage) { +/** + * Add a console message to the state. + * + * @param {ConsoleMessage} newMessage: The message to add to the state. + * @param {MessageState} state: The message state ( = managed by this reducer). + * @param {FiltersState} filtersState: The filters state. + * @param {PrefsState} prefsState: The preferences state. + * @returns {MessageState} a new messages state. + */ +function addMessage(newMessage, state, filtersState, prefsState) { const { messagesById, replayProgressMessages, @@ -121,7 +138,7 @@ function addMessage(state, filtersState, prefsState, newMessage) { } if (newMessage.allowRepeating && messagesById.size > 0) { - const lastMessage = [...messagesById.values()][messagesById.size - 1]; + const lastMessage = messagesById.get(getLastMessageId(state)); if ( lastMessage.repeatId === newMessage.repeatId @@ -139,6 +156,47 @@ function addMessage(state, filtersState, prefsState, newMessage) { ensureExecutionPoint(state, newMessage); + // Check if the current message could be placed in a Warning Group. + // This needs to be done before setting the new message in messagesById so we have a + // proper message. + const warningGroupType = getWarningGroupType(newMessage); + + // If the preference for warning grouping is true, and the new message could be in a + // warning group. + if (prefsState.groupWarnings && warningGroupType !== null) { + const warningGroupMessageId = getParentWarningGroupMessageId(newMessage); + + // If there's no warning group for the type/innerWindowID yet + if (!state.messagesById.has(warningGroupMessageId)) { + // We create it and add it to the store. + const groupMessage = createWarningGroupMessage( + warningGroupMessageId, warningGroupType, newMessage); + state = addMessage(groupMessage, state, filtersState, prefsState); + state.warningGroupsById.set(warningGroupMessageId, []); + } + + // We add the new message to the appropriate warningGroup. + state.warningGroupsById.get(warningGroupMessageId).push(newMessage.id); + + // If the warningGroup message is not visible yet, but should be. + if (!state.visibleMessages.includes(warningGroupMessageId) + && getMessageVisibility(state.messagesById.get(warningGroupMessageId), { + messagesState: state, + filtersState, + prefsState, + }).visible + ) { + // Then we put it in the visibleMessages properties, at the position of the first + // warning message inside the warningGroup. + // TODO [Bug 1534927]: It should be added before the outermost console.group message + // a warning message could be in. + const index = state + .visibleMessages + .indexOf(state.warningGroupsById.get(warningGroupMessageId)[0]); + state.visibleMessages.splice(index, 1, warningGroupMessageId); + } + } + const addedMessage = Object.freeze(newMessage); state.messagesById.set(newMessage.id, addedMessage); @@ -155,13 +213,35 @@ function addMessage(state, filtersState, prefsState, newMessage) { } } - const { - visible, - cause, - } = getMessageVisibility(addedMessage, state, filtersState); + const { visible, cause } = getMessageVisibility(addedMessage, { + messagesState: state, + filtersState, + prefsState, + }); if (visible) { - state.visibleMessages.push(newMessage.id); + // If the message is part of a visible warning group, we want to add it after the last + // visible message of the group. + const warningGroupId = getParentWarningGroupMessageId(newMessage); + if (warningGroupId && state.visibleMessages.includes(warningGroupId)) { + // Defaults to the warning group message. + let index = state.visibleMessages.indexOf(warningGroupId); + + // We loop backward through the warning group's messages to get the latest visible + // messages in it. + const messagesInWarningGroup = state.warningGroupsById.get(warningGroupId); + for (let i = messagesInWarningGroup.length - 1; i >= 0; i--) { + const idx = state.visibleMessages.indexOf(messagesInWarningGroup[i]); + if (idx > -1) { + index = idx; + break; + } + } + // Inserts the new warning message at the wanted location "in" the warning group. + state.visibleMessages.splice(index + 1, 0, newMessage.id); + } else { + state.visibleMessages.push(newMessage.id); + } maybeSortVisibleMessages(state); } else if (DEFAULT_FILTERS.includes(cause)) { state.filteredMessagesCount.global++; @@ -222,7 +302,7 @@ function messages(state = MessageState(), action, filtersState, prefsState) { newState = cloneState(state); list.forEach(message => { - newState = addMessage(newState, filtersState, prefsState, message); + newState = addMessage(message, newState, filtersState, prefsState); }); return limitTopLevelMessageCount(newState, logLimit); @@ -278,21 +358,27 @@ function messages(state = MessageState(), action, filtersState, prefsState) { openState.messagesUiById = [...messagesUiById, action.id]; const currMessage = messagesById.get(action.id); - // If the message is a group - if (isGroupType(currMessage.type)) { + // If the message is a console.group/groupCollapsed or a warning group. + if (isGroupType(currMessage.type) || isWarningGroup(currMessage)) { // We want to make its children visible const messagesToShow = [...messagesById].reduce((res, [id, message]) => { if ( !visibleMessages.includes(message.id) - && getParentGroups(message.groupId, groupsById).includes(action.id) - && getMessageVisibility( - message, - openState, + && ( + (isWarningGroup(currMessage) && !!getWarningGroupType(message)) + || ( + isGroupType(currMessage.type) + && getParentGroups(message.groupId, groupsById).includes(action.id) + ) + ) + && getMessageVisibility(message, { + messagesState: openState, filtersState, - // We want to check if the message is in an open group - // only if it is not a direct child of the group we're opening. - message.groupId !== action.id - ).visible + prefsState, + // We want to check if the message is in an open group + // only if it is not a direct child of the group we're opening. + checkGroup: message.groupId !== action.id, + }).visible ) { res.push(id); } @@ -334,6 +420,11 @@ function messages(state = MessageState(), action, filtersState, prefsState) { getParentGroups(messagesById.get(id).groupId, groupsById) .includes(messageId) === false ); + } else if (isWarningGroup(messagesById.get(messageId))) { + // If the message was a warningGroup, we hide all the messages in the group. + const groupMessages = closeState.warningGroupsById.get(messageId); + closeState.visibleMessages = + visibleMessages.filter(id => !groupMessages.includes(id)); } return closeState; @@ -387,10 +478,12 @@ function messages(state = MessageState(), action, filtersState, prefsState) { const filtered = getDefaultFiltersCounter(); messagesById.forEach((message, msgId) => { - const { - visible, - cause, - } = getMessageVisibility(message, state, filtersState); + const { visible, cause } = getMessageVisibility(message, { + messagesState: state, + filtersState, + prefsState, + }); + if (visible) { messagesToShow.push(msgId); } else if (DEFAULT_FILTERS.includes(cause)) { @@ -635,7 +728,12 @@ function getToplevelMessageCount(state) { * - visible {Boolean}: true if the message should be visible * - cause {String}: if visible is false, what causes the message to be hidden. */ -function getMessageVisibility(message, messagesState, filtersState, checkGroup = true) { +function getMessageVisibility(message, { + messagesState, + filtersState, + prefsState, + checkGroup = true, +}) { // Do not display the message if it's in closed group. if ( checkGroup @@ -647,6 +745,30 @@ function getMessageVisibility(message, messagesState, filtersState, checkGroup = }; } + // If the message is a warningGroup, check if it should be displayed. + if ( + isWarningGroup(message) + && !shouldGroupWarningMessages(message, messagesState, prefsState) + ) { + return { + visible: false, + cause: "warningGroupHeuristicNotMet", + }; + } + + // Do not display the the message if it can be in a warningGroup, and the group is + // displayed but collapsed. + const warningGroupMessageId = getParentWarningGroupMessageId(message); + if ( + messagesState.visibleMessages.includes(warningGroupMessageId) + && !messagesState.messagesUiById.includes(warningGroupMessageId) + ) { + return { + visible: false, + cause: "closedWarningGroup", + }; + } + // Some messages can't be filtered out (e.g. groups). // So, always return visible: true for those. if (isUnfilterable(message)) { @@ -1049,6 +1171,28 @@ function maybeSortVisibleMessages(state) { } } +function getLastMessageId(state) { + return Array.from(state.messagesById.keys())[state.messagesById.size - 1]; +} + +/** + * Returns if a given type of warning message should be grouped. + * + * @param {ConsoleMessage} warningGroupMessage + * @param {MessageState} messagesState + * @param {PrefsState} prefsState + */ +function shouldGroupWarningMessages(warningGroupMessage, messagesState, prefsState) { + // Only group if the preference is ON. + if (!prefsState.groupWarnings) { + return false; + } + + // We group warning messages if there are at least 2 messages that could go in it. + const warningGroup = messagesState.warningGroupsById.get(warningGroupMessage.id); + return warningGroup && warningGroup.length > 1; +} + exports.messages = messages; // Export for testing purpose. diff --git a/devtools/client/webconsole/selectors/messages.js b/devtools/client/webconsole/selectors/messages.js index 96347a410b06..c2ad52753241 100644 --- a/devtools/client/webconsole/selectors/messages.js +++ b/devtools/client/webconsole/selectors/messages.js @@ -5,6 +5,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; +loader.lazyRequireGetter(this, "getWarningGroupType", "devtools/client/webconsole/utils/messages", true); +loader.lazyRequireGetter(this, "getParentWarningGroupMessageId", "devtools/client/webconsole/utils/messages", true); + function getAllMessagesById(state) { return state.messages.messagesById; } @@ -53,8 +56,21 @@ function getPausedExecutionPoint(state) { return state.messages.pausedExecutionPoint; } +function getAllWarningGroupsById(state) { + return state.messages.warningGroupsById; +} + +function isMessageInWarningGroup(state, message) { + if (!getWarningGroupType(message)) { + return false; + } + + return getVisibleMessages(state).includes(getParentWarningGroupMessageId(message)); +} + module.exports = { getAllGroupsById, + getAllWarningGroupsById, getAllMessagesById, getAllMessagesTableDataById, getAllMessagesUiById, @@ -66,4 +82,5 @@ module.exports = { getMessage, getVisibleMessages, getPausedExecutionPoint, + isMessageInWarningGroup, }; diff --git a/devtools/client/webconsole/test/components/warning-group.test.js b/devtools/client/webconsole/test/components/warning-group.test.js index 3bae02c68624..1275beabdef7 100644 --- a/devtools/client/webconsole/test/components/warning-group.test.js +++ b/devtools/client/webconsole/test/components/warning-group.test.js @@ -8,12 +8,14 @@ const { render } = require("enzyme"); // Components under test. const WarningGroup = require("devtools/client/webconsole/components/message-types/WarningGroup"); -const { MESSAGE_SOURCE } = require("devtools/client/webconsole/constants"); +const { MESSAGE_SOURCE, MESSAGE_TYPE } = require("devtools/client/webconsole/constants"); const { ConsoleMessage } = require("devtools/client/webconsole/types"); +const { createWarningGroupMessage } = require("devtools/client/webconsole/utils/messages"); // Test fakes. +const { stubPreparedMessages } = require("devtools/client/webconsole/test/fixtures/stubs/index"); const serviceContainer = require("devtools/client/webconsole/test/fixtures/serviceContainer"); -const message = ConsoleMessage({ +const mockMessage = ConsoleMessage({ messageText: "this is a warning group", source: MESSAGE_SOURCE.CONSOLE_FRONTEND, timeStamp: Date.now(), @@ -22,21 +24,22 @@ const message = ConsoleMessage({ describe("WarningGroup component:", () => { it("renders", () => { const wrapper = render(WarningGroup({ - message, + message: mockMessage, serviceContainer, timestampsVisible: true, badge: 42, })); const { timestampString } = require("devtools/client/webconsole/webconsole-l10n"); - expect(wrapper.find(".timestamp").text()).toBe(timestampString(message.timeStamp)); + expect(wrapper.find(".timestamp").text()) + .toBe(timestampString(mockMessage.timeStamp)); expect(wrapper.find(".message-body").text()).toBe("this is a warning group 42"); expect(wrapper.find(".arrow[aria-expanded=false]")).toExist(); }); it("does have an expanded arrow when `open` prop is true", () => { const wrapper = render(WarningGroup({ - message, + message: mockMessage, serviceContainer, open: true, })); @@ -46,11 +49,27 @@ describe("WarningGroup component:", () => { it("does not have a timestamp when timestampsVisible prop is falsy", () => { const wrapper = render(WarningGroup({ - message, + message: mockMessage, serviceContainer, timestampsVisible: false, })); expect(wrapper.find(".timestamp").length).toBe(0); }); + + it("renders Content Blocking Group message", () => { + const firstMessage = stubPreparedMessages.get("ReferenceError: asdf is not defined"); + const type = MESSAGE_TYPE.CONTENT_BLOCKING_GROUP; + const message = createWarningGroupMessage(`${type}-${firstMessage.innerWindowID}`, + type, firstMessage); + + const wrapper = render(WarningGroup({ + message, + serviceContainer, + badge: 24, + })); + + expect(wrapper.find(".message-body").text()).toBe("Content blocked messages 24"); + expect(wrapper.find(".arrow[aria-expanded=false]")).toExist(); + }); }); diff --git a/devtools/client/webconsole/test/fixtures/L10n.js b/devtools/client/webconsole/test/fixtures/L10n.js index 42a5fe5c5939..2df8f5830e26 100644 --- a/devtools/client/webconsole/test/fixtures/L10n.js +++ b/devtools/client/webconsole/test/fixtures/L10n.js @@ -41,6 +41,8 @@ class L10n { return "#1 repeat;#1 repeats"; case "webconsole.filteredMessages.label": return "#1 item hidden by filters;#1 items hidden by filters"; + case "webconsole.group.contentBlocked": + return "Content blocked messages"; default: return str; } diff --git a/devtools/client/webconsole/test/mochitest/browser.ini b/devtools/client/webconsole/test/mochitest/browser.ini index 2d02e2306654..fe2e6cffc301 100644 --- a/devtools/client/webconsole/test/mochitest/browser.ini +++ b/devtools/client/webconsole/test/mochitest/browser.ini @@ -115,6 +115,7 @@ support-files = test-subresource-security-error.js^headers^ test-time-methods.html test-trackingprotection-securityerrors.html + test-warning-groups.html test-webconsole-error-observer.html test-websocket.html test-websocket.js @@ -397,4 +398,6 @@ tags = trackingprotection [browser_webconsole_view_source.js] [browser_webconsole_visibility_messages.js] [browser_webconsole_warn_about_replaced_api.js] +[browser_webconsole_warning_group_content_blocking.js] +[browser_webconsole_warning_groups.js] [browser_webconsole_websocket.js] diff --git a/devtools/client/webconsole/test/mochitest/browser_webconsole_trackingprotection_errors.js b/devtools/client/webconsole/test/mochitest/browser_webconsole_trackingprotection_errors.js index 48e414ca7284..7a229e6f6b99 100644 --- a/devtools/client/webconsole/test/mochitest/browser_webconsole_trackingprotection_errors.js +++ b/devtools/client/webconsole/test/mochitest/browser_webconsole_trackingprotection_errors.js @@ -118,14 +118,6 @@ add_task(async function testCookieBlockedByPermissionMessage() { Services.perms.removeFromPrincipal(p, "cookie"); }); -async function openNewWindowAndConsole(url) { - const win = await openNewBrowserWindow(); - const tab = await addTab(url, {window: win}); - win.gBrowser.selectedTab = tab; - const hud = await openConsole(tab); - return {win, hud}; -} - function getStorageErrorUrl(category) { const BASE_STORAGE_ERROR_URL = "https://developer.mozilla.org/docs/Mozilla/Firefox/" + "Privacy/Storage_access_policy/Errors/"; diff --git a/devtools/client/webconsole/test/mochitest/browser_webconsole_warning_group_content_blocking.js b/devtools/client/webconsole/test/mochitest/browser_webconsole_warning_group_content_blocking.js new file mode 100644 index 000000000000..46d061eea044 --- /dev/null +++ b/devtools/client/webconsole/test/mochitest/browser_webconsole_warning_group_content_blocking.js @@ -0,0 +1,194 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Load a page with tracking elements that get blocked and make sure that a +// 'learn more' link shows up in the webconsole. + +"use strict"; +requestLongerTimeout(2); + +const TEST_FILE = + "browser/devtools/client/webconsole/test/mochitest/test-warning-groups.html"; +const TEST_URI = "http://example.com/" + TEST_FILE; + +const TRACKER_URL = "http://tracking.example.com/"; +const IMG_FILE = "browser/devtools/client/webconsole/test/mochitest/test-image.png"; +const TRACKER_IMG = "http://tracking.example.org/" + IMG_FILE; + +const CONTENT_BLOCKING_GROUP_LABEL = "Content blocked messages"; + +const COOKIE_BEHAVIOR_PREF = "network.cookie.cookieBehavior"; +const COOKIE_BEHAVIORS = { +// reject all third-party cookies + REJECT_FOREIGN: 1, +// reject all cookies + REJECT: 2, +// reject third-party cookies unless the eTLD already has at least one cookie + LIMIT_FOREIGN: 3, +// reject trackers + REJECT_TRACKER: 4, +}; + +const {UrlClassifierTestUtils} = ChromeUtils.import("resource://testing-common/UrlClassifierTestUtils.jsm"); +UrlClassifierTestUtils.addTestTrackers(); +registerCleanupFunction(function() { + UrlClassifierTestUtils.cleanupTestTrackers(); +}); + +pushPref("privacy.trackingprotection.enabled", true); +pushPref("devtools.webconsole.groupWarningMessages", true); + +add_task(async function testContentBlockingMessage() { + const {hud, tab, win} = await openNewWindowAndConsole( + "http://tracking.example.org/" + TEST_FILE); + const now = Date.now(); + + info("Test content blocking message"); + const message = `The resource at \u201chttp://tracking.example.com/?1&${now}\u201d ` + + `was blocked because content blocking is enabled`; + const onContentBlockingWarningMessage = waitForMessage(hud, message, ".warn"); + emitContentBlockingMessage(tab, `${TRACKER_URL}?1&${now}`); + await onContentBlockingWarningMessage; + + ok(true, "The content blocking message was displayed"); + + info("Emit a new content blocking message to check that it causes a grouping"); + const onContentBlockingWarningGroupMessage = + waitForMessage(hud, CONTENT_BLOCKING_GROUP_LABEL, ".warn"); + emitContentBlockingMessage(tab, `${TRACKER_URL}?2&${now}`); + const {node} = await onContentBlockingWarningGroupMessage; + is(node.querySelector(".warning-group-badge").textContent, "2", + "The badge has the expected text"); + + checkConsoleOutputForWarningGroup(hud, [ + `▶︎ ${CONTENT_BLOCKING_GROUP_LABEL} 2`, + ]); + + info("Open the group"); + node.querySelector(".arrow").click(); + await waitFor(() => findMessage(hud, "http://tracking.example.com/?1")); + + checkConsoleOutputForWarningGroup(hud, [ + `▼︎ ${CONTENT_BLOCKING_GROUP_LABEL} 2`, + `| The resource at \u201chttp://tracking.example.com/?1&${now}\u201d was blocked`, + `| The resource at \u201chttp://tracking.example.com/?2&${now}\u201d was blocked`, + ]); + await win.close(); +}); + +add_task(async function testForeignCookieBlockedMessage() { + info("Test foreign cookie blocked message"); + // We change the pref and open a new window to ensure it will be taken into account. + await pushPref(COOKIE_BEHAVIOR_PREF, COOKIE_BEHAVIORS.REJECT_FOREIGN); + const getWarningMsg = url => `Request to access cookie or storage on “${url}” was ` + + `blocked because we are blocking all third-party`; + await testStorageAccessBlockedGrouping(getWarningMsg); +}); + +add_task(async function testLimitForeignCookieBlockedMessage() { + info("Test unvisited eTLD foreign cookies blocked message"); + // We change the pref and open a new window to ensure it will be taken into account. + await pushPref(COOKIE_BEHAVIOR_PREF, COOKIE_BEHAVIORS.LIMIT_FOREIGN); + const getWarningMsg = url => `Request to access cookie or storage on “${url}” was ` + + `blocked because we are blocking all third-party`; + await testStorageAccessBlockedGrouping(getWarningMsg); +}); + +add_task(async function testAllCookieBlockedMessage() { + info("Test all cookies blocked message"); + // We change the pref and open a new window to ensure it will be taken into account. + await pushPref(COOKIE_BEHAVIOR_PREF, COOKIE_BEHAVIORS.REJECT); + const getWarningMsg = url => `Request to access cookie or storage on “${url}” was ` + + `blocked because we are blocking all storage access requests`; + await testStorageAccessBlockedGrouping(getWarningMsg); +}); + +add_task(async function testTrackerCookieBlockedMessage() { + info("Test tracker cookie blocked message"); + // We change the pref and open a new window to ensure it will be taken into account. + await pushPref(COOKIE_BEHAVIOR_PREF, COOKIE_BEHAVIORS.REJECT_TRACKER); + const getWarningMsg = url => `Request to access cookie or storage on “${url}” was ` + + `blocked because it came from a tracker`; + await testStorageAccessBlockedGrouping(getWarningMsg); +}); + +add_task(async function testCookieBlockedByPermissionMessage() { + info("Test cookie blocked by permission message"); + // Turn off tracking protection and add a block permission on the URL. + await pushPref("privacy.trackingprotection.enabled", false); + const p = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin("http://tracking.example.org/"); + Services.perms.addFromPrincipal(p, "cookie", Ci.nsIPermissionManager.DENY_ACTION); + + const getWarningMsg = url => `Request to access cookies or storage on “${url}” was ` + + `blocked because of custom cookie permission`; + await testStorageAccessBlockedGrouping(getWarningMsg); + + // Remove the custom permission. + Services.perms.removeFromPrincipal(p, "cookie"); +}); + +/** + * Test that storage access blocked messages are grouped by emitting 2 messages. + * + * @param {Function} getWarningMessage: A function that takes an URL string as a parameter + * and returns the corresponding warning message. + */ +async function testStorageAccessBlockedGrouping(getWarningMessage) { + const {hud, win, tab} = await openNewWindowAndConsole(TEST_URI); + const now = Date.now(); + + hud.ui.clearOutput(); + const onStorageAccessBlockedMessage = + waitForMessage(hud, getWarningMessage(`${TRACKER_IMG}?1&${now}`), ".warn"); + emitStorageAccessBlockedMessage(tab, `${TRACKER_IMG}?1&${now}`); + await onStorageAccessBlockedMessage; + + info("Emit a new content blocking message to check that it causes a grouping"); + const onContentBlockingWarningGroupMessage = + waitForMessage(hud, CONTENT_BLOCKING_GROUP_LABEL, ".warn"); + emitStorageAccessBlockedMessage(tab, `${TRACKER_IMG}?2&${now}`); + const {node} = await onContentBlockingWarningGroupMessage; + is(node.querySelector(".warning-group-badge").textContent, "2", + "The badge has the expected text"); + + checkConsoleOutputForWarningGroup(hud, [ + `▶︎ ${CONTENT_BLOCKING_GROUP_LABEL} 2`, + ]); + + info("Open the group"); + node.querySelector(".arrow").click(); + await waitFor(() => findMessage(hud, TRACKER_IMG)); + + checkConsoleOutputForWarningGroup(hud, [ + `▼︎ ${CONTENT_BLOCKING_GROUP_LABEL} 2`, + `| ${getWarningMessage(TRACKER_IMG + "?1&" + now)}`, + `| ${getWarningMessage(TRACKER_IMG + "?2&" + now)}`, + ]); + + hud.ui.clearOutput(); + await win.close(); +} + +/** + * Emit a Content Blocking message. This is done by loading an iframe from an origin + * tagged as tracker. The image is loaded with a incremented counter query parameter + * each time so we can get the warning message. + */ +function emitContentBlockingMessage(tab, url) { + ContentTask.spawn(tab.linkedBrowser, url, function(innerURL) { + content.wrappedJSObject.loadIframe(innerURL); + }); +} + +/** + * Emit a Storage blocked message. This is done by loading an image from an origin + * tagged as tracker. The image is loaded with a incremented counter query parameter + * each time so we can get the warning message. + */ +function emitStorageAccessBlockedMessage(tab, url) { + ContentTask.spawn(tab.linkedBrowser, url, async function(innerURL) { + content.wrappedJSObject.loadImage(innerURL); + }); +} diff --git a/devtools/client/webconsole/test/mochitest/browser_webconsole_warning_groups.js b/devtools/client/webconsole/test/mochitest/browser_webconsole_warning_groups.js new file mode 100644 index 000000000000..0e4d55a75ff0 --- /dev/null +++ b/devtools/client/webconsole/test/mochitest/browser_webconsole_warning_groups.js @@ -0,0 +1,241 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Test that warning messages can be grouped, per navigation and category, and that +// interacting with these groups works as expected. + +"use strict"; +requestLongerTimeout(2); + +const TEST_FILE = + "browser/devtools/client/webconsole/test/mochitest/test-warning-groups.html"; +const TEST_URI = "http://example.com/" + TEST_FILE; + +const TRACKER_URL = "http://tracking.example.org/"; +const BLOCKED_URL = TRACKER_URL + + "browser/devtools/client/webconsole/test/mochitest/test-image.png"; + +const {UrlClassifierTestUtils} = ChromeUtils.import("resource://testing-common/UrlClassifierTestUtils.jsm"); +registerCleanupFunction(function() { + UrlClassifierTestUtils.cleanupTestTrackers(); +}); + +add_task(async function testContentBlockingMessage() { + const CONTENT_BLOCKING_GROUP_LABEL = "Content blocked messages"; + + // Tracking protection preferences + await UrlClassifierTestUtils.addTestTrackers(); + await pushPref("privacy.trackingprotection.enabled", true); + + // Enable groupWarning and persist log + await pushPref("devtools.webconsole.groupWarningMessages", true); + await pushPref("devtools.webconsole.persistlog", true); + + const hud = await openNewTabAndConsole(TEST_URI); + + info("Log a tracking protection message to check a single message isn't grouped"); + let onContentBlockingWarningMessage = waitForMessage(hud, BLOCKED_URL, ".warn"); + emitStorageAccessBlockedMessage(hud); + let {node} = await onContentBlockingWarningMessage; + is(node.querySelector(".warning-indent"), null, "The message has the expected style"); + is(node.querySelector(".indent").getAttribute("data-indent"), "0", + "The message has the expected indent"); + + info("Log a simple message"); + await logString(hud, "simple message 1"); + + info("Log a second tracking protection message to check that it causes the grouping"); + let onContentBlockingWarningGroupMessage = + waitForMessage(hud, CONTENT_BLOCKING_GROUP_LABEL, ".warn"); + emitStorageAccessBlockedMessage(hud); + ({node} = await onContentBlockingWarningGroupMessage); + is(node.querySelector(".warning-group-badge").textContent, "2", + "The badge has the expected text"); + + checkConsoleOutputForWarningGroup(hud, [ + `▶︎ ${CONTENT_BLOCKING_GROUP_LABEL}`, + `simple message 1`, + ]); + + info("Log another simple message"); + await logString(hud, "simple message 2"); + + checkConsoleOutputForWarningGroup(hud, [ + `▶︎ ${CONTENT_BLOCKING_GROUP_LABEL}`, + `simple message 1`, + `simple message 2`, + ]); + + info("Log a third tracking protection message to check that the badge updates"); + emitStorageAccessBlockedMessage(hud); + await waitFor(() => node.querySelector(".warning-group-badge").textContent == "3"); + + checkConsoleOutputForWarningGroup(hud, [ + `▶︎ ${CONTENT_BLOCKING_GROUP_LABEL}`, + `simple message 1`, + `simple message 2`, + ]); + + info("Open the group"); + node.querySelector(".arrow").click(); + await waitFor(() => findMessage(hud, BLOCKED_URL)); + + checkConsoleOutputForWarningGroup(hud, [ + `▼︎ ${CONTENT_BLOCKING_GROUP_LABEL}`, + `| ${BLOCKED_URL}?1`, + `| ${BLOCKED_URL}?2`, + `| ${BLOCKED_URL}?3`, + `simple message 1`, + `simple message 2`, + ]); + + info("Log a new tracking protection message to check it appears inside the group"); + onContentBlockingWarningMessage = + waitForMessage(hud, BLOCKED_URL, ".warn"); + emitStorageAccessBlockedMessage(hud); + await onContentBlockingWarningMessage; + ok(true, "The new tracking protection message is displayed"); + + checkConsoleOutputForWarningGroup(hud, [ + `▼︎ ${CONTENT_BLOCKING_GROUP_LABEL}`, + `| ${BLOCKED_URL}?1`, + `| ${BLOCKED_URL}?2`, + `| ${BLOCKED_URL}?3`, + `| ${BLOCKED_URL}?4`, + `simple message 1`, + `simple message 2`, + ]); + + info("Reload the page and wait for it to be ready"); + const onDomContentLoaded = BrowserTestUtils.waitForContentEvent( + hud.target.tab.linkedBrowser, "DOMContentLoaded", true); + ContentTask.spawn(gBrowser.selectedBrowser, null, () => { + content.location.reload(); + }); + await onDomContentLoaded; + + // Also wait for the navigation message to be displayed. + await waitFor(() => findMessage(hud, "Navigated to")); + + info("Log a tracking protection message to check it is not grouped"); + onContentBlockingWarningMessage = + waitForMessage(hud, BLOCKED_URL, ".warn"); + emitStorageAccessBlockedMessage(hud); + await onContentBlockingWarningMessage; + + await logString(hud, "simple message 3"); + + checkConsoleOutputForWarningGroup(hud, [ + `▼︎ ${CONTENT_BLOCKING_GROUP_LABEL}`, + `| ${BLOCKED_URL}?1`, + `| ${BLOCKED_URL}?2`, + `| ${BLOCKED_URL}?3`, + `| ${BLOCKED_URL}?4`, + `simple message 1`, + `simple message 2`, + "Navigated to", + `${BLOCKED_URL}?5`, + `simple message 3`, + ]); + + info("Log a second tracking protection message to check that it causes the grouping"); + onContentBlockingWarningGroupMessage = + waitForMessage(hud, CONTENT_BLOCKING_GROUP_LABEL, ".warn"); + emitStorageAccessBlockedMessage(hud); + ({node} = await onContentBlockingWarningGroupMessage); + is(node.querySelector(".warning-group-badge").textContent, "2", + "The badge has the expected text"); + + checkConsoleOutputForWarningGroup(hud, [ + `▼︎ ${CONTENT_BLOCKING_GROUP_LABEL}`, + `| ${BLOCKED_URL}?1`, + `| ${BLOCKED_URL}?2`, + `| ${BLOCKED_URL}?3`, + `| ${BLOCKED_URL}?4`, + `simple message 1`, + `simple message 2`, + `Navigated to`, + `▶︎ ${CONTENT_BLOCKING_GROUP_LABEL}`, + `simple message 3`, + ]); + + info("Check that opening this group works"); + node.querySelector(".arrow").click(); + await waitFor(() => findMessages(hud, BLOCKED_URL).length === 6); + + checkConsoleOutputForWarningGroup(hud, [ + `▼︎ ${CONTENT_BLOCKING_GROUP_LABEL}`, + `| ${BLOCKED_URL}?1`, + `| ${BLOCKED_URL}?2`, + `| ${BLOCKED_URL}?3`, + `| ${BLOCKED_URL}?4`, + `simple message 1`, + `simple message 2`, + `Navigated to`, + `▼︎ ${CONTENT_BLOCKING_GROUP_LABEL}`, + `| ${BLOCKED_URL}?5`, + `| ${BLOCKED_URL}?6`, + `simple message 3`, + ]); + + info("Check that closing this group works, and let the other one open"); + node.querySelector(".arrow").click(); + await waitFor(() => findMessages(hud, BLOCKED_URL).length === 4); + + checkConsoleOutputForWarningGroup(hud, [ + `▼︎ ${CONTENT_BLOCKING_GROUP_LABEL}`, + `| ${BLOCKED_URL}?1`, + `| ${BLOCKED_URL}?2`, + `| ${BLOCKED_URL}?3`, + `| ${BLOCKED_URL}?4`, + `simple message 1`, + `simple message 2`, + `Navigated to`, + `▶︎ ${CONTENT_BLOCKING_GROUP_LABEL}`, + `simple message 3`, + ]); + + info("Log a third tracking protection message to check that the badge updates"); + emitStorageAccessBlockedMessage(hud); + await waitFor(() => node.querySelector(".warning-group-badge").textContent == "3"); + + checkConsoleOutputForWarningGroup(hud, [ + `▼︎ ${CONTENT_BLOCKING_GROUP_LABEL}`, + `| ${BLOCKED_URL}?1`, + `| ${BLOCKED_URL}?2`, + `| ${BLOCKED_URL}?3`, + `| ${BLOCKED_URL}?4`, + `simple message 1`, + `simple message 2`, + `Navigated to`, + `▶︎ ${CONTENT_BLOCKING_GROUP_LABEL}`, + `simple message 3`, + ]); +}); + +let cpt = 0; +/** + * Emit a Content Blocking message. This is done by loading an image from an origin + * tagged as tracker. The image is loaded with a incremented counter query parameter + * each time so we can get the warning message. + */ +function emitStorageAccessBlockedMessage() { + const url = `${BLOCKED_URL}?${++cpt}`; + ContentTask.spawn(gBrowser.selectedBrowser, url, function(innerURL) { + content.wrappedJSObject.loadImage(innerURL); + }); +} + +/** + * Log a string from the content page. + * + * @param {WebConsole} hud + * @param {String} str + */ +function logString(hud, str) { + const onMessage = waitForMessage(hud, str); + ContentTask.spawn(gBrowser.selectedBrowser, str, function(arg) { + content.console.log(arg); + }); + return onMessage; +} diff --git a/devtools/client/webconsole/test/mochitest/head.js b/devtools/client/webconsole/test/mochitest/head.js index 6a0bf0984128..d8eb1e3654ee 100644 --- a/devtools/client/webconsole/test/mochitest/head.js +++ b/devtools/client/webconsole/test/mochitest/head.js @@ -86,6 +86,23 @@ async function openNewTabAndConsole(url, clearJstermHistory = true) { return hud; } +/** + * Open a new window with a tab,open the toolbox, and select the webconsole. + * + * @param string url + * The URL for the tab to be opened. + * @return Promise<{win, hud, tab}> + * Resolves when the tab has been added, loaded and the toolbox has been opened. + * Resolves to the toolbox. + */ +async function openNewWindowAndConsole(url) { + const win = await openNewBrowserWindow(); + const tab = await addTab(url, {window: win}); + win.gBrowser.selectedTab = tab; + const hud = await openConsole(tab); + return {win, hud, tab}; +} + /** * Subscribe to the store and log out stringinfied versions of messages. * This is a helper function for debugging, to make is easier to see what @@ -1221,3 +1238,43 @@ function isScrolledToBottom(container) { return container.scrollTop + container.clientHeight >= container.scrollHeight - lastNodeHeight / 2; } + +/** + * + * @param {WebConsole} hud + * @param {Array} expectedMessages: An array of string representing the messages + * from the output. This can only be a part of the string of the + * message. + * Start the string with "▶︎ " or "▼ " to indicate that the + * message is a warningGroup (with respectively an open or + * collapsed arrow). + * Start the string with "|︎ " to indicate that the message is + * inside a group and should be indented. + */ +function checkConsoleOutputForWarningGroup(hud, expectedMessages) { + const messages = findMessages(hud, ""); + is(messages.length, expectedMessages.length, "Got the expected number of messages"); + expectedMessages.forEach((expectedMessage, i) => { + const message = messages[i]; + if (expectedMessage.startsWith("▶︎")) { + is(message.querySelector(".arrow").getAttribute("aria-expanded"), "false", + "There's a collapsed arrow"); + expectedMessage = expectedMessage.replace("▶︎ ", ""); + } + + if (expectedMessage.startsWith("▼")) { + is(message.querySelector(".arrow").getAttribute("aria-expanded"), "true", + "There's an expanded arrow"); + expectedMessage = expectedMessage.replace("▼︎ ", ""); + } + + if (expectedMessage.startsWith("|")) { + is(message.querySelector(".indent.warning-indent").getAttribute("data-indent"), "1", + "The message has the expected indent"); + expectedMessage = expectedMessage.replace("| ", ""); + } + + ok(message.textContent.trim().includes(expectedMessage.trim()), `Message includes ` + + `the expected "${expectedMessage}" content - "${message.textContent.trim()}"`); + }); +} diff --git a/devtools/client/webconsole/test/mochitest/test-warning-groups.html b/devtools/client/webconsole/test/mochitest/test-warning-groups.html new file mode 100644 index 000000000000..f1442ce1bb08 --- /dev/null +++ b/devtools/client/webconsole/test/mochitest/test-warning-groups.html @@ -0,0 +1,28 @@ + + + + + Warning groups webconsole test page + + +

Warning groups webconsole test page

+ + + diff --git a/devtools/client/webconsole/utils/messages.js b/devtools/client/webconsole/utils/messages.js index f1c74a82a247..4a612d555d33 100644 --- a/devtools/client/webconsole/utils/messages.js +++ b/devtools/client/webconsole/utils/messages.js @@ -430,19 +430,76 @@ function isPacketPrivate(packet) { ); } +function createWarningGroupMessage(id, type, firstMessage) { + let messageText; + if (type === MESSAGE_TYPE.CONTENT_BLOCKING_GROUP) { + messageText = l10n.getStr("webconsole.group.contentBlocked"); + } + return new ConsoleMessage({ + id, + level: MESSAGE_LEVEL.WARN, + source: MESSAGE_SOURCE.CONSOLE_FRONTEND, + type, + messageText, + timeStamp: firstMessage.timeStamp, + innerWindowID: firstMessage.innerWindowID, + }); +} + +/** + * Get the warningGroup type in which the message could be in. + * @param {ConsoleMessage} message + * @returns {String|null} null if the message can't be part of a warningGroup. + */ +function getWarningGroupType(message) { + if (isContentBlockingMessage(message)) { + return MESSAGE_TYPE.CONTENT_BLOCKING_GROUP; + } + return null; +} + +/** + * Returns a computed id given a message + * + * @param {ConsoleMessage} type: the message type, from MESSAGE_TYPE. + * @param {Integer} innerWindowID: the message innerWindowID. + * @returns {String} + */ +function getParentWarningGroupMessageId(message) { + return `${message.type}-${message.innerWindowID}`; +} + /** * Returns true if the message is a warningGroup message (i.e. the "Header"). * @param {ConsoleMessage} message * @returns {Boolean} */ function isWarningGroup(message) { - return message.type === MESSAGE_TYPE.TRACKING_PROTECTION_GROUP + return message.type === MESSAGE_TYPE.CONTENT_BLOCKING_GROUP || message.type === MESSAGE_TYPE.CORS_GROUP || message.type === MESSAGE_TYPE.CSP_GROUP; } +/** + * Returns true if the message is a content blocking message. + * @param {ConsoleMessage} message + * @returns {Boolean} + */ +function isContentBlockingMessage(message) { + const {category} = message; + return category == "cookieBlockedPermission" || + category == "cookieBlockedTracker" || + category == "cookieBlockedAll" || + category == "cookieBlockedForeign" || + category == "Tracking Protection"; +} + module.exports = { + createWarningGroupMessage, getInitialMessageCountForViewport, + getParentWarningGroupMessageId, + getWarningGroupType, + isContentBlockingMessage, isGroupType, isPacketPrivate, isWarningGroup, From 437397c84797869353939d2d99ce3db55e285101 Mon Sep 17 00:00:00 2001 From: Andi-Bogdan Postelnicu Date: Thu, 28 Mar 2019 17:49:41 +0000 Subject: [PATCH 013/100] Bug 1536790 - Upgrade to clang-{tidy,format} 8.0.0 (from 7.0.1) r=andi Patch wrote by Sylvestre Ledru (sylvestre@mozilla.com) Differential Revision: https://phabricator.services.mozilla.com/D24175 --HG-- extra : moz-landing-system : lando --- build/build-clang/clang-tidy-linux64.json | 12 ++++++------ build/build-clang/clang-tidy-macosx64.json | 12 ++++++------ build/build-clang/clang-tidy-win64.json | 12 ++++++------ tools/clang-tidy/config.yaml | 2 +- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/build/build-clang/clang-tidy-linux64.json b/build/build-clang/clang-tidy-linux64.json index 5c18fc5b5d5b..cac28baf2f1f 100644 --- a/build/build-clang/clang-tidy-linux64.json +++ b/build/build-clang/clang-tidy-linux64.json @@ -1,15 +1,15 @@ { - "llvm_revision": "349247", + "llvm_revision": "356365", "stages": "1", "build_libcxx": true, "build_type": "Release", "assertions": false, "build_clang_tidy": true, - "llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_701/final/", - "clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_701/final/", - "extra_repo": "https://llvm.org/svn/llvm-project/clang-tools-extra/tags/RELEASE_701/final/", - "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_701/final/", - "libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_701/final/", + "llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_800/final/", + "clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_800/final/", + "extra_repo": "https://llvm.org/svn/llvm-project/clang-tools-extra/tags/RELEASE_800/final/", + "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_800/final/", + "libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_800/final/", "python_path": "/usr/bin/python2.7", "gcc_dir": "/builds/worker/workspace/build/src/gcc", "cc": "/builds/worker/workspace/build/src/gcc/bin/gcc", diff --git a/build/build-clang/clang-tidy-macosx64.json b/build/build-clang/clang-tidy-macosx64.json index dcbb12c793b2..1681af010aaf 100644 --- a/build/build-clang/clang-tidy-macosx64.json +++ b/build/build-clang/clang-tidy-macosx64.json @@ -1,16 +1,16 @@ { - "llvm_revision": "349247", + "llvm_revision": "356365", "stages": "1", "build_libcxx": true, "build_type": "Release", "assertions": false, "build_clang_tidy": true, "osx_cross_compile": true, - "llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_701/final", - "clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_701/final", - "extra_repo": "https://llvm.org/svn/llvm-project/clang-tools-extra/tags/RELEASE_701/final", - "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_701/final", - "libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_701/final", + "llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_800/final", + "clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_800/final", + "extra_repo": "https://llvm.org/svn/llvm-project/clang-tools-extra/tags/RELEASE_800/final", + "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_800/final", + "libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_800/final", "python_path": "/usr/bin/python2.7", "gcc_dir": "/builds/worker/workspace/build/src/gcc", "cc": "/builds/worker/workspace/build/src/clang/bin/clang", diff --git a/build/build-clang/clang-tidy-win64.json b/build/build-clang/clang-tidy-win64.json index 539f594fd807..b51aefdb2d37 100644 --- a/build/build-clang/clang-tidy-win64.json +++ b/build/build-clang/clang-tidy-win64.json @@ -1,15 +1,15 @@ { - "llvm_revision": "349247", + "llvm_revision": "356365", "stages": "1", "build_libcxx": false, "build_type": "Release", "assertions": false, "build_clang_tidy": true, - "llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_701/final", - "clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_701/final", - "extra_repo": "https://llvm.org/svn/llvm-project/clang-tools-extra/tags/RELEASE_701/final", - "compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_701/final", - "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_701/final", + "llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_800/final", + "clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_800/final", + "extra_repo": "https://llvm.org/svn/llvm-project/clang-tools-extra/tags/RELEASE_800/final", + "compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_800/final", + "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_800/final", "python_path": "c:/mozilla-build/python/python.exe", "cc": "cl.exe", "cxx": "cl.exe", diff --git a/tools/clang-tidy/config.yaml b/tools/clang-tidy/config.yaml index 09e5bda52c2a..69d80c57571e 100644 --- a/tools/clang-tidy/config.yaml +++ b/tools/clang-tidy/config.yaml @@ -18,7 +18,7 @@ platforms: - win64 # Minimum clang-tidy version that is required for all the following checkers # to work properly. -min_clang_tidy: "7.0.0" +min_clang_tidy: "8.0.0" clang_checkers: - name: -* publish: !!bool no From 2473b505db6b0208767f36ae953f3fab33d8495e Mon Sep 17 00:00:00 2001 From: Andi-Bogdan Postelnicu Date: Fri, 29 Mar 2019 08:08:31 +0000 Subject: [PATCH 014/100] Bug 1539779 - clang-tidy 8 mixes stderr and stdout causing parsing issues. r=sylvestre Differential Revision: https://phabricator.services.mozilla.com/D25255 --HG-- extra : moz-landing-system : lando --- build/build-clang/clang-tidy-8.patch | 11 +++++++++++ build/build-clang/clang-tidy-linux64.json | 1 + build/build-clang/clang-tidy-macosx64.json | 1 + build/build-clang/clang-tidy-win64.json | 1 + 4 files changed, 14 insertions(+) create mode 100644 build/build-clang/clang-tidy-8.patch diff --git a/build/build-clang/clang-tidy-8.patch b/build/build-clang/clang-tidy-8.patch new file mode 100644 index 000000000000..53a1deec8a68 --- /dev/null +++ b/build/build-clang/clang-tidy-8.patch @@ -0,0 +1,11 @@ +--- a/extra/clang-tidy/tool/run-clang-tidy.py 2019-03-27 15:12:48.000000000 +0200 ++++ b/extra/clang-tidy/tool/run-clang-tidy.py 2019-03-27 15:12:39.000000000 +0200 +@@ -169,7 +169,7 @@ + with lock: + sys.stdout.write(' '.join(invocation) + '\n' + output.decode('utf-8') + '\n') + if len(err) > 0: +- sys.stderr.write(err.decode('utf-8') + '\n') ++ sys.stdout.write(err.decode('utf-8') + '\n') + queue.task_done() + + diff --git a/build/build-clang/clang-tidy-linux64.json b/build/build-clang/clang-tidy-linux64.json index cac28baf2f1f..dd27b0570b3b 100644 --- a/build/build-clang/clang-tidy-linux64.json +++ b/build/build-clang/clang-tidy-linux64.json @@ -16,5 +16,6 @@ "cxx": "/builds/worker/workspace/build/src/gcc/bin/g++", "as": "/builds/worker/workspace/build/src/gcc/bin/gcc", "patches": [ + "clang-tidy-8.patch" ] } diff --git a/build/build-clang/clang-tidy-macosx64.json b/build/build-clang/clang-tidy-macosx64.json index 1681af010aaf..8226b6f6f2da 100644 --- a/build/build-clang/clang-tidy-macosx64.json +++ b/build/build-clang/clang-tidy-macosx64.json @@ -21,5 +21,6 @@ "libtool": "/builds/worker/workspace/build/src/cctools/bin/x86_64-darwin11-libtool", "ld": "/builds/worker/workspace/build/src/clang/bin/clang", "patches": [ + "clang-tidy-8.patch" ] } diff --git a/build/build-clang/clang-tidy-win64.json b/build/build-clang/clang-tidy-win64.json index b51aefdb2d37..6249e5492cee 100644 --- a/build/build-clang/clang-tidy-win64.json +++ b/build/build-clang/clang-tidy-win64.json @@ -15,5 +15,6 @@ "cxx": "cl.exe", "ml": "ml64.exe", "patches": [ + "clang-tidy-8.patch" ] } From 0bc3e10232e1e1f4ec92f2d7635a6fb4473dc6eb Mon Sep 17 00:00:00 2001 From: Daniel Varga Date: Fri, 29 Mar 2019 10:34:45 +0200 Subject: [PATCH 015/100] Backed out 2 changesets (bug 1539779, bug 1536790) for toolchain failure. On a CLOSED TREE Backed out changeset 5ecdbfab88b4 (bug 1539779) Backed out changeset 20d5cdaa08e3 (bug 1536790) --- build/build-clang/clang-tidy-8.patch | 11 ----------- build/build-clang/clang-tidy-linux64.json | 13 ++++++------- build/build-clang/clang-tidy-macosx64.json | 13 ++++++------- build/build-clang/clang-tidy-win64.json | 13 ++++++------- tools/clang-tidy/config.yaml | 2 +- 5 files changed, 19 insertions(+), 33 deletions(-) delete mode 100644 build/build-clang/clang-tidy-8.patch diff --git a/build/build-clang/clang-tidy-8.patch b/build/build-clang/clang-tidy-8.patch deleted file mode 100644 index 53a1deec8a68..000000000000 --- a/build/build-clang/clang-tidy-8.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/extra/clang-tidy/tool/run-clang-tidy.py 2019-03-27 15:12:48.000000000 +0200 -+++ b/extra/clang-tidy/tool/run-clang-tidy.py 2019-03-27 15:12:39.000000000 +0200 -@@ -169,7 +169,7 @@ - with lock: - sys.stdout.write(' '.join(invocation) + '\n' + output.decode('utf-8') + '\n') - if len(err) > 0: -- sys.stderr.write(err.decode('utf-8') + '\n') -+ sys.stdout.write(err.decode('utf-8') + '\n') - queue.task_done() - - diff --git a/build/build-clang/clang-tidy-linux64.json b/build/build-clang/clang-tidy-linux64.json index dd27b0570b3b..5c18fc5b5d5b 100644 --- a/build/build-clang/clang-tidy-linux64.json +++ b/build/build-clang/clang-tidy-linux64.json @@ -1,21 +1,20 @@ { - "llvm_revision": "356365", + "llvm_revision": "349247", "stages": "1", "build_libcxx": true, "build_type": "Release", "assertions": false, "build_clang_tidy": true, - "llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_800/final/", - "clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_800/final/", - "extra_repo": "https://llvm.org/svn/llvm-project/clang-tools-extra/tags/RELEASE_800/final/", - "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_800/final/", - "libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_800/final/", + "llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_701/final/", + "clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_701/final/", + "extra_repo": "https://llvm.org/svn/llvm-project/clang-tools-extra/tags/RELEASE_701/final/", + "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_701/final/", + "libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_701/final/", "python_path": "/usr/bin/python2.7", "gcc_dir": "/builds/worker/workspace/build/src/gcc", "cc": "/builds/worker/workspace/build/src/gcc/bin/gcc", "cxx": "/builds/worker/workspace/build/src/gcc/bin/g++", "as": "/builds/worker/workspace/build/src/gcc/bin/gcc", "patches": [ - "clang-tidy-8.patch" ] } diff --git a/build/build-clang/clang-tidy-macosx64.json b/build/build-clang/clang-tidy-macosx64.json index 8226b6f6f2da..dcbb12c793b2 100644 --- a/build/build-clang/clang-tidy-macosx64.json +++ b/build/build-clang/clang-tidy-macosx64.json @@ -1,16 +1,16 @@ { - "llvm_revision": "356365", + "llvm_revision": "349247", "stages": "1", "build_libcxx": true, "build_type": "Release", "assertions": false, "build_clang_tidy": true, "osx_cross_compile": true, - "llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_800/final", - "clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_800/final", - "extra_repo": "https://llvm.org/svn/llvm-project/clang-tools-extra/tags/RELEASE_800/final", - "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_800/final", - "libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_800/final", + "llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_701/final", + "clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_701/final", + "extra_repo": "https://llvm.org/svn/llvm-project/clang-tools-extra/tags/RELEASE_701/final", + "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_701/final", + "libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_701/final", "python_path": "/usr/bin/python2.7", "gcc_dir": "/builds/worker/workspace/build/src/gcc", "cc": "/builds/worker/workspace/build/src/clang/bin/clang", @@ -21,6 +21,5 @@ "libtool": "/builds/worker/workspace/build/src/cctools/bin/x86_64-darwin11-libtool", "ld": "/builds/worker/workspace/build/src/clang/bin/clang", "patches": [ - "clang-tidy-8.patch" ] } diff --git a/build/build-clang/clang-tidy-win64.json b/build/build-clang/clang-tidy-win64.json index 6249e5492cee..539f594fd807 100644 --- a/build/build-clang/clang-tidy-win64.json +++ b/build/build-clang/clang-tidy-win64.json @@ -1,20 +1,19 @@ { - "llvm_revision": "356365", + "llvm_revision": "349247", "stages": "1", "build_libcxx": false, "build_type": "Release", "assertions": false, "build_clang_tidy": true, - "llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_800/final", - "clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_800/final", - "extra_repo": "https://llvm.org/svn/llvm-project/clang-tools-extra/tags/RELEASE_800/final", - "compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_800/final", - "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_800/final", + "llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_701/final", + "clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_701/final", + "extra_repo": "https://llvm.org/svn/llvm-project/clang-tools-extra/tags/RELEASE_701/final", + "compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_701/final", + "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_701/final", "python_path": "c:/mozilla-build/python/python.exe", "cc": "cl.exe", "cxx": "cl.exe", "ml": "ml64.exe", "patches": [ - "clang-tidy-8.patch" ] } diff --git a/tools/clang-tidy/config.yaml b/tools/clang-tidy/config.yaml index 69d80c57571e..09e5bda52c2a 100644 --- a/tools/clang-tidy/config.yaml +++ b/tools/clang-tidy/config.yaml @@ -18,7 +18,7 @@ platforms: - win64 # Minimum clang-tidy version that is required for all the following checkers # to work properly. -min_clang_tidy: "8.0.0" +min_clang_tidy: "7.0.0" clang_checkers: - name: -* publish: !!bool no From bd12eaff994f21dcbe5ee25637f15aeda6013854 Mon Sep 17 00:00:00 2001 From: Daniel Varga Date: Fri, 29 Mar 2019 10:38:13 +0200 Subject: [PATCH 016/100] Backed out changeset 005d447749ec (bug 1370646) mochitest failure at layout/style/test/test_font_loading_api.html. On a CLOSED TREE --- layout/svg/SVGTextFrame.cpp | 17 +++--------- layout/svg/tests/mochitest.ini | 1 - layout/svg/tests/test_multiple_font_size.html | 26 ------------------- 3 files changed, 3 insertions(+), 41 deletions(-) delete mode 100644 layout/svg/tests/test_multiple_font_size.html diff --git a/layout/svg/SVGTextFrame.cpp b/layout/svg/SVGTextFrame.cpp index 38e4935bb818..54e77a991775 100644 --- a/layout/svg/SVGTextFrame.cpp +++ b/layout/svg/SVGTextFrame.cpp @@ -5223,20 +5223,9 @@ bool SVGTextFrame::UpdateFontSizeScaleFactor() { mFontSizeScaleFactor = contextScale; } else if (maxSize / minSize > CLAMP_MAX_SIZE / CLAMP_MIN_SIZE) { // We can't scale the font sizes so that all of the text frames lie - // within our ideal font size range. - // Heuristically, if the maxTextRunSize is within the CLAMP_MAX_SIZE - // as a reasonable value, it's likely to be the user's intent to - // get a valid font for the maxTextRunSize one, we should honor it. - // The same for minTextRunSize. - if (maxTextRunSize <= CLAMP_MAX_SIZE) { - mFontSizeScaleFactor = CLAMP_MAX_SIZE / maxSize; - } else if (minTextRunSize >= CLAMP_MIN_SIZE) { - mFontSizeScaleFactor = CLAMP_MIN_SIZE / minSize; - } else { - // So maxTextRunSize is too big, minTextRunSize is too small, - // we can't really do anything for this case, just leave it as is. - mFontSizeScaleFactor = contextScale; - } + // within our ideal font size range, so we treat the minimum as more + // important and just scale so that minSize = CLAMP_MIN_SIZE. + mFontSizeScaleFactor = CLAMP_MIN_SIZE / minSize; } else if (minTextRunSize < CLAMP_MIN_SIZE) { mFontSizeScaleFactor = CLAMP_MIN_SIZE / minSize; } else { diff --git a/layout/svg/tests/mochitest.ini b/layout/svg/tests/mochitest.ini index 935f5e8566c0..b8fcde88973f 100644 --- a/layout/svg/tests/mochitest.ini +++ b/layout/svg/tests/mochitest.ini @@ -11,5 +11,4 @@ support-files = file_yellow_black.svg [test_hover_near_text.html] -[test_multiple_font_size.html] [test_use_tree_cycle.html] diff --git a/layout/svg/tests/test_multiple_font_size.html b/layout/svg/tests/test_multiple_font_size.html deleted file mode 100644 index 77683f90512e..000000000000 --- a/layout/svg/tests/test_multiple_font_size.html +++ /dev/null @@ -1,26 +0,0 @@ - - - -Mozilla Bug 1370646 - - - - 3 - - - 3 - 0 - - - - - From c711763836543d909ec200e8247a2afb53427e4c Mon Sep 17 00:00:00 2001 From: Kershaw Chang Date: Thu, 28 Mar 2019 15:03:46 +0000 Subject: [PATCH 017/100] Bug 1539539 - Add main thread assertion and fix a clang warning r=mayhemer The resultCallback at [1] should be always executed on main thread, so adding an assertion to enforce this. This patch also fixes a warning at [2]. This is about moving a const captured variable. [1] https://searchfox.org/mozilla-central/rev/3d469329a42644b41e66944d8da22d78d8c0f5ec/netwerk/protocol/http/nsHttpChannel.cpp#551-558 [2] https://searchfox.org/mozilla-central/rev/3d469329a42644b41e66944d8da22d78d8c0f5ec/netwerk/base/nsNetUtil.cpp#2808 Differential Revision: https://phabricator.services.mozilla.com/D25219 --HG-- extra : moz-landing-system : lando --- netwerk/base/nsNetUtil.cpp | 2 +- netwerk/protocol/http/nsHttpChannel.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/netwerk/base/nsNetUtil.cpp b/netwerk/base/nsNetUtil.cpp index 087ec37ffba6..c0d53fed3319 100644 --- a/netwerk/base/nsNetUtil.cpp +++ b/netwerk/base/nsNetUtil.cpp @@ -2790,7 +2790,7 @@ nsresult NS_ShouldSecureUpgrade( [service{std::move(service)}, uri{std::move(uri)}, flags(flags), originAttributes(aOriginAttributes), handleResultFunc{std::move(handleResultFunc)}, - resultCallback{std::move(aResultCallback)}]() { + resultCallback{std::move(aResultCallback)}]() mutable { uint32_t hstsSource = 0; bool isStsHost = false; nsresult rv = service->IsSecureURI( diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index 148092432a9b..068761b72619 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -553,6 +553,8 @@ nsresult nsHttpChannel::OnBeforeConnect() { new nsMainThreadPtrHolder( "nsHttpChannel::OnBeforeConnect::self", this)); auto resultCallback = [self(self)](bool aResult, nsresult aStatus) { + MOZ_ASSERT(NS_IsMainThread()); + nsresult rv = self->ContinueOnBeforeConnect(aResult, aStatus); if (NS_FAILED(rv)) { self->CloseCacheEntry(false); From 7707038236300ed65afcf5f2718cfc051ab32155 Mon Sep 17 00:00:00 2001 From: Daniel Varga Date: Fri, 29 Mar 2019 11:18:33 +0200 Subject: [PATCH 018/100] Backed out changeset 29c306545aa5 (bug 1539528) for mochitest failure at /builds/worker/workspace/build/src/xpcom/threads/nsThreadManager.cpp:69. On a CLOSED TREE --- dom/websocket/WebSocket.cpp | 37 ++++++++++++++++++++++--------------- dom/websocket/WebSocket.h | 4 +++- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/dom/websocket/WebSocket.cpp b/dom/websocket/WebSocket.cpp index cc2502e72397..96cd8f98fe1e 100644 --- a/dom/websocket/WebSocket.cpp +++ b/dom/websocket/WebSocket.cpp @@ -870,8 +870,8 @@ WebSocketImpl::GetInterface(const nsIID& aIID, void** aResult) { // WebSocket //////////////////////////////////////////////////////////////////////////////// -WebSocket::WebSocket(nsIGlobalObject* aGlobal) - : DOMEventTargetHelper(aGlobal), +WebSocket::WebSocket(nsPIDOMWindowInner* aOwnerWindow) + : DOMEventTargetHelper(aOwnerWindow), mIsMainThread(true), mKeepingAlive(false), mCheckMustKeepAlive(true), @@ -879,8 +879,6 @@ WebSocket::WebSocket(nsIGlobalObject* aGlobal) mBinaryType(dom::BinaryType::Blob), mMutex("WebSocket::mMutex"), mReadyState(CONNECTING) { - MOZ_ASSERT(aGlobal); - mImpl = new WebSocketImpl(this); mIsMainThread = mImpl->mIsMainThread; } @@ -1182,12 +1180,7 @@ already_AddRefed WebSocket::ConstructorCommon( const nsACString& aNegotiatedExtensions, ErrorResult& aRv) { MOZ_ASSERT_IF(!aTransportProvider, aNegotiatedExtensions.IsEmpty()); nsCOMPtr principal; - - nsCOMPtr global = do_QueryInterface(aGlobal.GetAsSupports()); - if (NS_WARN_IF(!global)) { - aRv.Throw(NS_ERROR_FAILURE); - return nullptr; - } + nsCOMPtr ownerWindow; if (NS_IsMainThread()) { nsCOMPtr scriptPrincipal = @@ -1209,6 +1202,12 @@ already_AddRefed WebSocket::ConstructorCommon( aRv.Throw(NS_ERROR_FAILURE); return nullptr; } + + ownerWindow = do_QueryInterface(aGlobal.GetAsSupports()); + if (!ownerWindow) { + aRv.Throw(NS_ERROR_FAILURE); + return nullptr; + } } nsTArray protocolArray; @@ -1232,7 +1231,7 @@ already_AddRefed WebSocket::ConstructorCommon( protocolArray.AppendElement(protocolElement); } - RefPtr webSocket = new WebSocket(global); + RefPtr webSocket = new WebSocket(ownerWindow); RefPtr webSocketImpl = webSocket->mImpl; bool connectionFailed = true; @@ -1350,7 +1349,6 @@ already_AddRefed WebSocket::ConstructorCommon( if (NS_IsMainThread()) { MOZ_ASSERT(principal); - nsCOMPtr ownerWindow = do_QueryInterface(global); nsPIDOMWindowOuter* outerWindow = ownerWindow->GetOuterWindow(); uint64_t windowID = 0; @@ -1802,8 +1800,17 @@ nsresult WebSocket::CreateAndDispatchMessageEvent(const nsACString& aData, AssertIsOnTargetThread(); AutoJSAPI jsapi; - if (NS_WARN_IF(!jsapi.Init(GetOwnerGlobal()))) { - return NS_ERROR_FAILURE; + + if (NS_IsMainThread()) { + if (NS_WARN_IF(!jsapi.Init(GetOwner()))) { + return NS_ERROR_FAILURE; + } + } else { + MOZ_ASSERT(!mIsMainThread); + MOZ_ASSERT(mImpl->mWorkerRef); + if (NS_WARN_IF(!jsapi.Init(mImpl->mWorkerRef->Private()->GlobalScope()))) { + return NS_ERROR_FAILURE; + } } JSContext* cx = jsapi.cx(); @@ -1822,7 +1829,7 @@ nsresult WebSocket::CreateAndDispatchMessageEvent(const nsACString& aData, messageType = nsIWebSocketEventListener::TYPE_BLOB; RefPtr blob = - Blob::CreateStringBlob(GetOwnerGlobal(), aData, EmptyString()); + Blob::CreateStringBlob(GetOwner(), aData, EmptyString()); MOZ_ASSERT(blob); if (!ToJSValue(cx, blob, &jsData)) { diff --git a/dom/websocket/WebSocket.h b/dom/websocket/WebSocket.h index c25b350ec3c7..a43fe3d995b9 100644 --- a/dom/websocket/WebSocket.h +++ b/dom/websocket/WebSocket.h @@ -55,6 +55,8 @@ class WebSocket final : public DOMEventTargetHelper { virtual void DisconnectFromOwner() override; // nsWrapperCache + nsPIDOMWindowInner* GetParentObject() { return GetOwner(); } + virtual JSObject* WrapObject(JSContext* cx, JS::Handle aGivenProto) override; @@ -136,7 +138,7 @@ class WebSocket final : public DOMEventTargetHelper { void Send(const ArrayBufferView& aData, ErrorResult& aRv); private: // constructor && destructor - explicit WebSocket(nsIGlobalObject* aGlobal); + explicit WebSocket(nsPIDOMWindowInner* aOwnerWindow); virtual ~WebSocket(); void SetReadyState(uint16_t aReadyState); From 8e2534c46c7fb6033ac09cc6fdd35bd06a2248ff Mon Sep 17 00:00:00 2001 From: Nicolas Chevobbe Date: Fri, 29 Mar 2019 09:17:08 +0000 Subject: [PATCH 019/100] Bug 1538700 - Fix NotificationBox proptype. r=Honza. Differential Revision: https://phabricator.services.mozilla.com/D25358 --HG-- extra : moz-landing-system : lando --- devtools/client/shared/components/NotificationBox.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devtools/client/shared/components/NotificationBox.js b/devtools/client/shared/components/NotificationBox.js index 160953946549..4c96cfc6f8c4 100644 --- a/devtools/client/shared/components/NotificationBox.js +++ b/devtools/client/shared/components/NotificationBox.js @@ -73,7 +73,7 @@ class NotificationBox extends Component { // Message that should be shown when hovering over the close button closeButtonTooltip: PropTypes.string, // Wraps text when passed from console window as wrapping: true - wrapping: PropTypes.boolean, + wrapping: PropTypes.bool, }; } From 204f870fd6036a63fde1af6b90ad89055d0e1040 Mon Sep 17 00:00:00 2001 From: Johann Hofmann Date: Fri, 29 Mar 2019 09:33:58 +0000 Subject: [PATCH 020/100] Bug 1530348 - Unfork aboutNetError.{xhtml,css}. r=nhnt11 The larger changesets in this patch are simply moving code from one file into the other with hg mv. A short summary of the changes: - I removed the forked redirection from AboutRedirector.cpp - I deleted the original aboutNetError.xhtml and aboutNetError.css files and moved aboutNetError-new.xhtml and aboutNetError-new.css in their place instead. - I removed the browser.security.newcerterrorpage.enabled pref and all its usages. - I removed some localization strings and resources that went unused because of the above changes. Differential Revision: https://phabricator.services.mozilla.com/D25232 --HG-- extra : moz-landing-system : lando --- browser/actors/NetErrorChild.jsm | 135 +++----- browser/app/profile/firefox.js | 3 - browser/base/content/aboutNetError-new.xhtml | 237 -------------- browser/base/content/aboutNetError.js | 20 +- browser/base/content/aboutNetError.xhtml | 84 ++++- browser/base/content/browser.js | 62 ++-- .../test/about/browser_aboutCertError.js | 5 - .../about/browser_aboutCertError_clockSkew.js | 4 - .../about/browser_aboutCertError_exception.js | 16 +- .../test/about/browser_aboutCertError_mitm.js | 3 - .../about/browser_aboutCertError_telemetry.js | 8 +- browser/base/content/test/general/head.js | 41 --- .../base/content/test/siteIdentity/head.js | 43 --- .../browser_misused_characters_in_strings.js | 4 - browser/base/jar.mn | 1 - browser/components/about/AboutRedirector.cpp | 12 - browser/installer/allowed-dupes.mn | 3 - .../en-US/chrome/overrides/netError.dtd | 12 +- browser/themes/shared/aboutNetError-new.css | 290 ------------------ browser/themes/shared/aboutNetError.css | 104 ++++++- .../shared/incontent-icons/cert-error-new.svg | 7 - .../shared/incontent-icons/cert-error.svg | 46 +-- browser/themes/shared/jar.inc.mn | 2 - 23 files changed, 242 insertions(+), 900 deletions(-) delete mode 100644 browser/base/content/aboutNetError-new.xhtml delete mode 100644 browser/themes/shared/aboutNetError-new.css delete mode 100644 browser/themes/shared/incontent-icons/cert-error-new.svg diff --git a/browser/actors/NetErrorChild.jsm b/browser/actors/NetErrorChild.jsm index 0bd685b7f6e1..1aaa96971d15 100644 --- a/browser/actors/NetErrorChild.jsm +++ b/browser/actors/NetErrorChild.jsm @@ -24,8 +24,6 @@ XPCOMUtils.defineLazyGetter(this, "gPipNSSBundle", function() { XPCOMUtils.defineLazyGetter(this, "gBrandBundle", function() { return Services.strings.createBundle("chrome://branding/locale/brand.properties"); }); -XPCOMUtils.defineLazyPreferenceGetter(this, "newErrorPagesEnabled", - "browser.security.newcerterrorpage.enabled"); XPCOMUtils.defineLazyPreferenceGetter(this, "mitmErrorPageEnabled", "browser.security.newcerterrorpage.mitm.enabled"); XPCOMUtils.defineLazyPreferenceGetter(this, "mitmPrimingEnabled", @@ -128,7 +126,7 @@ class NetErrorChild extends ActorChild { if (input.data.certIsUntrusted) { switch (input.data.code) { case MOZILLA_PKIX_ERROR_MITM_DETECTED: - if (newErrorPagesEnabled && mitmErrorPageEnabled) { + if (mitmErrorPageEnabled) { let brandName = gBrandBundle.GetStringFromName("brandShortName"); msg1 = gPipNSSBundle.GetStringFromName("certErrorMitM"); msg1 += "\n\n"; @@ -141,17 +139,11 @@ class NetErrorChild extends ActorChild { // If the condition is false, fall through... case SEC_ERROR_UNKNOWN_ISSUER: let brandName = gBrandBundle.GetStringFromName("brandShortName"); - if (newErrorPagesEnabled) { - msg1 = ""; - msg1 += gPipNSSBundle.formatStringFromName("certErrorTrust_UnknownIssuer4", [hostString], 1); - msg1 += "\n\n"; - msg1 += gPipNSSBundle.formatStringFromName("certErrorTrust_UnknownIssuer6", [brandName, hostString], 2); - msg1 += "\n\n"; - } else { - msg1 += gPipNSSBundle.GetStringFromName("certErrorTrust_UnknownIssuer") + "\n"; - msg1 += gPipNSSBundle.GetStringFromName("certErrorTrust_UnknownIssuer2") + "\n"; - msg1 += gPipNSSBundle.GetStringFromName("certErrorTrust_UnknownIssuer3") + "\n"; - } + msg1 = ""; + msg1 += gPipNSSBundle.formatStringFromName("certErrorTrust_UnknownIssuer4", [hostString], 1); + msg1 += "\n\n"; + msg1 += gPipNSSBundle.formatStringFromName("certErrorTrust_UnknownIssuer6", [brandName, hostString], 2); + msg1 += "\n\n"; break; case SEC_ERROR_CA_CERT_INVALID: msg1 += gPipNSSBundle.GetStringFromName("certErrorTrust_CaInvalid") + "\n"; @@ -190,14 +182,10 @@ class NetErrorChild extends ActorChild { let msgPrefix = ""; if (numSubjectAltNames != 0) { if (numSubjectAltNames == 1) { - if (newErrorPagesEnabled) { - technicalInfo.textContent = ""; - let brandName = gBrandBundle.GetStringFromName("brandShortName"); - msgPrefix = gPipNSSBundle.formatStringFromName("certErrorMismatchSinglePrefix3", [brandName, hostString], 2) + " "; - msgPrefix += gPipNSSBundle.GetStringFromName("certErrorMismatchSinglePrefix"); - } else { - msgPrefix = gPipNSSBundle.GetStringFromName("certErrorMismatchSinglePrefix"); - } + technicalInfo.textContent = ""; + let brandName = gBrandBundle.GetStringFromName("brandShortName"); + msgPrefix = gPipNSSBundle.formatStringFromName("certErrorMismatchSinglePrefix3", [brandName, hostString], 2) + " "; + msgPrefix += gPipNSSBundle.GetStringFromName("certErrorMismatchSinglePrefix"); // Let's check if we want to make this a link. let okHost = input.data.certSubjectAltNames; let href = ""; @@ -264,13 +252,9 @@ class NetErrorChild extends ActorChild { technicalInfo.append("\n"); } else { let msg = ""; - if (newErrorPagesEnabled) { - technicalInfo.textContent = ""; - let brandName = gBrandBundle.GetStringFromName("brandShortName"); - msg = gPipNSSBundle.formatStringFromName("certErrorMismatchMultiple3", [brandName, hostString], 2) + " "; - } else { - msg = gPipNSSBundle.GetStringFromName("certErrorMismatchMultiple") + "\n"; - } + technicalInfo.textContent = ""; + let brandName = gBrandBundle.GetStringFromName("brandShortName"); + msg = gPipNSSBundle.formatStringFromName("certErrorMismatchMultiple3", [brandName, hostString], 2) + " "; for (let i = 0; i < numSubjectAltNames; i++) { msg += subjectAltNames[i]; if (i != (numSubjectAltNames - 1)) { @@ -281,61 +265,34 @@ class NetErrorChild extends ActorChild { } } else { let msg = ""; - if (newErrorPagesEnabled) { - technicalInfo.textContent = ""; - let brandName = gBrandBundle.GetStringFromName("brandShortName"); - msg = gPipNSSBundle.formatStringFromName("certErrorMismatch3", [brandName, hostString], 2) + " "; - } else { - msg = gPipNSSBundle.formatStringFromName("certErrorMismatch", - [hostString], 1); - } + technicalInfo.textContent = ""; + let brandName = gBrandBundle.GetStringFromName("brandShortName"); + msg = gPipNSSBundle.formatStringFromName("certErrorMismatch3", [brandName, hostString], 2) + " "; technicalInfo.append(msg + "\n"); } } if (input.data.isNotValidAtThisTime) { let nowTime = new Date().getTime() * 1000; - let dateOptions = { year: "numeric", month: "long", day: "numeric", hour: "numeric", minute: "numeric" }; - let now = new Services.intl.DateTimeFormat(undefined, dateOptions).format(new Date()); let msg = ""; if (input.data.validity.notBefore) { if (nowTime > input.data.validity.notAfter) { - if (newErrorPagesEnabled) { - technicalInfo.textContent = ""; - msg += gPipNSSBundle.formatStringFromName("certErrorExpiredNow2", - [hostString], 1); - msg += "\n"; - } else { - msg += gPipNSSBundle.formatStringFromName("certErrorExpiredNow", - [input.data.validity.notAfterLocalTime, now], 2); - msg += "\n"; - } + technicalInfo.textContent = ""; + msg += gPipNSSBundle.formatStringFromName("certErrorExpiredNow2", + [hostString], 1); + msg += "\n"; } else { - // eslint-disable-next-line no-lonely-if - if (newErrorPagesEnabled) { - technicalInfo.textContent = ""; - msg += gPipNSSBundle.formatStringFromName("certErrorNotYetValidNow2", - [hostString], 1); - msg += "\n"; - } else { - msg += gPipNSSBundle.formatStringFromName("certErrorNotYetValidNow", - [input.data.validity.notBeforeLocalTime, now], 2); - msg += "\n"; - } + technicalInfo.textContent = ""; + msg += gPipNSSBundle.formatStringFromName("certErrorNotYetValidNow2", + [hostString], 1); + msg += "\n"; } } else { - // If something goes wrong, we assume the cert expired. - // eslint-disable-next-line no-lonely-if - if (newErrorPagesEnabled) { - technicalInfo.textContent = ""; - msg += gPipNSSBundle.formatStringFromName("certErrorExpiredNow2", - [hostString], 1); - msg += "\n"; - } else { - msg += gPipNSSBundle.formatStringFromName("certErrorExpiredNow", - ["", now], 2); - msg += "\n"; - } + // If something goes wrong, we assume the cert expired. + technicalInfo.textContent = ""; + msg += gPipNSSBundle.formatStringFromName("certErrorExpiredNow2", + [hostString], 1); + msg += "\n"; } technicalInfo.append(msg); } @@ -387,8 +344,7 @@ class NetErrorChild extends ActorChild { // Check if the connection is being man-in-the-middled. When the parent // detects an intercepted connection, the page may be reloaded with a new // error code (MOZILLA_PKIX_ERROR_MITM_DETECTED). - if (newErrorPagesEnabled && mitmPrimingEnabled && - msg.data.code == SEC_ERROR_UNKNOWN_ISSUER && + if (mitmPrimingEnabled && msg.data.code == SEC_ERROR_UNKNOWN_ISSUER && // Only do this check for top-level failures. doc.ownerGlobal.top === doc.ownerGlobal) { this.mm.sendAsyncMessage("Browser:PrimeMitm"); @@ -433,9 +389,6 @@ class NetErrorChild extends ActorChild { case SSL_ERROR_BAD_CERT_DOMAIN: case SEC_ERROR_OCSP_INVALID_SIGNING_CERT: case SEC_ERROR_UNKNOWN_ISSUER: - if (!newErrorPagesEnabled) { - break; - } if (es) { // eslint-disable-next-line no-unsanitized/property es.innerHTML = errWhatToDo.innerHTML; @@ -468,7 +421,7 @@ class NetErrorChild extends ActorChild { updateContainerPosition(); break; case MOZILLA_PKIX_ERROR_MITM_DETECTED: - if (newErrorPagesEnabled && mitmErrorPageEnabled) { + if (mitmErrorPageEnabled) { let autoEnabledEnterpriseRoots = Services.prefs.getBoolPref("security.enterprise_roots.auto-enabled", false); if (mitmPrimingEnabled && autoEnabledEnterpriseRoots) { @@ -575,9 +528,7 @@ class NetErrorChild extends ActorChild { .textContent = formatter.format(systemDate); } } - if (!newErrorPagesEnabled) { - break; - } + let systemDate = formatter.format(new Date()); doc.getElementById("wrongSystemTime_systemDate1").textContent = systemDate; if (clockSkew) { @@ -640,18 +591,16 @@ class NetErrorChild extends ActorChild { // Add slightly more alarming UI unless there are indicators that // show that the error is harmless or can not be skipped anyway. - if (newErrorPagesEnabled) { - let {cssClass} = this.getParams(doc); - // Don't alarm users when they can't continue to the website anyway... - if (cssClass != "badStsCert" && - // Errors in iframes can't be skipped either... - doc.ownerGlobal.parent == doc.ownerGlobal && - // Also don't bother if it's just the user's clock being off... - !clockSkew && - // Symantec distrust is likely harmless as well. - msg.data.code != MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED) { - doc.body.classList.add("caution"); - } + let {cssClass} = this.getParams(doc); + // Don't alarm users when they can't continue to the website anyway... + if (cssClass != "badStsCert" && + // Errors in iframes can't be skipped either... + doc.ownerGlobal.parent == doc.ownerGlobal && + // Also don't bother if it's just the user's clock being off... + !clockSkew && + // Symantec distrust is likely harmless as well. + msg.data.code != MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED) { + doc.body.classList.add("caution"); } } diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index 00a4bd74620a..db415959d017 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -968,9 +968,6 @@ pref("app.productInfo.baseURL", "https://www.mozilla.org/firefox/features/"); // Name of alternate about: page for certificate errors (when undefined, defaults to about:neterror) pref("security.alternate_certificate_error_page", "certerror"); -// Enable the new certificate error pages. -pref("browser.security.newcerterrorpage.enabled", true); - pref("browser.security.newcerterrorpage.mitm.enabled", true); pref("security.certerrors.recordEventTelemetry", true); pref("security.certerrors.permanentOverride", true); diff --git a/browser/base/content/aboutNetError-new.xhtml b/browser/base/content/aboutNetError-new.xhtml deleted file mode 100644 index c3ea5d25a580..000000000000 --- a/browser/base/content/aboutNetError-new.xhtml +++ /dev/null @@ -1,237 +0,0 @@ - - - - %htmlDTD; - - %netErrorDTD; - - %globalDTD; -]> - - - - - - - &loadError.label; - - - - - - - -
-
- &certerror.pagetitle2; - &certerror.sts.pagetitle; - &captivePortal.title; - &dnsNotFound.pageTitle; - &malformedURI.pageTitle; - &blockedByPolicy.title; -
-
-

&generic.title;

-

&captivePortal.title;

-

&dnsNotFound.title1;

-

&fileNotFound.title;

-

&fileAccessDenied.title;

-

&malformedURI.title1;

-

&unknownProtocolFound.title;

-

&connectionFailure.title;

-

&netTimeout.title;

-

&redirectLoop.title;

-

&unknownSocketType.title;

-

&netReset.title;

-

¬Cached.title;

-

&netOffline.title;

-

&netInterrupt.title;

-

&deniedPortAccess.title;

-

&proxyResolveFailure.title;

-

&proxyConnectFailure.title;

-

&contentEncodingError.title;

-

&unsafeContentType.title;

-

&nssFailure2.title;

-

&certerror.longpagetitle2;

-

&certerror.sts.longpagetitle;

-

&cspBlocked.title;

-

&remoteXUL.title;

-

&corruptedContentErrorv2.title;

-

&sslv3Used.title;

-

&inadequateSecurityError.title;

-

&blockedByPolicy.title;

-

&certerror.mitm.title;

-

&clockSkewError.title;

-

&networkProtocolError.title;

-
-
-
&generic.longDesc;
-
&captivePortal.longDesc2;
-
&dnsNotFound.longDesc1;
-
&fileNotFound.longDesc;
-
&fileAccessDenied.longDesc;
-
-
&unknownProtocolFound.longDesc;
-
&connectionFailure.longDesc;
-
&netTimeout.longDesc;
-
&redirectLoop.longDesc;
-
&unknownSocketType.longDesc;
-
&netReset.longDesc;
-
¬Cached.longDesc;
-
&netOffline.longDesc2;
-
&netInterrupt.longDesc;
-
&deniedPortAccess.longDesc;
-
&proxyResolveFailure.longDesc;
-
&proxyConnectFailure.longDesc;
-
&contentEncodingError.longDesc;
-
&unsafeContentType.longDesc;
-
&nssFailure2.longDesc2;
-
&certerror.introPara2;
-
&certerror.sts.introPara;
-
&certerror.expiredCert.introPara;
-
&certerror.mitm.longDesc;
-
&cspBlocked.longDesc;
-
&remoteXUL.longDesc;
-
&corruptedContentErrorv2.longDesc;
-
&sslv3Used.longDesc2;
-
&inadequateSecurityError.longDesc;
-
-
&clockSkewError.longDesc;
-
&networkProtocolError.longDesc;
-
-
-
&certerror.expiredCert.secondPara2;
-
&certerror.expiredCert.sts.secondPara;
-
-
-
&certerror.whatCanYouDoAboutItTitle;
-
-
-
&certerror.unknownIssuer.whatCanYouDoAboutIt;
-
&certerror.expiredCert.whatCanYouDoAboutIt2;
-
&certerror.expiredCert.whatCanYouDoAboutIt2;
-
&certerror.expiredCert.whatCanYouDoAboutIt2;
-
&certerror.expiredCert.whatCanYouDoAboutIt2;
-
&certerror.badCertDomain.whatCanYouDoAboutIt;
-
-
    -
  • &certerror.mitm.whatCanYouDoAboutIt1;
  • -
  • &certerror.mitm.whatCanYouDoAboutIt2;
  • -
  • &certerror.mitm.whatCanYouDoAboutIt3;
  • -
-
-
- - &returnToPreviousPage.label; - &certerror.mitm.sts.whatCanYouDoAboutIt3; -
- - -
-
- -
-

-

- - -
- - -
-

-

- -
-

-

- -
-

-

- -
- -

-

- -
-

-

-
- -
- &certerror.wrongSystemTime2; -
- -
- &certerror.wrongSystemTimeWithoutReference; -
- - - - - -
-

&prefReset.longDesc;

- -
- -
- - - - -
-
- -
- -
- -
-
-

- &viewCertificate.label; -

- - -
- -
-
-
- -
-

- - -

-
- -
- -
- -
-
-
- - + diff --git a/testing/web-platform/tests/xhtml/adopt-while-parsing.xhtml b/testing/web-platform/tests/xhtml/adopt-while-parsing.xhtml new file mode 100644 index 000000000000..2d85d21558b1 --- /dev/null +++ b/testing/web-platform/tests/xhtml/adopt-while-parsing.xhtml @@ -0,0 +1,11 @@ + + + + +
+ PASS +
+ + From 100931f6b92e3506bdd0a3fd12fea4a35e4ae0ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A3o=20Gottwald?= Date: Thu, 28 Mar 2019 17:50:44 +0000 Subject: [PATCH 028/100] Bug 1537767 - Adjust --tabs-navbar-shadow-size for 300% DPI. r=Gijs Differential Revision: https://phabricator.services.mozilla.com/D25048 --HG-- extra : moz-landing-system : lando --- browser/themes/shared/browser.inc.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/browser/themes/shared/browser.inc.css b/browser/themes/shared/browser.inc.css index 4f8e30c832ea..1834faeaa4e1 100644 --- a/browser/themes/shared/browser.inc.css +++ b/browser/themes/shared/browser.inc.css @@ -25,6 +25,12 @@ } } +@media (min-resolution: 3dppx) { + :root { + --tabs-navbar-shadow-size: 0.33px; + } +} + /* Increase contrast of UI links on dark themes */ :root[lwt-popup-brighttext] panel .text-link { From ca307a61f16bddd1cf2a0d9860d5efacef784294 Mon Sep 17 00:00:00 2001 From: Petru Lingurar Date: Fri, 29 Mar 2019 07:57:51 +0000 Subject: [PATCH 029/100] Bug 1506231 - Top Sites tiles will show only one site for the same base url; r=JanH Differential Revision: https://phabricator.services.mozilla.com/D24487 --HG-- extra : moz-landing-system : lando --- .../homepanel/ActivityStreamPanel.java | 7 ++- .../homepanel/stream/TopPanelRow.java | 63 ++++++++++++++++++- 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/ActivityStreamPanel.java b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/ActivityStreamPanel.java index 591474f92948..3a2d7f3a348e 100644 --- a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/ActivityStreamPanel.java +++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/ActivityStreamPanel.java @@ -192,12 +192,15 @@ public class ActivityStreamPanel extends FrameLayout { @Override public Loader onCreateLoader(int id, Bundle args) { final int topSitesPerPage = TopSitesPage.NUM_COLUMNS * TopSitesPage.NUM_ROWS; + // Top Sites limit multiplier needed to account for duplicated base URLs which will be ignored. + // Speculative value. May be changed depending on user feedback. + final int limitMultiplier = 3; final Context context = getContext(); return BrowserDB.from(context).getActivityStreamTopSites( context, - topSitesPerPage * TopSitesPagerAdapter.SUGGESTED_SITES_MAX_PAGES, - topSitesPerPage * TopSitesPagerAdapter.PAGES); + topSitesPerPage * TopSitesPagerAdapter.SUGGESTED_SITES_MAX_PAGES * limitMultiplier, + topSitesPerPage * TopSitesPagerAdapter.PAGES * limitMultiplier); } @Override diff --git a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/stream/TopPanelRow.java b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/stream/TopPanelRow.java index 865eca516fac..4a71238b912c 100644 --- a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/stream/TopPanelRow.java +++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/stream/TopPanelRow.java @@ -7,6 +7,8 @@ package org.mozilla.gecko.activitystream.homepanel.stream; import android.content.res.Resources; import android.database.Cursor; +import android.database.MatrixCursor; +import android.support.annotation.Nullable; import android.support.v4.view.ViewPager; import android.view.View; import android.view.ViewGroup; @@ -14,11 +16,18 @@ import android.view.ViewGroup; import org.mozilla.gecko.R; import org.mozilla.gecko.Telemetry; import org.mozilla.gecko.TelemetryContract; +import org.mozilla.gecko.activitystream.homepanel.model.Metadata; import org.mozilla.gecko.activitystream.homepanel.model.TopSite; import org.mozilla.gecko.activitystream.homepanel.topsites.TopSitesPage; import org.mozilla.gecko.activitystream.homepanel.topsites.TopSitesPagerAdapter; +import org.mozilla.gecko.db.BrowserContract; import org.mozilla.gecko.home.HomePager; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashSet; +import java.util.Set; + public class TopPanelRow extends StreamViewHolder { public static final int LAYOUT_ID = R.layout.activity_stream_main_toppanel; @@ -61,7 +70,8 @@ public class TopPanelRow extends StreamViewHolder { public void bind(Cursor cursor, int tilesSize) { final TopSitesPagerAdapter adapter = (TopSitesPagerAdapter) topSitesPager.getAdapter(); - adapter.swapCursor(cursor, tilesSize); + final Cursor filteredCursor = getCursorForUniqueBaseUrls(cursor); + adapter.swapCursor(filteredCursor, tilesSize); final Resources resources = itemView.getResources(); final int tilesMargin = resources.getDimensionPixelSize(R.dimen.activity_stream_base_margin); @@ -72,7 +82,7 @@ public class TopPanelRow extends StreamViewHolder { // set initially (while we load the Cursor) and these rows (with no content) will be briefly visible // to users. Since we expect 2 rows to be the most common for users, we show 2 rows at this point; // the RecyclerView will gracefully animate a collapse if we display fewer. - if (cursor == null || cursor.getCount() > TopSitesPage.NUM_COLUMNS) { + if (filteredCursor == null || filteredCursor.getCount() > TopSitesPage.NUM_COLUMNS) { rows = 2; } else if (cursor.getCount() > 0) { rows = 1; @@ -91,6 +101,55 @@ public class TopPanelRow extends StreamViewHolder { swipeListener.currentPosition = 0; } + @Nullable + private Cursor getCursorForUniqueBaseUrls(final Cursor cursor) { + if (cursor == null || !cursor.moveToFirst()) { + return cursor; + } + + final String[] projection = new String[] { + BrowserContract.Combined._ID, + BrowserContract.Combined.BOOKMARK_ID, + BrowserContract.Combined.HISTORY_ID, + BrowserContract.Combined.URL, + BrowserContract.Combined.TITLE, + BrowserContract.Highlights.POSITION, + BrowserContract.TopSites.TYPE, + BrowserContract.TopSites.PAGE_METADATA_JSON, + }; + final int limit = TopSitesPage.NUM_TILES * TopSitesPagerAdapter.PAGES; + final MatrixCursor filteredCursor = new MatrixCursor(projection); + final Set urls = new HashSet(limit); + do { + String baseUrl = getBaseForUrl(cursor.getString(cursor.getColumnIndex(BrowserContract.Combined.URL))); + if (!urls.contains(baseUrl)) { + final Object[] originalColumns = new Object[] { + cursor.getLong(cursor.getColumnIndex(BrowserContract.Combined._ID)), + cursor.getLong(cursor.getColumnIndex(BrowserContract.Combined.BOOKMARK_ID)), + cursor.getLong(cursor.getColumnIndex(BrowserContract.Combined.HISTORY_ID)), + cursor.getString(cursor.getColumnIndex(BrowserContract.Combined.URL)), + cursor.getString(cursor.getColumnIndex(BrowserContract.Combined.TITLE)), + cursor.getInt(cursor.getColumnIndex(BrowserContract.Highlights.POSITION)), + cursor.getInt(cursor.getColumnIndex(BrowserContract.TopSites.TYPE)), + Metadata.fromCursor(cursor, BrowserContract.TopSites.PAGE_METADATA_JSON) + }; + // match the original cursor fields + filteredCursor.addRow(originalColumns); + urls.add(baseUrl); + } + } while (filteredCursor.getCount() < limit && cursor.moveToNext()); + + return filteredCursor; + } + + private String getBaseForUrl(final String url) { + try { + return new URL(url).getHost(); + } catch (MalformedURLException e) { + return null; + } + } + public interface OnCardLongClickListener { boolean onLongClick(TopSite topSite, int absolutePosition, View tabletContextMenuAnchor, int faviconWidth, int faviconHeight); } From d00c43f03305ea735a9c1cad5097c14dce65ffad Mon Sep 17 00:00:00 2001 From: Dorel Luca Date: Fri, 29 Mar 2019 12:27:27 +0200 Subject: [PATCH 030/100] Backed out changeset b81febb43f21 (bug 1539528) for Mochitest failues in dom/websocket/tests/test_webSocket_sharedWorker.html. CLOSED TREE --- dom/websocket/WebSocket.cpp | 40 +++++++++++++++++++++---------------- dom/websocket/WebSocket.h | 4 +++- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/dom/websocket/WebSocket.cpp b/dom/websocket/WebSocket.cpp index 6d323505dc84..96cd8f98fe1e 100644 --- a/dom/websocket/WebSocket.cpp +++ b/dom/websocket/WebSocket.cpp @@ -870,8 +870,8 @@ WebSocketImpl::GetInterface(const nsIID& aIID, void** aResult) { // WebSocket //////////////////////////////////////////////////////////////////////////////// -WebSocket::WebSocket(nsIGlobalObject* aGlobal) - : DOMEventTargetHelper(aGlobal), +WebSocket::WebSocket(nsPIDOMWindowInner* aOwnerWindow) + : DOMEventTargetHelper(aOwnerWindow), mIsMainThread(true), mKeepingAlive(false), mCheckMustKeepAlive(true), @@ -879,8 +879,6 @@ WebSocket::WebSocket(nsIGlobalObject* aGlobal) mBinaryType(dom::BinaryType::Blob), mMutex("WebSocket::mMutex"), mReadyState(CONNECTING) { - MOZ_ASSERT(aGlobal); - mImpl = new WebSocketImpl(this); mIsMainThread = mImpl->mIsMainThread; } @@ -1182,12 +1180,7 @@ already_AddRefed WebSocket::ConstructorCommon( const nsACString& aNegotiatedExtensions, ErrorResult& aRv) { MOZ_ASSERT_IF(!aTransportProvider, aNegotiatedExtensions.IsEmpty()); nsCOMPtr principal; - - nsCOMPtr global = do_QueryInterface(aGlobal.GetAsSupports()); - if (NS_WARN_IF(!global)) { - aRv.Throw(NS_ERROR_FAILURE); - return nullptr; - } + nsCOMPtr ownerWindow; if (NS_IsMainThread()) { nsCOMPtr scriptPrincipal = @@ -1209,6 +1202,12 @@ already_AddRefed WebSocket::ConstructorCommon( aRv.Throw(NS_ERROR_FAILURE); return nullptr; } + + ownerWindow = do_QueryInterface(aGlobal.GetAsSupports()); + if (!ownerWindow) { + aRv.Throw(NS_ERROR_FAILURE); + return nullptr; + } } nsTArray protocolArray; @@ -1232,7 +1231,7 @@ already_AddRefed WebSocket::ConstructorCommon( protocolArray.AppendElement(protocolElement); } - RefPtr webSocket = new WebSocket(global); + RefPtr webSocket = new WebSocket(ownerWindow); RefPtr webSocketImpl = webSocket->mImpl; bool connectionFailed = true; @@ -1350,7 +1349,6 @@ already_AddRefed WebSocket::ConstructorCommon( if (NS_IsMainThread()) { MOZ_ASSERT(principal); - nsCOMPtr ownerWindow = do_QueryInterface(global); nsPIDOMWindowOuter* outerWindow = ownerWindow->GetOuterWindow(); uint64_t windowID = 0; @@ -1429,8 +1427,7 @@ void WebSocket::DisconnectFromOwner() { // If we haven't called WebSocketImpl::Disconnect yet, update web // socket count here. - if (mImpl && !mImpl->mDisconnectingOrDisconnected && mIsMainThread && - GetOwner()) { + if (mImpl && !mImpl->mDisconnectingOrDisconnected) { GetOwner()->UpdateWebSocketCount(-1); } @@ -1803,8 +1800,17 @@ nsresult WebSocket::CreateAndDispatchMessageEvent(const nsACString& aData, AssertIsOnTargetThread(); AutoJSAPI jsapi; - if (NS_WARN_IF(!jsapi.Init(GetOwnerGlobal()))) { - return NS_ERROR_FAILURE; + + if (NS_IsMainThread()) { + if (NS_WARN_IF(!jsapi.Init(GetOwner()))) { + return NS_ERROR_FAILURE; + } + } else { + MOZ_ASSERT(!mIsMainThread); + MOZ_ASSERT(mImpl->mWorkerRef); + if (NS_WARN_IF(!jsapi.Init(mImpl->mWorkerRef->Private()->GlobalScope()))) { + return NS_ERROR_FAILURE; + } } JSContext* cx = jsapi.cx(); @@ -1823,7 +1829,7 @@ nsresult WebSocket::CreateAndDispatchMessageEvent(const nsACString& aData, messageType = nsIWebSocketEventListener::TYPE_BLOB; RefPtr blob = - Blob::CreateStringBlob(GetOwnerGlobal(), aData, EmptyString()); + Blob::CreateStringBlob(GetOwner(), aData, EmptyString()); MOZ_ASSERT(blob); if (!ToJSValue(cx, blob, &jsData)) { diff --git a/dom/websocket/WebSocket.h b/dom/websocket/WebSocket.h index c25b350ec3c7..a43fe3d995b9 100644 --- a/dom/websocket/WebSocket.h +++ b/dom/websocket/WebSocket.h @@ -55,6 +55,8 @@ class WebSocket final : public DOMEventTargetHelper { virtual void DisconnectFromOwner() override; // nsWrapperCache + nsPIDOMWindowInner* GetParentObject() { return GetOwner(); } + virtual JSObject* WrapObject(JSContext* cx, JS::Handle aGivenProto) override; @@ -136,7 +138,7 @@ class WebSocket final : public DOMEventTargetHelper { void Send(const ArrayBufferView& aData, ErrorResult& aRv); private: // constructor && destructor - explicit WebSocket(nsIGlobalObject* aGlobal); + explicit WebSocket(nsPIDOMWindowInner* aOwnerWindow); virtual ~WebSocket(); void SetReadyState(uint16_t aReadyState); From bcfd6cd96195f2d0c7c28435c56ca613d7a6e3eb Mon Sep 17 00:00:00 2001 From: Patrick Brosset Date: Fri, 29 Mar 2019 09:47:35 +0000 Subject: [PATCH 031/100] Bug 1409085 - Tell RDM when picking to stop simulating touch; r=mtigley,gl Differential Revision: https://phabricator.services.mozilla.com/D25231 --HG-- extra : moz-landing-system : lando --- devtools/client/framework/toolbox.js | 23 ++++++++++++++++++ devtools/server/actors/emulation.js | 24 +++++++++++++++++++ .../actors/emulation/touch-simulator.js | 16 +++++++++++++ devtools/shared/specs/emulation.js | 7 ++++++ 4 files changed, 70 insertions(+) diff --git a/devtools/client/framework/toolbox.js b/devtools/client/framework/toolbox.js index 3a46f2497c99..3426c0b4454c 100644 --- a/devtools/client/framework/toolbox.js +++ b/devtools/client/framework/toolbox.js @@ -64,6 +64,8 @@ loader.lazyRequireGetter(this, "createEditContextMenu", "devtools/client/framework/toolbox-context-menu", true); loader.lazyRequireGetter(this, "remoteClientManager", "devtools/client/shared/remote-debugging/remote-client-manager.js", true); +loader.lazyRequireGetter(this, "ResponsiveUIManager", + "devtools/client/responsive.html/manager", true); loader.lazyGetter(this, "domNodeConstants", () => { return require("devtools/shared/dom-node-constants"); @@ -1343,6 +1345,7 @@ Toolbox.prototype = { }, _onPickerStarting: async function() { + this.tellRDMAboutPickerState(true); this.pickerButton.isChecked = true; await this.selectTool("inspector", "inspect_dom"); this.on("select", this.inspector.nodePicker.stop); @@ -1354,11 +1357,31 @@ Toolbox.prototype = { }, _onPickerStopped: function() { + this.tellRDMAboutPickerState(false); this.off("select", this.inspector.nodePicker.stop); this.doc.removeEventListener("keypress", this._onPickerKeypress, true); this.pickerButton.isChecked = false; }, + /** + * RDM sometimes simulates touch events. For this to work correctly at all times, it + * needs to know when the picker is active or not. + * This method communicates with the RDM Manager if it exists. + * + * @param {Boolean} state + */ + tellRDMAboutPickerState: async function(state) { + const { tab } = this.target; + + if (!ResponsiveUIManager.isActiveForTab(tab) || + await !this.target.actorHasMethod("emulation", "setElementPickerState")) { + return; + } + + const ui = ResponsiveUIManager.getResponsiveUIForTab(tab); + await ui.emulationFront.setElementPickerState(state); + }, + /** * When the picker is canceled, make sure the toolbox * gets the focus. diff --git a/devtools/server/actors/emulation.js b/devtools/server/actors/emulation.js index ab00b246ebbf..c3c6f4585d71 100644 --- a/devtools/server/actors/emulation.js +++ b/devtools/server/actors/emulation.js @@ -177,6 +177,30 @@ const EmulationActor = protocol.ActorClassWithSpec(emulationSpec, { _previousTouchEventsOverride: undefined, + /** + * Set the current element picker state. + * + * True means the element picker is currently active and we should not be emulating + * touch events. + * False means the element picker is not active and it is ok to emulate touch events. + * + * This actor method is meant to be called by the DevTools front-end. The reason for + * this is the following: + * RDM is the only current consumer of the touch simulator. RDM instantiates this actor + * on its own, whether or not the Toolbox is opened. That means it does so in its own + * Debugger Server instance. + * When the Toolbox is running, it uses a different DebuggerServer. Therefore, it is not + * possible for the touch simulator to know whether the picker is active or not. This + * state has to be sent by the client code of the Toolbox to this actor. + * If a future use case arises where we want to use the touch simulator from the Toolbox + * too, then we could add code in here to detect the picker mode as described in + * https://bugzilla.mozilla.org/show_bug.cgi?id=1409085#c3 + * @param {Boolean} state + */ + setElementPickerState(state) { + this.touchSimulator.setElementPickerState(state); + }, + setTouchEventsOverride(flag) { if (this.getTouchEventsOverride() == flag) { return false; diff --git a/devtools/server/actors/emulation/touch-simulator.js b/devtools/server/actors/emulation/touch-simulator.js index cccecbf0a243..88834ff63ddf 100644 --- a/devtools/server/actors/emulation/touch-simulator.js +++ b/devtools/server/actors/emulation/touch-simulator.js @@ -73,7 +73,23 @@ TouchSimulator.prototype = { this.enabled = false; }, + /** + * Set the current element picker state value. + * True means the element picker is currently active and we should not be emulating + * touch events. + * False means the element picker is not active and it is ok to emulate touch events. + * @param {Boolean} state + */ + setElementPickerState(state) { + this._isPicking = state; + }, + handleEvent(evt) { + // Bail out if devtools is in pick mode in the same tab. + if (this._isPicking) { + return; + } + // The gaia system window use an hybrid system even on the device which is // a mix of mouse/touch events. So let's not cancel *all* mouse events // if it is the current target. diff --git a/devtools/shared/specs/emulation.js b/devtools/shared/specs/emulation.js index bf716d5d5d15..f0448d2ea191 100644 --- a/devtools/shared/specs/emulation.js +++ b/devtools/shared/specs/emulation.js @@ -123,6 +123,13 @@ const emulationSpec = generateActorSpec({ valueChanged: RetVal("boolean"), }, }, + + setElementPickerState: { + request: { + state: Arg(0, "boolean"), + }, + response: {}, + }, }, }); From 624de11cb10c4f3260811cb2ed8cd306afd8cac4 Mon Sep 17 00:00:00 2001 From: Liang-Heng Chen Date: Fri, 29 Mar 2019 10:49:58 +0000 Subject: [PATCH 032/100] Bug 1492587 - spoof date picker to en-US when pref is set; r=zbraniecki,baku spoof locale on datepicker to English when privacy.spoof_english == 2 Differential Revision: https://phabricator.services.mozilla.com/D19148 --HG-- extra : moz-landing-system : lando --- dom/base/nsGlobalWindowInner.cpp | 13 ++++++ dom/base/nsGlobalWindowInner.h | 2 + dom/webidl/Window.webidl | 17 ++++++++ intl/docs/locale.rst | 10 +++++ intl/locale/LocaleService.cpp | 43 ++++++++++++++++++- intl/locale/LocaleService.h | 6 +++ intl/locale/mozILocaleService.idl | 2 + intl/locale/tests/gtest/TestLocaleService.cpp | 24 +++++++++++ modules/libpref/init/StaticPrefList.h | 7 +++ toolkit/content/widgets/datetimebox.js | 2 +- toolkit/modules/DateTimePickerPanel.jsm | 2 +- 11 files changed, 125 insertions(+), 3 deletions(-) diff --git a/dom/base/nsGlobalWindowInner.cpp b/dom/base/nsGlobalWindowInner.cpp index 4ab0cb2a8db8..cee6223b9cfc 100644 --- a/dom/base/nsGlobalWindowInner.cpp +++ b/dom/base/nsGlobalWindowInner.cpp @@ -6796,6 +6796,8 @@ Worklet* nsGlobalWindowInner::GetPaintWorklet(ErrorResult& aRv) { void nsGlobalWindowInner::GetRegionalPrefsLocales( nsTArray& aLocales) { + MOZ_ASSERT(mozilla::intl::LocaleService::GetInstance()); + AutoTArray rpLocales; mozilla::intl::LocaleService::GetInstance()->GetRegionalPrefsLocales( rpLocales); @@ -6805,6 +6807,17 @@ void nsGlobalWindowInner::GetRegionalPrefsLocales( } } +void nsGlobalWindowInner::GetWebExposedLocales(nsTArray& aLocales) { + MOZ_ASSERT(mozilla::intl::LocaleService::GetInstance()); + + AutoTArray rpLocales; + mozilla::intl::LocaleService::GetInstance()->GetWebExposedLocales(rpLocales); + + for (const auto& loc : rpLocales) { + aLocales.AppendElement(NS_ConvertUTF8toUTF16(loc)); + } +} + IntlUtils* nsGlobalWindowInner::GetIntlUtils(ErrorResult& aError) { if (!mIntlUtils) { mIntlUtils = new IntlUtils(this); diff --git a/dom/base/nsGlobalWindowInner.h b/dom/base/nsGlobalWindowInner.h index 624c866dbdd1..f806aa985fdf 100644 --- a/dom/base/nsGlobalWindowInner.h +++ b/dom/base/nsGlobalWindowInner.h @@ -633,6 +633,8 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget, void GetRegionalPrefsLocales(nsTArray& aLocales); + void GetWebExposedLocales(nsTArray& aLocales); + mozilla::dom::IntlUtils* GetIntlUtils(mozilla::ErrorResult& aRv); void StoreSharedWorker(mozilla::dom::SharedWorker* aSharedWorker); diff --git a/dom/webidl/Window.webidl b/dom/webidl/Window.webidl index aa08bd7f8947..91128a398b93 100644 --- a/dom/webidl/Window.webidl +++ b/dom/webidl/Window.webidl @@ -577,6 +577,23 @@ partial interface Window { [Func="IsChromeOrXBLOrUAWidget"] sequence getRegionalPrefsLocales(); + /** + * Returns a list of locales that the web content would know from the user. + * + * One of the fingerprinting technique is to recognize users from their locales + * exposed to web content. For those components that would be fingerprintable + * from the locale should call this API instead of |getRegionalPrefsLocales()|. + * + * If the pref is set to spoof locale setting, this function will return the + * spoofed locale, otherwise it returns what |getRegionalPrefsLocales()| returns. + * + * This API always returns at least one locale. + * + * Example: ["en-US"] + */ + [Func="IsChromeOrXBLOrUAWidget"] + sequence getWebExposedLocales(); + /** * Getter funcion for IntlUtils, which provides helper functions for * localization. diff --git a/intl/docs/locale.rst b/intl/docs/locale.rst index 1478e4139de6..08de6f72337a 100644 --- a/intl/docs/locale.rst +++ b/intl/docs/locale.rst @@ -428,6 +428,16 @@ the locales are packaged to allow for bundling applications with different sets of locales in different areas - dictionaries, hyphenations, product language resources, installer language resources, etc. +Web Exposed Locales +==================== + +For anti-tracking or some other reasons, we tend to expose spoofed locale to web content instead +of default locales. This can be done by setting the pref :js:`intl.locale.privacy.web_exposed`. +The pref is a comma separated list of locale, and empty string implies default locales. + +The pref has no function while :js:`privacy.spoof_english` is set to 2, where *"en-US"* will always +be returned. + Multi-Process ============= diff --git a/intl/locale/LocaleService.cpp b/intl/locale/LocaleService.cpp index abbe759c5b41..c0cd3a5af718 100644 --- a/intl/locale/LocaleService.cpp +++ b/intl/locale/LocaleService.cpp @@ -11,6 +11,7 @@ #include "mozilla/Omnijar.h" #include "mozilla/Preferences.h" #include "mozilla/Services.h" +#include "mozilla/StaticPrefs.h" #include "mozilla/intl/MozLocale.h" #include "mozilla/intl/OSPreferences.h" #include "nsDirectoryService.h" @@ -26,8 +27,10 @@ #define INTL_SYSTEM_LOCALES_CHANGED "intl:system-locales-changed" #define REQUESTED_LOCALES_PREF "intl.locale.requested" +#define WEB_EXPOSED_LOCALES_PREF "intl.locale.privacy.web_exposed" -static const char* kObservedPrefs[] = {REQUESTED_LOCALES_PREF, nullptr}; +static const char* kObservedPrefs[] = {REQUESTED_LOCALES_PREF, + WEB_EXPOSED_LOCALES_PREF, nullptr}; using namespace mozilla::intl; using namespace mozilla; @@ -120,6 +123,16 @@ static void ReadRequestedLocales(nsTArray& aRetVal) { } } +static void ReadWebExposedLocales(nsTArray& aRetVal) { + nsAutoCString str; + nsresult rv = Preferences::GetCString(WEB_EXPOSED_LOCALES_PREF, str); + if (NS_WARN_IF(NS_FAILED(rv)) || str.Length() == 0) { + return; + } + + SplitLocaleListStringIntoArray(str, aRetVal); +} + LocaleService::LocaleService(bool aIsServer) : mIsServer(aIsServer) {} /** @@ -230,6 +243,16 @@ void LocaleService::RequestedLocalesChanged() { } } +void LocaleService::WebExposedLocalesChanged() { + MOZ_ASSERT(mIsServer, "This should only be called in the server mode."); + + nsTArray newLocales; + ReadWebExposedLocales(newLocales); + if (mWebExposedLocales != newLocales) { + mWebExposedLocales = std::move(newLocales); + } +} + void LocaleService::LocalesChanged() { MOZ_ASSERT(mIsServer, "This should only be called in the server mode."); @@ -425,12 +448,15 @@ LocaleService::Observe(nsISupports* aSubject, const char* aTopic, if (!strcmp(aTopic, INTL_SYSTEM_LOCALES_CHANGED)) { RequestedLocalesChanged(); + WebExposedLocalesChanged(); } else { NS_ConvertUTF16toUTF8 pref(aData); // At the moment the only thing we're observing are settings indicating // user requested locales. if (pref.EqualsLiteral(REQUESTED_LOCALES_PREF)) { RequestedLocalesChanged(); + } else if (pref.EqualsLiteral(WEB_EXPOSED_LOCALES_PREF)) { + WebExposedLocalesChanged(); } } @@ -636,6 +662,21 @@ LocaleService::GetRegionalPrefsLocales(nsTArray& aRetVal) { return NS_OK; } +NS_IMETHODIMP +LocaleService::GetWebExposedLocales(nsTArray& aRetVal) { + if (StaticPrefs::privacy_spoof_english() == 2) { + aRetVal = nsTArray({NS_LITERAL_CSTRING("en-US")}); + return NS_OK; + } + + if (!mWebExposedLocales.IsEmpty()) { + aRetVal = mWebExposedLocales; + return NS_OK; + } + + return GetRegionalPrefsLocales(aRetVal); +} + NS_IMETHODIMP LocaleService::NegotiateLanguages(const nsTArray& aRequested, const nsTArray& aAvailable, diff --git a/intl/locale/LocaleService.h b/intl/locale/LocaleService.h index 92755c89ff77..bb7d71450ec8 100644 --- a/intl/locale/LocaleService.h +++ b/intl/locale/LocaleService.h @@ -132,6 +132,11 @@ class LocaleService final : public mozILocaleService, void RequestedLocalesChanged(); void LocalesChanged(); + /** + * This function keeps the pref setting updated. + */ + void WebExposedLocalesChanged(); + /** * Returns whether the current app locale is RTL. */ @@ -158,6 +163,7 @@ class LocaleService final : public mozILocaleService, nsTArray mRequestedLocales; nsTArray mAvailableLocales; nsTArray mPackagedLocales; + nsTArray mWebExposedLocales; const bool mIsServer; static StaticRefPtr sInstance; diff --git a/intl/locale/mozILocaleService.idl b/intl/locale/mozILocaleService.idl index 41ca6e3e6af0..e5d71b2fdb36 100644 --- a/intl/locale/mozILocaleService.idl +++ b/intl/locale/mozILocaleService.idl @@ -97,6 +97,8 @@ interface mozILocaleService : nsISupports */ readonly attribute Array regionalPrefsLocales; + readonly attribute Array webExposedLocales; + /** * Negotiates the best locales out of a ordered list of requested locales and * a list of available locales. diff --git a/intl/locale/tests/gtest/TestLocaleService.cpp b/intl/locale/tests/gtest/TestLocaleService.cpp index 3d87f0424db6..89c239b6700d 100644 --- a/intl/locale/tests/gtest/TestLocaleService.cpp +++ b/intl/locale/tests/gtest/TestLocaleService.cpp @@ -4,6 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "gtest/gtest.h" +#include "mozilla/Preferences.h" #include "mozilla/intl/LocaleService.h" #include "mozilla/intl/MozLocale.h" #include "nsIToolkitChromeRegistry.h" @@ -53,6 +54,29 @@ TEST(Intl_Locale_LocaleService, GetRegionalPrefsLocales) { ASSERT_TRUE(len > 0); } +TEST(Intl_Locale_LocaleService, GetWebExposedLocales) { + const nsTArray spoofLocale{NS_LITERAL_CSTRING("de")}; + LocaleService::GetInstance()->SetAvailableLocales(spoofLocale); + LocaleService::GetInstance()->SetRequestedLocales(spoofLocale); + + nsTArray pvLocales; + + mozilla::Preferences::SetInt("privacy.spoof_english", 0); + LocaleService::GetInstance()->GetWebExposedLocales(pvLocales); + ASSERT_TRUE(pvLocales.Length() > 0); + ASSERT_TRUE(pvLocales[0].Equals(NS_LITERAL_CSTRING("de"))); + + mozilla::Preferences::SetCString("intl.locale.privacy.web_exposed", "zh-TW"); + LocaleService::GetInstance()->GetWebExposedLocales(pvLocales); + ASSERT_TRUE(pvLocales.Length() > 0); + ASSERT_TRUE(pvLocales[0].Equals(NS_LITERAL_CSTRING("zh-TW"))); + + mozilla::Preferences::SetInt("privacy.spoof_english", 2); + LocaleService::GetInstance()->GetWebExposedLocales(pvLocales); + ASSERT_EQ(1u, pvLocales.Length()); + ASSERT_TRUE(pvLocales[0].Equals(NS_LITERAL_CSTRING("en-US"))); +} + TEST(Intl_Locale_LocaleService, GetRequestedLocales) { nsTArray reqLocales; LocaleService::GetInstance()->GetRequestedLocales(reqLocales); diff --git a/modules/libpref/init/StaticPrefList.h b/modules/libpref/init/StaticPrefList.h index ba2f15306870..edd8e242f8a3 100644 --- a/modules/libpref/init/StaticPrefList.h +++ b/modules/libpref/init/StaticPrefList.h @@ -2097,6 +2097,13 @@ VARCACHE_PREF( bool, false ) +// Spoof user locale to English +VARCACHE_PREF( + "privacy.spoof_english", + privacy_spoof_english, + RelaxedAtomicUint32, 0 +) + // Lower the priority of network loads for resources on the tracking protection // list. Note that this requires the // privacy.trackingprotection.annotate_channels pref to be on in order to have diff --git a/toolkit/content/widgets/datetimebox.js b/toolkit/content/widgets/datetimebox.js index 6c04eb2138c3..3d67e1314baa 100644 --- a/toolkit/content/widgets/datetimebox.js +++ b/toolkit/content/widgets/datetimebox.js @@ -88,7 +88,7 @@ this.DateTimeInputBaseImplWidget = class { this.DEBUG = false; this.mDateTimeBoxElement = this.shadowRoot.firstChild; this.mInputElement = this.element; - this.mLocales = this.window.getRegionalPrefsLocales(); + this.mLocales = this.window.getWebExposedLocales(); this.mIsRTL = false; let intlUtils = this.window.intlUtils; diff --git a/toolkit/modules/DateTimePickerPanel.jsm b/toolkit/modules/DateTimePickerPanel.jsm index a23f68cfa1ca..8342cb52473e 100644 --- a/toolkit/modules/DateTimePickerPanel.jsm +++ b/toolkit/modules/DateTimePickerPanel.jsm @@ -99,7 +99,7 @@ var DateTimePickerPanel = class { initPicker(detail) { // TODO: When bug 1376616 lands, replace this.setGregorian with // mozIntl.Locale for setting calendar to Gregorian - const locale = this.setGregorian(Services.locale.regionalPrefsLocales[0]); + const locale = this.setGregorian(Services.locale.webExposedLocales[0]); const dir = Services.intl.getLocaleInfo(locale).direction; switch (this.type) { From 81b30d71436ee8ece24114e96c587dbc0c36f975 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Fri, 29 Mar 2019 10:55:31 +0000 Subject: [PATCH 033/100] Bug 1539356 - Mark EditorBase::InsertNodeTransaction() as MOZ_CAN_RUN_SCRIPT r=m_kato This patch marks `EditorBase::InsertNodeTransaction()` **and** its callers as `MOZ_CAN_RUN_SCRIPT`. Unfortunately, this patch tells us that some `GetSomething()` methods may destroy the editor since `HTMLEditRules::GetNodesForOperation()`, `HTMLEditRules::GetNodesFromPoint()` and `HTMLEditRules::GetNodesFromSelection()` may change the DOM tree. Additionally, initialization methods may destroy the editor since it may insert a bogus `
` node. Note that this patch also removes some unused methods. I.e., they are not result of some cleaning up the code. This patch just avoids marking unused methods as `MOZ_CAN_RUN_SCRIPT`. Differential Revision: https://phabricator.services.mozilla.com/D25027 --HG-- extra : moz-landing-system : lando --- docshell/base/nsDocShellEditorData.cpp | 17 - docshell/base/nsDocShellEditorData.h | 1 - dom/html/nsTextEditorState.cpp | 6 +- editor/composer/nsEditingSession.h | 1 + editor/composer/nsIEditingSession.idl | 2 + editor/libeditor/CSSEditUtils.cpp | 13 +- editor/libeditor/CSSEditUtils.h | 3 + editor/libeditor/EditorBase.cpp | 10 +- editor/libeditor/EditorBase.h | 26 +- editor/libeditor/EditorEventListener.h | 1 + editor/libeditor/HTMLEditRules.cpp | 379 +++++++++++-------- editor/libeditor/HTMLEditRules.h | 51 +++ editor/libeditor/HTMLEditor.cpp | 12 +- editor/libeditor/HTMLEditor.h | 50 ++- editor/libeditor/HTMLEditorCommands.cpp | 48 ++- editor/libeditor/HTMLEditorCommands.h | 78 ++-- editor/libeditor/HTMLEditorDataTransfer.cpp | 53 +-- editor/libeditor/HTMLEditorEventListener.cpp | 2 +- editor/libeditor/HTMLEditorEventListener.h | 1 + editor/libeditor/HTMLEditorObjectResizer.cpp | 25 +- editor/libeditor/HTMLStyleEditor.cpp | 56 +-- editor/libeditor/HTMLTableEditor.cpp | 6 +- editor/libeditor/TextEditRules.cpp | 29 +- editor/libeditor/TextEditRules.h | 10 + editor/libeditor/TextEditUtils.cpp | 2 +- editor/libeditor/TextEditUtils.h | 3 +- editor/libeditor/TextEditor.cpp | 3 +- editor/libeditor/TextEditor.h | 6 + editor/libeditor/WSRunObject.cpp | 9 +- editor/libeditor/WSRunObject.h | 8 +- editor/nsIEditor.idl | 4 + editor/nsIEditorMailSupport.idl | 1 + editor/nsIHTMLEditor.idl | 13 + 33 files changed, 572 insertions(+), 357 deletions(-) diff --git a/docshell/base/nsDocShellEditorData.cpp b/docshell/base/nsDocShellEditorData.cpp index 0ff3adca227f..4633f8a2c2d7 100644 --- a/docshell/base/nsDocShellEditorData.cpp +++ b/docshell/base/nsDocShellEditorData.cpp @@ -58,23 +58,6 @@ bool nsDocShellEditorData::GetEditable() { return mMakeEditable || (mHTMLEditor != nullptr); } -nsresult nsDocShellEditorData::CreateEditor() { - nsCOMPtr editingSession; - nsresult rv = GetEditingSession(getter_AddRefs(editingSession)); - if (NS_FAILED(rv)) { - return rv; - } - - nsCOMPtr domWindow = - mDocShell ? mDocShell->GetWindow() : nullptr; - rv = editingSession->SetupEditorOnWindow(domWindow); - if (NS_FAILED(rv)) { - return rv; - } - - return NS_OK; -} - nsresult nsDocShellEditorData::GetEditingSession(nsIEditingSession** aResult) { EnsureEditingSession(); diff --git a/docshell/base/nsDocShellEditorData.h b/docshell/base/nsDocShellEditorData.h index 2beb80c4adfe..a980f55441e8 100644 --- a/docshell/base/nsDocShellEditorData.h +++ b/docshell/base/nsDocShellEditorData.h @@ -24,7 +24,6 @@ class nsDocShellEditorData { nsresult MakeEditable(bool aWaitForUriLoad); bool GetEditable(); - nsresult CreateEditor(); nsresult GetEditingSession(nsIEditingSession** aResult); mozilla::HTMLEditor* GetHTMLEditor() const { return mHTMLEditor; } nsresult SetHTMLEditor(mozilla::HTMLEditor* aHTMLEditor); diff --git a/dom/html/nsTextEditorState.cpp b/dom/html/nsTextEditorState.cpp index fb58a7d1e480..c4edcc72c277 100644 --- a/dom/html/nsTextEditorState.cpp +++ b/dom/html/nsTextEditorState.cpp @@ -1345,8 +1345,10 @@ nsresult nsTextEditorState::PrepareEditor(const nsAString* aValue) { // already does the relevant security checks. AutoNoJSAPI nojsapi; - rv = newTextEditor->Init(*doc, GetRootNode(), mSelCon, editorFlags, - defaultValue); + RefPtr rootElement = GetRootNode(); + RefPtr selectionController = mSelCon; + rv = newTextEditor->Init(*doc, rootElement, selectionController, + editorFlags, defaultValue); NS_ENSURE_SUCCESS(rv, rv); } diff --git a/editor/composer/nsEditingSession.h b/editor/composer/nsEditingSession.h index 8180a725c562..031b1afe7dac 100644 --- a/editor/composer/nsEditingSession.h +++ b/editor/composer/nsEditingSession.h @@ -72,6 +72,7 @@ class nsEditingSession final : public nsIEditingSession, // progress load stuff nsresult StartDocumentLoad(nsIWebProgress* aWebProgress, bool isToBeMadeEditable); + MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult EndDocumentLoad(nsIWebProgress* aWebProgress, nsIChannel* aChannel, nsresult aStatus, bool isToBeMadeEditable); nsresult StartPageLoad(nsIChannel* aChannel); diff --git a/editor/composer/nsIEditingSession.idl b/editor/composer/nsIEditingSession.idl index 6f5ea7b0d4f3..834b6e20c550 100644 --- a/editor/composer/nsIEditingSession.idl +++ b/editor/composer/nsIEditingSession.idl @@ -47,6 +47,7 @@ interface nsIEditingSession : nsISupports * (or part of it) editable. * @param aInteractive if PR_FALSE turn off scripting and plugins */ + [can_run_script] void makeWindowEditable(in mozIDOMWindowProxy window, in string aEditorType, in boolean doAfterUriLoad, @@ -70,6 +71,7 @@ interface nsIEditingSession : nsISupports /** * Setup editor and related support objects */ + [can_run_script] void setupEditorOnWindow(in mozIDOMWindowProxy window); /** diff --git a/editor/libeditor/CSSEditUtils.cpp b/editor/libeditor/CSSEditUtils.cpp index 791121305d3e..b66fc3fd15d6 100644 --- a/editor/libeditor/CSSEditUtils.cpp +++ b/editor/libeditor/CSSEditUtils.cpp @@ -495,11 +495,10 @@ already_AddRefed CSSEditUtils::GetComputedStyle( // whole node if it is a span and if its only attribute is _moz_dirty nsresult CSSEditUtils::RemoveCSSInlineStyle(nsINode& aNode, nsAtom* aProperty, const nsAString& aPropertyValue) { - RefPtr element = aNode.AsElement(); - NS_ENSURE_STATE(element); + OwningNonNull element(*aNode.AsElement()); // remove the property from the style attribute - nsresult rv = RemoveCSSProperty(*element, *aProperty, aPropertyValue); + nsresult rv = RemoveCSSProperty(element, *aProperty, aPropertyValue); NS_ENSURE_SUCCESS(rv, rv); if (!element->IsHTMLElement(nsGkAtoms::span) || @@ -507,7 +506,8 @@ nsresult CSSEditUtils::RemoveCSSInlineStyle(nsINode& aNode, nsAtom* aProperty, return NS_OK; } - return mHTMLEditor->RemoveContainerWithTransaction(*element); + OwningNonNull htmlEditor(*mHTMLEditor); + return htmlEditor->RemoveContainerWithTransaction(element); } // Answers true if the property can be removed by setting a "none" CSS value @@ -847,8 +847,9 @@ nsresult CSSEditUtils::RemoveCSSEquivalentToHTMLStyle( // remove the individual CSS inline styles int32_t count = cssPropertyArray.Length(); for (int32_t index = 0; index < count; index++) { - nsresult rv = RemoveCSSProperty(*aElement, *cssPropertyArray[index], - cssValueArray[index], aSuppressTransaction); + nsresult rv = + RemoveCSSProperty(*aElement, MOZ_KnownLive(*cssPropertyArray[index]), + cssValueArray[index], aSuppressTransaction); NS_ENSURE_SUCCESS(rv, rv); } return NS_OK; diff --git a/editor/libeditor/CSSEditUtils.h b/editor/libeditor/CSSEditUtils.h index c5f07f4ca27b..b405f75889bc 100644 --- a/editor/libeditor/CSSEditUtils.h +++ b/editor/libeditor/CSSEditUtils.h @@ -100,6 +100,7 @@ class CSSEditUtils final { const nsAString& aValue, bool aSuppressTxn = false); nsresult SetCSSPropertyPixels(dom::Element& aElement, nsAtom& aProperty, int32_t aIntValue); + MOZ_CAN_RUN_SCRIPT nsresult RemoveCSSProperty(dom::Element& aElement, nsAtom& aProperty, const nsAString& aPropertyValue, bool aSuppressTxn = false); @@ -127,6 +128,7 @@ class CSSEditUtils final { * @param aPropertyValue [IN] The value of the property we have to remove * if the property accepts more than one value. */ + MOZ_CAN_RUN_SCRIPT nsresult RemoveCSSInlineStyle(nsINode& aNode, nsAtom* aProperty, const nsAString& aPropertyValue); @@ -258,6 +260,7 @@ class CSSEditUtils final { * @param aSuppressTransaction [IN] A boolean indicating, when true, * that no transaction should be recorded. */ + MOZ_CAN_RUN_SCRIPT nsresult RemoveCSSEquivalentToHTMLStyle(dom::Element* aElement, nsAtom* aHTMLProperty, nsAtom* aAttribute, diff --git a/editor/libeditor/EditorBase.cpp b/editor/libeditor/EditorBase.cpp index 4b6bdfe63e1f..58cd9676c6d6 100644 --- a/editor/libeditor/EditorBase.cpp +++ b/editor/libeditor/EditorBase.cpp @@ -2372,13 +2372,15 @@ void EditorBase::CloneAttributesWithTransaction(Element& aDestElement, nsAutoString value; attr->GetValue(value); if (isDestElementInBody) { - SetAttributeOrEquivalent(destElement, attr->NodeInfo()->NameAtom(), value, - false); + SetAttributeOrEquivalent(destElement, + MOZ_KnownLive(attr->NodeInfo()->NameAtom()), + value, false); } else { // The element is not inserted in the document yet, we don't want to put // a transaction on the UndoStack - SetAttributeOrEquivalent(destElement, attr->NodeInfo()->NameAtom(), value, - true); + SetAttributeOrEquivalent(destElement, + MOZ_KnownLive(attr->NodeInfo()->NameAtom()), + value, true); } } } diff --git a/editor/libeditor/EditorBase.h b/editor/libeditor/EditorBase.h index 54def0f4e3fa..69a05e73391c 100644 --- a/editor/libeditor/EditorBase.h +++ b/editor/libeditor/EditorBase.h @@ -171,6 +171,7 @@ class EditorBase : public nsIEditor, * @param aFlags A bitmask of flags for specifying the behavior * of the editor. */ + MOZ_CAN_RUN_SCRIPT virtual nsresult Init(Document& doc, Element* aRoot, nsISelectionController* aSelCon, uint32_t aFlags, const nsAString& aInitialValue); @@ -885,6 +886,7 @@ class EditorBase : public nsIEditor, * does nothing during composition, returns NS_OK. * Otherwise, an error code. */ + MOZ_CAN_RUN_SCRIPT virtual nsresult InsertTextWithTransaction( Document& aDocument, const nsAString& aStringToInsert, const EditorRawDOMPoint& aPointToInsert, @@ -926,9 +928,9 @@ class EditorBase : public nsIEditor, * before child node referred by this. */ template - nsresult InsertNodeWithTransaction( - nsIContent& aContentToInsert, - const EditorDOMPointBase& aPointToInsert); + MOZ_CAN_RUN_SCRIPT nsresult + InsertNodeWithTransaction(nsIContent& aContentToInsert, + const EditorDOMPointBase& aPointToInsert); /** * ReplaceContainerWithTransaction() creates new element whose name is @@ -939,6 +941,7 @@ class EditorBase : public nsIEditor, * with new element. * @param aTagName The name of new element node. */ + MOZ_CAN_RUN_SCRIPT already_AddRefed ReplaceContainerWithTransaction( Element& aOldContainer, nsAtom& aTagName) { return ReplaceContainerWithTransactionInternal( @@ -955,6 +958,7 @@ class EditorBase : public nsIEditor, * with new element. * @param aTagName The name of new element node. */ + MOZ_CAN_RUN_SCRIPT already_AddRefed ReplaceContainerAndCloneAttributesWithTransaction( Element& aOldContainer, nsAtom& aTagName) { return ReplaceContainerWithTransactionInternal( @@ -973,6 +977,7 @@ class EditorBase : public nsIEditor, * @param aAttribute Attribute name to be set to the new element. * @param aAttributeValue Attribute value to be set to aAttribute. */ + MOZ_CAN_RUN_SCRIPT already_AddRefed ReplaceContainerWithTransaction( Element& aOldContainer, nsAtom& aTagName, nsAtom& aAttribute, const nsAString& aAttributeValue) { @@ -985,6 +990,7 @@ class EditorBase : public nsIEditor, * aSourceElement to aDestElement after removing all attributes in * aDestElement. */ + MOZ_CAN_RUN_SCRIPT void CloneAttributesWithTransaction(Element& aDestElement, Element& aSourceElement); @@ -994,6 +1000,7 @@ class EditorBase : public nsIEditor, * * @param aElement The element to be removed. */ + MOZ_CAN_RUN_SCRIPT nsresult RemoveContainerWithTransaction(Element& aElement); /** @@ -1010,6 +1017,7 @@ class EditorBase : public nsIEditor, * was. * @return The new element. */ + MOZ_CAN_RUN_SCRIPT already_AddRefed InsertContainerWithTransaction(nsIContent& aContent, nsAtom& aTagName) { return InsertContainerWithTransactionInternal( @@ -1033,6 +1041,7 @@ class EditorBase : public nsIEditor, * @param aAttributeValue Value to be set to aAttribute. * @return The new element. */ + MOZ_CAN_RUN_SCRIPT already_AddRefed InsertContainerWithTransaction( nsIContent& aContent, nsAtom& aTagName, nsAtom& aAttribute, const nsAString& aAttributeValue) { @@ -1075,7 +1084,7 @@ class EditorBase : public nsIEditor, * @param aContent The node to be moved. */ template - nsresult MoveNodeWithTransaction( + MOZ_CAN_RUN_SCRIPT nsresult MoveNodeWithTransaction( nsIContent& aContent, const EditorDOMPointBase& aPointToInsert); /** @@ -1085,6 +1094,7 @@ class EditorBase : public nsIEditor, * @param aNewContainer The new container which will contain aContent as * its last child. */ + MOZ_CAN_RUN_SCRIPT nsresult MoveNodeToEndWithTransaction(nsIContent& aContent, nsINode& aNewContainer) { EditorRawDOMPoint pointToInsert; @@ -1171,6 +1181,7 @@ class EditorBase : public nsIEditor, nsresult RemoveAttributeWithTransaction(Element& aElement, nsAtom& aAttribute); + MOZ_CAN_RUN_SCRIPT virtual nsresult RemoveAttributeOrEquivalent(Element* aElement, nsAtom* aAttribute, bool aSuppressTransaction) = 0; @@ -1185,6 +1196,7 @@ class EditorBase : public nsIEditor, nsresult SetAttributeWithTransaction(Element& aElement, nsAtom& aAttribute, const nsAString& aValue); + MOZ_CAN_RUN_SCRIPT virtual nsresult SetAttributeOrEquivalent(Element* aElement, nsAtom* aAttribute, const nsAString& aValue, @@ -1281,6 +1293,7 @@ class EditorBase : public nsIEditor, * @param aCloneAllAttributes If true, all attributes of aOldContainer will * be copied to the new element. */ + MOZ_CAN_RUN_SCRIPT already_AddRefed ReplaceContainerWithTransactionInternal( Element& aElement, nsAtom& aTagName, nsAtom& aAttribute, const nsAString& aAttributeValue, bool aCloneAllAttributes); @@ -1303,6 +1316,7 @@ class EditorBase : public nsIEditor, * @param aAttributeValue Value to be set to aAttribute. * @return The new element. */ + MOZ_CAN_RUN_SCRIPT already_AddRefed InsertContainerWithTransactionInternal( nsIContent& aContent, nsAtom& aTagName, nsAtom& aAttribute, const nsAString& aAttributeValue); @@ -1739,6 +1753,7 @@ class EditorBase : public nsIEditor, * OnEndHandlingTopLevelEditSubAction() is called after * SetTopLevelEditSubAction() is handled. */ + MOZ_CAN_RUN_SCRIPT virtual void OnEndHandlingTopLevelEditSubAction(); /** @@ -2116,9 +2131,10 @@ class EditorBase : public nsIEditor, } } + MOZ_CAN_RUN_SCRIPT_BOUNDARY ~AutoTopLevelEditSubActionNotifier() { if (!mDoNothing) { - mEditorBase.OnEndHandlingTopLevelEditSubAction(); + MOZ_KnownLive(mEditorBase).OnEndHandlingTopLevelEditSubAction(); } } diff --git a/editor/libeditor/EditorEventListener.h b/editor/libeditor/EditorEventListener.h index 7637a90b55fd..2c570c18ac9d 100644 --- a/editor/libeditor/EditorEventListener.h +++ b/editor/libeditor/EditorEventListener.h @@ -74,6 +74,7 @@ class EditorEventListener : public nsIDOMEventListener { void HandleEndComposition(WidgetCompositionEvent* aCompositionEvent); MOZ_CAN_RUN_SCRIPT virtual nsresult MouseDown(dom::MouseEvent* aMouseEvent); + MOZ_CAN_RUN_SCRIPT virtual nsresult MouseUp(dom::MouseEvent* aMouseEvent) { return NS_OK; } MOZ_CAN_RUN_SCRIPT virtual nsresult MouseClick(WidgetMouseEvent* aMouseClickEvent); diff --git a/editor/libeditor/HTMLEditRules.cpp b/editor/libeditor/HTMLEditRules.cpp index 9aa03096e342..45e085b126d6 100644 --- a/editor/libeditor/HTMLEditRules.cpp +++ b/editor/libeditor/HTMLEditRules.cpp @@ -1343,8 +1343,9 @@ nsresult HTMLEditRules::WillInsertText(EditSubAction aEditSubAction, } if (inString->IsEmpty()) { - rv = HTMLEditorRef().InsertTextWithTransaction( - *doc, *inString, EditorRawDOMPoint(pointToInsert)); + rv = MOZ_KnownLive(HTMLEditorRef()) + .InsertTextWithTransaction(*doc, *inString, + EditorRawDOMPoint(pointToInsert)); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -1444,9 +1445,10 @@ nsresult HTMLEditRules::WillInsertText(EditSubAction aEditSubAction, "by mutation observer"); } else { EditorRawDOMPoint pointAfterInsertedString; - rv = HTMLEditorRef().InsertTextWithTransaction( - *doc, subStr, EditorRawDOMPoint(currentPoint), - &pointAfterInsertedString); + rv = MOZ_KnownLive(HTMLEditorRef()) + .InsertTextWithTransaction(*doc, subStr, + EditorRawDOMPoint(currentPoint), + &pointAfterInsertedString); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -1731,8 +1733,8 @@ EditActionResult HTMLEditRules::WillInsertParagraphSeparator() { // MakeBasicBlock() creates AutoSelectionRestorer. // Therefore, even if it returns NS_OK, editor might have been destroyed // at restoring Selection. - OwningNonNull separatorTag = ParagraphSeparatorElement(separator); - nsresult rv = MakeBasicBlock(separatorTag); + nsresult rv = + MakeBasicBlock(MOZ_KnownLive(ParagraphSeparatorElement(separator))); if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED) || NS_WARN_IF(!CanHandleEditAction())) { return EditActionIgnored(NS_ERROR_EDITOR_DESTROYED); @@ -1796,9 +1798,9 @@ EditActionResult HTMLEditRules::WillInsertParagraphSeparator() { nsCOMPtr listItem = IsInListItem(blockParent); if (listItem && listItem != host) { - nsresult rv = - ReturnInListItem(*listItem, *atStartOfSelection.GetContainer(), - atStartOfSelection.Offset()); + nsresult rv = ReturnInListItem( + *listItem, MOZ_KnownLive(*atStartOfSelection.GetContainer()), + atStartOfSelection.Offset()); if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) { return EditActionIgnored(NS_ERROR_EDITOR_DESTROYED); } @@ -1965,8 +1967,10 @@ nsresult HTMLEditRules::InsertBRElement(const EditorDOMPoint& aPointToBreak) { // the style from the line above. EditorDOMPoint atSecondBRElement(maybeSecondBRNode); if (brElement->GetNextSibling() != maybeSecondBRNode) { - nsresult rv = HTMLEditorRef().MoveNodeWithTransaction( - *maybeSecondBRNode->AsContent(), afterBRElement); + nsresult rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeWithTransaction( + MOZ_KnownLive(*maybeSecondBRNode->AsContent()), + afterBRElement); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -2588,7 +2592,7 @@ nsresult HTMLEditRules::WillDeleteSelection( startPoint.GetContainerAsText() && sibling->GetAsText()) { EditorDOMPoint pt; nsresult rv = JoinNearestEditableNodesWithTransaction( - *sibling, *startPoint.GetContainerAsContent(), &pt); + *sibling, MOZ_KnownLive(*startPoint.GetContainerAsContent()), &pt); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -2700,7 +2704,8 @@ nsresult HTMLEditRules::WillDeleteSelection( return NS_ERROR_FAILURE; } EditActionResult ret = TryToJoinBlocksWithTransaction( - *leftNode->AsContent(), *rightNode->AsContent()); + MOZ_KnownLive(*leftNode->AsContent()), + MOZ_KnownLive(*rightNode->AsContent())); *aHandled |= ret.Handled(); *aCancel |= ret.Canceled(); if (NS_WARN_IF(ret.Failed())) { @@ -2780,7 +2785,8 @@ nsresult HTMLEditRules::WillDeleteSelection( return NS_ERROR_FAILURE; } EditActionResult ret = TryToJoinBlocksWithTransaction( - *leftNode->AsContent(), *rightNode->AsContent()); + MOZ_KnownLive(*leftNode->AsContent()), + MOZ_KnownLive(*rightNode->AsContent())); // This should claim that trying to join the block means that // this handles the action because the caller shouldn't do anything // anymore in this case. @@ -3458,8 +3464,8 @@ EditActionResult HTMLEditRules::TryToJoinBlocksWithTransaction( return EditActionIgnored(NS_ERROR_NULL_POINTER); } - ret |= MoveBlock(*previousContent.GetContainerAsElement(), *rightBlock, - previousContent.Offset(), 0); + ret |= MoveBlock(MOZ_KnownLive(*previousContent.GetContainerAsElement()), + *rightBlock, previousContent.Offset(), 0); if (NS_WARN_IF(ret.Failed())) { return ret; } @@ -3509,8 +3515,8 @@ EditActionResult HTMLEditRules::TryToJoinBlocksWithTransaction( return EditActionIgnored(NS_ERROR_EDITOR_DESTROYED); } if (pt.IsSet() && mergeLists) { - CreateElementResult convertListTypeResult = - ConvertListType(*rightBlock, *existingList, *nsGkAtoms::li); + CreateElementResult convertListTypeResult = ConvertListType( + *rightBlock, MOZ_KnownLive(*existingList), *nsGkAtoms::li); if (NS_WARN_IF(convertListTypeResult.Rv() == NS_ERROR_EDITOR_DESTROYED)) { return EditActionIgnored(NS_ERROR_EDITOR_DESTROYED); } @@ -3559,8 +3565,8 @@ EditActionResult HTMLEditRules::MoveBlock(Element& aLeftBlock, // get the node to act on if (IsBlockNode(arrayOfNodes[i])) { // For block nodes, move their contents only, then delete block. - ret |= - MoveContents(*arrayOfNodes[i]->AsElement(), aLeftBlock, &aLeftOffset); + ret |= MoveContents(MOZ_KnownLive(*arrayOfNodes[i]->AsElement()), + aLeftBlock, &aLeftOffset); if (NS_WARN_IF(ret.Failed())) { return ret; } @@ -3572,8 +3578,8 @@ EditActionResult HTMLEditRules::MoveBlock(Element& aLeftBlock, ret.MarkAsHandled(); } else { // Otherwise move the content as is, checking against the DTD. - ret |= MoveNodeSmart(*arrayOfNodes[i]->AsContent(), aLeftBlock, - &aLeftOffset); + ret |= MoveNodeSmart(MOZ_KnownLive(*arrayOfNodes[i]->AsContent()), + aLeftBlock, &aLeftOffset); if (NS_WARN_IF(ret.Rv() == NS_ERROR_EDITOR_DESTROYED)) { return ret; } @@ -3600,8 +3606,8 @@ EditActionResult HTMLEditRules::MoveNodeSmart(nsIContent& aNode, if (HTMLEditorRef().CanContain(aDestElement, aNode)) { // If it can, move it there. if (*aInOutDestOffset == -1) { - nsresult rv = - HTMLEditorRef().MoveNodeToEndWithTransaction(aNode, aDestElement); + nsresult rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeToEndWithTransaction(aNode, aDestElement); if (NS_WARN_IF(!CanHandleEditAction())) { return EditActionIgnored(NS_ERROR_EDITOR_DESTROYED); } @@ -3610,8 +3616,8 @@ EditActionResult HTMLEditRules::MoveNodeSmart(nsIContent& aNode, } } else { EditorRawDOMPoint pointToInsert(&aDestElement, *aInOutDestOffset); - nsresult rv = - HTMLEditorRef().MoveNodeWithTransaction(aNode, pointToInsert); + nsresult rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeWithTransaction(aNode, pointToInsert); if (NS_WARN_IF(!CanHandleEditAction())) { return EditActionIgnored(NS_ERROR_EDITOR_DESTROYED); } @@ -3629,7 +3635,8 @@ EditActionResult HTMLEditRules::MoveNodeSmart(nsIContent& aNode, // If it can't, move its children (if any), and then delete it. EditActionResult ret(NS_OK); if (aNode.IsElement()) { - ret = MoveContents(*aNode.AsElement(), aDestElement, aInOutDestOffset); + ret = MoveContents(MOZ_KnownLive(*aNode.AsElement()), aDestElement, + aInOutDestOffset); if (NS_WARN_IF(ret.Failed())) { return ret; } @@ -3656,7 +3663,7 @@ EditActionResult HTMLEditRules::MoveContents(Element& aElement, EditActionResult ret(NS_OK); while (aElement.GetFirstChild()) { - ret |= MoveNodeSmart(*aElement.GetFirstChild(), aDestElement, + ret |= MoveNodeSmart(MOZ_KnownLive(*aElement.GetFirstChild()), aDestElement, aInOutDestOffset); if (NS_WARN_IF(ret.Failed())) { return ret; @@ -3964,20 +3971,22 @@ nsresult HTMLEditRules::MakeList(nsAtom& aListType, bool aEntireList, // whole list and then RemoveContainerWithTransaction() on the list. // ConvertListType first: that routine handles converting the list // item types, if needed. - rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode, *curList); + rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeToEndWithTransaction(*curNode, *curList); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } - CreateElementResult convertListTypeResult = - ConvertListType(*curNode->AsElement(), aListType, aItemType); + CreateElementResult convertListTypeResult = ConvertListType( + MOZ_KnownLive(*curNode->AsElement()), aListType, aItemType); if (NS_WARN_IF(convertListTypeResult.Failed())) { return convertListTypeResult.Rv(); } - rv = HTMLEditorRef().RemoveBlockContainerWithTransaction( - *convertListTypeResult.GetNewNode()); + rv = MOZ_KnownLive(HTMLEditorRef()) + .RemoveBlockContainerWithTransaction( + MOZ_KnownLive(*convertListTypeResult.GetNewNode())); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -3987,8 +3996,8 @@ nsresult HTMLEditRules::MakeList(nsAtom& aListType, bool aEntireList, newBlock = convertListTypeResult.forget(); } else { // replace list with new list type - CreateElementResult convertListTypeResult = - ConvertListType(*curNode->AsElement(), aListType, aItemType); + CreateElementResult convertListTypeResult = ConvertListType( + MOZ_KnownLive(*curNode->AsElement()), aListType, aItemType); if (NS_WARN_IF(convertListTypeResult.Failed())) { return convertListTypeResult.Rv(); } @@ -4033,7 +4042,8 @@ nsresult HTMLEditRules::MakeList(nsAtom& aListType, bool aEntireList, } } // move list item to new list - rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode, *curList); + rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeToEndWithTransaction(*curNode, *curList); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -4042,8 +4052,9 @@ nsresult HTMLEditRules::MakeList(nsAtom& aListType, bool aEntireList, } // convert list item type if needed if (!curNode->IsHTMLElement(&aItemType)) { - newBlock = HTMLEditorRef().ReplaceContainerWithTransaction( - *curNode->AsElement(), aItemType); + newBlock = MOZ_KnownLive(HTMLEditorRef()) + .ReplaceContainerWithTransaction( + MOZ_KnownLive(*curNode->AsElement()), aItemType); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -4058,7 +4069,8 @@ nsresult HTMLEditRules::MakeList(nsAtom& aListType, bool aEntireList, curList = atCurNode.GetContainerAsElement(); } else if (atCurNode.GetContainer() != curList) { // move list item to new list - rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode, *curList); + rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeToEndWithTransaction(*curNode, *curList); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -4067,8 +4079,9 @@ nsresult HTMLEditRules::MakeList(nsAtom& aListType, bool aEntireList, } } if (!curNode->IsHTMLElement(&aItemType)) { - newBlock = HTMLEditorRef().ReplaceContainerWithTransaction( - *curNode->AsElement(), aItemType); + newBlock = MOZ_KnownLive(HTMLEditorRef()) + .ReplaceContainerWithTransaction( + MOZ_KnownLive(*curNode->AsElement()), aItemType); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -4109,8 +4122,9 @@ nsresult HTMLEditRules::MakeList(nsAtom& aListType, bool aEntireList, prevListItem = nullptr; int32_t j = i + 1; GetInnerContent(*curNode, arrayOfNodes, &j); - rv = - HTMLEditorRef().RemoveContainerWithTransaction(*curNode->AsElement()); + rv = MOZ_KnownLive(HTMLEditorRef()) + .RemoveContainerWithTransaction( + MOZ_KnownLive(*curNode->AsElement())); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -4152,8 +4166,8 @@ nsresult HTMLEditRules::MakeList(nsAtom& aListType, bool aEntireList, if (IsInlineNode(curNode) && prevListItem) { // this is a continuation of some inline nodes that belong together in // the same list item. use prevListItem - rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode, - *prevListItem); + rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeToEndWithTransaction(*curNode, *prevListItem); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -4163,8 +4177,9 @@ nsresult HTMLEditRules::MakeList(nsAtom& aListType, bool aEntireList, } else { // don't wrap li around a paragraph. instead replace paragraph with li if (curNode->IsHTMLElement(nsGkAtoms::p)) { - listItem = HTMLEditorRef().ReplaceContainerWithTransaction( - *curNode->AsElement(), aItemType); + listItem = MOZ_KnownLive(HTMLEditorRef()) + .ReplaceContainerWithTransaction( + MOZ_KnownLive(*curNode->AsElement()), aItemType); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -4172,8 +4187,8 @@ nsresult HTMLEditRules::MakeList(nsAtom& aListType, bool aEntireList, return NS_ERROR_FAILURE; } } else { - listItem = HTMLEditorRef().InsertContainerWithTransaction(*curNode, - aItemType); + listItem = MOZ_KnownLive(HTMLEditorRef()) + .InsertContainerWithTransaction(*curNode, aItemType); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -4194,7 +4209,8 @@ nsresult HTMLEditRules::MakeList(nsAtom& aListType, bool aEntireList, if (listItem) { // if we made a new list item, deal with it: tuck the listItem into the // end of the active list - rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*listItem, *curList); + rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeToEndWithTransaction(*listItem, *curList); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -4249,7 +4265,7 @@ nsresult HTMLEditRules::WillRemoveList(bool* aCancel, bool* aHandled) { // unlist this listitem bool bOutOfList; do { - rv = PopListItem(*curNode->AsContent(), &bOutOfList); + rv = PopListItem(MOZ_KnownLive(*curNode->AsContent()), &bOutOfList); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -4257,7 +4273,7 @@ nsresult HTMLEditRules::WillRemoveList(bool* aCancel, bool* aHandled) { !bOutOfList); // keep popping it out until it's not in a list anymore } else if (HTMLEditUtils::IsList(curNode)) { // node is a list, move list items out - rv = RemoveListStructure(*curNode->AsElement()); + rv = RemoveListStructure(MOZ_KnownLive(*curNode->AsElement())); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -4683,8 +4699,10 @@ nsresult HTMLEditRules::IndentAroundSelectionWithCSS() { sibling->NodeInfo()->NameAtom() && atCurNode.GetContainer()->NodeInfo()->NamespaceID() == sibling->NodeInfo()->NamespaceID()) { - nsresult rv = HTMLEditorRef().MoveNodeWithTransaction( - *curNode->AsContent(), EditorRawDOMPoint(sibling, 0)); + nsresult rv = + MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeWithTransaction(MOZ_KnownLive(*curNode->AsContent()), + EditorRawDOMPoint(sibling, 0)); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -4703,8 +4721,9 @@ nsresult HTMLEditRules::IndentAroundSelectionWithCSS() { sibling->NodeInfo()->NameAtom() && atCurNode.GetContainer()->NodeInfo()->NamespaceID() == sibling->NodeInfo()->NamespaceID()) { - nsresult rv = HTMLEditorRef().MoveNodeToEndWithTransaction( - *curNode->AsContent(), *sibling); + nsresult rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeToEndWithTransaction( + MOZ_KnownLive(*curNode->AsContent()), *sibling); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -4744,8 +4763,9 @@ nsresult HTMLEditRules::IndentAroundSelectionWithCSS() { mNewBlock = curList; } // tuck the node into the end of the active list - nsresult rv = HTMLEditorRef().MoveNodeToEndWithTransaction( - *curNode->AsContent(), *curList); + nsresult rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeToEndWithTransaction( + MOZ_KnownLive(*curNode->AsContent()), *curList); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -4758,7 +4778,8 @@ nsresult HTMLEditRules::IndentAroundSelectionWithCSS() { // Not a list item. if (IsBlockNode(*curNode)) { - nsresult rv = IncreaseMarginToIndent(*curNode->AsElement()); + nsresult rv = + IncreaseMarginToIndent(MOZ_KnownLive(*curNode->AsElement())); if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) { return NS_ERROR_EDITOR_DESTROYED; } @@ -4799,8 +4820,9 @@ nsresult HTMLEditRules::IndentAroundSelectionWithCSS() { } // tuck the node into the end of the active blockquote - nsresult rv = HTMLEditorRef().MoveNodeToEndWithTransaction( - *curNode->AsContent(), *curQuote); + nsresult rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeToEndWithTransaction( + MOZ_KnownLive(*curNode->AsContent()), *curQuote); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -4950,8 +4972,9 @@ nsresult HTMLEditRules::IndentAroundSelectionWithHTML() { sibling->NodeInfo()->NameAtom() && atCurNode.GetContainer()->NodeInfo()->NamespaceID() == sibling->NodeInfo()->NamespaceID()) { - rv = HTMLEditorRef().MoveNodeWithTransaction( - *curNode->AsContent(), EditorRawDOMPoint(sibling, 0)); + rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeWithTransaction(MOZ_KnownLive(*curNode->AsContent()), + EditorRawDOMPoint(sibling, 0)); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -4970,8 +4993,9 @@ nsresult HTMLEditRules::IndentAroundSelectionWithHTML() { sibling->NodeInfo()->NameAtom() && atCurNode.GetContainer()->NodeInfo()->NamespaceID() == sibling->NodeInfo()->NamespaceID()) { - rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode->AsContent(), - *sibling); + rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeToEndWithTransaction( + MOZ_KnownLive(*curNode->AsContent()), *sibling); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -5011,8 +5035,9 @@ nsresult HTMLEditRules::IndentAroundSelectionWithHTML() { mNewBlock = curList; } // tuck the node into the end of the active list - rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode->AsContent(), - *curList); + rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeToEndWithTransaction( + MOZ_KnownLive(*curNode->AsContent()), *curList); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -5069,7 +5094,8 @@ nsresult HTMLEditRules::IndentAroundSelectionWithHTML() { } } - rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*listItem, *curList); + rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeToEndWithTransaction(*listItem, *curList); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -5118,8 +5144,9 @@ nsresult HTMLEditRules::IndentAroundSelectionWithHTML() { } // tuck the node into the end of the active blockquote - rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode->AsContent(), - *curQuote); + rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeToEndWithTransaction(MOZ_KnownLive(*curNode->AsContent()), + *curQuote); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -5275,8 +5302,9 @@ SplitRangeOffFromNodeResult HTMLEditRules::OutdentAroundSelection() { lastBQChild = nullptr; curBlockQuoteIsIndentedWithCSS = false; } - rv = HTMLEditorRef().RemoveBlockContainerWithTransaction( - *curNode->AsElement()); + rv = MOZ_KnownLive(HTMLEditorRef()) + .RemoveBlockContainerWithTransaction( + MOZ_KnownLive(*curNode->AsElement())); if (NS_WARN_IF(!CanHandleEditAction())) { return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_DESTROYED); } @@ -5298,7 +5326,8 @@ SplitRangeOffFromNodeResult HTMLEditRules::OutdentAroundSelection() { RefPtr unit; CSSEditUtils::ParseLength(value, &f, getter_AddRefs(unit)); if (f > 0) { - nsresult rv = DecreaseMarginToOutdent(*curNode->AsElement()); + nsresult rv = + DecreaseMarginToOutdent(MOZ_KnownLive(*curNode->AsElement())); if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) { return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_DESTROYED); } @@ -5328,7 +5357,7 @@ SplitRangeOffFromNodeResult HTMLEditRules::OutdentAroundSelection() { lastBQChild = nullptr; curBlockQuoteIsIndentedWithCSS = false; } - rv = PopListItem(*curNode->AsContent()); + rv = PopListItem(MOZ_KnownLive(*curNode->AsContent())); if (NS_WARN_IF(NS_FAILED(rv))) { return SplitRangeOffFromNodeResult(rv); } @@ -5415,8 +5444,9 @@ SplitRangeOffFromNodeResult HTMLEditRules::OutdentAroundSelection() { // Move node out of list if (HTMLEditUtils::IsList(curNode)) { // Just unwrap this sublist - rv = HTMLEditorRef().RemoveBlockContainerWithTransaction( - *curNode->AsElement()); + rv = MOZ_KnownLive(HTMLEditorRef()) + .RemoveBlockContainerWithTransaction( + MOZ_KnownLive(*curNode->AsElement())); if (NS_WARN_IF(!CanHandleEditAction())) { return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_DESTROYED); } @@ -5441,8 +5471,8 @@ SplitRangeOffFromNodeResult HTMLEditRules::OutdentAroundSelection() { // list. Be sure to put it after the parent list because this // loop iterates backwards through the parent's list of children. EditorRawDOMPoint afterCurrentList(curParent, offset + 1); - rv = - HTMLEditorRef().MoveNodeWithTransaction(*child, afterCurrentList); + rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeWithTransaction(*child, afterCurrentList); if (NS_WARN_IF(!CanHandleEditAction())) { return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_DESTROYED); } @@ -5462,8 +5492,9 @@ SplitRangeOffFromNodeResult HTMLEditRules::OutdentAroundSelection() { child = curNode->GetLastChild(); } // Delete the now-empty list - rv = HTMLEditorRef().RemoveBlockContainerWithTransaction( - *curNode->AsElement()); + rv = MOZ_KnownLive(HTMLEditorRef()) + .RemoveBlockContainerWithTransaction( + MOZ_KnownLive(*curNode->AsElement())); if (NS_WARN_IF(!CanHandleEditAction())) { return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_DESTROYED); } @@ -5522,8 +5553,8 @@ HTMLEditRules::SplitRangeOffFromBlockAndRemoveMiddleContainer( } NS_WARNING_ASSERTION(splitResult.Succeeded(), "Failed to split the range off from the block element"); - nsresult rv = - HTMLEditorRef().RemoveBlockContainerWithTransaction(aBlockElement); + nsresult rv = MOZ_KnownLive(HTMLEditorRef()) + .RemoveBlockContainerWithTransaction(aBlockElement); if (NS_WARN_IF(!CanHandleEditAction())) { return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_DESTROYED); } @@ -5587,8 +5618,9 @@ SplitRangeOffFromNodeResult HTMLEditRules::OutdentPartOfBlock( } if (!aIsBlockIndentedWithCSS) { - nsresult rv = HTMLEditorRef().RemoveBlockContainerWithTransaction( - *splitResult.GetMiddleContentAsElement()); + nsresult rv = MOZ_KnownLive(HTMLEditorRef()) + .RemoveBlockContainerWithTransaction(MOZ_KnownLive( + *splitResult.GetMiddleContentAsElement())); if (NS_WARN_IF(!CanHandleEditAction())) { return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_DESTROYED); } @@ -5600,8 +5632,8 @@ SplitRangeOffFromNodeResult HTMLEditRules::OutdentPartOfBlock( } if (splitResult.GetMiddleContentAsElement()) { - nsresult rv = - DecreaseMarginToOutdent(*splitResult.GetMiddleContentAsElement()); + nsresult rv = DecreaseMarginToOutdent( + MOZ_KnownLive(*splitResult.GetMiddleContentAsElement())); if (NS_WARN_IF(NS_FAILED(rv))) { return SplitRangeOffFromNodeResult(rv); } @@ -5622,8 +5654,9 @@ CreateElementResult HTMLEditRules::ConvertListType(Element& aListElement, Element* element = child->AsElement(); if (HTMLEditUtils::IsListItem(element) && !element->IsHTMLElement(&aNewListItemTag)) { - child = HTMLEditorRef().ReplaceContainerWithTransaction( - *element, aNewListItemTag); + child = MOZ_KnownLive(HTMLEditorRef()) + .ReplaceContainerWithTransaction(MOZ_KnownLive(*element), + aNewListItemTag); if (NS_WARN_IF(!CanHandleEditAction())) { return CreateElementResult(NS_ERROR_EDITOR_DESTROYED); } @@ -5634,8 +5667,8 @@ CreateElementResult HTMLEditRules::ConvertListType(Element& aListElement, !element->IsHTMLElement(&aNewListTag)) { // XXX List elements shouldn't have other list elements as their // child. Why do we handle such invalid tree? - CreateElementResult convertListTypeResult = - ConvertListType(*child->AsElement(), aNewListTag, aNewListItemTag); + CreateElementResult convertListTypeResult = ConvertListType( + MOZ_KnownLive(*child->AsElement()), aNewListTag, aNewListItemTag); if (NS_WARN_IF(convertListTypeResult.Failed())) { return convertListTypeResult; } @@ -5649,8 +5682,9 @@ CreateElementResult HTMLEditRules::ConvertListType(Element& aListElement, return CreateElementResult(&aListElement); } - RefPtr listElement = HTMLEditorRef().ReplaceContainerWithTransaction( - aListElement, aNewListTag); + RefPtr listElement = + MOZ_KnownLive(HTMLEditorRef()) + .ReplaceContainerWithTransaction(aListElement, aNewListTag); if (NS_WARN_IF(!CanHandleEditAction())) { return CreateElementResult(NS_ERROR_EDITOR_DESTROYED); } @@ -5685,8 +5719,10 @@ nsresult HTMLEditRules::CreateStyleForInsertText(Document& aDocument) { while (item && node != rootElement) { // XXX If we redesign ClearStyle(), we can use EditorDOMPoint in this // method. - nsresult rv = HTMLEditorRef().ClearStyle(address_of(node), &offset, - item->tag, item->attr); + nsresult rv = + MOZ_KnownLive(HTMLEditorRef()) + .ClearStyle(address_of(node), &offset, MOZ_KnownLive(item->tag), + MOZ_KnownLive(item->attr)); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -5726,8 +5762,9 @@ nsresult HTMLEditRules::CreateStyleForInsertText(Document& aDocument) { } OwningNonNull newNode = EditorBase::CreateTextNode(aDocument, EmptyString()); - nsresult rv = HTMLEditorRef().InsertNodeWithTransaction( - *newNode, EditorRawDOMPoint(node, offset)); + nsresult rv = MOZ_KnownLive(HTMLEditorRef()) + .InsertNodeWithTransaction( + *newNode, EditorRawDOMPoint(node, offset)); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -5743,7 +5780,8 @@ nsresult HTMLEditRules::CreateStyleForInsertText(Document& aDocument) { HTMLEditor::FontSize dir = relFontSize > 0 ? HTMLEditor::FontSize::incr : HTMLEditor::FontSize::decr; for (int32_t j = 0; j < DeprecatedAbs(relFontSize); j++) { - rv = HTMLEditorRef().RelativeFontChangeOnTextNode(dir, newNode, 0, -1); + rv = MOZ_KnownLive(HTMLEditorRef()) + .RelativeFontChangeOnTextNode(dir, newNode, 0, -1); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -5754,8 +5792,10 @@ nsresult HTMLEditRules::CreateStyleForInsertText(Document& aDocument) { } while (item) { - rv = HTMLEditorRef().SetInlinePropertyOnNode( - *node->AsContent(), *item->tag, item->attr, item->value); + rv = MOZ_KnownLive(HTMLEditorRef()) + .SetInlinePropertyOnNode(MOZ_KnownLive(*node->AsContent()), + MOZ_KnownLive(*item->tag), + MOZ_KnownLive(item->attr), item->value); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -5854,7 +5894,7 @@ nsresult HTMLEditRules::AlignContentsAtSelection(const nsAString& aAlignType) { // header; in HTML 4, it can directly carry the ALIGN attribute and we // don't need to make a div! If we are in CSS mode, all the work is done // in AlignBlock - rv = AlignBlock(*node->AsElement(), aAlignType, + rv = AlignBlock(MOZ_KnownLive(*node->AsElement()), aAlignType, ResetAlignOf::OnlyDescendants); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; @@ -5993,7 +6033,7 @@ nsresult HTMLEditRules::AlignContentsAtSelection(const nsAString& aAlignType) { // don't need to nest it, just set the alignment. In CSS, assign the // corresponding CSS styles in AlignBlock if (HTMLEditUtils::SupportsAlignAttr(*curNode)) { - rv = AlignBlock(*curNode->AsElement(), aAlignType, + rv = AlignBlock(MOZ_KnownLive(*curNode->AsElement()), aAlignType, ResetAlignOf::ElementAndDescendants); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; @@ -6090,8 +6130,9 @@ nsresult HTMLEditRules::AlignContentsAtSelection(const nsAString& aAlignType) { } // Tuck the node into the end of the active div - rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode->AsContent(), - *curDiv); + rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeToEndWithTransaction(MOZ_KnownLive(*curNode->AsContent()), + *curDiv); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -6139,8 +6180,10 @@ nsresult HTMLEditRules::AlignBlockContents(nsINode& aNode, if (firstChild == lastChild && firstChild->IsHTMLElement(nsGkAtoms::div)) { // the cell already has a div containing all of its content: just // act on this div. - nsresult rv = HTMLEditorRef().SetAttributeOrEquivalent( - firstChild->AsElement(), nsGkAtoms::align, aAlignType, false); + nsresult rv = + MOZ_KnownLive(HTMLEditorRef()) + .SetAttributeOrEquivalent(MOZ_KnownLive(firstChild->AsElement()), + nsGkAtoms::align, aAlignType, false); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -6162,8 +6205,9 @@ nsresult HTMLEditRules::AlignBlockContents(nsINode& aNode, return NS_ERROR_FAILURE; } // set up the alignment on the div - nsresult rv = HTMLEditorRef().SetAttributeOrEquivalent( - divElem, nsGkAtoms::align, aAlignType, false); + nsresult rv = MOZ_KnownLive(HTMLEditorRef()) + .SetAttributeOrEquivalent(divElem, nsGkAtoms::align, + aAlignType, false); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -6172,8 +6216,9 @@ nsresult HTMLEditRules::AlignBlockContents(nsINode& aNode, } // tuck the children into the end of the active div while (lastChild && (lastChild != divElem)) { - nsresult rv = HTMLEditorRef().MoveNodeWithTransaction( - *lastChild, EditorRawDOMPoint(divElem, 0)); + nsresult rv = + MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeWithTransaction(*lastChild, EditorRawDOMPoint(divElem, 0)); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -7172,7 +7217,8 @@ nsresult HTMLEditRules::GetNodesForOperation( if (aTouchContent == TouchContent::yes && IsInlineNode(node) && HTMLEditorRef().IsContainer(node) && !EditorBase::IsTextNode(node)) { nsTArray> arrayOfInlines; - nsresult rv = BustUpInlinesAtBRs(*node->AsContent(), arrayOfInlines); + nsresult rv = BustUpInlinesAtBRs(MOZ_KnownLive(*node->AsContent()), + arrayOfInlines); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -7460,8 +7506,9 @@ nsresult HTMLEditRules::BustUpInlinesAtBRs( // Move break outside of container and also put in node list EditorRawDOMPoint atNextNode(splitNodeResult.GetNextNode()); - nsresult rv = HTMLEditorRef().MoveNodeWithTransaction(*brNode->AsContent(), - atNextNode); + nsresult rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeWithTransaction( + MOZ_KnownLive(*brNode->AsContent()), atNextNode); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -8069,8 +8116,9 @@ nsresult HTMLEditRules::ReturnInListItem(Element& aListItem, nsINode& aNode, "Failed to advance offset after the right list node"); if (HTMLEditUtils::IsList(atNextSiblingOfLeftList.GetContainer())) { // If so, move item out of this list and into the grandparent list - nsresult rv = HTMLEditorRef().MoveNodeWithTransaction( - aListItem, atNextSiblingOfLeftList); + nsresult rv = + MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeWithTransaction(aListItem, atNextSiblingOfLeftList); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -8222,9 +8270,10 @@ nsresult HTMLEditRules::ReturnInListItem(Element& aListItem, nsINode& aNode, } RefPtr brElement; - nsresult rv = - HTMLEditorRef().CopyLastEditableChildStylesWithTransaction( - *prevItem->AsElement(), aListItem, address_of(brElement)); + nsresult rv = MOZ_KnownLive(HTMLEditorRef()) + .CopyLastEditableChildStylesWithTransaction( + MOZ_KnownLive(*prevItem->AsElement()), aListItem, + address_of(brElement)); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -8361,8 +8410,9 @@ nsresult HTMLEditRules::MakeBlockquote( // note: doesn't matter if we set mNewBlock multiple times. } - nsresult rv = HTMLEditorRef().MoveNodeToEndWithTransaction( - *curNode->AsContent(), *curBlock); + nsresult rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeToEndWithTransaction( + MOZ_KnownLive(*curNode->AsContent()), *curBlock); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -8399,8 +8449,9 @@ nsresult HTMLEditRules::RemoveBlockStyle( continue; } // Remove current block - nsresult rv = HTMLEditorRef().RemoveBlockContainerWithTransaction( - *curNode->AsElement()); + nsresult rv = MOZ_KnownLive(HTMLEditorRef()) + .RemoveBlockContainerWithTransaction( + MOZ_KnownLive(*curNode->AsElement())); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -8524,9 +8575,9 @@ nsresult HTMLEditRules::ApplyBlockStyle( HTMLEditUtils::IsFormatNode(curNode)) { // Forget any previous block used for previous inline nodes curBlock = nullptr; - newBlock = - HTMLEditorRef().ReplaceContainerAndCloneAttributesWithTransaction( - *curNode->AsElement(), aBlockTag); + newBlock = MOZ_KnownLive(HTMLEditorRef()) + .ReplaceContainerAndCloneAttributesWithTransaction( + MOZ_KnownLive(*curNode->AsElement()), aBlockTag); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -8606,8 +8657,9 @@ nsresult HTMLEditRules::ApplyBlockStyle( // Remember our new block for postprocessing mNewBlock = curBlock; // Note: doesn't matter if we set mNewBlock multiple times. - nsresult rv = HTMLEditorRef().MoveNodeToEndWithTransaction( - *curNode->AsContent(), *curBlock); + nsresult rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeToEndWithTransaction( + MOZ_KnownLive(*curNode->AsContent()), *curBlock); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -8662,8 +8714,9 @@ nsresult HTMLEditRules::ApplyBlockStyle( // This is a continuation of some inline nodes that belong together in // the same block item. Use curBlock. - nsresult rv = HTMLEditorRef().MoveNodeToEndWithTransaction( - *curNode->AsContent(), *curBlock); + nsresult rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeToEndWithTransaction( + MOZ_KnownLive(*curNode->AsContent()), *curBlock); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -8751,8 +8804,9 @@ nsresult HTMLEditRules::JoinNearestEditableNodesWithTransaction( // left one if (parent != rightParent) { int32_t parOffset = parent->ComputeIndexOf(&aNodeLeft); - nsresult rv = HTMLEditorRef().MoveNodeWithTransaction( - aNodeRight, EditorRawDOMPoint(parent, parOffset)); + nsresult rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeWithTransaction( + aNodeRight, EditorRawDOMPoint(parent, parOffset)); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -9684,8 +9738,8 @@ nsresult HTMLEditRules::PopListItem(nsIContent& aListItem, bool* aOutOfList) { "Failed to advance offset to right list node"); } - nsresult rv = - HTMLEditorRef().MoveNodeWithTransaction(*listItem, pointToInsertListItem); + nsresult rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeWithTransaction(*listItem, pointToInsertListItem); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -9703,8 +9757,9 @@ nsresult HTMLEditRules::PopListItem(nsIContent& aListItem, bool* aOutOfList) { // current parent is
, there is same issue. if (!HTMLEditUtils::IsList(pointToInsertListItem.GetContainer()) && HTMLEditUtils::IsListItem(listItem)) { - rv = HTMLEditorRef().RemoveBlockContainerWithTransaction( - *listItem->AsElement()); + rv = MOZ_KnownLive(HTMLEditorRef()) + .RemoveBlockContainerWithTransaction( + MOZ_KnownLive(*listItem->AsElement())); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -9747,7 +9802,7 @@ nsresult HTMLEditRules::RemoveListStructure(Element& aListElement) { } if (HTMLEditUtils::IsList(child)) { - nsresult rv = RemoveListStructure(*child->AsElement()); + nsresult rv = RemoveListStructure(MOZ_KnownLive(*child->AsElement())); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -9768,8 +9823,8 @@ nsresult HTMLEditRules::RemoveListStructure(Element& aListElement) { } // Delete the now-empty list - nsresult rv = - HTMLEditorRef().RemoveBlockContainerWithTransaction(aListElement); + nsresult rv = MOZ_KnownLive(HTMLEditorRef()) + .RemoveBlockContainerWithTransaction(aListElement); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -10155,7 +10210,9 @@ nsresult HTMLEditRules::RemoveAlignment(nsINode& aNode, } // now remove the CENTER container - rv = HTMLEditorRef().RemoveContainerWithTransaction(*child->AsElement()); + rv = MOZ_KnownLive(HTMLEditorRef()) + .RemoveContainerWithTransaction( + MOZ_KnownLive(*child->AsElement())); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -10177,8 +10234,10 @@ nsresult HTMLEditRules::RemoveAlignment(nsINode& aNode, } if (useCSS) { if (child->IsAnyOfHTMLElements(nsGkAtoms::table, nsGkAtoms::hr)) { - nsresult rv = HTMLEditorRef().SetAttributeOrEquivalent( - child->AsElement(), nsGkAtoms::align, aAlignType, false); + nsresult rv = MOZ_KnownLive(HTMLEditorRef()) + .SetAttributeOrEquivalent( + MOZ_KnownLive(child->AsElement()), + nsGkAtoms::align, aAlignType, false); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -10291,8 +10350,9 @@ nsresult HTMLEditRules::AlignBlock(Element& aElement, if (HTMLEditorRef().IsCSSEnabled()) { // Let's use CSS alignment; we use margin-left and margin-right for tables // and text-align for other block-level elements - nsresult rv = HTMLEditorRef().SetAttributeOrEquivalent( - &aElement, nsGkAtoms::align, aAlignType, false); + nsresult rv = MOZ_KnownLive(HTMLEditorRef()) + .SetAttributeOrEquivalent(&aElement, nsGkAtoms::align, + aAlignType, false); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -10309,8 +10369,9 @@ nsresult HTMLEditRules::AlignBlock(Element& aElement, return NS_OK; } - rv = HTMLEditorRef().SetAttributeOrEquivalent(&aElement, nsGkAtoms::align, - aAlignType, false); + rv = MOZ_KnownLive(HTMLEditorRef()) + .SetAttributeOrEquivalent(&aElement, nsGkAtoms::align, aAlignType, + false); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -10370,8 +10431,8 @@ nsresult HTMLEditRules::ChangeMarginStart(Element& aElement, bool aIncrease) { return NS_OK; } - HTMLEditorRef().mCSSEditUtils->RemoveCSSProperty(aElement, marginProperty, - value); + HTMLEditorRef().mCSSEditUtils->RemoveCSSProperty( + aElement, MOZ_KnownLive(marginProperty), value); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -10384,7 +10445,8 @@ nsresult HTMLEditRules::ChangeMarginStart(Element& aElement, bool aIncrease) { return NS_OK; } - nsresult rv = HTMLEditorRef().RemoveContainerWithTransaction(aElement); + nsresult rv = + MOZ_KnownLive(HTMLEditorRef()).RemoveContainerWithTransaction(aElement); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -10575,8 +10637,9 @@ nsresult HTMLEditRules::PrepareToMakeElementAbsolutePosition( // new block for postprocessing. } // Tuck the node into the end of the active list - rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode->AsContent(), - *curList); + rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeToEndWithTransaction( + MOZ_KnownLive(*curNode->AsContent()), *curList); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -10641,7 +10704,8 @@ nsresult HTMLEditRules::PrepareToMakeElementAbsolutePosition( return NS_ERROR_FAILURE; } } - rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*listItem, *curList); + rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeToEndWithTransaction(*listItem, *curList); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -10681,8 +10745,9 @@ nsresult HTMLEditRules::PrepareToMakeElementAbsolutePosition( } // Tuck the node into the end of the active blockquote - rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode->AsContent(), - *curPositionedDiv); + rv = MOZ_KnownLive(HTMLEditorRef()) + .MoveNodeToEndWithTransaction(MOZ_KnownLive(*curNode->AsContent()), + *curPositionedDiv); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -10701,7 +10766,9 @@ nsresult HTMLEditRules::DidAbsolutePosition() { if (!mNewBlock) { return NS_OK; } - nsresult rv = HTMLEditorRef().SetPositionToAbsoluteOrStatic(*mNewBlock, true); + OwningNonNull newBlock(*mNewBlock); + nsresult rv = MOZ_KnownLive(HTMLEditorRef()) + .SetPositionToAbsoluteOrStatic(*newBlock, true); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } @@ -10738,8 +10805,8 @@ nsresult HTMLEditRules::WillRemoveAbsolutePosition(bool* aCancel, { AutoSelectionRestorer restoreSelectionLater(HTMLEditorRef()); - nsresult rv = - HTMLEditorRef().SetPositionToAbsoluteOrStatic(*element, false); + nsresult rv = MOZ_KnownLive(HTMLEditorRef()) + .SetPositionToAbsoluteOrStatic(*element, false); if (NS_WARN_IF(!CanHandleEditAction())) { return NS_ERROR_EDITOR_DESTROYED; } diff --git a/editor/libeditor/HTMLEditRules.h b/editor/libeditor/HTMLEditRules.h index a5a78297c6f4..bc6997a8ac1c 100644 --- a/editor/libeditor/HTMLEditRules.h +++ b/editor/libeditor/HTMLEditRules.h @@ -78,15 +78,23 @@ class HTMLEditRules : public TextEditRules { HTMLEditRules(); // TextEditRules methods + MOZ_CAN_RUN_SCRIPT virtual nsresult Init(TextEditor* aTextEditor) override; virtual nsresult DetachEditor() override; virtual nsresult BeforeEdit(EditSubAction aEditSubAction, nsIEditor::EDirection aDirection) override; + MOZ_CAN_RUN_SCRIPT virtual nsresult AfterEdit(EditSubAction aEditSubAction, nsIEditor::EDirection aDirection) override; + // NOTE: Don't mark WillDoAction() nor DidDoAction() as MOZ_CAN_RUN_SCRIPT + // because they are too generic and doing it makes a lot of public + // editor methods marked as MOZ_CAN_RUN_SCRIPT too, but some of them + // may not causes running script. So, ideal fix must be that we make + // each method callsed by this method public. MOZ_CAN_RUN_SCRIPT_BOUNDARY virtual nsresult WillDoAction(EditSubActionInfo& aInfo, bool* aCancel, bool* aHandled) override; + MOZ_CAN_RUN_SCRIPT_BOUNDARY virtual nsresult DidDoAction(EditSubActionInfo& aInfo, nsresult aResult) override; virtual bool DocumentIsEmpty() override; @@ -96,9 +104,13 @@ class HTMLEditRules : public TextEditRules { */ MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult DocumentModified(); + MOZ_CAN_RUN_SCRIPT nsresult GetListState(bool* aMixed, bool* aOL, bool* aUL, bool* aDL); + MOZ_CAN_RUN_SCRIPT nsresult GetListItemState(bool* aMixed, bool* aLI, bool* aDT, bool* aDD); + MOZ_CAN_RUN_SCRIPT nsresult GetAlignment(bool* aMixed, nsIHTMLEditor::EAlignment* aAlign); + MOZ_CAN_RUN_SCRIPT nsresult GetParagraphState(bool* aMixed, nsAString& outFormat); /** @@ -174,6 +186,7 @@ class HTMLEditRules : public TextEditRules { * @param aMaxLength The maximum string length which the editor * allows to set. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult WillInsertText(EditSubAction aEditSubAction, bool* aCancel, bool* aHandled, const nsAString* inString, @@ -210,6 +223,7 @@ class HTMLEditRules : public TextEditRules { * @param aInsertToBreak The point where new
element will be * inserted before. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult InsertBRElement(const EditorDOMPoint& aInsertToBreak); /** @@ -315,6 +329,7 @@ class HTMLEditRules : public TextEditRules { * be joined or it's impossible to join them but it's not * unexpected case, this returns true with this. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE EditActionResult TryToJoinBlocksWithTransaction(nsIContent& aLeftNode, nsIContent& aRightNode); @@ -327,6 +342,7 @@ class HTMLEditRules : public TextEditRules { * @return Sets handled to true if this actually joins the nodes. * canceled is always false. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE EditActionResult MoveBlock(Element& aLeftBlock, Element& aRightBlock, int32_t aLeftOffset, @@ -341,6 +357,7 @@ class HTMLEditRules : public TextEditRules { * the nodes. * canceled is always false. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE EditActionResult MoveNodeSmart(nsIContent& aNode, Element& aDestElement, int32_t* aInOutDestOffset); @@ -354,6 +371,7 @@ class HTMLEditRules : public TextEditRules { * the nodes. * canceled is always false. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE EditActionResult MoveContents(Element& aElement, Element& aDestElement, int32_t* aInOutDestOffset); @@ -455,6 +473,7 @@ class HTMLEditRules : public TextEditRules { * @param aCancel Returns true if the operation is canceled. * @param aHandled Returns true if the edit action is handled. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult WillRemoveAbsolutePosition(bool* aCancel, bool* aHandled); @@ -544,6 +563,7 @@ class HTMLEditRules : public TextEditRules { * @param aTargetElement Returns target element which should be * changed to absolute positioned. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult PrepareToMakeElementAbsolutePosition( bool* aHandled, RefPtr* aTargetElement); @@ -554,6 +574,7 @@ class HTMLEditRules : public TextEditRules { * WillAbsolutePosition() to absolute positioned. * Therefore, this might cause destroying the HTML editor. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult DidAbsolutePosition(); /** @@ -564,6 +585,7 @@ class HTMLEditRules : public TextEditRules { * to aAlignType. * @param aAlignType New value of align attribute of
. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult AlignInnerBlocks(nsINode& aNode, const nsAString& aAlignType); @@ -578,6 +600,7 @@ class HTMLEditRules : public TextEditRules { * @param aAlignType New value of align attribute of
which * is only child of aNode. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult AlignBlockContents(nsINode& aNode, const nsAString& aAlignType); @@ -592,6 +615,7 @@ class HTMLEditRules : public TextEditRules { * @param aAlignType New align attribute value where the contents * should be aligned to. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult AlignContentsAtSelection(const nsAString& aAlignType); nsresult AppendInnerFormatNodes(nsTArray>& aArray, @@ -677,6 +701,7 @@ class HTMLEditRules : public TextEditRules { * @param aOffset Typically, Selection start offset in the * start container, where to insert a break. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult ReturnInListItem(Element& aListItem, nsINode& aNode, int32_t aOffset); @@ -684,6 +709,7 @@ class HTMLEditRules : public TextEditRules { * Called after handling edit action. This may adjust Selection, remove * unnecessary empty nodes, create
elements if needed, etc. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult AfterEditInner(EditSubAction aEditSubAction, nsIEditor::EDirection aDirection); @@ -693,6 +719,7 @@ class HTMLEditRules : public TextEditRules { * need to check if the editor is still available even if this returns * NS_OK. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult IndentAroundSelectionWithCSS(); /** @@ -701,6 +728,7 @@ class HTMLEditRules : public TextEditRules { * need to check if the editor is still available even if this returns * NS_OK. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult IndentAroundSelectionWithHTML(); /** @@ -716,6 +744,7 @@ class HTMLEditRules : public TextEditRules { * The middle content is middle content of last * outdented element. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE SplitRangeOffFromNodeResult OutdentAroundSelection(); /** @@ -735,6 +764,7 @@ class HTMLEditRules : public TextEditRules { * The middle content is nullptr since * removing it is the job of this method. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE SplitRangeOffFromNodeResult SplitRangeOffFromBlockAndRemoveMiddleContainer(Element& aBlockElement, nsIContent& aStartOfRange, @@ -776,6 +806,7 @@ class HTMLEditRules : public TextEditRules { * if aIsBlockIndentedWithCSS is true. * Otherwise, nullptr. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE SplitRangeOffFromNodeResult OutdentPartOfBlock(Element& aBlockElement, nsIContent& aStartOfOutdent, nsIContent& aEndOutdent, bool aIsBlockIndentedWithCSS); @@ -786,6 +817,7 @@ class HTMLEditRules : public TextEditRules { * need to check if the editor is still available even if this returns * NS_OK. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult MakeList(nsAtom& aListType, bool aEntireList, const nsAString* aBulletType, bool* aCancel, nsAtom& aItemType); @@ -804,6 +836,7 @@ class HTMLEditRules : public TextEditRules { * New list element may be aListElement if its * tag name is same as aNewListTag. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE CreateElementResult ConvertListType(Element& aListElement, nsAtom& aListType, nsAtom& aItemType); @@ -814,6 +847,7 @@ class HTMLEditRules : public TextEditRules { * * @param aDocument The document of the editor. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult CreateStyleForInsertText(dom::Document& aDocument); /** @@ -901,6 +935,7 @@ class HTMLEditRules : public TextEditRules { * transaction. We should rename this to making clearer what this does. */ enum class TouchContent { no, yes }; + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult GetNodesForOperation( nsTArray>& aArrayOfRanges, nsTArray>& aOutArrayOfNodes, @@ -913,6 +948,7 @@ class HTMLEditRules : public TextEditRules { * GetNodesFromPoint() constructs a list of nodes from a point that will be * operated on. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult GetNodesFromPoint(const EditorDOMPoint& aPoint, EditSubAction aEditSubAction, nsTArray>& outArrayOfNodes, @@ -922,16 +958,19 @@ class HTMLEditRules : public TextEditRules { * GetNodesFromSelection() constructs a list of nodes from the selection that * will be operated on. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult GetNodesFromSelection(EditSubAction aEditSubAction, nsTArray>& outArrayOfNodes, TouchContent aTouchContent); enum class EntireList { no, yes }; + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult GetListActionNodes(nsTArray>& aOutArrayOfNodes, EntireList aEntireList, TouchContent aTouchContent); void GetDefinitionListItemTypes(Element* aElement, bool* aDT, bool* aDD); + MOZ_CAN_RUN_SCRIPT nsresult GetParagraphFormatNodes( nsTArray>& outArrayOfNodes); void LookInsideDivBQandList(nsTArray>& aNodeArray); @@ -959,6 +998,7 @@ class HTMLEditRules : public TextEditRules { * be set if
is at start edge of aNode) and * aNode itself. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult BustUpInlinesAtBRs( nsIContent& aNode, nsTArray>& aOutArrayOfNodes); @@ -985,6 +1025,7 @@ class HTMLEditRules : public TextEditRules { * If aNodeArray has a table related element,
  • ,
    or
    , * it will removed and its contents will be moved to where it was. */ + MOZ_CAN_RUN_SCRIPT nsresult RemoveBlockStyle(nsTArray>& aNodeArray); /** @@ -1003,6 +1044,7 @@ class HTMLEditRules : public TextEditRules { * @param aNodeArray Must be descendants of a node. * @param aBlockTag The element name of new block elements. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult ApplyBlockStyle( nsTArray>& aNodeArray, nsAtom& aBlockTag); @@ -1015,6 +1057,7 @@ class HTMLEditRules : public TextEditRules { * @param aNodeArray Nodes which will be moved into created *
    elements. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult MakeBlockquote(nsTArray>& aNodeArray); @@ -1060,6 +1103,7 @@ class HTMLEditRules : public TextEditRules { * @param aNewFirstChildOfRightNode * The point at the first child of aRightNode. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult JoinNearestEditableNodesWithTransaction( nsIContent& aLeftNode, nsIContent& aRightNode, EditorDOMPoint* aNewFirstChildOfRightNode); @@ -1081,6 +1125,7 @@ class HTMLEditRules : public TextEditRules { * removed (i.e., unwrapped contents of * aListItem). Otherwise, false. */ + MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult PopListItem(nsIContent& aListItem, bool* aOutOfList = nullptr); @@ -1096,6 +1141,7 @@ class HTMLEditRules : public TextEditRules { * * @param aListElement A