зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to f-t
This commit is contained in:
Коммит
73ccc79fc3
2
CLOBBER
2
CLOBBER
|
@ -22,4 +22,4 @@
|
||||||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||||
# don't change CLOBBER for WebIDL changes any more.
|
# don't change CLOBBER for WebIDL changes any more.
|
||||||
|
|
||||||
Bug 1280590 - xpcshell failure in windows7
|
Bug 1302855 changed build system to fold browsercomps into xul
|
||||||
|
|
|
@ -291,14 +291,20 @@ EventTree::FindOrInsert(Accessible* aContainer)
|
||||||
AccMutationEvent* ev = node->mDependentEvents[idx];
|
AccMutationEvent* ev = node->mDependentEvents[idx];
|
||||||
if (ev->GetAccessible() == parent) {
|
if (ev->GetAccessible() == parent) {
|
||||||
#ifdef A11Y_LOG
|
#ifdef A11Y_LOG
|
||||||
if (logging::IsEnabledAll(logging::eEventTree |
|
if (logging::IsEnabled(logging::eEventTree)) {
|
||||||
logging::eVerbose)) {
|
|
||||||
logging::MsgBegin("EVENTS_TREE",
|
logging::MsgBegin("EVENTS_TREE",
|
||||||
"Rejecting node since contained by show/hide target");
|
"Rejecting node contained by show/hide");
|
||||||
logging::AccessibleInfo("Container", aContainer);
|
logging::AccessibleInfo("Node", aContainer);
|
||||||
logging::MsgEnd();
|
logging::MsgEnd();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
// If the node is rejected, then check if it has related hide event
|
||||||
|
// on stack, and if so, then connect it to the parent show event.
|
||||||
|
if (ev->IsShow()) {
|
||||||
|
AccShowEvent* showEv = downcast_accEvent(ev);
|
||||||
|
Controller(aContainer)->
|
||||||
|
WithdrawPrecedingEvents(&showEv->mPrecedingEvents);
|
||||||
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,18 +53,14 @@ StyleInfo::TextIndent(nsAString& aValue)
|
||||||
switch (styleCoord.GetUnit()) {
|
switch (styleCoord.GetUnit()) {
|
||||||
case eStyleUnit_Coord:
|
case eStyleUnit_Coord:
|
||||||
coordVal = styleCoord.GetCoordValue();
|
coordVal = styleCoord.GetCoordValue();
|
||||||
|
aValue.AppendFloat(nsPresContext::AppUnitsToFloatCSSPixels(coordVal));
|
||||||
|
aValue.AppendLiteral("px");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case eStyleUnit_Percent:
|
case eStyleUnit_Percent:
|
||||||
{
|
aValue.AppendFloat(styleCoord.GetPercentValue() * 100);
|
||||||
nsIFrame* frame = mElement->GetPrimaryFrame();
|
aValue.AppendLiteral("%");
|
||||||
MOZ_ASSERT(frame, "frame must be a valid pointer.");
|
|
||||||
nsIFrame* containerFrame = frame->GetContainingBlock();
|
|
||||||
nscoord percentageBase = containerFrame->GetContentRect().width;
|
|
||||||
coordVal = NSCoordSaturatingMultiply(percentageBase,
|
|
||||||
styleCoord.GetPercentValue());
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case eStyleUnit_Null:
|
case eStyleUnit_Null:
|
||||||
case eStyleUnit_Normal:
|
case eStyleUnit_Normal:
|
||||||
|
@ -79,11 +75,9 @@ StyleInfo::TextIndent(nsAString& aValue)
|
||||||
case eStyleUnit_Integer:
|
case eStyleUnit_Integer:
|
||||||
case eStyleUnit_Enumerated:
|
case eStyleUnit_Enumerated:
|
||||||
case eStyleUnit_Calc:
|
case eStyleUnit_Calc:
|
||||||
|
aValue.AppendLiteral("0px");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
aValue.AppendFloat(nsPresContext::AppUnitsToFloatCSSPixels(coordVal));
|
|
||||||
aValue.AppendLiteral("px");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -559,13 +559,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move 't9_c2_moved' node by aria-owns, and then move 't9_c3_moved' node
|
* Move 't9_c3_moved' node under 't9_c2_moved', and then move 't9_c2_moved'
|
||||||
* under 't9_c2_moved' (same as test9 but has different aria-owns
|
* node by aria-owns (same as test10 but has different aria-owns
|
||||||
* ordering), the eventing looks same way as in test9:
|
* ordering), the eventing looks same way as in test10:
|
||||||
* reorder for 't9_c1'
|
* reorder for 't9_c1'
|
||||||
* hide for 't9_c1_child'
|
* hide for 't9_c1_child'
|
||||||
* show for 't9_c2_moved'
|
* show for 't9_c2_moved'
|
||||||
* reorder for 't9_c2'
|
* reorder for 't9_c2'
|
||||||
|
* hide for 't9_c2_child'
|
||||||
* hide for 't9_c2_moved'
|
* hide for 't9_c2_moved'
|
||||||
* reorder for 't9_c3'
|
* reorder for 't9_c3'
|
||||||
* hide for 't9_c3_moved'
|
* hide for 't9_c3_moved'
|
||||||
|
@ -604,6 +605,51 @@
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move a node 't10_c3_moved' by aria-owns under a node 't10_c2_moved',
|
||||||
|
* moved by under 't10_1', so that the eventing looks this way:
|
||||||
|
* reorder for 't10_c1'
|
||||||
|
* hide for 't10_c1_child'
|
||||||
|
* show for 't10_c2_moved'
|
||||||
|
* reorder for 't10_c2'
|
||||||
|
* hide for 't10_c2_child'
|
||||||
|
* hide for 't10_c2_moved'
|
||||||
|
* reorder for 't10_c3'
|
||||||
|
* hide for 't10_c3_moved'
|
||||||
|
*
|
||||||
|
* The hide events for 't10_c2_moved' and 't10_c3_moved' should be delivered
|
||||||
|
* before the show event for 't10_c2_moved'.
|
||||||
|
*/
|
||||||
|
function test10()
|
||||||
|
{
|
||||||
|
this.eventSeq = [
|
||||||
|
new invokerChecker(EVENT_HIDE, getNode('t10_c1_child')),
|
||||||
|
new invokerChecker(EVENT_HIDE, getNode('t10_c2_moved')),
|
||||||
|
new invokerChecker(EVENT_HIDE, getNode('t10_c3_moved')),
|
||||||
|
new invokerChecker(EVENT_SHOW, getNode('t10_c2_moved')),
|
||||||
|
new invokerChecker(EVENT_REORDER, 't10_c1'),
|
||||||
|
new invokerChecker(EVENT_HIDE, getNode('t10_c2_child')),
|
||||||
|
new invokerChecker(EVENT_REORDER, 't10_c2'),
|
||||||
|
new invokerChecker(EVENT_REORDER, 't10_c3')
|
||||||
|
];
|
||||||
|
|
||||||
|
this.invoke = function test10_invoke()
|
||||||
|
{
|
||||||
|
// Remove child nodes from 't10_c1' and 't10_c2' containers to give
|
||||||
|
// the event tree a needed structure ('t10_c1' and 't10_c2' nodes go first
|
||||||
|
// in the event tree),
|
||||||
|
getNode('t10_c1_child').remove();
|
||||||
|
getNode('t10_c2_child').remove();
|
||||||
|
// then do aria-owns stuff.
|
||||||
|
getNode('t10_c1').setAttribute('aria-owns', 't10_c2_moved');
|
||||||
|
getNode('t10_c2_moved').setAttribute('aria-owns', 't10_c3_moved');
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getID = function test10_getID() {
|
||||||
|
return "Move a node by aria-owns into a node moved by aria-owns to left within the tree";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Do tests.
|
// Do tests.
|
||||||
|
|
||||||
|
@ -639,6 +685,7 @@
|
||||||
gQueue.push(new test7());
|
gQueue.push(new test7());
|
||||||
gQueue.push(new test8());
|
gQueue.push(new test8());
|
||||||
gQueue.push(new test9());
|
gQueue.push(new test9());
|
||||||
|
gQueue.push(new test10());
|
||||||
|
|
||||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||||
}
|
}
|
||||||
|
@ -757,5 +804,16 @@
|
||||||
<div id="t9_c3_moved"></div>
|
<div id="t9_c3_moved"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="t10">
|
||||||
|
<div id="t10_c1"><div id="t10_c1_child"></div></div>
|
||||||
|
<div id="t10_c2">
|
||||||
|
<div id="t10_c2_child"></div>
|
||||||
|
<div id="t10_c2_moved"></div>
|
||||||
|
</div>
|
||||||
|
<div id="t10_c3">
|
||||||
|
<div id="t10_c3_moved"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -361,8 +361,8 @@
|
||||||
function showHiddenParentOfVisibleChild()
|
function showHiddenParentOfVisibleChild()
|
||||||
{
|
{
|
||||||
this.eventSeq = [
|
this.eventSeq = [
|
||||||
new invokerChecker(EVENT_SHOW, getNode("c4_middle")),
|
|
||||||
new invokerChecker(EVENT_HIDE, getNode("c4_child")),
|
new invokerChecker(EVENT_HIDE, getNode("c4_child")),
|
||||||
|
new invokerChecker(EVENT_SHOW, getNode("c4_middle")),
|
||||||
new invokerChecker(EVENT_REORDER, getNode("c4"))
|
new invokerChecker(EVENT_REORDER, getNode("c4"))
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -80,16 +80,6 @@ static bool IsArg(const char* arg, const char* s)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A helper class which calls NS_LogInit/NS_LogTerm in its scope.
|
|
||||||
*/
|
|
||||||
class ScopedLogging
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ScopedLogging() { NS_LogInit(); }
|
|
||||||
~ScopedLogging() { NS_LogTerm(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
XRE_GetFileFromPathType XRE_GetFileFromPath;
|
XRE_GetFileFromPathType XRE_GetFileFromPath;
|
||||||
XRE_CreateAppDataType XRE_CreateAppData;
|
XRE_CreateAppDataType XRE_CreateAppData;
|
||||||
XRE_FreeAppDataType XRE_FreeAppData;
|
XRE_FreeAppDataType XRE_FreeAppData;
|
||||||
|
|
|
@ -59,6 +59,7 @@ skip-if = os == "linux" # Bug 1073339 - Investigate autocomplete test unreliabil
|
||||||
[browser_urlbarKeepStateAcrossTabSwitches.js]
|
[browser_urlbarKeepStateAcrossTabSwitches.js]
|
||||||
[browser_urlbarOneOffs.js]
|
[browser_urlbarOneOffs.js]
|
||||||
[browser_urlbarPrivateBrowsingWindowChange.js]
|
[browser_urlbarPrivateBrowsingWindowChange.js]
|
||||||
|
[browser_urlbarRaceWithTabs.js]
|
||||||
[browser_urlbarRevert.js]
|
[browser_urlbarRevert.js]
|
||||||
[browser_urlbarSearchSingleWordNotification.js]
|
[browser_urlbarSearchSingleWordNotification.js]
|
||||||
[browser_urlbarSearchSuggestions.js]
|
[browser_urlbarSearchSuggestions.js]
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
const kURL = "http://example.org/browser/browser/base/content/test/urlbar/dummy_page.html";
|
||||||
|
|
||||||
|
function* addBookmark(bookmark) {
|
||||||
|
if (bookmark.keyword) {
|
||||||
|
yield PlacesUtils.keywords.insert({
|
||||||
|
keyword: bookmark.keyword,
|
||||||
|
url: bookmark.url,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let bm = yield PlacesUtils.bookmarks.insert({
|
||||||
|
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||||
|
url: bookmark.url,
|
||||||
|
title: bookmark.title,
|
||||||
|
});
|
||||||
|
|
||||||
|
registerCleanupFunction(function* () {
|
||||||
|
yield PlacesUtils.bookmarks.remove(bm);
|
||||||
|
if (bookmark.keyword) {
|
||||||
|
yield PlacesUtils.keywords.remove(bookmark.keyword);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check that if the user hits enter and ctrl-t at the same time, we open the URL in the right tab.
|
||||||
|
*/
|
||||||
|
add_task(function* hitEnterLoadInRightTab() {
|
||||||
|
info("Opening new tab");
|
||||||
|
let oldTabCreatedPromise = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "TabOpen");
|
||||||
|
BrowserOpenTab();
|
||||||
|
let oldTab = (yield oldTabCreatedPromise).target;
|
||||||
|
let oldTabLoadedPromise = BrowserTestUtils.browserLoaded(oldTab.linkedBrowser, false, kURL);
|
||||||
|
oldTabLoadedPromise.then(() => info("Old tab loaded"));
|
||||||
|
let newTabCreatedPromise = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "TabOpen");
|
||||||
|
|
||||||
|
info("Creating bookmark and keyword");
|
||||||
|
yield addBookmark({title: "Test for keyword bookmark and URL", url: kURL, keyword: "urlbarkeyword"});
|
||||||
|
info("Filling URL bar, sending <return> and opening a tab");
|
||||||
|
gURLBar.value = "urlbarkeyword";
|
||||||
|
gURLBar.select();
|
||||||
|
EventUtils.sendKey("return");
|
||||||
|
BrowserOpenTab();
|
||||||
|
info("Waiting for new tab");
|
||||||
|
let newTab = (yield newTabCreatedPromise).target;
|
||||||
|
info("Created new tab; waiting for either tab to load");
|
||||||
|
let newTabLoadedPromise = BrowserTestUtils.browserLoaded(newTab.linkedBrowser, false, kURL);
|
||||||
|
newTabLoadedPromise.then(() => info("New tab loaded"));
|
||||||
|
yield Promise.race([newTabLoadedPromise, oldTabLoadedPromise]);
|
||||||
|
is(newTab.linkedBrowser.currentURI.spec, "about:newtab", "New tab still has about:newtab");
|
||||||
|
is(oldTab.linkedBrowser.currentURI.spec, kURL, "Old tab loaded URL");
|
||||||
|
info("Closing new tab");
|
||||||
|
yield BrowserTestUtils.removeTab(newTab);
|
||||||
|
info("Closing old tab");
|
||||||
|
yield BrowserTestUtils.removeTab(oldTab);
|
||||||
|
info("Finished");
|
||||||
|
});
|
|
@ -399,6 +399,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
let mayInheritPrincipal = false;
|
let mayInheritPrincipal = false;
|
||||||
let postData = null;
|
let postData = null;
|
||||||
|
let browser = gBrowser.selectedBrowser;
|
||||||
let lastLocationChange = gBrowser.selectedBrowser.lastLocationChange;
|
let lastLocationChange = gBrowser.selectedBrowser.lastLocationChange;
|
||||||
let matchLastLocationChange = true;
|
let matchLastLocationChange = true;
|
||||||
|
|
||||||
|
@ -435,7 +436,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this._loadURL(url, postData, where, openUILinkParams,
|
this._loadURL(url, browser, postData, where, openUILinkParams,
|
||||||
matchLastLocationChange, mayInheritPrincipal);
|
matchLastLocationChange, mayInheritPrincipal);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -456,7 +457,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
[url, postData] =
|
[url, postData] =
|
||||||
this._recordSearchEngineLoad(selectedOneOff.engine, value,
|
this._recordSearchEngineLoad(selectedOneOff.engine, value,
|
||||||
event, where, openUILinkParams);
|
event, where, openUILinkParams);
|
||||||
this._loadURL(url, postData, where, openUILinkParams,
|
this._loadURL(url, browser, postData, where, openUILinkParams,
|
||||||
matchLastLocationChange, mayInheritPrincipal);
|
matchLastLocationChange, mayInheritPrincipal);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -466,8 +467,8 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
getShortcutOrURIAndPostData(url).then(({url, postData, mayInheritPrincipal}) => {
|
getShortcutOrURIAndPostData(url).then(({url, postData, mayInheritPrincipal}) => {
|
||||||
if (url) {
|
if (url) {
|
||||||
matchLastLocationChange =
|
matchLastLocationChange =
|
||||||
lastLocationChange == gBrowser.selectedBrowser.lastLocationChange;
|
lastLocationChange == browser.lastLocationChange;
|
||||||
this._loadURL(url, postData, where, openUILinkParams,
|
this._loadURL(url, browser, postData, where, openUILinkParams,
|
||||||
matchLastLocationChange, mayInheritPrincipal);
|
matchLastLocationChange, mayInheritPrincipal);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -487,6 +488,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
<method name="_loadURL">
|
<method name="_loadURL">
|
||||||
<parameter name="url"/>
|
<parameter name="url"/>
|
||||||
|
<parameter name="browser"/>
|
||||||
<parameter name="postData"/>
|
<parameter name="postData"/>
|
||||||
<parameter name="openUILinkWhere"/>
|
<parameter name="openUILinkWhere"/>
|
||||||
<parameter name="openUILinkParams"/>
|
<parameter name="openUILinkParams"/>
|
||||||
|
@ -494,9 +496,9 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
<parameter name="mayInheritPrincipal"/>
|
<parameter name="mayInheritPrincipal"/>
|
||||||
<body><![CDATA[
|
<body><![CDATA[
|
||||||
this.value = url;
|
this.value = url;
|
||||||
gBrowser.userTypedValue = url;
|
browser.userTypedValue = url;
|
||||||
if (gInitialPages.includes(url)) {
|
if (gInitialPages.includes(url)) {
|
||||||
gBrowser.selectedBrowser.initialPageLoadedFromURLBar = url;
|
browser.initialPageLoadedFromURLBar = url;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
addToUrlbarHistory(url);
|
addToUrlbarHistory(url);
|
||||||
|
@ -509,6 +511,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
let params = {
|
let params = {
|
||||||
postData: postData,
|
postData: postData,
|
||||||
allowThirdPartyFixup: true,
|
allowThirdPartyFixup: true,
|
||||||
|
currentBrowser: browser,
|
||||||
};
|
};
|
||||||
if (openUILinkWhere == "current") {
|
if (openUILinkWhere == "current") {
|
||||||
params.indicateErrorPageLoad = true;
|
params.indicateErrorPageLoad = true;
|
||||||
|
@ -528,7 +531,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
// Focus the content area before triggering loads, since if the load
|
// Focus the content area before triggering loads, since if the load
|
||||||
// occurs in a new tab, we want focus to be restored to the content
|
// occurs in a new tab, we want focus to be restored to the content
|
||||||
// area when the current tab is re-selected.
|
// area when the current tab is re-selected.
|
||||||
gBrowser.selectedBrowser.focus();
|
browser.focus();
|
||||||
|
|
||||||
if (openUILinkWhere == "current" && !matchLastLocationChange) {
|
if (openUILinkWhere == "current" && !matchLastLocationChange) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -226,6 +226,19 @@ function openLinkIn(url, where, params) {
|
||||||
var aForceAboutBlankViewerInCurrent =
|
var aForceAboutBlankViewerInCurrent =
|
||||||
params.forceAboutBlankViewerInCurrent;
|
params.forceAboutBlankViewerInCurrent;
|
||||||
|
|
||||||
|
// Establish a window in which we're running this code.
|
||||||
|
var w = getTopWin();
|
||||||
|
|
||||||
|
if ((where == "tab" || where == "tabshifted") &&
|
||||||
|
w && !w.toolbar.visible) {
|
||||||
|
w = getTopWin(true);
|
||||||
|
aRelatedToCurrent = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can only do this after we're sure of what |w| will be the rest of this function.
|
||||||
|
// Note that if |w| is null we might have no current browser (we'll open a new window).
|
||||||
|
var aCurrentBrowser = params.currentBrowser || (w && w.gBrowser.selectedBrowser);
|
||||||
|
|
||||||
if (where == "save") {
|
if (where == "save") {
|
||||||
// TODO(1073187): propagate referrerPolicy.
|
// TODO(1073187): propagate referrerPolicy.
|
||||||
|
|
||||||
|
@ -244,13 +257,6 @@ function openLinkIn(url, where, params) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var w = getTopWin();
|
|
||||||
if ((where == "tab" || where == "tabshifted") &&
|
|
||||||
w && !w.toolbar.visible) {
|
|
||||||
w = getTopWin(true);
|
|
||||||
aRelatedToCurrent = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!w || where == "window") {
|
if (!w || where == "window") {
|
||||||
// This propagates to window.arguments.
|
// This propagates to window.arguments.
|
||||||
var sa = Cc["@mozilla.org/supports-array;1"].
|
var sa = Cc["@mozilla.org/supports-array;1"].
|
||||||
|
@ -318,12 +324,17 @@ function openLinkIn(url, where, params) {
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (where == "current" && w.gBrowser.selectedTab.pinned &&
|
// NB: we avoid using |w| here because in the 'popup window' case,
|
||||||
|
// if we pass a currentBrowser param |w.gBrowser| might not be the
|
||||||
|
// tabbrowser that contains |aCurrentBrowser|. We really only care
|
||||||
|
// about the tab linked to |aCurrentBrowser|.
|
||||||
|
let tab = aCurrentBrowser.ownerGlobal.gBrowser.getTabForBrowser(aCurrentBrowser);
|
||||||
|
if (where == "current" && tab.pinned &&
|
||||||
!aAllowPinnedTabHostChange) {
|
!aAllowPinnedTabHostChange) {
|
||||||
try {
|
try {
|
||||||
// nsIURI.host can throw for non-nsStandardURL nsIURIs.
|
// nsIURI.host can throw for non-nsStandardURL nsIURIs.
|
||||||
if (!uriObj || (!uriObj.schemeIs("javascript") &&
|
if (!uriObj || (!uriObj.schemeIs("javascript") &&
|
||||||
w.gBrowser.currentURI.host != uriObj.host)) {
|
aCurrentBrowser.currentURI.host != uriObj.host)) {
|
||||||
where = "tab";
|
where = "tab";
|
||||||
loadInBackground = false;
|
loadInBackground = false;
|
||||||
}
|
}
|
||||||
|
@ -365,7 +376,7 @@ function openLinkIn(url, where, params) {
|
||||||
w.gBrowser.selectedBrowser.createAboutBlankContentViewer(aPrincipal);
|
w.gBrowser.selectedBrowser.createAboutBlankContentViewer(aPrincipal);
|
||||||
}
|
}
|
||||||
|
|
||||||
w.gBrowser.loadURIWithFlags(url, {
|
aCurrentBrowser.loadURIWithFlags(url, {
|
||||||
flags: flags,
|
flags: flags,
|
||||||
referrerURI: aNoReferrer ? null : aReferrerURI,
|
referrerURI: aNoReferrer ? null : aReferrerURI,
|
||||||
referrerPolicy: aReferrerPolicy,
|
referrerPolicy: aReferrerPolicy,
|
||||||
|
@ -394,7 +405,7 @@ function openLinkIn(url, where, params) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
w.gBrowser.selectedBrowser.focus();
|
aCurrentBrowser.focus();
|
||||||
|
|
||||||
if (!loadInBackground && w.isBlankPageURL(url)) {
|
if (!loadInBackground && w.isBlankPageURL(url)) {
|
||||||
w.focusAndSelectUrlBar();
|
w.focusAndSelectUrlBar();
|
||||||
|
|
|
@ -12,7 +12,8 @@ SOURCES += [
|
||||||
'nsModule.cpp',
|
'nsModule.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
XPCOMBinaryComponent('browsercomps')
|
Library('browsercomps')
|
||||||
|
FINAL_LIBRARY = 'xul'
|
||||||
|
|
||||||
LOCAL_INCLUDES += [
|
LOCAL_INCLUDES += [
|
||||||
'../about',
|
'../about',
|
||||||
|
@ -21,22 +22,3 @@ LOCAL_INCLUDES += [
|
||||||
'../migration',
|
'../migration',
|
||||||
'../shell',
|
'../shell',
|
||||||
]
|
]
|
||||||
|
|
||||||
if CONFIG['OS_ARCH'] == 'WINNT':
|
|
||||||
OS_LIBS += [
|
|
||||||
'esent',
|
|
||||||
'netapi32',
|
|
||||||
'ole32',
|
|
||||||
'shell32',
|
|
||||||
'shlwapi',
|
|
||||||
'version',
|
|
||||||
]
|
|
||||||
DELAYLOAD_DLLS += [
|
|
||||||
'esent.dll',
|
|
||||||
'netapi32.dll',
|
|
||||||
]
|
|
||||||
|
|
||||||
# Mac: Need to link with CoreFoundation for Mac Migrators (PList reading code)
|
|
||||||
# GTK2: Need to link with glib for GNOME shell service
|
|
||||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('cocoa', 'gtk2', 'gtk3'):
|
|
||||||
OS_LIBS += CONFIG['TK_LIBS']
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "nsDirectoryServiceUtils.h"
|
#include "nsDirectoryServiceUtils.h"
|
||||||
#include "mozilla/ModuleUtils.h"
|
#include "mozilla/ModuleUtils.h"
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
#include "nsStringAPI.h"
|
#include "nsString.h"
|
||||||
#include "nsXULAppAPI.h"
|
#include "nsXULAppAPI.h"
|
||||||
#include "nsIPrefLocalizedString.h"
|
#include "nsIPrefLocalizedString.h"
|
||||||
|
|
||||||
|
|
|
@ -185,9 +185,15 @@ IsDocumentElement(const char *start, const char* end)
|
||||||
static bool
|
static bool
|
||||||
ContainsTopLevelSubstring(nsACString& dataString, const char *substring)
|
ContainsTopLevelSubstring(nsACString& dataString, const char *substring)
|
||||||
{
|
{
|
||||||
int32_t offset = dataString.Find(substring);
|
nsACString::const_iterator start, end;
|
||||||
if (offset == -1)
|
dataString.BeginReading(start);
|
||||||
|
dataString.EndReading(end);
|
||||||
|
|
||||||
|
if (!FindInReadable(nsCString(substring), start, end)){
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto offset = start.get() - dataString.Data();
|
||||||
|
|
||||||
const char *begin = dataString.BeginReading();
|
const char *begin = dataString.BeginReading();
|
||||||
|
|
||||||
|
@ -312,9 +318,10 @@ nsFeedSniffer::GetMIMETypeFromContent(nsIRequest* request,
|
||||||
|
|
||||||
// RSS 1.0
|
// RSS 1.0
|
||||||
if (!isFeed) {
|
if (!isFeed) {
|
||||||
|
bool foundNS_RDF = FindInReadable(NS_LITERAL_CSTRING(NS_RDF), dataString);
|
||||||
|
bool foundNS_RSS = FindInReadable(NS_LITERAL_CSTRING(NS_RSS), dataString);
|
||||||
isFeed = ContainsTopLevelSubstring(dataString, "<rdf:RDF") &&
|
isFeed = ContainsTopLevelSubstring(dataString, "<rdf:RDF") &&
|
||||||
dataString.Find(NS_RDF) != -1 &&
|
foundNS_RDF && foundNS_RSS;
|
||||||
dataString.Find(NS_RSS) != -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we sniffed a feed, coerce our internal type
|
// If we sniffed a feed, coerce our internal type
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
#include "nsIContentSniffer.h"
|
#include "nsIContentSniffer.h"
|
||||||
#include "nsIStreamListener.h"
|
#include "nsIStreamListener.h"
|
||||||
#include "nsStringAPI.h"
|
#include "nsString.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
|
|
||||||
class nsFeedSniffer final : public nsIContentSniffer,
|
class nsFeedSniffer final : public nsIContentSniffer,
|
||||||
|
|
|
@ -9,9 +9,10 @@
|
||||||
|
|
||||||
#include "nsArrayEnumerator.h"
|
#include "nsArrayEnumerator.h"
|
||||||
#include "nsCOMArray.h"
|
#include "nsCOMArray.h"
|
||||||
|
#include "nsIURI.h"
|
||||||
#include "nsIVariant.h"
|
#include "nsIVariant.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
#include "nsStringAPI.h"
|
#include "nsString.h"
|
||||||
#include "nsWindowsMigrationUtils.h"
|
#include "nsWindowsMigrationUtils.h"
|
||||||
#include "prtime.h"
|
#include "prtime.h"
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include "nsDirectoryServiceDefs.h"
|
#include "nsDirectoryServiceDefs.h"
|
||||||
#include "nsIPrefService.h"
|
#include "nsIPrefService.h"
|
||||||
#include "prenv.h"
|
#include "prenv.h"
|
||||||
#include "nsStringAPI.h"
|
#include "nsString.h"
|
||||||
#include "nsIGConfService.h"
|
#include "nsIGConfService.h"
|
||||||
#include "nsIGIOService.h"
|
#include "nsIGIOService.h"
|
||||||
#include "nsIGSettingsService.h"
|
#include "nsIGSettingsService.h"
|
||||||
|
@ -70,16 +70,16 @@ static const MimeTypeAssociation appTypes[] = {
|
||||||
// GConf registry key constants
|
// GConf registry key constants
|
||||||
#define DG_BACKGROUND "/desktop/gnome/background"
|
#define DG_BACKGROUND "/desktop/gnome/background"
|
||||||
|
|
||||||
static const char kDesktopImageKey[] = DG_BACKGROUND "/picture_filename";
|
#define kDesktopImageKey DG_BACKGROUND "/picture_filename"
|
||||||
static const char kDesktopOptionsKey[] = DG_BACKGROUND "/picture_options";
|
#define kDesktopOptionsKey DG_BACKGROUND "/picture_options"
|
||||||
static const char kDesktopDrawBGKey[] = DG_BACKGROUND "/draw_background";
|
#define kDesktopDrawBGKey DG_BACKGROUND "/draw_background"
|
||||||
static const char kDesktopColorKey[] = DG_BACKGROUND "/primary_color";
|
#define kDesktopColorKey DG_BACKGROUND "/primary_color"
|
||||||
|
|
||||||
static const char kDesktopBGSchema[] = "org.gnome.desktop.background";
|
#define kDesktopBGSchema "org.gnome.desktop.background"
|
||||||
static const char kDesktopImageGSKey[] = "picture-uri";
|
#define kDesktopImageGSKey "picture-uri"
|
||||||
static const char kDesktopOptionGSKey[] = "picture-options";
|
#define kDesktopOptionGSKey "picture-options"
|
||||||
static const char kDesktopDrawBGGSKey[] = "draw-background";
|
#define kDesktopDrawBGGSKey "draw-background"
|
||||||
static const char kDesktopColorGSKey[] = "primary-color";
|
#define kDesktopColorGSKey "primary-color"
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsGNOMEShellService::Init()
|
nsGNOMEShellService::Init()
|
||||||
|
@ -508,7 +508,8 @@ static void
|
||||||
ColorToCString(uint32_t aColor, nsCString& aResult)
|
ColorToCString(uint32_t aColor, nsCString& aResult)
|
||||||
{
|
{
|
||||||
// The #rrrrggggbbbb format is used to match gdk_color_to_string()
|
// The #rrrrggggbbbb format is used to match gdk_color_to_string()
|
||||||
char *buf = aResult.BeginWriting(13);
|
aResult.SetLength(13);
|
||||||
|
char *buf = aResult.BeginWriting();
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#define nsgnomeshellservice_h____
|
#define nsgnomeshellservice_h____
|
||||||
|
|
||||||
#include "nsIGNOMEShellService.h"
|
#include "nsIGNOMEShellService.h"
|
||||||
#include "nsStringAPI.h"
|
#include "nsString.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
|
|
||||||
class nsGNOMEShellService final : public nsIGNOMEShellService
|
class nsGNOMEShellService final : public nsIGNOMEShellService
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "nsIProperties.h"
|
#include "nsIProperties.h"
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
#include "nsShellService.h"
|
#include "nsShellService.h"
|
||||||
#include "nsStringAPI.h"
|
#include "nsString.h"
|
||||||
#include "nsIDocShell.h"
|
#include "nsIDocShell.h"
|
||||||
#include "nsILoadContext.h"
|
#include "nsILoadContext.h"
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "nsIDOMElement.h"
|
#include "nsIDOMElement.h"
|
||||||
#include "nsIDOMHTMLImageElement.h"
|
#include "nsIDOMHTMLImageElement.h"
|
||||||
#include "nsIImageLoadingContent.h"
|
#include "nsIImageLoadingContent.h"
|
||||||
|
#include "nsIOutputStream.h"
|
||||||
#include "nsIPrefService.h"
|
#include "nsIPrefService.h"
|
||||||
#include "nsIPrefLocalizedString.h"
|
#include "nsIPrefLocalizedString.h"
|
||||||
#include "nsIServiceManager.h"
|
#include "nsIServiceManager.h"
|
||||||
|
@ -465,7 +466,7 @@ nsWindowsShellService::IsDefaultBrowser(bool aStartupCheck,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = ::RegOpenKeyExW(HKEY_CLASSES_ROOT, PromiseFlatString(keyName).get(),
|
res = ::RegOpenKeyExW(HKEY_CLASSES_ROOT, keyName.get(),
|
||||||
0, KEY_SET_VALUE, &theKey);
|
0, KEY_SET_VALUE, &theKey);
|
||||||
if (REG_FAILED(res)) {
|
if (REG_FAILED(res)) {
|
||||||
// If updating the open command fails try to update it using the helper
|
// If updating the open command fails try to update it using the helper
|
||||||
|
@ -474,10 +475,9 @@ nsWindowsShellService::IsDefaultBrowser(bool aStartupCheck,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
const nsString &flatValue = PromiseFlatString(valueData);
|
|
||||||
res = ::RegSetValueExW(theKey, L"", 0, REG_SZ,
|
res = ::RegSetValueExW(theKey, L"", 0, REG_SZ,
|
||||||
(const BYTE *) flatValue.get(),
|
(const BYTE *) valueData.get(),
|
||||||
(flatValue.Length() + 1) * sizeof(char16_t));
|
(valueData.Length() + 1) * sizeof(char16_t));
|
||||||
// Close the key that was created.
|
// Close the key that was created.
|
||||||
::RegCloseKey(theKey);
|
::RegCloseKey(theKey);
|
||||||
if (REG_FAILED(res)) {
|
if (REG_FAILED(res)) {
|
||||||
|
@ -529,9 +529,8 @@ nsWindowsShellService::IsDefaultBrowser(bool aStartupCheck,
|
||||||
if (REG_FAILED(res) || char16_t('\0') != *currValue) {
|
if (REG_FAILED(res) || char16_t('\0') != *currValue) {
|
||||||
// Key wasn't set or was set to something other than our registry entry.
|
// Key wasn't set or was set to something other than our registry entry.
|
||||||
// Delete the key along with all of its childrean and then recreate it.
|
// Delete the key along with all of its childrean and then recreate it.
|
||||||
const nsString &flatName = PromiseFlatString(keyName);
|
::SHDeleteKeyW(HKEY_CURRENT_USER, keyName.get());
|
||||||
::SHDeleteKeyW(HKEY_CURRENT_USER, flatName.get());
|
res = ::RegCreateKeyExW(HKEY_CURRENT_USER, keyName.get(), 0, nullptr,
|
||||||
res = ::RegCreateKeyExW(HKEY_CURRENT_USER, flatName.get(), 0, nullptr,
|
|
||||||
REG_OPTION_NON_VOLATILE, KEY_SET_VALUE,
|
REG_OPTION_NON_VOLATILE, KEY_SET_VALUE,
|
||||||
nullptr, &theKey, nullptr);
|
nullptr, &theKey, nullptr);
|
||||||
if (REG_FAILED(res)) {
|
if (REG_FAILED(res)) {
|
||||||
|
@ -583,10 +582,9 @@ nsWindowsShellService::IsDefaultBrowser(bool aStartupCheck,
|
||||||
|
|
||||||
NS_ConvertUTF8toUTF16 valueData(VAL_OPEN);
|
NS_ConvertUTF8toUTF16 valueData(VAL_OPEN);
|
||||||
valueData.Replace(offset, 9, appLongPath);
|
valueData.Replace(offset, 9, appLongPath);
|
||||||
const nsString &flatValue = PromiseFlatString(valueData);
|
|
||||||
res = ::RegSetValueExW(theKey, L"", 0, REG_SZ,
|
res = ::RegSetValueExW(theKey, L"", 0, REG_SZ,
|
||||||
(const BYTE *) flatValue.get(),
|
(const BYTE *) valueData.get(),
|
||||||
(flatValue.Length() + 1) * sizeof(char16_t));
|
(valueData.Length() + 1) * sizeof(char16_t));
|
||||||
// Close the key that was created.
|
// Close the key that was created.
|
||||||
::RegCloseKey(theKey);
|
::RegCloseKey(theKey);
|
||||||
// If updating the FTP protocol handlers shell open command fails try to
|
// If updating the FTP protocol handlers shell open command fails try to
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#define nswindowsshellservice_h____
|
#define nswindowsshellservice_h____
|
||||||
|
|
||||||
#include "nscore.h"
|
#include "nscore.h"
|
||||||
#include "nsStringAPI.h"
|
#include "nsString.h"
|
||||||
#include "nsIWindowsShellService.h"
|
#include "nsIWindowsShellService.h"
|
||||||
#include "nsITimer.h"
|
#include "nsITimer.h"
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,6 @@
|
||||||
@RESPATH@/browser/components/prebuilt-interfaces.manifest
|
@RESPATH@/browser/components/prebuilt-interfaces.manifest
|
||||||
@RESPATH@/browser/components/interfaces.xpt
|
@RESPATH@/browser/components/interfaces.xpt
|
||||||
#endif
|
#endif
|
||||||
@RESPATH@/browser/components/components.manifest
|
|
||||||
@RESPATH@/components/alerts.xpt
|
@RESPATH@/components/alerts.xpt
|
||||||
#ifdef ACCESSIBILITY
|
#ifdef ACCESSIBILITY
|
||||||
#ifdef XP_WIN32
|
#ifdef XP_WIN32
|
||||||
|
@ -445,7 +444,6 @@
|
||||||
@RESPATH@/browser/components/nsSessionStore.js
|
@RESPATH@/browser/components/nsSessionStore.js
|
||||||
@RESPATH@/components/nsURLFormatter.manifest
|
@RESPATH@/components/nsURLFormatter.manifest
|
||||||
@RESPATH@/components/nsURLFormatter.js
|
@RESPATH@/components/nsURLFormatter.js
|
||||||
@RESPATH@/browser/components/@DLL_PREFIX@browsercomps@DLL_SUFFIX@
|
|
||||||
@RESPATH@/components/txEXSLTRegExFunctions.manifest
|
@RESPATH@/components/txEXSLTRegExFunctions.manifest
|
||||||
@RESPATH@/components/txEXSLTRegExFunctions.js
|
@RESPATH@/components/txEXSLTRegExFunctions.js
|
||||||
@RESPATH@/components/toolkitplaces.manifest
|
@RESPATH@/components/toolkitplaces.manifest
|
||||||
|
|
|
@ -8,6 +8,7 @@ configobj.pth:python/configobj
|
||||||
jsmin.pth:python/jsmin
|
jsmin.pth:python/jsmin
|
||||||
mach.pth:python/mach
|
mach.pth:python/mach
|
||||||
mozbuild.pth:python/mozbuild
|
mozbuild.pth:python/mozbuild
|
||||||
|
mozversioncontrol.pth:python/mozversioncontrol
|
||||||
mozlint.pth:python/mozlint
|
mozlint.pth:python/mozlint
|
||||||
pymake.pth:build/pymake
|
pymake.pth:build/pymake
|
||||||
optional:setup.py:python/psutil:build_ext:--inplace
|
optional:setup.py:python/psutil:build_ext:--inplace
|
||||||
|
|
|
@ -923,8 +923,8 @@ nsScriptSecurityManager::CheckLoadURIFlags(nsIURI *aSourceURI,
|
||||||
if (hasFlags) {
|
if (hasFlags) {
|
||||||
// Allow domains that were whitelisted in the prefs. In 99.9% of cases,
|
// Allow domains that were whitelisted in the prefs. In 99.9% of cases,
|
||||||
// this array is empty.
|
// this array is empty.
|
||||||
for (size_t i = 0; i < mFileURIWhitelist.Length(); ++i) {
|
for (nsIURI* uri : EnsureFileURIWhitelist()) {
|
||||||
if (EqualOrSubdomain(aSourceURI, mFileURIWhitelist[i])) {
|
if (EqualOrSubdomain(aSourceURI, uri)) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1459,38 +1459,7 @@ nsScriptSecurityManager::ScriptSecurityPrefChanged()
|
||||||
Preferences::GetBool(sJSEnabledPrefName, mIsJavaScriptEnabled);
|
Preferences::GetBool(sJSEnabledPrefName, mIsJavaScriptEnabled);
|
||||||
sStrictFileOriginPolicy =
|
sStrictFileOriginPolicy =
|
||||||
Preferences::GetBool(sFileOriginPolicyPrefName, false);
|
Preferences::GetBool(sFileOriginPolicyPrefName, false);
|
||||||
|
mFileURIWhitelist.reset();
|
||||||
//
|
|
||||||
// Rebuild the set of principals for which we allow file:// URI loads. This
|
|
||||||
// implements a small subset of an old pref-based CAPS people that people
|
|
||||||
// have come to depend on. See bug 995943.
|
|
||||||
//
|
|
||||||
|
|
||||||
mFileURIWhitelist.Clear();
|
|
||||||
auto policies = mozilla::Preferences::GetCString("capability.policy.policynames");
|
|
||||||
for (uint32_t base = SkipPast<IsWhitespaceOrComma>(policies, 0), bound = 0;
|
|
||||||
base < policies.Length();
|
|
||||||
base = SkipPast<IsWhitespaceOrComma>(policies, bound))
|
|
||||||
{
|
|
||||||
// Grab the current policy name.
|
|
||||||
bound = SkipUntil<IsWhitespaceOrComma>(policies, base);
|
|
||||||
auto policyName = Substring(policies, base, bound - base);
|
|
||||||
|
|
||||||
// Figure out if this policy allows loading file:// URIs. If not, we can skip it.
|
|
||||||
nsCString checkLoadURIPrefName = NS_LITERAL_CSTRING("capability.policy.") +
|
|
||||||
policyName +
|
|
||||||
NS_LITERAL_CSTRING(".checkloaduri.enabled");
|
|
||||||
if (!Preferences::GetString(checkLoadURIPrefName.get()).LowerCaseEqualsLiteral("allaccess")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Grab the list of domains associated with this policy.
|
|
||||||
nsCString domainPrefName = NS_LITERAL_CSTRING("capability.policy.") +
|
|
||||||
policyName +
|
|
||||||
NS_LITERAL_CSTRING(".sites");
|
|
||||||
auto siteList = Preferences::GetCString(domainPrefName.get());
|
|
||||||
AddSitesToFileURIWhitelist(siteList);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1516,7 +1485,7 @@ nsScriptSecurityManager::AddSitesToFileURIWhitelist(const nsCString& aSiteList)
|
||||||
nsCOMPtr<nsIURI> uri;
|
nsCOMPtr<nsIURI> uri;
|
||||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), site, nullptr, nullptr, sIOService);
|
nsresult rv = NS_NewURI(getter_AddRefs(uri), site, nullptr, nullptr, sIOService);
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
mFileURIWhitelist.AppendElement(uri);
|
mFileURIWhitelist.ref().AppendElement(uri);
|
||||||
} else {
|
} else {
|
||||||
nsCOMPtr<nsIConsoleService> console(do_GetService("@mozilla.org/consoleservice;1"));
|
nsCOMPtr<nsIConsoleService> console(do_GetService("@mozilla.org/consoleservice;1"));
|
||||||
if (console) {
|
if (console) {
|
||||||
|
@ -1676,3 +1645,45 @@ nsScriptSecurityManager::PolicyAllowsScript(nsIURI* aURI, bool *aRv)
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const nsTArray<nsCOMPtr<nsIURI>>&
|
||||||
|
nsScriptSecurityManager::EnsureFileURIWhitelist()
|
||||||
|
{
|
||||||
|
if (mFileURIWhitelist.isSome()) {
|
||||||
|
return mFileURIWhitelist.ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Rebuild the set of principals for which we allow file:// URI loads. This
|
||||||
|
// implements a small subset of an old pref-based CAPS people that people
|
||||||
|
// have come to depend on. See bug 995943.
|
||||||
|
//
|
||||||
|
|
||||||
|
mFileURIWhitelist.emplace();
|
||||||
|
auto policies = mozilla::Preferences::GetCString("capability.policy.policynames");
|
||||||
|
for (uint32_t base = SkipPast<IsWhitespaceOrComma>(policies, 0), bound = 0;
|
||||||
|
base < policies.Length();
|
||||||
|
base = SkipPast<IsWhitespaceOrComma>(policies, bound))
|
||||||
|
{
|
||||||
|
// Grab the current policy name.
|
||||||
|
bound = SkipUntil<IsWhitespaceOrComma>(policies, base);
|
||||||
|
auto policyName = Substring(policies, base, bound - base);
|
||||||
|
|
||||||
|
// Figure out if this policy allows loading file:// URIs. If not, we can skip it.
|
||||||
|
nsCString checkLoadURIPrefName = NS_LITERAL_CSTRING("capability.policy.") +
|
||||||
|
policyName +
|
||||||
|
NS_LITERAL_CSTRING(".checkloaduri.enabled");
|
||||||
|
if (!Preferences::GetString(checkLoadURIPrefName.get()).LowerCaseEqualsLiteral("allaccess")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grab the list of domains associated with this policy.
|
||||||
|
nsCString domainPrefName = NS_LITERAL_CSTRING("capability.policy.") +
|
||||||
|
policyName +
|
||||||
|
NS_LITERAL_CSTRING(".sites");
|
||||||
|
auto siteList = Preferences::GetCString(domainPrefName.get());
|
||||||
|
AddSitesToFileURIWhitelist(siteList);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mFileURIWhitelist.ref();
|
||||||
|
}
|
||||||
|
|
|
@ -124,10 +124,18 @@ private:
|
||||||
CheckLoadURIFlags(nsIURI* aSourceURI, nsIURI* aTargetURI, nsIURI* aSourceBaseURI,
|
CheckLoadURIFlags(nsIURI* aSourceURI, nsIURI* aTargetURI, nsIURI* aSourceBaseURI,
|
||||||
nsIURI* aTargetBaseURI, uint32_t aFlags);
|
nsIURI* aTargetBaseURI, uint32_t aFlags);
|
||||||
|
|
||||||
|
// Returns the file URI whitelist, initializing it if it has not been
|
||||||
|
// initialized.
|
||||||
|
const nsTArray<nsCOMPtr<nsIURI>>& EnsureFileURIWhitelist();
|
||||||
|
|
||||||
nsCOMPtr<nsIPrincipal> mSystemPrincipal;
|
nsCOMPtr<nsIPrincipal> mSystemPrincipal;
|
||||||
bool mPrefInitialized;
|
bool mPrefInitialized;
|
||||||
bool mIsJavaScriptEnabled;
|
bool mIsJavaScriptEnabled;
|
||||||
nsTArray<nsCOMPtr<nsIURI>> mFileURIWhitelist;
|
|
||||||
|
// List of URIs whose domains and sub-domains are whitelisted to allow
|
||||||
|
// access to file: URIs. Lazily initialized; isNothing() when not yet
|
||||||
|
// initialized.
|
||||||
|
mozilla::Maybe<nsTArray<nsCOMPtr<nsIURI>>> mFileURIWhitelist;
|
||||||
|
|
||||||
// This machinery controls new-style domain policies. The old-style
|
// This machinery controls new-style domain policies. The old-style
|
||||||
// policy machinery will be removed soon.
|
// policy machinery will be removed soon.
|
||||||
|
|
|
@ -95,22 +95,6 @@ cppunittests-remote:
|
||||||
|
|
||||||
endif # COMPILE_ENVIRONMENT
|
endif # COMPILE_ENVIRONMENT
|
||||||
endif # CPP_UNIT_TESTS
|
endif # CPP_UNIT_TESTS
|
||||||
|
|
||||||
.PHONY: check
|
|
||||||
|
|
||||||
ifdef PYTHON_UNIT_TESTS
|
|
||||||
|
|
||||||
RUN_PYTHON_UNIT_TESTS := $(addsuffix -run,$(PYTHON_UNIT_TESTS))
|
|
||||||
|
|
||||||
.PHONY: $(RUN_PYTHON_UNIT_TESTS)
|
|
||||||
|
|
||||||
check:: $(RUN_PYTHON_UNIT_TESTS)
|
|
||||||
|
|
||||||
$(RUN_PYTHON_UNIT_TESTS): %-run: %
|
|
||||||
@PYTHONDONTWRITEBYTECODE=1 $(PYTHON) $<
|
|
||||||
|
|
||||||
endif # PYTHON_UNIT_TESTS
|
|
||||||
|
|
||||||
endif # ENABLE_TESTS
|
endif # ENABLE_TESTS
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ button {
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
padding-right: 20px;
|
padding-right: 20px;
|
||||||
min-width: 100px;
|
min-width: 100px;
|
||||||
|
margin: 0 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Category panels */
|
/* Category panels */
|
||||||
|
@ -60,14 +61,12 @@ button {
|
||||||
min-height: 34px;
|
min-height: 34px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: baseline;
|
align-items: self-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.target-icon {
|
.target-icon {
|
||||||
height: 24px;
|
height: 24px;
|
||||||
margin: 6px 5px 0 0;
|
margin: 0 5px 0 0;
|
||||||
/* Override the icon alignment and center it using margin-top. */
|
|
||||||
align-self: flex-start;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.target-icon:not([src]) {
|
.target-icon:not([src]) {
|
||||||
|
@ -80,6 +79,7 @@ button {
|
||||||
|
|
||||||
.target {
|
.target {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
margin-top: 2px;
|
||||||
/* This is silly: https://bugzilla.mozilla.org/show_bug.cgi?id=1086218#c4. */
|
/* This is silly: https://bugzilla.mozilla.org/show_bug.cgi?id=1086218#c4. */
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
@ -117,6 +117,37 @@ button {
|
||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.target-status {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
min-width: 50px;
|
||||||
|
margin: 4px 5px 0 0;
|
||||||
|
padding: 2px;
|
||||||
|
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
|
||||||
|
font-size: 0.6em;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.target-status-stopped {
|
||||||
|
border-color: grey;
|
||||||
|
background-color: lightgrey;
|
||||||
|
}
|
||||||
|
|
||||||
|
.target-status-running {
|
||||||
|
border-color: limegreen;
|
||||||
|
background-color: palegreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
.target-name {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
.addons-controls {
|
.addons-controls {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
|
@ -47,7 +47,7 @@ module.exports = createClass({
|
||||||
src: target.icon
|
src: target.icon
|
||||||
}),
|
}),
|
||||||
dom.div({ className: "target" },
|
dom.div({ className: "target" },
|
||||||
dom.div({ className: "target-name" }, target.name)
|
dom.div({ className: "target-name", title: target.name }, target.name)
|
||||||
),
|
),
|
||||||
dom.button({
|
dom.button({
|
||||||
className: "debug-button",
|
className: "debug-button",
|
||||||
|
|
|
@ -42,6 +42,8 @@ module.exports = createClass({
|
||||||
client.addListener("workerListChanged", this.update);
|
client.addListener("workerListChanged", this.update);
|
||||||
client.addListener("serviceWorkerRegistrationListChanged", this.update);
|
client.addListener("serviceWorkerRegistrationListChanged", this.update);
|
||||||
client.addListener("processListChanged", this.update);
|
client.addListener("processListChanged", this.update);
|
||||||
|
client.addListener("registration-changed", this.update);
|
||||||
|
|
||||||
this.update();
|
this.update();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -50,6 +52,7 @@ module.exports = createClass({
|
||||||
client.removeListener("processListChanged", this.update);
|
client.removeListener("processListChanged", this.update);
|
||||||
client.removeListener("serviceWorkerRegistrationListChanged", this.update);
|
client.removeListener("serviceWorkerRegistrationListChanged", this.update);
|
||||||
client.removeListener("workerListChanged", this.update);
|
client.removeListener("workerListChanged", this.update);
|
||||||
|
client.removeListener("registration-changed", this.update);
|
||||||
},
|
},
|
||||||
|
|
||||||
update() {
|
update() {
|
||||||
|
@ -62,7 +65,8 @@ module.exports = createClass({
|
||||||
name: form.url,
|
name: form.url,
|
||||||
url: form.url,
|
url: form.url,
|
||||||
scope: form.scope,
|
scope: form.scope,
|
||||||
registrationActor: form.actor
|
registrationActor: form.actor,
|
||||||
|
active: form.active
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -75,16 +79,22 @@ module.exports = createClass({
|
||||||
};
|
};
|
||||||
switch (form.type) {
|
switch (form.type) {
|
||||||
case Ci.nsIWorkerDebugger.TYPE_SERVICE:
|
case Ci.nsIWorkerDebugger.TYPE_SERVICE:
|
||||||
for (let registration of workers.service) {
|
let registration = this.getRegistrationForWorker(form, workers.service);
|
||||||
if (registration.scope === form.scope) {
|
if (registration) {
|
||||||
// XXX: Race, sometimes a ServiceWorkerRegistrationInfo doesn't
|
// XXX: Race, sometimes a ServiceWorkerRegistrationInfo doesn't
|
||||||
// have a scriptSpec, but its associated WorkerDebugger does.
|
// have a scriptSpec, but its associated WorkerDebugger does.
|
||||||
if (!registration.url) {
|
if (!registration.url) {
|
||||||
registration.name = registration.url = form.url;
|
registration.name = registration.url = form.url;
|
||||||
}
|
|
||||||
registration.workerActor = form.actor;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
registration.workerActor = form.actor;
|
||||||
|
} else {
|
||||||
|
// If a service worker registration could not be found, this means we are in
|
||||||
|
// e10s, and registrations are not forwarded to other processes until they
|
||||||
|
// reach the activated state. Augment the worker as a registration worker to
|
||||||
|
// display it in aboutdebugging.
|
||||||
|
worker.scope = form.scope;
|
||||||
|
worker.active = false;
|
||||||
|
workers.service.push(worker);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Ci.nsIWorkerDebugger.TYPE_SHARED:
|
case Ci.nsIWorkerDebugger.TYPE_SHARED:
|
||||||
|
@ -103,6 +113,15 @@ module.exports = createClass({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getRegistrationForWorker(form, registrations) {
|
||||||
|
for (let registration of registrations) {
|
||||||
|
if (registration.scope === form.scope) {
|
||||||
|
return registration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let { client, id } = this.props;
|
let { client, id } = this.props;
|
||||||
let { workers } = this.state;
|
let { workers } = this.state;
|
||||||
|
|
|
@ -25,15 +25,23 @@ module.exports = createClass({
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
let { client } = this.props;
|
let { client } = this.props;
|
||||||
client.addListener("push-subscription-modified",
|
client.addListener("push-subscription-modified", this.onPushSubscriptionModified);
|
||||||
this.onPushSubscriptionModified);
|
|
||||||
this.updatePushSubscription();
|
this.updatePushSubscription();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
componentDidUpdate(oldProps, oldState) {
|
||||||
|
let wasActive = oldProps.target.active;
|
||||||
|
if (!wasActive && this.isActive()) {
|
||||||
|
// While the service worker isn't active, any calls to `updatePushSubscription`
|
||||||
|
// won't succeed. If we just became active, make sure we didn't miss a push
|
||||||
|
// subscription change by updating it now.
|
||||||
|
this.updatePushSubscription();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
let { client } = this.props;
|
let { client } = this.props;
|
||||||
client.removeListener("push-subscription-modified",
|
client.removeListener("push-subscription-modified", this.onPushSubscriptionModified);
|
||||||
this.onPushSubscriptionModified);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
debug() {
|
debug() {
|
||||||
|
@ -47,8 +55,10 @@ module.exports = createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
push() {
|
push() {
|
||||||
if (!this.isRunning()) {
|
if (!this.isActive() || !this.isRunning()) {
|
||||||
// If the worker is not running, we can't push to it.
|
// If the worker is not running, we can't push to it.
|
||||||
|
// If the worker is not active, the registration might be unavailable and the
|
||||||
|
// push will not succeed.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,8 +70,8 @@ module.exports = createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
if (this.isRunning()) {
|
if (!this.isActive() || this.isRunning()) {
|
||||||
// If the worker is already running, we can't start it.
|
// If the worker is not active or if it is already running, we can't start it.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,6 +98,11 @@ module.exports = createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
updatePushSubscription() {
|
updatePushSubscription() {
|
||||||
|
if (!this.props.target.registrationActor) {
|
||||||
|
// A valid registrationActor is needed to retrieve the push subscription.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let { client, target } = this.props;
|
let { client, target } = this.props;
|
||||||
client.request({
|
client.request({
|
||||||
to: target.registrationActor,
|
to: target.registrationActor,
|
||||||
|
@ -102,10 +117,65 @@ module.exports = createClass({
|
||||||
return !!this.props.target.workerActor;
|
return !!this.props.target.workerActor;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
isActive() {
|
||||||
|
return this.props.target.active;
|
||||||
|
},
|
||||||
|
|
||||||
|
getServiceWorkerStatus() {
|
||||||
|
if (this.isActive() && this.isRunning()) {
|
||||||
|
return "running";
|
||||||
|
} else if (this.isActive()) {
|
||||||
|
return "stopped";
|
||||||
|
}
|
||||||
|
// We cannot get service worker registrations unless the registration is in
|
||||||
|
// ACTIVE state. Unable to know the actual state ("installing", "waiting"), we
|
||||||
|
// display a custom state "registering" for now. See Bug 1153292.
|
||||||
|
return "registering";
|
||||||
|
},
|
||||||
|
|
||||||
|
renderButtons() {
|
||||||
|
let pushButton = dom.button({
|
||||||
|
className: "push-button",
|
||||||
|
onClick: this.push
|
||||||
|
}, Strings.GetStringFromName("push"));
|
||||||
|
|
||||||
|
let debugButton = dom.button({
|
||||||
|
className: "debug-button",
|
||||||
|
onClick: this.debug,
|
||||||
|
disabled: this.props.debugDisabled
|
||||||
|
}, Strings.GetStringFromName("debug"));
|
||||||
|
|
||||||
|
let startButton = dom.button({
|
||||||
|
className: "start-button",
|
||||||
|
onClick: this.start,
|
||||||
|
}, Strings.GetStringFromName("start"));
|
||||||
|
|
||||||
|
if (this.isRunning()) {
|
||||||
|
if (this.isActive()) {
|
||||||
|
return [pushButton, debugButton];
|
||||||
|
}
|
||||||
|
// Only debug button is available if the service worker is not active.
|
||||||
|
return debugButton;
|
||||||
|
}
|
||||||
|
return startButton;
|
||||||
|
},
|
||||||
|
|
||||||
|
renderUnregisterLink() {
|
||||||
|
if (!this.isActive()) {
|
||||||
|
// If not active, there might be no registrationActor available.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dom.a({
|
||||||
|
onClick: this.unregister,
|
||||||
|
className: "unregister-link"
|
||||||
|
}, Strings.GetStringFromName("unregister"));
|
||||||
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let { target, debugDisabled } = this.props;
|
let { target } = this.props;
|
||||||
let { pushSubscription } = this.state;
|
let { pushSubscription } = this.state;
|
||||||
let isRunning = this.isRunning();
|
let status = this.getServiceWorkerStatus();
|
||||||
|
|
||||||
return dom.div({ className: "target-container" },
|
return dom.div({ className: "target-container" },
|
||||||
dom.img({
|
dom.img({
|
||||||
|
@ -113,43 +183,31 @@ module.exports = createClass({
|
||||||
role: "presentation",
|
role: "presentation",
|
||||||
src: target.icon
|
src: target.icon
|
||||||
}),
|
}),
|
||||||
|
dom.span({ className: `target-status target-status-${status}` },
|
||||||
|
Strings.GetStringFromName(status)),
|
||||||
dom.div({ className: "target" },
|
dom.div({ className: "target" },
|
||||||
dom.div({ className: "target-name" }, target.name),
|
dom.div({ className: "target-name", title: target.name }, target.name),
|
||||||
dom.ul({ className: "target-details" },
|
dom.ul({ className: "target-details" },
|
||||||
(pushSubscription ?
|
(pushSubscription ?
|
||||||
dom.li({ className: "target-detail" },
|
dom.li({ className: "target-detail" },
|
||||||
dom.strong(null, Strings.GetStringFromName("pushService")),
|
dom.strong(null, Strings.GetStringFromName("pushService")),
|
||||||
dom.span({ className: "service-worker-push-url" },
|
dom.span({
|
||||||
pushSubscription.endpoint)) :
|
className: "service-worker-push-url",
|
||||||
|
title: pushSubscription.endpoint
|
||||||
|
}, pushSubscription.endpoint)) :
|
||||||
null
|
null
|
||||||
),
|
),
|
||||||
dom.li({ className: "target-detail" },
|
dom.li({ className: "target-detail" },
|
||||||
dom.strong(null, Strings.GetStringFromName("scope")),
|
dom.strong(null, Strings.GetStringFromName("scope")),
|
||||||
dom.span({ className: "service-worker-scope" }, target.scope),
|
dom.span({
|
||||||
dom.a({
|
className: "service-worker-scope",
|
||||||
onClick: this.unregister,
|
title: target.scope
|
||||||
className: "unregister-link"
|
}, target.scope),
|
||||||
}, Strings.GetStringFromName("unregister"))
|
this.renderUnregisterLink()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
(isRunning ?
|
this.renderButtons()
|
||||||
[
|
|
||||||
dom.button({
|
|
||||||
className: "push-button",
|
|
||||||
onClick: this.push
|
|
||||||
}, Strings.GetStringFromName("push")),
|
|
||||||
dom.button({
|
|
||||||
className: "debug-button",
|
|
||||||
onClick: this.debug,
|
|
||||||
disabled: debugDisabled
|
|
||||||
}, Strings.GetStringFromName("debug"))
|
|
||||||
] :
|
|
||||||
dom.button({
|
|
||||||
className: "start-button",
|
|
||||||
onClick: this.start
|
|
||||||
}, Strings.GetStringFromName("start"))
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -32,7 +32,7 @@ module.exports = createClass({
|
||||||
src: target.icon
|
src: target.icon
|
||||||
}),
|
}),
|
||||||
dom.div({ className: "target" },
|
dom.div({ className: "target" },
|
||||||
dom.div({ className: "target-name" }, target.name)
|
dom.div({ className: "target-name", title: target.name }, target.name)
|
||||||
),
|
),
|
||||||
dom.button({
|
dom.button({
|
||||||
className: "debug-button",
|
className: "debug-button",
|
||||||
|
|
|
@ -9,6 +9,8 @@ support-files =
|
||||||
addons/bug1273184.xpi
|
addons/bug1273184.xpi
|
||||||
addons/test-devtools-webextension/*
|
addons/test-devtools-webextension/*
|
||||||
addons/test-devtools-webextension-nobg/*
|
addons/test-devtools-webextension-nobg/*
|
||||||
|
service-workers/delay-sw.html
|
||||||
|
service-workers/delay-sw.js
|
||||||
service-workers/empty-sw.html
|
service-workers/empty-sw.html
|
||||||
service-workers/empty-sw.js
|
service-workers/empty-sw.js
|
||||||
service-workers/push-sw.html
|
service-workers/push-sw.html
|
||||||
|
@ -34,6 +36,7 @@ tags = webextensions
|
||||||
[browser_service_workers_push.js]
|
[browser_service_workers_push.js]
|
||||||
[browser_service_workers_push_service.js]
|
[browser_service_workers_push_service.js]
|
||||||
[browser_service_workers_start.js]
|
[browser_service_workers_start.js]
|
||||||
|
[browser_service_workers_status.js]
|
||||||
[browser_service_workers_timeout.js]
|
[browser_service_workers_timeout.js]
|
||||||
skip-if = true # Bug 1232931
|
skip-if = true # Bug 1232931
|
||||||
[browser_service_workers_unregister.js]
|
[browser_service_workers_unregister.js]
|
||||||
|
|
|
@ -31,19 +31,13 @@ add_task(function* () {
|
||||||
ok(names.includes(SERVICE_WORKER),
|
ok(names.includes(SERVICE_WORKER),
|
||||||
"The service worker url appears in the list: " + names);
|
"The service worker url appears in the list: " + names);
|
||||||
|
|
||||||
// Finally, unregister the service worker itself
|
|
||||||
let aboutDebuggingUpdate = waitForMutation(serviceWorkersElement,
|
|
||||||
{ childList: true });
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
yield unregisterServiceWorker(swTab);
|
yield unregisterServiceWorker(swTab, serviceWorkersElement);
|
||||||
ok(true, "Service worker registration unregistered");
|
ok(true, "Service worker registration unregistered");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ok(false, "SW not unregistered; " + e);
|
ok(false, "SW not unregistered; " + e);
|
||||||
}
|
}
|
||||||
|
|
||||||
yield aboutDebuggingUpdate;
|
|
||||||
|
|
||||||
// Check that the service worker disappeared from the UI
|
// Check that the service worker disappeared from the UI
|
||||||
names = [...document.querySelectorAll("#service-workers .target-name")];
|
names = [...document.querySelectorAll("#service-workers .target-name")];
|
||||||
names = names.map(element => element.textContent);
|
names = names.map(element => element.textContent);
|
||||||
|
|
|
@ -62,11 +62,15 @@ add_task(function* () {
|
||||||
yield waitForServiceWorkerRegistered(swTab);
|
yield waitForServiceWorkerRegistered(swTab);
|
||||||
ok(true, "Service worker registration resolved");
|
ok(true, "Service worker registration resolved");
|
||||||
|
|
||||||
|
yield waitForServiceWorkerActivation(SERVICE_WORKER, document);
|
||||||
|
|
||||||
// Retrieve the Push button for the worker.
|
// Retrieve the Push button for the worker.
|
||||||
let names = [...document.querySelectorAll("#service-workers .target-name")];
|
let names = [...document.querySelectorAll("#service-workers .target-name")];
|
||||||
let name = names.filter(element => element.textContent === SERVICE_WORKER)[0];
|
let name = names.filter(element => element.textContent === SERVICE_WORKER)[0];
|
||||||
ok(name, "Found the service worker in the list");
|
ok(name, "Found the service worker in the list");
|
||||||
|
|
||||||
let targetElement = name.parentNode.parentNode;
|
let targetElement = name.parentNode.parentNode;
|
||||||
|
|
||||||
let pushBtn = targetElement.querySelector(".push-button");
|
let pushBtn = targetElement.querySelector(".push-button");
|
||||||
ok(pushBtn, "Found its push button");
|
ok(pushBtn, "Found its push button");
|
||||||
|
|
||||||
|
@ -88,7 +92,7 @@ add_task(function* () {
|
||||||
|
|
||||||
// Finally, unregister the service worker itself.
|
// Finally, unregister the service worker itself.
|
||||||
try {
|
try {
|
||||||
yield unregisterServiceWorker(swTab);
|
yield unregisterServiceWorker(swTab, serviceWorkersElement);
|
||||||
ok(true, "Service worker registration unregistered");
|
ok(true, "Service worker registration unregistered");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ok(false, "SW not unregistered; " + e);
|
ok(false, "SW not unregistered; " + e);
|
||||||
|
|
|
@ -72,16 +72,23 @@ add_task(function* () {
|
||||||
// Check that the service worker appears in the UI.
|
// Check that the service worker appears in the UI.
|
||||||
assertHasTarget(true, document, "service-workers", SERVICE_WORKER);
|
assertHasTarget(true, document, "service-workers", SERVICE_WORKER);
|
||||||
|
|
||||||
|
yield waitForServiceWorkerActivation(SERVICE_WORKER, document);
|
||||||
|
|
||||||
// Wait for the service worker details to update.
|
// Wait for the service worker details to update.
|
||||||
let names = [...document.querySelectorAll("#service-workers .target-name")];
|
let names = [...document.querySelectorAll("#service-workers .target-name")];
|
||||||
let name = names.filter(element => element.textContent === SERVICE_WORKER)[0];
|
let name = names.filter(element => element.textContent === SERVICE_WORKER)[0];
|
||||||
ok(name, "Found the service worker in the list");
|
ok(name, "Found the service worker in the list");
|
||||||
|
|
||||||
let targetContainer = name.parentNode.parentNode;
|
let targetContainer = name.parentNode.parentNode;
|
||||||
let targetDetailsElement = targetContainer.querySelector(".target-details");
|
let targetDetailsElement = targetContainer.querySelector(".target-details");
|
||||||
yield waitForMutation(targetDetailsElement, { childList: true });
|
|
||||||
|
|
||||||
// Retrieve the push subscription endpoint URL, and verify it looks good.
|
// Retrieve the push subscription endpoint URL, and verify it looks good.
|
||||||
let pushURL = targetContainer.querySelector(".service-worker-push-url");
|
let pushURL = targetContainer.querySelector(".service-worker-push-url");
|
||||||
|
if (!pushURL) {
|
||||||
|
yield waitForMutation(targetDetailsElement, { childList: true });
|
||||||
|
pushURL = targetContainer.querySelector(".service-worker-push-url");
|
||||||
|
}
|
||||||
|
|
||||||
ok(pushURL, "Found the push service URL in the service worker details");
|
ok(pushURL, "Found the push service URL in the service worker details");
|
||||||
is(pushURL.textContent, FAKE_ENDPOINT, "The push service URL looks correct");
|
is(pushURL.textContent, FAKE_ENDPOINT, "The push service URL looks correct");
|
||||||
|
|
||||||
|
@ -97,11 +104,12 @@ add_task(function* () {
|
||||||
"The push service URL should be removed");
|
"The push service URL should be removed");
|
||||||
|
|
||||||
// Finally, unregister the service worker itself.
|
// Finally, unregister the service worker itself.
|
||||||
yield unregisterServiceWorker(swTab).then(() => {
|
try {
|
||||||
|
yield unregisterServiceWorker(swTab, serviceWorkersElement);
|
||||||
ok(true, "Service worker registration unregistered");
|
ok(true, "Service worker registration unregistered");
|
||||||
}).catch(function (e) {
|
} catch (e) {
|
||||||
ok(false, "Service worker not unregistered; " + e);
|
ok(false, "SW not unregistered; " + e);
|
||||||
});
|
}
|
||||||
|
|
||||||
info("Unmock the push service");
|
info("Unmock the push service");
|
||||||
PushService.service = null;
|
PushService.service = null;
|
||||||
|
|
|
@ -47,6 +47,8 @@ add_task(function* () {
|
||||||
yield waitForServiceWorkerRegistered(swTab);
|
yield waitForServiceWorkerRegistered(swTab);
|
||||||
ok(true, "Service worker registration resolved");
|
ok(true, "Service worker registration resolved");
|
||||||
|
|
||||||
|
yield waitForServiceWorkerActivation(SERVICE_WORKER, document);
|
||||||
|
|
||||||
// Retrieve the Target element corresponding to the service worker.
|
// Retrieve the Target element corresponding to the service worker.
|
||||||
let names = [...document.querySelectorAll("#service-workers .target-name")];
|
let names = [...document.querySelectorAll("#service-workers .target-name")];
|
||||||
let name = names.filter(element => element.textContent === SERVICE_WORKER)[0];
|
let name = names.filter(element => element.textContent === SERVICE_WORKER)[0];
|
||||||
|
@ -82,7 +84,7 @@ add_task(function* () {
|
||||||
|
|
||||||
// Finally, unregister the service worker itself.
|
// Finally, unregister the service worker itself.
|
||||||
try {
|
try {
|
||||||
yield unregisterServiceWorker(swTab);
|
yield unregisterServiceWorker(swTab, serviceWorkersElement);
|
||||||
ok(true, "Service worker registration unregistered");
|
ok(true, "Service worker registration unregistered");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ok(false, "SW not unregistered; " + e);
|
ok(false, "SW not unregistered; " + e);
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Service workers can't be loaded from chrome://,
|
||||||
|
// but http:// is ok with dom.serviceWorkers.testing.enabled turned on.
|
||||||
|
const SERVICE_WORKER = URL_ROOT + "service-workers/delay-sw.js";
|
||||||
|
const TAB_URL = URL_ROOT + "service-workers/delay-sw.html";
|
||||||
|
const SW_TIMEOUT = 2000;
|
||||||
|
|
||||||
|
requestLongerTimeout(2);
|
||||||
|
|
||||||
|
add_task(function* () {
|
||||||
|
yield SpecialPowers.pushPrefEnv({
|
||||||
|
"set": [
|
||||||
|
// Accept workers from mochitest's http.
|
||||||
|
["dom.serviceWorkers.testing.enabled", true],
|
||||||
|
["dom.serviceWorkers.idle_timeout", SW_TIMEOUT],
|
||||||
|
["dom.serviceWorkers.idle_extended_timeout", SW_TIMEOUT],
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
let { tab, document } = yield openAboutDebugging("workers");
|
||||||
|
|
||||||
|
// Listen for mutations in the service-workers list.
|
||||||
|
let serviceWorkersElement = getServiceWorkerList(document);
|
||||||
|
let onMutation = waitForMutation(serviceWorkersElement, { childList: true });
|
||||||
|
|
||||||
|
let swTab = yield addTab(TAB_URL);
|
||||||
|
|
||||||
|
info("Make the test page notify us when the service worker sends a message.");
|
||||||
|
|
||||||
|
// Wait for the service-workers list to update.
|
||||||
|
yield onMutation;
|
||||||
|
|
||||||
|
// Check that the service worker appears in the UI
|
||||||
|
let names = [...document.querySelectorAll("#service-workers .target-name")];
|
||||||
|
let name = names.filter(element => element.textContent === SERVICE_WORKER)[0];
|
||||||
|
ok(name, "Found the service worker in the list");
|
||||||
|
|
||||||
|
let targetElement = name.parentNode.parentNode;
|
||||||
|
let status = targetElement.querySelector(".target-status");
|
||||||
|
is(status.textContent, "Registering", "Service worker is currently registering");
|
||||||
|
|
||||||
|
yield waitForMutation(serviceWorkersElement, { childList: true, subtree: true });
|
||||||
|
is(status.textContent, "Running", "Service worker is currently running");
|
||||||
|
|
||||||
|
yield waitForMutation(serviceWorkersElement, { attributes: true, subtree: true });
|
||||||
|
is(status.textContent, "Stopped", "Service worker is currently stopped");
|
||||||
|
|
||||||
|
try {
|
||||||
|
yield unregisterServiceWorker(swTab, serviceWorkersElement);
|
||||||
|
ok(true, "Service worker unregistered");
|
||||||
|
} catch (e) {
|
||||||
|
ok(false, "Service worker not unregistered; " + e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that the service worker disappeared from the UI
|
||||||
|
names = [...document.querySelectorAll("#service-workers .target-name")];
|
||||||
|
names = names.map(element => element.textContent);
|
||||||
|
ok(!names.includes(SERVICE_WORKER),
|
||||||
|
"The service worker url is no longer in the list: " + names);
|
||||||
|
|
||||||
|
yield removeTab(swTab);
|
||||||
|
yield closeAboutDebugging(tab);
|
||||||
|
});
|
|
@ -77,15 +77,12 @@ add_task(function* () {
|
||||||
|
|
||||||
// Finally, unregister the service worker itself.
|
// Finally, unregister the service worker itself.
|
||||||
try {
|
try {
|
||||||
yield unregisterServiceWorker(swTab);
|
yield unregisterServiceWorker(swTab, serviceWorkersElement);
|
||||||
ok(true, "Service worker registration unregistered");
|
ok(true, "Service worker registration unregistered");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ok(false, "SW not unregistered; " + e);
|
ok(false, "SW not unregistered; " + e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now ensure that the worker registration is correctly removed.
|
|
||||||
// The list should update once the registration is destroyed.
|
|
||||||
yield waitForMutation(serviceWorkersElement, { childList: true });
|
|
||||||
assertHasTarget(false, document, "service-workers", SERVICE_WORKER);
|
assertHasTarget(false, document, "service-workers", SERVICE_WORKER);
|
||||||
|
|
||||||
yield removeTab(swTab);
|
yield removeTab(swTab);
|
||||||
|
|
|
@ -39,6 +39,8 @@ add_task(function* () {
|
||||||
// Check that the service worker appears in the UI.
|
// Check that the service worker appears in the UI.
|
||||||
assertHasTarget(true, document, "service-workers", SERVICE_WORKER);
|
assertHasTarget(true, document, "service-workers", SERVICE_WORKER);
|
||||||
|
|
||||||
|
yield waitForServiceWorkerActivation(SERVICE_WORKER, document);
|
||||||
|
|
||||||
info("Ensure that the registration resolved before trying to interact with " +
|
info("Ensure that the registration resolved before trying to interact with " +
|
||||||
"the service worker.");
|
"the service worker.");
|
||||||
yield waitForServiceWorkerRegistered(swTab);
|
yield waitForServiceWorkerRegistered(swTab);
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
installAddon, uninstallAddon, waitForMutation, assertHasTarget,
|
installAddon, uninstallAddon, waitForMutation, assertHasTarget,
|
||||||
getServiceWorkerList, getTabList, openPanel, waitForInitialAddonList,
|
getServiceWorkerList, getTabList, openPanel, waitForInitialAddonList,
|
||||||
waitForServiceWorkerRegistered, unregisterServiceWorker,
|
waitForServiceWorkerRegistered, unregisterServiceWorker,
|
||||||
waitForDelayedStartupFinished, setupTestAboutDebuggingWebExtension */
|
waitForDelayedStartupFinished, setupTestAboutDebuggingWebExtension,
|
||||||
|
waitForServiceWorkerActivation */
|
||||||
/* import-globals-from ../../framework/test/shared-head.js */
|
/* import-globals-from ../../framework/test/shared-head.js */
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
@ -259,17 +260,22 @@ function waitForServiceWorkerRegistered(tab) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asks the service worker within the test page to unregister, and returns a
|
* Asks the service worker within the test page to unregister, and returns a
|
||||||
* promise that will resolve when it has successfully unregistered itself.
|
* promise that will resolve when it has successfully unregistered itself and the
|
||||||
|
* about:debugging UI has fully processed this update.
|
||||||
|
*
|
||||||
* @param {Tab} tab
|
* @param {Tab} tab
|
||||||
|
* @param {Node} serviceWorkersElement
|
||||||
* @return {Promise} Resolves when the service worker is unregistered.
|
* @return {Promise} Resolves when the service worker is unregistered.
|
||||||
*/
|
*/
|
||||||
function unregisterServiceWorker(tab) {
|
function* unregisterServiceWorker(tab, serviceWorkersElement) {
|
||||||
return ContentTask.spawn(tab.linkedBrowser, {}, function* () {
|
let onMutation = waitForMutation(serviceWorkersElement, { childList: true });
|
||||||
|
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
|
||||||
// Retrieve the `sw` promise created in the html page
|
// Retrieve the `sw` promise created in the html page
|
||||||
let { sw } = content.wrappedJSObject;
|
let { sw } = content.wrappedJSObject;
|
||||||
let registration = yield sw;
|
let registration = yield sw;
|
||||||
yield registration.unregister();
|
yield registration.unregister();
|
||||||
});
|
});
|
||||||
|
return onMutation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -326,3 +332,20 @@ function* setupTestAboutDebuggingWebExtension(name, path) {
|
||||||
|
|
||||||
return { tab, document, debugBtn };
|
return { tab, document, debugBtn };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait for aboutdebugging to be notified about the activation of the service worker
|
||||||
|
* corresponding to the provided service worker url.
|
||||||
|
*/
|
||||||
|
function* waitForServiceWorkerActivation(swUrl, document) {
|
||||||
|
let serviceWorkersElement = getServiceWorkerList(document);
|
||||||
|
let names = serviceWorkersElement.querySelectorAll(".target-name");
|
||||||
|
let name = [...names].filter(element => element.textContent === swUrl)[0];
|
||||||
|
|
||||||
|
let targetElement = name.parentNode.parentNode;
|
||||||
|
let targetStatus = targetElement.querySelector(".target-status");
|
||||||
|
while (targetStatus.textContent === "Registering") {
|
||||||
|
// Wait for the status to leave the "registering" stage.
|
||||||
|
yield waitForMutation(serviceWorkersElement, { childList: true, subtree: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Service worker test</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script type="text/javascript">
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var sw = navigator.serviceWorker.register("delay-sw.js");
|
||||||
|
sw.then(
|
||||||
|
function () {
|
||||||
|
dump("SW registered\n");
|
||||||
|
},
|
||||||
|
function (e) {
|
||||||
|
dump("SW not registered: " + e + "\n");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,17 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
/* eslint-env worker */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function wait(ms) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
setTimeout(resolve, ms);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for one second to switch from installing to installed.
|
||||||
|
self.addEventListener("install", function (event) {
|
||||||
|
event.waitUntil(wait(1000));
|
||||||
|
});
|
|
@ -71,6 +71,20 @@ serviceWorkers = Service Workers
|
||||||
sharedWorkers = Shared Workers
|
sharedWorkers = Shared Workers
|
||||||
otherWorkers = Other Workers
|
otherWorkers = Other Workers
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (running):
|
||||||
|
# This string is displayed as the state of a service worker in RUNNING state.
|
||||||
|
running = Running
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (stopped):
|
||||||
|
# This string is displayed as the state of a service worker in STOPPED state.
|
||||||
|
stopped = Stopped
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (registering):
|
||||||
|
# This string is displayed as the state of a service worker for which no service worker
|
||||||
|
# registration could be found yet. Only active registrations are visible from
|
||||||
|
# about:debugging, so such service workers are considered as registering.
|
||||||
|
registering = Registering
|
||||||
|
|
||||||
# LOCALIZATION NOTE (tabs):
|
# LOCALIZATION NOTE (tabs):
|
||||||
# This string is displayed as a header of the about:debugging#tabs page.
|
# This string is displayed as a header of the about:debugging#tabs page.
|
||||||
tabs = Tabs
|
tabs = Tabs
|
||||||
|
|
|
@ -10,6 +10,7 @@ support-files =
|
||||||
browser_devices.json
|
browser_devices.json
|
||||||
doc_options-view.xul
|
doc_options-view.xul
|
||||||
head.js
|
head.js
|
||||||
|
helper_color_data.js
|
||||||
helper_html_tooltip.js
|
helper_html_tooltip.js
|
||||||
helper_inplace_editor.js
|
helper_inplace_editor.js
|
||||||
html-mdn-css-basic-testing.html
|
html-mdn-css-basic-testing.html
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
|
|
||||||
const TEST_URI = "data:text/html;charset=utf-8,browser_css_color.js";
|
const TEST_URI = "data:text/html;charset=utf-8,browser_css_color.js";
|
||||||
var {colorUtils} = require("devtools/shared/css/color");
|
var {colorUtils} = require("devtools/shared/css/color");
|
||||||
|
/* global getFixtureColorData */
|
||||||
|
loadHelperScript("helper_color_data.js");
|
||||||
|
|
||||||
var origColorUnit;
|
var origColorUnit;
|
||||||
|
|
||||||
add_task(function* () {
|
add_task(function* () {
|
||||||
|
@ -26,7 +29,7 @@ function createTestCanvas(doc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function testColorUtils(canvas) {
|
function testColorUtils(canvas) {
|
||||||
let data = getTestData();
|
let data = getFixtureColorData();
|
||||||
|
|
||||||
for (let {authored, name, hex, hsl, rgb} of data) {
|
for (let {authored, name, hex, hsl, rgb} of data) {
|
||||||
let color = new colorUtils.CssColor(authored);
|
let color = new colorUtils.CssColor(authored);
|
||||||
|
@ -111,8 +114,8 @@ function testSetAlpha() {
|
||||||
["hex", "#f0f", 0.2, "rgba(255, 0, 255, 0.2)"],
|
["hex", "#f0f", 0.2, "rgba(255, 0, 255, 0.2)"],
|
||||||
["rgba", "rgba(120, 34, 23, 1)", 0.25, "rgba(120, 34, 23, 0.25)"],
|
["rgba", "rgba(120, 34, 23, 1)", 0.25, "rgba(120, 34, 23, 0.25)"],
|
||||||
["rgb", "rgb(120, 34, 23)", 0.25, "rgba(120, 34, 23, 0.25)"],
|
["rgb", "rgb(120, 34, 23)", 0.25, "rgba(120, 34, 23, 0.25)"],
|
||||||
["hsl", "hsl(208, 100%, 97%)", 0.75, "rgba(239, 247, 255, 0.75)"],
|
["hsl", "hsl(208, 100%, 97%)", 0.75, "rgba(240, 248, 255, 0.75)"],
|
||||||
["hsla", "hsla(208, 100%, 97%, 1)", 0.75, "rgba(239, 247, 255, 0.75)"],
|
["hsla", "hsla(208, 100%, 97%, 1)", 0.75, "rgba(240, 248, 255, 0.75)"],
|
||||||
["alphahex", "#f08f", 0.6, "rgba(255, 0, 136, 0.6)"],
|
["alphahex", "#f08f", 0.6, "rgba(255, 0, 136, 0.6)"],
|
||||||
["longalphahex", "#00ff80ff", 0.2, "rgba(0, 255, 128, 0.2)"]
|
["longalphahex", "#00ff80ff", 0.2, "rgba(0, 255, 128, 0.2)"]
|
||||||
];
|
];
|
||||||
|
@ -129,170 +132,3 @@ function testSetAlpha() {
|
||||||
|
|
||||||
is(colorUtils.setAlpha("#fff"), "rgba(255, 255, 255, 1)", "sets alpha to 1 if invalid.");
|
is(colorUtils.setAlpha("#fff"), "rgba(255, 255, 255, 1)", "sets alpha to 1 if invalid.");
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTestData() {
|
|
||||||
return [
|
|
||||||
{authored: "aliceblue", name: "aliceblue", hex: "#f0f8ff", hsl: "hsl(208, 100%, 97%)", rgb: "rgb(240, 248, 255)"},
|
|
||||||
{authored: "antiquewhite", name: "antiquewhite", hex: "#faebd7", hsl: "hsl(34, 78%, 91%)", rgb: "rgb(250, 235, 215)"},
|
|
||||||
{authored: "aqua", name: "aqua", hex: "#0ff", hsl: "hsl(180, 100%, 50%)", rgb: "rgb(0, 255, 255)"},
|
|
||||||
{authored: "aquamarine", name: "aquamarine", hex: "#7fffd4", hsl: "hsl(160, 100%, 75%)", rgb: "rgb(127, 255, 212)"},
|
|
||||||
{authored: "azure", name: "azure", hex: "#f0ffff", hsl: "hsl(180, 100%, 97%)", rgb: "rgb(240, 255, 255)"},
|
|
||||||
{authored: "beige", name: "beige", hex: "#f5f5dc", hsl: "hsl(60, 56%, 91%)", rgb: "rgb(245, 245, 220)"},
|
|
||||||
{authored: "bisque", name: "bisque", hex: "#ffe4c4", hsl: "hsl(33, 100%, 88%)", rgb: "rgb(255, 228, 196)"},
|
|
||||||
{authored: "black", name: "black", hex: "#000", hsl: "hsl(0, 0%, 0%)", rgb: "rgb(0, 0, 0)"},
|
|
||||||
{authored: "blanchedalmond", name: "blanchedalmond", hex: "#ffebcd", hsl: "hsl(36, 100%, 90%)", rgb: "rgb(255, 235, 205)"},
|
|
||||||
{authored: "blue", name: "blue", hex: "#00f", hsl: "hsl(240, 100%, 50%)", rgb: "rgb(0, 0, 255)"},
|
|
||||||
{authored: "blueviolet", name: "blueviolet", hex: "#8a2be2", hsl: "hsl(271, 76%, 53%)", rgb: "rgb(138, 43, 226)"},
|
|
||||||
{authored: "brown", name: "brown", hex: "#a52a2a", hsl: "hsl(0, 59%, 41%)", rgb: "rgb(165, 42, 42)"},
|
|
||||||
{authored: "burlywood", name: "burlywood", hex: "#deb887", hsl: "hsl(34, 57%, 70%)", rgb: "rgb(222, 184, 135)"},
|
|
||||||
{authored: "cadetblue", name: "cadetblue", hex: "#5f9ea0", hsl: "hsl(182, 25%, 50%)", rgb: "rgb(95, 158, 160)"},
|
|
||||||
{authored: "chartreuse", name: "chartreuse", hex: "#7fff00", hsl: "hsl(90, 100%, 50%)", rgb: "rgb(127, 255, 0)"},
|
|
||||||
{authored: "chocolate", name: "chocolate", hex: "#d2691e", hsl: "hsl(25, 75%, 47%)", rgb: "rgb(210, 105, 30)"},
|
|
||||||
{authored: "coral", name: "coral", hex: "#ff7f50", hsl: "hsl(16, 100%, 66%)", rgb: "rgb(255, 127, 80)"},
|
|
||||||
{authored: "cornflowerblue", name: "cornflowerblue", hex: "#6495ed", hsl: "hsl(219, 79%, 66%)", rgb: "rgb(100, 149, 237)"},
|
|
||||||
{authored: "cornsilk", name: "cornsilk", hex: "#fff8dc", hsl: "hsl(48, 100%, 93%)", rgb: "rgb(255, 248, 220)"},
|
|
||||||
{authored: "crimson", name: "crimson", hex: "#dc143c", hsl: "hsl(348, 83%, 47%)", rgb: "rgb(220, 20, 60)"},
|
|
||||||
{authored: "cyan", name: "aqua", hex: "#0ff", hsl: "hsl(180, 100%, 50%)", rgb: "rgb(0, 255, 255)"},
|
|
||||||
{authored: "darkblue", name: "darkblue", hex: "#00008b", hsl: "hsl(240, 100%, 27%)", rgb: "rgb(0, 0, 139)"},
|
|
||||||
{authored: "darkcyan", name: "darkcyan", hex: "#008b8b", hsl: "hsl(180, 100%, 27%)", rgb: "rgb(0, 139, 139)"},
|
|
||||||
{authored: "darkgoldenrod", name: "darkgoldenrod", hex: "#b8860b", hsl: "hsl(43, 89%, 38%)", rgb: "rgb(184, 134, 11)"},
|
|
||||||
{authored: "darkgray", name: "darkgray", hex: "#a9a9a9", hsl: "hsl(0, 0%, 66%)", rgb: "rgb(169, 169, 169)"},
|
|
||||||
{authored: "darkgreen", name: "darkgreen", hex: "#006400", hsl: "hsl(120, 100%, 20%)", rgb: "rgb(0, 100, 0)"},
|
|
||||||
{authored: "darkgrey", name: "darkgray", hex: "#a9a9a9", hsl: "hsl(0, 0%, 66%)", rgb: "rgb(169, 169, 169)"},
|
|
||||||
{authored: "darkkhaki", name: "darkkhaki", hex: "#bdb76b", hsl: "hsl(56, 38%, 58%)", rgb: "rgb(189, 183, 107)"},
|
|
||||||
{authored: "darkmagenta", name: "darkmagenta", hex: "#8b008b", hsl: "hsl(300, 100%, 27%)", rgb: "rgb(139, 0, 139)"},
|
|
||||||
{authored: "darkolivegreen", name: "darkolivegreen", hex: "#556b2f", hsl: "hsl(82, 39%, 30%)", rgb: "rgb(85, 107, 47)"},
|
|
||||||
{authored: "darkorange", name: "darkorange", hex: "#ff8c00", hsl: "hsl(33, 100%, 50%)", rgb: "rgb(255, 140, 0)"},
|
|
||||||
{authored: "darkorchid", name: "darkorchid", hex: "#9932cc", hsl: "hsl(280, 61%, 50%)", rgb: "rgb(153, 50, 204)"},
|
|
||||||
{authored: "darkred", name: "darkred", hex: "#8b0000", hsl: "hsl(0, 100%, 27%)", rgb: "rgb(139, 0, 0)"},
|
|
||||||
{authored: "darksalmon", name: "darksalmon", hex: "#e9967a", hsl: "hsl(15, 72%, 70%)", rgb: "rgb(233, 150, 122)"},
|
|
||||||
{authored: "darkseagreen", name: "darkseagreen", hex: "#8fbc8f", hsl: "hsl(120, 25%, 65%)", rgb: "rgb(143, 188, 143)"},
|
|
||||||
{authored: "darkslateblue", name: "darkslateblue", hex: "#483d8b", hsl: "hsl(248, 39%, 39%)", rgb: "rgb(72, 61, 139)"},
|
|
||||||
{authored: "darkslategray", name: "darkslategray", hex: "#2f4f4f", hsl: "hsl(180, 25%, 25%)", rgb: "rgb(47, 79, 79)"},
|
|
||||||
{authored: "darkslategrey", name: "darkslategray", hex: "#2f4f4f", hsl: "hsl(180, 25%, 25%)", rgb: "rgb(47, 79, 79)"},
|
|
||||||
{authored: "darkturquoise", name: "darkturquoise", hex: "#00ced1", hsl: "hsl(181, 100%, 41%)", rgb: "rgb(0, 206, 209)"},
|
|
||||||
{authored: "darkviolet", name: "darkviolet", hex: "#9400d3", hsl: "hsl(282, 100%, 41%)", rgb: "rgb(148, 0, 211)"},
|
|
||||||
{authored: "deeppink", name: "deeppink", hex: "#ff1493", hsl: "hsl(328, 100%, 54%)", rgb: "rgb(255, 20, 147)"},
|
|
||||||
{authored: "deepskyblue", name: "deepskyblue", hex: "#00bfff", hsl: "hsl(195, 100%, 50%)", rgb: "rgb(0, 191, 255)"},
|
|
||||||
{authored: "dimgray", name: "dimgray", hex: "#696969", hsl: "hsl(0, 0%, 41%)", rgb: "rgb(105, 105, 105)"},
|
|
||||||
{authored: "dodgerblue", name: "dodgerblue", hex: "#1e90ff", hsl: "hsl(210, 100%, 56%)", rgb: "rgb(30, 144, 255)"},
|
|
||||||
{authored: "firebrick", name: "firebrick", hex: "#b22222", hsl: "hsl(0, 68%, 42%)", rgb: "rgb(178, 34, 34)"},
|
|
||||||
{authored: "floralwhite", name: "floralwhite", hex: "#fffaf0", hsl: "hsl(40, 100%, 97%)", rgb: "rgb(255, 250, 240)"},
|
|
||||||
{authored: "forestgreen", name: "forestgreen", hex: "#228b22", hsl: "hsl(120, 61%, 34%)", rgb: "rgb(34, 139, 34)"},
|
|
||||||
{authored: "fuchsia", name: "fuchsia", hex: "#f0f", hsl: "hsl(300, 100%, 50%)", rgb: "rgb(255, 0, 255)"},
|
|
||||||
{authored: "gainsboro", name: "gainsboro", hex: "#dcdcdc", hsl: "hsl(0, 0%, 86%)", rgb: "rgb(220, 220, 220)"},
|
|
||||||
{authored: "ghostwhite", name: "ghostwhite", hex: "#f8f8ff", hsl: "hsl(240, 100%, 99%)", rgb: "rgb(248, 248, 255)"},
|
|
||||||
{authored: "gold", name: "gold", hex: "#ffd700", hsl: "hsl(51, 100%, 50%)", rgb: "rgb(255, 215, 0)"},
|
|
||||||
{authored: "goldenrod", name: "goldenrod", hex: "#daa520", hsl: "hsl(43, 74%, 49%)", rgb: "rgb(218, 165, 32)"},
|
|
||||||
{authored: "gray", name: "gray", hex: "#808080", hsl: "hsl(0, 0%, 50%)", rgb: "rgb(128, 128, 128)"},
|
|
||||||
{authored: "green", name: "green", hex: "#008000", hsl: "hsl(120, 100%, 25%)", rgb: "rgb(0, 128, 0)"},
|
|
||||||
{authored: "greenyellow", name: "greenyellow", hex: "#adff2f", hsl: "hsl(84, 100%, 59%)", rgb: "rgb(173, 255, 47)"},
|
|
||||||
{authored: "grey", name: "gray", hex: "#808080", hsl: "hsl(0, 0%, 50%)", rgb: "rgb(128, 128, 128)"},
|
|
||||||
{authored: "honeydew", name: "honeydew", hex: "#f0fff0", hsl: "hsl(120, 100%, 97%)", rgb: "rgb(240, 255, 240)"},
|
|
||||||
{authored: "hotpink", name: "hotpink", hex: "#ff69b4", hsl: "hsl(330, 100%, 71%)", rgb: "rgb(255, 105, 180)"},
|
|
||||||
{authored: "indianred", name: "indianred", hex: "#cd5c5c", hsl: "hsl(0, 53%, 58%)", rgb: "rgb(205, 92, 92)"},
|
|
||||||
{authored: "indigo", name: "indigo", hex: "#4b0082", hsl: "hsl(275, 100%, 25%)", rgb: "rgb(75, 0, 130)"},
|
|
||||||
{authored: "ivory", name: "ivory", hex: "#fffff0", hsl: "hsl(60, 100%, 97%)", rgb: "rgb(255, 255, 240)"},
|
|
||||||
{authored: "khaki", name: "khaki", hex: "#f0e68c", hsl: "hsl(54, 77%, 75%)", rgb: "rgb(240, 230, 140)"},
|
|
||||||
{authored: "lavender", name: "lavender", hex: "#e6e6fa", hsl: "hsl(240, 67%, 94%)", rgb: "rgb(230, 230, 250)"},
|
|
||||||
{authored: "lavenderblush", name: "lavenderblush", hex: "#fff0f5", hsl: "hsl(340, 100%, 97%)", rgb: "rgb(255, 240, 245)"},
|
|
||||||
{authored: "lawngreen", name: "lawngreen", hex: "#7cfc00", hsl: "hsl(90, 100%, 49%)", rgb: "rgb(124, 252, 0)"},
|
|
||||||
{authored: "lemonchiffon", name: "lemonchiffon", hex: "#fffacd", hsl: "hsl(54, 100%, 90%)", rgb: "rgb(255, 250, 205)"},
|
|
||||||
{authored: "lightblue", name: "lightblue", hex: "#add8e6", hsl: "hsl(195, 53%, 79%)", rgb: "rgb(173, 216, 230)"},
|
|
||||||
{authored: "lightcoral", name: "lightcoral", hex: "#f08080", hsl: "hsl(0, 79%, 72%)", rgb: "rgb(240, 128, 128)"},
|
|
||||||
{authored: "lightcyan", name: "lightcyan", hex: "#e0ffff", hsl: "hsl(180, 100%, 94%)", rgb: "rgb(224, 255, 255)"},
|
|
||||||
{authored: "lightgoldenrodyellow", name: "lightgoldenrodyellow", hex: "#fafad2", hsl: "hsl(60, 80%, 90%)", rgb: "rgb(250, 250, 210)"},
|
|
||||||
{authored: "lightgray", name: "lightgray", hex: "#d3d3d3", hsl: "hsl(0, 0%, 83%)", rgb: "rgb(211, 211, 211)"},
|
|
||||||
{authored: "lightgreen", name: "lightgreen", hex: "#90ee90", hsl: "hsl(120, 73%, 75%)", rgb: "rgb(144, 238, 144)"},
|
|
||||||
{authored: "lightgrey", name: "lightgray", hex: "#d3d3d3", hsl: "hsl(0, 0%, 83%)", rgb: "rgb(211, 211, 211)"},
|
|
||||||
{authored: "lightpink", name: "lightpink", hex: "#ffb6c1", hsl: "hsl(351, 100%, 86%)", rgb: "rgb(255, 182, 193)"},
|
|
||||||
{authored: "lightsalmon", name: "lightsalmon", hex: "#ffa07a", hsl: "hsl(17, 100%, 74%)", rgb: "rgb(255, 160, 122)"},
|
|
||||||
{authored: "lightseagreen", name: "lightseagreen", hex: "#20b2aa", hsl: "hsl(177, 70%, 41%)", rgb: "rgb(32, 178, 170)"},
|
|
||||||
{authored: "lightskyblue", name: "lightskyblue", hex: "#87cefa", hsl: "hsl(203, 92%, 75%)", rgb: "rgb(135, 206, 250)"},
|
|
||||||
{authored: "lightslategray", name: "lightslategray", hex: "#789", hsl: "hsl(210, 14%, 53%)", rgb: "rgb(119, 136, 153)"},
|
|
||||||
{authored: "lightslategrey", name: "lightslategray", hex: "#789", hsl: "hsl(210, 14%, 53%)", rgb: "rgb(119, 136, 153)"},
|
|
||||||
{authored: "lightsteelblue", name: "lightsteelblue", hex: "#b0c4de", hsl: "hsl(214, 41%, 78%)", rgb: "rgb(176, 196, 222)"},
|
|
||||||
{authored: "lightyellow", name: "lightyellow", hex: "#ffffe0", hsl: "hsl(60, 100%, 94%)", rgb: "rgb(255, 255, 224)"},
|
|
||||||
{authored: "lime", name: "lime", hex: "#0f0", hsl: "hsl(120, 100%, 50%)", rgb: "rgb(0, 255, 0)"},
|
|
||||||
{authored: "limegreen", name: "limegreen", hex: "#32cd32", hsl: "hsl(120, 61%, 50%)", rgb: "rgb(50, 205, 50)"},
|
|
||||||
{authored: "linen", name: "linen", hex: "#faf0e6", hsl: "hsl(30, 67%, 94%)", rgb: "rgb(250, 240, 230)"},
|
|
||||||
{authored: "magenta", name: "fuchsia", hex: "#f0f", hsl: "hsl(300, 100%, 50%)", rgb: "rgb(255, 0, 255)"},
|
|
||||||
{authored: "maroon", name: "maroon", hex: "#800000", hsl: "hsl(0, 100%, 25%)", rgb: "rgb(128, 0, 0)"},
|
|
||||||
{authored: "mediumaquamarine", name: "mediumaquamarine", hex: "#66cdaa", hsl: "hsl(160, 51%, 60%)", rgb: "rgb(102, 205, 170)"},
|
|
||||||
{authored: "mediumblue", name: "mediumblue", hex: "#0000cd", hsl: "hsl(240, 100%, 40%)", rgb: "rgb(0, 0, 205)"},
|
|
||||||
{authored: "mediumorchid", name: "mediumorchid", hex: "#ba55d3", hsl: "hsl(288, 59%, 58%)", rgb: "rgb(186, 85, 211)"},
|
|
||||||
{authored: "mediumpurple", name: "mediumpurple", hex: "#9370db", hsl: "hsl(260, 60%, 65%)", rgb: "rgb(147, 112, 219)"},
|
|
||||||
{authored: "mediumseagreen", name: "mediumseagreen", hex: "#3cb371", hsl: "hsl(147, 50%, 47%)", rgb: "rgb(60, 179, 113)"},
|
|
||||||
{authored: "mediumslateblue", name: "mediumslateblue", hex: "#7b68ee", hsl: "hsl(249, 80%, 67%)", rgb: "rgb(123, 104, 238)"},
|
|
||||||
{authored: "mediumspringgreen", name: "mediumspringgreen", hex: "#00fa9a", hsl: "hsl(157, 100%, 49%)", rgb: "rgb(0, 250, 154)"},
|
|
||||||
{authored: "mediumturquoise", name: "mediumturquoise", hex: "#48d1cc", hsl: "hsl(178, 60%, 55%)", rgb: "rgb(72, 209, 204)"},
|
|
||||||
{authored: "mediumvioletred", name: "mediumvioletred", hex: "#c71585", hsl: "hsl(322, 81%, 43%)", rgb: "rgb(199, 21, 133)"},
|
|
||||||
{authored: "midnightblue", name: "midnightblue", hex: "#191970", hsl: "hsl(240, 64%, 27%)", rgb: "rgb(25, 25, 112)"},
|
|
||||||
{authored: "mintcream", name: "mintcream", hex: "#f5fffa", hsl: "hsl(150, 100%, 98%)", rgb: "rgb(245, 255, 250)"},
|
|
||||||
{authored: "mistyrose", name: "mistyrose", hex: "#ffe4e1", hsl: "hsl(6, 100%, 94%)", rgb: "rgb(255, 228, 225)"},
|
|
||||||
{authored: "moccasin", name: "moccasin", hex: "#ffe4b5", hsl: "hsl(38, 100%, 85%)", rgb: "rgb(255, 228, 181)"},
|
|
||||||
{authored: "navajowhite", name: "navajowhite", hex: "#ffdead", hsl: "hsl(36, 100%, 84%)", rgb: "rgb(255, 222, 173)"},
|
|
||||||
{authored: "navy", name: "navy", hex: "#000080", hsl: "hsl(240, 100%, 25%)", rgb: "rgb(0, 0, 128)"},
|
|
||||||
{authored: "oldlace", name: "oldlace", hex: "#fdf5e6", hsl: "hsl(39, 85%, 95%)", rgb: "rgb(253, 245, 230)"},
|
|
||||||
{authored: "olive", name: "olive", hex: "#808000", hsl: "hsl(60, 100%, 25%)", rgb: "rgb(128, 128, 0)"},
|
|
||||||
{authored: "olivedrab", name: "olivedrab", hex: "#6b8e23", hsl: "hsl(80, 60%, 35%)", rgb: "rgb(107, 142, 35)"},
|
|
||||||
{authored: "orange", name: "orange", hex: "#ffa500", hsl: "hsl(39, 100%, 50%)", rgb: "rgb(255, 165, 0)"},
|
|
||||||
{authored: "orangered", name: "orangered", hex: "#ff4500", hsl: "hsl(16, 100%, 50%)", rgb: "rgb(255, 69, 0)"},
|
|
||||||
{authored: "orchid", name: "orchid", hex: "#da70d6", hsl: "hsl(302, 59%, 65%)", rgb: "rgb(218, 112, 214)"},
|
|
||||||
{authored: "palegoldenrod", name: "palegoldenrod", hex: "#eee8aa", hsl: "hsl(55, 67%, 80%)", rgb: "rgb(238, 232, 170)"},
|
|
||||||
{authored: "palegreen", name: "palegreen", hex: "#98fb98", hsl: "hsl(120, 93%, 79%)", rgb: "rgb(152, 251, 152)"},
|
|
||||||
{authored: "paleturquoise", name: "paleturquoise", hex: "#afeeee", hsl: "hsl(180, 65%, 81%)", rgb: "rgb(175, 238, 238)"},
|
|
||||||
{authored: "palevioletred", name: "palevioletred", hex: "#db7093", hsl: "hsl(340, 60%, 65%)", rgb: "rgb(219, 112, 147)"},
|
|
||||||
{authored: "papayawhip", name: "papayawhip", hex: "#ffefd5", hsl: "hsl(37, 100%, 92%)", rgb: "rgb(255, 239, 213)"},
|
|
||||||
{authored: "peachpuff", name: "peachpuff", hex: "#ffdab9", hsl: "hsl(28, 100%, 86%)", rgb: "rgb(255, 218, 185)"},
|
|
||||||
{authored: "peru", name: "peru", hex: "#cd853f", hsl: "hsl(30, 59%, 53%)", rgb: "rgb(205, 133, 63)"},
|
|
||||||
{authored: "pink", name: "pink", hex: "#ffc0cb", hsl: "hsl(350, 100%, 88%)", rgb: "rgb(255, 192, 203)"},
|
|
||||||
{authored: "plum", name: "plum", hex: "#dda0dd", hsl: "hsl(300, 47%, 75%)", rgb: "rgb(221, 160, 221)"},
|
|
||||||
{authored: "powderblue", name: "powderblue", hex: "#b0e0e6", hsl: "hsl(187, 52%, 80%)", rgb: "rgb(176, 224, 230)"},
|
|
||||||
{authored: "purple", name: "purple", hex: "#800080", hsl: "hsl(300, 100%, 25%)", rgb: "rgb(128, 0, 128)"},
|
|
||||||
{authored: "rebeccapurple", name: "rebeccapurple", hex: "#639", hsl: "hsl(270, 50%, 40%)", rgb: "rgb(102, 51, 153)"},
|
|
||||||
{authored: "red", name: "red", hex: "#f00", hsl: "hsl(0, 100%, 50%)", rgb: "rgb(255, 0, 0)"},
|
|
||||||
{authored: "rosybrown", name: "rosybrown", hex: "#bc8f8f", hsl: "hsl(0, 25%, 65%)", rgb: "rgb(188, 143, 143)"},
|
|
||||||
{authored: "royalblue", name: "royalblue", hex: "#4169e1", hsl: "hsl(225, 73%, 57%)", rgb: "rgb(65, 105, 225)"},
|
|
||||||
{authored: "saddlebrown", name: "saddlebrown", hex: "#8b4513", hsl: "hsl(25, 76%, 31%)", rgb: "rgb(139, 69, 19)"},
|
|
||||||
{authored: "salmon", name: "salmon", hex: "#fa8072", hsl: "hsl(6, 93%, 71%)", rgb: "rgb(250, 128, 114)"},
|
|
||||||
{authored: "sandybrown", name: "sandybrown", hex: "#f4a460", hsl: "hsl(28, 87%, 67%)", rgb: "rgb(244, 164, 96)"},
|
|
||||||
{authored: "seagreen", name: "seagreen", hex: "#2e8b57", hsl: "hsl(146, 50%, 36%)", rgb: "rgb(46, 139, 87)"},
|
|
||||||
{authored: "seashell", name: "seashell", hex: "#fff5ee", hsl: "hsl(25, 100%, 97%)", rgb: "rgb(255, 245, 238)"},
|
|
||||||
{authored: "sienna", name: "sienna", hex: "#a0522d", hsl: "hsl(19, 56%, 40%)", rgb: "rgb(160, 82, 45)"},
|
|
||||||
{authored: "silver", name: "silver", hex: "#c0c0c0", hsl: "hsl(0, 0%, 75%)", rgb: "rgb(192, 192, 192)"},
|
|
||||||
{authored: "skyblue", name: "skyblue", hex: "#87ceeb", hsl: "hsl(197, 71%, 73%)", rgb: "rgb(135, 206, 235)"},
|
|
||||||
{authored: "slateblue", name: "slateblue", hex: "#6a5acd", hsl: "hsl(248, 53%, 58%)", rgb: "rgb(106, 90, 205)"},
|
|
||||||
{authored: "slategray", name: "slategray", hex: "#708090", hsl: "hsl(210, 13%, 50%)", rgb: "rgb(112, 128, 144)"},
|
|
||||||
{authored: "slategrey", name: "slategray", hex: "#708090", hsl: "hsl(210, 13%, 50%)", rgb: "rgb(112, 128, 144)"},
|
|
||||||
{authored: "snow", name: "snow", hex: "#fffafa", hsl: "hsl(0, 100%, 99%)", rgb: "rgb(255, 250, 250)"},
|
|
||||||
{authored: "springgreen", name: "springgreen", hex: "#00ff7f", hsl: "hsl(150, 100%, 50%)", rgb: "rgb(0, 255, 127)"},
|
|
||||||
{authored: "steelblue", name: "steelblue", hex: "#4682b4", hsl: "hsl(207, 44%, 49%)", rgb: "rgb(70, 130, 180)"},
|
|
||||||
{authored: "tan", name: "tan", hex: "#d2b48c", hsl: "hsl(34, 44%, 69%)", rgb: "rgb(210, 180, 140)"},
|
|
||||||
{authored: "teal", name: "teal", hex: "#008080", hsl: "hsl(180, 100%, 25%)", rgb: "rgb(0, 128, 128)"},
|
|
||||||
{authored: "thistle", name: "thistle", hex: "#d8bfd8", hsl: "hsl(300, 24%, 80%)", rgb: "rgb(216, 191, 216)"},
|
|
||||||
{authored: "tomato", name: "tomato", hex: "#ff6347", hsl: "hsl(9, 100%, 64%)", rgb: "rgb(255, 99, 71)"},
|
|
||||||
{authored: "turquoise", name: "turquoise", hex: "#40e0d0", hsl: "hsl(174, 72%, 56%)", rgb: "rgb(64, 224, 208)"},
|
|
||||||
{authored: "violet", name: "violet", hex: "#ee82ee", hsl: "hsl(300, 76%, 72%)", rgb: "rgb(238, 130, 238)"},
|
|
||||||
{authored: "wheat", name: "wheat", hex: "#f5deb3", hsl: "hsl(39, 77%, 83%)", rgb: "rgb(245, 222, 179)"},
|
|
||||||
{authored: "white", name: "white", hex: "#fff", hsl: "hsl(0, 0%, 100%)", rgb: "rgb(255, 255, 255)"},
|
|
||||||
{authored: "whitesmoke", name: "whitesmoke", hex: "#f5f5f5", hsl: "hsl(0, 0%, 96%)", rgb: "rgb(245, 245, 245)"},
|
|
||||||
{authored: "yellow", name: "yellow", hex: "#ff0", hsl: "hsl(60, 100%, 50%)", rgb: "rgb(255, 255, 0)"},
|
|
||||||
{authored: "yellowgreen", name: "yellowgreen", hex: "#9acd32", hsl: "hsl(80, 61%, 50%)", rgb: "rgb(154, 205, 50)"},
|
|
||||||
{authored: "rgba(0, 0, 0, 0)", name: "#0000", hex: "#0000", hsl: "hsla(0, 0%, 0%, 0)", rgb: "rgba(0, 0, 0, 0)"},
|
|
||||||
{authored: "hsla(0, 0%, 0%, 0)", name: "#0000", hex: "#0000", hsl: "hsla(0, 0%, 0%, 0)", rgb: "rgba(0, 0, 0, 0)"},
|
|
||||||
{authored: "rgba(50, 60, 70, 0.5)", name: "#323c4680", hex: "#323c4680", hsl: "hsla(210, 17%, 24%, 0.5)", rgb: "rgba(50, 60, 70, 0.5)"},
|
|
||||||
{authored: "rgba(0, 0, 0, 0.3)", name: "#0000004d", hex: "#0000004d", hsl: "hsla(0, 0%, 0%, 0.3)", rgb: "rgba(0, 0, 0, 0.3)"},
|
|
||||||
{authored: "rgba(255, 255, 255, 0.6)", name: "#fff9", hex: "#fff9", hsl: "hsla(0, 0%, 100%, 0.6)", rgb: "rgba(255, 255, 255, 0.6)"},
|
|
||||||
{authored: "rgba(127, 89, 45, 1)", name: "#7f592d", hex: "#7f592d", hsl: "hsl(32, 48%, 34%)", rgb: "rgb(127, 89, 45)"},
|
|
||||||
{authored: "hsla(19.304, 56%, 40%, 1)", name: "#9f512c", hex: "#9f512c", hsl: "hsl(19, 57%, 40%)", rgb: "rgb(159, 81, 44)"},
|
|
||||||
{authored: "#f089", name: "#f089", hex: "#f089", hsl: "hsla(328, 100%, 50%, 0.6)", rgb: "rgba(255, 0, 136, 0.6)"},
|
|
||||||
{authored: "#00ff8080", name: "#00ff8080", hex: "#00ff8080", hsl: "hsla(150, 100%, 50%, 0.5)", rgb: "rgba(0, 255, 128, 0.5)"},
|
|
||||||
{authored: "currentcolor", name: "currentcolor", hex: "currentcolor", hsl: "currentcolor", rgb: "currentcolor"},
|
|
||||||
{authored: "inherit", name: "inherit", hex: "inherit", hsl: "inherit", rgb: "inherit"},
|
|
||||||
{authored: "initial", name: "initial", hex: "initial", hsl: "initial", rgb: "initial"},
|
|
||||||
{authored: "invalidColor", name: "", hex: "", hsl: "", rgb: ""},
|
|
||||||
{authored: "transparent", name: "transparent", hex: "transparent", hsl: "transparent", rgb: "transparent"},
|
|
||||||
{authored: "unset", name: "unset", hex: "unset", hsl: "unset", rgb: "unset"}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,171 @@
|
||||||
|
function getFixtureColorData() {
|
||||||
|
return [
|
||||||
|
{authored: "aliceblue", name: "aliceblue", hex: "#f0f8ff", hsl: "hsl(208, 100%, 97.1%)", rgb: "rgb(240, 248, 255)", cycle: 4},
|
||||||
|
{authored: "antiquewhite", name: "antiquewhite", hex: "#faebd7", hsl: "hsl(34.3, 77.8%, 91.2%)", rgb: "rgb(250, 235, 215)", cycle: 4},
|
||||||
|
{authored: "aqua", name: "aqua", hex: "#0ff", hsl: "hsl(180, 100%, 50%)", rgb: "rgb(0, 255, 255)", cycle: 4},
|
||||||
|
{authored: "aquamarine", name: "aquamarine", hex: "#7fffd4", hsl: "hsl(159.8, 100%, 74.9%)", rgb: "rgb(127, 255, 212)", cycle: 4},
|
||||||
|
{authored: "azure", name: "azure", hex: "#f0ffff", hsl: "hsl(180, 100%, 97.1%)", rgb: "rgb(240, 255, 255)", cycle: 4},
|
||||||
|
{authored: "beige", name: "beige", hex: "#f5f5dc", hsl: "hsl(60, 55.6%, 91.2%)", rgb: "rgb(245, 245, 220)", cycle: 4},
|
||||||
|
{authored: "bisque", name: "bisque", hex: "#ffe4c4", hsl: "hsl(32.5, 100%, 88.4%)", rgb: "rgb(255, 228, 196)", cycle: 4},
|
||||||
|
{authored: "black", name: "black", hex: "#000", hsl: "hsl(0, 0%, 0%)", rgb: "rgb(0, 0, 0)", cycle: 4},
|
||||||
|
{authored: "blanchedalmond", name: "blanchedalmond", hex: "#ffebcd", hsl: "hsl(36, 100%, 90.2%)", rgb: "rgb(255, 235, 205)", cycle: 4},
|
||||||
|
{authored: "blue", name: "blue", hex: "#00f", hsl: "hsl(240, 100%, 50%)", rgb: "rgb(0, 0, 255)", cycle: 4},
|
||||||
|
{authored: "blueviolet", name: "blueviolet", hex: "#8a2be2", hsl: "hsl(271.1, 75.9%, 52.7%)", rgb: "rgb(138, 43, 226)", cycle: 4},
|
||||||
|
{authored: "brown", name: "brown", hex: "#a52a2a", hsl: "hsl(0, 59.4%, 40.6%)", rgb: "rgb(165, 42, 42)", cycle: 4},
|
||||||
|
{authored: "burlywood", name: "burlywood", hex: "#deb887", hsl: "hsl(33.8, 56.9%, 70%)", rgb: "rgb(222, 184, 135)", cycle: 4},
|
||||||
|
{authored: "cadetblue", name: "cadetblue", hex: "#5f9ea0", hsl: "hsl(181.8, 25.5%, 50%)", rgb: "rgb(95, 158, 160)", cycle: 4},
|
||||||
|
{authored: "chartreuse", name: "chartreuse", hex: "#7fff00", hsl: "hsl(90.1, 100%, 50%)", rgb: "rgb(127, 255, 0)", cycle: 4},
|
||||||
|
{authored: "chocolate", name: "chocolate", hex: "#d2691e", hsl: "hsl(25, 75%, 47.1%)", rgb: "rgb(210, 105, 30)", cycle: 4},
|
||||||
|
{authored: "coral", name: "coral", hex: "#ff7f50", hsl: "hsl(16.1, 100%, 65.7%)", rgb: "rgb(255, 127, 80)", cycle: 4},
|
||||||
|
{authored: "cornflowerblue", name: "cornflowerblue", hex: "#6495ed", hsl: "hsl(218.5, 79.2%, 66.1%)", rgb: "rgb(100, 149, 237)", cycle: 4},
|
||||||
|
{authored: "cornsilk", name: "cornsilk", hex: "#fff8dc", hsl: "hsl(48, 100%, 93.1%)", rgb: "rgb(255, 248, 220)", cycle: 4},
|
||||||
|
{authored: "crimson", name: "crimson", hex: "#dc143c", hsl: "hsl(348, 83.3%, 47.1%)", rgb: "rgb(220, 20, 60)", cycle: 4},
|
||||||
|
{authored: "cyan", name: "aqua", hex: "#0ff", hsl: "hsl(180, 100%, 50%)", rgb: "rgb(0, 255, 255)", cycle: 4},
|
||||||
|
{authored: "darkblue", name: "darkblue", hex: "#00008b", hsl: "hsl(240, 100%, 27.3%)", rgb: "rgb(0, 0, 139)", cycle: 4},
|
||||||
|
{authored: "darkcyan", name: "darkcyan", hex: "#008b8b", hsl: "hsl(180, 100%, 27.3%)", rgb: "rgb(0, 139, 139)", cycle: 4},
|
||||||
|
{authored: "darkgoldenrod", name: "darkgoldenrod", hex: "#b8860b", hsl: "hsl(42.7, 88.7%, 38.2%)", rgb: "rgb(184, 134, 11)", cycle: 4},
|
||||||
|
{authored: "darkgray", name: "darkgray", hex: "#a9a9a9", hsl: "hsl(0, 0%, 66.3%)", rgb: "rgb(169, 169, 169)", cycle: 4},
|
||||||
|
{authored: "darkgreen", name: "darkgreen", hex: "#006400", hsl: "hsl(120, 100%, 19.6%)", rgb: "rgb(0, 100, 0)", cycle: 4},
|
||||||
|
{authored: "darkgrey", name: "darkgray", hex: "#a9a9a9", hsl: "hsl(0, 0%, 66.3%)", rgb: "rgb(169, 169, 169)", cycle: 4},
|
||||||
|
{authored: "darkkhaki", name: "darkkhaki", hex: "#bdb76b", hsl: "hsl(55.6, 38.3%, 58%)", rgb: "rgb(189, 183, 107)", cycle: 4},
|
||||||
|
{authored: "darkmagenta", name: "darkmagenta", hex: "#8b008b", hsl: "hsl(300, 100%, 27.3%)", rgb: "rgb(139, 0, 139)", cycle: 4},
|
||||||
|
{authored: "darkolivegreen", name: "darkolivegreen", hex: "#556b2f", hsl: "hsl(82, 39%, 30.2%)", rgb: "rgb(85, 107, 47)", cycle: 4},
|
||||||
|
{authored: "darkorange", name: "darkorange", hex: "#ff8c00", hsl: "hsl(32.9, 100%, 50%)", rgb: "rgb(255, 140, 0)", cycle: 4},
|
||||||
|
{authored: "darkorchid", name: "darkorchid", hex: "#9932cc", hsl: "hsl(280.1, 60.6%, 49.8%)", rgb: "rgb(153, 50, 204)", cycle: 4},
|
||||||
|
{authored: "darkred", name: "darkred", hex: "#8b0000", hsl: "hsl(0, 100%, 27.3%)", rgb: "rgb(139, 0, 0)", cycle: 4},
|
||||||
|
{authored: "darksalmon", name: "darksalmon", hex: "#e9967a", hsl: "hsl(15.1, 71.6%, 69.6%)", rgb: "rgb(233, 150, 122)", cycle: 4},
|
||||||
|
{authored: "darkseagreen", name: "darkseagreen", hex: "#8fbc8f", hsl: "hsl(120, 25.1%, 64.9%)", rgb: "rgb(143, 188, 143)", cycle: 4},
|
||||||
|
{authored: "darkslateblue", name: "darkslateblue", hex: "#483d8b", hsl: "hsl(248.5, 39%, 39.2%)", rgb: "rgb(72, 61, 139)", cycle: 4},
|
||||||
|
{authored: "darkslategray", name: "darkslategray", hex: "#2f4f4f", hsl: "hsl(180, 25.4%, 24.7%)", rgb: "rgb(47, 79, 79)", cycle: 4},
|
||||||
|
{authored: "darkslategrey", name: "darkslategray", hex: "#2f4f4f", hsl: "hsl(180, 25.4%, 24.7%)", rgb: "rgb(47, 79, 79)", cycle: 4},
|
||||||
|
{authored: "darkturquoise", name: "darkturquoise", hex: "#00ced1", hsl: "hsl(180.9, 100%, 41%)", rgb: "rgb(0, 206, 209)", cycle: 4},
|
||||||
|
{authored: "darkviolet", name: "darkviolet", hex: "#9400d3", hsl: "hsl(282.1, 100%, 41.4%)", rgb: "rgb(148, 0, 211)", cycle: 4},
|
||||||
|
{authored: "deeppink", name: "deeppink", hex: "#ff1493", hsl: "hsl(327.6, 100%, 53.9%)", rgb: "rgb(255, 20, 147)", cycle: 4},
|
||||||
|
{authored: "deepskyblue", name: "deepskyblue", hex: "#00bfff", hsl: "hsl(195.1, 100%, 50%)", rgb: "rgb(0, 191, 255)", cycle: 4},
|
||||||
|
{authored: "dimgray", name: "dimgray", hex: "#696969", hsl: "hsl(0, 0%, 41.2%)", rgb: "rgb(105, 105, 105)", cycle: 4},
|
||||||
|
{authored: "dodgerblue", name: "dodgerblue", hex: "#1e90ff", hsl: "hsl(209.6, 100%, 55.9%)", rgb: "rgb(30, 144, 255)", cycle: 4},
|
||||||
|
{authored: "firebrick", name: "firebrick", hex: "#b22222", hsl: "hsl(0, 67.9%, 41.6%)", rgb: "rgb(178, 34, 34)", cycle: 4},
|
||||||
|
{authored: "floralwhite", name: "floralwhite", hex: "#fffaf0", hsl: "hsl(40, 100%, 97.1%)", rgb: "rgb(255, 250, 240)", cycle: 4},
|
||||||
|
{authored: "forestgreen", name: "forestgreen", hex: "#228b22", hsl: "hsl(120, 60.7%, 33.9%)", rgb: "rgb(34, 139, 34)", cycle: 4},
|
||||||
|
{authored: "fuchsia", name: "fuchsia", hex: "#f0f", hsl: "hsl(300, 100%, 50%)", rgb: "rgb(255, 0, 255)", cycle: 4},
|
||||||
|
{authored: "gainsboro", name: "gainsboro", hex: "#dcdcdc", hsl: "hsl(0, 0%, 86.3%)", rgb: "rgb(220, 220, 220)", cycle: 4},
|
||||||
|
{authored: "ghostwhite", name: "ghostwhite", hex: "#f8f8ff", hsl: "hsl(240, 100%, 98.6%)", rgb: "rgb(248, 248, 255)", cycle: 4},
|
||||||
|
{authored: "gold", name: "gold", hex: "#ffd700", hsl: "hsl(50.6, 100%, 50%)", rgb: "rgb(255, 215, 0)", cycle: 4},
|
||||||
|
{authored: "goldenrod", name: "goldenrod", hex: "#daa520", hsl: "hsl(42.9, 74.4%, 49%)", rgb: "rgb(218, 165, 32)", cycle: 4},
|
||||||
|
{authored: "gray", name: "gray", hex: "#808080", hsl: "hsl(0, 0%, 50.2%)", rgb: "rgb(128, 128, 128)", cycle: 4},
|
||||||
|
{authored: "green", name: "green", hex: "#008000", hsl: "hsl(120, 100%, 25.1%)", rgb: "rgb(0, 128, 0)", cycle: 4},
|
||||||
|
{authored: "greenyellow", name: "greenyellow", hex: "#adff2f", hsl: "hsl(83.7, 100%, 59.2%)", rgb: "rgb(173, 255, 47)", cycle: 4},
|
||||||
|
{authored: "grey", name: "gray", hex: "#808080", hsl: "hsl(0, 0%, 50.2%)", rgb: "rgb(128, 128, 128)", cycle: 4},
|
||||||
|
{authored: "honeydew", name: "honeydew", hex: "#f0fff0", hsl: "hsl(120, 100%, 97.1%)", rgb: "rgb(240, 255, 240)", cycle: 4},
|
||||||
|
{authored: "hotpink", name: "hotpink", hex: "#ff69b4", hsl: "hsl(330, 100%, 70.6%)", rgb: "rgb(255, 105, 180)", cycle: 4},
|
||||||
|
{authored: "indianred", name: "indianred", hex: "#cd5c5c", hsl: "hsl(0, 53.1%, 58.2%)", rgb: "rgb(205, 92, 92)", cycle: 4},
|
||||||
|
{authored: "indigo", name: "indigo", hex: "#4b0082", hsl: "hsl(274.6, 100%, 25.5%)", rgb: "rgb(75, 0, 130)", cycle: 4},
|
||||||
|
{authored: "ivory", name: "ivory", hex: "#fffff0", hsl: "hsl(60, 100%, 97.1%)", rgb: "rgb(255, 255, 240)", cycle: 4},
|
||||||
|
{authored: "khaki", name: "khaki", hex: "#f0e68c", hsl: "hsl(54, 76.9%, 74.5%)", rgb: "rgb(240, 230, 140)", cycle: 4},
|
||||||
|
{authored: "lavender", name: "lavender", hex: "#e6e6fa", hsl: "hsl(240, 66.7%, 94.1%)", rgb: "rgb(230, 230, 250)", cycle: 4},
|
||||||
|
{authored: "lavenderblush", name: "lavenderblush", hex: "#fff0f5", hsl: "hsl(340, 100%, 97.1%)", rgb: "rgb(255, 240, 245)", cycle: 4},
|
||||||
|
{authored: "lawngreen", name: "lawngreen", hex: "#7cfc00", hsl: "hsl(90.5, 100%, 49.4%)", rgb: "rgb(124, 252, 0)", cycle: 4},
|
||||||
|
{authored: "lemonchiffon", name: "lemonchiffon", hex: "#fffacd", hsl: "hsl(54, 100%, 90.2%)", rgb: "rgb(255, 250, 205)", cycle: 4},
|
||||||
|
{authored: "lightblue", name: "lightblue", hex: "#add8e6", hsl: "hsl(194.7, 53.3%, 79%)", rgb: "rgb(173, 216, 230)", cycle: 4},
|
||||||
|
{authored: "lightcoral", name: "lightcoral", hex: "#f08080", hsl: "hsl(0, 78.9%, 72.2%)", rgb: "rgb(240, 128, 128)", cycle: 4},
|
||||||
|
{authored: "lightcyan", name: "lightcyan", hex: "#e0ffff", hsl: "hsl(180, 100%, 93.9%)", rgb: "rgb(224, 255, 255)", cycle: 4},
|
||||||
|
{authored: "lightgoldenrodyellow", name: "lightgoldenrodyellow", hex: "#fafad2", hsl: "hsl(60, 80%, 90.2%)", rgb: "rgb(250, 250, 210)", cycle: 4},
|
||||||
|
{authored: "lightgray", name: "lightgray", hex: "#d3d3d3", hsl: "hsl(0, 0%, 82.7%)", rgb: "rgb(211, 211, 211)", cycle: 4},
|
||||||
|
{authored: "lightgreen", name: "lightgreen", hex: "#90ee90", hsl: "hsl(120, 73.4%, 74.9%)", rgb: "rgb(144, 238, 144)", cycle: 4},
|
||||||
|
{authored: "lightgrey", name: "lightgray", hex: "#d3d3d3", hsl: "hsl(0, 0%, 82.7%)", rgb: "rgb(211, 211, 211)", cycle: 4},
|
||||||
|
{authored: "lightpink", name: "lightpink", hex: "#ffb6c1", hsl: "hsl(351, 100%, 85.7%)", rgb: "rgb(255, 182, 193)", cycle: 4},
|
||||||
|
{authored: "lightsalmon", name: "lightsalmon", hex: "#ffa07a", hsl: "hsl(17.1, 100%, 73.9%)", rgb: "rgb(255, 160, 122)", cycle: 4},
|
||||||
|
{authored: "lightseagreen", name: "lightseagreen", hex: "#20b2aa", hsl: "hsl(176.7, 69.5%, 41.2%)", rgb: "rgb(32, 178, 170)", cycle: 4},
|
||||||
|
{authored: "lightskyblue", name: "lightskyblue", hex: "#87cefa", hsl: "hsl(203, 92%, 75.5%)", rgb: "rgb(135, 206, 250)", cycle: 4},
|
||||||
|
{authored: "lightslategray", name: "lightslategray", hex: "#789", hsl: "hsl(210, 14.3%, 53.3%)", rgb: "rgb(119, 136, 153)", cycle: 4},
|
||||||
|
{authored: "lightslategrey", name: "lightslategray", hex: "#789", hsl: "hsl(210, 14.3%, 53.3%)", rgb: "rgb(119, 136, 153)", cycle: 4},
|
||||||
|
{authored: "lightsteelblue", name: "lightsteelblue", hex: "#b0c4de", hsl: "hsl(213.9, 41.1%, 78%)", rgb: "rgb(176, 196, 222)", cycle: 4},
|
||||||
|
{authored: "lightyellow", name: "lightyellow", hex: "#ffffe0", hsl: "hsl(60, 100%, 93.9%)", rgb: "rgb(255, 255, 224)", cycle: 4},
|
||||||
|
{authored: "lime", name: "lime", hex: "#0f0", hsl: "hsl(120, 100%, 50%)", rgb: "rgb(0, 255, 0)", cycle: 4},
|
||||||
|
{authored: "limegreen", name: "limegreen", hex: "#32cd32", hsl: "hsl(120, 60.8%, 50%)", rgb: "rgb(50, 205, 50)", cycle: 4},
|
||||||
|
{authored: "linen", name: "linen", hex: "#faf0e6", hsl: "hsl(30, 66.7%, 94.1%)", rgb: "rgb(250, 240, 230)", cycle: 4},
|
||||||
|
{authored: "magenta", name: "fuchsia", hex: "#f0f", hsl: "hsl(300, 100%, 50%)", rgb: "rgb(255, 0, 255)", cycle: 4},
|
||||||
|
{authored: "maroon", name: "maroon", hex: "#800000", hsl: "hsl(0, 100%, 25.1%)", rgb: "rgb(128, 0, 0)", cycle: 4},
|
||||||
|
{authored: "mediumaquamarine", name: "mediumaquamarine", hex: "#66cdaa", hsl: "hsl(159.6, 50.7%, 60.2%)", rgb: "rgb(102, 205, 170)", cycle: 4},
|
||||||
|
{authored: "mediumblue", name: "mediumblue", hex: "#0000cd", hsl: "hsl(240, 100%, 40.2%)", rgb: "rgb(0, 0, 205)", cycle: 4},
|
||||||
|
{authored: "mediumorchid", name: "mediumorchid", hex: "#ba55d3", hsl: "hsl(288.1, 58.9%, 58%)", rgb: "rgb(186, 85, 211)", cycle: 4},
|
||||||
|
{authored: "mediumpurple", name: "mediumpurple", hex: "#9370db", hsl: "hsl(259.6, 59.8%, 64.9%)", rgb: "rgb(147, 112, 219)", cycle: 4},
|
||||||
|
{authored: "mediumseagreen", name: "mediumseagreen", hex: "#3cb371", hsl: "hsl(146.7, 49.8%, 46.9%)", rgb: "rgb(60, 179, 113)", cycle: 4},
|
||||||
|
{authored: "mediumslateblue", name: "mediumslateblue", hex: "#7b68ee", hsl: "hsl(248.5, 79.8%, 67.1%)", rgb: "rgb(123, 104, 238)", cycle: 4},
|
||||||
|
{authored: "mediumspringgreen", name: "mediumspringgreen", hex: "#00fa9a", hsl: "hsl(157, 100%, 49%)", rgb: "rgb(0, 250, 154)", cycle: 4},
|
||||||
|
{authored: "mediumturquoise", name: "mediumturquoise", hex: "#48d1cc", hsl: "hsl(177.8, 59.8%, 55.1%)", rgb: "rgb(72, 209, 204)", cycle: 4},
|
||||||
|
{authored: "mediumvioletred", name: "mediumvioletred", hex: "#c71585", hsl: "hsl(322.2, 80.9%, 43.1%)", rgb: "rgb(199, 21, 133)", cycle: 4},
|
||||||
|
{authored: "midnightblue", name: "midnightblue", hex: "#191970", hsl: "hsl(240, 63.5%, 26.9%)", rgb: "rgb(25, 25, 112)", cycle: 4},
|
||||||
|
{authored: "mintcream", name: "mintcream", hex: "#f5fffa", hsl: "hsl(150, 100%, 98%)", rgb: "rgb(245, 255, 250)", cycle: 4},
|
||||||
|
{authored: "mistyrose", name: "mistyrose", hex: "#ffe4e1", hsl: "hsl(6, 100%, 94.1%)", rgb: "rgb(255, 228, 225)", cycle: 4},
|
||||||
|
{authored: "moccasin", name: "moccasin", hex: "#ffe4b5", hsl: "hsl(38.1, 100%, 85.5%)", rgb: "rgb(255, 228, 181)", cycle: 4},
|
||||||
|
{authored: "navajowhite", name: "navajowhite", hex: "#ffdead", hsl: "hsl(35.9, 100%, 83.9%)", rgb: "rgb(255, 222, 173)", cycle: 4},
|
||||||
|
{authored: "navy", name: "navy", hex: "#000080", hsl: "hsl(240, 100%, 25.1%)", rgb: "rgb(0, 0, 128)", cycle: 4},
|
||||||
|
{authored: "oldlace", name: "oldlace", hex: "#fdf5e6", hsl: "hsl(39.1, 85.2%, 94.7%)", rgb: "rgb(253, 245, 230)", cycle: 4},
|
||||||
|
{authored: "olive", name: "olive", hex: "#808000", hsl: "hsl(60, 100%, 25.1%)", rgb: "rgb(128, 128, 0)", cycle: 4},
|
||||||
|
{authored: "olivedrab", name: "olivedrab", hex: "#6b8e23", hsl: "hsl(79.6, 60.5%, 34.7%)", rgb: "rgb(107, 142, 35)", cycle: 4},
|
||||||
|
{authored: "orange", name: "orange", hex: "#ffa500", hsl: "hsl(38.8, 100%, 50%)", rgb: "rgb(255, 165, 0)", cycle: 4},
|
||||||
|
{authored: "orangered", name: "orangered", hex: "#ff4500", hsl: "hsl(16.2, 100%, 50%)", rgb: "rgb(255, 69, 0)", cycle: 4},
|
||||||
|
{authored: "orchid", name: "orchid", hex: "#da70d6", hsl: "hsl(302.3, 58.9%, 64.7%)", rgb: "rgb(218, 112, 214)", cycle: 4},
|
||||||
|
{authored: "palegoldenrod", name: "palegoldenrod", hex: "#eee8aa", hsl: "hsl(54.7, 66.7%, 80%)", rgb: "rgb(238, 232, 170)", cycle: 4},
|
||||||
|
{authored: "palegreen", name: "palegreen", hex: "#98fb98", hsl: "hsl(120, 92.5%, 79%)", rgb: "rgb(152, 251, 152)", cycle: 4},
|
||||||
|
{authored: "paleturquoise", name: "paleturquoise", hex: "#afeeee", hsl: "hsl(180, 64.9%, 81%)", rgb: "rgb(175, 238, 238)", cycle: 4},
|
||||||
|
{authored: "palevioletred", name: "palevioletred", hex: "#db7093", hsl: "hsl(340.4, 59.8%, 64.9%)", rgb: "rgb(219, 112, 147)", cycle: 4},
|
||||||
|
{authored: "papayawhip", name: "papayawhip", hex: "#ffefd5", hsl: "hsl(37.1, 100%, 91.8%)", rgb: "rgb(255, 239, 213)", cycle: 4},
|
||||||
|
{authored: "peachpuff", name: "peachpuff", hex: "#ffdab9", hsl: "hsl(28.3, 100%, 86.3%)", rgb: "rgb(255, 218, 185)", cycle: 4},
|
||||||
|
{authored: "peru", name: "peru", hex: "#cd853f", hsl: "hsl(29.6, 58.7%, 52.5%)", rgb: "rgb(205, 133, 63)", cycle: 4},
|
||||||
|
{authored: "pink", name: "pink", hex: "#ffc0cb", hsl: "hsl(349.5, 100%, 87.6%)", rgb: "rgb(255, 192, 203)", cycle: 4},
|
||||||
|
{authored: "plum", name: "plum", hex: "#dda0dd", hsl: "hsl(300, 47.3%, 74.7%)", rgb: "rgb(221, 160, 221)", cycle: 4},
|
||||||
|
{authored: "powderblue", name: "powderblue", hex: "#b0e0e6", hsl: "hsl(186.7, 51.9%, 79.6%)", rgb: "rgb(176, 224, 230)", cycle: 4},
|
||||||
|
{authored: "purple", name: "purple", hex: "#800080", hsl: "hsl(300, 100%, 25.1%)", rgb: "rgb(128, 0, 128)", cycle: 4},
|
||||||
|
{authored: "rebeccapurple", name: "rebeccapurple", hex: "#639", hsl: "hsl(270, 50%, 40%)", rgb: "rgb(102, 51, 153)", cycle: 4},
|
||||||
|
{authored: "red", name: "red", hex: "#f00", hsl: "hsl(0, 100%, 50%)", rgb: "rgb(255, 0, 0)", cycle: 4},
|
||||||
|
{authored: "rosybrown", name: "rosybrown", hex: "#bc8f8f", hsl: "hsl(0, 25.1%, 64.9%)", rgb: "rgb(188, 143, 143)", cycle: 4},
|
||||||
|
{authored: "royalblue", name: "royalblue", hex: "#4169e1", hsl: "hsl(225, 72.7%, 56.9%)", rgb: "rgb(65, 105, 225)", cycle: 4},
|
||||||
|
{authored: "saddlebrown", name: "saddlebrown", hex: "#8b4513", hsl: "hsl(25, 75.9%, 31%)", rgb: "rgb(139, 69, 19)", cycle: 4},
|
||||||
|
{authored: "salmon", name: "salmon", hex: "#fa8072", hsl: "hsl(6.2, 93.2%, 71.4%)", rgb: "rgb(250, 128, 114)", cycle: 4},
|
||||||
|
{authored: "sandybrown", name: "sandybrown", hex: "#f4a460", hsl: "hsl(27.6, 87.1%, 66.7%)", rgb: "rgb(244, 164, 96)", cycle: 4},
|
||||||
|
{authored: "seagreen", name: "seagreen", hex: "#2e8b57", hsl: "hsl(146.5, 50.3%, 36.3%)", rgb: "rgb(46, 139, 87)", cycle: 4},
|
||||||
|
{authored: "seashell", name: "seashell", hex: "#fff5ee", hsl: "hsl(24.7, 100%, 96.7%)", rgb: "rgb(255, 245, 238)", cycle: 4},
|
||||||
|
{authored: "sienna", name: "sienna", hex: "#a0522d", hsl: "hsl(19.3, 56.1%, 40.2%)", rgb: "rgb(160, 82, 45)", cycle: 4},
|
||||||
|
{authored: "silver", name: "silver", hex: "#c0c0c0", hsl: "hsl(0, 0%, 75.3%)", rgb: "rgb(192, 192, 192)", cycle: 4},
|
||||||
|
{authored: "skyblue", name: "skyblue", hex: "#87ceeb", hsl: "hsl(197.4, 71.4%, 72.5%)", rgb: "rgb(135, 206, 235)", cycle: 4},
|
||||||
|
{authored: "slateblue", name: "slateblue", hex: "#6a5acd", hsl: "hsl(248.3, 53.5%, 57.8%)", rgb: "rgb(106, 90, 205)", cycle: 4},
|
||||||
|
{authored: "slategray", name: "slategray", hex: "#708090", hsl: "hsl(210, 12.6%, 50.2%)", rgb: "rgb(112, 128, 144)", cycle: 4},
|
||||||
|
{authored: "slategrey", name: "slategray", hex: "#708090", hsl: "hsl(210, 12.6%, 50.2%)", rgb: "rgb(112, 128, 144)", cycle: 4},
|
||||||
|
{authored: "snow", name: "snow", hex: "#fffafa", hsl: "hsl(0, 100%, 99%)", rgb: "rgb(255, 250, 250)", cycle: 4},
|
||||||
|
{authored: "springgreen", name: "springgreen", hex: "#00ff7f", hsl: "hsl(149.9, 100%, 50%)", rgb: "rgb(0, 255, 127)", cycle: 4},
|
||||||
|
{authored: "steelblue", name: "steelblue", hex: "#4682b4", hsl: "hsl(207.3, 44%, 49%)", rgb: "rgb(70, 130, 180)", cycle: 4},
|
||||||
|
{authored: "tan", name: "tan", hex: "#d2b48c", hsl: "hsl(34.3, 43.7%, 68.6%)", rgb: "rgb(210, 180, 140)", cycle: 4},
|
||||||
|
{authored: "teal", name: "teal", hex: "#008080", hsl: "hsl(180, 100%, 25.1%)", rgb: "rgb(0, 128, 128)", cycle: 4},
|
||||||
|
{authored: "thistle", name: "thistle", hex: "#d8bfd8", hsl: "hsl(300, 24.3%, 79.8%)", rgb: "rgb(216, 191, 216)", cycle: 4},
|
||||||
|
{authored: "tomato", name: "tomato", hex: "#ff6347", hsl: "hsl(9.1, 100%, 63.9%)", rgb: "rgb(255, 99, 71)", cycle: 4},
|
||||||
|
{authored: "turquoise", name: "turquoise", hex: "#40e0d0", hsl: "hsl(174, 72.1%, 56.5%)", rgb: "rgb(64, 224, 208)", cycle: 4},
|
||||||
|
{authored: "violet", name: "violet", hex: "#ee82ee", hsl: "hsl(300, 76.1%, 72.2%)", rgb: "rgb(238, 130, 238)", cycle: 4},
|
||||||
|
{authored: "wheat", name: "wheat", hex: "#f5deb3", hsl: "hsl(39.1, 76.7%, 83.1%)", rgb: "rgb(245, 222, 179)", cycle: 4},
|
||||||
|
{authored: "white", name: "white", hex: "#fff", hsl: "hsl(0, 0%, 100%)", rgb: "rgb(255, 255, 255)", cycle: 4},
|
||||||
|
{authored: "whitesmoke", name: "whitesmoke", hex: "#f5f5f5", hsl: "hsl(0, 0%, 96.1%)", rgb: "rgb(245, 245, 245)", cycle: 4},
|
||||||
|
{authored: "yellow", name: "yellow", hex: "#ff0", hsl: "hsl(60, 100%, 50%)", rgb: "rgb(255, 255, 0)", cycle: 4},
|
||||||
|
{authored: "yellowgreen", name: "yellowgreen", hex: "#9acd32", hsl: "hsl(79.7, 60.8%, 50%)", rgb: "rgb(154, 205, 50)", cycle: 4},
|
||||||
|
{authored: "rgba(0, 0, 0, 0)", name: "#0000", hex: "#0000", hsl: "hsla(0, 0%, 0%, 0)", rgb: "rgba(0, 0, 0, 0)", cycle: 3},
|
||||||
|
{authored: "hsla(0, 0%, 0%, 0)", name: "#0000", hex: "#0000", hsl: "hsla(0, 0%, 0%, 0)", rgb: "rgba(0, 0, 0, 0)", cycle: 3},
|
||||||
|
{authored: "rgba(50, 60, 70, 0.5)", name: "#323c4680", hex: "#323c4680", hsl: "hsla(210, 16.7%, 23.5%, 0.5)", rgb: "rgba(50, 60, 70, 0.5)", cycle: 3},
|
||||||
|
{authored: "rgba(0, 0, 0, 0.3)", name: "#0000004d", hex: "#0000004d", hsl: "hsla(0, 0%, 0%, 0.3)", rgb: "rgba(0, 0, 0, 0.3)", cycle: 3},
|
||||||
|
{authored: "rgba(255, 255, 255, 0.6)", name: "#fff9", hex: "#fff9", hsl: "hsla(0, 0%, 100%, 0.6)", rgb: "rgba(255, 255, 255, 0.6)", cycle: 3},
|
||||||
|
{authored: "rgba(127, 89, 45, 1)", name: "#7f592d", hex: "#7f592d", hsl: "hsl(32.2, 47.7%, 33.7%)", rgb: "rgb(127, 89, 45)", cycle: 3},
|
||||||
|
{authored: "hsla(19.304, 56%, 40%, 1)", name: "#9f522d", hex: "#9f522d", hsl: "hsl(19.5, 55.9%, 40%)", rgb: "rgb(159, 82, 45)", cycle: 3},
|
||||||
|
{authored: "#f089", name: "#f089", hex: "#f089", hsl: "hsla(328, 100%, 50%, 0.6)", rgb: "rgba(255, 0, 136, 0.6)", cycle: 3},
|
||||||
|
{authored: "#00ff8080", name: "#00ff8080", hex: "#00ff8080", hsl: "hsla(150.1, 100%, 50%, 0.5)", rgb: "rgba(0, 255, 128, 0.5)", cycle: 3},
|
||||||
|
{authored: "currentcolor", name: "currentcolor", hex: "currentcolor", hsl: "currentcolor", rgb: "currentcolor", cycle: false},
|
||||||
|
{authored: "inherit", name: "inherit", hex: "inherit", hsl: "inherit", rgb: "inherit", cycle: false},
|
||||||
|
{authored: "initial", name: "initial", hex: "initial", hsl: "initial", rgb: "initial", cycle: false},
|
||||||
|
{authored: "invalidColor", name: "", hex: "", hsl: "", rgb: "", cycle: false},
|
||||||
|
{authored: "transparent", name: "transparent", hex: "transparent", hsl: "transparent", rgb: "transparent", cycle: false},
|
||||||
|
{authored: "unset", name: "unset", hex: "unset", hsl: "unset", rgb: "unset", cycle: false},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow this function to be shared on mochitests and xpcshell tests.
|
||||||
|
if (typeof module === "object") {
|
||||||
|
module.exports = getFixtureColorData;
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test color cycling regression - Bug 1303748.
|
||||||
|
*
|
||||||
|
* Values should cycle from a starting value, back to their original values. This can
|
||||||
|
* potentially be a little flaky due to the precision of different color representations.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const {require} = Components.utils.import("resource://devtools/shared/Loader.jsm", {});
|
||||||
|
const {colorUtils} = require("devtools/shared/css/color");
|
||||||
|
const getFixtureColorData = require("resource://test/helper_color_data.js");
|
||||||
|
|
||||||
|
function run_test() {
|
||||||
|
getFixtureColorData().forEach(({authored, name, hex, hsl, rgb, cycle}) => {
|
||||||
|
if (cycle) {
|
||||||
|
const nameCycled = runCycle(name, cycle);
|
||||||
|
const hexCycled = runCycle(hex, cycle);
|
||||||
|
const hslCycled = runCycle(hsl, cycle);
|
||||||
|
const rgbCycled = runCycle(rgb, cycle);
|
||||||
|
// Cut down on log output by only reporting a single pass/fail for the color.
|
||||||
|
ok(nameCycled && hexCycled && hslCycled && rgbCycled,
|
||||||
|
`${authored} was able to cycle back to the original value`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test a color cycle to see if a color cycles back to its original value in a fixed
|
||||||
|
* number of steps.
|
||||||
|
*
|
||||||
|
* @param {string} value - The color value, e.g. "#000".
|
||||||
|
* @param {integer) times - The number of times it takes to cycle back to the
|
||||||
|
* original color.
|
||||||
|
*/
|
||||||
|
function runCycle(value, times) {
|
||||||
|
let color = new colorUtils.CssColor(value);
|
||||||
|
for (let i = 0; i < times; i++) {
|
||||||
|
color.nextColorUnit();
|
||||||
|
color = new colorUtils.CssColor(color.toString());
|
||||||
|
}
|
||||||
|
return color.toString() === value;
|
||||||
|
}
|
|
@ -5,12 +5,16 @@ tail =
|
||||||
firefox-appdir = browser
|
firefox-appdir = browser
|
||||||
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||||
|
|
||||||
|
support-files =
|
||||||
|
../helper_color_data.js
|
||||||
|
|
||||||
[test_advanceValidate.js]
|
[test_advanceValidate.js]
|
||||||
[test_attribute-parsing-01.js]
|
[test_attribute-parsing-01.js]
|
||||||
[test_attribute-parsing-02.js]
|
[test_attribute-parsing-02.js]
|
||||||
[test_bezierCanvas.js]
|
[test_bezierCanvas.js]
|
||||||
[test_cssAngle.js]
|
[test_cssAngle.js]
|
||||||
[test_cssColor.js]
|
[test_cssColor-01.js]
|
||||||
|
[test_cssColor-02.js]
|
||||||
[test_cssColorDatabase.js]
|
[test_cssColorDatabase.js]
|
||||||
[test_cubicBezier.js]
|
[test_cubicBezier.js]
|
||||||
[test_escapeCSSComment.js]
|
[test_escapeCSSComment.js]
|
||||||
|
|
|
@ -14,6 +14,7 @@ const {
|
||||||
workerSpec,
|
workerSpec,
|
||||||
pushSubscriptionSpec,
|
pushSubscriptionSpec,
|
||||||
serviceWorkerRegistrationSpec,
|
serviceWorkerRegistrationSpec,
|
||||||
|
serviceWorkerSpec,
|
||||||
} = require("devtools/shared/specs/worker");
|
} = require("devtools/shared/specs/worker");
|
||||||
|
|
||||||
loader.lazyRequireGetter(this, "ChromeUtils");
|
loader.lazyRequireGetter(this, "ChromeUtils");
|
||||||
|
@ -339,6 +340,29 @@ let PushSubscriptionActor = protocol.ActorClassWithSpec(pushSubscriptionSpec, {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let ServiceWorkerActor = protocol.ActorClassWithSpec(serviceWorkerSpec, {
|
||||||
|
initialize(conn, worker) {
|
||||||
|
protocol.Actor.prototype.initialize.call(this, conn);
|
||||||
|
this._worker = worker;
|
||||||
|
},
|
||||||
|
|
||||||
|
form() {
|
||||||
|
if (!this._worker) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
url: this._worker.scriptSpec,
|
||||||
|
state: this._worker.state,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
protocol.Actor.prototype.destroy.call(this);
|
||||||
|
this._worker = null;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// Lazily load the service-worker-child.js process script only once.
|
// Lazily load the service-worker-child.js process script only once.
|
||||||
let _serviceWorkerProcessScriptLoaded = false;
|
let _serviceWorkerProcessScriptLoaded = false;
|
||||||
|
|
||||||
|
@ -356,29 +380,70 @@ protocol.ActorClassWithSpec(serviceWorkerRegistrationSpec, {
|
||||||
this._conn = conn;
|
this._conn = conn;
|
||||||
this._registration = registration;
|
this._registration = registration;
|
||||||
this._pushSubscriptionActor = null;
|
this._pushSubscriptionActor = null;
|
||||||
|
this._registration.addListener(this);
|
||||||
|
|
||||||
|
let {installingWorker, waitingWorker, activeWorker} = registration;
|
||||||
|
this._installingWorker = new ServiceWorkerActor(conn, installingWorker);
|
||||||
|
this._waitingWorker = new ServiceWorkerActor(conn, waitingWorker);
|
||||||
|
this._activeWorker = new ServiceWorkerActor(conn, activeWorker);
|
||||||
|
|
||||||
Services.obs.addObserver(this, PushService.subscriptionModifiedTopic, false);
|
Services.obs.addObserver(this, PushService.subscriptionModifiedTopic, false);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onChange() {
|
||||||
|
this._installingWorker.destroy();
|
||||||
|
this._waitingWorker.destroy();
|
||||||
|
this._activeWorker.destroy();
|
||||||
|
|
||||||
|
let {installingWorker, waitingWorker, activeWorker} = this._registration;
|
||||||
|
this._installingWorker = new ServiceWorkerActor(this._conn, installingWorker);
|
||||||
|
this._waitingWorker = new ServiceWorkerActor(this._conn, waitingWorker);
|
||||||
|
this._activeWorker = new ServiceWorkerActor(this._conn, activeWorker);
|
||||||
|
|
||||||
|
events.emit(this, "registration-changed");
|
||||||
|
},
|
||||||
|
|
||||||
form(detail) {
|
form(detail) {
|
||||||
if (detail === "actorid") {
|
if (detail === "actorid") {
|
||||||
return this.actorID;
|
return this.actorID;
|
||||||
}
|
}
|
||||||
let registration = this._registration;
|
let registration = this._registration;
|
||||||
|
let installingWorker = this._installingWorker.form();
|
||||||
|
let waitingWorker = this._waitingWorker.form();
|
||||||
|
let activeWorker = this._activeWorker.form();
|
||||||
|
|
||||||
|
let isE10s = Services.appinfo.browserTabsRemoteAutostart;
|
||||||
return {
|
return {
|
||||||
actor: this.actorID,
|
actor: this.actorID,
|
||||||
scope: registration.scope,
|
scope: registration.scope,
|
||||||
url: registration.scriptSpec
|
url: registration.scriptSpec,
|
||||||
|
installingWorker,
|
||||||
|
waitingWorker,
|
||||||
|
activeWorker,
|
||||||
|
// - In e10s: only active registrations are available.
|
||||||
|
// - In non-e10s: registrations always have at least one worker, if the worker is
|
||||||
|
// active, the registration is active.
|
||||||
|
active: isE10s ? true : !!activeWorker
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
protocol.Actor.prototype.destroy.call(this);
|
protocol.Actor.prototype.destroy.call(this);
|
||||||
Services.obs.removeObserver(this, PushService.subscriptionModifiedTopic, false);
|
Services.obs.removeObserver(this, PushService.subscriptionModifiedTopic, false);
|
||||||
|
this._registration.removeListener(this);
|
||||||
this._registration = null;
|
this._registration = null;
|
||||||
if (this._pushSubscriptionActor) {
|
if (this._pushSubscriptionActor) {
|
||||||
this._pushSubscriptionActor.destroy();
|
this._pushSubscriptionActor.destroy();
|
||||||
}
|
}
|
||||||
this._pushSubscriptionActor = null;
|
this._pushSubscriptionActor = null;
|
||||||
|
|
||||||
|
this._installingWorker.destroy();
|
||||||
|
this._waitingWorker.destroy();
|
||||||
|
this._activeWorker.destroy();
|
||||||
|
|
||||||
|
this._installingWorker = null;
|
||||||
|
this._waitingWorker = null;
|
||||||
|
this._activeWorker = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
disconnect() {
|
disconnect() {
|
||||||
|
|
|
@ -461,7 +461,12 @@ function rgbToHsl([r, g, b]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return [Math.round(h), Math.round(s * 100), Math.round(l * 100)];
|
return [roundTo(h, 1), roundTo(s * 100, 1), roundTo(l * 100, 1)];
|
||||||
|
}
|
||||||
|
|
||||||
|
function roundTo(number, digits) {
|
||||||
|
const multiplier = Math.pow(10, digits);
|
||||||
|
return Math.round(number * multiplier) / multiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -573,9 +578,9 @@ function hslToRGB([h, s, l]) {
|
||||||
m2 = l + s - l * s;
|
m2 = l + s - l * s;
|
||||||
}
|
}
|
||||||
m1 = l * 2 - m2;
|
m1 = l * 2 - m2;
|
||||||
r = Math.floor(255 * _hslValue(m1, m2, h + 1.0 / 3.0));
|
r = Math.round(255 * _hslValue(m1, m2, h + 1.0 / 3.0));
|
||||||
g = Math.floor(255 * _hslValue(m1, m2, h));
|
g = Math.round(255 * _hslValue(m1, m2, h));
|
||||||
b = Math.floor(255 * _hslValue(m1, m2, h - 1.0 / 3.0));
|
b = Math.round(255 * _hslValue(m1, m2, h - 1.0 / 3.0));
|
||||||
return [r, g, b];
|
return [r, g, b];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,9 @@ const serviceWorkerRegistrationSpec = generateActorSpec({
|
||||||
events: {
|
events: {
|
||||||
"push-subscription-modified": {
|
"push-subscription-modified": {
|
||||||
type: "push-subscription-modified"
|
type: "push-subscription-modified"
|
||||||
|
},
|
||||||
|
"registration-changed": {
|
||||||
|
type: "registration-changed"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -66,3 +69,10 @@ const serviceWorkerRegistrationSpec = generateActorSpec({
|
||||||
});
|
});
|
||||||
|
|
||||||
exports.serviceWorkerRegistrationSpec = serviceWorkerRegistrationSpec;
|
exports.serviceWorkerRegistrationSpec = serviceWorkerRegistrationSpec;
|
||||||
|
|
||||||
|
const serviceWorkerSpec = generateActorSpec({
|
||||||
|
typeName: "serviceWorker",
|
||||||
|
});
|
||||||
|
|
||||||
|
exports.serviceWorkerSpec = serviceWorkerSpec;
|
||||||
|
|
||||||
|
|
|
@ -193,11 +193,20 @@ nsDefaultURIFixup::GetFixupURIInfo(const nsACString& aStringURI,
|
||||||
uint32_t newFixupFlags = aFixupFlags & ~FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP
|
uint32_t newFixupFlags = aFixupFlags & ~FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP
|
||||||
& ~FIXUP_FLAGS_MAKE_ALTERNATE_URI;
|
& ~FIXUP_FLAGS_MAKE_ALTERNATE_URI;
|
||||||
|
|
||||||
rv = GetFixupURIInfo(Substring(uriString,
|
const uint32_t viewSourceLen = sizeof("view-source:") - 1;
|
||||||
sizeof("view-source:") - 1,
|
nsAutoCString innerURIString(Substring(uriString, viewSourceLen,
|
||||||
uriString.Length() -
|
uriString.Length() -
|
||||||
(sizeof("view-source:") - 1)),
|
viewSourceLen));
|
||||||
newFixupFlags, aPostData, getter_AddRefs(uriInfo));
|
// Prevent recursion:
|
||||||
|
innerURIString.Trim(" ");
|
||||||
|
nsAutoCString innerScheme;
|
||||||
|
ioService->ExtractScheme(innerURIString, innerScheme);
|
||||||
|
if (innerScheme.LowerCaseEqualsLiteral("view-source")) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = GetFixupURIInfo(innerURIString, newFixupFlags, aPostData,
|
||||||
|
getter_AddRefs(uriInfo));
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,10 +16,6 @@
|
||||||
#include "nsRuleNode.h"
|
#include "nsRuleNode.h"
|
||||||
#include "nsRuleData.h"
|
#include "nsRuleData.h"
|
||||||
|
|
||||||
// For IsPictureEnabled() -- the candidate parser needs to be aware of sizes
|
|
||||||
// support being enabled
|
|
||||||
#include "HTMLPictureElement.h"
|
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
|
|
||||||
|
@ -557,8 +553,7 @@ ResponsiveImageDescriptors::AddDescriptor(const nsAString& aDescriptor)
|
||||||
// If the value is not a valid non-negative integer, it doesn't match this
|
// If the value is not a valid non-negative integer, it doesn't match this
|
||||||
// descriptor, fall through.
|
// descriptor, fall through.
|
||||||
if (ParseInteger(valueStr, possibleWidth) && possibleWidth >= 0) {
|
if (ParseInteger(valueStr, possibleWidth) && possibleWidth >= 0) {
|
||||||
if (possibleWidth != 0 && HTMLPictureElement::IsPictureEnabled() &&
|
if (possibleWidth != 0 && mWidth.isNothing() && mDensity.isNothing()) {
|
||||||
mWidth.isNothing() && mDensity.isNothing()) {
|
|
||||||
mWidth.emplace(possibleWidth);
|
mWidth.emplace(possibleWidth);
|
||||||
} else {
|
} else {
|
||||||
// Valid width descriptor, but width or density were already seen, sizes
|
// Valid width descriptor, but width or density were already seen, sizes
|
||||||
|
|
|
@ -6239,12 +6239,18 @@ NS_IMETHODIMP
|
||||||
nsDocument::LoadBindingDocument(const nsAString& aURI)
|
nsDocument::LoadBindingDocument(const nsAString& aURI)
|
||||||
{
|
{
|
||||||
ErrorResult rv;
|
ErrorResult rv;
|
||||||
nsIDocument::LoadBindingDocument(aURI, rv);
|
nsIDocument::LoadBindingDocument(aURI,
|
||||||
|
nsContentUtils::GetCurrentJSContext()
|
||||||
|
? Some(nsContentUtils::SubjectPrincipal())
|
||||||
|
: Nothing(),
|
||||||
|
rv);
|
||||||
return rv.StealNSResult();
|
return rv.StealNSResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsIDocument::LoadBindingDocument(const nsAString& aURI, ErrorResult& rv)
|
nsIDocument::LoadBindingDocument(const nsAString& aURI,
|
||||||
|
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||||
|
ErrorResult& rv)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIURI> uri;
|
nsCOMPtr<nsIURI> uri;
|
||||||
rv = NS_NewURI(getter_AddRefs(uri), aURI,
|
rv = NS_NewURI(getter_AddRefs(uri), aURI,
|
||||||
|
@ -6258,8 +6264,7 @@ nsIDocument::LoadBindingDocument(const nsAString& aURI, ErrorResult& rv)
|
||||||
// It's just designed to preserve the old semantics during a mass-conversion
|
// It's just designed to preserve the old semantics during a mass-conversion
|
||||||
// patch.
|
// patch.
|
||||||
nsCOMPtr<nsIPrincipal> subjectPrincipal =
|
nsCOMPtr<nsIPrincipal> subjectPrincipal =
|
||||||
nsContentUtils::GetCurrentJSContext() ? nsContentUtils::SubjectPrincipal()
|
aSubjectPrincipal.isSome() ? aSubjectPrincipal.value() : NodePrincipal();
|
||||||
: NodePrincipal();
|
|
||||||
BindingManager()->LoadBindingDocument(this, uri, subjectPrincipal);
|
BindingManager()->LoadBindingDocument(this, uri, subjectPrincipal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10577,7 +10577,8 @@ nsGlobalWindow::GetSessionStorage(ErrorResult& aError)
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMStorage*
|
DOMStorage*
|
||||||
nsGlobalWindow::GetLocalStorage(ErrorResult& aError)
|
nsGlobalWindow::GetLocalStorage(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||||
|
ErrorResult& aError)
|
||||||
{
|
{
|
||||||
MOZ_RELEASE_ASSERT(IsInnerWindow());
|
MOZ_RELEASE_ASSERT(IsInnerWindow());
|
||||||
|
|
||||||
|
@ -10586,7 +10587,7 @@ nsGlobalWindow::GetLocalStorage(ErrorResult& aError)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mLocalStorage) {
|
if (!mLocalStorage) {
|
||||||
if (!DOMStorage::CanUseStorage(AsInner())) {
|
if (!DOMStorage::CanUseStorage(AsInner(), aSubjectPrincipal)) {
|
||||||
aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -11535,8 +11536,7 @@ nsGlobalWindow::Observe(nsISupports* aSubject, const char* aTopic,
|
||||||
// Clone the storage event included in the observer notification. We want
|
// Clone the storage event included in the observer notification. We want
|
||||||
// to dispatch clones rather than the original event.
|
// to dispatch clones rather than the original event.
|
||||||
ErrorResult error;
|
ErrorResult error;
|
||||||
RefPtr<StorageEvent> newEvent = CloneStorageEvent(eventType,
|
RefPtr<StorageEvent> newEvent = CloneStorageEvent(eventType, event, error);
|
||||||
event, error);
|
|
||||||
if (error.Failed()) {
|
if (error.Failed()) {
|
||||||
return error.StealNSResult();
|
return error.StealNSResult();
|
||||||
}
|
}
|
||||||
|
@ -11653,7 +11653,10 @@ nsGlobalWindow::CloneStorageEvent(const nsAString& aType,
|
||||||
|
|
||||||
RefPtr<DOMStorage> storage;
|
RefPtr<DOMStorage> storage;
|
||||||
if (storageArea->GetType() == DOMStorage::LocalStorage) {
|
if (storageArea->GetType() == DOMStorage::LocalStorage) {
|
||||||
storage = GetLocalStorage(aRv);
|
storage = GetLocalStorage(nsContentUtils::GetCurrentJSContext()
|
||||||
|
? Some(nsContentUtils::SubjectPrincipal())
|
||||||
|
: Nothing(),
|
||||||
|
aRv);
|
||||||
} else {
|
} else {
|
||||||
MOZ_ASSERT(storageArea->GetType() == DOMStorage::SessionStorage);
|
MOZ_ASSERT(storageArea->GetType() == DOMStorage::SessionStorage);
|
||||||
storage = GetSessionStorage(aRv);
|
storage = GetSessionStorage(aRv);
|
||||||
|
|
|
@ -1044,7 +1044,9 @@ public:
|
||||||
void Btoa(const nsAString& aBinaryData, nsAString& aAsciiBase64String,
|
void Btoa(const nsAString& aBinaryData, nsAString& aAsciiBase64String,
|
||||||
mozilla::ErrorResult& aError);
|
mozilla::ErrorResult& aError);
|
||||||
mozilla::dom::DOMStorage* GetSessionStorage(mozilla::ErrorResult& aError);
|
mozilla::dom::DOMStorage* GetSessionStorage(mozilla::ErrorResult& aError);
|
||||||
mozilla::dom::DOMStorage* GetLocalStorage(mozilla::ErrorResult& aError);
|
mozilla::dom::DOMStorage*
|
||||||
|
GetLocalStorage(const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||||
|
mozilla::ErrorResult& aError);
|
||||||
mozilla::dom::Selection* GetSelectionOuter();
|
mozilla::dom::Selection* GetSelectionOuter();
|
||||||
mozilla::dom::Selection* GetSelection(mozilla::ErrorResult& aError);
|
mozilla::dom::Selection* GetSelection(mozilla::ErrorResult& aError);
|
||||||
already_AddRefed<nsISelection> GetSelection() override;
|
already_AddRefed<nsISelection> GetSelection() override;
|
||||||
|
|
|
@ -134,6 +134,11 @@ BroadcastBlobURLRegistration(const nsACString& aURI,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We don't need to broadcast Blob URL if we have just 1 content process.
|
||||||
|
if (Preferences::GetInt("dom.ipc.processCount", 0) <= 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ContentChild* cc = ContentChild::GetSingleton();
|
ContentChild* cc = ContentChild::GetSingleton();
|
||||||
BlobChild* actor = cc->GetOrCreateActorForBlobImpl(aBlobImpl);
|
BlobChild* actor = cc->GetOrCreateActorForBlobImpl(aBlobImpl);
|
||||||
if (NS_WARN_IF(!actor)) {
|
if (NS_WARN_IF(!actor)) {
|
||||||
|
|
|
@ -2685,7 +2685,9 @@ public:
|
||||||
const nsAString& aAttrName,
|
const nsAString& aAttrName,
|
||||||
const nsAString& aAttrValue);
|
const nsAString& aAttrValue);
|
||||||
Element* GetBindingParent(nsINode& aNode);
|
Element* GetBindingParent(nsINode& aNode);
|
||||||
void LoadBindingDocument(const nsAString& aURI, mozilla::ErrorResult& rv);
|
void LoadBindingDocument(const nsAString& aURI,
|
||||||
|
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||||
|
mozilla::ErrorResult& rv);
|
||||||
mozilla::dom::XPathExpression*
|
mozilla::dom::XPathExpression*
|
||||||
CreateExpression(const nsAString& aExpression,
|
CreateExpression(const nsAString& aExpression,
|
||||||
mozilla::dom::XPathNSResolver* aResolver,
|
mozilla::dom::XPathNSResolver* aResolver,
|
||||||
|
|
|
@ -3537,8 +3537,10 @@ nsObjectLoadingContent::ShouldPlay(FallbackType &aReason, bool aIgnoreCurrentTyp
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIDocument*
|
nsIDocument*
|
||||||
nsObjectLoadingContent::GetContentDocument()
|
nsObjectLoadingContent::GetContentDocument(const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||||
|
|
||||||
nsCOMPtr<nsIContent> thisContent =
|
nsCOMPtr<nsIContent> thisContent =
|
||||||
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
|
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
|
||||||
|
|
||||||
|
@ -3552,7 +3554,7 @@ nsObjectLoadingContent::GetContentDocument()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return null for cross-origin contentDocument.
|
// Return null for cross-origin contentDocument.
|
||||||
if (!nsContentUtils::SubjectPrincipal()->SubsumesConsideringDomain(sub_doc->NodePrincipal())) {
|
if (!aSubjectPrincipal.value()->SubsumesConsideringDomain(sub_doc->NodePrincipal())) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
class nsAsyncInstantiateEvent;
|
class nsAsyncInstantiateEvent;
|
||||||
class nsStopPluginRunnable;
|
class nsStopPluginRunnable;
|
||||||
class AutoSetInstantiatingToFalse;
|
class AutoSetInstantiatingToFalse;
|
||||||
|
class nsIPrincipal;
|
||||||
class nsFrameLoader;
|
class nsFrameLoader;
|
||||||
class nsPluginFrame;
|
class nsPluginFrame;
|
||||||
class nsXULElement;
|
class nsXULElement;
|
||||||
|
@ -179,7 +180,7 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
||||||
mozilla::ErrorResult& aRv);
|
mozilla::ErrorResult& aRv);
|
||||||
|
|
||||||
// WebIDL API
|
// WebIDL API
|
||||||
nsIDocument* GetContentDocument();
|
nsIDocument* GetContentDocument(const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal);
|
||||||
void GetActualType(nsAString& aType) const
|
void GetActualType(nsAString& aType) const
|
||||||
{
|
{
|
||||||
CopyUTF8toUTF16(mContentType, aType);
|
CopyUTF8toUTF16(mContentType, aType);
|
||||||
|
|
|
@ -329,6 +329,12 @@ operator<(const RefPtr<nsPluginElement>& lhs,
|
||||||
return lhs->PluginTag()->Name() < rhs->PluginTag()->Name();
|
return lhs->PluginTag()->Name() < rhs->PluginTag()->Name();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
PluginShouldBeHidden(nsCString aName) {
|
||||||
|
// This only supports one hidden plugin
|
||||||
|
return Preferences::GetCString("plugins.navigator.hidden_ctp_plugin").Equals(aName);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsPluginArray::EnsurePlugins()
|
nsPluginArray::EnsurePlugins()
|
||||||
{
|
{
|
||||||
|
@ -357,8 +363,7 @@ nsPluginArray::EnsurePlugins()
|
||||||
if (pluginTag->IsClicktoplay()) {
|
if (pluginTag->IsClicktoplay()) {
|
||||||
nsCString name;
|
nsCString name;
|
||||||
pluginTag->GetName(name);
|
pluginTag->GetName(name);
|
||||||
if (name.EqualsLiteral("Shockwave Flash") &&
|
if (PluginShouldBeHidden(name)) {
|
||||||
Preferences::GetBool("plugins.navigator_hide_disabled_flash", false)) {
|
|
||||||
RefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
|
RefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
|
||||||
nsCString permString;
|
nsCString permString;
|
||||||
nsresult rv = pluginHost->GetPermissionStringForTag(pluginTag, 0, permString);
|
nsresult rv = pluginHost->GetPermissionStringForTag(pluginTag, 0, permString);
|
||||||
|
@ -377,6 +382,12 @@ nsPluginArray::EnsurePlugins()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mPlugins.Length() == 0 && mCTPPlugins.Length() != 0) {
|
||||||
|
nsCOMPtr<nsPluginTag> hiddenTag = new nsPluginTag("Hidden Plugin", NULL, "dummy.plugin", NULL, NULL,
|
||||||
|
NULL, NULL, NULL, 0, 0, false);
|
||||||
|
mPlugins.AppendElement(new nsPluginElement(mWindow, hiddenTag));
|
||||||
|
}
|
||||||
|
|
||||||
// Alphabetize the enumeration order of non-hidden plugins to reduce
|
// Alphabetize the enumeration order of non-hidden plugins to reduce
|
||||||
// fingerprintable entropy based on plugins' installation file times.
|
// fingerprintable entropy based on plugins' installation file times.
|
||||||
mPlugins.Sort();
|
mPlugins.Sort();
|
||||||
|
|
|
@ -167,9 +167,10 @@ public:
|
||||||
{
|
{
|
||||||
GetEnumAttr(nsGkAtoms::referrerpolicy, EmptyCString().get(), aReferrer);
|
GetEnumAttr(nsGkAtoms::referrerpolicy, EmptyCString().get(), aReferrer);
|
||||||
}
|
}
|
||||||
nsIDocument* GetSVGDocument()
|
nsIDocument*
|
||||||
|
GetSVGDocument(const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal)
|
||||||
{
|
{
|
||||||
return GetContentDocument();
|
return GetContentDocument(aSubjectPrincipal);
|
||||||
}
|
}
|
||||||
bool Mozbrowser() const
|
bool Mozbrowser() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -50,12 +50,8 @@
|
||||||
|
|
||||||
#include "nsLayoutUtils.h"
|
#include "nsLayoutUtils.h"
|
||||||
|
|
||||||
#include "mozilla/Preferences.h"
|
|
||||||
|
|
||||||
using namespace mozilla::net;
|
using namespace mozilla::net;
|
||||||
|
|
||||||
static const char *kPrefSrcsetEnabled = "dom.image.srcset.enabled";
|
|
||||||
|
|
||||||
NS_IMPL_NS_NEW_HTML_ELEMENT(Image)
|
NS_IMPL_NS_NEW_HTML_ELEMENT(Image)
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -170,19 +166,9 @@ HTMLImageElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const
|
||||||
nsGenericHTMLElement::IsInteractiveHTMLContent(aIgnoreTabindex);
|
nsGenericHTMLElement::IsInteractiveHTMLContent(aIgnoreTabindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
HTMLImageElement::IsSrcsetEnabled()
|
|
||||||
{
|
|
||||||
return Preferences::GetBool(kPrefSrcsetEnabled, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
HTMLImageElement::GetCurrentSrc(nsAString& aValue)
|
HTMLImageElement::GetCurrentSrc(nsAString& aValue)
|
||||||
{
|
{
|
||||||
if (!IsSrcsetEnabled()) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIURI> currentURI;
|
nsCOMPtr<nsIURI> currentURI;
|
||||||
GetCurrentURI(getter_AddRefs(currentURI));
|
GetCurrentURI(getter_AddRefs(currentURI));
|
||||||
if (currentURI) {
|
if (currentURI) {
|
||||||
|
@ -433,12 +419,10 @@ HTMLImageElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||||
CancelImageRequests(aNotify);
|
CancelImageRequests(aNotify);
|
||||||
}
|
}
|
||||||
} else if (aName == nsGkAtoms::srcset &&
|
} else if (aName == nsGkAtoms::srcset &&
|
||||||
aNameSpaceID == kNameSpaceID_None &&
|
aNameSpaceID == kNameSpaceID_None) {
|
||||||
IsSrcsetEnabled()) {
|
|
||||||
PictureSourceSrcsetChanged(this, attrVal.String(), aNotify);
|
PictureSourceSrcsetChanged(this, attrVal.String(), aNotify);
|
||||||
} else if (aName == nsGkAtoms::sizes &&
|
} else if (aName == nsGkAtoms::sizes &&
|
||||||
aNameSpaceID == kNameSpaceID_None &&
|
aNameSpaceID == kNameSpaceID_None) {
|
||||||
HTMLPictureElement::IsPictureEnabled()) {
|
|
||||||
PictureSourceSizesChanged(this, attrVal.String(), aNotify);
|
PictureSourceSizesChanged(this, attrVal.String(), aNotify);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -929,14 +913,10 @@ HTMLImageElement::QueueImageLoadTask(bool aAlwaysLoad)
|
||||||
bool
|
bool
|
||||||
HTMLImageElement::HaveSrcsetOrInPicture()
|
HTMLImageElement::HaveSrcsetOrInPicture()
|
||||||
{
|
{
|
||||||
if (IsSrcsetEnabled() && HasAttr(kNameSpaceID_None, nsGkAtoms::srcset)) {
|
if (HasAttr(kNameSpaceID_None, nsGkAtoms::srcset)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!HTMLPictureElement::IsPictureEnabled()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Element *parent = nsINode::GetParentElement();
|
Element *parent = nsINode::GetParentElement();
|
||||||
return (parent && parent->IsHTMLElement(nsGkAtoms::picture));
|
return (parent && parent->IsHTMLElement(nsGkAtoms::picture));
|
||||||
}
|
}
|
||||||
|
@ -1027,14 +1007,8 @@ HTMLImageElement::PictureSourceSrcsetChanged(nsIContent *aSourceNode,
|
||||||
const nsAString& aNewValue,
|
const nsAString& aNewValue,
|
||||||
bool aNotify)
|
bool aNotify)
|
||||||
{
|
{
|
||||||
bool isSelf = aSourceNode == this;
|
MOZ_ASSERT(aSourceNode == this ||
|
||||||
|
IsPreviousSibling(aSourceNode, this),
|
||||||
if (!IsSrcsetEnabled() ||
|
|
||||||
(!isSelf && !HTMLPictureElement::IsPictureEnabled())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_ASSERT(isSelf || IsPreviousSibling(aSourceNode, this),
|
|
||||||
"Should not be getting notifications for non-previous-siblings");
|
"Should not be getting notifications for non-previous-siblings");
|
||||||
|
|
||||||
nsIContent *currentSrc =
|
nsIContent *currentSrc =
|
||||||
|
@ -1064,10 +1038,6 @@ HTMLImageElement::PictureSourceSizesChanged(nsIContent *aSourceNode,
|
||||||
const nsAString& aNewValue,
|
const nsAString& aNewValue,
|
||||||
bool aNotify)
|
bool aNotify)
|
||||||
{
|
{
|
||||||
if (!HTMLPictureElement::IsPictureEnabled()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_ASSERT(aSourceNode == this ||
|
MOZ_ASSERT(aSourceNode == this ||
|
||||||
IsPreviousSibling(aSourceNode, this),
|
IsPreviousSibling(aSourceNode, this),
|
||||||
"Should not be getting notifications for non-previous-siblings");
|
"Should not be getting notifications for non-previous-siblings");
|
||||||
|
@ -1090,10 +1060,6 @@ void
|
||||||
HTMLImageElement::PictureSourceMediaOrTypeChanged(nsIContent *aSourceNode,
|
HTMLImageElement::PictureSourceMediaOrTypeChanged(nsIContent *aSourceNode,
|
||||||
bool aNotify)
|
bool aNotify)
|
||||||
{
|
{
|
||||||
if (!HTMLPictureElement::IsPictureEnabled()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_ASSERT(IsPreviousSibling(aSourceNode, this),
|
MOZ_ASSERT(IsPreviousSibling(aSourceNode, this),
|
||||||
"Should not be getting notifications for non-previous-siblings");
|
"Should not be getting notifications for non-previous-siblings");
|
||||||
|
|
||||||
|
@ -1105,10 +1071,6 @@ HTMLImageElement::PictureSourceMediaOrTypeChanged(nsIContent *aSourceNode,
|
||||||
void
|
void
|
||||||
HTMLImageElement::PictureSourceAdded(nsIContent *aSourceNode)
|
HTMLImageElement::PictureSourceAdded(nsIContent *aSourceNode)
|
||||||
{
|
{
|
||||||
if (!HTMLPictureElement::IsPictureEnabled()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_ASSERT(aSourceNode == this ||
|
MOZ_ASSERT(aSourceNode == this ||
|
||||||
IsPreviousSibling(aSourceNode, this),
|
IsPreviousSibling(aSourceNode, this),
|
||||||
"Should not be getting notifications for non-previous-siblings");
|
"Should not be getting notifications for non-previous-siblings");
|
||||||
|
@ -1119,10 +1081,6 @@ HTMLImageElement::PictureSourceAdded(nsIContent *aSourceNode)
|
||||||
void
|
void
|
||||||
HTMLImageElement::PictureSourceRemoved(nsIContent *aSourceNode)
|
HTMLImageElement::PictureSourceRemoved(nsIContent *aSourceNode)
|
||||||
{
|
{
|
||||||
if (!HTMLPictureElement::IsPictureEnabled()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_ASSERT(aSourceNode == this ||
|
MOZ_ASSERT(aSourceNode == this ||
|
||||||
IsPreviousSibling(aSourceNode, this),
|
IsPreviousSibling(aSourceNode, this),
|
||||||
"Should not be getting notifications for non-previous-siblings");
|
"Should not be getting notifications for non-previous-siblings");
|
||||||
|
@ -1135,15 +1093,9 @@ HTMLImageElement::UpdateResponsiveSource()
|
||||||
{
|
{
|
||||||
bool hadSelector = !!mResponsiveSelector;
|
bool hadSelector = !!mResponsiveSelector;
|
||||||
|
|
||||||
if (!IsSrcsetEnabled()) {
|
|
||||||
mResponsiveSelector = nullptr;
|
|
||||||
return hadSelector;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIContent *currentSource =
|
nsIContent *currentSource =
|
||||||
mResponsiveSelector ? mResponsiveSelector->Content() : nullptr;
|
mResponsiveSelector ? mResponsiveSelector->Content() : nullptr;
|
||||||
bool pictureEnabled = HTMLPictureElement::IsPictureEnabled();
|
Element *parent = nsINode::GetParentElement();
|
||||||
Element *parent = pictureEnabled ? nsINode::GetParentElement() : nullptr;
|
|
||||||
|
|
||||||
nsINode *candidateSource = nullptr;
|
nsINode *candidateSource = nullptr;
|
||||||
if (parent && parent->IsHTMLElement(nsGkAtoms::picture)) {
|
if (parent && parent->IsHTMLElement(nsGkAtoms::picture)) {
|
||||||
|
@ -1231,7 +1183,6 @@ HTMLImageElement::SourceElementMatches(nsIContent* aSourceNode)
|
||||||
DebugOnly<Element *> parent(nsINode::GetParentElement());
|
DebugOnly<Element *> parent(nsINode::GetParentElement());
|
||||||
MOZ_ASSERT(parent && parent->IsHTMLElement(nsGkAtoms::picture));
|
MOZ_ASSERT(parent && parent->IsHTMLElement(nsGkAtoms::picture));
|
||||||
MOZ_ASSERT(IsPreviousSibling(aSourceNode, this));
|
MOZ_ASSERT(IsPreviousSibling(aSourceNode, this));
|
||||||
MOZ_ASSERT(HTMLPictureElement::IsPictureEnabled());
|
|
||||||
|
|
||||||
// Check media and type
|
// Check media and type
|
||||||
HTMLSourceElement *src = static_cast<HTMLSourceElement*>(aSourceNode);
|
HTMLSourceElement *src = static_cast<HTMLSourceElement*>(aSourceNode);
|
||||||
|
@ -1249,15 +1200,8 @@ HTMLImageElement::SourceElementMatches(nsIContent* aSourceNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HTMLImageElement::TryCreateResponsiveSelector(nsIContent *aSourceNode,
|
HTMLImageElement::TryCreateResponsiveSelector(nsIContent *aSourceNode)
|
||||||
const nsAString *aSrcset,
|
|
||||||
const nsAString *aSizes)
|
|
||||||
{
|
{
|
||||||
if (!IsSrcsetEnabled()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool pictureEnabled = HTMLPictureElement::IsPictureEnabled();
|
|
||||||
// Skip if this is not a <source> with matching media query
|
// Skip if this is not a <source> with matching media query
|
||||||
bool isSourceTag = aSourceNode->IsHTMLElement(nsGkAtoms::source);
|
bool isSourceTag = aSourceNode->IsHTMLElement(nsGkAtoms::source);
|
||||||
if (isSourceTag) {
|
if (isSourceTag) {
|
||||||
|
@ -1271,10 +1215,7 @@ HTMLImageElement::TryCreateResponsiveSelector(nsIContent *aSourceNode,
|
||||||
|
|
||||||
// Skip if has no srcset or an empty srcset
|
// Skip if has no srcset or an empty srcset
|
||||||
nsString srcset;
|
nsString srcset;
|
||||||
if (aSrcset) {
|
if (!aSourceNode->GetAttr(kNameSpaceID_None, nsGkAtoms::srcset, srcset)) {
|
||||||
srcset = *aSrcset;
|
|
||||||
} else if (!aSourceNode->GetAttr(kNameSpaceID_None, nsGkAtoms::srcset,
|
|
||||||
srcset)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1290,13 +1231,9 @@ HTMLImageElement::TryCreateResponsiveSelector(nsIContent *aSourceNode,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pictureEnabled && aSizes) {
|
nsAutoString sizes;
|
||||||
sel->SetSizesFromDescriptor(*aSizes);
|
aSourceNode->GetAttr(kNameSpaceID_None, nsGkAtoms::sizes, sizes);
|
||||||
} else if (pictureEnabled) {
|
sel->SetSizesFromDescriptor(sizes);
|
||||||
nsAutoString sizes;
|
|
||||||
aSourceNode->GetAttr(kNameSpaceID_None, nsGkAtoms::sizes, sizes);
|
|
||||||
sel->SetSizesFromDescriptor(sizes);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this is the <img> tag, also pull in src as the default source
|
// If this is the <img> tag, also pull in src as the default source
|
||||||
if (!isSourceTag) {
|
if (!isSourceTag) {
|
||||||
|
@ -1326,12 +1263,7 @@ HTMLImageElement::SelectSourceForTagWithAttrs(nsIDocument *aDocument,
|
||||||
MOZ_ASSERT(!aIsSourceTag || aSrcAttr.IsEmpty(),
|
MOZ_ASSERT(!aIsSourceTag || aSrcAttr.IsEmpty(),
|
||||||
"Passing aSrcAttr makes no sense with aIsSourceTag set");
|
"Passing aSrcAttr makes no sense with aIsSourceTag set");
|
||||||
|
|
||||||
bool pictureEnabled = HTMLPictureElement::IsPictureEnabled();
|
if (aSrcsetAttr.IsEmpty()) {
|
||||||
if (aIsSourceTag && !pictureEnabled) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IsSrcsetEnabled() || aSrcsetAttr.IsEmpty()) {
|
|
||||||
if (!aIsSourceTag) {
|
if (!aIsSourceTag) {
|
||||||
// For an <img> with no srcset, we would always select the src attr.
|
// For an <img> with no srcset, we would always select the src attr.
|
||||||
aResult.Assign(aSrcAttr);
|
aResult.Assign(aSrcAttr);
|
||||||
|
@ -1355,7 +1287,7 @@ HTMLImageElement::SelectSourceForTagWithAttrs(nsIDocument *aDocument,
|
||||||
new ResponsiveImageSelector(aDocument);
|
new ResponsiveImageSelector(aDocument);
|
||||||
|
|
||||||
sel->SetCandidatesFromSourceSet(aSrcsetAttr);
|
sel->SetCandidatesFromSourceSet(aSrcsetAttr);
|
||||||
if (pictureEnabled && !aSizesAttr.IsEmpty()) {
|
if (!aSizesAttr.IsEmpty()) {
|
||||||
sel->SetSizesFromDescriptor(aSizesAttr);
|
sel->SetSizesFromDescriptor(aSizesAttr);
|
||||||
}
|
}
|
||||||
if (!aIsSourceTag) {
|
if (!aIsSourceTag) {
|
||||||
|
|
|
@ -15,9 +15,6 @@
|
||||||
#include "Units.h"
|
#include "Units.h"
|
||||||
#include "nsCycleCollectionParticipant.h"
|
#include "nsCycleCollectionParticipant.h"
|
||||||
|
|
||||||
// Only needed for IsPictureEnabled()
|
|
||||||
#include "mozilla/dom/HTMLPictureElement.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
class EventChainPreVisitor;
|
class EventChainPreVisitor;
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
@ -97,8 +94,6 @@ public:
|
||||||
|
|
||||||
void MaybeLoadImage();
|
void MaybeLoadImage();
|
||||||
|
|
||||||
static bool IsSrcsetEnabled();
|
|
||||||
|
|
||||||
bool IsMap()
|
bool IsMap()
|
||||||
{
|
{
|
||||||
return GetBoolAttr(nsGkAtoms::ismap);
|
return GetBoolAttr(nsGkAtoms::ismap);
|
||||||
|
@ -336,9 +331,7 @@ protected:
|
||||||
// If the node's srcset/sizes make for an invalid selector, returns
|
// If the node's srcset/sizes make for an invalid selector, returns
|
||||||
// false. This does not guarantee the resulting selector matches an image,
|
// false. This does not guarantee the resulting selector matches an image,
|
||||||
// only that it is valid.
|
// only that it is valid.
|
||||||
bool TryCreateResponsiveSelector(nsIContent *aSourceNode,
|
bool TryCreateResponsiveSelector(nsIContent *aSourceNode);
|
||||||
const nsAString *aSrcset = nullptr,
|
|
||||||
const nsAString *aSizes = nullptr);
|
|
||||||
|
|
||||||
CSSIntPoint GetXY();
|
CSSIntPoint GetXY();
|
||||||
virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
|
virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||||
|
|
|
@ -2907,7 +2907,6 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNo
|
||||||
mAudioChannelVolume(1.0),
|
mAudioChannelVolume(1.0),
|
||||||
mPlayingThroughTheAudioChannel(false),
|
mPlayingThroughTheAudioChannel(false),
|
||||||
mDisableVideo(false),
|
mDisableVideo(false),
|
||||||
mElementInTreeState(ELEMENT_NOT_INTREE),
|
|
||||||
mHasUserInteraction(false),
|
mHasUserInteraction(false),
|
||||||
mFirstFrameLoaded(false),
|
mFirstFrameLoaded(false),
|
||||||
mDefaultPlaybackStartPosition(0.0),
|
mDefaultPlaybackStartPosition(0.0),
|
||||||
|
@ -3408,6 +3407,9 @@ nsresult HTMLMediaElement::BindToTree(nsIDocument* aDocument, nsIContent* aParen
|
||||||
aParent,
|
aParent,
|
||||||
aBindingParent,
|
aBindingParent,
|
||||||
aCompileEventHandlers);
|
aCompileEventHandlers);
|
||||||
|
|
||||||
|
mUnboundFromTree = false;
|
||||||
|
|
||||||
if (aDocument) {
|
if (aDocument) {
|
||||||
mAutoplayEnabled =
|
mAutoplayEnabled =
|
||||||
IsAutoplayEnabled() && (!aDocument || !aDocument->IsStaticDocument()) &&
|
IsAutoplayEnabled() && (!aDocument || !aDocument->IsStaticDocument()) &&
|
||||||
|
@ -3416,7 +3418,6 @@ nsresult HTMLMediaElement::BindToTree(nsIDocument* aDocument, nsIContent* aParen
|
||||||
// It's value may have changed, so update it.
|
// It's value may have changed, so update it.
|
||||||
UpdatePreloadAction();
|
UpdatePreloadAction();
|
||||||
}
|
}
|
||||||
mElementInTreeState = ELEMENT_INTREE;
|
|
||||||
|
|
||||||
if (mDecoder) {
|
if (mDecoder) {
|
||||||
// When the MediaElement is binding to tree, the dormant status is
|
// When the MediaElement is binding to tree, the dormant status is
|
||||||
|
@ -3650,11 +3651,7 @@ HTMLMediaElement::ReportTelemetry()
|
||||||
void HTMLMediaElement::UnbindFromTree(bool aDeep,
|
void HTMLMediaElement::UnbindFromTree(bool aDeep,
|
||||||
bool aNullParent)
|
bool aNullParent)
|
||||||
{
|
{
|
||||||
if (!mPaused && mNetworkState != nsIDOMHTMLMediaElement::NETWORK_EMPTY) {
|
mUnboundFromTree = true;
|
||||||
Pause();
|
|
||||||
}
|
|
||||||
|
|
||||||
mElementInTreeState = ELEMENT_NOT_INTREE_HAD_INTREE;
|
|
||||||
|
|
||||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||||
|
|
||||||
|
@ -3662,6 +3659,15 @@ void HTMLMediaElement::UnbindFromTree(bool aDeep,
|
||||||
MOZ_ASSERT(IsHidden());
|
MOZ_ASSERT(IsHidden());
|
||||||
mDecoder->NotifyOwnerActivityChanged(false);
|
mDecoder->NotifyOwnerActivityChanged(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RefPtr<HTMLMediaElement> self(this);
|
||||||
|
nsCOMPtr<nsIRunnable> task = NS_NewRunnableFunction([self] () {
|
||||||
|
if (self->mUnboundFromTree &&
|
||||||
|
self->mNetworkState != nsIDOMHTMLMediaElement::NETWORK_EMPTY) {
|
||||||
|
self->Pause();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
RunInStableState(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
|
@ -4989,11 +4995,8 @@ bool HTMLMediaElement::IsActive() const
|
||||||
|
|
||||||
bool HTMLMediaElement::IsHidden() const
|
bool HTMLMediaElement::IsHidden() const
|
||||||
{
|
{
|
||||||
if (mElementInTreeState == ELEMENT_NOT_INTREE_HAD_INTREE) {
|
nsIDocument* ownerDoc;
|
||||||
return true;
|
return mUnboundFromTree || !(ownerDoc = OwnerDoc()) || ownerDoc->Hidden();
|
||||||
}
|
|
||||||
nsIDocument* ownerDoc = OwnerDoc();
|
|
||||||
return !ownerDoc || ownerDoc->Hidden();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoFrameContainer* HTMLMediaElement::GetVideoFrameContainer()
|
VideoFrameContainer* HTMLMediaElement::GetVideoFrameContainer()
|
||||||
|
|
|
@ -1632,17 +1632,10 @@ protected:
|
||||||
// MediaStream.
|
// MediaStream.
|
||||||
nsCOMPtr<nsIPrincipal> mSrcStreamVideoPrincipal;
|
nsCOMPtr<nsIPrincipal> mSrcStreamVideoPrincipal;
|
||||||
|
|
||||||
enum ElementInTreeState {
|
// True if UnbindFromTree() is called on the element.
|
||||||
// The MediaElement is not in the DOM tree now.
|
// Note this flag is false when the element is in a phase after creation and
|
||||||
ELEMENT_NOT_INTREE,
|
// before attaching to the DOM tree.
|
||||||
// The MediaElement is in the DOM tree now.
|
bool mUnboundFromTree = false;
|
||||||
ELEMENT_INTREE,
|
|
||||||
// The MediaElement is not in the DOM tree now but had been binded to the
|
|
||||||
// tree before.
|
|
||||||
ELEMENT_NOT_INTREE_HAD_INTREE
|
|
||||||
};
|
|
||||||
|
|
||||||
ElementInTreeState mElementInTreeState;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Helper class to measure times for MSE telemetry stats
|
// Helper class to measure times for MSE telemetry stats
|
||||||
|
|
|
@ -465,15 +465,16 @@ HTMLObjectElement::GetContentDocument(nsIDOMDocument **aContentDocument)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG_POINTER(aContentDocument);
|
NS_ENSURE_ARG_POINTER(aContentDocument);
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(GetContentDocument());
|
nsCOMPtr<nsIDOMDocument> domDoc =
|
||||||
|
do_QueryInterface(GetContentDocument(Some(nsContentUtils::SubjectPrincipal())));
|
||||||
domDoc.forget(aContentDocument);
|
domDoc.forget(aContentDocument);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsPIDOMWindowOuter*
|
nsPIDOMWindowOuter*
|
||||||
HTMLObjectElement::GetContentWindow()
|
HTMLObjectElement::GetContentWindow(const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal)
|
||||||
{
|
{
|
||||||
nsIDocument* doc = GetContentDocument();
|
nsIDocument* doc = GetContentDocument(aSubjectPrincipal);
|
||||||
if (doc) {
|
if (doc) {
|
||||||
return doc->GetWindow();
|
return doc->GetWindow();
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,7 +156,10 @@ public:
|
||||||
SetHTMLAttr(nsGkAtoms::height, aValue, aRv);
|
SetHTMLAttr(nsGkAtoms::height, aValue, aRv);
|
||||||
}
|
}
|
||||||
using nsObjectLoadingContent::GetContentDocument;
|
using nsObjectLoadingContent::GetContentDocument;
|
||||||
nsPIDOMWindowOuter* GetContentWindow();
|
|
||||||
|
nsPIDOMWindowOuter*
|
||||||
|
GetContentWindow(const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal);
|
||||||
|
|
||||||
using nsIConstraintValidation::CheckValidity;
|
using nsIConstraintValidation::CheckValidity;
|
||||||
using nsIConstraintValidation::ReportValidity;
|
using nsIConstraintValidation::ReportValidity;
|
||||||
using nsIConstraintValidation::GetValidationMessage;
|
using nsIConstraintValidation::GetValidationMessage;
|
||||||
|
@ -234,9 +237,11 @@ public:
|
||||||
{
|
{
|
||||||
SetHTMLAttr(nsGkAtoms::border, aValue, aRv);
|
SetHTMLAttr(nsGkAtoms::border, aValue, aRv);
|
||||||
}
|
}
|
||||||
nsIDocument* GetSVGDocument()
|
|
||||||
|
nsIDocument*
|
||||||
|
GetSVGDocument(const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal)
|
||||||
{
|
{
|
||||||
return GetContentDocument();
|
return GetContentDocument(aSubjectPrincipal);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -8,18 +8,11 @@
|
||||||
#include "mozilla/dom/HTMLPictureElementBinding.h"
|
#include "mozilla/dom/HTMLPictureElementBinding.h"
|
||||||
#include "mozilla/dom/HTMLImageElement.h"
|
#include "mozilla/dom/HTMLImageElement.h"
|
||||||
|
|
||||||
#include "mozilla/Preferences.h"
|
|
||||||
static const char *kPrefPictureEnabled = "dom.image.picture.enabled";
|
|
||||||
|
|
||||||
// Expand NS_IMPL_NS_NEW_HTML_ELEMENT(Picture) to add pref check.
|
// Expand NS_IMPL_NS_NEW_HTML_ELEMENT(Picture) to add pref check.
|
||||||
nsGenericHTMLElement*
|
nsGenericHTMLElement*
|
||||||
NS_NewHTMLPictureElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
|
NS_NewHTMLPictureElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
|
||||||
mozilla::dom::FromParser aFromParser)
|
mozilla::dom::FromParser aFromParser)
|
||||||
{
|
{
|
||||||
if (!mozilla::dom::HTMLPictureElement::IsPictureEnabled()) {
|
|
||||||
return new mozilla::dom::HTMLUnknownElement(aNodeInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new mozilla::dom::HTMLPictureElement(aNodeInfo);
|
return new mozilla::dom::HTMLPictureElement(aNodeInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,13 +88,6 @@ HTMLPictureElement::InsertChildAt(nsIContent* aKid, uint32_t aIndex, bool aNotif
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
HTMLPictureElement::IsPictureEnabled()
|
|
||||||
{
|
|
||||||
return HTMLImageElement::IsSrcsetEnabled() &&
|
|
||||||
Preferences::GetBool(kPrefPictureEnabled, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
JSObject*
|
JSObject*
|
||||||
HTMLPictureElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
HTMLPictureElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,8 +11,6 @@
|
||||||
#include "nsIDOMHTMLPictureElement.h"
|
#include "nsIDOMHTMLPictureElement.h"
|
||||||
#include "nsGenericHTMLElement.h"
|
#include "nsGenericHTMLElement.h"
|
||||||
|
|
||||||
#include "mozilla/dom/HTMLUnknownElement.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
|
@ -32,8 +30,6 @@ public:
|
||||||
virtual void RemoveChildAt(uint32_t aIndex, bool aNotify) override;
|
virtual void RemoveChildAt(uint32_t aIndex, bool aNotify) override;
|
||||||
virtual nsresult InsertChildAt(nsIContent* aKid, uint32_t aIndex, bool aNotify) override;
|
virtual nsresult InsertChildAt(nsIContent* aKid, uint32_t aIndex, bool aNotify) override;
|
||||||
|
|
||||||
static bool IsPictureEnabled();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~HTMLPictureElement();
|
virtual ~HTMLPictureElement();
|
||||||
|
|
||||||
|
|
|
@ -187,9 +187,10 @@ public:
|
||||||
// height covered by <applet>
|
// height covered by <applet>
|
||||||
// align covered by <applet>
|
// align covered by <applet>
|
||||||
// name covered by <applet>
|
// name covered by <applet>
|
||||||
nsIDocument* GetSVGDocument()
|
nsIDocument*
|
||||||
|
GetSVGDocument(const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal)
|
||||||
{
|
{
|
||||||
return GetContentDocument();
|
return GetContentDocument(aSubjectPrincipal);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -71,7 +71,7 @@ load 903106.html
|
||||||
load 916322-1.html
|
load 916322-1.html
|
||||||
load 916322-2.html
|
load 916322-2.html
|
||||||
load 1032654.html
|
load 1032654.html
|
||||||
pref(dom.image.srcset.enabled,true) load 1141260.html
|
load 1141260.html
|
||||||
load 1228876.html
|
load 1228876.html
|
||||||
load 1230110.html
|
load 1230110.html
|
||||||
load 1237633.html
|
load 1237633.html
|
||||||
|
|
|
@ -79,13 +79,14 @@ nsresult
|
||||||
nsGenericHTMLFrameElement::GetContentDocument(nsIDOMDocument** aContentDocument)
|
nsGenericHTMLFrameElement::GetContentDocument(nsIDOMDocument** aContentDocument)
|
||||||
{
|
{
|
||||||
NS_PRECONDITION(aContentDocument, "Null out param");
|
NS_PRECONDITION(aContentDocument, "Null out param");
|
||||||
nsCOMPtr<nsIDOMDocument> document = do_QueryInterface(GetContentDocument());
|
nsCOMPtr<nsIDOMDocument> document =
|
||||||
|
do_QueryInterface(GetContentDocument(Some(nsContentUtils::SubjectPrincipal())));
|
||||||
document.forget(aContentDocument);
|
document.forget(aContentDocument);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIDocument*
|
nsIDocument*
|
||||||
nsGenericHTMLFrameElement::GetContentDocument()
|
nsGenericHTMLFrameElement::GetContentDocument(const Maybe<nsIPrincipal*>& aSubjectPrincipal)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsPIDOMWindowOuter> win = GetContentWindow();
|
nsCOMPtr<nsPIDOMWindowOuter> win = GetContentWindow();
|
||||||
if (!win) {
|
if (!win) {
|
||||||
|
@ -98,8 +99,8 @@ nsGenericHTMLFrameElement::GetContentDocument()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return null for cross-origin contentDocument.
|
// Return null for cross-origin contentDocument.
|
||||||
if (!nsContentUtils::SubjectPrincipal()->
|
if (!aSubjectPrincipal.value()
|
||||||
SubsumesConsideringDomain(doc->NodePrincipal())) {
|
->SubsumesConsideringDomain(doc->NodePrincipal())) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return doc;
|
return doc;
|
||||||
|
|
|
@ -102,7 +102,8 @@ protected:
|
||||||
// it makes sense.
|
// it makes sense.
|
||||||
void EnsureFrameLoader();
|
void EnsureFrameLoader();
|
||||||
nsresult LoadSrc();
|
nsresult LoadSrc();
|
||||||
nsIDocument* GetContentDocument();
|
nsIDocument*
|
||||||
|
GetContentDocument(const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal);
|
||||||
nsresult GetContentDocument(nsIDOMDocument** aContentDocument);
|
nsresult GetContentDocument(nsIDOMDocument** aContentDocument);
|
||||||
already_AddRefed<nsPIDOMWindowOuter> GetContentWindow();
|
already_AddRefed<nsPIDOMWindowOuter> GetContentWindow();
|
||||||
|
|
||||||
|
|
|
@ -2390,7 +2390,7 @@ nsHTMLDocument::GenerateParserKey(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsHTMLDocument::GetDesignMode(nsAString & aDesignMode)
|
nsHTMLDocument::GetDesignMode(nsAString& aDesignMode)
|
||||||
{
|
{
|
||||||
if (HasFlag(NODE_IS_EDITABLE)) {
|
if (HasFlag(NODE_IS_EDITABLE)) {
|
||||||
aDesignMode.AssignLiteral("on");
|
aDesignMode.AssignLiteral("on");
|
||||||
|
@ -2832,17 +2832,22 @@ nsHTMLDocument::EditingStateChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsHTMLDocument::SetDesignMode(const nsAString & aDesignMode)
|
nsHTMLDocument::SetDesignMode(const nsAString& aDesignMode)
|
||||||
{
|
{
|
||||||
ErrorResult rv;
|
ErrorResult rv;
|
||||||
SetDesignMode(aDesignMode, rv);
|
SetDesignMode(aDesignMode, nsContentUtils::GetCurrentJSContext()
|
||||||
|
? Some(nsContentUtils::SubjectPrincipal())
|
||||||
|
: Nothing(), rv);
|
||||||
return rv.StealNSResult();
|
return rv.StealNSResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsHTMLDocument::SetDesignMode(const nsAString& aDesignMode, ErrorResult& rv)
|
nsHTMLDocument::SetDesignMode(const nsAString& aDesignMode,
|
||||||
|
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||||
|
ErrorResult& rv)
|
||||||
{
|
{
|
||||||
if (!nsContentUtils::LegacyIsCallerNativeCode() && !nsContentUtils::SubjectPrincipal()->Subsumes(NodePrincipal())) {
|
if (!nsContentUtils::LegacyIsCallerNativeCode() &&
|
||||||
|
!aSubjectPrincipal.value()->Subsumes(NodePrincipal())) {
|
||||||
rv.Throw(NS_ERROR_DOM_PROP_ACCESS_DENIED);
|
rv.Throw(NS_ERROR_DOM_PROP_ACCESS_DENIED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -210,8 +210,14 @@ public:
|
||||||
mozilla::ErrorResult& rv);
|
mozilla::ErrorResult& rv);
|
||||||
void Writeln(JSContext* cx, const mozilla::dom::Sequence<nsString>& aText,
|
void Writeln(JSContext* cx, const mozilla::dom::Sequence<nsString>& aText,
|
||||||
mozilla::ErrorResult& rv);
|
mozilla::ErrorResult& rv);
|
||||||
// The XPCOM GetDesignMode() works OK for us, since it never throws.
|
void GetDesignMode(nsAString& aDesignMode,
|
||||||
void SetDesignMode(const nsAString& aDesignMode, mozilla::ErrorResult& rv);
|
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal)
|
||||||
|
{
|
||||||
|
GetDesignMode(aDesignMode);
|
||||||
|
}
|
||||||
|
void SetDesignMode(const nsAString& aDesignMode,
|
||||||
|
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||||
|
mozilla::ErrorResult& rv);
|
||||||
bool ExecCommand(const nsAString& aCommandID, bool aDoShowUI,
|
bool ExecCommand(const nsAString& aCommandID, bool aDoShowUI,
|
||||||
const nsAString& aValue, mozilla::ErrorResult& rv);
|
const nsAString& aValue, mozilla::ErrorResult& rv);
|
||||||
bool QueryCommandEnabled(const nsAString& aCommandID,
|
bool QueryCommandEnabled(const nsAString& aCommandID,
|
||||||
|
|
|
@ -48,8 +48,8 @@ skip == bug917595-exif-rotated.jpg bug917595-exif-rotated.jpg
|
||||||
# Bug 1150490 disabling on Mulet as on B2G
|
# Bug 1150490 disabling on Mulet as on B2G
|
||||||
|
|
||||||
# Test support for SVG-as-image in <picture> elements.
|
# Test support for SVG-as-image in <picture> elements.
|
||||||
pref(dom.image.picture.enabled,true) pref(dom.image.srcset.enabled,true) == bug1106522-1.html bug1106522-1.html
|
== bug1106522-1.html bug1106522-1.html
|
||||||
pref(dom.image.picture.enabled,true) pref(dom.image.srcset.enabled,true) == bug1106522-2.html bug1106522-2.html
|
== bug1106522-2.html bug1106522-2.html
|
||||||
|
|
||||||
== href-attr-change-restyles.html href-attr-change-restyles.html
|
== href-attr-change-restyles.html href-attr-change-restyles.html
|
||||||
== figure.html figure.html
|
== figure.html figure.html
|
||||||
|
|
|
@ -44,8 +44,8 @@ fuzzy(1,149) == bug917595-iframe-1.html bug917595-1-ref.html
|
||||||
skip-if(B2G||Mulet) fuzzy-if((!B2G&&!Mulet),3,640) == bug917595-exif-rotated.jpg bug917595-pixel-rotated.jpg # bug 1060869 # Bug 1150490 disabling on Mulet as on B2G
|
skip-if(B2G||Mulet) fuzzy-if((!B2G&&!Mulet),3,640) == bug917595-exif-rotated.jpg bug917595-pixel-rotated.jpg # bug 1060869 # Bug 1150490 disabling on Mulet as on B2G
|
||||||
|
|
||||||
# Test support for SVG-as-image in <picture> elements.
|
# Test support for SVG-as-image in <picture> elements.
|
||||||
pref(dom.image.picture.enabled,true) pref(dom.image.srcset.enabled,true) == bug1106522-1.html bug1106522-ref.html
|
== bug1106522-1.html bug1106522-ref.html
|
||||||
pref(dom.image.picture.enabled,true) pref(dom.image.srcset.enabled,true) == bug1106522-2.html bug1106522-ref.html
|
== bug1106522-2.html bug1106522-ref.html
|
||||||
|
|
||||||
== href-attr-change-restyles.html href-attr-change-restyles-ref.html
|
== href-attr-change-restyles.html href-attr-change-restyles-ref.html
|
||||||
== figure.html figure-ref.html
|
== figure.html figure-ref.html
|
||||||
|
|
|
@ -29,9 +29,19 @@ interface nsIWorkerDebugger;
|
||||||
[scriptable, builtinclass, uuid(76e357ed-208d-4e4c-9165-1c4059707879)]
|
[scriptable, builtinclass, uuid(76e357ed-208d-4e4c-9165-1c4059707879)]
|
||||||
interface nsIServiceWorkerInfo : nsISupports
|
interface nsIServiceWorkerInfo : nsISupports
|
||||||
{
|
{
|
||||||
|
// State values below should match the ServiceWorkerState enumeration.
|
||||||
|
const unsigned short STATE_INSTALLING = 0;
|
||||||
|
const unsigned short STATE_INSTALLED = 1;
|
||||||
|
const unsigned short STATE_ACTIVATING = 2;
|
||||||
|
const unsigned short STATE_ACTIVATED = 3;
|
||||||
|
const unsigned short STATE_REDUNDANT = 4;
|
||||||
|
const unsigned short STATE_UNKNOWN = 5;
|
||||||
|
|
||||||
readonly attribute DOMString scriptSpec;
|
readonly attribute DOMString scriptSpec;
|
||||||
readonly attribute DOMString cacheName;
|
readonly attribute DOMString cacheName;
|
||||||
|
|
||||||
|
readonly attribute unsigned short state;
|
||||||
|
|
||||||
readonly attribute nsIWorkerDebugger debugger;
|
readonly attribute nsIWorkerDebugger debugger;
|
||||||
|
|
||||||
void attachDebugger();
|
void attachDebugger();
|
||||||
|
|
|
@ -3259,6 +3259,10 @@ TabChild::ReinitRendering()
|
||||||
lf->IdentifyTextureHost(mTextureFactoryIdentifier);
|
lf->IdentifyTextureHost(mTextureFactoryIdentifier);
|
||||||
|
|
||||||
mApzcTreeManager = CompositorBridgeChild::Get()->GetAPZCTreeManager(mLayersId);
|
mApzcTreeManager = CompositorBridgeChild::Get()->GetAPZCTreeManager(mLayersId);
|
||||||
|
if (mApzcTreeManager) {
|
||||||
|
APZChild* apz = ContentProcessController::Create(mUniqueId);
|
||||||
|
CompositorBridgeChild::Get()->SendPAPZConstructor(apz, mLayersId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -437,11 +437,8 @@ public:
|
||||||
|
|
||||||
mDecodeStartTime = TimeStamp::Now();
|
mDecodeStartTime = TimeStamp::Now();
|
||||||
|
|
||||||
// Reset other state to pristine values before starting decode.
|
mMaster->mIsPrerolling = true;
|
||||||
mMaster->mIsAudioPrerolling = !mMaster->DonePrerollingAudio() &&
|
mMaster->MaybeStopPrerolling();
|
||||||
!Reader()->IsWaitingAudioData();
|
|
||||||
mMaster->mIsVideoPrerolling = !mMaster->DonePrerollingVideo() &&
|
|
||||||
!Reader()->IsWaitingVideoData();
|
|
||||||
|
|
||||||
// Ensure that we've got tasks enqueued to decode data if we need to.
|
// Ensure that we've got tasks enqueued to decode data if we need to.
|
||||||
mMaster->DispatchDecodeTasksIfNeeded();
|
mMaster->DispatchDecodeTasksIfNeeded();
|
||||||
|
@ -455,6 +452,7 @@ public:
|
||||||
TimeDuration decodeDuration = TimeStamp::Now() - mDecodeStartTime;
|
TimeDuration decodeDuration = TimeStamp::Now() - mDecodeStartTime;
|
||||||
SLOG("Exiting DECODING, decoded for %.3lfs", decodeDuration.ToSeconds());
|
SLOG("Exiting DECODING, decoded for %.3lfs", decodeDuration.ToSeconds());
|
||||||
}
|
}
|
||||||
|
mMaster->mIsPrerolling = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Step() override
|
void Step() override
|
||||||
|
@ -718,8 +716,6 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
|
||||||
mPlaybackRate(1.0),
|
mPlaybackRate(1.0),
|
||||||
mLowAudioThresholdUsecs(detail::LOW_AUDIO_USECS),
|
mLowAudioThresholdUsecs(detail::LOW_AUDIO_USECS),
|
||||||
mAmpleAudioThresholdUsecs(detail::AMPLE_AUDIO_USECS),
|
mAmpleAudioThresholdUsecs(detail::AMPLE_AUDIO_USECS),
|
||||||
mIsAudioPrerolling(false),
|
|
||||||
mIsVideoPrerolling(false),
|
|
||||||
mAudioCaptured(false),
|
mAudioCaptured(false),
|
||||||
INIT_WATCHABLE(mAudioCompleted, false),
|
INIT_WATCHABLE(mAudioCompleted, false),
|
||||||
INIT_WATCHABLE(mVideoCompleted, false),
|
INIT_WATCHABLE(mVideoCompleted, false),
|
||||||
|
@ -989,12 +985,11 @@ MediaDecoderStateMachine::NeedToSkipToNextKeyframe()
|
||||||
// readers that are async, as since their audio decode runs on a different
|
// readers that are async, as since their audio decode runs on a different
|
||||||
// task queue it should never run low and skipping won't help their decode.
|
// task queue it should never run low and skipping won't help their decode.
|
||||||
bool isLowOnDecodedAudio = !mReader->IsAsync() &&
|
bool isLowOnDecodedAudio = !mReader->IsAsync() &&
|
||||||
!mIsAudioPrerolling && IsAudioDecoding() &&
|
IsAudioDecoding() &&
|
||||||
(GetDecodedAudioDuration() <
|
(GetDecodedAudioDuration() <
|
||||||
mLowAudioThresholdUsecs * mPlaybackRate);
|
mLowAudioThresholdUsecs * mPlaybackRate);
|
||||||
bool isLowOnDecodedVideo = !mIsVideoPrerolling &&
|
bool isLowOnDecodedVideo = (GetClock() - mDecodedVideoEndTime) * mPlaybackRate >
|
||||||
((GetClock() - mDecodedVideoEndTime) * mPlaybackRate >
|
LOW_VIDEO_THRESHOLD_USECS;
|
||||||
LOW_VIDEO_THRESHOLD_USECS);
|
|
||||||
bool lowBuffered = HasLowBufferedData();
|
bool lowBuffered = HasLowBufferedData();
|
||||||
|
|
||||||
if ((isLowOnDecodedAudio || isLowOnDecodedVideo) && !lowBuffered) {
|
if ((isLowOnDecodedAudio || isLowOnDecodedVideo) && !lowBuffered) {
|
||||||
|
@ -1050,9 +1045,7 @@ MediaDecoderStateMachine::OnAudioDecoded(MediaData* aAudioSample)
|
||||||
|
|
||||||
case DECODER_STATE_DECODING: {
|
case DECODER_STATE_DECODING: {
|
||||||
Push(audio, MediaData::AUDIO_DATA);
|
Push(audio, MediaData::AUDIO_DATA);
|
||||||
if (mIsAudioPrerolling && DonePrerollingAudio()) {
|
MaybeStopPrerolling();
|
||||||
StopPrerollingAudio();
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1128,15 +1121,7 @@ MediaDecoderStateMachine::OnNotDecoded(MediaData::Type aType,
|
||||||
MOZ_ASSERT(mReader->IsWaitForDataSupported(),
|
MOZ_ASSERT(mReader->IsWaitForDataSupported(),
|
||||||
"Readers that send WAITING_FOR_DATA need to implement WaitForData");
|
"Readers that send WAITING_FOR_DATA need to implement WaitForData");
|
||||||
mReader->WaitForData(aType);
|
mReader->WaitForData(aType);
|
||||||
|
MaybeStopPrerolling();
|
||||||
// We are out of data to decode and will enter buffering mode soon.
|
|
||||||
// We want to play the frames we have already decoded, so we stop pre-rolling
|
|
||||||
// and ensure that loadeddata is fired as required.
|
|
||||||
if (isAudio) {
|
|
||||||
StopPrerollingAudio();
|
|
||||||
} else {
|
|
||||||
StopPrerollingVideo();
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1159,11 +1144,12 @@ MediaDecoderStateMachine::OnNotDecoded(MediaData::Type aType,
|
||||||
// state.
|
// state.
|
||||||
if (isAudio) {
|
if (isAudio) {
|
||||||
AudioQueue().Finish();
|
AudioQueue().Finish();
|
||||||
StopPrerollingAudio();
|
|
||||||
} else {
|
} else {
|
||||||
VideoQueue().Finish();
|
VideoQueue().Finish();
|
||||||
StopPrerollingVideo();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MaybeStopPrerolling();
|
||||||
|
|
||||||
switch (mState) {
|
switch (mState) {
|
||||||
case DECODER_STATE_DECODING_FIRSTFRAME:
|
case DECODER_STATE_DECODING_FIRSTFRAME:
|
||||||
MaybeFinishDecodeFirstFrame();
|
MaybeFinishDecodeFirstFrame();
|
||||||
|
@ -1238,9 +1224,7 @@ MediaDecoderStateMachine::OnVideoDecoded(MediaData* aVideoSample,
|
||||||
|
|
||||||
case DECODER_STATE_DECODING: {
|
case DECODER_STATE_DECODING: {
|
||||||
Push(video, MediaData::VIDEO_DATA);
|
Push(video, MediaData::VIDEO_DATA);
|
||||||
if (mIsVideoPrerolling && DonePrerollingVideo()) {
|
MaybeStopPrerolling();
|
||||||
StopPrerollingVideo();
|
|
||||||
}
|
|
||||||
|
|
||||||
// For non async readers, if the requested video sample was slow to
|
// For non async readers, if the requested video sample was slow to
|
||||||
// arrive, increase the amount of audio we buffer to ensure that we
|
// arrive, increase the amount of audio we buffer to ensure that we
|
||||||
|
@ -1400,6 +1384,19 @@ void MediaDecoderStateMachine::StopPlayback()
|
||||||
DispatchDecodeTasksIfNeeded();
|
DispatchDecodeTasksIfNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaDecoderStateMachine::MaybeStopPrerolling()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
|
if (mIsPrerolling &&
|
||||||
|
(DonePrerollingAudio() || mReader->IsWaitingAudioData()) &&
|
||||||
|
(DonePrerollingVideo() || mReader->IsWaitingVideoData())) {
|
||||||
|
mIsPrerolling = false;
|
||||||
|
// Check if we can start playback.
|
||||||
|
ScheduleStateMachine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MediaDecoderStateMachine::MaybeStartPlayback()
|
void MediaDecoderStateMachine::MaybeStartPlayback()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
|
@ -1414,13 +1411,10 @@ void MediaDecoderStateMachine::MaybeStartPlayback()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool playStatePermits = mPlayState == MediaDecoder::PLAY_STATE_PLAYING;
|
bool playStatePermits = mPlayState == MediaDecoder::PLAY_STATE_PLAYING;
|
||||||
if (!playStatePermits || mIsAudioPrerolling ||
|
if (!playStatePermits || mIsPrerolling || mAudioOffloading) {
|
||||||
mIsVideoPrerolling || mAudioOffloading) {
|
|
||||||
DECODER_LOG("Not starting playback [playStatePermits: %d, "
|
DECODER_LOG("Not starting playback [playStatePermits: %d, "
|
||||||
"mIsAudioPrerolling: %d, mIsVideoPrerolling: %d, "
|
"mIsPrerolling: %d, mAudioOffloading: %d]",
|
||||||
"mAudioOffloading: %d]",
|
playStatePermits, mIsPrerolling, mAudioOffloading);
|
||||||
(int)playStatePermits, (int)mIsAudioPrerolling,
|
|
||||||
(int)mIsVideoPrerolling, (int)mAudioOffloading);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2110,12 +2104,10 @@ MediaDecoderStateMachine::OnSeekTaskResolved(SeekTaskResolveValue aValue)
|
||||||
|
|
||||||
if (aValue.mIsAudioQueueFinished) {
|
if (aValue.mIsAudioQueueFinished) {
|
||||||
AudioQueue().Finish();
|
AudioQueue().Finish();
|
||||||
StopPrerollingAudio();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aValue.mIsVideoQueueFinished) {
|
if (aValue.mIsVideoQueueFinished) {
|
||||||
VideoQueue().Finish();
|
VideoQueue().Finish();
|
||||||
StopPrerollingVideo();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SeekCompleted();
|
SeekCompleted();
|
||||||
|
@ -2131,12 +2123,10 @@ MediaDecoderStateMachine::OnSeekTaskRejected(SeekTaskRejectValue aValue)
|
||||||
|
|
||||||
if (aValue.mIsAudioQueueFinished) {
|
if (aValue.mIsAudioQueueFinished) {
|
||||||
AudioQueue().Finish();
|
AudioQueue().Finish();
|
||||||
StopPrerollingAudio();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aValue.mIsVideoQueueFinished) {
|
if (aValue.mIsVideoQueueFinished) {
|
||||||
VideoQueue().Finish();
|
VideoQueue().Finish();
|
||||||
StopPrerollingVideo();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DecodeError(aValue.mError);
|
DecodeError(aValue.mError);
|
||||||
|
@ -2765,13 +2755,7 @@ MediaDecoderStateMachine::SetPlaybackRate(double aPlaybackRate)
|
||||||
mPlaybackRate = aPlaybackRate;
|
mPlaybackRate = aPlaybackRate;
|
||||||
mMediaSink->SetPlaybackRate(mPlaybackRate);
|
mMediaSink->SetPlaybackRate(mPlaybackRate);
|
||||||
|
|
||||||
if (mIsAudioPrerolling && DonePrerollingAudio()) {
|
// Schedule next cycle to check if we can stop prerolling.
|
||||||
StopPrerollingAudio();
|
|
||||||
}
|
|
||||||
if (mIsVideoPrerolling && DonePrerollingVideo()) {
|
|
||||||
StopPrerollingVideo();
|
|
||||||
}
|
|
||||||
|
|
||||||
ScheduleStateMachine();
|
ScheduleStateMachine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2933,9 +2917,8 @@ MediaDecoderStateMachine::SetAudioCaptured(bool aCaptured)
|
||||||
mAmpleAudioThresholdUsecs = mAudioCaptured ?
|
mAmpleAudioThresholdUsecs = mAudioCaptured ?
|
||||||
detail::AMPLE_AUDIO_USECS / 2 :
|
detail::AMPLE_AUDIO_USECS / 2 :
|
||||||
detail::AMPLE_AUDIO_USECS;
|
detail::AMPLE_AUDIO_USECS;
|
||||||
if (mIsAudioPrerolling && DonePrerollingAudio()) {
|
|
||||||
StopPrerollingAudio();
|
MaybeStopPrerolling();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t MediaDecoderStateMachine::GetAmpleVideoFrames() const
|
uint32_t MediaDecoderStateMachine::GetAmpleVideoFrames() const
|
||||||
|
@ -2959,12 +2942,11 @@ MediaDecoderStateMachine::DumpDebugInfo()
|
||||||
"GetMediaTime=%lld GetClock=%lld mMediaSink=%p "
|
"GetMediaTime=%lld GetClock=%lld mMediaSink=%p "
|
||||||
"mState=%s mPlayState=%d mSentFirstFrameLoadedEvent=%d IsPlaying=%d "
|
"mState=%s mPlayState=%d mSentFirstFrameLoadedEvent=%d IsPlaying=%d "
|
||||||
"mAudioStatus=%s mVideoStatus=%s mDecodedAudioEndTime=%lld mDecodedVideoEndTime=%lld "
|
"mAudioStatus=%s mVideoStatus=%s mDecodedAudioEndTime=%lld mDecodedVideoEndTime=%lld "
|
||||||
"mIsAudioPrerolling=%d mIsVideoPrerolling=%d "
|
"mIsPrerolling=%d mAudioCompleted=%d mVideoCompleted=%d",
|
||||||
"mAudioCompleted=%d mVideoCompleted=%d",
|
|
||||||
GetMediaTime(), mMediaSink->IsStarted() ? GetClock() : -1, mMediaSink.get(),
|
GetMediaTime(), mMediaSink->IsStarted() ? GetClock() : -1, mMediaSink.get(),
|
||||||
ToStateStr(), mPlayState.Ref(), mSentFirstFrameLoadedEvent, IsPlaying(),
|
ToStateStr(), mPlayState.Ref(), mSentFirstFrameLoadedEvent, IsPlaying(),
|
||||||
AudioRequestStatus(), VideoRequestStatus(), mDecodedAudioEndTime, mDecodedVideoEndTime,
|
AudioRequestStatus(), VideoRequestStatus(), mDecodedAudioEndTime, mDecodedVideoEndTime,
|
||||||
mIsAudioPrerolling, mIsVideoPrerolling, mAudioCompleted.Ref(), mVideoCompleted.Ref());
|
mIsPrerolling, mAudioCompleted.Ref(), mVideoCompleted.Ref());
|
||||||
});
|
});
|
||||||
|
|
||||||
OwnerThread()->DispatchStateChange(r.forget());
|
OwnerThread()->DispatchStateChange(r.forget());
|
||||||
|
|
|
@ -730,23 +730,7 @@ private:
|
||||||
VideoPrerollFrames() * mPlaybackRate + 1;
|
VideoPrerollFrames() * mPlaybackRate + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StopPrerollingAudio()
|
void MaybeStopPrerolling();
|
||||||
{
|
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
|
||||||
if (mIsAudioPrerolling) {
|
|
||||||
mIsAudioPrerolling = false;
|
|
||||||
ScheduleStateMachine();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void StopPrerollingVideo()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
|
||||||
if (mIsVideoPrerolling) {
|
|
||||||
mIsVideoPrerolling = false;
|
|
||||||
ScheduleStateMachine();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// When we start decoding (either for the first time, or after a pause)
|
// When we start decoding (either for the first time, or after a pause)
|
||||||
// we may be low on decoded data. We don't want our "low data" logic to
|
// we may be low on decoded data. We don't want our "low data" logic to
|
||||||
|
@ -754,10 +738,8 @@ private:
|
||||||
// can't keep up with the decode, and cause us to pause playback. So we
|
// can't keep up with the decode, and cause us to pause playback. So we
|
||||||
// have a "preroll" stage, where we ignore the results of our "low data"
|
// have a "preroll" stage, where we ignore the results of our "low data"
|
||||||
// logic during the first few frames of our decode. This occurs during
|
// logic during the first few frames of our decode. This occurs during
|
||||||
// playback. The flags below are true when the corresponding stream is
|
// playback.
|
||||||
// being "prerolled".
|
bool mIsPrerolling = false;
|
||||||
bool mIsAudioPrerolling;
|
|
||||||
bool mIsVideoPrerolling;
|
|
||||||
|
|
||||||
// Only one of a given pair of ({Audio,Video}DataPromise, WaitForDataPromise)
|
// Only one of a given pair of ({Audio,Video}DataPromise, WaitForDataPromise)
|
||||||
// should exist at any given moment.
|
// should exist at any given moment.
|
||||||
|
|
|
@ -464,7 +464,8 @@ public:
|
||||||
|
|
||||||
bool IsEncrypted() const
|
bool IsEncrypted() const
|
||||||
{
|
{
|
||||||
return mCrypto.IsEncrypted();
|
return (HasAudio() && mAudio.mCrypto.mValid) ||
|
||||||
|
(HasVideo() && mVideo.mCrypto.mValid);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasValidMedia() const
|
bool HasValidMedia() const
|
||||||
|
|
|
@ -1447,35 +1447,56 @@ MediaStreamGraphImpl::ForceShutDown(ShutdownTicket* aShutdownTicket)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Must be called on main thread");
|
NS_ASSERTION(NS_IsMainThread(), "Must be called on main thread");
|
||||||
STREAM_LOG(LogLevel::Debug, ("MediaStreamGraph %p ForceShutdown", this));
|
STREAM_LOG(LogLevel::Debug, ("MediaStreamGraph %p ForceShutdown", this));
|
||||||
{
|
|
||||||
MonitorAutoLock lock(mMonitor);
|
MonitorAutoLock lock(mMonitor);
|
||||||
mForceShutDown = true;
|
if (aShutdownTicket) {
|
||||||
mForceShutdownTicket = aShutdownTicket;
|
MOZ_ASSERT(!mForceShutdownTicket);
|
||||||
if (mLifecycleState == LIFECYCLE_THREAD_NOT_STARTED) {
|
// Avoid waiting forever for a graph to shut down
|
||||||
// We *could* have just sent this a message to start up, so don't
|
// synchronously. Reports are that some 3rd-party audio drivers
|
||||||
// yank the rug out from under it. Tell it to startup and let it
|
// occasionally hang in shutdown (both for us and Chrome).
|
||||||
// shut down.
|
mShutdownTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||||
RefPtr<GraphDriver> driver = CurrentDriver();
|
if (!mShutdownTimer) {
|
||||||
MonitorAutoUnlock unlock(mMonitor);
|
return;
|
||||||
driver->Start();
|
|
||||||
}
|
}
|
||||||
EnsureNextIterationLocked();
|
mShutdownTimer->InitWithCallback(this,
|
||||||
|
MediaStreamGraph::AUDIO_CALLBACK_DRIVER_SHUTDOWN_TIMEOUT,
|
||||||
|
nsITimer::TYPE_ONE_SHOT);
|
||||||
}
|
}
|
||||||
|
mForceShutDown = true;
|
||||||
|
mForceShutdownTicket = aShutdownTicket;
|
||||||
|
if (mLifecycleState == LIFECYCLE_THREAD_NOT_STARTED) {
|
||||||
|
// We *could* have just sent this a message to start up, so don't
|
||||||
|
// yank the rug out from under it. Tell it to startup and let it
|
||||||
|
// shut down.
|
||||||
|
RefPtr<GraphDriver> driver = CurrentDriver();
|
||||||
|
MonitorAutoUnlock unlock(mMonitor);
|
||||||
|
driver->Start();
|
||||||
|
}
|
||||||
|
EnsureNextIterationLocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
MediaStreamGraphImpl::Notify(nsITimer* aTimer)
|
||||||
|
{
|
||||||
|
MonitorAutoLock lock(mMonitor);
|
||||||
|
NS_ASSERTION(!mForceShutdownTicket, "MediaStreamGraph took too long to shut down!");
|
||||||
|
// Sigh, graph took too long to shut down. Stop blocking system
|
||||||
|
// shutdown and hope all is well.
|
||||||
|
mForceShutdownTicket = nullptr;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* static */ StaticRefPtr<nsIAsyncShutdownBlocker> gMediaStreamGraphShutdownBlocker;
|
/* static */ StaticRefPtr<nsIAsyncShutdownBlocker> gMediaStreamGraphShutdownBlocker;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class MediaStreamGraphShutDownRunnable : public Runnable
|
class MediaStreamGraphShutDownRunnable : public Runnable {
|
||||||
, public nsITimerCallback {
|
|
||||||
public:
|
public:
|
||||||
explicit MediaStreamGraphShutDownRunnable(MediaStreamGraphImpl* aGraph)
|
explicit MediaStreamGraphShutDownRunnable(MediaStreamGraphImpl* aGraph)
|
||||||
: mGraph(aGraph)
|
: mGraph(aGraph)
|
||||||
{}
|
{}
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_IMETHOD Run()
|
||||||
|
|
||||||
NS_IMETHOD Run() override
|
|
||||||
{
|
{
|
||||||
NS_ASSERTION(mGraph->mDetectedNotRunning,
|
NS_ASSERTION(mGraph->mDetectedNotRunning,
|
||||||
"We should know the graph thread control loop isn't running!");
|
"We should know the graph thread control loop isn't running!");
|
||||||
|
@ -1493,24 +1514,12 @@ public:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (mGraph->mForceShutdownTicket) {
|
|
||||||
// Avoid waiting forever for a callback driver to shut down
|
|
||||||
// synchronously. Reports are that some 3rd-party audio drivers
|
|
||||||
// occasionally hang in shutdown (both for us and Chrome).
|
|
||||||
mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
|
||||||
if (!mTimer) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
mTimer->InitWithCallback(this,
|
|
||||||
MediaStreamGraph::AUDIO_CALLBACK_DRIVER_SHUTDOWN_TIMEOUT,
|
|
||||||
nsITimer::TYPE_ONE_SHOT);
|
|
||||||
}
|
|
||||||
|
|
||||||
mGraph->mDriver->Shutdown(); // This will wait until it's shutdown since
|
mGraph->mDriver->Shutdown(); // This will wait until it's shutdown since
|
||||||
// we'll start tearing down the graph after this
|
// we'll start tearing down the graph after this
|
||||||
|
|
||||||
|
// Safe to access these without the monitor since the graph isn't running.
|
||||||
// We may be one of several graphs. Drop ticket to eventually unblock shutdown.
|
// We may be one of several graphs. Drop ticket to eventually unblock shutdown.
|
||||||
if (mTimer && !mGraph->mForceShutdownTicket) {
|
if (mGraph->mShutdownTimer && !mGraph->mForceShutdownTicket) {
|
||||||
MOZ_ASSERT(false,
|
MOZ_ASSERT(false,
|
||||||
"AudioCallbackDriver took too long to shut down and we let shutdown"
|
"AudioCallbackDriver took too long to shut down and we let shutdown"
|
||||||
" continue - freezing and leaking");
|
" continue - freezing and leaking");
|
||||||
|
@ -1519,7 +1528,6 @@ public:
|
||||||
// teardown and just leak, for safety.
|
// teardown and just leak, for safety.
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
mTimer = nullptr;
|
|
||||||
mGraph->mForceShutdownTicket = nullptr;
|
mGraph->mForceShutdownTicket = nullptr;
|
||||||
|
|
||||||
// We can't block past the final LIFECYCLE_WAITING_FOR_STREAM_DESTRUCTION
|
// We can't block past the final LIFECYCLE_WAITING_FOR_STREAM_DESTRUCTION
|
||||||
|
@ -1552,30 +1560,10 @@ public:
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHOD Notify(nsITimer* aTimer) override
|
|
||||||
{
|
|
||||||
// Sigh, driver took too long to shut down. Stop blocking system
|
|
||||||
// shutdown and hope all is well. Shutdown of this graph will proceed
|
|
||||||
// if the driver eventually comes back.
|
|
||||||
NS_ASSERTION(!(mGraph->mForceShutdownTicket),
|
|
||||||
"AudioCallbackDriver took too long to shut down - probably hung");
|
|
||||||
|
|
||||||
mGraph->mForceShutdownTicket = nullptr;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~MediaStreamGraphShutDownRunnable() {}
|
|
||||||
|
|
||||||
nsCOMPtr<nsITimer> mTimer;
|
|
||||||
RefPtr<MediaStreamGraphImpl> mGraph;
|
RefPtr<MediaStreamGraphImpl> mGraph;
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS_INHERITED(MediaStreamGraphShutDownRunnable, Runnable, nsITimerCallback)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MediaStreamGraphStableStateRunnable : public Runnable {
|
class MediaStreamGraphStableStateRunnable : public Runnable {
|
||||||
public:
|
public:
|
||||||
explicit MediaStreamGraphStableStateRunnable(MediaStreamGraphImpl* aGraph,
|
explicit MediaStreamGraphStableStateRunnable(MediaStreamGraphImpl* aGraph,
|
||||||
|
@ -3444,8 +3432,6 @@ MediaStreamGraph::DestroyNonRealtimeInstance(MediaStreamGraph* aGraph)
|
||||||
MOZ_ASSERT(aGraph->IsNonRealtime(), "Should not destroy the global graph here");
|
MOZ_ASSERT(aGraph->IsNonRealtime(), "Should not destroy the global graph here");
|
||||||
|
|
||||||
MediaStreamGraphImpl* graph = static_cast<MediaStreamGraphImpl*>(aGraph);
|
MediaStreamGraphImpl* graph = static_cast<MediaStreamGraphImpl*>(aGraph);
|
||||||
if (graph->mForceShutDown)
|
|
||||||
return; // already done
|
|
||||||
|
|
||||||
if (!graph->mNonRealtimeProcessing) {
|
if (!graph->mNonRealtimeProcessing) {
|
||||||
// Start the graph, but don't produce anything
|
// Start the graph, but don't produce anything
|
||||||
|
@ -3454,7 +3440,7 @@ MediaStreamGraph::DestroyNonRealtimeInstance(MediaStreamGraph* aGraph)
|
||||||
graph->ForceShutDown(nullptr);
|
graph->ForceShutDown(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(MediaStreamGraphImpl, nsIMemoryReporter)
|
NS_IMPL_ISUPPORTS(MediaStreamGraphImpl, nsIMemoryReporter, nsITimerCallback)
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
MediaStreamGraphImpl::CollectReports(nsIHandleReportCallback* aHandleReport,
|
MediaStreamGraphImpl::CollectReports(nsIHandleReportCallback* aHandleReport,
|
||||||
|
@ -3969,7 +3955,7 @@ void
|
||||||
MediaStreamGraphImpl::UnregisterCaptureStreamForWindow(uint64_t aWindowId)
|
MediaStreamGraphImpl::UnregisterCaptureStreamForWindow(uint64_t aWindowId)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
for (uint32_t i = 0; i < mWindowCaptureStreams.Length(); i++) {
|
for (int32_t i = mWindowCaptureStreams.Length() - 1; i >= 0; i--) {
|
||||||
if (mWindowCaptureStreams[i].mWindowId == aWindowId) {
|
if (mWindowCaptureStreams[i].mWindowId == aWindowId) {
|
||||||
mWindowCaptureStreams.RemoveElementAt(i);
|
mWindowCaptureStreams.RemoveElementAt(i);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include "nsDataHashtable.h"
|
#include "nsDataHashtable.h"
|
||||||
|
|
||||||
|
#include "nsITimer.h"
|
||||||
#include "mozilla/Monitor.h"
|
#include "mozilla/Monitor.h"
|
||||||
#include "mozilla/TimeStamp.h"
|
#include "mozilla/TimeStamp.h"
|
||||||
#include "nsIMemoryReporter.h"
|
#include "nsIMemoryReporter.h"
|
||||||
|
@ -97,11 +98,13 @@ public:
|
||||||
* object too.
|
* object too.
|
||||||
*/
|
*/
|
||||||
class MediaStreamGraphImpl : public MediaStreamGraph,
|
class MediaStreamGraphImpl : public MediaStreamGraph,
|
||||||
public nsIMemoryReporter
|
public nsIMemoryReporter,
|
||||||
|
public nsITimerCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||||||
NS_DECL_NSIMEMORYREPORTER
|
NS_DECL_NSIMEMORYREPORTER
|
||||||
|
NS_DECL_NSITIMERCALLBACK
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use aGraphDriverRequested with SYSTEM_THREAD_DRIVER or AUDIO_THREAD_DRIVER
|
* Use aGraphDriverRequested with SYSTEM_THREAD_DRIVER or AUDIO_THREAD_DRIVER
|
||||||
|
@ -808,6 +811,9 @@ public:
|
||||||
|
|
||||||
dom::AudioChannel AudioChannel() const { return mAudioChannel; }
|
dom::AudioChannel AudioChannel() const { return mAudioChannel; }
|
||||||
|
|
||||||
|
// used to limit graph shutdown time
|
||||||
|
nsCOMPtr<nsITimer> mShutdownTimer;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual ~MediaStreamGraphImpl();
|
virtual ~MediaStreamGraphImpl();
|
||||||
|
|
||||||
|
|
|
@ -54,11 +54,13 @@ parent:
|
||||||
async Drain();
|
async Drain();
|
||||||
async Shutdown();
|
async Shutdown();
|
||||||
|
|
||||||
|
async SetSeekThreshold(int64_t time);
|
||||||
|
|
||||||
async __delete__();
|
async __delete__();
|
||||||
|
|
||||||
child:
|
child:
|
||||||
|
|
||||||
async InitComplete();
|
async InitComplete(bool hardware, nsCString hardwareReason);
|
||||||
async InitFailed(nsresult reason);
|
async InitFailed(nsresult reason);
|
||||||
|
|
||||||
// Each output includes a SurfaceDescriptorGPUVideo that represents the decoded
|
// Each output includes a SurfaceDescriptorGPUVideo that represents the decoded
|
||||||
|
|
|
@ -102,6 +102,26 @@ RemoteVideoDecoder::Shutdown()
|
||||||
}), NS_DISPATCH_NORMAL);
|
}), NS_DISPATCH_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
RemoteVideoDecoder::IsHardwareAccelerated(nsACString& aFailureReason) const
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mCallback->OnReaderTaskQueue());
|
||||||
|
return mActor->IsHardwareAccelerated(aFailureReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RemoteVideoDecoder::SetSeekThreshold(const media::TimeUnit& aTime)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mCallback->OnReaderTaskQueue());
|
||||||
|
RefPtr<RemoteVideoDecoder> self = this;
|
||||||
|
media::TimeUnit time = aTime;
|
||||||
|
VideoDecoderManagerChild::GetManagerThread()->Dispatch(NS_NewRunnableFunction([=]() {
|
||||||
|
MOZ_ASSERT(self->mActor);
|
||||||
|
self->mActor->SetSeekThreshold(time);
|
||||||
|
}), NS_DISPATCH_NORMAL);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
RemoteDecoderModule::Startup()
|
RemoteDecoderModule::Startup()
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,6 +32,8 @@ public:
|
||||||
void Flush() override;
|
void Flush() override;
|
||||||
void Drain() override;
|
void Drain() override;
|
||||||
void Shutdown() override;
|
void Shutdown() override;
|
||||||
|
bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
|
||||||
|
void SetSeekThreshold(const media::TimeUnit& aTime) override;
|
||||||
|
|
||||||
const char* GetDescriptionName() const override { return "RemoteVideoDecoder"; }
|
const char* GetDescriptionName() const override { return "RemoteVideoDecoder"; }
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,8 @@ VideoDecoderChild::VideoDecoderChild()
|
||||||
: mThread(VideoDecoderManagerChild::GetManagerThread())
|
: mThread(VideoDecoderManagerChild::GetManagerThread())
|
||||||
, mLayersBackend(layers::LayersBackend::LAYERS_NONE)
|
, mLayersBackend(layers::LayersBackend::LAYERS_NONE)
|
||||||
, mCanSend(true)
|
, mCanSend(true)
|
||||||
|
, mInitialized(false)
|
||||||
|
, mIsHardwareAccelerated(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,10 +82,13 @@ VideoDecoderChild::RecvError(const nsresult& aError)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
VideoDecoderChild::RecvInitComplete()
|
VideoDecoderChild::RecvInitComplete(const bool& aHardware, const nsCString& aHardwareReason)
|
||||||
{
|
{
|
||||||
AssertOnManagerThread();
|
AssertOnManagerThread();
|
||||||
mInitPromise.Resolve(TrackInfo::kVideoTrack, __func__);
|
mInitPromise.Resolve(TrackInfo::kVideoTrack, __func__);
|
||||||
|
mInitialized = true;
|
||||||
|
mIsHardwareAccelerated = aHardware;
|
||||||
|
mHardwareAcceleratedReason = aHardwareReason;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,6 +103,13 @@ VideoDecoderChild::RecvInitFailed(const nsresult& aReason)
|
||||||
void
|
void
|
||||||
VideoDecoderChild::ActorDestroy(ActorDestroyReason aWhy)
|
VideoDecoderChild::ActorDestroy(ActorDestroyReason aWhy)
|
||||||
{
|
{
|
||||||
|
if (aWhy == AbnormalShutdown) {
|
||||||
|
if (mInitialized) {
|
||||||
|
mCallback->Error(NS_ERROR_DOM_MEDIA_FATAL_ERR);
|
||||||
|
} else {
|
||||||
|
mInitPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
|
||||||
|
}
|
||||||
|
}
|
||||||
mCanSend = false;
|
mCanSend = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,6 +209,23 @@ VideoDecoderChild::Shutdown()
|
||||||
if (!mCanSend || !SendShutdown()) {
|
if (!mCanSend || !SendShutdown()) {
|
||||||
mCallback->Error(NS_ERROR_DOM_MEDIA_FATAL_ERR);
|
mCallback->Error(NS_ERROR_DOM_MEDIA_FATAL_ERR);
|
||||||
}
|
}
|
||||||
|
mInitialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
VideoDecoderChild::IsHardwareAccelerated(nsACString& aFailureReason) const
|
||||||
|
{
|
||||||
|
aFailureReason = mHardwareAcceleratedReason;
|
||||||
|
return mIsHardwareAccelerated;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
VideoDecoderChild::SetSeekThreshold(const media::TimeUnit& aTime)
|
||||||
|
{
|
||||||
|
AssertOnManagerThread();
|
||||||
|
if (!mCanSend || !SendSetSeekThreshold(aTime.ToMicroseconds())) {
|
||||||
|
mCallback->Error(NS_ERROR_DOM_MEDIA_FATAL_ERR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
bool RecvInputExhausted() override;
|
bool RecvInputExhausted() override;
|
||||||
bool RecvDrainComplete() override;
|
bool RecvDrainComplete() override;
|
||||||
bool RecvError(const nsresult& aError) override;
|
bool RecvError(const nsresult& aError) override;
|
||||||
bool RecvInitComplete() override;
|
bool RecvInitComplete(const bool& aHardware, const nsCString& aHardwareReason) override;
|
||||||
bool RecvInitFailed(const nsresult& aReason) override;
|
bool RecvInitFailed(const nsresult& aReason) override;
|
||||||
|
|
||||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||||
|
@ -39,6 +39,8 @@ public:
|
||||||
void Flush();
|
void Flush();
|
||||||
void Drain();
|
void Drain();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
bool IsHardwareAccelerated(nsACString& aFailureReason) const;
|
||||||
|
void SetSeekThreshold(const media::TimeUnit& aTime);
|
||||||
|
|
||||||
MOZ_IS_CLASS_INIT
|
MOZ_IS_CLASS_INIT
|
||||||
void InitIPDL(MediaDataDecoderCallback* aCallback,
|
void InitIPDL(MediaDataDecoderCallback* aCallback,
|
||||||
|
@ -63,7 +65,10 @@ private:
|
||||||
|
|
||||||
VideoInfo mVideoInfo;
|
VideoInfo mVideoInfo;
|
||||||
layers::LayersBackend mLayersBackend;
|
layers::LayersBackend mLayersBackend;
|
||||||
|
nsCString mHardwareAcceleratedReason;
|
||||||
bool mCanSend;
|
bool mCanSend;
|
||||||
|
bool mInitialized;
|
||||||
|
bool mIsHardwareAccelerated;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
|
@ -81,7 +81,9 @@ VideoDecoderParent::RecvInit(const VideoInfo& aInfo, const layers::LayersBackend
|
||||||
mDecoder->Init()->Then(mManagerTaskQueue, __func__,
|
mDecoder->Init()->Then(mManagerTaskQueue, __func__,
|
||||||
[self] (TrackInfo::TrackType aTrack) {
|
[self] (TrackInfo::TrackType aTrack) {
|
||||||
if (!self->mDestroyed) {
|
if (!self->mDestroyed) {
|
||||||
Unused << self->SendInitComplete();
|
nsCString hardwareReason;
|
||||||
|
bool hardwareAccelerated = self->mDecoder->IsHardwareAccelerated(hardwareReason);
|
||||||
|
Unused << self->SendInitComplete(hardwareAccelerated, hardwareReason);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[self] (MediaResult aReason) {
|
[self] (MediaResult aReason) {
|
||||||
|
@ -135,6 +137,14 @@ VideoDecoderParent::RecvShutdown()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
VideoDecoderParent::RecvSetSeekThreshold(const int64_t& aTime)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(!mDestroyed);
|
||||||
|
mDecoder->SetSeekThreshold(media::TimeUnit::FromMicroseconds(aTime));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
VideoDecoderParent::ActorDestroy(ActorDestroyReason aWhy)
|
VideoDecoderParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,6 +35,7 @@ public:
|
||||||
bool RecvFlush() override;
|
bool RecvFlush() override;
|
||||||
bool RecvDrain() override;
|
bool RecvDrain() override;
|
||||||
bool RecvShutdown() override;
|
bool RecvShutdown() override;
|
||||||
|
bool RecvSetSeekThreshold(const int64_t& aTime) override;
|
||||||
|
|
||||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||||
|
|
||||||
|
|
|
@ -461,3 +461,35 @@ function SetupEMEPref(callback) {
|
||||||
|
|
||||||
SpecialPowers.pushPrefEnv({ "set" : prefs }, callback);
|
SpecialPowers.pushPrefEnv({ "set" : prefs }, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function fetchWithXHR(uri, onLoadFunction) {
|
||||||
|
var p = new Promise(function(resolve, reject) {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("GET", uri, true);
|
||||||
|
xhr.responseType = "arraybuffer";
|
||||||
|
xhr.addEventListener("load", function () {
|
||||||
|
is(xhr.status, 200, "fetchWithXHR load uri='" + uri + "' status=" + xhr.status);
|
||||||
|
resolve(xhr.response);
|
||||||
|
});
|
||||||
|
xhr.send();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (onLoadFunction) {
|
||||||
|
p.then(onLoadFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
return p;
|
||||||
|
};
|
||||||
|
|
||||||
|
function once(target, name, cb) {
|
||||||
|
var p = new Promise(function(resolve, reject) {
|
||||||
|
target.addEventListener(name, function onceEvent(arg) {
|
||||||
|
target.removeEventListener(name, onceEvent);
|
||||||
|
resolve(arg);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
if (cb) {
|
||||||
|
p.then(cb);
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
|
@ -540,6 +540,8 @@ support-files =
|
||||||
sine.webm^headers^
|
sine.webm^headers^
|
||||||
short.mp4
|
short.mp4
|
||||||
short.mp4^headers^
|
short.mp4^headers^
|
||||||
|
short-audio-fragmented-cenc-without-pssh.mp4
|
||||||
|
short-audio-fragmented-cenc-without-pssh.mp4^headers^
|
||||||
short-video.ogv
|
short-video.ogv
|
||||||
short-video.ogv^headers^
|
short-video.ogv^headers^
|
||||||
small-shot-mp3.mp4
|
small-shot-mp3.mp4
|
||||||
|
@ -688,6 +690,8 @@ skip-if = toolkit == 'android' # bug 1149374
|
||||||
skip-if = toolkit == 'android' # bug 1149374
|
skip-if = toolkit == 'android' # bug 1149374
|
||||||
[test_eme_initDataTypes.html]
|
[test_eme_initDataTypes.html]
|
||||||
skip-if = toolkit == 'android' # bug 1149374
|
skip-if = toolkit == 'android' # bug 1149374
|
||||||
|
[test_eme_missing_pssh.html]
|
||||||
|
skip-if = toolkit == 'android' # bug 1149374
|
||||||
[test_eme_non_mse_fails.html]
|
[test_eme_non_mse_fails.html]
|
||||||
skip-if = toolkit == 'android' # bug 1149374
|
skip-if = toolkit == 'android' # bug 1149374
|
||||||
[test_eme_request_notifications.html]
|
[test_eme_request_notifications.html]
|
||||||
|
|
Двоичный файл не отображается.
|
@ -0,0 +1 @@
|
||||||
|
Cache-Control: no-store
|
|
@ -0,0 +1,92 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Test Encrypted Media Extensions</title>
|
||||||
|
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||||
|
<script type="text/javascript" src="manifest.js"></script>
|
||||||
|
<script type="text/javascript" src="eme.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<audio controls id="audio"></audio>
|
||||||
|
<pre id="test">
|
||||||
|
<script class="testbody" type="text/javascript">
|
||||||
|
|
||||||
|
// Tests that a fragmented MP4 file without a PSSH, but with valid encrypted
|
||||||
|
// tracks with valid TENC boxes, is able to load with EME.
|
||||||
|
// We setup MSE before starting up EME, so that we exercise the "waiting for
|
||||||
|
// cdm" step in the MediaDecoderStateMachine.
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
|
var pssh = [
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x70, 0x73, 0x73, 0x68, // BMFF box header (76 bytes, 'pssh')
|
||||||
|
0x01, 0x00, 0x00, 0x00, // Full box header (version = 1, flags = 0)
|
||||||
|
0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02, // SystemID
|
||||||
|
0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b,
|
||||||
|
0x00, 0x00, 0x00, 0x01, // KID_count (1)
|
||||||
|
0x2f, 0xef, 0x8a, 0xd8, 0x12, 0xdf, 0x42, 0x97,
|
||||||
|
0x83, 0xe9, 0xbf, 0x6e, 0x5e, 0x49, 0x3e, 0x53,
|
||||||
|
0x00, 0x00, 0x00, 0x00 // Size of Data (0)
|
||||||
|
];
|
||||||
|
|
||||||
|
var audio = document.getElementById("audio");
|
||||||
|
|
||||||
|
function LoadEME() {
|
||||||
|
var options = [{
|
||||||
|
initDataType: 'cenc',
|
||||||
|
audioType: 'audio/mp4; codecs="mp4a.40.2"',
|
||||||
|
}];
|
||||||
|
navigator.requestMediaKeySystemAccess("org.w3.clearkey", options)
|
||||||
|
.then((keySystemAccess) => {
|
||||||
|
return keySystemAccess.createMediaKeys();
|
||||||
|
}, bail("Failed to request key system access."))
|
||||||
|
|
||||||
|
.then((mediaKeys) => {
|
||||||
|
audio.setMediaKeys(mediaKeys);
|
||||||
|
var session = mediaKeys.createSession();
|
||||||
|
once(session, "message", (message) => {
|
||||||
|
is(message.messageType, 'license-request', "Expected a license-request");
|
||||||
|
var license = new TextEncoder().encode(JSON.stringify({
|
||||||
|
'keys': [{
|
||||||
|
'kty':'oct',
|
||||||
|
'kid':'L--K2BLfQpeD6b9uXkk-Uw',
|
||||||
|
'k':HexToBase64('7f412f0575f44f718259beef56ec7771')
|
||||||
|
}],
|
||||||
|
'type': 'temporary'
|
||||||
|
}));
|
||||||
|
session.update(license);
|
||||||
|
});
|
||||||
|
session.generateRequest('cenc', new Uint8Array(pssh));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function DownloadMedia(url, type, mediaSource) {
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
var sourceBuffer = mediaSource.addSourceBuffer(type);
|
||||||
|
fetchWithXHR(url, (response) => {
|
||||||
|
once(sourceBuffer, "updateend", resolve);
|
||||||
|
sourceBuffer.appendBuffer(new Uint8Array(response));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function LoadMSE() {
|
||||||
|
var ms = new MediaSource();
|
||||||
|
audio.src = URL.createObjectURL(ms);
|
||||||
|
|
||||||
|
once(ms, "sourceopen", ()=>{
|
||||||
|
DownloadMedia('short-audio-fragmented-cenc-without-pssh.mp4', 'audio/mp4; codecs="mp4a.40.2"', ms)
|
||||||
|
.then(() => { ms.endOfStream(); LoadEME();});
|
||||||
|
});
|
||||||
|
|
||||||
|
audio.addEventListener("loadeddata", SimpleTest.finish);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetupEMEPref(LoadMSE);
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -31,9 +31,11 @@ function startTest(test, token) {
|
||||||
manager.started(token);
|
manager.started(token);
|
||||||
var a = new Audio(test.name);
|
var a = new Audio(test.name);
|
||||||
a.autoplay = true;
|
a.autoplay = true;
|
||||||
|
document.body.appendChild(a);
|
||||||
a.addEventListener("ended",
|
a.addEventListener("ended",
|
||||||
function(e){
|
function(e){
|
||||||
ok(true, "[" + a.src + "]We should get to the end. Oh look we did.");
|
ok(true, "[" + a.src + "]We should get to the end. Oh look we did.");
|
||||||
|
a.remove();
|
||||||
manager.finished(token);
|
manager.finished(token);
|
||||||
},
|
},
|
||||||
false);
|
false);
|
||||||
|
|
|
@ -33,9 +33,9 @@
|
||||||
#include "nsGlobalWindow.h"
|
#include "nsGlobalWindow.h"
|
||||||
#include "nsIDocument.h"
|
#include "nsIDocument.h"
|
||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
|
#include "nsIIDNService.h"
|
||||||
#include "nsIScriptGlobalObject.h"
|
#include "nsIScriptGlobalObject.h"
|
||||||
#include "nsIScriptContext.h"
|
#include "nsIScriptContext.h"
|
||||||
#include "nsIUnicodeNormalizer.h"
|
|
||||||
#include "nsDOMJSUtils.h"
|
#include "nsDOMJSUtils.h"
|
||||||
#include "nsIPrincipal.h"
|
#include "nsIPrincipal.h"
|
||||||
#include "nsWildCard.h"
|
#include "nsWildCard.h"
|
||||||
|
@ -1935,18 +1935,25 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
|
||||||
return NPERR_GENERIC_ERROR;
|
return NPERR_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIUnicodeNormalizer> normalizer = do_GetService(NS_UNICODE_NORMALIZER_CONTRACTID);
|
nsCOMPtr<nsIIDNService> idnService = do_GetService(NS_IDNSERVICE_CONTRACTID);
|
||||||
if (!normalizer) {
|
if (!idnService) {
|
||||||
return NPERR_GENERIC_ERROR;
|
return NPERR_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsAutoString normalizedUTF16Origin;
|
// This is a bit messy: we convert to UTF-8 here, but then
|
||||||
res = normalizer->NormalizeUnicodeNFKC(utf16Origin, normalizedUTF16Origin);
|
// nsIDNService::Normalize will convert back to UTF-16 for processing,
|
||||||
|
// and back to UTF-8 again to return the result.
|
||||||
|
// Alternative: perhaps we should add a NormalizeUTF16 version of the API,
|
||||||
|
// and just convert to UTF-8 for the final return (resulting in one
|
||||||
|
// encoding form conversion instead of three).
|
||||||
|
NS_ConvertUTF16toUTF8 utf8Origin(utf16Origin);
|
||||||
|
nsAutoCString normalizedUTF8Origin;
|
||||||
|
res = idnService->Normalize(utf8Origin, normalizedUTF8Origin);
|
||||||
if (NS_FAILED(res)) {
|
if (NS_FAILED(res)) {
|
||||||
return NPERR_GENERIC_ERROR;
|
return NPERR_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
*(char**)result = ToNewUTF8String(normalizedUTF16Origin);
|
*(char**)result = ToNewCString(normalizedUTF8Origin);
|
||||||
return *(char**)result ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
|
return *(char**)result ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2093,6 +2093,22 @@ nsPluginHost::AddPluginTag(nsPluginTag* aPluginTag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
PluginInfoIsFlash(const nsPluginInfo& info)
|
||||||
|
{
|
||||||
|
if (strcmp(info.fDescription, "Shockwave Flash") != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (uint32_t i = 0; i < info.fVariantCount; ++i) {
|
||||||
|
if (info.fMimeTypeArray[i] &&
|
||||||
|
(!strcmp(info.fMimeTypeArray[i], "application/x-shockwave-flash") ||
|
||||||
|
!strcmp(info.fMimeTypeArray[i], "application/x-shockwave-flash-test"))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
typedef NS_NPAPIPLUGIN_CALLBACK(char *, NP_GETMIMEDESCRIPTION)(void);
|
typedef NS_NPAPIPLUGIN_CALLBACK(char *, NP_GETMIMEDESCRIPTION)(void);
|
||||||
|
|
||||||
nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
|
nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
|
||||||
|
@ -2113,6 +2129,8 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
|
||||||
("nsPluginHost::ScanPluginsDirectory dir=%s\n", dirPath.get()));
|
("nsPluginHost::ScanPluginsDirectory dir=%s\n", dirPath.get()));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool flashOnly = Preferences::GetBool("plugin.load_flash_only", true);
|
||||||
|
|
||||||
nsCOMPtr<nsISimpleEnumerator> iter;
|
nsCOMPtr<nsISimpleEnumerator> iter;
|
||||||
rv = pluginsDir->GetDirectoryEntries(getter_AddRefs(iter));
|
rv = pluginsDir->GetDirectoryEntries(getter_AddRefs(iter));
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
|
@ -2215,7 +2233,8 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
|
||||||
res = pluginFile.GetPluginInfo(info, &library);
|
res = pluginFile.GetPluginInfo(info, &library);
|
||||||
}
|
}
|
||||||
// if we don't have mime type don't proceed, this is not a plugin
|
// if we don't have mime type don't proceed, this is not a plugin
|
||||||
if (NS_FAILED(res) || !info.fMimeTypeArray) {
|
if (NS_FAILED(res) || !info.fMimeTypeArray ||
|
||||||
|
(flashOnly && !PluginInfoIsFlash(info))) {
|
||||||
RefPtr<nsInvalidPluginTag> invalidTag = new nsInvalidPluginTag(filePath.get(),
|
RefPtr<nsInvalidPluginTag> invalidTag = new nsInvalidPluginTag(filePath.get(),
|
||||||
fileModTime);
|
fileModTime);
|
||||||
pluginFile.FreePluginInfo(info);
|
pluginFile.FreePluginInfo(info);
|
||||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче