From 02bdb2d1abafe8ca672e6fa54218f525aa8344fd Mon Sep 17 00:00:00 2001
From: "Byron Campen [:bwc]"
Date: Mon, 6 Aug 2018 18:08:55 +0000
Subject: [PATCH 01/28] Bug 1479853: Prevent more than one VideoConduit having
the same remote SSRC. r=ng
Differential Revision: https://phabricator.services.mozilla.com/D2738
--HG--
extra : moz-landing-system : lando
---
.../src/media-conduit/AudioConduit.h | 4 +
.../src/media-conduit/MediaConduitInterface.h | 142 +++++++++++-------
.../src/media-conduit/VideoConduit.cpp | 70 +++++++--
.../src/media-conduit/VideoConduit.h | 1 +
4 files changed, 148 insertions(+), 69 deletions(-)
diff --git a/media/webrtc/signaling/src/media-conduit/AudioConduit.h b/media/webrtc/signaling/src/media-conduit/AudioConduit.h
index f771b2279359..45dd635bbaa8 100644
--- a/media/webrtc/signaling/src/media-conduit/AudioConduit.h
+++ b/media/webrtc/signaling/src/media-conduit/AudioConduit.h
@@ -208,6 +208,10 @@ public:
{
return false;
}
+ bool UnsetRemoteSSRC(uint32_t ssrc) override
+ {
+ return true;
+ }
bool GetRemoteSSRC(unsigned int* ssrc) override;
bool SetLocalCNAME(const char* cname) override;
bool SetLocalMID(const std::string& mid) override;
diff --git a/media/webrtc/signaling/src/media-conduit/MediaConduitInterface.h b/media/webrtc/signaling/src/media-conduit/MediaConduitInterface.h
index 271f7fe245e1..dc28c7b65542 100644
--- a/media/webrtc/signaling/src/media-conduit/MediaConduitInterface.h
+++ b/media/webrtc/signaling/src/media-conduit/MediaConduitInterface.h
@@ -26,6 +26,7 @@
#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
#include
+#include
namespace webrtc {
class VideoFrame;
@@ -40,64 +41,6 @@ enum class MediaSessionConduitLocalDirection : int {
using RtpExtList = std::vector;
-// Wrap the webrtc.org Call class adding mozilla add/ref support.
-class WebRtcCallWrapper : public RefCounted
-{
-public:
- typedef webrtc::Call::Config Config;
-
- static RefPtr Create()
- {
- return new WebRtcCallWrapper();
- }
-
- static RefPtr Create(UniquePtr&& aCall)
- {
- return new WebRtcCallWrapper(std::move(aCall));
- }
-
- webrtc::Call* Call() const
- {
- return mCall.get();
- }
-
- virtual ~WebRtcCallWrapper()
- {
- if (mCall->voice_engine()) {
- webrtc::VoiceEngine* voice_engine = mCall->voice_engine();
- mCall.reset(nullptr); // Force it to release the voice engine reference
- // Delete() must be after all refs are released
- webrtc::VoiceEngine::Delete(voice_engine);
- } else {
- // Must ensure it's destroyed *before* the EventLog!
- mCall.reset(nullptr);
- }
- }
-
- MOZ_DECLARE_REFCOUNTED_TYPENAME(WebRtcCallWrapper)
-
-private:
- WebRtcCallWrapper()
- {
- webrtc::Call::Config config(&mEventLog);
- mCall.reset(webrtc::Call::Create(config));
- }
-
- explicit WebRtcCallWrapper(UniquePtr&& aCall)
- {
- MOZ_ASSERT(aCall);
- mCall = std::move(aCall);
- }
-
- // Don't allow copying/assigning.
- WebRtcCallWrapper(const WebRtcCallWrapper&) = delete;
- void operator=(const WebRtcCallWrapper&) = delete;
-
- UniquePtr mCall;
- webrtc::RtcEventLogNullImpl mEventLog;
-};
-
-
/**
* Abstract Interface for transporting RTP packets - audio/vidoeo
* The consumers of this interface are responsible for passing in
@@ -268,6 +211,7 @@ public:
virtual bool GetRemoteSSRC(unsigned int* ssrc) = 0;
virtual bool SetRemoteSSRC(unsigned int ssrc) = 0;
+ virtual bool UnsetRemoteSSRC(uint32_t ssrc) = 0;
virtual bool SetLocalCNAME(const char* cname) = 0;
virtual bool SetLocalMID(const std::string& mid) = 0;
@@ -319,6 +263,87 @@ public:
};
+// Wrap the webrtc.org Call class adding mozilla add/ref support.
+class WebRtcCallWrapper : public RefCounted
+{
+public:
+ typedef webrtc::Call::Config Config;
+
+ static RefPtr Create()
+ {
+ return new WebRtcCallWrapper();
+ }
+
+ static RefPtr Create(UniquePtr&& aCall)
+ {
+ return new WebRtcCallWrapper(std::move(aCall));
+ }
+
+ // Don't allow copying/assigning.
+ WebRtcCallWrapper(const WebRtcCallWrapper&) = delete;
+ void operator=(const WebRtcCallWrapper&) = delete;
+
+ webrtc::Call* Call() const
+ {
+ return mCall.get();
+ }
+
+ virtual ~WebRtcCallWrapper()
+ {
+ if (mCall->voice_engine()) {
+ webrtc::VoiceEngine* voice_engine = mCall->voice_engine();
+ mCall.reset(nullptr); // Force it to release the voice engine reference
+ // Delete() must be after all refs are released
+ webrtc::VoiceEngine::Delete(voice_engine);
+ } else {
+ // Must ensure it's destroyed *before* the EventLog!
+ mCall.reset(nullptr);
+ }
+ }
+
+ bool UnsetRemoteSSRC(uint32_t ssrc)
+ {
+ for (auto conduit : mConduits) {
+ if (!conduit->UnsetRemoteSSRC(ssrc)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ void RegisterConduit(MediaSessionConduit* conduit)
+ {
+ mConduits.insert(conduit);
+ }
+
+ void UnregisterConduit(MediaSessionConduit* conduit)
+ {
+ mConduits.erase(conduit);
+ }
+
+ MOZ_DECLARE_REFCOUNTED_TYPENAME(WebRtcCallWrapper)
+
+private:
+ WebRtcCallWrapper()
+ {
+ webrtc::Call::Config config(&mEventLog);
+ mCall.reset(webrtc::Call::Create(config));
+ }
+
+ explicit WebRtcCallWrapper(UniquePtr&& aCall)
+ {
+ MOZ_ASSERT(aCall);
+ mCall = std::move(aCall);
+ }
+
+ UniquePtr mCall;
+ webrtc::RtcEventLogNullImpl mEventLog;
+ // Allows conduits to know about one another, to avoid remote SSRC
+ // collisions.
+ std::set mConduits;
+};
+
// Abstract base classes for external encoder/decoder.
class CodecPluginID
{
@@ -389,6 +414,7 @@ public:
virtual void DisableSsrcChanges() = 0;
bool SetRemoteSSRC(unsigned int ssrc) override = 0;
+ bool UnsetRemoteSSRC(uint32_t ssrc) override = 0;
/**
* Function to deliver a capture video frame for encoding and transport.
diff --git a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
index 502d1dd0366d..7507e6e5796e 100644
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
@@ -277,6 +277,7 @@ WebrtcVideoConduit::WebrtcVideoConduit(RefPtr aCall,
, mRecvCodecPlugin(nullptr)
, mVideoStatsTimer(NS_NewTimer())
{
+ mCall->RegisterConduit(this);
mRecvStreamConfig.renderer = this;
// Video Stats Callback
@@ -307,6 +308,7 @@ WebrtcVideoConduit::~WebrtcVideoConduit()
{
CSFLogDebug(LOGTAG, "%s ", __FUNCTION__);
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
+ mCall->UnregisterConduit(this);
if (mVideoStatsTimer) {
CSFLogDebug(LOGTAG, "canceling StreamStats for VideoConduit: %p", this);
MutexAutoLock lock(mCodecMutex);
@@ -884,6 +886,22 @@ WebrtcVideoConduit::ConfigureSendMediaCodec(const VideoCodecConfig* codecConfig)
return condError;
}
+static uint32_t
+GenerateRandomSSRC()
+{
+ uint32_t ssrc;
+ do {
+ SECStatus rv = PK11_GenerateRandom(reinterpret_cast(&ssrc), sizeof(ssrc));
+ if (rv != SECSuccess) {
+ CSFLogError(LOGTAG, "%s: PK11_GenerateRandom failed with error %d",
+ __FUNCTION__, rv);
+ return 0;
+ }
+ } while (ssrc == 0); // webrtc.org code has fits if you select an SSRC of 0
+
+ return ssrc;
+}
+
bool
WebrtcVideoConduit::SetRemoteSSRC(unsigned int ssrc)
{
@@ -902,6 +920,11 @@ WebrtcVideoConduit::SetRemoteSSRC(unsigned int ssrc)
}
CSFLogDebug(LOGTAG, "%s: SSRC %u (0x%x)", __FUNCTION__, ssrc, ssrc);
+ if (!mCall->UnsetRemoteSSRC(ssrc)) {
+ CSFLogError(LOGTAG, "%s: Failed to unset SSRC %u (0x%x) on other conduits,"
+ " bailing", __FUNCTION__, ssrc, ssrc);
+ return false;
+ }
mRecvStreamConfig.rtp.remote_ssrc = ssrc;
mWaitingForInitialSsrc = false;
@@ -926,6 +949,33 @@ WebrtcVideoConduit::SetRemoteSSRC(unsigned int ssrc)
return (StartReceiving() == kMediaConduitNoError);
}
+bool
+WebrtcVideoConduit::UnsetRemoteSSRC(uint32_t ssrc)
+{
+ unsigned int our_ssrc;
+ if (!GetRemoteSSRC(&our_ssrc)) {
+ // This only fails when we aren't sending, which isn't really an error here
+ return true;
+ }
+
+ if (our_ssrc != ssrc) {
+ return true;
+ }
+
+ while (our_ssrc == ssrc) {
+ our_ssrc = GenerateRandomSSRC();
+ if (our_ssrc == 0) {
+ return false;
+ }
+ }
+
+ // There is a (tiny) chance that this new random ssrc will collide with some
+ // other conduit's remote ssrc, in which case that conduit will choose a new
+ // one.
+ SetRemoteSSRC(our_ssrc);
+ return true;
+}
+
bool
WebrtcVideoConduit::GetRemoteSSRC(unsigned int* ssrc)
{
@@ -1428,13 +1478,12 @@ WebrtcVideoConduit::ConfigureRecvMediaCodecs(
// Handle un-signalled SSRCs by creating a random one and then when it actually gets set,
// we'll destroy and recreate. Simpler than trying to unwind all the logic that assumes
// the receive stream is created and started when we ConfigureRecvMediaCodecs()
- unsigned int ssrc;
- do {
- SECStatus rv = PK11_GenerateRandom(reinterpret_cast(&ssrc), sizeof(ssrc));
- if (rv != SECSuccess) {
- return kMediaConduitUnknownError;
- }
- } while (ssrc == 0); // webrtc.org code has fits if you select an SSRC of 0
+ uint32_t ssrc = GenerateRandomSSRC();
+ if (ssrc == 0) {
+ // webrtc.org code has fits if you select an SSRC of 0, so that's how
+ // we signal an error.
+ return kMediaConduitUnknownError;
+ }
mRecvStreamConfig.rtp.remote_ssrc = ssrc;
mRecvSSRC = ssrc;
@@ -1451,13 +1500,12 @@ WebrtcVideoConduit::ConfigureRecvMediaCodecs(
auto ssrc = mSendStreamConfig.rtp.ssrcs.front();
Unused << NS_WARN_IF(ssrc == mRecvStreamConfig.rtp.remote_ssrc);
- while (ssrc == mRecvStreamConfig.rtp.remote_ssrc || ssrc == 0) {
- SECStatus rv = PK11_GenerateRandom(reinterpret_cast(&ssrc), sizeof(ssrc));
- if (rv != SECSuccess) {
+ while (ssrc == mRecvStreamConfig.rtp.remote_ssrc) {
+ ssrc = GenerateRandomSSRC();
+ if (ssrc == 0) {
return kMediaConduitUnknownError;
}
}
- // webrtc.org code has fits if you select an SSRC of 0
mRecvStreamConfig.rtp.local_ssrc = ssrc;
CSFLogDebug(LOGTAG, "%s (%p): Local SSRC 0x%08x (of %u), remote SSRC 0x%08x",
diff --git a/media/webrtc/signaling/src/media-conduit/VideoConduit.h b/media/webrtc/signaling/src/media-conduit/VideoConduit.h
index 6d09e828a027..cbba2ad41d6c 100644
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.h
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.h
@@ -275,6 +275,7 @@ public:
bool SetLocalSSRCs(const std::vector & ssrcs) override;
bool GetRemoteSSRC(unsigned int* ssrc) override;
bool SetRemoteSSRC(unsigned int ssrc) override;
+ bool UnsetRemoteSSRC(uint32_t ssrc) override;
bool SetLocalCNAME(const char* cname) override;
bool SetLocalMID(const std::string& mid) override;
From d7600324bbee128fb03113ba0f6df3b69201b49a Mon Sep 17 00:00:00 2001
From: Mark Striemer
Date: Wed, 11 Jul 2018 22:30:36 -0500
Subject: [PATCH 02/28] Bug 1470865 - Dynamically show hidden audio tabs in all
tabs menu r=dao
When a hidden audio tab is muted it isn't pulled into the main all tabs
panel. Unmuting that tab will now add it to the main all tabs panel,
even if the all tabs menu it open.
MozReview-Commit-ID: 2HtZvy7aBsG
--HG--
extra : rebase_source : d728739ef382f14f3a759e9c6aef7cb2771f7c95
---
browser/modules/TabsList.jsm | 50 ++++++++++++++++++++++++------------
1 file changed, 34 insertions(+), 16 deletions(-)
diff --git a/browser/modules/TabsList.jsm b/browser/modules/TabsList.jsm
index f497afbf3372..082fbadfd5ef 100644
--- a/browser/modules/TabsList.jsm
+++ b/browser/modules/TabsList.jsm
@@ -67,27 +67,18 @@ class TabsListBase {
for (let tab of this.gBrowser.tabs) {
if (this.filterFn(tab)) {
- let row = this._createRow(tab);
- row.tab = tab;
- row.addEventListener("command", this);
- this.tabToElement.set(tab, row);
- if (this.className) {
- row.classList.add(this.className);
- }
-
- fragment.appendChild(row);
+ fragment.appendChild(this._createRow(tab));
}
}
- if (this.insertBefore) {
- this.insertBefore.parentNode.insertBefore(fragment, this.insertBefore);
- } else {
- this.containerNode.appendChild(fragment);
- }
-
+ this._addElement(fragment);
this._setupListeners();
}
+ _addElement(elementOrFragment) {
+ this.containerNode.insertBefore(elementOrFragment, this.insertBefore);
+ }
+
/*
* Remove the menuitems from the DOM, cleanup internal state and listeners.
*/
@@ -115,11 +106,32 @@ class TabsListBase {
let item = this.tabToElement.get(tab);
if (item) {
if (!this.filterFn(tab)) {
- // If the tab is no longer in this set of tabs, hide the item.
+ // The tab no longer matches our criteria, remove it.
this._removeItem(item, tab);
} else {
this._setRowAttributes(item, tab);
}
+ } else if (this.filterFn(tab)) {
+ // The tab now matches our criteria, add a row for it.
+ this._addTab(tab);
+ }
+ }
+
+ _addTab(newTab) {
+ let newRow = this._createRow(newTab);
+ let nextTab = newTab.nextSibling;
+
+ while (nextTab && !this.filterFn(nextTab)) {
+ nextTab = nextTab.nextSibling;
+ }
+
+ if (nextTab) {
+ // If we found a tab after this one in the list, insert the new row before it.
+ let nextRow = this.tabToElement.get(nextTab);
+ nextRow.parentNode.insertBefore(newRow, nextRow);
+ } else {
+ // If there's no next tab then insert it as usual.
+ this._addElement(newRow);
}
}
@@ -206,6 +218,12 @@ class TabsPanel extends TabsListBase {
let {doc} = this;
let row = doc.createElementNS(NSXUL, "toolbaritem");
row.setAttribute("class", "all-tabs-item");
+ if (this.className) {
+ row.classList.add(this.className);
+ }
+ row.tab = tab;
+ row.addEventListener("command", this);
+ this.tabToElement.set(tab, row);
let button = doc.createElementNS(NSXUL, "toolbarbutton");
button.setAttribute("class", "all-tabs-button subviewbutton subviewbutton-iconic");
From 226f6e804294baaa18561d203222aa23e3bf393d Mon Sep 17 00:00:00 2001
From: Mark Striemer
Date: Mon, 30 Jul 2018 14:43:40 -0500
Subject: [PATCH 03/28] Bug 1477591 - Use default favicon in all tabs menu
r=dao
MozReview-Commit-ID: 31kPOLp1IVV
--HG--
extra : rebase_source : ef17514450e1911fdd3a183828e71430acc0738f
---
browser/themes/shared/tabs.inc.css | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/browser/themes/shared/tabs.inc.css b/browser/themes/shared/tabs.inc.css
index cab8f51d195e..0bf3e785ffb8 100644
--- a/browser/themes/shared/tabs.inc.css
+++ b/browser/themes/shared/tabs.inc.css
@@ -804,6 +804,10 @@
box-shadow: inset -4px 0 var(--blue-40);
}
+.all-tabs-button {
+ list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.svg");
+}
+
.all-tabs-secondary-button > label {
display: none;
margin: 0 5.5px;
From 40503db0b4b7c5eb1a8c9ff51ddeb34496f189ef Mon Sep 17 00:00:00 2001
From: Nico Grunbaum
Date: Thu, 2 Aug 2018 20:50:24 +0000
Subject: [PATCH 04/28] Bug 1480498 - P1 - Rename RTCRTPStreamStats in WebIDL
to match the spec IDL r=smaug
This renames the RTCRTPStreamStats partial dictionary to match the recent spec changes
Differential Revision: https://phabricator.services.mozilla.com/D2682
--HG--
extra : moz-landing-system : lando
---
dom/webidl/RTCStatsReport.webidl | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/dom/webidl/RTCStatsReport.webidl b/dom/webidl/RTCStatsReport.webidl
index 4f95a4b3ca19..ec54f56f981e 100644
--- a/dom/webidl/RTCStatsReport.webidl
+++ b/dom/webidl/RTCStatsReport.webidl
@@ -26,7 +26,7 @@ dictionary RTCStats {
DOMString id;
};
-dictionary RTCRTPStreamStats : RTCStats {
+dictionary RTCRtpStreamStats : RTCStats {
unsigned long ssrc;
DOMString mediaType;
DOMString remoteId;
@@ -48,7 +48,7 @@ dictionary RTCRTPStreamStats : RTCStats {
unsigned long nackCount;
};
-dictionary RTCInboundRTPStreamStats : RTCRTPStreamStats {
+dictionary RTCInboundRTPStreamStats : RTCRtpStreamStats {
unsigned long packetsReceived;
unsigned long long bytesReceived;
double jitter;
@@ -62,7 +62,7 @@ dictionary RTCInboundRTPStreamStats : RTCRTPStreamStats {
unsigned long framesDecoded;
};
-dictionary RTCOutboundRTPStreamStats : RTCRTPStreamStats {
+dictionary RTCOutboundRTPStreamStats : RTCRtpStreamStats {
unsigned long packetsSent;
unsigned long long bytesSent;
double targetBitrate; // config encoder bitrate target of this SSRC in bits/s
From 87231d61930fdb87da36b39e2bc7ee99fc9ae903 Mon Sep 17 00:00:00 2001
From: Nico Grunbaum
Date: Fri, 3 Aug 2018 17:41:30 +0000
Subject: [PATCH 05/28] Bug 1480498 - P2 - renaming RTCRTPStreamStats in the
WebRTCGlobals r=mjf
Renaming RTCRTPStreamStats in the WebRTCGlobals.
Differential Revision: https://phabricator.services.mozilla.com/D2683
--HG--
extra : moz-landing-system : lando
---
dom/media/webrtc/WebrtcGlobal.h | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/dom/media/webrtc/WebrtcGlobal.h b/dom/media/webrtc/WebrtcGlobal.h
index 15b9bcecc87c..d5892777f75f 100644
--- a/dom/media/webrtc/WebrtcGlobal.h
+++ b/dom/media/webrtc/WebrtcGlobal.h
@@ -280,9 +280,9 @@ struct ParamTraits
}
};
-static void WriteRTCRTPStreamStats(
+static void WriteRTCRtpStreamStats(
Message* aMsg,
- const mozilla::dom::RTCRTPStreamStats& aParam)
+ const mozilla::dom::RTCRtpStreamStats& aParam)
{
WriteParam(aMsg, aParam.mBitrateMean);
WriteParam(aMsg, aParam.mBitrateStdDev);
@@ -297,9 +297,9 @@ static void WriteRTCRTPStreamStats(
WriteParam(aMsg, aParam.mTransportId);
}
-static bool ReadRTCRTPStreamStats(
+static bool ReadRTCRtpStreamStats(
const Message* aMsg, PickleIterator* aIter,
- mozilla::dom::RTCRTPStreamStats* aResult)
+ mozilla::dom::RTCRtpStreamStats* aResult)
{
if (!ReadParam(aMsg, aIter, &(aResult->mBitrateMean)) ||
!ReadParam(aMsg, aIter, &(aResult->mBitrateStdDev)) ||
@@ -334,7 +334,7 @@ struct ParamTraits
WriteParam(aMsg, aParam.mRoundTripTime);
WriteParam(aMsg, aParam.mPacketsLost);
WriteParam(aMsg, aParam.mPacketsReceived);
- WriteRTCRTPStreamStats(aMsg, aParam);
+ WriteRTCRtpStreamStats(aMsg, aParam);
WriteRTCStats(aMsg, aParam);
}
@@ -349,7 +349,7 @@ struct ParamTraits
!ReadParam(aMsg, aIter, &(aResult->mRoundTripTime)) ||
!ReadParam(aMsg, aIter, &(aResult->mPacketsLost)) ||
!ReadParam(aMsg, aIter, &(aResult->mPacketsReceived)) ||
- !ReadRTCRTPStreamStats(aMsg, aIter, aResult) ||
+ !ReadRTCRtpStreamStats(aMsg, aIter, aResult) ||
!ReadRTCStats(aMsg, aIter, aResult)) {
return false;
}
@@ -373,7 +373,7 @@ struct ParamTraits
WriteParam(aMsg, aParam.mFirCount);
WriteParam(aMsg, aParam.mNackCount);
WriteParam(aMsg, aParam.mPliCount);
- WriteRTCRTPStreamStats(aMsg, aParam);
+ WriteRTCRtpStreamStats(aMsg, aParam);
WriteRTCStats(aMsg, aParam);
}
@@ -387,7 +387,7 @@ struct ParamTraits
!ReadParam(aMsg, aIter, &(aResult->mFirCount)) ||
!ReadParam(aMsg, aIter, &(aResult->mNackCount)) ||
!ReadParam(aMsg, aIter, &(aResult->mPliCount)) ||
- !ReadRTCRTPStreamStats(aMsg, aIter, aResult) ||
+ !ReadRTCRtpStreamStats(aMsg, aIter, aResult) ||
!ReadRTCStats(aMsg, aIter, aResult)) {
return false;
}
From 033b8142cfe230938e7ea63888a3bdfb749e74b3 Mon Sep 17 00:00:00 2001
From: Michael Kaply
Date: Mon, 6 Aug 2018 21:40:03 +0000
Subject: [PATCH 06/28] Bug 1476088 - Additional search submission telemetry.
r=florian
Differential Revision: https://phabricator.services.mozilla.com/D2165
--HG--
extra : moz-landing-system : lando
---
toolkit/components/search/nsSearchService.js | 30 +++++++++-
.../tests/xpcshell/test_sendSubmissionURL.js | 58 +++++++++++++++++++
.../search/tests/xpcshell/xpcshell.ini | 1 +
.../telemetry/docs/data/environment.rst | 2 +-
4 files changed, 89 insertions(+), 2 deletions(-)
create mode 100644 toolkit/components/search/tests/xpcshell/test_sendSubmissionURL.js
diff --git a/toolkit/components/search/nsSearchService.js b/toolkit/components/search/nsSearchService.js
index 29c891965845..91879751bcd0 100644
--- a/toolkit/components/search/nsSearchService.js
+++ b/toolkit/components/search/nsSearchService.js
@@ -989,9 +989,10 @@ function EngineURL(aType, aMethod, aTemplate, aResultDomain) {
FAIL("new EngineURL: template uses invalid scheme!", Cr.NS_ERROR_FAILURE);
}
+ this.templateHost = templateURI.host;
// If no resultDomain was specified in the engine definition file, use the
// host from the template.
- this.resultDomain = aResultDomain || templateURI.host;
+ this.resultDomain = aResultDomain || this.templateHost;
}
EngineURL.prototype = {
@@ -4154,6 +4155,33 @@ SearchService.prototype = {
}
}
+ if (!sendSubmissionURL) {
+ // ... or engines that are the same domain as a default engine.
+ let engineHost = engine._getURLOfType(URLTYPE_SEARCH_HTML).templateHost;
+ for (let name in this._engines) {
+ let innerEngine = this._engines[name];
+ if (!innerEngine._isDefault) {
+ continue;
+ }
+
+ let innerEngineURL = innerEngine._getURLOfType(URLTYPE_SEARCH_HTML);
+ if (innerEngineURL.templateHost == engineHost) {
+ sendSubmissionURL = true;
+ break;
+ }
+ }
+
+ if (!sendSubmissionURL) {
+ // ... or well known search domains.
+ //
+ // Starts with: www.google., search.aol., yandex.
+ // or
+ // Ends with: search.yahoo.com, .ask.com, .bing.com, .startpage.com, baidu.com, duckduckgo.com
+ const urlTest = /^(?:www\.google\.|search\.aol\.|yandex\.)|(?:search\.yahoo|\.ask|\.bing|\.startpage|\.baidu|\.duckduckgo)\.com$/;
+ sendSubmissionURL = urlTest.test(engineHost);
+ }
+ }
+
if (sendSubmissionURL) {
let uri = engine._getURLOfType("text/html")
.getSubmission("", engine, "searchbar").uri;
diff --git a/toolkit/components/search/tests/xpcshell/test_sendSubmissionURL.js b/toolkit/components/search/tests/xpcshell/test_sendSubmissionURL.js
new file mode 100644
index 000000000000..8b2418555083
--- /dev/null
+++ b/toolkit/components/search/tests/xpcshell/test_sendSubmissionURL.js
@@ -0,0 +1,58 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * Tests covering sending submission URLs for major engines
+ */
+
+const SUBMISSION_YES = new Map([
+ ["Google1 Test", "https://www.google.com/search?q={searchTerms}"],
+ ["Google2 Test", "https://www.google.co.uk/search?q={searchTerms}"],
+ ["Yahoo1 Test", "https://search.yahoo.com/search?p={searchTerms}"],
+ ["Yahoo2 Test", "https://uk.search.yahoo.com/search?p={searchTerms}"],
+ ["AOL1 Test", "https://search.aol.com/aol/search?q={searchTerms}"],
+ ["AOL2 Test", "https://search.aol.co.uk/aol/search?q={searchTerms}"],
+ ["Yandex1 Test", "https://yandex.ru/search/?text={searchTerms}"],
+ ["Yandex2 Test", "https://yandex.com/search/?text{searchTerms}"],
+ ["Ask1 Test", "https://www.ask.com/web?q={searchTerms}"],
+ ["Ask2 Test", "https://fr.ask.com/web?q={searchTerms}"],
+ ["Bing Test", "https://www.bing.com/search?q={searchTerms}"],
+ ["Startpage Test", "https://www.startpage.com/do/search?query={searchTerms}"],
+ ["DuckDuckGo Test", "https://duckduckgo.com/?q={searchTerms}"],
+ ["Baidu Test", "https://www.baidu.com/s?wd={searchTerms}"],
+]);
+
+const SUBMISSION_NO = new Map([
+ ["Other1 Test", "https://example.com?q={searchTerms}"],
+ ["Other2 Test", "https://googlebutnotgoogle.com?q={searchTerms}"],
+]);
+
+function addAndMakeDefault(name, searchURL) {
+ Services.search.addEngineWithDetails(name, null, null, null, "GET", searchURL);
+ let engine = Services.search.getEngineByName(name);
+ Services.search.currentEngine = engine;
+ return engine;
+}
+
+add_task(async function test() {
+ Assert.ok(!Services.search.isInitialized);
+
+ await asyncInit();
+
+ let engineInfo;
+ let engine;
+
+ for (let [name, searchURL] of SUBMISSION_YES) {
+ engine = addAndMakeDefault(name, searchURL);
+ engineInfo = Services.search.getDefaultEngineInfo();
+ Assert.equal(engineInfo.submissionURL, searchURL.replace("{searchTerms}", ""));
+ Services.search.removeEngine(engine);
+ }
+
+ for (let [name, searchURL] of SUBMISSION_NO) {
+ engine = addAndMakeDefault(name, searchURL);
+ engineInfo = Services.search.getDefaultEngineInfo();
+ Assert.equal(engineInfo.submissionURL, null);
+ Services.search.removeEngine(engine);
+ }
+});
diff --git a/toolkit/components/search/tests/xpcshell/xpcshell.ini b/toolkit/components/search/tests/xpcshell/xpcshell.ini
index 667c76322877..d921936bacbe 100644
--- a/toolkit/components/search/tests/xpcshell/xpcshell.ini
+++ b/toolkit/components/search/tests/xpcshell/xpcshell.ini
@@ -101,3 +101,4 @@ skip-if = (verify && !debug && (os == 'linux'))
[test_engineUpdate.js]
[test_paramSubstitution.js]
[test_migrateWebExtensionEngine.js]
+[test_sendSubmissionURL.js]
diff --git a/toolkit/components/telemetry/docs/data/environment.rst b/toolkit/components/telemetry/docs/data/environment.rst
index a8b88c0bbe80..89b52468209f 100644
--- a/toolkit/components/telemetry/docs/data/environment.rst
+++ b/toolkit/components/telemetry/docs/data/environment.rst
@@ -42,7 +42,7 @@ Structure:
name: , // engine name, e.g. "Yahoo"; or "NONE" if no default
loadPath: , // where the engine line is located; missing if no default
origin: , // 'default', 'verified', 'unverified', or 'invalid'; based on the presence and validity of the engine's loadPath verification hash.
- submissionURL: // missing if no default or for user-installed engines
+ submissionURL: // set for default engines or well known search domains
},
searchCohort: , // optional, contains an identifier for any active search A/B experiments
e10sEnabled: , // whether e10s is on, i.e. browser tabs open by default in a different process
From 913ae8e3d3710578b3d33ec1800537e805a5b23b Mon Sep 17 00:00:00 2001
From: Nico Grunbaum
Date: Mon, 6 Aug 2018 21:44:32 +0000
Subject: [PATCH 07/28] Bug 1480525 - ensure localIdp, remoteIdp exist before
closing them r=mjf
If PeerConnection initialization terminates early due to an excpetion localIdp, and remoteIdp aren't created.
This causes another exception in close(). The patch checks that they each exist in close before attempting to
access them.
Differential Revision: https://phabricator.services.mozilla.com/D2686
--HG--
extra : moz-landing-system : lando
---
dom/media/PeerConnection.js | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/dom/media/PeerConnection.js b/dom/media/PeerConnection.js
index da0302db64d9..148b7f6797d8 100644
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -1419,8 +1419,12 @@ class RTCPeerConnection {
}
this._closed = true;
this.changeIceConnectionState("closed");
- this._localIdp.close();
- this._remoteIdp.close();
+ if (this._localIdp) {
+ this._localIdp.close();
+ }
+ if (this._remoteIdp) {
+ this._remoteIdp.close();
+ }
this._impl.close();
this._suppressEvents = true;
delete this._pc;
From 5ae0e08589b6db914d98ff4eb6f1b406020c35ec Mon Sep 17 00:00:00 2001
From: Chris Manchester
Date: Mon, 6 Aug 2018 21:38:43 +0000
Subject: [PATCH 08/28] Bug 1480771 - Take CLOBBER into account when deciding
whether to re-run configure. r=gps,firefox-build-system-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D2802
--HG--
extra : moz-landing-system : lando
---
moz.configure | 1 +
1 file changed, 1 insertion(+)
diff --git a/moz.configure b/moz.configure
index 3b9269a3ff39..225459044826 100755
--- a/moz.configure
+++ b/moz.configure
@@ -581,6 +581,7 @@ def config_status_deps(build_env, build_project):
extra_deps = [os.path.join(topobjdir[:-7], '.mozconfig.json')]
return list(__sandbox__._all_paths) + extra_deps + [
+ os.path.join(topsrcdir, 'CLOBBER'),
os.path.join(topsrcdir, 'configure'),
os.path.join(topsrcdir, 'js', 'src', 'configure'),
os.path.join(topsrcdir, 'configure.in'),
From 5eb09563bc9882bda5dc1b52543102385e552736 Mon Sep 17 00:00:00 2001
From: Michael Kaply
Date: Mon, 6 Aug 2018 22:02:02 +0000
Subject: [PATCH 09/28] Bug 1475571 - Replace follow-on addon with in tree
telemetry. r=mikedeboer,florian
Differential Revision: https://phabricator.services.mozilla.com/D2125
--HG--
extra : moz-landing-system : lando
---
browser/extensions/moz.build | 1 -
browser/modules/BrowserUsageTelemetry.jsm | 79 ++++++++++++++++----
toolkit/components/search/nsSearchService.js | 7 +-
toolkit/components/telemetry/Histograms.json | 2 +-
4 files changed, 73 insertions(+), 16 deletions(-)
diff --git a/browser/extensions/moz.build b/browser/extensions/moz.build
index c2b67265febe..66ac545f478c 100644
--- a/browser/extensions/moz.build
+++ b/browser/extensions/moz.build
@@ -6,7 +6,6 @@
DIRS += [
'aushelper',
- 'followonsearch',
'formautofill',
'onboarding',
'pdfjs',
diff --git a/browser/modules/BrowserUsageTelemetry.jsm b/browser/modules/BrowserUsageTelemetry.jsm
index a60692631aec..3211c23c9999 100644
--- a/browser/modules/BrowserUsageTelemetry.jsm
+++ b/browser/modules/BrowserUsageTelemetry.jsm
@@ -13,10 +13,13 @@ var EXPORTED_SYMBOLS = [
];
ChromeUtils.import("resource://gre/modules/Services.jsm");
+ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
+XPCOMUtils.defineLazyGlobalGetters(this, ["URLSearchParams"]);
+
// The upper bound for the count of the visited unique domain names.
const MAX_UNIQUE_VISITED_DOMAINS = 100;
@@ -88,7 +91,6 @@ const URLBAR_SELECTED_RESULT_METHODS = {
const MINIMUM_TAB_COUNT_INTERVAL_MS = 5 * 60 * 1000; // 5 minutes, in ms
-
function getOpenTabsAndWinsCounts() {
let tabCount = 0;
let winCount = 0;
@@ -159,6 +161,10 @@ let URICountListener = {
return;
}
+ // Don't include URI and domain counts when in private mode.
+ let shouldCountURI = !PrivateBrowsingUtils.isWindowPrivate(browser.ownerGlobal) ||
+ Services.prefs.getBoolPref("browser.engagement.total_uri_count.pbm", false);
+
// Track URI loads, even if they're not http(s).
let uriSpec = null;
try {
@@ -166,7 +172,9 @@ let URICountListener = {
} catch (e) {
// If we have troubles parsing the spec, still count this as
// an unfiltered URI.
- Services.telemetry.scalarAdd(UNFILTERED_URI_COUNT_SCALAR_NAME, 1);
+ if (shouldCountURI) {
+ Services.telemetry.scalarAdd(UNFILTERED_URI_COUNT_SCALAR_NAME, 1);
+ }
return;
}
@@ -188,12 +196,42 @@ let URICountListener = {
// The URI wasn't from a restored tab. Count it among the unfiltered URIs.
// If this is an http(s) URI, this also gets counted by the "total_uri_count"
// probe.
- Services.telemetry.scalarAdd(UNFILTERED_URI_COUNT_SCALAR_NAME, 1);
+ if (shouldCountURI) {
+ Services.telemetry.scalarAdd(UNFILTERED_URI_COUNT_SCALAR_NAME, 1);
+ }
if (!this.isHttpURI(uri)) {
return;
}
+ let parseURLResult = Services.search.parseSubmissionURL(uriSpec);
+ if (parseURLResult.engine) {
+ this._recordSearchTelemetry(uriSpec, parseURLResult);
+ } else if (this._urlsQueuedForParsing) {
+ if (Services.search.isInitialized) {
+ this._urlsQueuedForParsing = null;
+ } else {
+ this._urlsQueuedForParsing.push(uriSpec);
+ if (this._urlsQueuedForParsing.length == 1) {
+ Services.search.init(rv => {
+ if (Components.isSuccessCode(rv)) {
+ for (let url of this._urlsQueuedForParsing) {
+ let innerParseURLResult = Services.search.parseSubmissionURL(url);
+ if (innerParseURLResult.engine) {
+ this._recordSearchTelemetry(url, innerParseURLResult);
+ }
+ }
+ }
+ this._urlsQueuedForParsing = null;
+ });
+ }
+ }
+ }
+
+ if (!shouldCountURI) {
+ return;
+ }
+
// Update the URI counts.
Services.telemetry.scalarAdd(TOTAL_URI_COUNT_SCALAR_NAME, 1);
@@ -226,6 +264,31 @@ let URICountListener = {
this._domainSet.clear();
},
+ _urlsQueuedForParsing: [],
+
+ _recordSearchTelemetry(url, parseURLResult) {
+ switch (parseURLResult.engine.identifier) {
+ case "google":
+ case "google-2018":
+ let type;
+ let queries = new URLSearchParams(url.split("?")[1]);
+ let code = queries.get("client");
+ if (code) {
+ // Detecting follow-on searches for sap is a little tricky.
+ // There are a few parameters that only show up
+ // with follow-ons, so we look for those. (oq/ved/ei)
+ type = queries.has("oq") || queries.has("ved") || queries.has("ei") ? "sap-follow-on" : "sap";
+ } else {
+ type = "organic";
+ }
+ let payload = `google.in-content.${type}:${code || "none"}`;
+
+ let histogram = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS");
+ histogram.add(payload);
+ break;
+ }
+ },
+
QueryInterface: ChromeUtils.generateQI([Ci.nsIWebProgressListener,
Ci.nsISupportsWeakReference]),
};
@@ -614,11 +677,6 @@ let BrowserUsageTelemetry = {
win.addEventListener("unload", this);
win.addEventListener("TabOpen", this, true);
- // Don't include URI and domain counts when in private mode.
- if (PrivateBrowsingUtils.isWindowPrivate(win) &&
- !Services.prefs.getBoolPref("browser.engagement.total_uri_count.pbm", false)) {
- return;
- }
win.gBrowser.tabContainer.addEventListener(TAB_RESTORING_TOPIC, this);
win.gBrowser.addTabsProgressListener(URICountListener);
},
@@ -630,11 +688,6 @@ let BrowserUsageTelemetry = {
win.removeEventListener("unload", this);
win.removeEventListener("TabOpen", this, true);
- // Don't include URI and domain counts when in private mode.
- if (PrivateBrowsingUtils.isWindowPrivate(win.defaultView) &&
- !Services.prefs.getBoolPref("browser.engagement.total_uri_count.pbm", false)) {
- return;
- }
win.defaultView.gBrowser.tabContainer.removeEventListener(TAB_RESTORING_TOPIC, this);
win.defaultView.gBrowser.removeTabsProgressListener(URICountListener);
},
diff --git a/toolkit/components/search/nsSearchService.js b/toolkit/components/search/nsSearchService.js
index 91879751bcd0..bc101d213fa0 100644
--- a/toolkit/components/search/nsSearchService.js
+++ b/toolkit/components/search/nsSearchService.js
@@ -4331,7 +4331,12 @@ SearchService.prototype = {
},
parseSubmissionURL: function SRCH_SVC_parseSubmissionURL(aURL) {
- this._ensureInitialized();
+ if (!gInitialized) {
+ // If search is not initialized, do nothing.
+ // This allows us to use this function early in telemetry.
+ // The only other consumer of this (places) uses it much later.
+ return gEmptyParseSubmissionResult;
+ }
LOG("parseSubmissionURL: Parsing \"" + aURL + "\".");
if (!this._parseSubmissionMap) {
diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json
index ef0167ce46a6..c86cad1d92b4 100644
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -7827,7 +7827,7 @@
"kind": "count",
"keyed": true,
"releaseChannelCollection": "opt-out",
- "description": "Record the search counts for search engines"
+ "description": "Records search counts for search access points and in content searches. For search access points, the format is: . For in content searches, the format is .in-content:[sap|sap-follow-on|organic]:[code|none]"
},
"SEARCH_RESET_RESULT": {
"record_in_processes": ["main", "content"],
From 613a40ff153411c254d0dd9810842adf7ddb48eb Mon Sep 17 00:00:00 2001
From: Rob Wu
Date: Mon, 6 Aug 2018 11:24:20 +0200
Subject: [PATCH 10/28] Bug 1416103 - Re-enable browser_ext_omnibox.js
everywhere r=aswan
Likely fixed by the patch for bug 1417052
Ran the test with --repeat=50 on Linux and did not observe any failures.
MozReview-Commit-ID: FuMo8jdgJCn
--HG--
extra : rebase_source : 2a296cc7817607d352bc56b5b200da81d3e26bf0
---
browser/components/extensions/test/browser/browser-common.ini | 1 -
1 file changed, 1 deletion(-)
diff --git a/browser/components/extensions/test/browser/browser-common.ini b/browser/components/extensions/test/browser/browser-common.ini
index ccf43aa4ead2..70f52baace6b 100644
--- a/browser/components/extensions/test/browser/browser-common.ini
+++ b/browser/components/extensions/test/browser/browser-common.ini
@@ -111,7 +111,6 @@ skip-if = (verify && (os == 'linux' || os == 'mac'))
[browser_ext_menus_events.js]
[browser_ext_menus_refresh.js]
[browser_ext_omnibox.js]
-skip-if = (debug && (os == 'linux' || os == 'mac')) || (verify && (os == 'linux' || os == 'mac')) # Bug 1416103 (was bug 1417052)
[browser_ext_openPanel.js]
skip-if = (verify && !debug && (os == 'linux' || os == 'mac'))
[browser_ext_optionsPage_browser_style.js]
From f22cd9a62c7f036d8c7241d9cc0bc32e25b1d901 Mon Sep 17 00:00:00 2001
From: Kyle Machulis
Date: Fri, 3 Aug 2018 19:16:26 +0000
Subject: [PATCH 11/28] Bug 1480641 - Remove nsITextScroll; r=nika
Implemented by nsDocShell and nsWebBrowser (which just wraps the
docshell functions), but not actually used anywhere.
MozReview-Commit-ID: 2YzfsrvOolX
Differential Revision: https://phabricator.services.mozilla.com/D2695
--HG--
extra : moz-landing-system : lando
---
docshell/base/moz.build | 1 -
docshell/base/nsDocShell.cpp | 27 -----------------
docshell/base/nsDocShell.h | 3 --
docshell/base/nsITextScroll.idl | 33 ---------------------
toolkit/components/browser/nsWebBrowser.cpp | 27 +----------------
toolkit/components/browser/nsWebBrowser.h | 4 ---
6 files changed, 1 insertion(+), 94 deletions(-)
delete mode 100644 docshell/base/nsITextScroll.idl
diff --git a/docshell/base/moz.build b/docshell/base/moz.build
index ec9baa446ad8..b69ced726ca5 100644
--- a/docshell/base/moz.build
+++ b/docshell/base/moz.build
@@ -49,7 +49,6 @@ XPIDL_SOURCES += [
'nsIReflowObserver.idl',
'nsIRefreshURI.idl',
'nsIScrollable.idl',
- 'nsITextScroll.idl',
'nsITooltipListener.idl',
'nsITooltipTextProvider.idl',
'nsIURIFixup.idl',
diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp
index ea0c2d3e40d4..095a31af4bfc 100644
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -520,7 +520,6 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDocShell)
NS_INTERFACE_MAP_ENTRY(nsIWebNavigation)
NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
NS_INTERFACE_MAP_ENTRY(nsIScrollable)
- NS_INTERFACE_MAP_ENTRY(nsITextScroll)
NS_INTERFACE_MAP_ENTRY(nsIRefreshURI)
NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
@@ -6089,32 +6088,6 @@ nsDocShell::GetScrollbarVisibility(bool* aVerticalVisible,
return NS_OK;
}
-//*****************************************************************************
-// nsDocShell::nsITextScroll
-//*****************************************************************************
-
-NS_IMETHODIMP
-nsDocShell::ScrollByLines(int32_t aNumLines)
-{
- nsIScrollableFrame* sf = GetRootScrollFrame();
- NS_ENSURE_TRUE(sf, NS_ERROR_FAILURE);
-
- sf->ScrollBy(nsIntPoint(0, aNumLines), nsIScrollableFrame::LINES,
- nsIScrollableFrame::SMOOTH);
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocShell::ScrollByPages(int32_t aNumPages)
-{
- nsIScrollableFrame* sf = GetRootScrollFrame();
- NS_ENSURE_TRUE(sf, NS_ERROR_FAILURE);
-
- sf->ScrollBy(nsIntPoint(0, aNumPages), nsIScrollableFrame::PAGES,
- nsIScrollableFrame::SMOOTH);
- return NS_OK;
-}
-
//*****************************************************************************
// nsDocShell::nsIRefreshURI
//*****************************************************************************
diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h
index f50d464ba1a6..ff138adf8a78 100644
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -35,7 +35,6 @@
#include "nsIRefreshURI.h"
#include "nsIScrollable.h"
#include "nsITabParent.h"
-#include "nsITextScroll.h"
#include "nsIWebNavigation.h"
#include "nsIWebPageDescriptor.h"
#include "nsIWebProgressListener.h"
@@ -122,7 +121,6 @@ class nsDocShell final
, public nsIWebNavigation
, public nsIBaseWindow
, public nsIScrollable
- , public nsITextScroll
, public nsIRefreshURI
, public nsIWebProgressListener
, public nsIWebPageDescriptor
@@ -173,7 +171,6 @@ public:
NS_DECL_NSIWEBNAVIGATION
NS_DECL_NSIBASEWINDOW
NS_DECL_NSISCROLLABLE
- NS_DECL_NSITEXTSCROLL
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSIWEBPROGRESSLISTENER
NS_DECL_NSIREFRESHURI
diff --git a/docshell/base/nsITextScroll.idl b/docshell/base/nsITextScroll.idl
deleted file mode 100644
index 87338c491e2e..000000000000
--- a/docshell/base/nsITextScroll.idl
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-
-/**
- * The nsITextScroll is an interface that can be implemented by a control that
- * supports text scrolling.
- */
-
-[scriptable, uuid(067B28A0-877F-11d3-AF7E-00A024FFC08C)]
-interface nsITextScroll : nsISupports
-{
- /**
- * Scroll the view up or down by aNumLines lines. positive
- * values move down in the view. Prevents scrolling off the
- * end of the view.
- * @param numLines number of lines to scroll the view by
- */
- void scrollByLines(in long numLines);
-
- /**
- * Scroll the view up or down by numPages pages. a page
- * is considered to be the amount displayed by the clip view.
- * positive values move down in the view. Prevents scrolling
- * off the end of the view.
- * @param numPages number of pages to scroll the view by
- */
- void scrollByPages(in long numPages);
-};
\ No newline at end of file
diff --git a/toolkit/components/browser/nsWebBrowser.cpp b/toolkit/components/browser/nsWebBrowser.cpp
index 0f23e2b726c9..3881db40d162 100644
--- a/toolkit/components/browser/nsWebBrowser.cpp
+++ b/toolkit/components/browser/nsWebBrowser.cpp
@@ -115,7 +115,6 @@ NS_IMPL_CYCLE_COLLECTION(nsWebBrowser,
mDocShellAsWin,
mDocShellAsNav,
mDocShellAsScrollable,
- mDocShellAsTextScroll,
mWebProgress)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsWebBrowser)
@@ -124,7 +123,6 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsWebBrowser)
NS_INTERFACE_MAP_ENTRY(nsIWebNavigation)
NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
NS_INTERFACE_MAP_ENTRY(nsIScrollable)
- NS_INTERFACE_MAP_ENTRY(nsITextScroll)
NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeItem)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_INTERFACE_MAP_ENTRY(nsIWebBrowserSetup)
@@ -1641,26 +1639,6 @@ nsWebBrowser::GetScrollbarVisibility(bool* aVerticalVisible,
aHorizontalVisible);
}
-//*****************************************************************************
-// nsWebBrowser::nsITextScroll
-//*****************************************************************************
-
-NS_IMETHODIMP
-nsWebBrowser::ScrollByLines(int32_t aNumLines)
-{
- NS_ENSURE_STATE(mDocShell);
-
- return mDocShellAsTextScroll->ScrollByLines(aNumLines);
-}
-
-NS_IMETHODIMP
-nsWebBrowser::ScrollByPages(int32_t aNumPages)
-{
- NS_ENSURE_STATE(mDocShell);
-
- return mDocShellAsTextScroll->ScrollByPages(aNumPages);
-}
-
//*****************************************************************************
// nsWebBrowser: Listener Helpers
//*****************************************************************************
@@ -1680,9 +1658,8 @@ nsWebBrowser::SetDocShell(nsIDocShell* aDocShell)
nsCOMPtr baseWin(do_QueryInterface(aDocShell));
nsCOMPtr nav(do_QueryInterface(aDocShell));
nsCOMPtr scrollable(do_QueryInterface(aDocShell));
- nsCOMPtr textScroll(do_QueryInterface(aDocShell));
nsCOMPtr progress(do_GetInterface(aDocShell));
- NS_ENSURE_TRUE(req && baseWin && nav && scrollable && textScroll && progress,
+ NS_ENSURE_TRUE(req && baseWin && nav && scrollable && progress,
NS_ERROR_FAILURE);
mDocShell = aDocShell;
@@ -1690,7 +1667,6 @@ nsWebBrowser::SetDocShell(nsIDocShell* aDocShell)
mDocShellAsWin = baseWin;
mDocShellAsNav = nav;
mDocShellAsScrollable = scrollable;
- mDocShellAsTextScroll = textScroll;
mWebProgress = progress;
// By default, do not allow DNS prefetch, so we don't break our frozen
@@ -1715,7 +1691,6 @@ nsWebBrowser::SetDocShell(nsIDocShell* aDocShell)
mDocShellAsWin = nullptr;
mDocShellAsNav = nullptr;
mDocShellAsScrollable = nullptr;
- mDocShellAsTextScroll = nullptr;
mWebProgress = nullptr;
}
diff --git a/toolkit/components/browser/nsWebBrowser.h b/toolkit/components/browser/nsWebBrowser.h
index a378612d679e..e7593a6c1d66 100644
--- a/toolkit/components/browser/nsWebBrowser.h
+++ b/toolkit/components/browser/nsWebBrowser.h
@@ -24,7 +24,6 @@
#include "nsIInterfaceRequestorUtils.h"
#include "nsIScrollable.h"
#include "nsISHistory.h"
-#include "nsITextScroll.h"
#include "nsIWidget.h"
#include "nsIWebProgress.h"
#include "nsISecureBrowserUI.h"
@@ -76,7 +75,6 @@ class nsWebBrowser final : public nsIWebBrowser,
public nsIDocShellTreeItem,
public nsIBaseWindow,
public nsIScrollable,
- public nsITextScroll,
public nsIInterfaceRequestor,
public nsIWebBrowserPersist,
public nsIWebBrowserFocus,
@@ -115,7 +113,6 @@ public:
NS_DECL_NSIDOCSHELLTREEITEM
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSISCROLLABLE
- NS_DECL_NSITEXTSCROLL
NS_DECL_NSIWEBBROWSER
NS_DECL_NSIWEBNAVIGATION
NS_DECL_NSIWEBBROWSERSETUP
@@ -148,7 +145,6 @@ protected:
nsCOMPtr mDocShellAsWin;
nsCOMPtr mDocShellAsNav;
nsCOMPtr mDocShellAsScrollable;
- nsCOMPtr mDocShellAsTextScroll;
mozilla::OriginAttributes mOriginAttributes;
nsCOMPtr mInternalWidget;
From bb22e8a0feca95dcbce8dbd4417ade86a4b23154 Mon Sep 17 00:00:00 2001
From: Tiberius Oros
Date: Tue, 7 Aug 2018 02:45:36 +0300
Subject: [PATCH 12/28] Backed out changeset 8228e57646bf (bug 1480641) for
build bustages on a CLOSED TREE
---
docshell/base/moz.build | 1 +
docshell/base/nsDocShell.cpp | 27 +++++++++++++++++
docshell/base/nsDocShell.h | 3 ++
docshell/base/nsITextScroll.idl | 33 +++++++++++++++++++++
toolkit/components/browser/nsWebBrowser.cpp | 27 ++++++++++++++++-
toolkit/components/browser/nsWebBrowser.h | 4 +++
6 files changed, 94 insertions(+), 1 deletion(-)
create mode 100644 docshell/base/nsITextScroll.idl
diff --git a/docshell/base/moz.build b/docshell/base/moz.build
index b69ced726ca5..ec9baa446ad8 100644
--- a/docshell/base/moz.build
+++ b/docshell/base/moz.build
@@ -49,6 +49,7 @@ XPIDL_SOURCES += [
'nsIReflowObserver.idl',
'nsIRefreshURI.idl',
'nsIScrollable.idl',
+ 'nsITextScroll.idl',
'nsITooltipListener.idl',
'nsITooltipTextProvider.idl',
'nsIURIFixup.idl',
diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp
index 095a31af4bfc..ea0c2d3e40d4 100644
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -520,6 +520,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDocShell)
NS_INTERFACE_MAP_ENTRY(nsIWebNavigation)
NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
NS_INTERFACE_MAP_ENTRY(nsIScrollable)
+ NS_INTERFACE_MAP_ENTRY(nsITextScroll)
NS_INTERFACE_MAP_ENTRY(nsIRefreshURI)
NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
@@ -6088,6 +6089,32 @@ nsDocShell::GetScrollbarVisibility(bool* aVerticalVisible,
return NS_OK;
}
+//*****************************************************************************
+// nsDocShell::nsITextScroll
+//*****************************************************************************
+
+NS_IMETHODIMP
+nsDocShell::ScrollByLines(int32_t aNumLines)
+{
+ nsIScrollableFrame* sf = GetRootScrollFrame();
+ NS_ENSURE_TRUE(sf, NS_ERROR_FAILURE);
+
+ sf->ScrollBy(nsIntPoint(0, aNumLines), nsIScrollableFrame::LINES,
+ nsIScrollableFrame::SMOOTH);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShell::ScrollByPages(int32_t aNumPages)
+{
+ nsIScrollableFrame* sf = GetRootScrollFrame();
+ NS_ENSURE_TRUE(sf, NS_ERROR_FAILURE);
+
+ sf->ScrollBy(nsIntPoint(0, aNumPages), nsIScrollableFrame::PAGES,
+ nsIScrollableFrame::SMOOTH);
+ return NS_OK;
+}
+
//*****************************************************************************
// nsDocShell::nsIRefreshURI
//*****************************************************************************
diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h
index ff138adf8a78..f50d464ba1a6 100644
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -35,6 +35,7 @@
#include "nsIRefreshURI.h"
#include "nsIScrollable.h"
#include "nsITabParent.h"
+#include "nsITextScroll.h"
#include "nsIWebNavigation.h"
#include "nsIWebPageDescriptor.h"
#include "nsIWebProgressListener.h"
@@ -121,6 +122,7 @@ class nsDocShell final
, public nsIWebNavigation
, public nsIBaseWindow
, public nsIScrollable
+ , public nsITextScroll
, public nsIRefreshURI
, public nsIWebProgressListener
, public nsIWebPageDescriptor
@@ -171,6 +173,7 @@ public:
NS_DECL_NSIWEBNAVIGATION
NS_DECL_NSIBASEWINDOW
NS_DECL_NSISCROLLABLE
+ NS_DECL_NSITEXTSCROLL
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSIWEBPROGRESSLISTENER
NS_DECL_NSIREFRESHURI
diff --git a/docshell/base/nsITextScroll.idl b/docshell/base/nsITextScroll.idl
new file mode 100644
index 000000000000..87338c491e2e
--- /dev/null
+++ b/docshell/base/nsITextScroll.idl
@@ -0,0 +1,33 @@
+/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+/**
+ * The nsITextScroll is an interface that can be implemented by a control that
+ * supports text scrolling.
+ */
+
+[scriptable, uuid(067B28A0-877F-11d3-AF7E-00A024FFC08C)]
+interface nsITextScroll : nsISupports
+{
+ /**
+ * Scroll the view up or down by aNumLines lines. positive
+ * values move down in the view. Prevents scrolling off the
+ * end of the view.
+ * @param numLines number of lines to scroll the view by
+ */
+ void scrollByLines(in long numLines);
+
+ /**
+ * Scroll the view up or down by numPages pages. a page
+ * is considered to be the amount displayed by the clip view.
+ * positive values move down in the view. Prevents scrolling
+ * off the end of the view.
+ * @param numPages number of pages to scroll the view by
+ */
+ void scrollByPages(in long numPages);
+};
\ No newline at end of file
diff --git a/toolkit/components/browser/nsWebBrowser.cpp b/toolkit/components/browser/nsWebBrowser.cpp
index 3881db40d162..0f23e2b726c9 100644
--- a/toolkit/components/browser/nsWebBrowser.cpp
+++ b/toolkit/components/browser/nsWebBrowser.cpp
@@ -115,6 +115,7 @@ NS_IMPL_CYCLE_COLLECTION(nsWebBrowser,
mDocShellAsWin,
mDocShellAsNav,
mDocShellAsScrollable,
+ mDocShellAsTextScroll,
mWebProgress)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsWebBrowser)
@@ -123,6 +124,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsWebBrowser)
NS_INTERFACE_MAP_ENTRY(nsIWebNavigation)
NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
NS_INTERFACE_MAP_ENTRY(nsIScrollable)
+ NS_INTERFACE_MAP_ENTRY(nsITextScroll)
NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeItem)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_INTERFACE_MAP_ENTRY(nsIWebBrowserSetup)
@@ -1639,6 +1641,26 @@ nsWebBrowser::GetScrollbarVisibility(bool* aVerticalVisible,
aHorizontalVisible);
}
+//*****************************************************************************
+// nsWebBrowser::nsITextScroll
+//*****************************************************************************
+
+NS_IMETHODIMP
+nsWebBrowser::ScrollByLines(int32_t aNumLines)
+{
+ NS_ENSURE_STATE(mDocShell);
+
+ return mDocShellAsTextScroll->ScrollByLines(aNumLines);
+}
+
+NS_IMETHODIMP
+nsWebBrowser::ScrollByPages(int32_t aNumPages)
+{
+ NS_ENSURE_STATE(mDocShell);
+
+ return mDocShellAsTextScroll->ScrollByPages(aNumPages);
+}
+
//*****************************************************************************
// nsWebBrowser: Listener Helpers
//*****************************************************************************
@@ -1658,8 +1680,9 @@ nsWebBrowser::SetDocShell(nsIDocShell* aDocShell)
nsCOMPtr baseWin(do_QueryInterface(aDocShell));
nsCOMPtr nav(do_QueryInterface(aDocShell));
nsCOMPtr scrollable(do_QueryInterface(aDocShell));
+ nsCOMPtr textScroll(do_QueryInterface(aDocShell));
nsCOMPtr progress(do_GetInterface(aDocShell));
- NS_ENSURE_TRUE(req && baseWin && nav && scrollable && progress,
+ NS_ENSURE_TRUE(req && baseWin && nav && scrollable && textScroll && progress,
NS_ERROR_FAILURE);
mDocShell = aDocShell;
@@ -1667,6 +1690,7 @@ nsWebBrowser::SetDocShell(nsIDocShell* aDocShell)
mDocShellAsWin = baseWin;
mDocShellAsNav = nav;
mDocShellAsScrollable = scrollable;
+ mDocShellAsTextScroll = textScroll;
mWebProgress = progress;
// By default, do not allow DNS prefetch, so we don't break our frozen
@@ -1691,6 +1715,7 @@ nsWebBrowser::SetDocShell(nsIDocShell* aDocShell)
mDocShellAsWin = nullptr;
mDocShellAsNav = nullptr;
mDocShellAsScrollable = nullptr;
+ mDocShellAsTextScroll = nullptr;
mWebProgress = nullptr;
}
diff --git a/toolkit/components/browser/nsWebBrowser.h b/toolkit/components/browser/nsWebBrowser.h
index e7593a6c1d66..a378612d679e 100644
--- a/toolkit/components/browser/nsWebBrowser.h
+++ b/toolkit/components/browser/nsWebBrowser.h
@@ -24,6 +24,7 @@
#include "nsIInterfaceRequestorUtils.h"
#include "nsIScrollable.h"
#include "nsISHistory.h"
+#include "nsITextScroll.h"
#include "nsIWidget.h"
#include "nsIWebProgress.h"
#include "nsISecureBrowserUI.h"
@@ -75,6 +76,7 @@ class nsWebBrowser final : public nsIWebBrowser,
public nsIDocShellTreeItem,
public nsIBaseWindow,
public nsIScrollable,
+ public nsITextScroll,
public nsIInterfaceRequestor,
public nsIWebBrowserPersist,
public nsIWebBrowserFocus,
@@ -113,6 +115,7 @@ public:
NS_DECL_NSIDOCSHELLTREEITEM
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSISCROLLABLE
+ NS_DECL_NSITEXTSCROLL
NS_DECL_NSIWEBBROWSER
NS_DECL_NSIWEBNAVIGATION
NS_DECL_NSIWEBBROWSERSETUP
@@ -145,6 +148,7 @@ protected:
nsCOMPtr mDocShellAsWin;
nsCOMPtr mDocShellAsNav;
nsCOMPtr mDocShellAsScrollable;
+ nsCOMPtr mDocShellAsTextScroll;
mozilla::OriginAttributes mOriginAttributes;
nsCOMPtr mInternalWidget;
From 7b8f8f1076c7f1de67199b4f0a0abbfcf5261678 Mon Sep 17 00:00:00 2001
From: Matt Brubeck
Date: Mon, 6 Aug 2018 22:11:11 +0000
Subject: [PATCH 13/28] Bug 1458662 - Re-enable regex JIT on aarch64. r=jchen
MozReview-Commit-ID: 8d2pO69R2OD
Differential Revision: https://phabricator.services.mozilla.com/D2796
--HG--
extra : moz-landing-system : lando
---
mobile/android/app/mobile.js | 4 ----
1 file changed, 4 deletions(-)
diff --git a/mobile/android/app/mobile.js b/mobile/android/app/mobile.js
index c6fe4f180267..328fc752ca17 100644
--- a/mobile/android/app/mobile.js
+++ b/mobile/android/app/mobile.js
@@ -880,10 +880,6 @@ pref("media.openUnsupportedTypeWithExternalApp", true);
pref("dom.keyboardevent.dispatch_during_composition", true);
-#if CPU_ARCH == aarch64
-pref("javascript.options.native_regexp", false);
-#endif
-
// Ask for permission when enumerating WebRTC devices.
pref("media.navigator.permission.device", true);
From 6ddc6d1828a30d2c30edf617b5d32501a60379c9 Mon Sep 17 00:00:00 2001
From: Zibi Braniecki
Date: Tue, 7 Aug 2018 00:08:29 +0000
Subject: [PATCH 14/28] Bug 1480881 - Upgrade Gecko to Fluent 0.6. r=stas
Upgrade Gecko to Fluent 0.6.
Differential Revision: https://phabricator.services.mozilla.com/D2740
--HG--
extra : moz-landing-system : lando
---
intl/l10n/DOMLocalization.jsm | 6 +-
intl/l10n/Localization.jsm | 86 +-
intl/l10n/MessageContext.jsm | 207 ++--
intl/l10n/fluent.js.patch | 1013 ++++++++---------
intl/l10n/test/dom/test_domloc.xul | 4 +-
.../dom/test_domloc_translateElements.html | 2 +-
6 files changed, 683 insertions(+), 635 deletions(-)
diff --git a/intl/l10n/DOMLocalization.jsm b/intl/l10n/DOMLocalization.jsm
index 3f2b676fab76..d3fb9b803833 100644
--- a/intl/l10n/DOMLocalization.jsm
+++ b/intl/l10n/DOMLocalization.jsm
@@ -16,7 +16,7 @@
*/
-/* fluent-dom@aa95b1f (July 10, 2018) */
+/* fluent-dom@cab517f (July 31, 2018) */
const { Localization } =
ChromeUtils.import("resource://gre/modules/Localization.jsm", {});
@@ -60,10 +60,10 @@ const LOCALIZABLE_ATTRIBUTES = {
th: ["abbr"]
},
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul": {
- description: ["value"],
global: [
"accesskey", "aria-label", "aria-valuetext", "aria-moz-hint", "label"
],
+ description: ["value"],
key: ["key", "keycode"],
label: ["value"],
textbox: ["placeholder"],
@@ -523,7 +523,7 @@ class DOMLocalization extends Localization {
if (this.windowElement) {
if (this.windowElement !== newRoot.ownerGlobal) {
throw new Error(`Cannot connect a root:
- DOMLocalization already has a root from a different window`);
+ DOMLocalization already has a root from a different window.`);
}
} else {
this.windowElement = newRoot.ownerGlobal;
diff --git a/intl/l10n/Localization.jsm b/intl/l10n/Localization.jsm
index 2a0c0c4ae27e..8aa0722f20d8 100644
--- a/intl/l10n/Localization.jsm
+++ b/intl/l10n/Localization.jsm
@@ -16,7 +16,7 @@
*/
-/* fluent-dom@aa95b1f (July 10, 2018) */
+/* fluent-dom@cab517f (July 31, 2018) */
/* eslint no-console: ["error", { allow: ["warn", "error"] }] */
/* global console */
@@ -25,13 +25,25 @@ const { L10nRegistry } = ChromeUtils.import("resource://gre/modules/L10nRegistry
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm", {});
const { AppConstants } = ChromeUtils.import("resource://gre/modules/AppConstants.jsm", {});
-/*
- * CachedAsyncIterable caches the elements yielded by an iterable.
- *
- * It can be used to iterate over an iterable many times without depleting the
- * iterable.
- */
-class CachedAsyncIterable {
+class CachedIterable extends Array {
+ /**
+ * Create a `CachedIterable` instance from an iterable or, if another
+ * instance of `CachedIterable` is passed, return it without any
+ * modifications.
+ *
+ * @param {Iterable} iterable
+ * @returns {CachedIterable}
+ */
+ static from(iterable) {
+ if (iterable instanceof this) {
+ return iterable;
+ }
+
+ return new this(iterable);
+ }
+}
+
+class CachedAsyncIterable extends CachedIterable {
/**
* Create an `CachedAsyncIterable` instance.
*
@@ -39,6 +51,8 @@ class CachedAsyncIterable {
* @returns {CachedAsyncIterable}
*/
constructor(iterable) {
+ super();
+
if (Symbol.asyncIterator in Object(iterable)) {
this.iterator = iterable[Symbol.asyncIterator]();
} else if (Symbol.iterator in Object(iterable)) {
@@ -46,20 +60,46 @@ class CachedAsyncIterable {
} else {
throw new TypeError("Argument must implement the iteration protocol.");
}
-
- this.seen = [];
}
+ /**
+ * Synchronous iterator over the cached elements.
+ *
+ * Return a generator object implementing the iterator protocol over the
+ * cached elements of the original (async or sync) iterable.
+ */
+ [Symbol.iterator]() {
+ const cached = this;
+ let cur = 0;
+
+ return {
+ next() {
+ if (cached.length === cur) {
+ return {value: undefined, done: true};
+ }
+ return cached[cur++];
+ }
+ };
+ }
+
+ /**
+ * Asynchronous iterator caching the yielded elements.
+ *
+ * Elements yielded by the original iterable will be cached and available
+ * synchronously. Returns an async generator object implementing the
+ * iterator protocol over the elements of the original (async or sync)
+ * iterable.
+ */
[Symbol.asyncIterator]() {
- const { seen, iterator } = this;
+ const cached = this;
let cur = 0;
return {
async next() {
- if (seen.length <= cur) {
- seen.push(await iterator.next());
+ if (cached.length <= cur) {
+ cached.push(await cached.iterator.next());
}
- return seen[cur++];
+ return cached[cur++];
}
};
}
@@ -71,13 +111,17 @@ class CachedAsyncIterable {
* @param {number} count - number of elements to consume
*/
async touchNext(count = 1) {
- const { seen, iterator } = this;
let idx = 0;
while (idx++ < count) {
- if (seen.length === 0 || seen[seen.length - 1].done === false) {
- seen.push(await iterator.next());
+ const last = this[this.length - 1];
+ if (last && last.done) {
+ break;
}
+ this.push(await this.iterator.next());
}
+ // Return the last cached {value, done} object to allow the calling
+ // code to decide if it needs to call touchNext again.
+ return this[this.length - 1];
}
}
@@ -112,8 +156,8 @@ class Localization {
constructor(resourceIds = [], generateMessages = defaultGenerateMessages) {
this.resourceIds = resourceIds;
this.generateMessages = generateMessages;
- this.ctxs =
- new CachedAsyncIterable(this.generateMessages(this.resourceIds));
+ this.ctxs = CachedAsyncIterable.from(
+ this.generateMessages(this.resourceIds));
}
addResourceIds(resourceIds) {
@@ -276,8 +320,8 @@ class Localization {
* that language negotiation or available resources changed.
*/
onChange() {
- this.ctxs =
- new CachedAsyncIterable(this.generateMessages(this.resourceIds));
+ this.ctxs = CachedAsyncIterable.from(
+ this.generateMessages(this.resourceIds));
this.ctxs.touchNext(2);
}
}
diff --git a/intl/l10n/MessageContext.jsm b/intl/l10n/MessageContext.jsm
index 270fe82adae1..71932040660b 100644
--- a/intl/l10n/MessageContext.jsm
+++ b/intl/l10n/MessageContext.jsm
@@ -16,7 +16,7 @@
*/
-/* fluent@aa95b1f (July 10, 2018) */
+/* fluent@0.7.0 */
/* eslint no-magic-numbers: [0] */
@@ -25,6 +25,9 @@ const MAX_PLACEABLES = 100;
const entryIdentifierRe = /-?[a-zA-Z][a-zA-Z0-9_-]*/y;
const identifierRe = /[a-zA-Z][a-zA-Z0-9_-]*/y;
const functionIdentifierRe = /^[A-Z][A-Z_?-]*$/;
+const unicodeEscapeRe = /^[a-fA-F0-9]{4}$/;
+const trailingWSRe = /[ \t\n\r]+$/;
+
/**
* The `Parser` class is responsible for parsing FTL resources.
@@ -94,46 +97,15 @@ class RuntimeParser {
const ch = this._source[this._index];
// We don't care about comments or sections at runtime
- if (ch === "/" ||
- (ch === "#" &&
- [" ", "#", "\n"].includes(this._source[this._index + 1]))) {
+ if (ch === "#" &&
+ [" ", "#", "\n"].includes(this._source[this._index + 1])) {
this.skipComment();
return;
}
- if (ch === "[") {
- this.skipSection();
- return;
- }
-
this.getMessage();
}
- /**
- * Skip the section entry from the current index.
- *
- * @private
- */
- skipSection() {
- this._index += 1;
- if (this._source[this._index] !== "[") {
- throw this.error('Expected "[[" to open a section');
- }
-
- this._index += 1;
-
- this.skipInlineWS();
- this.getVariantName();
- this.skipInlineWS();
-
- if (this._source[this._index] !== "]" ||
- this._source[this._index + 1] !== "]") {
- throw this.error('Expected "]]" to close a section');
- }
-
- this._index += 2;
- }
-
/**
* Parse the source string from the current index as an FTL message
* and add it to the entries property on the Parser.
@@ -147,6 +119,8 @@ class RuntimeParser {
if (this._source[this._index] === "=") {
this._index++;
+ } else {
+ throw this.error("Expected \"=\" after the identifier");
}
this.skipInlineWS();
@@ -236,7 +210,7 @@ class RuntimeParser {
* Get identifier using the provided regex.
*
* By default this will get identifiers of public messages, attributes and
- * external arguments (without the $).
+ * variables (without the $).
*
* @returns {String}
* @private
@@ -311,21 +285,30 @@ class RuntimeParser {
* @private
*/
getString() {
- const start = this._index + 1;
+ let value = "";
+ this._index++;
- while (++this._index < this._length) {
+ while (this._index < this._length) {
const ch = this._source[this._index];
if (ch === '"') {
+ this._index++;
break;
}
if (ch === "\n") {
throw this.error("Unterminated string expression");
}
+
+ if (ch === "\\") {
+ value += this.getEscapedCharacter(["{", "\\", "\""]);
+ } else {
+ this._index++;
+ value += ch;
+ }
}
- return this._source.substring(start, this._index++);
+ return value;
}
/**
@@ -349,10 +332,17 @@ class RuntimeParser {
eol = this._length;
}
- const firstLineContent = start !== eol ?
- this._source.slice(start, eol) : null;
+ // If there's any text between the = and the EOL, store it for now. The next
+ // non-empty line will decide what to do with it.
+ const firstLineContent = start !== eol
+ // Trim the trailing whitespace in case this is a single-line pattern.
+ // Multiline patterns are parsed anew by getComplexPattern.
+ ? this._source.slice(start, eol).replace(trailingWSRe, "")
+ : null;
- if (firstLineContent && firstLineContent.includes("{")) {
+ if (firstLineContent
+ && (firstLineContent.includes("{")
+ || firstLineContent.includes("\\"))) {
return this.getComplexPattern();
}
@@ -439,13 +429,19 @@ class RuntimeParser {
}
ch = this._source[this._index];
continue;
- } else if (ch === "\\") {
- const ch2 = this._source[this._index + 1];
- if (ch2 === '"' || ch2 === "{" || ch2 === "\\") {
- ch = ch2;
- this._index++;
- }
- } else if (ch === "{") {
+ }
+
+ if (ch === undefined) {
+ break;
+ }
+
+ if (ch === "\\") {
+ buffer += this.getEscapedCharacter();
+ ch = this._source[this._index];
+ continue;
+ }
+
+ if (ch === "{") {
// Push the buffer to content array right before placeable
if (buffer.length) {
content.push(buffer);
@@ -457,18 +453,13 @@ class RuntimeParser {
buffer = "";
content.push(this.getPlaceable());
- this._index++;
-
- ch = this._source[this._index];
+ ch = this._source[++this._index];
placeables++;
continue;
}
- if (ch) {
- buffer += ch;
- }
- this._index++;
- ch = this._source[this._index];
+ buffer += ch;
+ ch = this._source[++this._index];
}
if (content.length === 0) {
@@ -476,13 +467,42 @@ class RuntimeParser {
}
if (buffer.length) {
- content.push(buffer);
+ // Trim trailing whitespace, too.
+ content.push(buffer.replace(trailingWSRe, ""));
}
return content;
}
/* eslint-enable complexity */
+ /**
+ * Parse an escape sequence and return the unescaped character.
+ *
+ * @returns {string}
+ * @private
+ */
+ getEscapedCharacter(specials = ["{", "\\"]) {
+ this._index++;
+ const next = this._source[this._index];
+
+ if (specials.includes(next)) {
+ this._index++;
+ return next;
+ }
+
+ if (next === "u") {
+ const sequence = this._source.slice(this._index + 1, this._index + 5);
+ if (unicodeEscapeRe.test(sequence)) {
+ this._index += 5;
+ return String.fromCodePoint(parseInt(sequence, 16));
+ }
+
+ throw this.error(`Invalid Unicode escape sequence: \\u${sequence}`);
+ }
+
+ throw this.error(`Unknown escape sequence: \\${next}`);
+ }
+
/**
* Parses a single placeable in a Message pattern and returns its
* expression.
@@ -519,7 +539,7 @@ class RuntimeParser {
const ch = this._source[this._index];
if (ch === "}") {
- if (selector.type === "attr" && selector.id.name.startsWith("-")) {
+ if (selector.type === "getattr" && selector.id.name.startsWith("-")) {
throw this.error(
"Attributes of private messages cannot be interpolated."
);
@@ -536,11 +556,11 @@ class RuntimeParser {
throw this.error("Message references cannot be used as selectors.");
}
- if (selector.type === "var") {
+ if (selector.type === "getvar") {
throw this.error("Variants cannot be used as selectors.");
}
- if (selector.type === "attr" && !selector.id.name.startsWith("-")) {
+ if (selector.type === "getattr" && !selector.id.name.startsWith("-")) {
throw this.error(
"Attributes of public messages cannot be used as selectors."
);
@@ -578,6 +598,10 @@ class RuntimeParser {
* @private
*/
getSelectorExpression() {
+ if (this._source[this._index] === "{") {
+ return this.getPlaceable();
+ }
+
const literal = this.getLiteral();
if (literal.type !== "ref") {
@@ -590,7 +614,7 @@ class RuntimeParser {
const name = this.getIdentifier();
this._index++;
return {
- type: "attr",
+ type: "getattr",
id: literal,
name
};
@@ -602,7 +626,7 @@ class RuntimeParser {
const key = this.getVariantKey();
this._index++;
return {
- type: "var",
+ type: "getvar",
id: literal,
key
};
@@ -640,7 +664,7 @@ class RuntimeParser {
const args = [];
while (this._index < this._length) {
- this.skipInlineWS();
+ this.skipWS();
if (this._source[this._index] === ")") {
return args;
@@ -657,7 +681,7 @@ class RuntimeParser {
if (this._source[this._index] === ":") {
this._index++;
- this.skipInlineWS();
+ this.skipWS();
const val = this.getSelectorExpression();
@@ -685,7 +709,7 @@ class RuntimeParser {
}
}
- this.skipInlineWS();
+ this.skipWS();
if (this._source[this._index] === ")") {
break;
@@ -885,7 +909,7 @@ class RuntimeParser {
if (cc0 === 36) { // $
this._index++;
return {
- type: "ext",
+ type: "var",
name: this.getIdentifier()
};
}
@@ -925,12 +949,11 @@ class RuntimeParser {
// to parse them properly and skip their content.
let eol = this._source.indexOf("\n", this._index);
- while (eol !== -1 &&
- ((this._source[eol + 1] === "/" && this._source[eol + 2] === "/") ||
- (this._source[eol + 1] === "#" &&
- [" ", "#"].includes(this._source[eol + 2])))) {
- this._index = eol + 3;
+ while (eol !== -1
+ && this._source[eol + 1] === "#"
+ && [" ", "#"].includes(this._source[eol + 2])) {
+ this._index = eol + 3;
eol = this._source.indexOf("\n", this._index);
if (eol === -1) {
@@ -972,7 +995,7 @@ class RuntimeParser {
if ((cc >= 97 && cc <= 122) || // a-z
(cc >= 65 && cc <= 90) || // A-Z
- cc === 47 || cc === 91) { // /[
+ cc === 45) { // -
this._index = start;
return;
}
@@ -1169,11 +1192,11 @@ function values(opts) {
* The role of the Fluent resolver is to format a translation object to an
* instance of `FluentType` or an array of instances.
*
- * Translations can contain references to other messages or external arguments,
+ * Translations can contain references to other messages or variables,
* conditional logic in form of select expressions, traits which describe their
* grammatical features, and can use Fluent builtins which make use of the
* `Intl` formatters to format numbers, dates, lists and more into the
- * context's language. See the documentation of the Fluent syntax for more
+ * context's language. See the documentation of the Fluent syntax for more
* information.
*
* In case of errors the resolver will try to salvage as much of the
@@ -1436,8 +1459,8 @@ function Type(env, expr) {
return new FluentSymbol(expr.name);
case "num":
return new FluentNumber(expr.val);
- case "ext":
- return ExternalArgument(env, expr);
+ case "var":
+ return VariableReference(env, expr);
case "fun":
return FunctionReference(env, expr);
case "call":
@@ -1446,11 +1469,11 @@ function Type(env, expr) {
const message = MessageReference(env, expr);
return Type(env, message);
}
- case "attr": {
+ case "getattr": {
const attr = AttributeExpression(env, expr);
return Type(env, attr);
}
- case "var": {
+ case "getvar": {
const variant = VariantExpression(env, expr);
return Type(env, variant);
}
@@ -1474,7 +1497,7 @@ function Type(env, expr) {
}
/**
- * Resolve a reference to an external argument.
+ * Resolve a reference to a variable.
*
* @param {Object} env
* Resolver environment object.
@@ -1485,11 +1508,11 @@ function Type(env, expr) {
* @returns {FluentType}
* @private
*/
-function ExternalArgument(env, {name}) {
+function VariableReference(env, {name}) {
const { args, errors } = env;
if (!args || !args.hasOwnProperty(name)) {
- errors.push(new ReferenceError(`Unknown external: ${name}`));
+ errors.push(new ReferenceError(`Unknown variable: ${name}`));
return new FluentNone(name);
}
@@ -1512,7 +1535,7 @@ function ExternalArgument(env, {name}) {
}
default:
errors.push(
- new TypeError(`Unsupported external type: ${name}, ${typeof arg}`)
+ new TypeError(`Unsupported variable type: ${name}, ${typeof arg}`)
);
return new FluentNone(name);
}
@@ -1691,13 +1714,13 @@ class FluentResource extends Map {
* responsible for parsing translation resources in the Fluent syntax and can
* format translation units (entities) to strings.
*
- * Always use `MessageContext.format` to retrieve translation units from
- * a context. Translations can contain references to other entities or
- * external arguments, conditional logic in form of select expressions, traits
- * which describe their grammatical features, and can use Fluent builtins which
- * make use of the `Intl` formatters to format numbers, dates, lists and more
- * into the context's language. See the documentation of the Fluent syntax for
- * more information.
+ * Always use `MessageContext.format` to retrieve translation units from a
+ * context. Translations can contain references to other entities or variables,
+ * conditional logic in form of select expressions, traits which describe their
+ * grammatical features, and can use Fluent builtins which make use of the
+ * `Intl` formatters to format numbers, dates, lists and more into the
+ * context's language. See the documentation of the Fluent syntax for more
+ * information.
*/
class MessageContext {
@@ -1849,8 +1872,8 @@ class MessageContext {
* Format a message to a string or null.
*
* Format a raw `message` from the context into a string (or a null if it has
- * a null value). `args` will be used to resolve references to external
- * arguments inside of the translation.
+ * a null value). `args` will be used to resolve references to variables
+ * passed as arguments to the translation.
*
* In case of errors `format` will try to salvage as much of the translation
* as possible and will still return a string. For performance reasons, the
@@ -1868,7 +1891,7 @@ class MessageContext {
*
* // Returns 'Hello, name!' and `errors` is now:
*
- * []
+ * []
*
* @param {Object | string} message
* @param {Object | undefined} args
diff --git a/intl/l10n/fluent.js.patch b/intl/l10n/fluent.js.patch
index f4dbe98ea136..f6072c69e831 100644
--- a/intl/l10n/fluent.js.patch
+++ b/intl/l10n/fluent.js.patch
@@ -1,481 +1,360 @@
-diff -uNr ./dist/DOMLocalization.jsm /home/zbraniecki/projects/mozilla-unified/intl/l10n/DOMLocalization.jsm
---- ./dist/DOMLocalization.jsm 2018-04-13 08:25:21.143138950 -0700
-+++ /home/zbraniecki/projects/mozilla-unified/intl/l10n/DOMLocalization.jsm 2018-04-13 08:27:11.658083766 -0700
-@@ -18,10 +18,8 @@
+diff -uN -x README -x moz.build -x L10nRegistry.jsm -x jar.mn -x fluent.js.patch ./intl/l10n/DOMLocalization.jsm /home/zbraniecki/projects/fluent/fluent.js/fluent-gecko/dist/DOMLocalization.jsm
+--- ./intl/l10n/DOMLocalization.jsm 2018-08-03 13:25:20.275840905 -0700
++++ /home/zbraniecki/projects/fluent/fluent.js/fluent-gecko/dist/DOMLocalization.jsm 2018-08-01 09:15:58.916763182 -0700
+@@ -16,10 +16,12 @@
+ */
- /* fluent-dom@0.2.0 */
--import Localization from '../../fluent-dom/src/localization.js';
--
--/* eslint no-console: ["error", {allow: ["warn"]}] */
--/* global console */
-+const { Localization } =
-+ ChromeUtils.import("resource://gre/modules/Localization.jsm", {});
+-/* fluent-dom@cab517f (July 31, 2018) */
++/* fluent-dom@0.3.0 */
+
+-const { Localization } =
+- ChromeUtils.import("resource://gre/modules/Localization.jsm", {});
++import Localization from '../../fluent-dom/src/localization.js';
++
++/* eslint no-console: ["error", {allow: ["warn"]}] */
++/* global console */
// Match the opening angle bracket (<) in HTML tags, and HTML entities like
// &, &, &.
-@@ -96,6 +94,7 @@
+@@ -61,9 +63,7 @@
+ global: [
+ "accesskey", "aria-label", "aria-valuetext", "aria-moz-hint", "label"
+ ],
+- description: ["value"],
+ key: ["key", "keycode"],
+- label: ["value"],
+ textbox: ["placeholder"],
+ toolbarbutton: ["tooltiptext"],
+ }
+@@ -96,7 +96,6 @@
const templateElement = element.ownerDocument.createElementNS(
"http://www.w3.org/1999/xhtml", "template"
);
-+ // eslint-disable-next-line no-unsanitized/property
+- // eslint-disable-next-line no-unsanitized/property
templateElement.innerHTML = value;
overlayChildNodes(templateElement.content, element);
}
-@@ -323,6 +322,46 @@
+@@ -350,46 +349,6 @@
return toElement;
}
-+/**
-+ * Sanitizes a translation before passing them to Node.localize API.
-+ *
-+ * It returns `false` if the translation contains DOM Overlays and should
-+ * not go into Node.localize.
-+ *
-+ * Note: There's a third item of work that JS DOM Overlays do - removal
-+ * of attributes from the previous translation.
-+ * This is not trivial to implement for Node.localize scenario, so
-+ * at the moment it is not supported.
-+ *
-+ * @param {{
-+ * localName: string,
-+ * namespaceURI: string,
-+ * type: string || null
-+ * l10nId: string,
-+ * l10nArgs: Array
- Your browser window is too small. For most accurate results, please make the view port size at least 850px by 650px.
+ Your browser window is too small. For most accurate results, please make the viewport size at least 850px by 650px.
It's currently .
diff --git a/third_party/webkit/PerformanceTests/StyleBench/index.html b/third_party/webkit/PerformanceTests/StyleBench/index.html
index 5e57bbb27a17..ed2c6cacb2e8 100644
--- a/third_party/webkit/PerformanceTests/StyleBench/index.html
+++ b/third_party/webkit/PerformanceTests/StyleBench/index.html
@@ -29,7 +29,7 @@
StyleBench is a browser benchmark that measures the performance of the style resolution mechanism.
- Your browser window is too small. For most accurate results, please make the view port size at least 850px by 650px.
+ Your browser window is too small. For most accurate results, please make the viewport size at least 850px by 650px.
It's currently .
From 37669b3f4a931bcba8333cd75d50aec4a550ca84 Mon Sep 17 00:00:00 2001
From: Kyle Machulis
Date: Tue, 7 Aug 2018 00:53:58 +0000
Subject: [PATCH 17/28] Bug 1473833 - Skip object loading when given
unrecognized mime type; r=bzbarsky
At the moment, a tag that has document type capabilities will try to
load tag content with invalid MIME types as a document. This patch
will cause the load to fail silently instead.
This will cause failures in certain WPTs that expect plugins to be
present to fill in MIME type requirements, which we currently don't
have available on CI. These WPTs have been disabled for the moment.
MozReview-Commit-ID: 9JGR4LClE5x
Differential Revision: https://phabricator.services.mozilla.com/D2542
--HG--
extra : moz-landing-system : lando
---
devtools/client/inspector/test/doc_inspector_embed.html | 2 +-
dom/base/nsObjectLoadingContent.cpp | 9 ++++++---
.../svg/object-in-svg-foreignobject.sub.html.ini | 2 ++
3 files changed, 9 insertions(+), 4 deletions(-)
create mode 100644 testing/web-platform/meta/content-security-policy/svg/object-in-svg-foreignobject.sub.html.ini
diff --git a/devtools/client/inspector/test/doc_inspector_embed.html b/devtools/client/inspector/test/doc_inspector_embed.html
index af84dd31c2a2..8262fc2934a9 100644
--- a/devtools/client/inspector/test/doc_inspector_embed.html
+++ b/devtools/client/inspector/test/doc_inspector_embed.html
@@ -1,6 +1,6 @@
-
diff --git a/dom/base/nsObjectLoadingContent.cpp b/dom/base/nsObjectLoadingContent.cpp
index 4c335886a4eb..c61d270f46dc 100644
--- a/dom/base/nsObjectLoadingContent.cpp
+++ b/dom/base/nsObjectLoadingContent.cpp
@@ -1810,12 +1810,15 @@ nsObjectLoadingContent::UpdateObjectParameters()
IsPluginType(newMime_Type)) {
newType = newMime_Type;
LOG(("OBJLC [%p]: Plugin type with no URI, skipping channel load", this));
- } else if (newURI) {
+ } else if (newURI && (mOriginalContentType.IsEmpty() || newMime_Type != eType_Null)) {
// We could potentially load this if we opened a channel on mURI, indicate
- // This by leaving type as loading
+ // this by leaving type as loading.
+ //
+ // If a MIME type was requested in the tag, but we have decided to set load
+ // type to null, ignore (otherwise we'll default to document type loading).
newType = eType_Loading;
} else {
- // Unloadable - no URI, and no plugin type. Non-plugin types (images,
+ // Unloadable - no URI, and no plugin/MIME type. Non-plugin types (images,
// documents) always load with a channel.
newType = eType_Null;
}
diff --git a/testing/web-platform/meta/content-security-policy/svg/object-in-svg-foreignobject.sub.html.ini b/testing/web-platform/meta/content-security-policy/svg/object-in-svg-foreignobject.sub.html.ini
new file mode 100644
index 000000000000..f387e7d52268
--- /dev/null
+++ b/testing/web-platform/meta/content-security-policy/svg/object-in-svg-foreignobject.sub.html.ini
@@ -0,0 +1,2 @@
+[object-in-svg-foreignobject.sub.html]
+ disabled: https://github.com/web-platform-tests/wpt/issues/12282
From 7a58a577d54d87ef5608832e754a0da527c3e0b4 Mon Sep 17 00:00:00 2001
From: alwu
Date: Fri, 3 Aug 2018 11:28:30 -0700
Subject: [PATCH 18/28] Bug 1480738 - part1 : only allow top-level video
document to autoplay. r=cpearce
Only allow top-level video document to autoplay in order to avoid autoplay from
video document which is in the iframe.
MozReview-Commit-ID: BbyjviK1BRK
--HG--
extra : rebase_source : f84421e27c6029dd3733f3c5a5d329b1755a0ee3
---
dom/media/AutoplayPolicy.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/dom/media/AutoplayPolicy.cpp b/dom/media/AutoplayPolicy.cpp
index afc1fae0a232..5204a33bde04 100644
--- a/dom/media/AutoplayPolicy.cpp
+++ b/dom/media/AutoplayPolicy.cpp
@@ -140,7 +140,9 @@ IsMediaElementAllowedToPlay(const HTMLMediaElement& aElement)
return true;
}
- if (aElement.OwnerDoc()->MediaDocumentKind() == nsIDocument::MediaDocumentKind::Video) {
+ nsIDocument* topDocument = ApproverDocOf(*aElement.OwnerDoc());
+ if (topDocument &&
+ topDocument->MediaDocumentKind() == nsIDocument::MediaDocumentKind::Video) {
AUTOPLAY_LOG("Allow video document %p to autoplay\n", &aElement);
return true;
}
From c9a517ec966aae6189f234bc1886ec5f12f91210 Mon Sep 17 00:00:00 2001
From: alwu
Date: Fri, 3 Aug 2018 12:57:38 -0700
Subject: [PATCH 19/28] Bug 1480738 - part2 : add test. r=cpearce
MozReview-Commit-ID: 8GwifOpAQNf
--HG--
extra : rebase_source : 8f21f469894deb5ae815582dcb7c50625c7b50b8
---
.../browser/browser_autoplay_videoDocument.js | 38 ++++++++++++++++++-
1 file changed, 36 insertions(+), 2 deletions(-)
diff --git a/toolkit/content/tests/browser/browser_autoplay_videoDocument.js b/toolkit/content/tests/browser/browser_autoplay_videoDocument.js
index 421fc6a11bd5..8f75b38b4560 100644
--- a/toolkit/content/tests/browser/browser_autoplay_videoDocument.js
+++ b/toolkit/content/tests/browser/browser_autoplay_videoDocument.js
@@ -12,12 +12,33 @@ function setup_test_preference() {
function checkIsVideoDocumentAutoplay(browser) {
return ContentTask.spawn(browser, null, async () => {
- let video = content.document.getElementsByTagName("video")[0];
- let played = video && await video.play().then(() => true, () => false);
+ const video = content.document.getElementsByTagName("video")[0];
+ const played = video && await video.play().then(() => true, () => false);
ok(played, "Should be able to play in video document.");
});
}
+async function checkIsIframeVideoDocumentAutoplay(browser) {
+ info("- create iframe video document -");
+ await ContentTask.spawn(browser, PAGE, async (pageURL) => {
+ const iframe = content.document.createElement("iframe");
+ iframe.src = pageURL;
+ content.document.body.appendChild(iframe);
+ const iframeLoaded = new Promise((resolve, reject) => {
+ iframe.addEventListener("load", e => resolve(), {once: true});
+ });
+ await iframeLoaded;
+ });
+
+ info("- check whether iframe video document starts playing -");
+ await ContentTask.spawn(browser, null, async () => {
+ const iframe = content.document.querySelector("iframe");
+ const video = iframe.contentDocument.querySelector("video");
+ ok(video.paused, "Subdoc video should not have played");
+ is(video.played.length, 0, "Should have empty played ranges");
+ });
+}
+
add_task(async () => {
await BrowserTestUtils.withNewTab({
gBrowser,
@@ -31,3 +52,16 @@ add_task(async () => {
});
});
+add_task(async () => {
+ await BrowserTestUtils.withNewTab({
+ gBrowser,
+ url: "about:blank",
+ }, async (browser) => {
+ info("- setup test preference -");
+ await setup_test_preference();
+
+ info(`- check whether video document in iframe is autoplay -`);
+ await checkIsIframeVideoDocumentAutoplay(browser);
+ });
+});
+
From a6e0ebd8ef25d0b0b0331819c56bfe8a6385f04e Mon Sep 17 00:00:00 2001
From: Tiberius Oros
Date: Tue, 7 Aug 2018 04:46:22 +0300
Subject: [PATCH 20/28] Backed out changeset 502893089232 (bug 1475571) for
browser_preferences_usage.js on a CLOSED TREE
---
browser/extensions/moz.build | 1 +
browser/modules/BrowserUsageTelemetry.jsm | 79 ++++----------------
toolkit/components/search/nsSearchService.js | 7 +-
toolkit/components/telemetry/Histograms.json | 2 +-
4 files changed, 16 insertions(+), 73 deletions(-)
diff --git a/browser/extensions/moz.build b/browser/extensions/moz.build
index 66ac545f478c..c2b67265febe 100644
--- a/browser/extensions/moz.build
+++ b/browser/extensions/moz.build
@@ -6,6 +6,7 @@
DIRS += [
'aushelper',
+ 'followonsearch',
'formautofill',
'onboarding',
'pdfjs',
diff --git a/browser/modules/BrowserUsageTelemetry.jsm b/browser/modules/BrowserUsageTelemetry.jsm
index 3211c23c9999..a60692631aec 100644
--- a/browser/modules/BrowserUsageTelemetry.jsm
+++ b/browser/modules/BrowserUsageTelemetry.jsm
@@ -13,13 +13,10 @@ var EXPORTED_SYMBOLS = [
];
ChromeUtils.import("resource://gre/modules/Services.jsm");
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
-XPCOMUtils.defineLazyGlobalGetters(this, ["URLSearchParams"]);
-
// The upper bound for the count of the visited unique domain names.
const MAX_UNIQUE_VISITED_DOMAINS = 100;
@@ -91,6 +88,7 @@ const URLBAR_SELECTED_RESULT_METHODS = {
const MINIMUM_TAB_COUNT_INTERVAL_MS = 5 * 60 * 1000; // 5 minutes, in ms
+
function getOpenTabsAndWinsCounts() {
let tabCount = 0;
let winCount = 0;
@@ -161,10 +159,6 @@ let URICountListener = {
return;
}
- // Don't include URI and domain counts when in private mode.
- let shouldCountURI = !PrivateBrowsingUtils.isWindowPrivate(browser.ownerGlobal) ||
- Services.prefs.getBoolPref("browser.engagement.total_uri_count.pbm", false);
-
// Track URI loads, even if they're not http(s).
let uriSpec = null;
try {
@@ -172,9 +166,7 @@ let URICountListener = {
} catch (e) {
// If we have troubles parsing the spec, still count this as
// an unfiltered URI.
- if (shouldCountURI) {
- Services.telemetry.scalarAdd(UNFILTERED_URI_COUNT_SCALAR_NAME, 1);
- }
+ Services.telemetry.scalarAdd(UNFILTERED_URI_COUNT_SCALAR_NAME, 1);
return;
}
@@ -196,42 +188,12 @@ let URICountListener = {
// The URI wasn't from a restored tab. Count it among the unfiltered URIs.
// If this is an http(s) URI, this also gets counted by the "total_uri_count"
// probe.
- if (shouldCountURI) {
- Services.telemetry.scalarAdd(UNFILTERED_URI_COUNT_SCALAR_NAME, 1);
- }
+ Services.telemetry.scalarAdd(UNFILTERED_URI_COUNT_SCALAR_NAME, 1);
if (!this.isHttpURI(uri)) {
return;
}
- let parseURLResult = Services.search.parseSubmissionURL(uriSpec);
- if (parseURLResult.engine) {
- this._recordSearchTelemetry(uriSpec, parseURLResult);
- } else if (this._urlsQueuedForParsing) {
- if (Services.search.isInitialized) {
- this._urlsQueuedForParsing = null;
- } else {
- this._urlsQueuedForParsing.push(uriSpec);
- if (this._urlsQueuedForParsing.length == 1) {
- Services.search.init(rv => {
- if (Components.isSuccessCode(rv)) {
- for (let url of this._urlsQueuedForParsing) {
- let innerParseURLResult = Services.search.parseSubmissionURL(url);
- if (innerParseURLResult.engine) {
- this._recordSearchTelemetry(url, innerParseURLResult);
- }
- }
- }
- this._urlsQueuedForParsing = null;
- });
- }
- }
- }
-
- if (!shouldCountURI) {
- return;
- }
-
// Update the URI counts.
Services.telemetry.scalarAdd(TOTAL_URI_COUNT_SCALAR_NAME, 1);
@@ -264,31 +226,6 @@ let URICountListener = {
this._domainSet.clear();
},
- _urlsQueuedForParsing: [],
-
- _recordSearchTelemetry(url, parseURLResult) {
- switch (parseURLResult.engine.identifier) {
- case "google":
- case "google-2018":
- let type;
- let queries = new URLSearchParams(url.split("?")[1]);
- let code = queries.get("client");
- if (code) {
- // Detecting follow-on searches for sap is a little tricky.
- // There are a few parameters that only show up
- // with follow-ons, so we look for those. (oq/ved/ei)
- type = queries.has("oq") || queries.has("ved") || queries.has("ei") ? "sap-follow-on" : "sap";
- } else {
- type = "organic";
- }
- let payload = `google.in-content.${type}:${code || "none"}`;
-
- let histogram = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS");
- histogram.add(payload);
- break;
- }
- },
-
QueryInterface: ChromeUtils.generateQI([Ci.nsIWebProgressListener,
Ci.nsISupportsWeakReference]),
};
@@ -677,6 +614,11 @@ let BrowserUsageTelemetry = {
win.addEventListener("unload", this);
win.addEventListener("TabOpen", this, true);
+ // Don't include URI and domain counts when in private mode.
+ if (PrivateBrowsingUtils.isWindowPrivate(win) &&
+ !Services.prefs.getBoolPref("browser.engagement.total_uri_count.pbm", false)) {
+ return;
+ }
win.gBrowser.tabContainer.addEventListener(TAB_RESTORING_TOPIC, this);
win.gBrowser.addTabsProgressListener(URICountListener);
},
@@ -688,6 +630,11 @@ let BrowserUsageTelemetry = {
win.removeEventListener("unload", this);
win.removeEventListener("TabOpen", this, true);
+ // Don't include URI and domain counts when in private mode.
+ if (PrivateBrowsingUtils.isWindowPrivate(win.defaultView) &&
+ !Services.prefs.getBoolPref("browser.engagement.total_uri_count.pbm", false)) {
+ return;
+ }
win.defaultView.gBrowser.tabContainer.removeEventListener(TAB_RESTORING_TOPIC, this);
win.defaultView.gBrowser.removeTabsProgressListener(URICountListener);
},
diff --git a/toolkit/components/search/nsSearchService.js b/toolkit/components/search/nsSearchService.js
index bc101d213fa0..91879751bcd0 100644
--- a/toolkit/components/search/nsSearchService.js
+++ b/toolkit/components/search/nsSearchService.js
@@ -4331,12 +4331,7 @@ SearchService.prototype = {
},
parseSubmissionURL: function SRCH_SVC_parseSubmissionURL(aURL) {
- if (!gInitialized) {
- // If search is not initialized, do nothing.
- // This allows us to use this function early in telemetry.
- // The only other consumer of this (places) uses it much later.
- return gEmptyParseSubmissionResult;
- }
+ this._ensureInitialized();
LOG("parseSubmissionURL: Parsing \"" + aURL + "\".");
if (!this._parseSubmissionMap) {
diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json
index c86cad1d92b4..ef0167ce46a6 100644
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -7827,7 +7827,7 @@
"kind": "count",
"keyed": true,
"releaseChannelCollection": "opt-out",
- "description": "Records search counts for search access points and in content searches. For search access points, the format is: . For in content searches, the format is .in-content:[sap|sap-follow-on|organic]:[code|none]"
+ "description": "Record the search counts for search engines"
},
"SEARCH_RESET_RESULT": {
"record_in_processes": ["main", "content"],
From 04b50a312d1e433ad8b2ef3f35411f984b5e88fb Mon Sep 17 00:00:00 2001
From: Kyle Machulis
Date: Tue, 7 Aug 2018 01:10:31 +0000
Subject: [PATCH 21/28] Bug 1480607 - Remove nsCWebBrowser and
nsCWebBrowserPersist; r=nika
It doesn't appear these IDL files have had interfaces in them since
before the Netscape import, and were mostly just hanging around
because they contained some IDs needed elsewhere. Move the IDs
somewhere more appropriate and remove files.
MozReview-Commit-ID: AINtTerqHu1
Differential Revision: https://phabricator.services.mozilla.com/D2688
--HG--
extra : moz-landing-system : lando
---
dom/webbrowserpersist/moz.build | 1 -
.../nsCWebBrowserPersist.idl | 15 --------
.../nsIWebBrowserPersist.idl | 13 +++++++
dom/webbrowserpersist/nsWebBrowserPersist.h | 3 +-
toolkit/components/browser/moz.build | 1 -
toolkit/components/browser/nsCWebBrowser.idl | 34 -------------------
toolkit/components/browser/nsEmbedCID.h | 11 ------
toolkit/components/browser/nsWebBrowser.cpp | 1 -
toolkit/components/browser/nsWebBrowser.h | 1 -
widget/windows/nsDragService.cpp | 1 -
10 files changed, 14 insertions(+), 67 deletions(-)
delete mode 100644 dom/webbrowserpersist/nsCWebBrowserPersist.idl
delete mode 100644 toolkit/components/browser/nsCWebBrowser.idl
diff --git a/dom/webbrowserpersist/moz.build b/dom/webbrowserpersist/moz.build
index 6270b9d578f6..459f999c9537 100644
--- a/dom/webbrowserpersist/moz.build
+++ b/dom/webbrowserpersist/moz.build
@@ -9,7 +9,6 @@ with Files("**"):
BUG_COMPONENT = ("Core", "DOM")
XPIDL_SOURCES += [
- 'nsCWebBrowserPersist.idl',
'nsIWebBrowserPersist.idl',
'nsIWebBrowserPersistDocument.idl',
]
diff --git a/dom/webbrowserpersist/nsCWebBrowserPersist.idl b/dom/webbrowserpersist/nsCWebBrowserPersist.idl
deleted file mode 100644
index 69f2db7caa90..000000000000
--- a/dom/webbrowserpersist/nsCWebBrowserPersist.idl
+++ /dev/null
@@ -1,15 +0,0 @@
-/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsIWebBrowserPersist.idl"
-
-%{ C++
-// {7E677795-C582-4cd1-9E8D-8271B3474D2A}
-#define NS_WEBBROWSERPERSIST_CID \
-{ 0x7e677795, 0xc582, 0x4cd1, { 0x9e, 0x8d, 0x82, 0x71, 0xb3, 0x47, 0x4d, 0x2a } }
-#define NS_WEBBROWSERPERSIST_CONTRACTID \
-"@mozilla.org/embedding/browser/nsWebBrowserPersist;1"
-%}
diff --git a/dom/webbrowserpersist/nsIWebBrowserPersist.idl b/dom/webbrowserpersist/nsIWebBrowserPersist.idl
index 3b3e4adcc065..ed5b907adef0 100644
--- a/dom/webbrowserpersist/nsIWebBrowserPersist.idl
+++ b/dom/webbrowserpersist/nsIWebBrowserPersist.idl
@@ -261,3 +261,16 @@ interface nsIWebBrowserPersist : nsICancelable
*/
void cancelSave();
};
+
+/**
+ * We don't export nsWebBrowserPersist.h as a public header, so we need a place
+ * to put the CID/ContractID. All places uses the WebBrowserPersist include
+ * nsIWebBrowserPersist.h, so we define our contract IDs here for now.
+ */
+%{ C++
+// {7E677795-C582-4cd1-9E8D-8271B3474D2A}
+#define NS_WEBBROWSERPERSIST_CID \
+ { 0x7e677795, 0xc582, 0x4cd1, { 0x9e, 0x8d, 0x82, 0x71, 0xb3, 0x47, 0x4d, 0x2a } }
+#define NS_WEBBROWSERPERSIST_CONTRACTID \
+ "@mozilla.org/embedding/browser/nsWebBrowserPersist;1"
+%}
diff --git a/dom/webbrowserpersist/nsWebBrowserPersist.h b/dom/webbrowserpersist/nsWebBrowserPersist.h
index 3eb55f0fcd52..9df8647e9dbe 100644
--- a/dom/webbrowserpersist/nsWebBrowserPersist.h
+++ b/dom/webbrowserpersist/nsWebBrowserPersist.h
@@ -21,6 +21,7 @@
#include "nsIProgressEventSink.h"
#include "nsIFile.h"
#include "nsIWebProgressListener2.h"
+#include "nsIWebBrowserPersist.h"
#include "nsIWebBrowserPersistDocument.h"
#include "mozilla/UniquePtr.h"
@@ -28,8 +29,6 @@
#include "nsHashKeys.h"
#include "nsTArray.h"
-#include "nsCWebBrowserPersist.h"
-
class nsIStorageStream;
class nsIWebBrowserPersistDocument;
diff --git a/toolkit/components/browser/moz.build b/toolkit/components/browser/moz.build
index 92ab3fd903d9..bb659a4a9d1e 100644
--- a/toolkit/components/browser/moz.build
+++ b/toolkit/components/browser/moz.build
@@ -10,7 +10,6 @@ with Files('**'):
DIRS += ['build']
XPIDL_SOURCES += [
- 'nsCWebBrowser.idl',
'nsIEmbeddingSiteWindow.idl',
'nsIWebBrowser.idl',
'nsIWebBrowserChrome.idl',
diff --git a/toolkit/components/browser/nsCWebBrowser.idl b/toolkit/components/browser/nsCWebBrowser.idl
deleted file mode 100644
index 21927f7c7ef8..000000000000
--- a/toolkit/components/browser/nsCWebBrowser.idl
+++ /dev/null
@@ -1,34 +0,0 @@
-/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsIWebBrowser.idl"
-#include "nsIBaseWindow.idl"
-#include "nsIScrollable.idl"
-#include "nsITextScroll.idl"
-
-/*
-nsCWebBrowser implements:
--------------------------
-nsIWebBrowser
-nsIDocShellTreeItem
-nsIWebNavigation
-nsIWebProgress
-nsIBaseWindow
-nsIScrollable
-nsITextScroll
-nsIInterfaceRequestor
-
-
-Outwardly communicates with:
-----------------------------
-nsIWebBrowserChrome
-nsIBaseWindow
-nsIInterfaceRequestor
-*/
-
-%{ C++
-#include "nsEmbedCID.h"
-%}
diff --git a/toolkit/components/browser/nsEmbedCID.h b/toolkit/components/browser/nsEmbedCID.h
index 82fe237631a4..ab182a033f72 100644
--- a/toolkit/components/browser/nsEmbedCID.h
+++ b/toolkit/components/browser/nsEmbedCID.h
@@ -43,15 +43,4 @@
#define NS_PROMPTSERVICE_CONTRACTID \
"@mozilla.org/embedcomp/prompt-service;1"
-/**
- * This contract ID should be implemented by password managers to be able to
- * override the standard implementation of nsIAuthPrompt2. It will be used as
- * a service.
- *
- * This contract implements the following interfaces:
- * nsIPromptFactory
- */
-#define NS_PWMGR_AUTHPROMPTFACTORY \
- "@mozilla.org/passwordmanager/authpromptfactory;1"
-
#endif // NSEMBEDCID_H
diff --git a/toolkit/components/browser/nsWebBrowser.cpp b/toolkit/components/browser/nsWebBrowser.cpp
index 0f23e2b726c9..ac7630f3fdec 100644
--- a/toolkit/components/browser/nsWebBrowser.cpp
+++ b/toolkit/components/browser/nsWebBrowser.cpp
@@ -31,7 +31,6 @@
#include "nsISHistoryListener.h"
#include "nsIURI.h"
#include "nsIWebBrowserPersist.h"
-#include "nsCWebBrowserPersist.h"
#include "nsIServiceManager.h"
#include "nsFocusManager.h"
#include "Layers.h"
diff --git a/toolkit/components/browser/nsWebBrowser.h b/toolkit/components/browser/nsWebBrowser.h
index a378612d679e..c9784a5d8123 100644
--- a/toolkit/components/browser/nsWebBrowser.h
+++ b/toolkit/components/browser/nsWebBrowser.h
@@ -16,7 +16,6 @@
#include "nsCycleCollectionParticipant.h"
// Interfaces needed
-#include "nsCWebBrowser.h"
#include "nsIBaseWindow.h"
#include "nsIDocShell.h"
#include "nsIDocShellTreeItem.h"
diff --git a/widget/windows/nsDragService.cpp b/widget/windows/nsDragService.cpp
index c6d711126a8c..9b5c2be26b36 100644
--- a/widget/windows/nsDragService.cpp
+++ b/widget/windows/nsDragService.cpp
@@ -29,7 +29,6 @@
#include "nsIScreenManager.h"
#include "nsISupportsPrimitives.h"
#include "nsIURL.h"
-#include "nsCWebBrowserPersist.h"
#include "nsToolkit.h"
#include "nsCRT.h"
#include "nsDirectoryServiceDefs.h"
From f3ef96fcc07a3fe51b55021b25935cca285d3a89 Mon Sep 17 00:00:00 2001
From: Jan-Ivar Bruaroey
Date: Wed, 1 Aug 2018 22:46:17 -0400
Subject: [PATCH 22/28] Bug 1480306: Fix unused variable variable
'hasLineOfContext' in TokenStream.cpp. r=Waldo
MozReview-Commit-ID: EK1IAvCZFwv
--HG--
extra : rebase_source : 8ed430ca01927142f77814a81364c6645c3a2581
---
js/src/frontend/TokenStream.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/js/src/frontend/TokenStream.cpp b/js/src/frontend/TokenStream.cpp
index 0157e48bf64c..aa53509bdb2f 100644
--- a/js/src/frontend/TokenStream.cpp
+++ b/js/src/frontend/TokenStream.cpp
@@ -626,7 +626,8 @@ TokenStreamChars::internalEncodingError(uint8_t releva
TokenStreamAnyChars& anyChars = anyCharsAccess();
- if (bool hasLineOfContext = anyChars.fillExcludingContext(&err, offset)) {
+ bool hasLineOfContext = anyChars.fillExcludingContext(&err, offset);
+ if (hasLineOfContext) {
if (!internalComputeLineOfContext(&err, offset))
break;
From 809d66a5587aedaf7c142df716e95bb8bccfdcd8 Mon Sep 17 00:00:00 2001
From: Julian Descottes
Date: Tue, 7 Aug 2018 04:47:56 +0000
Subject: [PATCH 23/28] Bug 1480743 - Update styles in aboutdebugging-new to
match other about:pages;r=daisuke
This duplicates some of the styles from other about:pages, reusing existing
variables when possible.
Differential Revision: https://phabricator.services.mozilla.com/D2717
--HG--
extra : moz-landing-system : lando
---
.../aboutdebugging-new/aboutdebugging.css | 8 +++++-
devtools/client/aboutdebugging-new/index.html | 1 +
.../aboutdebugging-new/src/components/App.css | 1 +
.../src/components/SidebarItem.css | 28 ++++++++++++-------
4 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/devtools/client/aboutdebugging-new/aboutdebugging.css b/devtools/client/aboutdebugging-new/aboutdebugging.css
index 4e9d1b88014d..43d02c97fdc9 100644
--- a/devtools/client/aboutdebugging-new/aboutdebugging.css
+++ b/devtools/client/aboutdebugging-new/aboutdebugging.css
@@ -2,16 +2,22 @@
* 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/. */
-@import "resource://devtools/client/themes/variables.css";
+@import "chrome://global/skin/in-content/common.css";
@import "resource://devtools/client/aboutdebugging-new/src/components/App.css";
@import "resource://devtools/client/aboutdebugging-new/src/components/RuntimeInfo.css";
@import "resource://devtools/client/aboutdebugging-new/src/components/RuntimePage.css";
@import "resource://devtools/client/aboutdebugging-new/src/components/Sidebar.css";
@import "resource://devtools/client/aboutdebugging-new/src/components/SidebarItem.css";
+:root {
+ /* Import css variables from common.css */
+ --text-color: var(--in-content-page-color);
+}
+
html, body {
margin: 0;
padding: 0;
+ color: var(--text-color);
}
ul {
diff --git a/devtools/client/aboutdebugging-new/index.html b/devtools/client/aboutdebugging-new/index.html
index 1420da8d533f..d0196bfa402f 100644
--- a/devtools/client/aboutdebugging-new/index.html
+++ b/devtools/client/aboutdebugging-new/index.html
@@ -5,6 +5,7 @@
+
diff --git a/devtools/client/aboutdebugging-new/src/components/App.css b/devtools/client/aboutdebugging-new/src/components/App.css
index 7eca3c724fc3..b46e423ab94f 100644
--- a/devtools/client/aboutdebugging-new/src/components/App.css
+++ b/devtools/client/aboutdebugging-new/src/components/App.css
@@ -14,6 +14,7 @@
.app {
display: grid;
font-size: 15px;
+ grid-column-gap: 40px;
grid-template-columns: 240px auto;
height: 100vh;
overflow: hidden;
diff --git a/devtools/client/aboutdebugging-new/src/components/SidebarItem.css b/devtools/client/aboutdebugging-new/src/components/SidebarItem.css
index a2a0dd7bc7f9..1140cc15be39 100644
--- a/devtools/client/aboutdebugging-new/src/components/SidebarItem.css
+++ b/devtools/client/aboutdebugging-new/src/components/SidebarItem.css
@@ -3,20 +3,32 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
.sidebar-item {
- --sidebar-item-color: var(--grey-50);
- --sidebar-item-selected-color: var(--blue-55);
+ /* Import css variables from common.css */
+ --sidebar-text-color: var(--in-content-category-text);
+ --sidebar-selected-color: var(--in-content-category-text-selected);
+ --sidebar-background-hover: var(--in-content-category-background-hover);
}
.sidebar-item {
- color: var(--sidebar-item-color);
align-items: center;
+ border-radius: 2px;
+ color: var(--sidebar-text-color);
display: flex;
- font-size: 20px;
+ font-size: 16px;
+ height: 48px;
margin-inline-start: 24px;
+ padding-inline-end: 10px;
+ padding-inline-start: 10px;
+ transition: background-color 150ms;
+ -moz-user-select: none;
+}
+
+.sidebar-item:hover {
+ background-color: var(--sidebar-background-hover);
}
.sidebar-item__icon {
- fill: var(--sidebar-item-color);
+ fill: currentColor;
height: 24px;
margin-inline-end: 9px;
width: 24px;
@@ -24,9 +36,5 @@
}
.sidebar-item--selected {
- color: var(--sidebar-item-selected-color);
-}
-
-.sidebar-item__icon--selected {
- fill: var(--sidebar-item-selected-color);
+ color: var(--sidebar-selected-color);
}
From d1f26ef91d405184ea98edbedb5c33160dd67efd Mon Sep 17 00:00:00 2001
From: Julian Descottes
Date: Tue, 7 Aug 2018 04:56:56 +0000
Subject: [PATCH 24/28] Bug 1480789 - Add Connect page to new
aboutdebugging;r=daisuke
Differential Revision: https://phabricator.services.mozilla.com/D2724
--HG--
extra : moz-landing-system : lando
---
.../aboutdebugging-new/aboutdebugging.css | 4 +-
.../aboutdebugging-new/src/components/App.css | 8 +-
.../aboutdebugging-new/src/components/App.js | 3 +
.../src/components/ConnectPage.css | 24 +++++
.../src/components/ConnectPage.js | 92 +++++++++++++++++++
.../src/components/RuntimePage.css | 7 --
.../src/components/RuntimePage.js | 2 +-
.../src/components/moz.build | 3 +-
8 files changed, 130 insertions(+), 13 deletions(-)
create mode 100644 devtools/client/aboutdebugging-new/src/components/ConnectPage.css
create mode 100644 devtools/client/aboutdebugging-new/src/components/ConnectPage.js
delete mode 100644 devtools/client/aboutdebugging-new/src/components/RuntimePage.css
diff --git a/devtools/client/aboutdebugging-new/aboutdebugging.css b/devtools/client/aboutdebugging-new/aboutdebugging.css
index 43d02c97fdc9..6e00515d7649 100644
--- a/devtools/client/aboutdebugging-new/aboutdebugging.css
+++ b/devtools/client/aboutdebugging-new/aboutdebugging.css
@@ -4,8 +4,8 @@
@import "chrome://global/skin/in-content/common.css";
@import "resource://devtools/client/aboutdebugging-new/src/components/App.css";
+@import "resource://devtools/client/aboutdebugging-new/src/components/ConnectPage.css";
@import "resource://devtools/client/aboutdebugging-new/src/components/RuntimeInfo.css";
-@import "resource://devtools/client/aboutdebugging-new/src/components/RuntimePage.css";
@import "resource://devtools/client/aboutdebugging-new/src/components/Sidebar.css";
@import "resource://devtools/client/aboutdebugging-new/src/components/SidebarItem.css";
@@ -24,4 +24,4 @@ ul {
list-style: none;
margin: 0;
padding: 0;
-}
+}
\ No newline at end of file
diff --git a/devtools/client/aboutdebugging-new/src/components/App.css b/devtools/client/aboutdebugging-new/src/components/App.css
index b46e423ab94f..152e21d9688d 100644
--- a/devtools/client/aboutdebugging-new/src/components/App.css
+++ b/devtools/client/aboutdebugging-new/src/components/App.css
@@ -3,10 +3,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
- * The current layout of the about:debugging is
+ * The current layout of about:debugging is
*
* +-------------+-------------------------------+
- * | Sidebar | RuntimePage |
+ * | Sidebar | Page (Runtime or Connect) |
* | (240px) | |
* | | |
* +-------------+-------------------------------+
@@ -20,3 +20,7 @@
overflow: hidden;
width: 100vw;
}
+
+.page {
+ padding-block-start: 60px;
+}
diff --git a/devtools/client/aboutdebugging-new/src/components/App.js b/devtools/client/aboutdebugging-new/src/components/App.js
index 88f528e50fe3..753250395f06 100644
--- a/devtools/client/aboutdebugging-new/src/components/App.js
+++ b/devtools/client/aboutdebugging-new/src/components/App.js
@@ -11,6 +11,7 @@ const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const { PAGES } = require("../constants");
+const ConnectPage = createFactory(require("./ConnectPage"));
const RuntimePage = createFactory(require("./RuntimePage"));
const Sidebar = createFactory(require("./Sidebar"));
@@ -29,6 +30,8 @@ class App extends PureComponent {
switch (this.props.selectedPage) {
case PAGES.THIS_FIREFOX:
return RuntimePage();
+ case PAGES.CONNECT:
+ return ConnectPage();
default:
// Invalid page, blank.
return null;
diff --git a/devtools/client/aboutdebugging-new/src/components/ConnectPage.css b/devtools/client/aboutdebugging-new/src/components/ConnectPage.css
new file mode 100644
index 000000000000..569b6ce3ad30
--- /dev/null
+++ b/devtools/client/aboutdebugging-new/src/components/ConnectPage.css
@@ -0,0 +1,24 @@
+/* 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/. */
+
+.connect-page__steps {
+ list-style-type: decimal;
+ margin-inline-start: 40px;
+ line-height: 1.5em;
+ margin-block-end: 20px;
+}
+
+.connect-page__step {
+ padding-inline-start: 20px;
+}
+
+.connect-page__section__title {
+ display: flex;
+}
+
+.connect-page__section__icon {
+ width: 32px;
+ height: 32px;
+ margin-inline-end: 5px;
+}
diff --git a/devtools/client/aboutdebugging-new/src/components/ConnectPage.js b/devtools/client/aboutdebugging-new/src/components/ConnectPage.js
new file mode 100644
index 000000000000..00cb5024978d
--- /dev/null
+++ b/devtools/client/aboutdebugging-new/src/components/ConnectPage.js
@@ -0,0 +1,92 @@
+/* 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";
+
+const { PureComponent } = require("devtools/client/shared/vendor/react");
+const dom = require("devtools/client/shared/vendor/react-dom-factories");
+
+const USB_ICON_SRC = "chrome://devtools/skin/images/aboutdebugging-connect-icon.svg";
+const WIFI_ICON_SRC = "chrome://devtools/skin/images/aboutdebugging-connect-icon.svg";
+
+class RuntimePage extends PureComponent {
+ renderSteps(steps) {
+ return dom.ul(
+ {
+ className: "connect-page__steps"
+ },
+ steps.map(step => dom.li(
+ {
+ className: "connect-page__step"
+ },
+ step)
+ )
+ );
+ }
+
+ renderWifi() {
+ return dom.section(
+ {},
+ dom.h2(
+ {
+ className: "connect-page__section__title"
+ },
+ dom.img(
+ {
+ className: "connect-page__section__icon",
+ src: WIFI_ICON_SRC
+ }
+ ),
+ "Via WiFi (Recommended)"
+ ),
+ this.renderSteps([
+ "Ensure that your browser and device are on the same network",
+ "Open Firefox for Android",
+ "Go to Options -> Settings -> Advanced",
+ "Enable Remote Debugging via WiFi in the Developer Tools section",
+ ])
+ );
+ }
+
+ renderUsb() {
+ return dom.section(
+ {},
+ dom.h2(
+ {
+ className: "connect-page__section__title"
+ },
+ dom.img(
+ {
+ className: "connect-page__section__icon",
+ src: USB_ICON_SRC
+ }
+ ),
+ "Via USB"
+ ),
+ this.renderSteps([
+ "Enable Developer menu on your Android device",
+ "Enable USB Debugging on the Android Developer Menu",
+ "Connect the USB Device to your computer",
+ ])
+ );
+ }
+
+ render() {
+ return dom.article(
+ {
+ className: "page connect-page",
+ },
+ dom.h1(
+ {
+ className: "connect-page__title"
+ },
+ "Connect a Device"
+ ),
+ this.renderWifi(),
+ this.renderUsb(),
+ );
+ }
+}
+
+module.exports = RuntimePage;
diff --git a/devtools/client/aboutdebugging-new/src/components/RuntimePage.css b/devtools/client/aboutdebugging-new/src/components/RuntimePage.css
deleted file mode 100644
index de6d07513150..000000000000
--- a/devtools/client/aboutdebugging-new/src/components/RuntimePage.css
+++ /dev/null
@@ -1,7 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-.runtime-page {
- padding-block-start: 60px;
-}
diff --git a/devtools/client/aboutdebugging-new/src/components/RuntimePage.js b/devtools/client/aboutdebugging-new/src/components/RuntimePage.js
index 08575538d005..b465bcb64b9f 100644
--- a/devtools/client/aboutdebugging-new/src/components/RuntimePage.js
+++ b/devtools/client/aboutdebugging-new/src/components/RuntimePage.js
@@ -15,7 +15,7 @@ class RuntimePage extends PureComponent {
render() {
return dom.article(
{
- className: "runtime-page",
+ className: "page",
},
RuntimeInfo({
icon: "chrome://branding/content/icon64.png",
diff --git a/devtools/client/aboutdebugging-new/src/components/moz.build b/devtools/client/aboutdebugging-new/src/components/moz.build
index f61c9fc7ba88..e11f957d9df9 100644
--- a/devtools/client/aboutdebugging-new/src/components/moz.build
+++ b/devtools/client/aboutdebugging-new/src/components/moz.build
@@ -5,9 +5,10 @@
DevToolsModules(
'App.css',
'App.js',
+ 'ConnectPage.css',
+ 'ConnectPage.js',
'RuntimeInfo.css',
'RuntimeInfo.js',
- 'RuntimePage.css',
'RuntimePage.js',
'Sidebar.css',
'Sidebar.js',
From e3cf7e35dd41a38bb8855657f3a4a036611cb42a Mon Sep 17 00:00:00 2001
From: Nicolas Chevobbe
Date: Tue, 7 Aug 2018 05:07:31 +0000
Subject: [PATCH 25/28] Bug 1478252 - Enable
client/shared/test/browser_outputparser.js in e10s; r=jdescottes.
The test was disabled for intermittent failure, but I did
not managed to make it fail with --verify.
There was a fixed needed in the test for the angle since
the property used there was deprecated.
Differential Revision: https://phabricator.services.mozilla.com/D2784
--HG--
extra : moz-landing-system : lando
---
devtools/client/shared/test/browser.ini | 1 -
devtools/client/shared/test/browser_outputparser.js | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/devtools/client/shared/test/browser.ini b/devtools/client/shared/test/browser.ini
index a79c7efaa575..9b0a4ddcfccc 100644
--- a/devtools/client/shared/test/browser.ini
+++ b/devtools/client/shared/test/browser.ini
@@ -170,7 +170,6 @@ skip-if = verify
[browser_num-l10n.js]
[browser_options-view-01.js]
[browser_outputparser.js]
-skip-if = e10s # Test intermittently fails with e10s. Bug 1124162.
[browser_poller.js]
[browser_prefs-01.js]
[browser_prefs-02.js]
diff --git a/devtools/client/shared/test/browser_outputparser.js b/devtools/client/shared/test/browser_outputparser.js
index f3a34639f68d..67f65b0acbcf 100644
--- a/devtools/client/shared/test/browser_outputparser.js
+++ b/devtools/client/shared/test/browser_outputparser.js
@@ -283,7 +283,7 @@ function testParseFilter(doc, parser) {
}
function testParseAngle(doc, parser) {
- let frag = parser.parseCssProperty("image-orientation", "90deg", {
+ let frag = parser.parseCssProperty("rotate", "90deg", {
angleSwatchClass: "test-angleswatch"
});
From 6647aa6cc004caf24808a46c40af0b6a11f9c19d Mon Sep 17 00:00:00 2001
From: James Teh
Date: Thu, 2 Aug 2018 16:25:09 +1000
Subject: [PATCH 26/28] Bug 1480058 part 1: Expose states for
aria-selected/aria-multiselectable on XUL tab/tabs. r=surkov
MozReview-Commit-ID: JeV5vBffQIq
--HG--
extra : rebase_source : 3e6979e1e1995e62951250937d0c28f1128dcbac
---
.../tests/mochitest/states/test_aria.xul | 16 ++++++++++++++
accessible/xul/XULTabAccessible.cpp | 22 +++++++++++++++++++
accessible/xul/XULTabAccessible.h | 2 ++
3 files changed, 40 insertions(+)
diff --git a/accessible/tests/mochitest/states/test_aria.xul b/accessible/tests/mochitest/states/test_aria.xul
index b15cc7781569..f642ab1cf4a2 100644
--- a/accessible/tests/mochitest/states/test_aria.xul
+++ b/accessible/tests/mochitest/states/test_aria.xul
@@ -24,6 +24,14 @@
testStates("pressed_button", STATE_PRESSED, 0, STATE_CHECKABLE);
testStates("pressed_menu_button", STATE_PRESSED | STATE_HASPOPUP, 0, STATE_CHECKABLE);
+ testStates("tabs", STATE_MULTISELECTABLE);
+ // Make sure XUL selection works, since aria-selected defaults to false.
+ testStates("tab1", STATE_SELECTED);
+ // aria-selected="true".
+ testStates("tab2", STATE_SELECTED);
+ // Neither.
+ testStates("tab3", 0, 0, STATE_SELECTED);
+
SimpleTest.finish()
}
@@ -53,6 +61,14 @@
+
+
+
+
+
+
+
+
diff --git a/accessible/xul/XULTabAccessible.cpp b/accessible/xul/XULTabAccessible.cpp
index 5c2b099f939e..16ac5068a7d3 100644
--- a/accessible/xul/XULTabAccessible.cpp
+++ b/accessible/xul/XULTabAccessible.cpp
@@ -5,6 +5,7 @@
#include "XULTabAccessible.h"
+#include "ARIAMap.h"
#include "nsAccUtils.h"
#include "Relation.h"
#include "Role.h"
@@ -123,6 +124,17 @@ XULTabAccessible::RelationByType(RelationType aType) const
return rel;
}
+void
+XULTabAccessible::ApplyARIAState(uint64_t* aState) const
+{
+ HyperTextAccessibleWrap::ApplyARIAState(aState);
+ // XUL tab has an implicit ARIA role of tab, so support aria-selected.
+ // Don't use aria::MapToState because that will set the SELECTABLE state
+ // even if the tab is disabled.
+ if (nsAccUtils::IsARIASelected(this)) {
+ *aState |= states::SELECTED;
+ }
+}
////////////////////////////////////////////////////////////////////////////////
// XULTabsAccessible
@@ -159,6 +171,16 @@ XULTabsAccessible::NativeName(nsString& aName) const
return eNameOK;
}
+void
+XULTabsAccessible::ApplyARIAState(uint64_t* aState) const
+{
+ XULSelectControlAccessible::ApplyARIAState(aState);
+ // XUL tabs has an implicit ARIA role of tablist, so support
+ // aria-multiselectable.
+ MOZ_ASSERT(Elm());
+ aria::MapToState(aria::eARIAMultiSelectable, Elm(), aState);
+}
+
////////////////////////////////////////////////////////////////////////////////
// XULTabpanelsAccessible
diff --git a/accessible/xul/XULTabAccessible.h b/accessible/xul/XULTabAccessible.h
index 7ee132e7a9c4..b84035002af8 100644
--- a/accessible/xul/XULTabAccessible.h
+++ b/accessible/xul/XULTabAccessible.h
@@ -29,6 +29,7 @@ public:
virtual uint64_t NativeState() const override;
virtual uint64_t NativeInteractiveState() const override;
virtual Relation RelationByType(RelationType aType) const override;
+ virtual void ApplyARIAState(uint64_t* aState) const override;
// ActionAccessible
virtual uint8_t ActionCount() const override;
@@ -48,6 +49,7 @@ public:
// Accessible
virtual void Value(nsString& aValue) const override;
virtual a11y::role NativeRole() const override;
+ virtual void ApplyARIAState(uint64_t* aState) const override;
// ActionAccessible
virtual uint8_t ActionCount() const override;
From 46ba6df24976b5d78dca73ad16e832cf30961c88 Mon Sep 17 00:00:00 2001
From: James Teh
Date: Thu, 2 Aug 2018 16:27:18 +1000
Subject: [PATCH 27/28] Bug 1480058 part 2: Add
nsAccUtils::IsARIAMultiSelectable and make nsAccUtils::ISARIASelected const.
r=surkov
We need to be able to call these methods from const methods, so they must take a const Accessible*.
MozReview-Commit-ID: CDsWZG1ik31
--HG--
extra : rebase_source : 4721669afcd9101cb017361bd8f87fb8a860664a
---
accessible/base/nsAccUtils.cpp | 10 ++++------
accessible/base/nsAccUtils.h | 18 +++++++++++++++++-
2 files changed, 21 insertions(+), 7 deletions(-)
diff --git a/accessible/base/nsAccUtils.cpp b/accessible/base/nsAccUtils.cpp
index 275f88300266..78fd8bd7ee7f 100644
--- a/accessible/base/nsAccUtils.cpp
+++ b/accessible/base/nsAccUtils.cpp
@@ -244,13 +244,11 @@ nsAccUtils::GetSelectableContainer(Accessible* aAccessible, uint64_t aState)
}
bool
-nsAccUtils::IsARIASelected(Accessible* aAccessible)
+nsAccUtils::IsDOMAttrTrue(const Accessible* aAccessible, nsAtom* aAttr)
{
- if (!aAccessible->GetContent()->IsElement())
- return false;
- return aAccessible->GetContent()->AsElement()->
- AttrValueIs(kNameSpaceID_None, nsGkAtoms::aria_selected,
- nsGkAtoms::_true, eCaseMatters);
+ dom::Element* el = aAccessible->Elm();
+ return el && el->AttrValueIs(kNameSpaceID_None, aAttr, nsGkAtoms::_true,
+ eCaseMatters);
}
Accessible*
diff --git a/accessible/base/nsAccUtils.h b/accessible/base/nsAccUtils.h
index da80fc8a4724..bacbb5127e20 100644
--- a/accessible/base/nsAccUtils.h
+++ b/accessible/base/nsAccUtils.h
@@ -137,11 +137,27 @@ public:
static Accessible* TableFor(Accessible* aRow);
+ /**
+ * Return true if the DOM node of a given accessible has a given attribute
+ * with a value of "true".
+ */
+ static bool IsDOMAttrTrue(const Accessible* aAccessible, nsAtom* aAttr);
+
/**
* Return true if the DOM node of given accessible has aria-selected="true"
* attribute.
*/
- static bool IsARIASelected(Accessible* aAccessible);
+ static inline bool IsARIASelected(const Accessible* aAccessible) {
+ return IsDOMAttrTrue(aAccessible, nsGkAtoms::aria_selected);
+ }
+
+ /**
+ * Return true if the DOM node of given accessible has
+ * aria-multiselectable="true" attribute.
+ */
+ static inline bool IsARIAMultiSelectable(const Accessible* aAccessible) {
+ return IsDOMAttrTrue(aAccessible, nsGkAtoms::aria_multiselectable);
+ }
/**
* Converts the given coordinates to coordinates relative screen.
From 5a83999558459adf11d3f814de194d8db2b6017e Mon Sep 17 00:00:00 2001
From: James Teh
Date: Fri, 3 Aug 2018 13:31:43 +1000
Subject: [PATCH 28/28] Bug 1480058 part 3: Support accessible selection
retrieval methods for XUL tabs with aria-multiselectable. r=surkov
The XULSelectControlAccessible selection methods don't handle ARIA selection.
Therefore, if aria-multiselectable is set, use the base implementation of the selection retrieval methods.
We don't bother overriding the selection setting methods because implementations (e.g. browser tabs) don't support setting of aria-selected by the a11y engine and we still want to be able to set the primary selected item according to XUL.
Being able to retrieve multiple selection programmatically is far more important than being able to set it.
MozReview-Commit-ID: CmVp9KyieMY
--HG--
extra : rebase_source : e3fa93aad4726b322956babb5422dceebfa0fbb2
---
.../tests/mochitest/selectable/a11y.ini | 1 +
.../tests/mochitest/selectable/test_tabs.xul | 94 +++++++++++++++++++
accessible/xul/XULTabAccessible.cpp | 50 ++++++++++
accessible/xul/XULTabAccessible.h | 6 ++
4 files changed, 151 insertions(+)
create mode 100644 accessible/tests/mochitest/selectable/test_tabs.xul
diff --git a/accessible/tests/mochitest/selectable/a11y.ini b/accessible/tests/mochitest/selectable/a11y.ini
index 4fc11fee84fa..fcdd5b67a613 100644
--- a/accessible/tests/mochitest/selectable/a11y.ini
+++ b/accessible/tests/mochitest/selectable/a11y.ini
@@ -8,4 +8,5 @@ support-files =
[test_menu.xul]
[test_menulist.xul]
[test_select.html]
+[test_tabs.xul]
[test_tree.xul]
diff --git a/accessible/tests/mochitest/selectable/test_tabs.xul b/accessible/tests/mochitest/selectable/test_tabs.xul
new file mode 100644
index 000000000000..76820c98fddc
--- /dev/null
+++ b/accessible/tests/mochitest/selectable/test_tabs.xul
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Mozilla Bug 1480058
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/accessible/xul/XULTabAccessible.cpp b/accessible/xul/XULTabAccessible.cpp
index 16ac5068a7d3..68f4d7ae97d9 100644
--- a/accessible/xul/XULTabAccessible.cpp
+++ b/accessible/xul/XULTabAccessible.cpp
@@ -181,6 +181,56 @@ XULTabsAccessible::ApplyARIAState(uint64_t* aState) const
aria::MapToState(aria::eARIAMultiSelectable, Elm(), aState);
}
+// XUL tabs is a single selection control and doesn't allow ARIA selection.
+// However, if aria-multiselectable is used, it becomes a multiselectable
+// control, where both native and ARIA markup are used to set selection.
+// Therefore, if aria-multiselectable is set, use the base implementation of
+// the selection retrieval methods in order to support ARIA selection.
+// We don't bother overriding the selection setting methods because
+// current front-end code using XUL tabs doesn't support setting of
+// aria-selected by the a11y engine and we still want to be able to set the
+// primary selected item according to XUL.
+
+void
+XULTabsAccessible::SelectedItems(nsTArray* aItems)
+{
+ if (nsAccUtils::IsARIAMultiSelectable(this)) {
+ AccessibleWrap::SelectedItems(aItems);
+ } else {
+ XULSelectControlAccessible::SelectedItems(aItems);
+ }
+}
+
+Accessible*
+XULTabsAccessible::GetSelectedItem(uint32_t aIndex)
+{
+ if (nsAccUtils::IsARIAMultiSelectable(this)) {
+ return AccessibleWrap::GetSelectedItem(aIndex);
+ }
+
+ return XULSelectControlAccessible::GetSelectedItem(aIndex);
+}
+
+uint32_t
+XULTabsAccessible::SelectedItemCount()
+{
+ if (nsAccUtils::IsARIAMultiSelectable(this)) {
+ return AccessibleWrap::SelectedItemCount();
+ }
+
+ return XULSelectControlAccessible::SelectedItemCount();
+}
+
+bool
+XULTabsAccessible::IsItemSelected(uint32_t aIndex)
+{
+ if (nsAccUtils::IsARIAMultiSelectable(this)) {
+ return AccessibleWrap::IsItemSelected(aIndex);
+ }
+
+ return XULSelectControlAccessible::IsItemSelected(aIndex);
+}
+
////////////////////////////////////////////////////////////////////////////////
// XULTabpanelsAccessible
diff --git a/accessible/xul/XULTabAccessible.h b/accessible/xul/XULTabAccessible.h
index b84035002af8..db68b9502c79 100644
--- a/accessible/xul/XULTabAccessible.h
+++ b/accessible/xul/XULTabAccessible.h
@@ -54,6 +54,12 @@ public:
// ActionAccessible
virtual uint8_t ActionCount() const override;
+ // SelectAccessible
+ virtual void SelectedItems(nsTArray* aItems) override;
+ virtual uint32_t SelectedItemCount() override;
+ virtual Accessible* GetSelectedItem(uint32_t aIndex) override;
+ virtual bool IsItemSelected(uint32_t aIndex) override;
+
protected:
// Accessible
virtual ENameValueFlag NativeName(nsString& aName) const override;