merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2015-09-29 12:00:25 +02:00
commit 5249c06cb0
465 changed files with 7923 additions and 3764 deletions

View File

@ -22,7 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1108782 - Follow-up: clobber. r=me
There's all kinds fail waiting at the end of these dependency changes.
Definitely clobber needed!
Bug 1205242 - Changed toolchain, needs clobber

View File

@ -2071,6 +2071,10 @@ DocAccessible::ValidateARIAOwned()
nsIContent* childEl = childEls->ElementAt(idx);
Accessible* child = GetAccessible(childEl);
if (child && child->IsInDocument() && !child->GetFrame()) {
if (!child->Parent()) {
NS_ERROR("An element in the document doesn't have a parent?");
continue;
}
UpdateTreeOnRemoval(child->Parent(), childEl);
}
}

View File

@ -225,7 +225,7 @@ child:
prio(high) sync MaxValue(uint64_t aID) returns(double aValue);
prio(high) sync Step(uint64_t aID) returns(double aStep);
prio(high) sync TakeFocus(uint64_t aID);
async TakeFocus(uint64_t aID);
prio(high) sync EmbeddedChildCount(uint64_t aID) returns(uint32_t aCount);
prio(high) sync IndexOfEmbeddedChild(uint64_t aID, uint64_t aChildID)
returns(uint32_t childIdx);

View File

@ -1872,6 +1872,9 @@ pref("privacy.trackingprotection.ui.enabled", false);
pref("privacy.trackingprotection.introCount", 0);
pref("privacy.trackingprotection.introURL", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%/tracking-protection/start/");
// Enable Contextual Identity Containers
pref("privacy.userContext.enabled", false);
#ifndef RELEASE_BUILD
// At the moment, autostart.2 is used, while autostart.1 is unused.
// We leave it here set to false to reset users' defaults and allow

View File

@ -11,12 +11,44 @@
style="border:0px;padding:0px;margin:0px;-moz-appearance:none">
<menu id="file-menu" label="&fileMenu.label;"
accesskey="&fileMenu.accesskey;">
<menupopup id="menu_FilePopup">
<menupopup id="menu_FilePopup"
onpopupshowing="updateUserContextUIVisibility();">
<menuitem id="menu_newNavigatorTab"
label="&tabCmd.label;"
command="cmd_newNavigatorTab"
key="key_newNavigatorTab"
accesskey="&tabCmd.accesskey;"/>
<menu id="menu_newUserContext"
label="&newUserContext.label;"
accesskey="&newUserContext.accesskey;"
hidden="true">
<menupopup>
<menuitem id="menu_newUserContextTabPersonal"
usercontextid="1"
class="menuitem-iconic"
label="&userContextPersonal.label;"
command="Browser:NewUserContextTab"
accesskey="&userContextPersonal.accesskey;"/>
<menuitem id="menu_newUserContextTabWork"
usercontextid="2"
class="menuitem-iconic"
label="&userContextWork.label;"
command="Browser:NewUserContextTab"
accesskey="&userContextWork.accesskey;"/>
<menuitem id="menu_newUserContextTabBanking"
usercontextid="3"
class="menuitem-iconic"
label="&userContextBanking.label;"
command="Browser:NewUserContextTab"
accesskey="&userContextBanking.accesskey;"/>
<menuitem id="menu_newUserContextTabShopping"
usercontextid="4"
class="menuitem-iconic"
label="&userContextShopping.label;"
command="Browser:NewUserContextTab"
accesskey="&userContextShopping.accesskey;"/>
</menupopup>
</menu>
<menuitem id="menu_newNavigator"
label="&newNavigatorCmd.label;"
accesskey="&newNavigatorCmd.accesskey;"

View File

@ -92,6 +92,7 @@
<command id="cmd_gestureRotateEnd" oncommand="gGestureSupport.rotateEnd()"/>
<command id="Browser:OpenLocation" oncommand="openLocation();"/>
<command id="Browser:RestoreLastSession" oncommand="restoreLastSession();" disabled="true"/>
<command id="Browser:NewUserContextTab" oncommand="openNewUserContextTab(event.sourceEvent);" reserved="true"/>
<command id="Tools:Search" oncommand="BrowserSearch.webSearch();"/>
<command id="Tools:Downloads" oncommand="BrowserDownloadsUI();"/>

View File

@ -4060,6 +4060,31 @@ function updateEditUIVisibility()
#endif
}
/**
* Opens a new tab with the userContextId specified as an attribute of
* sourceEvent. This attribute is propagated to the top level originAttributes
* living on the tab's docShell.
*
* @param event
* A click event on a userContext File Menu option
*/
function openNewUserContextTab(event)
{
openUILinkIn(BROWSER_NEW_TAB_URL, "tab", {
userContextId: event.target.getAttribute('usercontextid'),
});
}
/**
* Updates File Menu User Context UI visibility depending on
* privacy.userContext.enabled pref state.
*/
function updateUserContextUIVisibility()
{
let userContextEnabled = Services.prefs.getBoolPref("privacy.userContext.enabled");
document.getElementById("menu_newUserContext").hidden = !userContextEnabled;
}
/**
* Makes the Character Encoding menu enabled or disabled as appropriate.
* To be called when the View menu or the app menu is opened.

View File

@ -1415,6 +1415,7 @@
var aSkipAnimation;
var aForceNotRemote;
var aNoReferrer;
var aUserContextId;
if (arguments.length == 2 &&
typeof arguments[1] == "object" &&
!(arguments[1] instanceof Ci.nsIURI)) {
@ -1431,6 +1432,7 @@
aSkipAnimation = params.skipAnimation;
aForceNotRemote = params.forceNotRemote;
aNoReferrer = params.noReferrer;
aUserContextId = params.userContextId;
}
var bgLoad = (aLoadInBackground != null) ? aLoadInBackground :
@ -1448,7 +1450,8 @@
skipAnimation: aSkipAnimation,
allowMixedContent: aAllowMixedContent,
forceNotRemote: aForceNotRemote,
noReferrer: aNoReferrer });
noReferrer: aNoReferrer,
userContextId: aUserContextId });
if (!bgLoad)
this.selectedTab = tab;
@ -1690,6 +1693,7 @@
let remote = aParams && aParams.remote;
let uriIsAboutBlank = aParams && aParams.uriIsAboutBlank;
let isPreloadBrowser = aParams && aParams.isPreloadBrowser;
let userContextId = aParams && aParams.userContextId;
let b = document.createElementNS(NS_XUL, "browser");
b.permanentKey = {};
@ -1699,6 +1703,9 @@
b.setAttribute("contextmenu", this.getAttribute("contentcontextmenu"));
b.setAttribute("tooltip", this.getAttribute("contenttooltip"));
if (userContextId)
b.setAttribute("usercontextid", userContextId);
if (remote)
b.setAttribute("remote", "true");
@ -1767,6 +1774,7 @@
var aAllowMixedContent;
var aForceNotRemote;
var aNoReferrer;
var aUserContextId;
if (arguments.length == 2 &&
typeof arguments[1] == "object" &&
!(arguments[1] instanceof Ci.nsIURI)) {
@ -1783,6 +1791,7 @@
aAllowMixedContent = params.allowMixedContent;
aForceNotRemote = params.forceNotRemote;
aNoReferrer = params.noReferrer;
aUserContextId = params.userContextId;
}
// if we're adding tabs, we're past interrupt mode, ditch the owner
@ -1831,16 +1840,18 @@
let b;
let usingPreloadedContent = false;
// If we open a new tab with the newtab URL,
// check if there is a preloaded browser ready.
if (aURI == BROWSER_NEW_TAB_URL) {
// If we open a new tab with the newtab URL in the default
// userContext, check if there is a preloaded browser ready.
if (aURI == BROWSER_NEW_TAB_URL && !aUserContextId) {
b = this._getPreloadedBrowser();
usingPreloadedContent = !!b;
}
if (!b) {
// No preloaded browser found, create one.
b = this._createBrowser({remote, uriIsAboutBlank});
b = this._createBrowser({remote: remote,
uriIsAboutBlank: uriIsAboutBlank,
userContextId: aUserContextId});
}
let notificationbox = this.getNotificationBox(b);
@ -2486,6 +2497,11 @@
if (ourBrowser.isRemoteBrowser != otherBrowser.isRemoteBrowser)
return;
// Keep the userContextId if set on other browser
if (otherBrowser.hasAttribute("usercontextid")) {
ourBrowser.setAttribute("usercontextid", otherBrowser.getAttribute("usercontextid"));
}
// That's gBrowser for the other window, not the tab's browser!
var remoteBrowser = aOtherTab.ownerDocument.defaultView.gBrowser;
var isPending = aOtherTab.hasAttribute("pending");

View File

@ -18,6 +18,7 @@ function onTabModalDialogLoaded(node) {
}
}
SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunload", false]]});
// Listen for the dialog being created
Services.obs.addObserver(onTabModalDialogLoaded, "tabmodal-dialog-loaded", false);

View File

@ -2,6 +2,8 @@
const TEST_PAGE = "http://mochi.test:8888/browser/browser/base/content/test/general/file_double_close_tab.html";
var testTab;
SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunload", false]]});
function waitForDialog(callback) {
function onTabModalDialogLoaded(node) {
Services.obs.removeObserver(onTabModalDialogLoaded, "tabmodal-dialog-loaded");

View File

@ -1,5 +1,7 @@
"use strict";
SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunload", false]]});
const FIRST_TAB = getRootDirectory(gTestPath) + "close_beforeunload_opens_second_tab.html";
const SECOND_TAB = getRootDirectory(gTestPath) + "close_beforeunload.html";

View File

@ -173,6 +173,7 @@ function whereToOpenLink( e, ignoreButton, ignoreAlt )
* skipTabAnimation (boolean)
* allowPinnedTabHostChange (boolean)
* allowPopups (boolean)
* userContextId (unsigned int)
*/
function openUILinkIn(url, where, aAllowThirdPartyFixup, aPostData, aReferrerURI) {
var params;
@ -216,6 +217,7 @@ function openLinkIn(url, where, params) {
var aAllowPinnedTabHostChange = !!params.allowPinnedTabHostChange;
var aNoReferrer = params.noReferrer;
var aAllowPopups = !!params.allowPopups;
var aUserContextId = params.userContextId;
if (where == "save") {
if (!aInitiatingDoc) {
@ -357,7 +359,8 @@ function openLinkIn(url, where, params) {
relatedToCurrent: aRelatedToCurrent,
skipAnimation: aSkipTabAnimation,
allowMixedContent: aAllowMixedContent,
noReferrer: aNoReferrer
noReferrer: aNoReferrer,
userContextId: aUserContextId
});
break;
}

View File

@ -6,6 +6,8 @@
const TEST_URL = 'data:text/html,<script>window.onbeforeunload=' +
'function(e){e.returnValue="?"}</script>';
SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunload", false]]});
function test() {
waitForExplicitFinish();
showTabView(onTabViewShown);

View File

@ -15,6 +15,8 @@ const TEST_URL = 'data:text/html,<script>window.onbeforeunload=' +
var contentWindow;
var activeGroup;
SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunload", false]]});
Components.utils.import("resource://gre/modules/Promise.jsm", this);
function test() {

View File

@ -1,10 +1,10 @@
[
{
"clang_version": "r241406"
"clang_version": "r247539"
},
{
"size": 100307285,
"digest": "4d147d0072a928945fc1e938f39a5d0a9d3c676399c09e092c8750b2f973cdbbebda8d94d4d05805fae74a5c49c54263dc22b8b443c23c9a0ae830a261d3cf30",
"size": 93197192,
"digest": "6ebd8994ac76cf6694c3d9054104219836f47578223c799cb9ba9669cfdee00112e9de56aea9d1e6d9d50ee94a201970555de19794b5fbb7546f58fdf8e59a99",
"algorithm": "sha512",
"filename": "clang.tar.bz2",
"unpack": true,

View File

@ -1,10 +1,10 @@
[
{
"clang_version": "r241406"
"clang_version": "r247539"
},
{
"size": 83297360,
"digest": "18e3deaf608b58a9153d647e1acbe6e93b7d6461bd4f86f24d13f4b6818b048a65063200d7acb100fa41eb5a7e66dfe6bdc89770c15c87e32a3e9a50d97094c6",
"size": 93197192,
"digest": "6ebd8994ac76cf6694c3d9054104219836f47578223c799cb9ba9669cfdee00112e9de56aea9d1e6d9d50ee94a201970555de19794b5fbb7546f58fdf8e59a99",
"algorithm": "sha512",
"filename": "clang.tar.xz",
"unpack": true

View File

@ -1,10 +1,10 @@
[
{
"clang_version": "r241406"
"clang_version": "r247539"
},
{
"size": 83297360,
"digest": "18e3deaf608b58a9153d647e1acbe6e93b7d6461bd4f86f24d13f4b6818b048a65063200d7acb100fa41eb5a7e66dfe6bdc89770c15c87e32a3e9a50d97094c6",
"size": 93197192,
"digest": "6ebd8994ac76cf6694c3d9054104219836f47578223c799cb9ba9669cfdee00112e9de56aea9d1e6d9d50ee94a201970555de19794b5fbb7546f58fdf8e59a99",
"algorithm": "sha512",
"filename": "clang.tar.xz",
"unpack": true

View File

@ -1,12 +1,12 @@
[
{
"clang_version": "r241406"
"clang_version": "r247539"
},
{
"size": 86465808,
"digest": "947eaaf11ac8cbe12e11b48c8b052721e018d31fb8ce20f8bf14b117b6623c56513b1422d8d9c8011bc0b0b985ef74d8f181e7200c6d7a05d79a1bce0d75ddee",
"size": 97314461,
"digest": "9a74670fa917f760a4767923485d5166bbd258a8023c8aeb899b8c4d22f2847be76508ac5f26d7d2193318a2bb368a71bc62888d1bfe9d81eb45329a60451aa4",
"algorithm": "sha512",
"filename": "clang.tar.bz2",
"filename": "clang.tar.xz",
"unpack": true
},
{

View File

@ -1,19 +1,12 @@
[
{
"clang_version": "r241406"
"clang_version": "r247539"
},
{
"size": 100307285,
"digest": "4d147d0072a928945fc1e938f39a5d0a9d3c676399c09e092c8750b2f973cdbbebda8d94d4d05805fae74a5c49c54263dc22b8b443c23c9a0ae830a261d3cf30",
"size": 93197192,
"digest": "6ebd8994ac76cf6694c3d9054104219836f47578223c799cb9ba9669cfdee00112e9de56aea9d1e6d9d50ee94a201970555de19794b5fbb7546f58fdf8e59a99",
"algorithm": "sha512",
"filename": "clang.tar.bz2",
"unpack": true
},
{
"size": 80458572,
"digest": "e5101f9dee1e462f6cbd3897ea57eede41d23981825c7b20d91d23ab461875d54d3dfc24999aa58a31e8b01f49fb3140e05ffe5af2957ef1d1afb89fd0dfe1ad",
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"filename": "clang.tar.xz",
"unpack": true
},
{

View File

@ -308,6 +308,16 @@ These should match what Safari and other Apple applications use on OS X Lion. --
<!ENTITY fileMenu.label "File">
<!ENTITY fileMenu.accesskey "F">
<!ENTITY newUserContext.label "New Container Tab">
<!ENTITY newUserContext.accesskey "C">
<!ENTITY userContextPersonal.label "Personal">
<!ENTITY userContextPersonal.accesskey "P">
<!ENTITY userContextWork.label "Work">
<!ENTITY userContextWork.accesskey "W">
<!ENTITY userContextBanking.label "Banking">
<!ENTITY userContextBanking.accesskey "B">
<!ENTITY userContextShopping.label "Shopping">
<!ENTITY userContextShopping.accesskey "S">
<!ENTITY newNavigatorCmd.label "New Window">
<!ENTITY newNavigatorCmd.key "N">
<!ENTITY newNavigatorCmd.accesskey "N">

View File

@ -152,8 +152,15 @@
locale/browser/syncQuota.properties (%chrome/browser/syncQuota.properties)
#endif
% resource search-plugins chrome://browser/locale/searchplugins/
# little trick to make the test below work
#define en_US en-US
#if AB_CD == en_US
locale/browser/searchplugins/list.txt (%searchplugins/list.txt)
locale/browser/searchplugins/ (%searchplugins/*.xml)
#else
locale/browser/searchplugins/list.txt (.deps/generated_@AB_CD@/list.txt)
locale/browser/searchplugins/ (.deps/generated_@AB_CD@/*.xml)
#endif
% locale browser-region @AB_CD@ %locale/browser-region/
locale/browser-region/region.properties (%chrome/browser-region/region.properties)
# the following files are browser-specific overrides

View File

@ -166,7 +166,7 @@ PluginContent.prototype = {
pluginName = BrowserUtils.makeNicePluginName(pluginTag.name);
// Convert this from nsIPluginTag so it can be serialized.
let properties = ["name", "description", "filename", "version", "enabledState"];
let properties = ["name", "description", "filename", "version", "enabledState", "niceName"];
let pluginTagCopy = {};
for (let prop of properties) {
pluginTagCopy[prop] = pluginTag[prop];
@ -422,6 +422,7 @@ PluginContent.prototype = {
break;
case "PluginInstantiated":
Services.telemetry.getKeyedHistogramById('PLUGIN_ACTIVATION_COUNT').add(this._getPluginInfo(plugin).pluginTag.niceName);
shouldShowNotification = true;
break;
}

View File

@ -1969,3 +1969,5 @@ chatbox {
.browser-action-panel > .panel-arrowcontainer > .panel-arrowcontent {
padding: 0;
}
%include ../shared/usercontext/usercontext.inc.css

View File

@ -142,6 +142,10 @@ browser.jar:
skin/classic/browser/tabview/stack-expander.png (tabview/stack-expander.png)
skin/classic/browser/tabview/tabview.png (tabview/tabview.png)
skin/classic/browser/tabview/tabview.css (tabview/tabview.css)
skin/classic/browser/usercontext/personal.svg (../shared/usercontext/personal.svg)
skin/classic/browser/usercontext/work.svg (../shared/usercontext/work.svg)
skin/classic/browser/usercontext/banking.svg (../shared/usercontext/banking.svg)
skin/classic/browser/usercontext/shopping.svg (../shared/usercontext/shopping.svg)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/sync-16.png
skin/classic/browser/sync-32.png

View File

@ -3655,3 +3655,5 @@ window > chatbox {
.browser-action-panel > .panel-arrowcontainer > .panel-arrowcontent {
padding: 0;
}
%include ../shared/usercontext/usercontext.inc.css

View File

@ -229,6 +229,10 @@ browser.jar:
skin/classic/browser/tabview/stack-expander.png (tabview/stack-expander.png)
skin/classic/browser/tabview/tabview.png (tabview/tabview.png)
skin/classic/browser/tabview/tabview.css (tabview/tabview.css)
skin/classic/browser/usercontext/personal.svg (../shared/usercontext/personal.svg)
skin/classic/browser/usercontext/work.svg (../shared/usercontext/work.svg)
skin/classic/browser/usercontext/banking.svg (../shared/usercontext/banking.svg)
skin/classic/browser/usercontext/shopping.svg (../shared/usercontext/shopping.svg)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/sync-16.png
skin/classic/browser/sync-32.png

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg"
width="32" height="32" viewBox="0 0 32 32">
<path fill="#7dc14c" d="M17.3857868,14.0527919 C14.2304569,13.0862944 13.4913706,12.4609137 13.4913706,11.0964467 C13.4913706,9.61827411 14.7137056,8.85076142 16.4192893,8.85076142 C17.9827411,8.85076142 19.3187817,9.33401015 20.5979695,10.4994924 L22.4456853,8.42436548 C21.1664975,7.20203046 19.3187819,6.26535905 17,6.00952148 L17,2 L15,2 L15,6.00952148 C12.3827412,6.43591742 9.76751269,8.53807107 9.76751269,11.3238579 C9.76751269,14.1664975 11.4730964,15.786802 15.4812183,17.0091371 C18.4375635,17.9187817 19.2335025,18.6294416 19.2335025,20.2213198 C19.2335025,22.0690355 17.7553299,23.035533 15.7370558,23.035533 C13.7756345,23.035533 12.2406091,22.3248731 10.9329949,21.1025381 L9,23.2345178 C10.4213198,24.6274112 12.8659899,25.8324934 15,26.0030518 L15,30 L17,30 L17,26.0030518 C20.7116753,25.4060974 22.9857868,22.893401 22.9857868,20.022335 C22.9857868,16.4690355 20.7116751,15.1045685 17.3857868,14.0527919 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg"
width="32" height="32" viewBox="0 0 32 32">
<path fill="#00a7e0" d="M7.17741905,12 C7.10965537,12 7.041327,11.9953181 6.97243393,11.985018 C6.33263187,11.8918489 5.90515601,11.3862071 6.01809547,10.8552833 C7.41798011,4.26321358 12.2613889,2.57493207 15.0238882,2.15590491 C19.6448063,1.45690206 24.3408291,3.21541158 25.8344535,5.29743816 C26.1664955,5.76047488 25.9835336,6.35881757 25.4244832,6.63364321 C24.8654329,6.9098734 24.1437497,6.75583996 23.8122724,6.29327142 C22.8923805,5.01043967 19.1749781,3.51130562 15.4479759,4.07406612 C12.8080159,4.474834 9.43056132,6.03623689 8.33561323,11.1942506 C8.23453242,11.666651 7.73816348,12 7.17741905,12 Z M16.63127,26 C16.1452186,26 15.6509104,25.9658335 15.147795,25.8938767 C10.637921,25.257137 6.71207921,21.8114952 6.01575422,17.8807924 C5.91171832,17.2932317 6.33391695,16.7382846 6.95813239,16.6404441 C7.58454965,16.5343208 8.17298555,16.9406954 8.27757192,17.5272206 C8.80876054,20.5255916 11.9766264,23.26409 15.4885263,23.7610576 C17.3975027,24.02766 20.959494,23.8221432 23.3220449,19.3789425 C24.4625867,17.2331815 23.0049831,11.881462 19.9521622,9.34692739 C18.2380468,7.92384005 16.4573263,7.76905536 14.6628445,8.89499751 C13.26469,9.77142052 11.8070864,12.2857658 11.8665355,14.6287608 C11.9127737,16.4835887 12.8386382,17.9325598 14.6171568,18.9363308 C15.2210054,19.2764429 16.9411759,19.4933486 17.9424527,18.8296898 C18.7257495,18.3104622 18.9591422,17.2761485 18.6365758,15.7583267 C18.3822659,14.5650869 17.2219077,12.4452096 16.6664991,12.3711821 C16.6692513,12.3722175 16.4666841,12.4312324 16.1276041,12.9095636 C15.8545786,13.2936782 15.58981,14.7297074 15.9476054,15.3581643 C16.0142104,15.4761941 16.0725586,15.5465978 16.3202632,15.5465978 C16.9532859,15.5465978 17.46686,16.0290705 17.46686,16.6249139 C17.46686,17.2207573 16.9543868,17.7042653 16.3213641,17.7042653 C15.2644914,17.7042653 14.4140391,17.2336992 13.9268868,16.3774655 C13.1083609,14.9388479 13.5536787,12.6548678 14.2202791,11.7137354 C15.2540327,10.2564816 16.3631986,10.1151564 17.1123672,10.2564816 C19.7066595,10.7389543 20.8763754,15.2908666 20.8857331,15.3359043 C21.5303153,18.3648181 20.3594985,19.8665919 19.264094,20.593407 C17.4151172,21.8192603 14.6920186,21.493643 13.4380832,20.7859819 C10.3280151,19.0310652 9.62013053,16.497566 9.5744428,14.6805283 C9.49022326,11.3643051 11.4779146,8.30018945 13.391845,7.10021984 C16.0417332,5.43848454 18.9877658,5.66781436 21.4714167,7.72919442 C25.1176276,10.7565552 27.0871539,17.1229168 25.3746898,20.3433702 C23.4326862,23.9950465 20.2983981,26 16.63127,26 Z M16.0845157,30 C14.9348455,30 13.9050564,29.8557557 13.0394288,29.6610017 C10.2114238,29.0257442 7.58700058,27.4599412 6.18892823,25.5735955 C5.84440518,25.1078371 5.98426642,24.4803503 6.50105099,24.1700066 C7.01675554,23.8596629 7.71552172,23.986423 8.06112477,24.4507244 C9.89498097,26.9252176 15.9397944,29.9781448 22.2508301,26.1937972 C22.7676147,25.8844249 23.4658409,26.0087566 23.8109039,26.474515 C24.155427,26.9397877 24.0161057,27.5672745 23.4993212,27.8776182 C20.7987573,29.4963593 18.2315746,30 16.0845157,30 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg"
width="32" height="32" viewBox="0 0 32 32">
<path fill="#ee5195" fill-rule="evenodd" d="M20.8195396,14 L15.1804604,14 L15.1804604,14 L15.8471271,18 L20.1528729,18 L20.8195396,14 Z M22.8471271,14 L27.6125741,14 L27.6125741,14 L26.2792408,18 L22.1804604,18 L22.8471271,14 Z M21.1528729,12 L14.8471271,12 L14.8471271,12 L14.1804604,8 L21.8195396,8 L21.1528729,12 Z M23.1804604,12 L28.2792408,12 L28.2792408,12 L29.6125741,8 L23.8471271,8 L23.1804604,12 Z M13.1528729,14 L8.47703296,14 L10.077033,18 L10.077033,18 L13.8195396,18 L13.1528729,14 Z M12.8195396,12 L7.67703296,12 L6.07703296,8 L12.1528729,8 L12.8195396,12 L12.8195396,12 Z M31.7207592,8 L32,8 L32,6 L31,6 L5.27703296,6 L5.27703296,6 L4,2.8074176 L4,2 L3,2 L1,2 L0,2 L0,4 L1,4 L2.32296704,4 L9.78931928,22.6658806 L9.78931928,22.6658806 C8.71085924,23.3823847 8,24.6081773 8,26 C8,28.209139 9.790861,30 12,30 C14.209139,30 16,28.209139 16,26 C16,25.2714257 15.8052114,24.5883467 15.4648712,24 L22.5351288,24 C22.1947886,24.5883467 22,25.2714257 22,26 C22,28.209139 23.790861,30 26,30 C28.209139,30 30,28.209139 30,26 C30,23.790861 28.209139,22 26,22 L11.677033,22 L10.877033,20 L27,20 L28,20 L28,19.1622777 L31.7207592,8 L31.7207592,8 Z M26,28 C27.1045695,28 28,27.1045695 28,26 C28,24.8954305 27.1045695,24 26,24 C24.8954305,24 24,24.8954305 24,26 C24,27.1045695 24.8954305,28 26,28 Z M12,28 C13.1045695,28 14,27.1045695 14,26 C14,24.8954305 13.1045695,24 12,24 C10.8954305,24 10,24.8954305 10,26 C10,27.1045695 10.8954305,28 12,28 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,17 @@
/* User Context UI browser styles */
#menu_newUserContextTabPersonal {
list-style-image: url("chrome://browser/skin/usercontext/personal.svg");
}
#menu_newUserContextTabWork {
list-style-image: url("chrome://browser/skin/usercontext/work.svg");
}
#menu_newUserContextTabBanking {
list-style-image: url("chrome://browser/skin/usercontext/banking.svg");
}
#menu_newUserContextTabShopping {
list-style-image: url("chrome://browser/skin/usercontext/shopping.svg");
}

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg"
width="32" height="32" viewBox="0 0 32 32">
<path fill="#f89c24" fill-rule="evenodd" d="M22,9.99887085 L21.635468,10 L29.0034652,10 C29.5538362,10 30,10.4449463 30,10.9933977 L30,27.0066023 C30,27.5552407 29.5601869,28 29.0034652,28 L2.99653482,28 C2.44616384,28 2,27.5550537 2,27.0066023 L2,10.9933977 C2,10.4447593 2.43981314,10 2.99653482,10 L8,10 L8,7.99922997 C8,5.79051625 10.0426627,4 12.5635454,4 L19.4364546,4 C21.9568311,4 24,5.79246765 24,7.99922997 L24,9.99267578 L22,9.99887085 L22,10 L10,10 L10,7.99922997 C10,6.89421235 11.0713286,6 12.3917227,6 L19.6082773,6 C20.9273761,6 22,6.89552665 22,7.99922997 L22,9.99887085 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 941 B

View File

@ -2842,3 +2842,5 @@ chatbox {
.browser-action-panel > .panel-arrowcontainer > .panel-arrowcontent {
padding: 0;
}
%include ../shared/usercontext/usercontext.inc.css

View File

@ -254,6 +254,10 @@ browser.jar:
skin/classic/browser/tabview/tabview.png (tabview/tabview.png)
skin/classic/browser/tabview/tabview-inverted.png (tabview/tabview-inverted.png)
skin/classic/browser/tabview/tabview.css (tabview/tabview.css)
skin/classic/browser/usercontext/personal.svg (../shared/usercontext/personal.svg)
skin/classic/browser/usercontext/work.svg (../shared/usercontext/work.svg)
skin/classic/browser/usercontext/banking.svg (../shared/usercontext/banking.svg)
skin/classic/browser/usercontext/shopping.svg (../shared/usercontext/shopping.svg)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/sync-16.png
skin/classic/browser/sync-32.png

View File

@ -39,7 +39,7 @@ if test -n "$ENABLE_CLANG_PLUGIN"; then
LLVM_LDFLAGS=`$LLVMCONFIG --system-libs | xargs`
LLVM_LDFLAGS="$LLVM_LDFLAGS `$LLVMCONFIG --ldflags --libs core mc analysis asmparser mcparser bitreader option | xargs`"
if test "${OS_ARCH}" = "Darwin"; then
if test "${HOST_OS_ARCH}" = "Darwin"; then
CLANG_LDFLAGS="-lclangFrontend -lclangDriver -lclangSerialization"
CLANG_LDFLAGS="$CLANG_LDFLAGS -lclangParse -lclangSema -lclangAnalysis"
CLANG_LDFLAGS="$CLANG_LDFLAGS -lclangEdit -lclangAST -lclangLex"

View File

@ -222,3 +222,15 @@ MOZ_RUN_CONFIG_STATUS()],
define([AC_CONFIG_HEADER],
[m4_fatal([Use CONFIGURE_DEFINE_FILES in moz.build files to produce header files.])
])
define([MOZ_BUILD_BACKEND],
[
BUILD_BACKENDS="RecursiveMake"
MOZ_ARG_ENABLE_STRING(build-backend,
[ --enable-build-backend={AndroidEclipse,CppEclipse,VisualStudio,FasterMake,CompileDB}
Enable additional build backends],
[ BUILD_BACKENDS="RecursiveMake `echo $enableval | sed 's/,/ /g'`"])
AC_SUBST_LIST([BUILD_BACKENDS])
])

View File

@ -14,6 +14,17 @@ OS_COMPILE_CXXFLAGS :=
OS_LDFLAGS := $(LLVM_LDFLAGS) $(CLANG_LDFLAGS)
DSO_LDOPTS := -shared
ifeq ($(HOST_OS_ARCH)_$(OS_ARCH),Linux_Darwin)
# Use the host compiler instead of the target compiler.
CXX := $(HOST_CXX)
# expandlibs doesn't know the distinction between host and target toolchains,
# and on cross linux/darwin builds, the options to give to the linker for file
# lists differ between both, so don't use file lists.
EXPAND_MKSHLIB_ARGS :=
# Don't pass OSX linker arguments.
MOZ_FIX_LINK_PATHS :=
endif
# Use the default OS X deployment target to enable using the libc++ headers
# correctly. Note that the binary produced here is a host tool and doesn't need
# to be distributed.

View File

@ -13,6 +13,11 @@ SOURCES += [
DISABLE_STL_WRAPPING = True
NO_VISIBILITY_FLAGS = True
# libc++ is required to build plugins against clang on OS X.
if CONFIG['HOST_OS_ARCH'] == 'Darwin':
CXXFLAGS += ['-stdlib=libc++']
LDFLAGS += ['-lc++']
DIRS += [
'tests',
]

View File

@ -131,6 +131,7 @@ MACH_MODULES = [
'python/mozbuild/mozbuild/mach_commands.py',
'python/mozbuild/mozbuild/backend/mach_commands.py',
'python/mozbuild/mozbuild/compilation/codecomplete.py',
'python/mozbuild/mozbuild/compilation/database.py',
'python/mozbuild/mozbuild/frontend/mach_commands.py',
'services/common/tests/mach_commands.py',
'testing/luciddream/mach_commands.py',

View File

@ -38,10 +38,9 @@ export OTOOL=${TOOLCHAIN_PREFIX}otool
export GENISOIMAGE=$topsrcdir/genisoimage/genisoimage
export DMG_TOOL=$topsrcdir/dmg/dmg
# The system gcc installed on CentOS 6 is 4.4, which our
# build system rejects.
export HOST_CC="$topsrcdir/gcc/bin/gcc"
export HOST_CXX="$topsrcdir/gcc/bin/g++"
export HOST_CC="$topsrcdir/clang/bin/clang"
export HOST_CXX="$topsrcdir/clang/bin/clang++"
export HOST_CPP="$topsrcdir/clang/bin/clang -E"
export HOST_LDFLAGS="-g"
ac_add_options --target=x86_64-apple-darwin

View File

@ -1,5 +1,5 @@
{
"llvm_revision": "241406",
"llvm_revision": "247539",
"llvm_repo": "https://llvm.org/svn/llvm-project/llvm/trunk",
"clang_repo": "https://llvm.org/svn/llvm-project/cfe/trunk",
"compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/trunk",

View File

@ -45,7 +45,9 @@ ifndef JS_STANDALONE
ifndef MOZ_PROFILE_USE
# Generate a new buildid every time we "export" in config... that's only
# supposed to be once per-build!
export::
export:: buildid
buildid: FORCE
ifdef MOZ_BUILD_DATE
printf '%s' $(MOZ_BUILD_DATE) > buildid
else

209
config/faster/rules.mk Normal file
View File

@ -0,0 +1,209 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# /!\ Please make sure to update the following comment when you touch this
# file. Thank you /!\
# The traditional Mozilla build system relied on going through the entire
# build tree a number of times with different targets, and many of the
# things happening at each step required other things happening in previous
# steps without any documentation of those dependencies.
#
# This new build system tries to start afresh by establishing what files or
# operations are needed for the build, and applying the necessary rules to
# have those in place, relying on make dependencies to get them going.
#
# As of writing, only building non-compiled parts of Firefox is supported
# here (a few other things are also left out). This is a starting point, with
# the intent to grow this build system to make it more complete.
#
# This file contains rules and dependencies to get things working. The intent
# is for a Makefile to define some dependencies and variables, and include
# this file. What needs to be defined there, and ends up being generated by
# python/mozbuild/mozbuild/backend/fastermake.py is the following:
# - TOPSRCDIR/TOPOBJDIR, respectively the top source directory and the top
# object directory
# - PYTHON, the path to the python executable
# - ACDEFINES, which contains a set of -Dvar=name to be used during
# preprocessing
# - MOZ_CHROME_FILE_FORMAT, which defines whether to use file copies or
# symbolic links
# - JAR_MN_TARGETS, which defines the targets to use for jar manifest
# processing, see further below
# - PP_TARGETS, which defines the file paths of preprocessed files, see
# further below
# - INSTALL_MANIFESTS, which defines the list of base directories handled
# by install manifests, see further below
# - MANIFEST_TARGETS, which defines the file paths of chrome manifests, see
# further below
#
# A convention used between this file and the Makefile including it is that
# global Make variables names are uppercase, while "local" Make variables
# applied to specific targets are lowercase.
# Targets to be triggered for a default build
default: $(addprefix install-,$(INSTALL_MANIFESTS))
default: $(addprefix jar-,$(JAR_MN_TARGETS))
# Explicit files to be built for a default build
default: $(addprefix $(TOPOBJDIR)/,$(PP_TARGETS))
default: $(addprefix $(TOPOBJDIR)/,$(MANIFEST_TARGETS))
default: $(TOPOBJDIR)/dist/bin/greprefs.js
default: $(TOPOBJDIR)/dist/bin/platform.ini
default: $(TOPOBJDIR)/dist/bin/webapprt/webapprt.ini
.PHONY: FORCE
# Extra define to trigger some workarounds. We should strive to limit the
# use of those. As of writing the only one is in
# toolkit/content/buildconfig.html.
ACDEFINES += -DBUILD_FASTER
# Generic rule to fall back to the recursive make backend
$(TOPOBJDIR)/%: FORCE
$(MAKE) -C $(dir $@) $(notdir $@)
# Files under the faster/ sub-directory, however, are not meant to use the
# fallback
$(TOPOBJDIR)/faster/%: ;
# And files under dist/ are meant to be copied from their first dependency
# if there is no other rule.
$(TOPOBJDIR)/dist/%:
rm -f $@
cp $< $@
# Install files using install manifests
#
# The list of base directories is given in INSTALL_MANIFESTS. The
# corresponding install manifests are named correspondingly, with forward
# slashes replaced with underscores, and prefixed with `install_`. That is,
# the install manifest for `dist/bin` would be `install_dist_bin`.
$(addprefix install-,$(INSTALL_MANIFESTS)): install-%:
$(PYTHON) -m mozbuild.action.process_install_manifest \
--no-remove \
--no-remove-empty-directories \
$(TOPOBJDIR)/$* \
install_$(subst /,_,$*)
# Preprocessed files. Ideally they would be using install manifests but
# right now, it's not possible because of things like APP_BUILDID or
# nsURLFormatter.js.
# Things missing:
# - XULPPFLAGS
#
# The list of preprocessed files is defined in PP_TARGETS. The list is
# relative to TOPOBJDIR.
# The source file for each of those preprocessed files is defined as a Make
# dependency for the $(TOPOBJDIR)/path target. For example:
# PP_TARGETS = foo/bar
# $(TOPOBJDIR)/foo/bar: /path/to/source/for/foo/bar.in
# The file name for the source doesn't need to be different.
# Additionally, extra defines can be specified for a given preprocessing
# by setting the `defines` variable specifically for the given target.
# For example:
# $(TOPOBJDIR)/foo/bar: defines = -Dqux=foobar
$(addprefix $(TOPOBJDIR)/,$(PP_TARGETS)): Makefile
$(addprefix $(TOPOBJDIR)/,$(PP_TARGETS)): $(TOPOBJDIR)/%:
$(PYTHON) -m mozbuild.action.preprocessor \
--depend $(TOPOBJDIR)/faster/.deps/$(subst /,_,$*) \
-DAB_CD=en-US \
$(defines) \
$(ACDEFINES) \
$< \
-o $@
# Include the dependency files from the above preprocessed files rule.
$(foreach pp_target,$(PP_TARGETS), \
$(eval -include $(TOPOBJDIR)/faster/.deps/$(subst /,_,$(pp_target))))
# Install files from jar manifests. Ideally, they would be using install
# manifests, but the code to read jar manifests and emit appropriate
# install manifests is not there yet.
# Things missing:
# - XULPPFLAGS
# - DEFINES from config/config.mk
# - L10N
# - -e when USE_EXTENSION_MANIFEST is set in moz.build
#
# The list given in JAR_MN_TARGETS corresponds to the list of `jar-%` targets
# to be processed, with the `jar-` prefix stripped.
# The Makefile is expected to specify the source jar manifest as a dependency
# to each target. There is no expectation that the `jar-%` target name matches
# the source file name in any way. For example:
# JAR_MN_TARGETS = foo
# jar-foo: /path/to/some/jar.mn
# Additionally, extra defines can be specified for the processing of the jar
# manifest by settig the `defines` variable specifically for the given target.
# For example:
# jar-foo: defines = -Dqux=foo
# The default base path where files are going to be installed is `dist/bin`.
# It is possible to use a different path by setting the `install_target`
# variable. For example:
# jar-foo: install_target = dist/bin/foo
# When processing jar manifests, relative paths given inside a jar manifest
# can be resolved from an object directory. The default path for that object
# directory is the translation of the jar manifest directory path from the
# source directory to the object directory. That is, for
# $(TOPSRCDIR)/path/to/jar.mn, the default would be $(TOPOBJDIR)/path/to.
# In case a different path must be used for the object directory, the `objdir`
# variable can be set. For example:
# jar-foo: objdir=/some/other/path
jar-%: objdir ?= $(dir $(patsubst $(TOPSRCDIR)%,$(TOPOBJDIR)%,$<))
jar-%: install_target ?= dist/bin
jar-%:
cd $(objdir) && \
$(PYTHON) -m mozbuild.action.jar_maker \
-j $(TOPOBJDIR)/$(install_target)/chrome \
-t $(TOPSRCDIR) \
-f $(MOZ_CHROME_FILE_FORMAT) \
-c $(dir $<)/en-US \
-DAB_CD=en-US \
$(defines) \
$(ACDEFINES) \
$<
# Create some chrome manifests
# This rule is forced to run every time because it may be updating files that
# already exit.
#
# The list of chrome manifests is given in MANIFEST_TARGETS, relative to the
# top object directory. The content for those manifests is given in the
# `content` variable associated with the target. For example:
# MANIFEST_TARGETS = foo
# $(TOPOBJDIR)/foo: content = "manifest foo.manifest" "manifest bar.manifest"
$(addprefix $(TOPOBJDIR)/,$(MANIFEST_TARGETS)): FORCE
$(PYTHON) -m mozbuild.action.buildlist \
$@ \
$(content)
# ============================================================================
# Below is a set of additional dependencies and variables used to build things
# that are not supported by data in moz.build.
# GENERATED_FILES are not supported yet, and even if they were, the
# dependencies are missing information.
$(foreach p,linux osx windows,jar-browser-themes-$(p)-jar.mn): \
jar-browser-themes-%-jar.mn: \
$(TOPOBJDIR)/browser/themes/%/tab-selected-end.svg \
$(TOPOBJDIR)/browser/themes/%/tab-selected-start.svg
# These files are manually generated from
# toolkit/components/urlformatter/Makefile.in and are force-included so that
# the corresponding defines don't end up in the command lines.
KEYS = mozilla_api_key google_api_key google_oauth_api_key bing_api_key
$(TOPOBJDIR)/dist/bin/components/nsURLFormatter.js: \
$(addprefix $(TOPOBJDIR)/toolkit/components/urlformatter/, $(KEYS))
$(TOPOBJDIR)/dist/bin/components/nsURLFormatter.js: defines += \
$(addprefix -I $(TOPOBJDIR)/toolkit/components/urlformatter/,$(KEYS))
# Extra dependencies and/or definitions for preprocessed files.
$(TOPOBJDIR)/dist/bin/application.ini: $(TOPOBJDIR)/config/buildid
$(TOPOBJDIR)/dist/bin/application.ini: defines += \
-DAPP_BUILDID=$(shell cat $(TOPOBJDIR)/config/buildid)
# Files to build with the recursive backend and simply copy
$(TOPOBJDIR)/dist/bin/greprefs.js: $(TOPOBJDIR)/modules/libpref/greprefs.js
$(TOPOBJDIR)/dist/bin/platform.ini: $(TOPOBJDIR)/toolkit/xre/platform.ini
$(TOPOBJDIR)/dist/bin/webapprt/webapprt.ini: $(TOPOBJDIR)/webapprt/webapprt.ini

View File

@ -1,202 +0,0 @@
#!/bin/sh
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
##############################################################################
##
## Name: glibcversion.sh - Print __GLIBC__ version if gnu libc 2 is
## found.
##
## Description: This script is needed by the mozilla build system. It needs
## to determine whether the current platform (mostly the
## various linux "platforms") are based on the gnu libc2. This
## information is later used in mozilla to determine whether
## gnu libc 2 specific "features" need to be handled, such
## as broken locales.
##
## Author: Ramiro Estrugo <ramiro@netscape.com>
##
##############################################################################
##
## Command Line Flags Supported:
##
## -g | --is-glibc2: Print True/False if detected __GLIBC__.
##
## -v | --print-version: Print value of __GLIBC__ if found, or none.
##
## -o | --set-object-name: Set object name for current system.
## -cc | --set-compiler: Set compiler for building test program.
##
##
## Constants
##
GLIBC_PROG_PREFIX=./get_glibc_info
##
## Defaults
##
GLIBC_PRINT_IS_GLIBC2=False
GLIBC_PRINT_VERSION=False
GLIBC_OBJECT_NAME=`uname`-`uname -r`
GLIBC_CC=cc
function glibc_usage()
{
echo
echo "Usage: `basename $0` [options]"
echo
echo " -g, --is-glibc2: Print True/False if detected __GLIBC__."
echo
echo " -v, --print-version: Print value of __GLIBC__ if found, or none."
echo
echo " -o, --set-object-name: Set object name for current system."
echo " -cc, --set-compiler: Set compiler for building test program."
echo
echo " -h, --help: Print this blurb."
echo
echo "The default is '-v' if no options are given."
echo
}
##
## Parse the command line
##
while [ "$*" ]; do
case $1 in
-h | --help)
shift
glibc_usage
exit 0
;;
-g | --is-glibc2)
shift
GLIBC_PRINT_IS_GLIBC2=True
;;
-v | --print-version)
shift
GLIBC_PRINT_VERSION=True
;;
-o | --set-object-name)
shift
GLIBC_OBJECT_NAME="$1"
shift
;;
-cc | --set-compiler)
shift
GLIBC_CC="$1"
shift
;;
-*)
echo "`basename $0`: invalid option '$1'"
shift
glibc_usage
exit 0
;;
esac
done
##
## Motif info program name
##
GLIBC_PROG="$GLIBC_PROG_PREFIX"_"$GLIBC_OBJECT_NAME"
GLIBC_SRC="$GLIBC_PROG_PREFIX"_"$GLIBC_OBJECT_NAME.c"
##
## Cleanup the dummy test source/program
##
function glibc_cleanup()
{
true
# rm -f $GLIBC_PROG
# rm -f $GLIBC_SRC
}
glibc_cleanup
if [ ! -f $GLIBC_SRC ]
then
cat << EOF > $GLIBC_SRC
#include <stdio.h>
int main(int argc,char ** argv)
{
#ifdef __GLIBC__
fprintf(stdout,"%d\n",__GLIBC__);
#else
fprintf(stdout,"none\n");
#endif
return 0;
}
EOF
fi
if [ ! -f $GLIBC_SRC ]
then
echo
echo "Could not create test program source $GLIBC_SRC."
echo
glibc_cleanup
exit
fi
##
## Compile the dummy test program if needed
##
if [ ! -x $GLIBC_PROG ]
then
$GLIBC_CC -o $GLIBC_PROG $GLIBC_SRC
fi
if [ ! -x $GLIBC_PROG ]
then
echo
echo "Could not create test program $GLIBC_PROG."
echo
glibc_cleanup
exit
fi
##
## Execute the dummy test program
##
GLIBC_PROG_OUTPUT=`$GLIBC_PROG`
##
## -g | --is-glibc2
##
if [ "$GLIBC_PRINT_IS_GLIBC2" = "True" ]
then
if [ "$GLIBC_PROG_OUTPUT" = "2" ]
then
echo True
else
echo False
fi
glibc_cleanup
exit 0
fi
echo $GLIBC_PROG_OUTPUT
glibc_cleanup

View File

@ -137,6 +137,8 @@ MOZ_BUILD_ROOT=`pwd -W 2>/dev/null || pwd`
MOZ_PYTHON
MOZ_BUILD_BACKEND
MOZ_DEFAULT_COMPILER
COMPILE_ENVIRONMENT=1

View File

@ -49,7 +49,7 @@ function* testPressingEscapeRevertsChanges(view) {
yield ruleEditor.rule._applyingModifications;
yield waitForComputedStyleProperty("body", null, "animation-timing-function",
"cubic-bezier(0, 0, 1, 1)");
"linear");
is(propEditor.valueSpan.textContent, "linear",
"Got expected property value.");
}

View File

@ -10,6 +10,8 @@ const URL2 = MAIN_DOMAIN + "navigate-second.html";
var events = require("sdk/event/core");
var client;
SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunload", false]]});
// State machine to check events order
var i = 0;
function assertEvent(event, data) {

View File

@ -6,6 +6,8 @@ var stayingOnPage = true;
var TEST_PAGE = "http://mochi.test:8888/browser/docshell/test/browser/file_bug1046022.html";
var TARGETED_PAGE = "data:text/html," + encodeURIComponent("<body>Shouldn't be seeing this</body>");
SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunload", false]]});
var loadExpected = TEST_PAGE;
var testTab;

View File

@ -10,6 +10,7 @@
#include "AnimationCommon.h"
#include "nsCSSPropertySet.h"
#include "nsCSSProps.h" // For nsCSSProps::PropHasFlags
#include "nsStyleUtil.h"
namespace mozilla {
@ -17,11 +18,12 @@ void
ComputedTimingFunction::Init(const nsTimingFunction &aFunction)
{
mType = aFunction.mType;
if (mType == nsTimingFunction::Function) {
if (nsTimingFunction::IsSplineType(mType)) {
mTimingFunction.Init(aFunction.mFunc.mX1, aFunction.mFunc.mY1,
aFunction.mFunc.mX2, aFunction.mFunc.mY2);
} else {
mSteps = aFunction.mSteps;
mStepSyntax = aFunction.mStepSyntax;
}
}
@ -35,23 +37,67 @@ StepEnd(uint32_t aSteps, double aPortion)
double
ComputedTimingFunction::GetValue(double aPortion) const
{
if (HasSpline()) {
return mTimingFunction.GetSplineValue(aPortion);
}
if (mType == nsTimingFunction::Type::StepStart) {
// There are diagrams in the spec that seem to suggest this check
// and the bounds point should not be symmetric with StepEnd, but
// should actually step up at rather than immediately after the
// fraction points. However, we rely on rounding negative values
// up to zero, so we can't do that. And it's not clear the spec
// really meant it.
return 1.0 - StepEnd(mSteps, 1.0 - aPortion);
}
MOZ_ASSERT(mType == nsTimingFunction::Type::StepEnd, "bad type");
return StepEnd(mSteps, aPortion);
}
int32_t
ComputedTimingFunction::Compare(const ComputedTimingFunction& aRhs) const
{
if (mType != aRhs.mType) {
return int32_t(mType) - int32_t(aRhs.mType);
}
if (mType == nsTimingFunction::Type::CubicBezier) {
int32_t order = mTimingFunction.Compare(aRhs.mTimingFunction);
if (order != 0) {
return order;
}
} else if (mType == nsTimingFunction::Type::StepStart ||
mType == nsTimingFunction::Type::StepEnd) {
if (mSteps != aRhs.mSteps) {
return int32_t(mSteps) - int32_t(aRhs.mSteps);
}
if (mStepSyntax != aRhs.mStepSyntax) {
return int32_t(mStepSyntax) - int32_t(aRhs.mStepSyntax);
}
}
return 0;
}
void
ComputedTimingFunction::AppendToString(nsAString& aResult) const
{
switch (mType) {
case nsTimingFunction::Function:
return mTimingFunction.GetSplineValue(aPortion);
case nsTimingFunction::StepStart:
// There are diagrams in the spec that seem to suggest this check
// and the bounds point should not be symmetric with StepEnd, but
// should actually step up at rather than immediately after the
// fraction points. However, we rely on rounding negative values
// up to zero, so we can't do that. And it's not clear the spec
// really meant it.
return 1.0 - StepEnd(mSteps, 1.0 - aPortion);
case nsTimingFunction::Type::CubicBezier:
nsStyleUtil::AppendCubicBezierTimingFunction(mTimingFunction.X1(),
mTimingFunction.Y1(),
mTimingFunction.X2(),
mTimingFunction.Y2(),
aResult);
break;
case nsTimingFunction::Type::StepStart:
case nsTimingFunction::Type::StepEnd:
nsStyleUtil::AppendStepsTimingFunction(mType, mSteps, mStepSyntax,
aResult);
break;
default:
MOZ_ASSERT(false, "bad type");
// fall through
case nsTimingFunction::StepEnd:
return StepEnd(mSteps, aPortion);
nsStyleUtil::AppendCubicBezierKeywordTimingFunction(mType, aResult);
break;
}
}
@ -456,5 +502,116 @@ KeyframeEffectReadOnly::ResetIsRunningOnCompositor()
}
}
struct KeyframeValueEntry
{
float mOffset;
nsCSSProperty mProperty;
nsString mValue;
const ComputedTimingFunction* mTimingFunction;
bool operator==(const KeyframeValueEntry& aRhs) const
{
NS_ASSERTION(mOffset != aRhs.mOffset || mProperty != aRhs.mProperty,
"shouldn't have duplicate (offset, property) pairs");
return false;
}
bool operator<(const KeyframeValueEntry& aRhs) const
{
NS_ASSERTION(mOffset != aRhs.mOffset || mProperty != aRhs.mProperty,
"shouldn't have duplicate (offset, property) pairs");
// First, sort by offset.
if (mOffset != aRhs.mOffset) {
return mOffset < aRhs.mOffset;
}
// Second, by timing function.
int32_t order = mTimingFunction->Compare(*aRhs.mTimingFunction);
if (order != 0) {
return order < 0;
}
// Last, by property IDL name.
return nsCSSProps::PropertyIDLNameSortPosition(mProperty) <
nsCSSProps::PropertyIDLNameSortPosition(aRhs.mProperty);
}
};
void
KeyframeEffectReadOnly::GetFrames(JSContext*& aCx,
nsTArray<JSObject*>& aResult,
ErrorResult& aRv)
{
// Collect tuples of the form (offset, property, value, easing) from
// mProperties, then sort them so we can generate one ComputedKeyframe per
// offset/easing pair. We sort secondarily by property IDL name so that we
// have a uniform order that we set properties on the ComputedKeyframe
// object.
nsAutoTArray<KeyframeValueEntry,4> entries;
for (const AnimationProperty& property : mProperties) {
if (property.mSegments.IsEmpty()) {
continue;
}
for (size_t i = 0, n = property.mSegments.Length(); i < n; i++) {
const AnimationPropertySegment& segment = property.mSegments[i];
KeyframeValueEntry* entry = entries.AppendElement();
entry->mOffset = segment.mFromKey;
entry->mProperty = property.mProperty;
entry->mTimingFunction = &segment.mTimingFunction;
StyleAnimationValue::UncomputeValue(property.mProperty,
segment.mFromValue,
entry->mValue);
}
const AnimationPropertySegment& segment = property.mSegments.LastElement();
KeyframeValueEntry* entry = entries.AppendElement();
entry->mOffset = segment.mToKey;
entry->mProperty = property.mProperty;
// We don't have the an appropriate animation-timing-function value to use,
// either from the element or from the 100% keyframe, so we just set it to
// the animation-timing-value value used on the previous segment.
entry->mTimingFunction = &segment.mTimingFunction;
StyleAnimationValue::UncomputeValue(property.mProperty,
segment.mToValue,
entry->mValue);
}
entries.Sort();
for (size_t i = 0, n = entries.Length(); i < n; ) {
// Create a JS object with the explicit ComputedKeyframe dictionary members.
ComputedKeyframe keyframeDict;
keyframeDict.mOffset.SetValue(entries[i].mOffset);
keyframeDict.mComputedOffset.Construct(entries[i].mOffset);
keyframeDict.mEasing.Truncate();
entries[i].mTimingFunction->AppendToString(keyframeDict.mEasing);
keyframeDict.mComposite.SetValue(CompositeOperation::Replace);
JS::Rooted<JS::Value> keyframeValue(aCx);
if (!ToJSValue(aCx, keyframeDict, &keyframeValue)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
JS::Rooted<JSObject*> keyframe(aCx, &keyframeValue.toObject());
// Set the property name/value pairs on the JS object.
do {
const KeyframeValueEntry& entry = entries[i];
const char* name = nsCSSProps::PropertyIDLName(entry.mProperty);
JS::Rooted<JS::Value> value(aCx);
if (!ToJSValue(aCx, entry.mValue, &value) ||
!JS_DefineProperty(aCx, keyframe, name, value, JSPROP_ENUMERATE)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
++i;
} while (i < n &&
entries[i].mOffset == entries[i - 1].mOffset &&
*entries[i].mTimingFunction == *entries[i - 1].mTimingFunction);
aResult.AppendElement(keyframe);
}
}
} // namespace dom
} // namespace mozilla

View File

@ -19,6 +19,7 @@
#include "mozilla/TimeStamp.h"
#include "mozilla/dom/AnimationEffectReadOnly.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/KeyframeBinding.h"
#include "mozilla/dom/Nullable.h"
#include "nsSMILKeySpline.h"
#include "nsStyleStruct.h" // for nsTimingFunction
@ -109,28 +110,35 @@ class ComputedTimingFunction
{
public:
typedef nsTimingFunction::Type Type;
typedef nsTimingFunction::StepSyntax StepSyntax;
void Init(const nsTimingFunction &aFunction);
double GetValue(double aPortion) const;
const nsSMILKeySpline* GetFunction() const {
NS_ASSERTION(mType == nsTimingFunction::Function, "Type mismatch");
NS_ASSERTION(HasSpline(), "Type mismatch");
return &mTimingFunction;
}
Type GetType() const { return mType; }
bool HasSpline() const { return nsTimingFunction::IsSplineType(mType); }
uint32_t GetSteps() const { return mSteps; }
StepSyntax GetStepSyntax() const { return mStepSyntax; }
bool operator==(const ComputedTimingFunction& aOther) const {
return mType == aOther.mType &&
(mType == nsTimingFunction::Function ?
(HasSpline() ?
mTimingFunction == aOther.mTimingFunction :
mSteps == aOther.mSteps);
(mSteps == aOther.mSteps &&
mStepSyntax == aOther.mStepSyntax));
}
bool operator!=(const ComputedTimingFunction& aOther) const {
return !(*this == aOther);
}
int32_t Compare(const ComputedTimingFunction& aRhs) const;
void AppendToString(nsAString& aResult) const;
private:
Type mType;
nsSMILKeySpline mTimingFunction;
uint32_t mSteps;
StepSyntax mStepSyntax;
};
struct AnimationPropertySegment
@ -225,6 +233,9 @@ public:
" pseudo-element is not yet supported.");
return mTarget;
}
void GetFrames(JSContext*& aCx,
nsTArray<JSObject*>& aResult,
ErrorResult& aRv);
// Temporary workaround to return both the target element and pseudo-type
// until we implement PseudoElement (bug 1174575).

View File

@ -30,8 +30,11 @@ UNIFIED_SOURCES += [
'PendingAnimationTracker.cpp',
]
FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [
'/dom/base',
]
FINAL_LIBRARY = 'xul'
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -0,0 +1,455 @@
<!doctype html>
<meta charset=utf-8>
<script src="../testcommon.js"></script>
<style>
@keyframes anim-empty { }
@keyframes anim-empty-frames {
from { }
to { }
}
@keyframes anim-only-timing {
from { animation-timing-function: linear; }
to { }
}
@keyframes anim-only-non-animatable {
from { display: none; }
to { display: inline; }
}
@keyframes anim-simple {
from { color: black; }
to { color: white; }
}
@keyframes anim-simple-timing {
from { color: black; animation-timing-function: linear; }
50% { color: blue; animation-timing-function: ease-in-out; }
to { color: white; animation-timing-function: step-end; }
}
@keyframes anim-simple-timing-some {
from { color: black; animation-timing-function: linear; }
50% { color: blue; }
to { color: white; }
}
@keyframes anim-simple-shorthand {
from { margin: 8px; }
to { margin: 16px; }
}
@keyframes anim-omit-to {
from { color: blue; }
}
@keyframes anim-omit-from {
to { color: blue; }
}
@keyframes anim-omit-from-to {
50% { color: blue; }
}
@keyframes anim-different-props {
from { color: black; margin-top: 8px; }
25% { color: blue; }
75% { margin-top: 12px; }
to { color: white; margin-top: 16px }
}
@keyframes anim-different-props-and-easing {
from { color: black; margin-top: 8px; animation-timing-function: linear; }
25% { color: blue; animation-timing-function: step-end; }
75% { margin-top: 12px; animation-timing-function: ease-in; }
to { color: white; margin-top: 16px }
}
@keyframes anim-merge-offset {
from { color: black; }
to { color: white; }
from { margin-top: 8px; }
to { margin-top: 16px; }
}
@keyframes anim-merge-offset-and-easing {
from { color: black; animation-timing-function: step-end; }
to { color: white; }
from { margin-top: 8px; animation-timing-function: linear; }
to { margin-top: 16px; }
from { font-size: 16px; animation-timing-function: step-end; }
to { font-size: 32px; }
from { padding-left: 2px; animation-timing-function: linear; }
to { padding-left: 4px; }
}
@keyframes anim-no-merge-equiv-easing {
from { margin-top: 0px; animation-timing-function: steps(1, end); }
from { margin-right: 0px; animation-timing-function: step-end; }
from { margin-bottom: 0px; animation-timing-function: steps(1); }
50% { margin-top: 10px; animation-timing-function: step-end; }
50% { margin-right: 10px; animation-timing-function: step-end; }
50% { margin-bottom: 10px; animation-timing-function: step-end; }
to { margin-top: 20px; margin-right: 20px; margin-bottom: 20px; }
}
</style>
<body>
<script>
"use strict";
function getFrames(e) {
return e.getAnimations()[0].effect.getFrames();
}
function assert_frames_equal(a, b, name) {
assert_equals(Object.keys(a).sort().toString(),
Object.keys(b).sort().toString(),
"properties on " + name);
for (var p in a) {
assert_equals(a[p], b[p], "value for '" + p + "' on " + name);
}
}
// animation-timing-function values to test with, where the value
// is exactly the same as its serialization, sorted by the order
// getFrames() will group frames with the same easing function
// together (by nsTimingFunction::Compare).
const kTimingFunctionValues = [
"ease",
"linear",
"ease-in",
"ease-out",
"ease-in-out",
"step-start",
"steps(1, start)",
"steps(2, start)",
"step-end",
"steps(1)",
"steps(1, end)",
"steps(2)",
"steps(2, end)",
"cubic-bezier(0, 0, 1, 1)",
"cubic-bezier(0, 0.25, 0.75, 1)",
];
test(function(t) {
var div = addDiv(t);
var frames;
div.style.animation = 'anim-empty 100s';
assert_equals(getFrames(div).length, 0,
"number of frames with empty @keyframes");
div.style.animation = 'anim-empty-frames 100s';
assert_equals(getFrames(div).length, 0,
"number of frames when @keyframes has empty keyframes");
div.style.animation = 'anim-only-timing 100s';
assert_equals(getFrames(div).length, 0,
"number of frames when @keyframes only has keyframes with " +
"animation-timing-function");
div.style.animation = 'anim-only-non-animatable 100s';
assert_equals(getFrames(div).length, 0,
"number of frames when @keyframes only has frames with " +
"non-animatable properties");
}, 'KeyframeEffectReadOnly.getFrames() returns no frames for various kinds ' +
'of empty enimations');
test(function(t) {
var div = addDiv(t);
div.style.animation = 'anim-simple 100s';
var frames = getFrames(div);
assert_equals(frames.length, 2, "number of frames");
var expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: "replace",
color: "rgb(0, 0, 0)" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "replace",
color: "rgb(255, 255, 255)" },
];
for (var i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffectReadOnly.getFrames() returns expected frames for a simple ' +
'animation');
test(function(t) {
kTimingFunctionValues.forEach(function(easing) {
var div = addDiv(t);
div.style.animation = 'anim-simple 100s ' + easing;
var frames = getFrames(div);
assert_equals(frames.length, 2, "number of frames");
for (var i = 0; i < frames.length; i++) {
assert_equals(frames[i].easing, easing,
"value for 'easing' on ComputedKeyframe #" + i);
}
});
}, 'KeyframeEffectReadOnly.getFrames() returns frames with expected easing ' +
'values, when the easing comes from animation-timing-function on the ' +
'element');
test(function(t) {
var div = addDiv(t);
div.style.animation = 'anim-simple-timing 100s';
var frames = getFrames(div);
assert_equals(frames.length, 3, "number of frames");
assert_equals(frames[0].easing, "linear",
"value of 'easing' on ComputedKeyframe #0");
assert_equals(frames[1].easing, "ease-in-out",
"value of 'easing' on ComputedKeyframe #1");
assert_equals(frames[2].easing, "ease-in-out",
"value of 'easing' on ComputedKeyframe #2");
}, 'KeyframeEffectReadOnly.getFrames() returns frames with expected easing ' +
'values, when the easing is specified on each keyframe');
test(function(t) {
var div = addDiv(t);
div.style.animation = 'anim-simple-timing-some 100s step-start';
var frames = getFrames(div);
assert_equals(frames.length, 3, "number of frames");
assert_equals(frames[0].easing, "linear",
"value of 'easing' on ComputedKeyframe #0");
assert_equals(frames[1].easing, "step-start",
"value of 'easing' on ComputedKeyframe #1");
assert_equals(frames[2].easing, "step-start",
"value of 'easing' on ComputedKeyframe #2");
}, 'KeyframeEffectReadOnly.getFrames() returns frames with expected easing ' +
'values, when the easing is specified on some keyframes');
test(function(t) {
var div = addDiv(t);
div.style.animation = 'anim-simple-shorthand 100s';
var frames = getFrames(div);
assert_equals(frames.length, 2, "number of frames");
var expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: "replace",
marginTop: "8px", marginRight: "8px",
marginBottom: "8px", marginLeft: "8px" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "replace",
marginTop: "16px", marginRight: "16px",
marginBottom: "16px", marginLeft: "16px" },
];
for (var i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffectReadOnly.getFrames() returns expected frames for a simple ' +
'animation that specifies a single shorthand property');
test(function(t) {
var div = addDiv(t);
div.style.animation = 'anim-omit-to 100s';
div.style.color = 'white';
var frames = getFrames(div);
assert_equals(frames.length, 2, "number of frames");
var expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: "replace",
color: "rgb(0, 0, 255)" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "replace",
color: "rgb(255, 255, 255)" },
];
for (var i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffectReadOnly.getFrames() returns expected frames for an ' +
'animation with a 0% keyframe and no 100% keyframe');
test(function(t) {
var div = addDiv(t);
div.style.animation = 'anim-omit-from 100s';
div.style.color = 'white';
var frames = getFrames(div);
assert_equals(frames.length, 2, "number of frames");
var expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: "replace",
color: "rgb(255, 255, 255)" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "replace",
color: "rgb(0, 0, 255)" },
];
for (var i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffectReadOnly.getFrames() returns expected frames for an ' +
'animation with a 100% keyframe and no 0% keyframe');
test(function(t) {
var div = addDiv(t);
div.style.animation = 'anim-omit-from-to 100s';
div.style.color = 'white';
var frames = getFrames(div);
assert_equals(frames.length, 3, "number of frames");
var expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: "replace",
color: "rgb(255, 255, 255)" },
{ offset: 0.5, computedOffset: 0.5, easing: "ease", composite: "replace",
color: "rgb(0, 0, 255)" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "replace",
color: "rgb(255, 255, 255)" },
];
for (var i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffectReadOnly.getFrames() returns expected frames for an ' +
'animation with no 0% or 100% keyframe but with a 50% keyframe');
test(function(t) {
var div = addDiv(t);
div.style.animation = 'anim-different-props 100s';
var frames = getFrames(div);
assert_equals(frames.length, 4, "number of frames");
var expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: "replace",
color: "rgb(0, 0, 0)", marginTop: "8px" },
{ offset: 0.25, computedOffset: 0.25, easing: "ease", composite: "replace",
color: "rgb(0, 0, 255)" },
{ offset: 0.75, computedOffset: 0.75, easing: "ease", composite: "replace",
marginTop: "12px" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "replace",
color: "rgb(255, 255, 255)", marginTop: "16px" },
];
for (var i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffectReadOnly.getFrames() returns expected frames for an ' +
'animation with different properties on different keyframes, all ' +
'with the same easing function');
test(function(t) {
var div = addDiv(t);
div.style.animation = 'anim-different-props-and-easing 100s';
var frames = getFrames(div);
assert_equals(frames.length, 5, "number of frames");
var expected = [
{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace",
color: "rgb(0, 0, 0)", marginTop: "8px" },
{ offset: 0.25, computedOffset: 0.25, easing: "step-end", composite: "replace",
color: "rgb(0, 0, 255)" },
{ offset: 0.75, computedOffset: 0.75, easing: "ease-in", composite: "replace",
marginTop: "12px" },
{ offset: 1, computedOffset: 1, easing: "ease-in", composite: "replace",
marginTop: "16px" },
{ offset: 1, computedOffset: 1, easing: "step-end", composite: "replace",
color: "rgb(255, 255, 255)", },
];
for (var i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffectReadOnly.getFrames() returns expected frames for an ' +
'animation with different properties on different keyframes, with ' +
'a different easing function on each');
test(function(t) {
var div = addDiv(t);
div.style.animation = 'anim-merge-offset 100s';
var frames = getFrames(div);
assert_equals(frames.length, 2, "number of frames");
var expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: "replace",
color: "rgb(0, 0, 0)", marginTop: "8px" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "replace",
color: "rgb(255, 255, 255)", marginTop: "16px" },
];
for (var i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffectReadOnly.getFrames() returns expected frames for an ' +
'animation with multiple keyframes for the same time, and all with ' +
'the same easing function');
test(function(t) {
var div = addDiv(t);
div.style.animation = 'anim-merge-offset-and-easing 100s';
var frames = getFrames(div);
assert_equals(frames.length, 4, "number of frames");
var expected = [
{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace",
marginTop: "8px", paddingLeft: "2px" },
{ offset: 0, computedOffset: 0, easing: "step-end", composite: "replace",
color: "rgb(0, 0, 0)", fontSize: "16px" },
{ offset: 1, computedOffset: 1, easing: "linear", composite: "replace",
marginTop: "16px", paddingLeft: "4px" },
{ offset: 1, computedOffset: 1, easing: "step-end", composite: "replace",
color: "rgb(255, 255, 255)", fontSize: "32px" },
];
for (var i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffectReadOnly.getFrames() returns expected frames for an ' +
'animation with multiple keyframes for the same time and with ' +
'different easing functions');
test(function(t) {
var div = addDiv(t);
div.style.animation = 'anim-no-merge-equiv-easing 100s';
var frames = getFrames(div);
assert_equals(frames.length, 5, "number of frames");
var expected = [
{ offset: 0, computedOffset: 0, easing: "step-end", composite: "replace",
marginRight: "0px" },
{ offset: 0, computedOffset: 0, easing: "steps(1)", composite: "replace",
marginBottom: "0px" },
{ offset: 0, computedOffset: 0, easing: "steps(1, end)", composite: "replace",
marginTop: "0px" },
{ offset: 0.5, computedOffset: 0.5, easing: "step-end", composite: "replace",
marginTop: "10px", marginRight: "10px", marginBottom: "10px" },
{ offset: 1, computedOffset: 1, easing: "step-end", composite: "replace",
marginTop: "20px", marginRight: "20px", marginBottom: "20px" },
];
for (var i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffectReadOnly.getFrames() returns expected frames for an ' +
'animation with multiple keyframes for the same time and with ' +
'different but equivalent easing functions');
done();
</script>
</body>

View File

@ -0,0 +1,15 @@
<!doctype html>
<meta charset=utf-8>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
'use strict';
setup({explicit_done: true});
SpecialPowers.pushPrefEnv(
{ "set": [["dom.animations-api.core.enabled", true]]},
function() {
window.open("file_keyframeeffect-getframes.html");
});
</script>
</html>

View File

@ -0,0 +1,73 @@
<!doctype html>
<meta charset=utf-8>
<script src="../testcommon.js"></script>
<body>
<script>
'use strict';
function getFrames(e) {
return e.getAnimations()[0].effect.getFrames();
}
function assert_frames_equal(a, b, name) {
assert_equals(Object.keys(a).sort().toString(),
Object.keys(b).sort().toString(),
"properties on " + name);
for (var p in a) {
assert_equals(a[p], b[p], "value for '" + p + "' on " + name);
}
}
test(function(t) {
var div = addDiv(t);
div.style.left = '0px';
window.getComputedStyle(div).transitionProperty;
div.style.transition = 'left 100s';
div.style.left = '100px';
var frames = getFrames(div);
assert_equals(frames.length, 2, "number of frames");
var expected = [
{ offset: 0, computedOffset: 0, easing: "ease", composite: "replace",
left: "0px" },
{ offset: 1, computedOffset: 1, easing: "ease", composite: "replace",
left: "100px" },
];
for (var i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffectReadOnly.getFrames() returns expected frames for a simple ' +
'transition');
test(function(t) {
var div = addDiv(t);
div.style.left = '0px';
window.getComputedStyle(div).transitionProperty;
div.style.transition = 'left 100s steps(2,end)';
div.style.left = '100px';
var frames = getFrames(div);
assert_equals(frames.length, 2, "number of frames");
var expected = [
{ offset: 0, computedOffset: 0, easing: "steps(2, end)", composite: "replace",
left: "0px" },
{ offset: 1, computedOffset: 1, easing: "steps(2, end)", composite: "replace",
left: "100px" },
];
for (var i = 0; i < frames.length; i++) {
assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
}
}, 'KeyframeEffectReadOnly.getFrames() returns expected frames for a simple ' +
'transition with a non-default easing function');
done();
</script>
</body>

View File

@ -0,0 +1,14 @@
<!doctype html>
<meta charset=utf-8>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
'use strict';
setup({explicit_done: true});
SpecialPowers.pushPrefEnv(
{ "set": [["dom.animations-api.core.enabled", true]]},
function() {
window.open("file_keyframeeffect-getframes.html");
});
</script>

View File

@ -32,6 +32,8 @@ support-files = css-animations/file_animation-reverse.html
support-files = css-animations/file_animation-starttime.html
[css-animations/test_cssanimation-animationname.html]
support-files = css-animations/file_cssanimation-animationname.html
[css-animations/test_keyframeeffect-getframes.html]
support-files = css-animations/file_keyframeeffect-getframes.html
[css-animations/test_effect-target.html]
support-files = css-animations/file_effect-target.html
[css-animations/test_element-get-animations.html]
@ -53,6 +55,8 @@ support-files = css-transitions/file_animation-ready.html
support-files = css-transitions/file_animation-starttime.html
[css-transitions/test_csstransition-transitionproperty.html]
support-files = css-transitions/file_csstransition-transitionproperty.html
[css-transitions/test_keyframeeffect-getframes.html]
support-files = css-transitions/file_keyframeeffect-getframes.html
[css-transitions/test_effect-target.html]
support-files = css-transitions/file_effect-target.html
[css-transitions/test_element-get-animations.html]

View File

@ -8,6 +8,7 @@
#include "nsIDOMDocument.h"
#include "nsNetUtil.h"
#include "nsIStreamListener.h"
#include "nsStringStream.h"
#include "nsIScriptSecurityManager.h"
#include "nsCRT.h"

View File

@ -17,6 +17,7 @@
#include "nsNetUtil.h"
#include "nsIAuthPrompt.h"
#include "nsIAuthPrompt2.h"
#include "nsIInputStream.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsMimeTypes.h"
#include "nsIPromptFactory.h"

View File

@ -6,6 +6,7 @@
#include "mozilla/dom/FileList.h"
#include "mozilla/dom/FileListBinding.h"
#include "mozilla/dom/File.h"
namespace mozilla {
namespace dom {

View File

@ -8,6 +8,7 @@
#include "MessageEvent.h"
#include "mozilla/dom/BlobBinding.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/FileList.h"
#include "mozilla/dom/FileListBinding.h"
#include "mozilla/dom/MessagePort.h"

View File

@ -17,7 +17,9 @@
#include "nsIRunnable.h"
#include "nsIGlobalObject.h"
#include "nsIScriptObjectPrincipal.h"
#include "nsServiceManagerUtils.h"
#include "nsWeakReference.h"
#include "nsWrapperCache.h"
namespace mozilla {
namespace dom {

View File

@ -4,9 +4,18 @@
#include "ScreenOrientation.h"
#include "nsIDeviceSensors.h"
#include "nsIDocShell.h"
#include "nsIDocument.h"
#include "nsGlobalWindow.h"
#include "nsSandboxFlags.h"
#include "nsScreen.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/Hal.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/Promise.h"
using namespace mozilla::dom;
NS_IMPL_CYCLE_COLLECTION_INHERITED(ScreenOrientation,

View File

@ -6,6 +6,8 @@
#ifndef nsCopySupport_h__
#define nsCopySupport_h__
#include "nsError.h"
#include "nsIDocument.h"
#include "mozilla/EventForwards.h"
class nsINode;

View File

@ -31,6 +31,7 @@
#include "nsICategoryManager.h"
#include "nsIComponentRegistrar.h"
#include "nsXPCOM.h"
#include "nsISimpleEnumerator.h"
#include "nsISupportsPrimitives.h"
#include "nsIXPConnect.h"
#include "xptcall.h"

View File

@ -213,6 +213,12 @@ nsDOMDataChannel::BufferedAmount() const
return mDataChannel->GetBufferedAmount();
}
uint32_t
nsDOMDataChannel::BufferedAmountLowThreshold() const
{
return mDataChannel->GetBufferedAmountLowThreshold();
}
NS_IMETHODIMP
nsDOMDataChannel::GetBufferedAmount(uint32_t* aBufferedAmount)
{
@ -220,6 +226,12 @@ nsDOMDataChannel::GetBufferedAmount(uint32_t* aBufferedAmount)
return NS_OK;
}
void
nsDOMDataChannel::SetBufferedAmountLowThreshold(uint32_t aThreshold)
{
mDataChannel->SetBufferedAmountLowThreshold(aThreshold);
}
NS_IMETHODIMP nsDOMDataChannel::GetBinaryType(nsAString & aBinaryType)
{
switch (mBinaryType) {
@ -468,6 +480,14 @@ nsDOMDataChannel::OnChannelClosed(nsISupports* aContext)
return OnSimpleEvent(aContext, NS_LITERAL_STRING("close"));
}
nsresult
nsDOMDataChannel::OnBufferLow(nsISupports* aContext)
{
LOG(("%p(%p): %s - Dispatching\n",this,(void*)mDataChannel,__FUNCTION__));
return OnSimpleEvent(aContext, NS_LITERAL_STRING("bufferedamountlow"));
}
void
nsDOMDataChannel::AppReady()
{

View File

@ -54,11 +54,14 @@ public:
bool Reliable() const;
mozilla::dom::RTCDataChannelState ReadyState() const;
uint32_t BufferedAmount() const;
uint32_t BufferedAmountLowThreshold() const;
void SetBufferedAmountLowThreshold(uint32_t aThreshold);
IMPL_EVENT_HANDLER(open)
IMPL_EVENT_HANDLER(error)
IMPL_EVENT_HANDLER(close)
// Uses XPIDL Close.
IMPL_EVENT_HANDLER(message)
IMPL_EVENT_HANDLER(bufferedamountlow)
mozilla::dom::RTCDataChannelType BinaryType() const
{
return static_cast<mozilla::dom::RTCDataChannelType>(
@ -97,6 +100,9 @@ public:
virtual nsresult
OnChannelClosed(nsISupports* aContext) override;
virtual nsresult
OnBufferLow(nsISupports* aContext) override;
virtual void
AppReady();

View File

@ -12,6 +12,7 @@
#include "nsError.h"
#include "nsIFile.h"
#include "nsNetCID.h"
#include "nsNetUtil.h"
#include "nsXPCOM.h"
#include "nsIDOMEventListener.h"

View File

@ -19,6 +19,7 @@
#include "nsTextFragment.h"
#include "nsThreadUtils.h"
using mozilla::dom::TreeOrderComparator;
using mozilla::dom::Animation;
nsAutoTArray<nsRefPtr<nsDOMMutationObserver>, 4>*

View File

@ -1532,7 +1532,8 @@ nsIDocument::nsIDocument()
mGetUserFontSetCalled(false),
mPostedFlushUserFontSet(false),
mPartID(0),
mDidFireDOMContentLoaded(true)
mDidFireDOMContentLoaded(true),
mUserHasInteracted(false)
{
SetInDocument();

View File

@ -1343,7 +1343,7 @@ nsFocusManager::SetFocusInner(nsIContent* aNewContent, int32_t aFlags,
nsCOMPtr<nsIDocShell> docShell = newWindow->GetDocShell();
nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
if (presShell)
if (presShell && presShell->DidInitialize())
ScrollIntoView(presShell, contentToFocus, aFlags);
}

View File

@ -14,6 +14,7 @@
#include "prenv.h"
#include "mozIApplication.h"
#include "nsDocShell.h"
#include "nsIDOMHTMLIFrameElement.h"
#include "nsIDOMHTMLFrameElement.h"
#include "nsIDOMMozBrowserFrame.h"

View File

@ -699,6 +699,7 @@ GK_ATOM(onblocked, "onblocked")
GK_ATOM(onblur, "onblur")
GK_ATOM(onbroadcast, "onbroadcast")
GK_ATOM(onbusy, "onbusy")
GK_ATOM(onbufferedamountlow, "onbufferedamountlow")
GK_ATOM(oncached, "oncached")
GK_ATOM(oncallschanged, "oncallschanged")
GK_ATOM(oncancel, "oncancel")

View File

@ -2602,6 +2602,16 @@ public:
void PropagateUseCounters(nsIDocument* aParentDocument);
void SetUserHasInteracted(bool aUserHasInteracted)
{
mUserHasInteracted = aUserHasInteracted;
}
bool UserHasInteracted()
{
return mUserHasInteracted;
}
protected:
bool GetUseCounter(mozilla::UseCounter aUseCounter)
{
@ -3007,6 +3017,9 @@ protected:
// Flags for whether we've notified our top-level "page" of a use counter
// for this child document.
std::bitset<mozilla::eUseCounter_Count> mNotifiedPageForUseCounter;
// Whether the user has interacted with the document or not:
bool mUserHasInteracted;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocument, NS_IDOCUMENT_IID)

View File

@ -16,6 +16,7 @@
#include "nsIProtocolHandler.h"
#include "nsIIOService.h"
#include "nsIExternalProtocolHandler.h"
#include "nsIURI.h"
#include "nsNetUtil.h"
#include "nsContentUtils.h"

View File

@ -1473,6 +1473,37 @@ nsObjectLoadingContent::CheckJavaCodebase()
return true;
}
bool
nsObjectLoadingContent::IsYoutubeEmbed()
{
nsCOMPtr<nsIContent> thisContent =
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
NS_ASSERTION(thisContent, "Must be an instance of content");
// We're only interested in switching out embed tags
if (!thisContent->NodeInfo()->Equals(nsGkAtoms::embed)) {
return false;
}
nsCOMPtr<nsIEffectiveTLDService> tldService =
do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
// If we can't analyze the URL, just pass on through.
if(!tldService) {
NS_WARNING("Could not get TLD service!");
return false;
}
nsAutoCString currentBaseDomain;
bool ok = NS_SUCCEEDED(tldService->GetBaseDomain(mURI, 0, currentBaseDomain));
if (!ok) {
NS_WARNING("Could not parse plugin domain!");
return false;
}
nsAutoCString domain("youtube.com");
if (StringEndsWith(domain, currentBaseDomain)) {
return true;
}
return false;
}
bool
nsObjectLoadingContent::CheckLoadPolicy(int16_t *aContentPolicy)
{
@ -2122,6 +2153,11 @@ nsObjectLoadingContent::LoadObject(bool aNotify,
return NS_OK;
}
// Check whether this is a youtube embed.
if (IsYoutubeEmbed()) {
Telemetry::Accumulate(Telemetry::YOUTUBE_EMBED_SEEN, 1);
}
//
// Security checks
//

View File

@ -519,6 +519,8 @@ class nsObjectLoadingContent : public nsImageLoadingContent
*/
nsPluginFrame* GetExistingFrame();
bool IsYoutubeEmbed();
// Helper class for SetupProtoChain
class SetupProtoChainRunner final : public nsIRunnable
{

View File

@ -31,6 +31,7 @@
#include "nsContentUtils.h"
#include "nsLWBrkCIID.h"
#include "nsIScriptElement.h"
#include "nsStubMutationObserver.h"
#include "nsAttrName.h"
#include "nsParserConstants.h"
#include "nsComputedDOMStyle.h"

View File

@ -503,6 +503,8 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
mouseEvent->mMessage != eMouseEnterIntoWidget &&
mouseEvent->mMessage != eMouseExitFromWidget) ||
aEvent->mClass == eWheelEventClass ||
aEvent->mClass == ePointerEventClass ||
aEvent->mClass == eTouchEventClass ||
aEvent->mClass == eKeyboardEventClass)) {
if (gMouseOrKeyboardEventCounter == 0) {
nsCOMPtr<nsIObserverService> obs =
@ -513,6 +515,20 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
}
}
++gMouseOrKeyboardEventCounter;
nsCOMPtr<nsINode> node = do_QueryInterface(aTargetContent);
if (node &&
(aEvent->mMessage == eKeyUp || aEvent->mMessage == eMouseUp ||
aEvent->mMessage == eWheel || aEvent->mMessage == eTouchEnd ||
aEvent->mMessage == ePointerUp)) {
nsIDocument* doc = node->OwnerDoc();
while (doc && !doc->UserHasInteracted()) {
doc->SetUserHasInteracted(true);
doc = nsContentUtils::IsChildOfSameType(doc) ?
doc->GetParentDocument() : nullptr;
}
}
}
WheelTransaction::OnEvent(aEvent);

View File

@ -1411,7 +1411,9 @@ MediaFormatReader::Seek(int64_t aTime, int64_t aUnused)
nsRefPtr<SeekPromise> p = mSeekPromise.Ensure(__func__);
AttemptSeek();
RefPtr<nsIRunnable> task(
NS_NewRunnableMethod(this, &MediaFormatReader::AttemptSeek));
OwnerThread()->Dispatch(task.forget());
return p;
}
@ -1420,6 +1422,13 @@ void
MediaFormatReader::AttemptSeek()
{
MOZ_ASSERT(OnTaskQueue());
if (mPendingSeekTime.isNothing()) {
return;
}
// An internal seek may be pending due to Seek queueing multiple tasks calling
// AttemptSeek ; we can ignore those by resetting any pending demuxer's seek.
mAudio.mSeekRequest.DisconnectIfExists();
mVideo.mSeekRequest.DisconnectIfExists();
if (HasVideo()) {
DoVideoSeek();
} else if (HasAudio()) {

View File

@ -18,6 +18,9 @@
#include "mozilla/SharedThreadPool.h"
#include "nsIRandomGenerator.h"
#include "nsIServiceManager.h"
#include "nsServiceManagerUtils.h"
#include "nsIConsoleService.h"
#include "nsThreadUtils.h"
#include <stdint.h>
@ -369,4 +372,98 @@ CreateFlushableMediaDecodeTaskQueue()
return queue.forget();
}
void
SimpleTimer::Cancel() {
if (mTimer) {
#ifdef DEBUG
nsCOMPtr<nsIEventTarget> target;
mTimer->GetTarget(getter_AddRefs(target));
nsCOMPtr<nsIThread> thread(do_QueryInterface(target));
MOZ_ASSERT(NS_GetCurrentThread() == thread);
#endif
mTimer->Cancel();
mTimer = nullptr;
}
mTask = nullptr;
}
NS_IMETHODIMP
SimpleTimer::Notify(nsITimer *timer) {
nsRefPtr<SimpleTimer> deathGrip(this);
if (mTask) {
mTask->Run();
mTask = nullptr;
}
return NS_OK;
}
nsresult
SimpleTimer::Init(nsIRunnable* aTask, uint32_t aTimeoutMs, nsIThread* aTarget)
{
nsresult rv;
// Get target thread first, so we don't have to cancel the timer if it fails.
nsCOMPtr<nsIThread> target;
if (aTarget) {
target = aTarget;
} else {
rv = NS_GetMainThread(getter_AddRefs(target));
if (NS_FAILED(rv)) {
return rv;
}
}
nsCOMPtr<nsITimer> timer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
if (NS_FAILED(rv)) {
return rv;
}
// Note: set target before InitWithCallback in case the timer fires before
// we change the event target.
rv = timer->SetTarget(aTarget);
if (NS_FAILED(rv)) {
timer->Cancel();
return rv;
}
rv = timer->InitWithCallback(this, aTimeoutMs, nsITimer::TYPE_ONE_SHOT);
if (NS_FAILED(rv)) {
return rv;
}
mTimer = timer.forget();
mTask = aTask;
return NS_OK;
}
NS_IMPL_ISUPPORTS(SimpleTimer, nsITimerCallback)
already_AddRefed<SimpleTimer>
SimpleTimer::Create(nsIRunnable* aTask, uint32_t aTimeoutMs, nsIThread* aTarget)
{
nsRefPtr<SimpleTimer> t(new SimpleTimer());
if (NS_FAILED(t->Init(aTask, aTimeoutMs, aTarget))) {
return nullptr;
}
return t.forget();
}
void
LogToBrowserConsole(const nsAString& aMsg)
{
if (!NS_IsMainThread()) {
nsAutoString msg(aMsg);
nsCOMPtr<nsIRunnable> task =
NS_NewRunnableFunction([msg]() { LogToBrowserConsole(msg); });
NS_DispatchToMainThread(task.forget(), NS_DISPATCH_NORMAL);
return;
}
nsCOMPtr<nsIConsoleService> console(
do_GetService("@mozilla.org/consoleservice;1"));
if (!console) {
NS_WARNING("Failed to log message to console.");
return;
}
nsAutoString msg(aMsg);
console->LogStringMessage(msg.get());
}
} // end namespace mozilla

View File

@ -22,6 +22,8 @@
#include "prtime.h"
#include "AudioSampleFormat.h"
#include "TimeUnits.h"
#include "nsITimer.h"
#include "nsCOMPtr.h"
using mozilla::CheckedInt64;
using mozilla::CheckedUint64;
@ -301,6 +303,32 @@ nsRefPtr<GenericPromise> InvokeUntil(Work aWork, Condition aCondition) {
return p.forget();
}
// Simple timer to run a runnable after a timeout.
class SimpleTimer : public nsITimerCallback
{
public:
NS_DECL_ISUPPORTS
// Create a new timer to run aTask after aTimeoutMs milliseconds
// on thread aTarget. If aTarget is null, task is run on the main thread.
static already_AddRefed<SimpleTimer> Create(nsIRunnable* aTask,
uint32_t aTimeoutMs,
nsIThread* aTarget = nullptr);
void Cancel();
NS_IMETHOD Notify(nsITimer *timer) override;
private:
virtual ~SimpleTimer() {}
nsresult Init(nsIRunnable* aTask, uint32_t aTimeoutMs, nsIThread* aTarget);
nsRefPtr<nsIRunnable> mTask;
nsCOMPtr<nsITimer> mTimer;
};
void
LogToBrowserConsole(const nsAString& aMsg);
} // end namespace mozilla
#endif

View File

@ -5,8 +5,6 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/EMEUtils.h"
#include "nsServiceManagerUtils.h"
#include "nsIConsoleService.h"
namespace mozilla {
@ -110,19 +108,6 @@ ParseKeySystem(const nsAString& aInputKeySystem,
return false;
}
void
LogToBrowserConsole(const nsAString& aMsg)
{
nsCOMPtr<nsIConsoleService> console(
do_GetService("@mozilla.org/consoleservice;1"));
if (!console) {
NS_WARNING("Failed to log message to console.");
return;
}
nsAutoString msg(aMsg);
console->LogStringMessage(msg.get());
}
void
ConstructKeySystem(const nsAString& aKeySystem,
const nsAString& aCDMVersion,

View File

@ -51,9 +51,6 @@ bool ParseKeySystem(const nsAString& aKeySystem,
nsAString& aOutKeySystem,
int32_t& aOutMinCDMVersion);
void
LogToBrowserConsole(const nsAString& aMsg);
void
ConstructKeySystem(const nsAString& aKeySystem,
const nsAString& aCDMVersion,

View File

@ -50,6 +50,7 @@ GMPVideoDecoderParent::GMPVideoDecoderParent(GMPContentParent* aPlugin)
, mCallback(nullptr)
, mVideoHost(this)
, mPluginId(aPlugin->GetPluginId())
, mFrameCount(0)
{
MOZ_ASSERT(mPlugin);
}
@ -157,6 +158,7 @@ GMPVideoDecoderParent::Decode(GMPUniquePtr<GMPVideoEncodedFrame> aInputFrame,
aRenderTimeMs)) {
return NS_ERROR_FAILURE;
}
mFrameCount++;
// Async IPC, we don't have access to a return value.
return NS_OK;
@ -180,14 +182,33 @@ GMPVideoDecoderParent::Reset()
mIsAwaitingResetComplete = true;
nsRefPtr<GMPVideoDecoderParent> self(this);
nsCOMPtr<nsIRunnable> task = NS_NewRunnableFunction([self]() -> void
{
LOGD(("GMPVideoDecoderParent[%p]::ResetCompleteTimeout() timed out waiting for ResetComplete", self.get()));
self->mResetCompleteTimeout = nullptr;
LogToBrowserConsole(NS_LITERAL_STRING("GMPVideoDecoderParent timed out waiting for ResetComplete()"));
});
CancelResetCompleteTimeout();
mResetCompleteTimeout = SimpleTimer::Create(task, 5000, mPlugin->GMPThread());
// Async IPC, we don't have access to a return value.
return NS_OK;
}
void
GMPVideoDecoderParent::CancelResetCompleteTimeout()
{
if (mResetCompleteTimeout) {
mResetCompleteTimeout->Cancel();
mResetCompleteTimeout = nullptr;
}
}
nsresult
GMPVideoDecoderParent::Drain()
{
LOGD(("GMPVideoDecoderParent[%p]::Drain()", this));
LOGD(("GMPVideoDecoderParent[%p]::Drain() frameCount=%d", this, mFrameCount));
if (!mIsOpen) {
NS_WARNING("Trying to use an dead GMP video decoder");
@ -280,8 +301,9 @@ GMPVideoDecoderParent::ActorDestroy(ActorDestroyReason aWhy)
bool
GMPVideoDecoderParent::RecvDecoded(const GMPVideoi420FrameData& aDecodedFrame)
{
LOGV(("GMPVideoDecoderParent[%p]::RecvDecoded() timestamp=%lld",
this, aDecodedFrame.mTimestamp()));
--mFrameCount;
LOGV(("GMPVideoDecoderParent[%p]::RecvDecoded() timestamp=%lld frameCount=%d",
this, aDecodedFrame.mTimestamp(), mFrameCount));
if (!mCallback) {
return false;
@ -345,8 +367,11 @@ GMPVideoDecoderParent::RecvInputDataExhausted()
bool
GMPVideoDecoderParent::RecvDrainComplete()
{
LOGD(("GMPVideoDecoderParent[%p]::RecvDrainComplete()", this));
LOGD(("GMPVideoDecoderParent[%p]::RecvDrainComplete() frameCount=%d", this, mFrameCount));
nsAutoString msg;
msg.AppendLiteral("GMPVideoDecoderParent::RecvDrainComplete() outstanding frames=");
msg.AppendInt(mFrameCount);
LogToBrowserConsole(msg);
if (!mCallback) {
return false;
}
@ -367,6 +392,8 @@ GMPVideoDecoderParent::RecvResetComplete()
{
LOGD(("GMPVideoDecoderParent[%p]::RecvResetComplete()", this));
CancelResetCompleteTimeout();
if (!mCallback) {
return false;
}
@ -375,6 +402,7 @@ GMPVideoDecoderParent::RecvResetComplete()
return true;
}
mIsAwaitingResetComplete = false;
mFrameCount = 0;
// Ignore any return code. It is OK for this to fail without killing the process.
mCallback->ResetComplete();
@ -457,7 +485,9 @@ GMPVideoDecoderParent::Recv__delete__()
void
GMPVideoDecoderParent::UnblockResetAndDrain()
{
LOGD(("GMPVideoDecoderParent[%p]::UnblockResetAndDrain()", this));
LOGD(("GMPVideoDecoderParent[%p]::UnblockResetAndDrain() "
"awaitingResetComplete=%d awaitingDrainComplete=%d",
this, mIsAwaitingResetComplete, mIsAwaitingDrainComplete));
if (!mCallback) {
MOZ_ASSERT(!mIsAwaitingResetComplete);
@ -472,6 +502,7 @@ GMPVideoDecoderParent::UnblockResetAndDrain()
mIsAwaitingDrainComplete = false;
mCallback->DrainComplete();
}
CancelResetCompleteTimeout();
}
} // namespace gmp

View File

@ -14,6 +14,7 @@
#include "GMPUtils.h"
#include "GMPVideoHost.h"
#include "GMPVideoDecoderProxy.h"
#include "VideoUtils.h"
namespace mozilla {
namespace gmp {
@ -80,6 +81,7 @@ private:
virtual bool Recv__delete__() override;
void UnblockResetAndDrain();
void CancelResetCompleteTimeout();
bool mIsOpen;
bool mShuttingDown;
@ -90,6 +92,8 @@ private:
GMPVideoDecoderCallbackProxy* mCallback;
GMPVideoHostImpl mVideoHost;
const uint32_t mPluginId;
int32_t mFrameCount;
nsRefPtr<SimpleTimer> mResetCompleteTimeout;
};
} // namespace gmp

View File

@ -309,7 +309,7 @@ MediaSourceTrackDemuxer::Reset()
nsRefPtr<MediaSourceTrackDemuxer> self = this;
nsCOMPtr<nsIRunnable> task =
NS_NewRunnableFunction([self] () {
self->mManager->Seek(self->mType, TimeUnit());
self->mManager->Seek(self->mType, TimeUnit(), TimeUnit());
{
MonitorAutoLock mon(self->mMonitor);
self->mNextRandomAccessPoint =
@ -364,7 +364,8 @@ MediaSourceTrackDemuxer::DoSeek(media::TimeUnit aTime)
return SeekPromise::CreateAndReject(DemuxerFailureReason::WAITING_FOR_DATA,
__func__);
}
TimeUnit seekTime = mManager->Seek(mType, aTime);
TimeUnit seekTime =
mManager->Seek(mType, aTime, TimeUnit::FromMicroseconds(EOS_FUZZ_US));
{
MonitorAutoLock mon(mMonitor);
mNextRandomAccessPoint = mManager->GetNextRandomAccessPoint(mType);

View File

@ -1660,11 +1660,14 @@ TrackBuffersManager::InsertFrames(TrackBuffer& aSamples,
}
// Adjust our demuxing index if necessary.
if (trackBuffer.mNextGetSampleIndex.isSome() &&
(trackBuffer.mNextInsertionIndex.ref() < trackBuffer.mNextGetSampleIndex.ref() ||
(trackBuffer.mNextInsertionIndex.ref() == trackBuffer.mNextGetSampleIndex.ref() &&
aIntervals.GetEnd() < trackBuffer.mNextSampleTime))) {
trackBuffer.mNextGetSampleIndex.ref() += aSamples.Length();
if (trackBuffer.mNextGetSampleIndex.isSome()) {
if (trackBuffer.mNextInsertionIndex.ref() == trackBuffer.mNextGetSampleIndex.ref() &&
aIntervals.GetEnd() >= trackBuffer.mNextSampleTime) {
MSE_DEBUG("Next sample to be played got overwritten");
trackBuffer.mNextGetSampleIndex.reset();
} else if (trackBuffer.mNextInsertionIndex.ref() <= trackBuffer.mNextGetSampleIndex.ref()) {
trackBuffer.mNextGetSampleIndex.ref() += aSamples.Length();
}
}
TrackBuffer& data = trackBuffer.mBuffers.LastElement();
@ -1890,36 +1893,82 @@ TrackBuffersManager::GetTrackBuffer(TrackInfo::TrackType aTrack)
return GetTracksData(aTrack).mBuffers.LastElement();
}
uint32_t TrackBuffersManager::FindSampleIndex(const TrackBuffer& aTrackBuffer,
const TimeInterval& aInterval)
{
TimeUnit target = aInterval.mStart - aInterval.mFuzz;
for (uint32_t i = 0; i < aTrackBuffer.Length(); i++) {
const nsRefPtr<MediaRawData>& sample = aTrackBuffer[i];
if (sample->mTime >= target.ToMicroseconds() ||
sample->GetEndTime() > target.ToMicroseconds()) {
return i;
}
}
NS_ASSERTION(false, "FindSampleIndex called with invalid arguments");
return 0;
}
TimeUnit
TrackBuffersManager::Seek(TrackInfo::TrackType aTrack,
const TimeUnit& aTime)
const TimeUnit& aTime,
const TimeUnit& aFuzz)
{
MOZ_ASSERT(OnTaskQueue());
auto& trackBuffer = GetTracksData(aTrack);
const TrackBuffersManager::TrackBuffer& track = GetTrackBuffer(aTrack);
TimeUnit lastKeyFrameTime;
if (!track.Length()) {
// This a reset. It will be followed by another valid seek.
trackBuffer.mNextGetSampleIndex = Some(uint32_t(0));
trackBuffer.mNextSampleTimecode = TimeUnit();
trackBuffer.mNextSampleTime = TimeUnit();
return TimeUnit();
}
uint32_t i = 0;
if (aTime != TimeUnit()) {
// Determine the interval of samples we're attempting to seek to.
TimeIntervals buffered = trackBuffer.mBufferedRanges;
TimeIntervals::IndexType index = buffered.Find(aTime);
buffered.SetFuzz(aFuzz);
index = buffered.Find(aTime);
MOZ_ASSERT(index != TimeIntervals::NoIndex);
TimeInterval target = buffered[index];
i = FindSampleIndex(track, target);
}
Maybe<TimeUnit> lastKeyFrameTime;
TimeUnit lastKeyFrameTimecode;
uint32_t lastKeyFrameIndex = 0;
for (uint32_t i = 0; i < track.Length(); i++) {
for (; i < track.Length(); i++) {
const nsRefPtr<MediaRawData>& sample = track[i];
TimeUnit sampleTime = TimeUnit::FromMicroseconds(sample->mTime);
if (sampleTime > aTime) {
if (sampleTime > aTime && lastKeyFrameTime.isSome()) {
break;
}
if (sample->mKeyframe) {
lastKeyFrameTimecode = TimeUnit::FromMicroseconds(sample->mTimecode);
lastKeyFrameTime = sampleTime;
lastKeyFrameTime = Some(sampleTime);
lastKeyFrameIndex = i;
}
if (sampleTime == aTime) {
if (sampleTime == aTime ||
(sampleTime > aTime && lastKeyFrameTime.isSome())) {
break;
}
}
MSE_DEBUG("Keyframe %s found at %lld",
lastKeyFrameTime.isSome() ? "" : "not",
lastKeyFrameTime.refOr(TimeUnit()).ToMicroseconds());
trackBuffer.mNextGetSampleIndex = Some(lastKeyFrameIndex);
trackBuffer.mNextSampleTimecode = lastKeyFrameTimecode;
trackBuffer.mNextSampleTime = lastKeyFrameTime;
trackBuffer.mNextSampleTime = lastKeyFrameTime.refOr(TimeUnit());
return lastKeyFrameTime;
return lastKeyFrameTime.refOr(TimeUnit());
}
uint32_t

View File

@ -88,7 +88,8 @@ public:
return mEnded;
}
media::TimeUnit Seek(TrackInfo::TrackType aTrack,
const media::TimeUnit& aTime);
const media::TimeUnit& aTime,
const media::TimeUnit& aFuzz);
uint32_t SkipToNextRandomAccessPoint(TrackInfo::TrackType aTrack,
const media::TimeUnit& aTimeThreadshold,
bool& aFound);
@ -262,6 +263,8 @@ private:
nsRefPtr<SharedTrackInfo> mLastInfo;
// If set, position of the next sample to be retrieved by GetSample().
// If the position is equal to the TrackBuffer's length, it indicates that
// we've reached EOS.
Maybe<uint32_t> mNextGetSampleIndex;
// Approximation of the next sample's decode timestamp.
media::TimeUnit mNextSampleTimecode;
@ -290,6 +293,9 @@ private:
void RemoveFrames(const media::TimeIntervals& aIntervals,
TrackData& aTrackData,
uint32_t aStartIndex);
// Find index of sample. Return a negative value if not found.
uint32_t FindSampleIndex(const TrackBuffer& aTrackBuffer,
const media::TimeInterval& aInterval);
void UpdateBufferedRanges();
void RejectProcessing(nsresult aRejectValue, const char* aName);
void ResolveProcessing(bool aResolveValue, const char* aName);

View File

@ -19,7 +19,6 @@
#include "nsPromiseFlatString.h"
#include <jni.h>
#include <string.h>
using namespace mozilla;
using namespace mozilla::gl;
@ -34,10 +33,21 @@ namespace mozilla {
NS_WARNING("callback not set"); \
}
static const char* TranslateMimeType(const nsACString& aMimeType)
{
if (aMimeType.EqualsLiteral("video/webm; codecs=vp8")) {
return "video/x-vnd.on2.vp8";
} else if (aMimeType.EqualsLiteral("video/webm; codecs=vp9")) {
return "video/x-vnd.on2.vp9";
}
return PromiseFlatCString(aMimeType).get();
}
static MediaCodec::LocalRef CreateDecoder(const nsACString& aMimeType)
{
MediaCodec::LocalRef codec;
NS_ENSURE_SUCCESS(MediaCodec::CreateDecoderByType(PromiseFlatCString(aMimeType).get(), &codec), nullptr);
NS_ENSURE_SUCCESS(MediaCodec::CreateDecoderByType(TranslateMimeType(aMimeType),
&codec), nullptr);
return codec;
}
@ -76,8 +86,10 @@ public:
}
bool WantCopy() {
// Allocating a texture is incredibly slow on PowerVR
return mGLContext->Vendor() != GLVendor::Imagination;
// Allocating a texture is incredibly slow on PowerVR and may fail on
// emulators, see bug 1190379.
return mGLContext->Vendor() != GLVendor::Imagination &&
mGLContext->Renderer() != GLRenderer::AndroidEmulator;
}
EGLImage CopySurface(layers::Image* img) {
@ -287,7 +299,7 @@ AndroidDecoderModule::CreateVideoDecoder(
MediaFormat::LocalRef format;
NS_ENSURE_SUCCESS(MediaFormat::CreateVideoFormat(
aConfig.mMimeType,
TranslateMimeType(aConfig.mMimeType),
aConfig.mDisplay.width,
aConfig.mDisplay.height,
&format), nullptr);

View File

@ -168,9 +168,24 @@ var commandsCheckDataChannel = [
}
];
var commandsCheckLargeXfer = [
function SEND_BIG_BUFFER(test) {
var size = 512*1024; // SCTP internal buffer is 256K, so we'll have ~256K queued
var buffer = new ArrayBuffer(size);
// note: type received is always blob for binary data
var options = {};
options.bufferedAmountLowThreshold = 64*1024;
return test.send(buffer, options).then(result => {
ok(result.data instanceof Blob, "Received data is of instance Blob");
is(result.data.size, size, "Received data has the correct size.");
});
},
];
function addInitialDataChannel(chain) {
chain.insertBefore('PC_LOCAL_CREATE_OFFER', commandsCreateDataChannel);
chain.insertBefore('PC_LOCAL_CHECK_MEDIA_TRACKS', commandsWaitForDataChannel);
chain.removeAfter('PC_REMOTE_CHECK_ICE_CONNECTIONS');
chain.append(commandsCheckLargeXfer);
chain.append(commandsCheckDataChannel);
}

View File

@ -214,11 +214,21 @@ PeerConnectionTest.prototype.send = function(data, options) {
this.pcLocal.dataChannels[this.pcLocal.dataChannels.length - 1];
var target = options.targetChannel ||
this.pcRemote.dataChannels[this.pcRemote.dataChannels.length - 1];
var bufferedamount = options.bufferedAmountLowThreshold || 0;
var bufferlow_fired = true; // to make testing later easier
if (bufferedamount != 0) {
source.bufferedAmountLowThreshold = bufferedamount;
bufferlow_fired = false;
source.onbufferedamountlow = function() {
bufferlow_fired = true;
};
}
return new Promise(resolve => {
// Register event handler for the target channel
target.onmessage = e => {
resolve({ channel: target, data: e.data });
target.onmessage = e => {
ok(bufferlow_fired, "bufferedamountlow event fired");
resolve({ channel: target, data: e.data });
};
source.send(data);
@ -563,6 +573,7 @@ function DataChannelWrapper(dataChannel, peerConnectionWrapper) {
createOneShotEventWrapper(this, this._channel, 'close');
createOneShotEventWrapper(this, this._channel, 'error');
createOneShotEventWrapper(this, this._channel, 'message');
createOneShotEventWrapper(this, this._channel, 'bufferedamountlow');
this.opened = timerGuard(new Promise(resolve => {
this._channel.onopen = () => {
@ -640,6 +651,16 @@ DataChannelWrapper.prototype = {
return this._channel.readyState;
},
/**
* Sets the bufferlowthreshold of the channel
*
* @param {integer} amoutn
* The new threshold for the chanel
*/
set bufferedAmountLowThreshold(amount) {
this._channel.bufferedAmountLowThreshold = amount;
},
/**
* Close the data channel
*/

View File

@ -289,7 +289,7 @@ WebMDemuxer::ReadMetadata()
return NS_ERROR_FAILURE;
}
int type = nestegg_track_type(mContext, track);
if (type == NESTEGG_TRACK_VIDEO) {
if (type == NESTEGG_TRACK_VIDEO && !mHasVideo) {
nestegg_video_params params;
r = nestegg_track_video_params(mContext, track, &params);
if (r == -1) {
@ -364,7 +364,7 @@ WebMDemuxer::ReadMetadata()
if (!r) {
mInfo.mVideo.mDuration = media::TimeUnit::FromNanoseconds(duration).ToMicroseconds();
}
} else if (type == NESTEGG_TRACK_AUDIO) {
} else if (type == NESTEGG_TRACK_AUDIO && !mHasAudio) {
nestegg_audio_params params;
r = nestegg_track_audio_params(mContext, track, &params);
if (r == -1) {

View File

@ -209,12 +209,20 @@ DoContentSecurityChecks(nsIURI* aURI, nsILoadInfo* aLoadInfo)
}
case nsIContentPolicy::TYPE_WEBSOCKET:
case nsIContentPolicy::TYPE_CSP_REPORT:
case nsIContentPolicy::TYPE_XSLT: {
case nsIContentPolicy::TYPE_CSP_REPORT: {
MOZ_ASSERT(false, "contentPolicyType not supported yet");
break;
}
case nsIContentPolicy::TYPE_XSLT: {
mimeTypeGuess = NS_LITERAL_CSTRING("application/xml");
requestingContext = aLoadInfo->LoadingNode();
MOZ_ASSERT(!requestingContext ||
requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
"type_xslt requires requestingContext of type Document");
break;
}
case nsIContentPolicy::TYPE_BEACON: {
mimeTypeGuess = EmptyCString();
requestingContext = aLoadInfo->LoadingNode();

View File

@ -57,6 +57,13 @@ public:
bool operator!=(const nsSMILKeySpline& aOther) const {
return !(*this == aOther);
}
int32_t Compare(const nsSMILKeySpline& aRhs) const {
if (mX1 != aRhs.mX1) return mX1 < aRhs.mX1 ? -1 : 1;
if (mY1 != aRhs.mY1) return mY1 < aRhs.mY1 ? -1 : 1;
if (mX2 != aRhs.mX2) return mX2 < aRhs.mX2 ? -1 : 1;
if (mY2 != aRhs.mY2) return mY2 < aRhs.mY2 ? -1 : 1;
return 0;
}
private:
void

View File

@ -49,6 +49,8 @@ const kSameTab = "same tab";
const kNewWin = "new window";
const kNewTab = "new tab";
SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunload", false]]});
requestLongerTimeout(2);
// The following "matrices" represent the result of content attempting to

View File

@ -21,11 +21,13 @@ interface DataChannel : EventTarget
readonly attribute boolean reliable;
readonly attribute RTCDataChannelState readyState;
readonly attribute unsigned long bufferedAmount;
attribute unsigned long bufferedAmountLowThreshold;
attribute EventHandler onopen;
attribute EventHandler onerror;
attribute EventHandler onclose;
void close();
attribute EventHandler onmessage;
attribute EventHandler onbufferedamountlow;
attribute RTCDataChannelType binaryType;
[Throws]
void send(DOMString data);

View File

@ -392,6 +392,12 @@ partial interface Document {
void removeAnonymousContent(AnonymousContent aContent);
};
// Extension to give chrome JS the ability to determine whether
// the user has interacted with the document or not.
partial interface Document {
[ChromeOnly] readonly attribute boolean userHasInteracted;
};
Document implements XPathEvaluator;
Document implements GlobalEventHandlers;
Document implements TouchEventHandlers;

View File

@ -0,0 +1,25 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* https://w3c.github.io/web-animations/#the-compositeoperation-enumeration
* https://w3c.github.io/web-animations/#the-keyframe-dictionary
* https://w3c.github.io/web-animations/#the-computedkeyframe-dictionary
*
* Copyright © 2015 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
enum CompositeOperation { "replace", "add", "accumulate" };
dictionary Keyframe {
double? offset = null;
DOMString easing = "linear";
CompositeOperation? composite = null;
};
dictionary ComputedKeyframe : Keyframe {
double computedOffset;
};

View File

@ -19,5 +19,8 @@ interface KeyframeEffectReadOnly : AnimationEffectReadOnly {
// readonly attribute CompositeOperation composite;
// readonly attribute DOMString spacing;
// KeyframeEffect clone();
// sequence<ComputedKeyframe> getFrames ();
// We use object instead of ComputedKeyframe so that we can put the
// property-value pairs on the object.
[Throws] sequence<object> getFrames();
};

View File

@ -274,6 +274,7 @@ WEBIDL_FILES = [
'KeyAlgorithm.webidl',
'KeyboardEvent.webidl',
'KeyEvent.webidl',
'Keyframe.webidl',
'KeyframeEffect.webidl',
'KillSwitch.webidl',
'LegacyQueryInterface.webidl',

View File

@ -575,6 +575,13 @@ private:
return true;
}
NS_IMETHOD Cancel() override
{
// We need to run regardless.
Run();
return WorkerRunnable::Cancel();
}
virtual void
PostRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate, bool aRunResult)
override
@ -1230,6 +1237,13 @@ private:
return true;
}
NS_IMETHOD Cancel() override
{
// We need to run regardless.
Run();
return WorkerRunnable::Cancel();
}
};
class UpdateRuntimeOptionsRunnable final : public WorkerControlRunnable
@ -3823,6 +3837,7 @@ WorkerPrivate::WorkerPrivate(JSContext* aCx,
, mRunningExpiredTimeouts(false)
, mCloseHandlerStarted(false)
, mCloseHandlerFinished(false)
, mPendingEventQueueClearing(false)
, mMemoryReporterRunning(false)
, mBlockedForMemoryReporter(false)
, mCancelAllPendingRunnables(false)
@ -4651,6 +4666,7 @@ WorkerPrivate::ScheduleDeletion(WorkerRanOrNot aRanOrNot)
AssertIsOnWorkerThread();
MOZ_ASSERT(mChildWorkers.IsEmpty());
MOZ_ASSERT(mSyncLoopStack.IsEmpty());
MOZ_ASSERT(!mPendingEventQueueClearing);
ClearMainEventQueue(aRanOrNot);
#ifdef DEBUG
@ -4881,6 +4897,7 @@ WorkerPrivate::ClearMainEventQueue(WorkerRanOrNot aRanOrNot)
{
AssertIsOnWorkerThread();
MOZ_ASSERT(!mSyncLoopStack.Length());
MOZ_ASSERT(!mCancelAllPendingRunnables);
mCancelAllPendingRunnables = true;
@ -5243,6 +5260,11 @@ WorkerPrivate::DestroySyncLoop(uint32_t aLoopIndex, nsIThreadInternal* aThread)
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(aThread->PopEventQueue(nestedEventTarget)));
if (!mSyncLoopStack.Length() && mPendingEventQueueClearing) {
ClearMainEventQueue(WorkerRan);
mPendingEventQueueClearing = false;
}
return result;
}
@ -5509,7 +5531,13 @@ WorkerPrivate::NotifyInternal(JSContext* aCx, Status aStatus)
// If this is the first time our status has changed then we need to clear the
// main event queue.
if (previousStatus == Running) {
ClearMainEventQueue(WorkerRan);
// NB: If we're in a sync loop, we can't clear the queue immediately,
// because this is the wrong queue. So we have to defer it until later.
if (mSyncLoopStack.Length()) {
mPendingEventQueueClearing = true;
} else {
ClearMainEventQueue(WorkerRan);
}
}
// If we've run the close handler, we don't need to do anything else.

Some files were not shown because too many files have changed in this diff Show More