зеркало из https://github.com/mozilla/gecko-dev.git
merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
Коммит
c3c9e7c565
|
@ -83,6 +83,7 @@ browser/components/tabview/**
|
|||
browser/components/translation/**
|
||||
browser/components/uitour/**
|
||||
browser/extensions/pdfjs/**
|
||||
browser/extensions/pocket/content/panels/js/vendor/**
|
||||
browser/extensions/shumway/**
|
||||
browser/fuel/**
|
||||
browser/locales/**
|
||||
|
|
|
@ -360,11 +360,11 @@ pref("browser.safebrowsing.provider.google.lists", "goog-badbinurl-shavar,goog-d
|
|||
pref("browser.safebrowsing.provider.google.updateURL", "https://safebrowsing.google.com/safebrowsing/downloads?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2&key=%GOOGLE_API_KEY%");
|
||||
pref("browser.safebrowsing.provider.google.gethashURL", "https://safebrowsing.google.com/safebrowsing/gethash?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2");
|
||||
pref("browser.safebrowsing.provider.google.reportURL", "https://safebrowsing.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
|
||||
pref("browser.safebrowsing.provider.google.appRepURL", "https://sb-ssl.google.com/safebrowsing/clientreport/download?key=%GOOGLE_API_KEY%");
|
||||
|
||||
pref("browser.safebrowsing.reportPhishMistakeURL", "https://%LOCALE%.phish-error.mozilla.com/?hl=%LOCALE%&url=");
|
||||
pref("browser.safebrowsing.reportPhishURL", "https://%LOCALE%.phish-report.mozilla.com/?hl=%LOCALE%&url=");
|
||||
pref("browser.safebrowsing.reportMalwareMistakeURL", "https://%LOCALE%.malware-error.mozilla.com/?hl=%LOCALE%&url=");
|
||||
pref("browser.safebrowsing.appRepURL", "https://sb-ssl.google.com/safebrowsing/clientreport/download?key=%GOOGLE_API_KEY%");
|
||||
|
||||
pref("browser.safebrowsing.id", "Firefox");
|
||||
|
||||
|
|
|
@ -64,9 +64,9 @@ function toHexString(data) {
|
|||
}
|
||||
let hexString = "";
|
||||
if (typeof data === "string") {
|
||||
hexString = [toHexChar(data.charCodeAt(i)) for (i in data)].join("");
|
||||
hexString = Array.from(data, (c, i) => toHexChar(data.charCodeAt(i))).join("");
|
||||
} else if (typeof data === "array") {
|
||||
hexString = [toHexChar(data[i]) for (i in data)].join("");
|
||||
hexString = data.map(toHexChar).join("");
|
||||
}
|
||||
return hexString;
|
||||
}
|
||||
|
@ -387,7 +387,7 @@ this.PersistentDataBlock = {
|
|||
partition = _partition;
|
||||
return partition.setPosition(DIGEST_OFFSET, OS.File.POS_START);
|
||||
}).then(() => {
|
||||
return partition.write(new Uint8Array([digest.calculated.charCodeAt(i) for (i in digest.calculated)]));
|
||||
return partition.write(new Uint8Array(Array.from(digest.calculated, (c, i) => digest.calculated.charCodeAt(i))));
|
||||
}).then(bytesWrittenLength => {
|
||||
if (bytesWrittenLength != DIGEST_SIZE_BYTES) {
|
||||
log("_computeAndWriteDigest: Error writting digest to partition!. Expected: " + DIGEST_SIZE_BYTES + " Written: " + bytesWrittenLength);
|
||||
|
|
|
@ -32,9 +32,9 @@ function toHexString(data) {
|
|||
}
|
||||
let hexString = "";
|
||||
if (typeof data === "string") {
|
||||
hexString = [toHexChar(data.charCodeAt(i)) for (i in data)].join("");
|
||||
hexString = Array.from(data, (c, i) => toHexChar(data.charCodeAt(i))).join("");
|
||||
} else if (typeof data === "array") {
|
||||
hexString = [toHexChar(data[i]) for (i in data)].join("");
|
||||
hexString = data.map(toHexChar).join("");
|
||||
}
|
||||
return hexString;
|
||||
}
|
||||
|
|
|
@ -958,11 +958,12 @@ pref("browser.safebrowsing.provider.google.lists", "goog-badbinurl-shavar,goog-d
|
|||
pref("browser.safebrowsing.provider.google.updateURL", "https://safebrowsing.google.com/safebrowsing/downloads?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2&key=%GOOGLE_API_KEY%");
|
||||
pref("browser.safebrowsing.provider.google.gethashURL", "https://safebrowsing.google.com/safebrowsing/gethash?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2");
|
||||
pref("browser.safebrowsing.provider.google.reportURL", "https://safebrowsing.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
|
||||
pref("browser.safebrowsing.provider.google.appRepURL", "https://sb-ssl.google.com/safebrowsing/clientreport/download?key=%GOOGLE_API_KEY%");
|
||||
|
||||
pref("browser.safebrowsing.reportPhishMistakeURL", "https://%LOCALE%.phish-error.mozilla.com/?hl=%LOCALE%&url=");
|
||||
pref("browser.safebrowsing.reportPhishURL", "https://%LOCALE%.phish-report.mozilla.com/?hl=%LOCALE%&url=");
|
||||
pref("browser.safebrowsing.reportMalwareMistakeURL", "https://%LOCALE%.malware-error.mozilla.com/?hl=%LOCALE%&url=");
|
||||
pref("browser.safebrowsing.appRepURL", "https://sb-ssl.google.com/safebrowsing/clientreport/download?key=%GOOGLE_API_KEY%");
|
||||
|
||||
#ifdef MOZILLA_OFFICIAL
|
||||
// Normally the "client ID" sent in updates is appinfo.name, but for
|
||||
// official Firefox releases from Mozilla we use a special identifier.
|
||||
|
@ -1576,11 +1577,9 @@ pref("browser.tabs.crashReporting.email", "");
|
|||
pref("layers.async-pan-zoom.enabled", true);
|
||||
#endif
|
||||
|
||||
#ifdef E10S_TESTING_ONLY
|
||||
// Enable e10s add-on interposition by default.
|
||||
pref("extensions.interposition.enabled", true);
|
||||
pref("extensions.interposition.prefetching", true);
|
||||
#endif
|
||||
|
||||
pref("browser.defaultbrowser.notificationbar", false);
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ var gGrid = {
|
|||
}
|
||||
|
||||
// Create cells.
|
||||
let cells = [new Cell(this, cell) for (cell of fragment.childNodes)];
|
||||
let cells = Array.from(fragment.childNodes, (cell) => new Cell(this, cell));
|
||||
|
||||
// Fetch links.
|
||||
let links = gLinks.getLinks();
|
||||
|
|
|
@ -336,14 +336,18 @@ nsContextMenu.prototype = {
|
|||
this.showItem("context-markpageMenu", enablePageMarks && markProviders.length > SocialMarks.MENU_LIMIT);
|
||||
let enablePageMarkItems = enablePageMarks && markProviders.length <= SocialMarks.MENU_LIMIT;
|
||||
let linkmenus = document.getElementsByClassName("context-markpage");
|
||||
[m.hidden = !enablePageMarkItems for (m of linkmenus)];
|
||||
for (let m of linkmenus) {
|
||||
m.hidden = !enablePageMarkItems;
|
||||
}
|
||||
|
||||
let enableLinkMarks = markProviders.length > 0 &&
|
||||
((this.onLink && !this.onMailtoLink) || this.onPlainTextLink);
|
||||
this.showItem("context-marklinkMenu", enableLinkMarks && markProviders.length > SocialMarks.MENU_LIMIT);
|
||||
let enableLinkMarkItems = enableLinkMarks && markProviders.length <= SocialMarks.MENU_LIMIT;
|
||||
linkmenus = document.getElementsByClassName("context-marklink");
|
||||
[m.hidden = !enableLinkMarkItems for (m of linkmenus)];
|
||||
for (let m of linkmenus) {
|
||||
m.hidden = !enableLinkMarkItems;
|
||||
}
|
||||
|
||||
// SocialShare
|
||||
let shareButton = SocialShare.shareButton;
|
||||
|
|
|
@ -105,9 +105,6 @@ static RedirEntry kRedirMap[] = {
|
|||
nsIAboutModule::ALLOW_SCRIPT },
|
||||
{ "customizing", "chrome://browser/content/customizableui/aboutCustomizing.xul",
|
||||
nsIAboutModule::ALLOW_SCRIPT },
|
||||
{
|
||||
"debugging", "chrome://devtools/content/aboutdebugging/aboutdebugging.xhtml",
|
||||
nsIAboutModule::ALLOW_SCRIPT },
|
||||
{ "loopconversation", "chrome://loop/content/panels/conversation.html",
|
||||
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
|
||||
nsIAboutModule::ALLOW_SCRIPT |
|
||||
|
|
|
@ -109,7 +109,6 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = {
|
|||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "healthreport", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||
#endif
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "customizing", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "debugging", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "looppanel", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "loopconversation", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "reader", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||
|
|
|
@ -3352,7 +3352,7 @@ this.CustomizableUI = {
|
|||
* being affected.
|
||||
*/
|
||||
get areas() {
|
||||
return [area for ([area, props] of gAreas)];
|
||||
return [...gAreas.keys()];
|
||||
},
|
||||
/**
|
||||
* Check what kind of area (toolbar or menu panel) an area is. This is
|
||||
|
@ -3754,7 +3754,7 @@ function WidgetGroupWrapper(aWidget) {
|
|||
if (!buildAreas) {
|
||||
return [];
|
||||
}
|
||||
return [this.forWindow(node.ownerDocument.defaultView) for (node of buildAreas)];
|
||||
return Array.from(buildAreas, (node) => this.forWindow(node.ownerDocument.defaultView));
|
||||
});
|
||||
|
||||
this.__defineGetter__("areaType", function() {
|
||||
|
@ -3865,7 +3865,7 @@ function XULWidgetGroupWrapper(aWidgetId) {
|
|||
});
|
||||
|
||||
this.__defineGetter__("instances", function() {
|
||||
return [this.forWindow(win) for ([win,] of gBuildWindows)];
|
||||
return Array.from(gBuildWindows, ([win,]) => this.forWindow(win));
|
||||
});
|
||||
|
||||
Object.freeze(this);
|
||||
|
|
|
@ -92,7 +92,7 @@ var PanelWideWidgetTracker = {
|
|||
return;
|
||||
}
|
||||
this.adjusting = true;
|
||||
let widgetsAffected = [w for (w of gPanelPlacements) if (gWideWidgets.has(w))];
|
||||
let widgetsAffected = gPanelPlacements.filter((w) => gWideWidgets.has(w));
|
||||
// If we're moving the wide widgets forwards (down/to the right in the panel)
|
||||
// we want to start with the last widgets. Otherwise we move widgets over other wide
|
||||
// widgets, which might mess up their order. Likewise, if moving backwards we should start with
|
||||
|
|
|
@ -79,8 +79,9 @@
|
|||
}
|
||||
|
||||
// pass the current set of children for comparison with placements:
|
||||
let children = [node.id for (node of this.childNodes)
|
||||
if (node.getAttribute("skipintoolbarset") != "true" && node.id)];
|
||||
let children = Array.from(this.childNodes)
|
||||
.filter(node => node.getAttribute("skipintoolbarset") != "true" && node.id)
|
||||
.map(node => node.id);
|
||||
CustomizableUI.registerToolbarNode(this, children);
|
||||
]]></body>
|
||||
</method>
|
||||
|
@ -204,7 +205,7 @@
|
|||
let oldIds = CustomizableUI.getWidgetIdsInArea(this.id);
|
||||
|
||||
// Get a list of items only in the new list
|
||||
let newIds = [id for (id of newVal) if (oldIds.indexOf(id) == -1)];
|
||||
let newIds = newVal.filter(id => oldIds.indexOf(id) == -1);
|
||||
CustomizableUI.beginBatchUpdate();
|
||||
try {
|
||||
for (let newId of newIds) {
|
||||
|
@ -225,7 +226,7 @@
|
|||
}
|
||||
|
||||
let currentIds = this.currentSet.split(',');
|
||||
let removedIds = [id for (id of currentIds) if (newIds.indexOf(id) == -1 && newVal.indexOf(id) == -1)];
|
||||
let removedIds = currentIds.filter(id => newIds.indexOf(id) == -1 && newVal.indexOf(id) == -1);
|
||||
for (let removedId of removedIds) {
|
||||
CustomizableUI.removeWidgetFromArea(removedId);
|
||||
}
|
||||
|
@ -585,7 +586,7 @@
|
|||
</property>
|
||||
<property name="currentSet">
|
||||
<getter><![CDATA[
|
||||
return [node.id for (node of this.children)].join(',');
|
||||
return Array.from(this.children, node => node.id).join(",");
|
||||
]]></getter>
|
||||
<setter><![CDATA[
|
||||
let v = val.split(',');
|
||||
|
|
|
@ -86,7 +86,7 @@ add_task(function() {
|
|||
|
||||
function checkAbstractAndRealPlacements(aNode, aExpectedPlacements) {
|
||||
assertAreaPlacements(kToolbarName, aExpectedPlacements);
|
||||
let physicalWidgetIds = [node.id for (node of aNode.childNodes)];
|
||||
let physicalWidgetIds = Array.from(aNode.childNodes, (node) => node.id);
|
||||
placementArraysEqual(aNode.id, physicalWidgetIds, aExpectedPlacements);
|
||||
}
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ function getHash(aStr) {
|
|||
|
||||
// convert the binary hash data to a hex string.
|
||||
let binary = hasher.finish(false);
|
||||
return [toHexString(binary.charCodeAt(i)) for (i in binary)].join("").toLowerCase();
|
||||
return Array.from(binary, (c, i) => toHexString(binary.charCodeAt(i))).join("").toLowerCase();
|
||||
}
|
||||
|
||||
function Bookmarks(aProfileFolder) {
|
||||
|
|
|
@ -61,7 +61,7 @@ function sorter(a, b) {
|
|||
|
||||
Object.defineProperty(FirefoxProfileMigrator.prototype, "sourceProfiles", {
|
||||
get: function() {
|
||||
return [{id: x, name: x} for (x of this._getAllProfiles().keys())].sort(sorter);
|
||||
return this._getAllProfiles().keys().map(x => ({id: x, name: x})).sort(sorter);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -533,10 +533,10 @@ SearchStrings.prototype = {
|
|||
if (aDict.has("RecentSearchStrings")) {
|
||||
let recentSearchStrings = aDict.get("RecentSearchStrings");
|
||||
if (recentSearchStrings && recentSearchStrings.length > 0) {
|
||||
let changes = [{op: "add",
|
||||
let changes = recentSearchStrings.map((searchString) => (
|
||||
{op: "add",
|
||||
fieldname: "searchbar-history",
|
||||
value: searchString}
|
||||
for (searchString of recentSearchStrings)];
|
||||
value: searchString}));
|
||||
FormHistory.update(changes);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,12 @@ function checkDirectoryContains(dir, files) {
|
|||
}
|
||||
seen.add(file.leafName);
|
||||
}
|
||||
let missing = [x for (x in files) if (!seen.has(x))];
|
||||
let missing = [];
|
||||
for (let x in files) {
|
||||
if (!seen.has(x)) {
|
||||
missing.push(x);
|
||||
}
|
||||
}
|
||||
Assert.deepEqual(missing, [], "no missing files in " + dir.path);
|
||||
}
|
||||
|
||||
|
|
|
@ -332,7 +332,7 @@ function reset_preferences(win) {
|
|||
var testRunner;
|
||||
function run_test_subset(subset) {
|
||||
Services.prefs.setBoolPref("browser.preferences.instantApply", true);
|
||||
dump("subset: " + [x.name for (x of subset)].join(",") + "\n");
|
||||
dump("subset: " + Array.from(subset, x => x.name).join(",") + "\n");
|
||||
|
||||
waitForExplicitFinish();
|
||||
registerCleanupFunction(function() {
|
||||
|
|
|
@ -64,10 +64,12 @@ var SessionHistoryInternal = {
|
|||
* The docShell that owns the session history.
|
||||
*/
|
||||
collect: function (docShell) {
|
||||
let data = {entries: [], userContextId: docShell.userContextId };
|
||||
let loadContext = docShell.QueryInterface(Ci.nsILoadContext);
|
||||
let webNavigation = docShell.QueryInterface(Ci.nsIWebNavigation);
|
||||
let history = webNavigation.sessionHistory.QueryInterface(Ci.nsISHistoryInternal);
|
||||
|
||||
let data = {entries: [], userContextId: loadContext.originAttributes.userContextId };
|
||||
|
||||
if (history && history.count > 0) {
|
||||
// Loop over the transaction linked list directly so we can get the
|
||||
// persist property for each transaction.
|
||||
|
@ -254,7 +256,7 @@ var SessionHistoryInternal = {
|
|||
let history = webNavigation.sessionHistory;
|
||||
|
||||
if ("userContextId" in tabData) {
|
||||
docShell.userContextId = tabData.userContextId;
|
||||
docShell.setUserContextId(tabData.userContextId);
|
||||
}
|
||||
|
||||
if (history.count > 0) {
|
||||
|
|
|
@ -104,7 +104,18 @@ var SessionStorageInternal = {
|
|||
restore: function (aDocShell, aStorageData) {
|
||||
for (let origin of Object.keys(aStorageData)) {
|
||||
let data = aStorageData[origin];
|
||||
let principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(origin);
|
||||
|
||||
let principal;
|
||||
|
||||
try {
|
||||
let attrs = ChromeUtils.createOriginAttributesWithUserContextId(origin, aDocShell.userContextId);
|
||||
let originURI = Services.io.newURI(origin, null, null);
|
||||
principal = Services.scriptSecurityManager.createCodebasePrincipal(originURI, attrs);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
continue;
|
||||
}
|
||||
|
||||
let storageManager = aDocShell.QueryInterface(Ci.nsIDOMStorageManager);
|
||||
let window = aDocShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow);
|
||||
|
||||
|
|
|
@ -1907,10 +1907,10 @@ var SessionStoreInternal = {
|
|||
this._cleanupOldData([this._closedWindows]);
|
||||
|
||||
// Remove closed tabs of closed windows
|
||||
this._cleanupOldData([winData._closedTabs for (winData of this._closedWindows)]);
|
||||
this._cleanupOldData(this._closedWindows.map((winData) => winData._closedTabs));
|
||||
|
||||
// Remove closed tabs of open windows
|
||||
this._cleanupOldData([this._windows[key]._closedTabs for (key of Object.keys(this._windows))]);
|
||||
this._cleanupOldData(Object.keys(this._windows).map((key) => this._windows[key]._closedTabs));
|
||||
},
|
||||
|
||||
// Remove "old" data from an array
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
function retrieveUserContextId(browser) {
|
||||
return ContentTask.spawn(browser, null, function* () {
|
||||
return docShell.userContextId;
|
||||
let loadContext = docShell.QueryInterface(Ci.nsILoadContext);
|
||||
return loadContext.originAttributes.userContextId;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ function sha1(str) {
|
|||
}
|
||||
|
||||
// Convert the binary hash data to a hex string.
|
||||
return [toHexString(hash.charCodeAt(i)) for (i in hash)].join("");
|
||||
return Array.from(hash, (c, i) => toHexString(hash.charCodeAt(i))).join("");
|
||||
}
|
||||
|
||||
function parseXml(body) {
|
||||
|
|
|
@ -99,28 +99,7 @@ function sha1(str) {
|
|||
}
|
||||
|
||||
// Convert the binary hash data to a hex string.
|
||||
return [toHexString(hash.charCodeAt(i)) for (i in hash)].join("");function sha1(str) {
|
||||
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
|
||||
.createInstance(Ci.nsIScriptableUnicodeConverter);
|
||||
converter.charset = "UTF-8";
|
||||
// `result` is an out parameter, `result.value` will contain the array length.
|
||||
let result = {};
|
||||
// `data` is an array of bytes.
|
||||
let data = converter.convertToByteArray(str, result);
|
||||
let ch = Cc["@mozilla.org/security/hash;1"]
|
||||
.createInstance(Ci.nsICryptoHash);
|
||||
ch.init(ch.SHA1);
|
||||
ch.update(data, data.length);
|
||||
let hash = ch.finish(false);
|
||||
|
||||
// Return the two-digit hexadecimal code for a byte.
|
||||
function toHexString(charCode) {
|
||||
return ("0" + charCode.toString(16)).slice(-2);
|
||||
}
|
||||
|
||||
// Convert the binary hash data to a hex string.
|
||||
return [toHexString(hash.charCodeAt(i)) for (i in hash)].join("");
|
||||
}
|
||||
return Array.from(hash, (c, i) => toHexString(hash.charCodeAt(i))).join("");
|
||||
}
|
||||
|
||||
function getRequestBody(req) {
|
||||
|
|
|
@ -1831,9 +1831,8 @@ this.UITour = {
|
|||
let engines = Services.search.getVisibleEngines();
|
||||
data = {
|
||||
searchEngineIdentifier: Services.search.defaultEngine.identifier,
|
||||
engines: [TARGET_SEARCHENGINE_PREFIX + engine.identifier
|
||||
for (engine of engines)
|
||||
if (engine.identifier)]
|
||||
engines: engines.filter((engine) => engine.identifier)
|
||||
.map((engine) => TARGET_SEARCHENGINE_PREFIX + engine.identifier)
|
||||
};
|
||||
} else {
|
||||
data = {engines: [], searchEngineIdentifier: ""};
|
||||
|
|
|
@ -327,9 +327,8 @@ var tests = [
|
|||
let defaultEngine = Services.search.defaultEngine;
|
||||
gContentAPI.getConfiguration("search", data => {
|
||||
let visibleEngines = Services.search.getVisibleEngines();
|
||||
let expectedEngines = ["searchEngine-" + engine.identifier
|
||||
for (engine of visibleEngines)
|
||||
if (engine.identifier)];
|
||||
let expectedEngines = visibleEngines.filter((engine) => engine.identifier)
|
||||
.map((engine) => "searchEngine-" + engine.identifier);
|
||||
|
||||
let engines = data.engines;
|
||||
ok(Array.isArray(engines), "data.engines should be an array");
|
||||
|
|
|
@ -660,7 +660,7 @@ const kMessageHandlers = {
|
|||
hasher.updateFromStream(stringStream, -1);
|
||||
let hash = hasher.finish(false);
|
||||
// Convert the binary hash data to a hex string.
|
||||
let md5Email = [toHexString(hash.charCodeAt(i)) for (i in hash)].join("");
|
||||
let md5Email = Array.from(hash, (c, i) => toHexString(hash.charCodeAt(i))).join("");
|
||||
|
||||
// Compose the Gravatar URL.
|
||||
reply("https://www.gravatar.com/avatar/" + md5Email +
|
||||
|
|
|
@ -197,7 +197,7 @@ var pktUI = (function() {
|
|||
// Send error message for invalid url
|
||||
if (!isValidURL) {
|
||||
// TODO: Pass key for localized error in error object
|
||||
var error = {
|
||||
let error = {
|
||||
message: 'Only links can be saved',
|
||||
localizedKey: "onlylinkssaved"
|
||||
};
|
||||
|
@ -208,7 +208,7 @@ var pktUI = (function() {
|
|||
// Check online state
|
||||
if (!navigator.onLine) {
|
||||
// TODO: Pass key for localized error in error object
|
||||
var error = {
|
||||
let error = {
|
||||
message: 'You must be connected to the Internet in order to save to Pocket. Please connect to the Internet and try again.'
|
||||
};
|
||||
pktUIMessaging.sendErrorMessageToPanel(panelId, saveLinkMessageId, error);
|
||||
|
|
|
@ -75,4 +75,4 @@ var pktPanelMessaging = (function() {
|
|||
removeMessageListener : removeMessageListener,
|
||||
sendMessage: sendMessage
|
||||
};
|
||||
}());
|
||||
}());
|
||||
|
|
|
@ -147,4 +147,4 @@ templates['signupstoryboard_shell'] = template({"1":function(depth0,helpers,part
|
|||
+ escapeExpression(((helper = (helper = helpers.loginnow || (depth0 != null ? depth0.loginnow : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"loginnow","hash":{},"data":data}) : helper)))
|
||||
+ "</a>.</p>\n</div>";
|
||||
},"useData":true});
|
||||
})();
|
||||
})();
|
||||
|
|
|
@ -123,7 +123,7 @@ var pktApi = (function() {
|
|||
// https://developer.mozilla.org/en-US/Add-ons/Overlay_Extensions/XUL_School/Local_Storage
|
||||
|
||||
if (!prefBranch.prefHasUserValue(key))
|
||||
return;
|
||||
return undefined;
|
||||
|
||||
return prefBranch.getComplexValue(key, Components.interfaces.nsISupportsString).data;
|
||||
}
|
||||
|
|
|
@ -143,6 +143,10 @@
|
|||
#endif
|
||||
#endif
|
||||
@BINPATH@/@DLL_PREFIX@lgpllibs@DLL_SUFFIX@
|
||||
#ifdef MOZ_FFVPX
|
||||
@BINPATH@/@DLL_PREFIX@mozavutil@DLL_SUFFIX@
|
||||
@BINPATH@/@DLL_PREFIX@mozavcodec@DLL_SUFFIX@
|
||||
#endif
|
||||
@RESPATH@/browser/blocklist.xml
|
||||
#ifdef XP_UNIX
|
||||
#ifndef XP_MACOSX
|
||||
|
|
|
@ -371,6 +371,27 @@ Function .onInit
|
|||
${If} "$R9" == "false"
|
||||
SetShellVarContext current ; Set SHCTX to HKCU
|
||||
${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9
|
||||
|
||||
${If} ${RunningX64}
|
||||
; In HKCU there is no WOW64 redirection, which means we may have gotten
|
||||
; the path to a 32-bit install even though we're 64-bit, or vice-versa.
|
||||
; In that case, just use the default path instead of offering an upgrade.
|
||||
; But only do that override if the existing install is in Program Files,
|
||||
; because that's the only place we can be sure is specific
|
||||
; to either 32 or 64 bit applications.
|
||||
; The WordFind syntax below searches for the first occurence of the
|
||||
; "delimiter" (the Program Files path) in the install path and returns
|
||||
; anything that appears before that. If nothing appears before that,
|
||||
; then the install is under Program Files (32 or 64).
|
||||
!ifdef HAVE_64BIT_BUILD
|
||||
${WordFind} $R9 $PROGRAMFILES32 "+1{" $0
|
||||
!else
|
||||
${WordFind} $R9 $PROGRAMFILES64 "+1{" $0
|
||||
!endif
|
||||
${If} $0 == ""
|
||||
StrCpy $R9 "false"
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
|
||||
${If} "$R9" != "false"
|
||||
|
|
|
@ -33,6 +33,9 @@ function checkOriginAttributes(prin, attrs, suffix) {
|
|||
} else {
|
||||
checkThrows(() => ssm.createCodebasePrincipalFromOrigin(prin.origin));
|
||||
}
|
||||
|
||||
do_check_eq(ChromeUtils.createOriginAttributesWithUserContextId("http://example.org", 2).userContextId, 2);
|
||||
do_check_eq(ChromeUtils.createOriginAttributesWithUserContextId("https://www.example.com:123^userContextId=4", 2).userContextId, 2);
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
|
|
|
@ -44,6 +44,9 @@ if CONFIG['MOZ_WEBSPEECH_POCKETSPHINX']:
|
|||
'media/pocketsphinx',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_FFVPX']:
|
||||
external_dirs += ['media/ffvpx']
|
||||
|
||||
external_dirs += [
|
||||
'media/kiss_fft',
|
||||
'media/libcubeb',
|
||||
|
|
|
@ -20,6 +20,7 @@ new
|
|||
algorithm
|
||||
atomic
|
||||
deque
|
||||
initializer_list
|
||||
ios
|
||||
iosfwd
|
||||
iostream
|
||||
|
|
|
@ -548,6 +548,7 @@ image.h
|
|||
imagehlp.h
|
||||
imm.h
|
||||
initguid.h
|
||||
initializer_list
|
||||
InterfaceDefs.h
|
||||
InternetConfig.h
|
||||
IntlResources.h
|
||||
|
|
36
configure.in
36
configure.in
|
@ -3731,7 +3731,7 @@ if test -n "$MOZ_FMP4"; then
|
|||
else
|
||||
MOZ_FMP4=
|
||||
fi
|
||||
MOZ_FFMPEG=
|
||||
MOZ_FFMPEG=1
|
||||
MOZ_WEBRTC=1
|
||||
MOZ_PEERCONNECTION=
|
||||
MOZ_SRTP=
|
||||
|
@ -5219,14 +5219,6 @@ fi;
|
|||
dnl ========================================================
|
||||
dnl FFmpeg H264/AAC Decoding Support
|
||||
dnl ========================================================
|
||||
case "$OS_TARGET" in
|
||||
WINNT|Darwin|Android)
|
||||
;;
|
||||
*)
|
||||
MOZ_FFMPEG=1
|
||||
;;
|
||||
esac
|
||||
|
||||
MOZ_ARG_DISABLE_BOOL(ffmpeg,
|
||||
[ --disable-ffmpeg Disable FFmpeg for fragmented H264/AAC decoding],
|
||||
MOZ_FFMPEG=,
|
||||
|
@ -6183,6 +6175,29 @@ elif test -n "$MOZ_LIBAV_FFT" -a "${CPU_ARCH}" != "arm"; then
|
|||
AC_MSG_WARN([No assembler or assembly support for libav-fft. Using unoptimized C routines.])
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl = FFmpeg's ffvpx configuration
|
||||
dnl ========================================================
|
||||
|
||||
MOZ_FFVPX=
|
||||
case "$CPU_ARCH" in
|
||||
x86)
|
||||
MOZ_FFVPX=1
|
||||
;;
|
||||
x86_64)
|
||||
MOZ_FFVPX=1
|
||||
;;
|
||||
esac
|
||||
|
||||
dnl Use same conditional as MOZ_LIBAV_FFT to enable FFmpeg's ffvpx assembly decoder.
|
||||
if test -n "$MOZ_LIBAV_FFT"; then
|
||||
FFVPX_ASFLAGS=$LIBAV_FFT_ASFLAGS
|
||||
FFVPX_AS=$LIBAV_FFT_AS
|
||||
fi
|
||||
if test -n "$MOZ_FFVPX"; then
|
||||
AC_DEFINE(MOZ_FFVPX)
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Enable compilation of specific extension modules
|
||||
dnl ========================================================
|
||||
|
@ -8869,6 +8884,9 @@ AC_SUBST(MOZ_VORBIS)
|
|||
AC_SUBST(MOZ_TREMOR)
|
||||
AC_SUBST(MOZ_WMF)
|
||||
AC_SUBST(MOZ_FFMPEG)
|
||||
AC_SUBST(MOZ_FFVPX)
|
||||
AC_SUBST(FFVPX_AS)
|
||||
AC_SUBST_LIST(FFVPX_ASFLAGS)
|
||||
AC_SUBST(MOZ_FMP4)
|
||||
AC_SUBST(MOZ_EME)
|
||||
AC_SUBST(MOZ_DIRECTSHOW)
|
||||
|
|
|
@ -35,12 +35,12 @@ function consoleOpened(HUD) {
|
|||
|
||||
is(result + 1, container.gen1.next(), "gen1.next() did not execute");
|
||||
|
||||
result = container.gen2.next();
|
||||
result = container.gen2.next().value;
|
||||
|
||||
completion = JSPropertyProvider(dbgWindow, null, "_container.gen2.");
|
||||
isnot(completion.matches.length, 0, "Got matches for gen2");
|
||||
|
||||
is((result / 2 + 1) * 2, container.gen2.next(),
|
||||
is((result / 2 + 1) * 2, container.gen2.next().value,
|
||||
"gen2.next() did not execute");
|
||||
|
||||
result = container.iter1.next();
|
||||
|
|
|
@ -19,8 +19,7 @@ function testForOf(hud) {
|
|||
let deferred = promise.defer();
|
||||
|
||||
let jsterm = hud.jsterm;
|
||||
jsterm.execute("{ [x.tagName for (x of document.body.childNodes) " +
|
||||
"if (x.nodeType === 1)].join(' '); }",
|
||||
jsterm.execute("{ let _nodes = []; for (let x of document.body.childNodes) { if (x.nodeType === 1) { _nodes.push(x.tagName); } } _nodes.join(' '); }",
|
||||
(node) => {
|
||||
ok(/H1 DIV H2 P/.test(node.textContent),
|
||||
"for-of loop should find all top-level nodes");
|
||||
|
|
|
@ -46,7 +46,7 @@ Range.prototype.__iterator__ = function() {
|
|||
|
||||
_container.iter2 = new Range(3, 15);
|
||||
|
||||
_container.gen2 = (i * 2 for (i in _container.iter2));
|
||||
_container.gen2 = (function* () { for (let i in _container.iter2) yield i * 2; })();
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
|
|
|
@ -67,7 +67,7 @@ function loadSelector(selector) {
|
|||
}
|
||||
|
||||
function loadSelectors(selectors) {
|
||||
return promise.all([loadSelector(sel) for (sel of selectors)]);
|
||||
return promise.all(Array.from(selectors, (sel) => loadSelector(sel)));
|
||||
}
|
||||
|
||||
function doMoves(moves) {
|
||||
|
|
|
@ -328,7 +328,7 @@ addTest(function testReleaseWalker() {
|
|||
checkActorIDs.push(gWalker.actorID);
|
||||
|
||||
promiseDone(gWalker.release().then(() => {
|
||||
let promises = [checkMissing(gClient, id) for (id of checkActorIDs)];
|
||||
let promises = Array.from(checkActorIDs, (id) => checkMissing(gClient, id));
|
||||
return promise.all(promises)
|
||||
}).then(runNextTest));
|
||||
});
|
||||
|
|
|
@ -80,3 +80,6 @@ LOCAL_INCLUDES += [
|
|||
|
||||
if CONFIG['MOZ_TOOLKIT_SEARCH']:
|
||||
DEFINES['MOZ_TOOLKIT_SEARCH'] = True
|
||||
|
||||
if CONFIG['MOZ_DEVTOOLS'] == 'all':
|
||||
DEFINES['MOZ_DEVTOOLS_ALL'] = True
|
||||
|
|
|
@ -52,6 +52,12 @@ static RedirEntry kRedirMap[] = {
|
|||
"credits", "https://www.mozilla.org/credits/",
|
||||
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT
|
||||
},
|
||||
#ifdef MOZ_DEVTOOLS_ALL
|
||||
{
|
||||
"debugging", "chrome://devtools/content/aboutdebugging/aboutdebugging.xhtml",
|
||||
nsIAboutModule::ALLOW_SCRIPT
|
||||
},
|
||||
#endif
|
||||
{
|
||||
"license", "chrome://global/content/license.html",
|
||||
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT
|
||||
|
|
|
@ -13836,17 +13836,6 @@ nsDocShell::SetIsSignedPackage(const nsAString& aSignedPkg)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetUserContextId(uint32_t* aUserContextId)
|
||||
{
|
||||
if (!aUserContextId) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*aUserContextId = mUserContextId;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetUserContextId(uint32_t aUserContextId)
|
||||
{
|
||||
|
|
|
@ -43,7 +43,7 @@ interface nsITabParent;
|
|||
|
||||
typedef unsigned long nsLoadFlags;
|
||||
|
||||
[scriptable, builtinclass, uuid(258a8a33-219f-42f8-8fa8-f8f2dcd2358b)]
|
||||
[scriptable, builtinclass, uuid(98358234-3936-4b95-b051-fcda4e55b52d)]
|
||||
interface nsIDocShell : nsIDocShellTreeItem
|
||||
{
|
||||
/**
|
||||
|
@ -1097,8 +1097,8 @@ interface nsIDocShell : nsIDocShellTreeItem
|
|||
*/
|
||||
attribute boolean currentScrollRestorationIsManual;
|
||||
|
||||
/**
|
||||
* Sets/gets the user context ID for this docshell.
|
||||
/*
|
||||
* Sets the user context ID for this docshell.
|
||||
*/
|
||||
attribute unsigned long userContextId;
|
||||
void setUserContextId(in unsigned long aUserContextId);
|
||||
};
|
||||
|
|
|
@ -29,3 +29,6 @@ FINAL_LIBRARY = 'xul'
|
|||
|
||||
if CONFIG['GNU_CXX']:
|
||||
CXXFLAGS += ['-Wshadow']
|
||||
|
||||
if CONFIG['MOZ_DEVTOOLS'] == 'all':
|
||||
DEFINES['MOZ_DEVTOOLS_ALL'] = True
|
||||
|
|
|
@ -168,6 +168,9 @@ const mozilla::Module::ContractIDEntry kDocShellContracts[] = {
|
|||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "crashes", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
#endif
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "credits", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
#ifdef MOZ_DEVTOOLS_ALL
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "debugging", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
#endif
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "license", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "logo", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "memory", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
|
|
|
@ -54,7 +54,7 @@ skip-if = true
|
|||
[test_bug509055.html]
|
||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
|
||||
[test_bug511449.html]
|
||||
skip-if = toolkit != "cocoa" || e10s
|
||||
skip-if = toolkit != "cocoa"
|
||||
support-files = file_bug511449.html
|
||||
[test_bug529119-1.html]
|
||||
skip-if = buildapp == 'mulet' || (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
|
||||
|
|
|
@ -34,48 +34,6 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AnimationTimeline)
|
|||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
void
|
||||
AnimationTimeline::GetAnimations(AnimationSequence& aAnimations)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(mWindow);
|
||||
if (mWindow) {
|
||||
nsIDocument* doc = window->GetDoc();
|
||||
if (doc) {
|
||||
doc->FlushPendingNotifications(Flush_Style);
|
||||
}
|
||||
}
|
||||
|
||||
aAnimations.SetCapacity(mAnimations.Count());
|
||||
|
||||
for (Animation* animation = mAnimationOrder.getFirst(); animation;
|
||||
animation = animation->getNext()) {
|
||||
|
||||
// Skip animations which are no longer relevant or which have been
|
||||
// associated with another timeline. These animations will be removed
|
||||
// on the next tick.
|
||||
if (!animation->IsRelevant() || animation->GetTimeline() != this) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Bug 1174575: Until we implement a suitable PseudoElement interface we
|
||||
// don't have anything to return for the |target| attribute of
|
||||
// KeyframeEffect(ReadOnly) objects that refer to pseudo-elements.
|
||||
// Rather than return some half-baked version of these objects (e.g.
|
||||
// we a null effect attribute) we simply don't provide access to animations
|
||||
// whose effect refers to a pseudo-element until we can support them
|
||||
// properly.
|
||||
Element* target;
|
||||
nsCSSPseudoElements::Type pseudoType;
|
||||
animation->GetEffect()->GetTarget(target, pseudoType);
|
||||
if (pseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement) {
|
||||
aAnimations.AppendElement(animation);
|
||||
}
|
||||
}
|
||||
|
||||
// Sort animations by priority
|
||||
aAnimations.Sort(AnimationPtrComparator<RefPtr<Animation>>());
|
||||
}
|
||||
|
||||
void
|
||||
AnimationTimeline::NotifyAnimationUpdated(Animation& aAnimation)
|
||||
{
|
||||
|
|
|
@ -51,11 +51,8 @@ public:
|
|||
|
||||
nsIGlobalObject* GetParentObject() const { return mWindow; }
|
||||
|
||||
typedef nsTArray<RefPtr<Animation>> AnimationSequence;
|
||||
|
||||
// AnimationTimeline methods
|
||||
virtual Nullable<TimeDuration> GetCurrentTime() const = 0;
|
||||
void GetAnimations(AnimationSequence& aAnimations);
|
||||
|
||||
// Wrapper functions for AnimationTimeline DOM methods when called from
|
||||
// script.
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
'use strict';
|
||||
|
||||
test(function(t) {
|
||||
assert_equals(document.timeline.getAnimations().length, 0,
|
||||
assert_equals(document.getAnimations().length, 0,
|
||||
'getAnimations returns an empty sequence for a document'
|
||||
+ ' with no animations');
|
||||
}, 'getAnimations for non-animated content');
|
||||
|
@ -34,17 +34,17 @@ test(function(t) {
|
|||
|
||||
// Add an animation
|
||||
div.style.animation = 'animLeft 100s';
|
||||
assert_equals(document.timeline.getAnimations().length, 1,
|
||||
assert_equals(document.getAnimations().length, 1,
|
||||
'getAnimations returns a running CSS Animation');
|
||||
|
||||
// Add another animation
|
||||
div.style.animation = 'animLeft 100s, animTop 100s';
|
||||
assert_equals(document.timeline.getAnimations().length, 2,
|
||||
assert_equals(document.getAnimations().length, 2,
|
||||
'getAnimations returns two running CSS Animations');
|
||||
|
||||
// Remove both
|
||||
div.style.animation = '';
|
||||
assert_equals(document.timeline.getAnimations().length, 0,
|
||||
assert_equals(document.getAnimations().length, 0,
|
||||
'getAnimations returns no running CSS Animations');
|
||||
}, 'getAnimations for CSS Animations');
|
||||
|
||||
|
@ -53,7 +53,7 @@ test(function(t) {
|
|||
div.style.animation = 'animLeft 100s, animTop 100s, animRight 100s, ' +
|
||||
'animBottom 100s';
|
||||
|
||||
var animations = document.timeline.getAnimations();
|
||||
var animations = document.getAnimations();
|
||||
assert_equals(animations.length, 4,
|
||||
'getAnimations returns all running CSS Animations');
|
||||
assert_equals(animations[0].animationName, 'animLeft',
|
||||
|
@ -72,7 +72,7 @@ test(function(t) {
|
|||
var div3 = addDiv(t, { style: 'animation: animLeft 100s' });
|
||||
var div4 = addDiv(t, { style: 'animation: animLeft 100s' });
|
||||
|
||||
var animations = document.timeline.getAnimations();
|
||||
var animations = document.getAnimations();
|
||||
assert_equals(animations.length, 4,
|
||||
'getAnimations returns all running CSS Animations');
|
||||
assert_equals(animations[0].effect.target, div1,
|
||||
|
@ -95,7 +95,7 @@ test(function(t) {
|
|||
// Which should give: 2, 1, 4, 3
|
||||
div2.appendChild(div1);
|
||||
div2.appendChild(div4);
|
||||
animations = document.timeline.getAnimations();
|
||||
animations = document.getAnimations();
|
||||
assert_equals(animations[0].effect.target, div2,
|
||||
'Order of first animation returned after tree surgery');
|
||||
assert_equals(animations[1].effect.target, div1,
|
||||
|
@ -114,7 +114,7 @@ test(function(t) {
|
|||
var expectedResults = [ [ div1, 'animLeft' ],
|
||||
[ div1, 'animTop' ],
|
||||
[ div2, 'animBottom' ] ];
|
||||
var animations = document.timeline.getAnimations();
|
||||
var animations = document.getAnimations();
|
||||
assert_equals(animations.length, expectedResults.length,
|
||||
'getAnimations returns all running CSS Animations');
|
||||
animations.forEach(function(anim, i) {
|
||||
|
@ -132,7 +132,7 @@ test(function(t) {
|
|||
[ div1, 'animLeft' ],
|
||||
[ div1, 'animRight' ],
|
||||
[ div1, 'animTop' ] ];
|
||||
animations = document.timeline.getAnimations();
|
||||
animations = document.getAnimations();
|
||||
assert_equals(animations.length, expectedResults.length,
|
||||
'getAnimations returns all running CSS Animations after ' +
|
||||
'making changes');
|
||||
|
@ -145,10 +145,8 @@ test(function(t) {
|
|||
}, 'Order of CSS Animations - across and within elements');
|
||||
|
||||
test(function(t) {
|
||||
cancelAllAnimationsOnEnd(t);
|
||||
|
||||
var div = addDiv(t, { style: 'animation: animLeft 100s, animTop 100s' });
|
||||
var animLeft = document.timeline.getAnimations()[0];
|
||||
var animLeft = document.getAnimations()[0];
|
||||
assert_equals(animLeft.animationName, 'animLeft',
|
||||
'Originally, animLeft animation comes first');
|
||||
|
||||
|
@ -156,7 +154,7 @@ test(function(t) {
|
|||
div.style.animation = 'animTop 100s';
|
||||
animLeft.play();
|
||||
|
||||
var animations = document.timeline.getAnimations();
|
||||
var animations = document.getAnimations();
|
||||
assert_equals(animations.length, 2,
|
||||
'getAnimations returns markup-bound and free animations');
|
||||
assert_equals(animations[0].animationName, 'animTop',
|
||||
|
@ -165,18 +163,16 @@ test(function(t) {
|
|||
}, 'Order of CSS Animations - markup-bound vs free animations');
|
||||
|
||||
test(function(t) {
|
||||
cancelAllAnimationsOnEnd(t);
|
||||
|
||||
var div = addDiv(t, { style: 'animation: animLeft 100s, animTop 100s' });
|
||||
var animLeft = document.timeline.getAnimations()[0];
|
||||
var animTop = document.timeline.getAnimations()[1];
|
||||
var animLeft = document.getAnimations()[0];
|
||||
var animTop = document.getAnimations()[1];
|
||||
|
||||
// Disassociate both animations from markup and restart in opposite order
|
||||
div.style.animation = '';
|
||||
animTop.play();
|
||||
animLeft.play();
|
||||
|
||||
var animations = document.timeline.getAnimations();
|
||||
var animations = document.getAnimations();
|
||||
assert_equals(animations.length, 2,
|
||||
'getAnimations returns free animations');
|
||||
assert_equals(animations[0], animTop,
|
||||
|
@ -187,7 +183,7 @@ test(function(t) {
|
|||
// Restarting an animation should have no effect
|
||||
animTop.cancel();
|
||||
animTop.play();
|
||||
assert_equals(document.timeline.getAnimations()[0], animTop,
|
||||
assert_equals(document.getAnimations()[0], animTop,
|
||||
'After restarting, the ordering of free animations' +
|
||||
' does not change');
|
||||
}, 'Order of CSS Animations - free animations');
|
||||
|
@ -204,7 +200,7 @@ test(function(t) {
|
|||
flushComputedStyle(div);
|
||||
|
||||
// Although the transition was added later, it should come first in the list
|
||||
var animations = document.timeline.getAnimations();
|
||||
var animations = document.getAnimations();
|
||||
assert_equals(animations.length, 2,
|
||||
'Both CSS animations and transitions are returned');
|
||||
assert_class_string(animations[0], 'CSSTransition', 'Transition comes first');
|
||||
|
@ -214,38 +210,36 @@ test(function(t) {
|
|||
test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: animLeft 100s forwards' });
|
||||
div.getAnimations()[0].finish();
|
||||
assert_equals(document.timeline.getAnimations().length, 1,
|
||||
assert_equals(document.getAnimations().length, 1,
|
||||
'Forwards-filling CSS animations are returned');
|
||||
}, 'Finished but filling CSS Animations are returned');
|
||||
|
||||
test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: animLeft 100s' });
|
||||
div.getAnimations()[0].finish();
|
||||
assert_equals(document.timeline.getAnimations().length, 0,
|
||||
assert_equals(document.getAnimations().length, 0,
|
||||
'Non-filling finished CSS animations are not returned');
|
||||
}, 'Finished but not filling CSS Animations are not returned');
|
||||
|
||||
test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: animLeft 100s 100s' });
|
||||
assert_equals(document.timeline.getAnimations().length, 1,
|
||||
assert_equals(document.getAnimations().length, 1,
|
||||
'Yet-to-start CSS animations are returned');
|
||||
}, 'Yet-to-start CSS Animations are returned');
|
||||
|
||||
test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: animLeft 100s' });
|
||||
div.getAnimations()[0].cancel();
|
||||
assert_equals(document.timeline.getAnimations().length, 0,
|
||||
assert_equals(document.getAnimations().length, 0,
|
||||
'CSS animations cancelled by the API are not returned');
|
||||
}, 'CSS Animations cancelled via the API are not returned');
|
||||
|
||||
test(function(t) {
|
||||
cancelAllAnimationsOnEnd(t);
|
||||
|
||||
var div = addDiv(t, { style: 'animation: animLeft 100s' });
|
||||
var anim = div.getAnimations()[0];
|
||||
anim.cancel();
|
||||
anim.play();
|
||||
assert_equals(document.timeline.getAnimations().length, 1,
|
||||
assert_equals(document.getAnimations().length, 1,
|
||||
'CSS animations cancelled and restarted by the API are ' +
|
||||
'returned');
|
||||
}, 'CSS Animations cancelled and restarted via the API are returned');
|
||||
|
@ -256,7 +250,7 @@ test(function(t) {
|
|||
// but we haven't implemented a PseudoElement interface to use as
|
||||
// animation's target (bug 1174575) so we simply don't return these animations
|
||||
// until we can support them properly.
|
||||
assert_equals(document.timeline.getAnimations().length, 0,
|
||||
assert_equals(document.getAnimations().length, 0,
|
||||
'CSS animations on pseudo elements are not returned');
|
||||
}, 'CSS Animations targetting pseudo-elements are not returned');
|
||||
|
|
@ -9,7 +9,7 @@ setup({explicit_done: true});
|
|||
SpecialPowers.pushPrefEnv(
|
||||
{ "set": [["dom.animations-api.core.enabled", true]]},
|
||||
function() {
|
||||
window.open("file_timeline-get-animations.html");
|
||||
window.open("file_document-get-animations.html");
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -6,7 +6,7 @@
|
|||
'use strict';
|
||||
|
||||
test(function(t) {
|
||||
assert_equals(document.timeline.getAnimations().length, 0,
|
||||
assert_equals(document.getAnimations().length, 0,
|
||||
'getAnimations returns an empty sequence for a document'
|
||||
+ ' with no animations');
|
||||
}, 'getAnimations for non-animated content');
|
||||
|
@ -22,12 +22,12 @@ test(function(t) {
|
|||
div.style.transition = 'all 100s';
|
||||
div.style.left = '100px';
|
||||
div.style.top = '100px';
|
||||
assert_equals(document.timeline.getAnimations().length, 2,
|
||||
assert_equals(document.getAnimations().length, 2,
|
||||
'getAnimations returns two running CSS Transitions');
|
||||
|
||||
// Remove both
|
||||
div.style.transitionProperty = 'none';
|
||||
assert_equals(document.timeline.getAnimations().length, 0,
|
||||
assert_equals(document.getAnimations().length, 0,
|
||||
'getAnimations returns no running CSS Transitions');
|
||||
}, 'getAnimations for CSS Transitions');
|
||||
|
||||
|
@ -39,7 +39,7 @@ async_test(function(t) {
|
|||
var animations = div.getAnimations();
|
||||
assert_equals(animations.length, 1, 'Got transition');
|
||||
animations[0].finished.then(t.step_func(function() {
|
||||
assert_equals(document.timeline.getAnimations().length, 0,
|
||||
assert_equals(document.getAnimations().length, 0,
|
||||
'No animations returned');
|
||||
t.done();
|
||||
}));
|
|
@ -9,7 +9,7 @@ setup({explicit_done: true});
|
|||
SpecialPowers.pushPrefEnv(
|
||||
{ "set": [["dom.animations-api.core.enabled", true]]},
|
||||
function() {
|
||||
window.open("file_timeline-get-animations.html");
|
||||
window.open("file_document-get-animations.html");
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -34,15 +34,15 @@ 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_document-get-animations.html]
|
||||
support-files = css-animations/file_document-get-animations.html
|
||||
[css-animations/test_effect-target.html]
|
||||
support-files = css-animations/file_effect-target.html
|
||||
[css-animations/test_element-get-animations.html]
|
||||
skip-if = buildapp == 'mulet'
|
||||
support-files = css-animations/file_element-get-animations.html
|
||||
[css-animations/test_timeline-get-animations.html]
|
||||
support-files = css-animations/file_timeline-get-animations.html
|
||||
[css-animations/test_keyframeeffect-getframes.html]
|
||||
support-files = css-animations/file_keyframeeffect-getframes.html
|
||||
[css-transitions/test_animation-cancel.html]
|
||||
support-files = css-transitions/file_animation-cancel.html
|
||||
[css-transitions/test_animation-computed-timing.html]
|
||||
|
@ -59,15 +59,15 @@ 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_document-get-animations.html]
|
||||
support-files = css-transitions/file_document-get-animations.html
|
||||
[css-transitions/test_effect-target.html]
|
||||
support-files = css-transitions/file_effect-target.html
|
||||
[css-transitions/test_element-get-animations.html]
|
||||
skip-if = buildapp == 'mulet'
|
||||
support-files = css-transitions/file_element-get-animations.html
|
||||
[css-transitions/test_timeline-get-animations.html]
|
||||
support-files = css-transitions/file_timeline-get-animations.html
|
||||
[css-transitions/test_keyframeeffect-getframes.html]
|
||||
support-files = css-transitions/file_keyframeeffect-getframes.html
|
||||
[document-timeline/test_document-timeline.html]
|
||||
support-files = document-timeline/file_document-timeline.html
|
||||
[document-timeline/test_request_animation_frame.html]
|
||||
|
|
|
@ -29,18 +29,6 @@ function addDiv(t, attrs) {
|
|||
return div;
|
||||
}
|
||||
|
||||
/**
|
||||
* Some tests cause animations to continue to exist even after their target
|
||||
* element has been removed from the document tree. To ensure that these
|
||||
* animations do not impact other tests we should cancel them when the test
|
||||
* is complete.
|
||||
*/
|
||||
function cancelAllAnimationsOnEnd(t) {
|
||||
t.add_cleanup(function() {
|
||||
document.timeline.getAnimations().forEach(animation => animation.cancel());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Promise wrapper for requestAnimationFrame.
|
||||
*/
|
||||
|
|
|
@ -787,7 +787,7 @@ this.AppsUtils = {
|
|||
}
|
||||
|
||||
// Convert the binary hash data to a hex string.
|
||||
return [toHexString(hash.charCodeAt(i)) for (i in hash)].join("");
|
||||
return Array.from(hash, (c, i) => toHexString(hash.charCodeAt(i))).join("");
|
||||
},
|
||||
|
||||
// Returns the hash for a JS object.
|
||||
|
|
|
@ -3631,7 +3631,7 @@ this.DOMApplicationRegistry = {
|
|||
// We're passing false to get the binary hash and not base64.
|
||||
let data = hasher.finish(false);
|
||||
// Convert the binary hash data to a hex string.
|
||||
let hash = [toHexString(data.charCodeAt(i)) for (i in data)].join("");
|
||||
let hash = Array.from(data, (c, i) => toHexString(data.charCodeAt(i))).join("");
|
||||
debug("File hash computed: " + hash);
|
||||
|
||||
deferred.resolve(hash);
|
||||
|
|
|
@ -70,5 +70,23 @@ ChromeUtils::OriginAttributesMatchPattern(dom::GlobalObject& aGlobal,
|
|||
return pattern.Matches(attrs);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
ChromeUtils::CreateOriginAttributesWithUserContextId(dom::GlobalObject& aGlobal,
|
||||
const nsAString& aOrigin,
|
||||
uint32_t aUserContextId,
|
||||
dom::OriginAttributesDictionary& aAttrs,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
GenericOriginAttributes attrs;
|
||||
nsAutoCString suffix;
|
||||
if (!attrs.PopulateFromOrigin(NS_ConvertUTF16toUTF8(aOrigin), suffix)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
attrs.mUserContextId = aUserContextId;
|
||||
aAttrs = attrs;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -57,6 +57,13 @@ public:
|
|||
OriginAttributesMatchPattern(dom::GlobalObject& aGlobal,
|
||||
const dom::OriginAttributesDictionary& aAttrs,
|
||||
const dom::OriginAttributesPatternDictionary& aPattern);
|
||||
|
||||
static void
|
||||
CreateOriginAttributesWithUserContextId(dom::GlobalObject& aGlobal,
|
||||
const nsAString& aOrigin,
|
||||
uint32_t aUserContextId,
|
||||
dom::OriginAttributesDictionary& aAttrs,
|
||||
ErrorResult& aRv);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -3318,6 +3318,13 @@ Element::GetAnimations(nsTArray<RefPtr<Animation>>& aAnimations)
|
|||
doc->FlushPendingNotifications(Flush_Style);
|
||||
}
|
||||
|
||||
GetAnimationsUnsorted(aAnimations);
|
||||
aAnimations.Sort(AnimationPtrComparator<RefPtr<Animation>>());
|
||||
}
|
||||
|
||||
void
|
||||
Element::GetAnimationsUnsorted(nsTArray<RefPtr<Animation>>& aAnimations)
|
||||
{
|
||||
EffectSet* effects = EffectSet::GetEffectSet(this,
|
||||
nsCSSPseudoElements::ePseudo_NotPseudoElement);
|
||||
if (!effects) {
|
||||
|
@ -3335,8 +3342,6 @@ Element::GetAnimations(nsTArray<RefPtr<Animation>>& aAnimations)
|
|||
"effect set");
|
||||
aAnimations.AppendElement(animation);
|
||||
}
|
||||
|
||||
aAnimations.Sort(AnimationPtrComparator<RefPtr<Animation>>());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -821,7 +821,9 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
// Note: GetAnimations will flush style while GetAnimationsUnsorted won't.
|
||||
void GetAnimations(nsTArray<RefPtr<Animation>>& aAnimations);
|
||||
void GetAnimationsUnsorted(nsTArray<RefPtr<Animation>>& aAnimations);
|
||||
|
||||
NS_IMETHOD GetInnerHTML(nsAString& aInnerHTML);
|
||||
virtual void SetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError);
|
||||
|
|
|
@ -288,6 +288,8 @@ bool nsContentUtils::sFragmentParsingActive = false;
|
|||
bool nsContentUtils::sDOMWindowDumpEnabled;
|
||||
#endif
|
||||
|
||||
mozilla::LazyLogModule nsContentUtils::sDOMDumpLog("Dump");
|
||||
|
||||
// Subset of http://www.whatwg.org/specs/web-apps/current-work/#autofill-field-name
|
||||
enum AutocompleteFieldName
|
||||
{
|
||||
|
@ -7116,6 +7118,12 @@ nsContentUtils::DOMWindowDumpEnabled()
|
|||
#endif
|
||||
}
|
||||
|
||||
mozilla::LogModule*
|
||||
nsContentUtils::DOMDumpLog()
|
||||
{
|
||||
return sDOMDumpLog;
|
||||
}
|
||||
|
||||
bool
|
||||
nsContentUtils::GetNodeTextContent(nsINode* aNode, bool aDeep, nsAString& aResult,
|
||||
const fallible_t& aFallible)
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/FloatingPoint.h"
|
||||
#include "mozilla/net/ReferrerPolicy.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "nsIContentPolicy.h"
|
||||
|
||||
#if defined(XP_WIN)
|
||||
|
@ -2365,10 +2366,17 @@ public:
|
|||
const nsAString& aVersion);
|
||||
|
||||
/**
|
||||
* Return true if the browser.dom.window.dump.enabled pref is set.
|
||||
* Returns true if the browser.dom.window.dump.enabled pref is set.
|
||||
*/
|
||||
static bool DOMWindowDumpEnabled();
|
||||
|
||||
/**
|
||||
* Returns a LogModule that dump calls from content script are logged to.
|
||||
* This can be enabled with the 'Dump' module, and is useful for synchronizing
|
||||
* content JS to other logging modules.
|
||||
*/
|
||||
static mozilla::LogModule* DOMDumpLog();
|
||||
|
||||
/**
|
||||
* Returns whether a content is an insertion point for XBL
|
||||
* bindings or web components ShadowRoot. In web components,
|
||||
|
@ -2722,6 +2730,7 @@ private:
|
|||
#if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
|
||||
static bool sDOMWindowDumpEnabled;
|
||||
#endif
|
||||
static mozilla::LazyLogModule sDOMDumpLog;
|
||||
};
|
||||
|
||||
class MOZ_RAII nsAutoScriptBlocker {
|
||||
|
|
|
@ -10,10 +10,12 @@
|
|||
|
||||
#include "nsDocument.h"
|
||||
|
||||
#include "mozilla/AnimationComparator.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/AutoRestore.h"
|
||||
#include "mozilla/BinarySearch.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/EffectSet.h"
|
||||
#include "mozilla/IntegerRange.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/Likely.h"
|
||||
|
@ -3134,6 +3136,32 @@ nsDocument::Timeline()
|
|||
return mDocumentTimeline;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::GetAnimations(nsTArray<RefPtr<Animation>>& aAnimations)
|
||||
{
|
||||
FlushPendingNotifications(Flush_Style);
|
||||
|
||||
// Bug 1174575: Until we implement a suitable PseudoElement interface we
|
||||
// don't have anything to return for the |target| attribute of
|
||||
// KeyframeEffect(ReadOnly) objects that refer to pseudo-elements.
|
||||
// Rather than return some half-baked version of these objects (e.g.
|
||||
// we a null effect attribute) we simply don't provide access to animations
|
||||
// whose effect refers to a pseudo-element until we can support them
|
||||
// properly.
|
||||
for (nsIContent* node = nsINode::GetFirstChild();
|
||||
node;
|
||||
node = node->GetNextNode(this)) {
|
||||
if (!node->IsElement()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
node->AsElement()->GetAnimationsUnsorted(aAnimations);
|
||||
}
|
||||
|
||||
// Sort animations by priority
|
||||
aAnimations.Sort(AnimationPtrComparator<RefPtr<Animation>>());
|
||||
}
|
||||
|
||||
/* Return true if the document is in the focused top-level window, and is an
|
||||
* ancestor of the focused DOMWindow. */
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -787,6 +787,8 @@ public:
|
|||
|
||||
static bool IsWebAnimationsEnabled(JSContext* aCx, JSObject* aObject);
|
||||
virtual mozilla::dom::DocumentTimeline* Timeline() override;
|
||||
virtual void GetAnimations(
|
||||
nsTArray<RefPtr<mozilla::dom::Animation>>& aAnimations) override;
|
||||
|
||||
virtual nsresult SetSubDocumentFor(Element* aContent,
|
||||
nsIDocument* aSubDoc) override;
|
||||
|
|
|
@ -1799,10 +1799,13 @@ nsFrameLoader::MaybeCreateDocShell()
|
|||
}
|
||||
|
||||
if (!userContextIdStr.IsEmpty()) {
|
||||
nsresult err;
|
||||
nsDocShell * ds = nsDocShell::Cast(mDocShell);
|
||||
ds->SetUserContextId(userContextIdStr.ToInteger(&err));
|
||||
NS_ENSURE_SUCCESS(err, err);
|
||||
nsresult rv;
|
||||
uint32_t userContextId =
|
||||
static_cast<uint32_t>(userContextIdStr.ToInteger(&rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mDocShell->SetUserContextId(userContextId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// Inform our docShell that it has a new child.
|
||||
|
@ -3085,19 +3088,17 @@ nsFrameLoader::GetNewTabContext(MutableTabContext* aTabContext,
|
|||
|
||||
// set the userContextId on the attrs before we pass them into
|
||||
// the tab context
|
||||
if (mOwnerContent) {
|
||||
nsAutoString userContextIdStr;
|
||||
if (mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::usercontextid)) {
|
||||
mOwnerContent->GetAttr(kNameSpaceID_None,
|
||||
nsGkAtoms::usercontextid,
|
||||
userContextIdStr);
|
||||
}
|
||||
if (!userContextIdStr.IsEmpty()) {
|
||||
nsresult err;
|
||||
uint32_t userContextId = userContextIdStr.ToInteger(&err);
|
||||
NS_ENSURE_SUCCESS(err, err);
|
||||
attrs.mUserContextId = userContextId;
|
||||
}
|
||||
nsAutoString userContextIdStr;
|
||||
if (mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::usercontextid)) {
|
||||
mOwnerContent->GetAttr(kNameSpaceID_None,
|
||||
nsGkAtoms::usercontextid,
|
||||
userContextIdStr);
|
||||
}
|
||||
if (!userContextIdStr.IsEmpty()) {
|
||||
nsresult err;
|
||||
uint32_t userContextId = userContextIdStr.ToInteger(&err);
|
||||
NS_ENSURE_SUCCESS(err, err);
|
||||
attrs.mUserContextId = userContextId;
|
||||
}
|
||||
|
||||
bool tabContextUpdated =
|
||||
|
|
|
@ -6250,6 +6250,7 @@ nsGlobalWindow::Dump(const nsAString& aStr)
|
|||
#endif
|
||||
|
||||
if (cstr) {
|
||||
MOZ_LOG(nsContentUtils::DOMDumpLog(), LogLevel::Debug, ("[Window.Dump] %s", cstr));
|
||||
#ifdef XP_WIN
|
||||
PrintToDebugger(cstr);
|
||||
#endif
|
||||
|
|
|
@ -103,6 +103,7 @@ class Rule;
|
|||
} // namespace css
|
||||
|
||||
namespace dom {
|
||||
class Animation;
|
||||
class AnonymousContent;
|
||||
class Attr;
|
||||
class BoxObject;
|
||||
|
@ -2156,6 +2157,9 @@ public:
|
|||
|
||||
virtual mozilla::dom::DocumentTimeline* Timeline() = 0;
|
||||
|
||||
virtual void GetAnimations(
|
||||
nsTArray<RefPtr<mozilla::dom::Animation>>& aAnimations) = 0;
|
||||
|
||||
nsresult ScheduleFrameRequestCallback(mozilla::dom::FrameRequestCallback& aCallback,
|
||||
int32_t *aHandle);
|
||||
void CancelFrameRequestCallback(int32_t aHandle);
|
||||
|
|
|
@ -93,8 +93,7 @@ ThrowErrorMessage(JSContext* aCx, const ErrNum aErrorNumber, ...)
|
|||
|
||||
bool
|
||||
ThrowInvalidThis(JSContext* aCx, const JS::CallArgs& aArgs,
|
||||
const ErrNum aErrorNumber,
|
||||
const char* aInterfaceName)
|
||||
bool aSecurityError, const char* aInterfaceName)
|
||||
{
|
||||
NS_ConvertASCIItoUTF16 ifaceName(aInterfaceName);
|
||||
// This should only be called for DOM methods/getters/setters, which
|
||||
|
@ -109,19 +108,22 @@ ThrowInvalidThis(JSContext* aCx, const JS::CallArgs& aArgs,
|
|||
if (!funcNameStr.init(aCx, funcName)) {
|
||||
return false;
|
||||
}
|
||||
MOZ_RELEASE_ASSERT(GetErrorArgCount(aErrorNumber) <= 2);
|
||||
const ErrNum errorNumber = aSecurityError ?
|
||||
MSG_METHOD_THIS_UNWRAPPING_DENIED :
|
||||
MSG_METHOD_THIS_DOES_NOT_IMPLEMENT_INTERFACE;
|
||||
MOZ_RELEASE_ASSERT(GetErrorArgCount(errorNumber) <= 2);
|
||||
JS_ReportErrorNumberUC(aCx, GetErrorMessage, nullptr,
|
||||
static_cast<const unsigned>(aErrorNumber),
|
||||
static_cast<const unsigned>(errorNumber),
|
||||
funcNameStr.get(), ifaceName.get());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ThrowInvalidThis(JSContext* aCx, const JS::CallArgs& aArgs,
|
||||
const ErrNum aErrorNumber,
|
||||
bool aSecurityError,
|
||||
prototypes::ID aProtoId)
|
||||
{
|
||||
return ThrowInvalidThis(aCx, aArgs, aErrorNumber,
|
||||
return ThrowInvalidThis(aCx, aArgs, aSecurityError,
|
||||
NamesOfInterfacesWithProtos(aProtoId));
|
||||
}
|
||||
|
||||
|
@ -2627,9 +2629,7 @@ GenericBindingGetter(JSContext* cx, unsigned argc, JS::Value* vp)
|
|||
const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
|
||||
prototypes::ID protoID = static_cast<prototypes::ID>(info->protoID);
|
||||
if (!args.thisv().isObject()) {
|
||||
return ThrowInvalidThis(cx, args,
|
||||
MSG_GETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE,
|
||||
protoID);
|
||||
return ThrowInvalidThis(cx, args, false, protoID);
|
||||
}
|
||||
JS::Rooted<JSObject*> obj(cx, &args.thisv().toObject());
|
||||
|
||||
|
@ -2638,7 +2638,7 @@ GenericBindingGetter(JSContext* cx, unsigned argc, JS::Value* vp)
|
|||
nsresult rv = UnwrapObject<void>(obj, self, protoID, info->depth);
|
||||
if (NS_FAILED(rv)) {
|
||||
return ThrowInvalidThis(cx, args,
|
||||
GetInvalidThisErrorForGetter(rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO),
|
||||
rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO,
|
||||
protoID);
|
||||
}
|
||||
}
|
||||
|
@ -2661,9 +2661,7 @@ GenericBindingSetter(JSContext* cx, unsigned argc, JS::Value* vp)
|
|||
const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
|
||||
prototypes::ID protoID = static_cast<prototypes::ID>(info->protoID);
|
||||
if (!args.thisv().isObject()) {
|
||||
return ThrowInvalidThis(cx, args,
|
||||
MSG_SETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE,
|
||||
protoID);
|
||||
return ThrowInvalidThis(cx, args, false, protoID);
|
||||
}
|
||||
JS::Rooted<JSObject*> obj(cx, &args.thisv().toObject());
|
||||
|
||||
|
@ -2672,7 +2670,7 @@ GenericBindingSetter(JSContext* cx, unsigned argc, JS::Value* vp)
|
|||
nsresult rv = UnwrapObject<void>(obj, self, protoID, info->depth);
|
||||
if (NS_FAILED(rv)) {
|
||||
return ThrowInvalidThis(cx, args,
|
||||
GetInvalidThisErrorForSetter(rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO),
|
||||
rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO,
|
||||
protoID);
|
||||
}
|
||||
}
|
||||
|
@ -2698,9 +2696,7 @@ GenericBindingMethod(JSContext* cx, unsigned argc, JS::Value* vp)
|
|||
const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
|
||||
prototypes::ID protoID = static_cast<prototypes::ID>(info->protoID);
|
||||
if (!args.thisv().isObject()) {
|
||||
return ThrowInvalidThis(cx, args,
|
||||
MSG_METHOD_THIS_DOES_NOT_IMPLEMENT_INTERFACE,
|
||||
protoID);
|
||||
return ThrowInvalidThis(cx, args, false, protoID);
|
||||
}
|
||||
JS::Rooted<JSObject*> obj(cx, &args.thisv().toObject());
|
||||
|
||||
|
@ -2709,7 +2705,7 @@ GenericBindingMethod(JSContext* cx, unsigned argc, JS::Value* vp)
|
|||
nsresult rv = UnwrapObject<void>(obj, self, protoID, info->depth);
|
||||
if (NS_FAILED(rv)) {
|
||||
return ThrowInvalidThis(cx, args,
|
||||
GetInvalidThisErrorForMethod(rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO),
|
||||
rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO,
|
||||
protoID);
|
||||
}
|
||||
}
|
||||
|
@ -2736,9 +2732,7 @@ GenericPromiseReturningBindingMethod(JSContext* cx, unsigned argc, JS::Value* vp
|
|||
const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
|
||||
prototypes::ID protoID = static_cast<prototypes::ID>(info->protoID);
|
||||
if (!args.thisv().isObject()) {
|
||||
ThrowInvalidThis(cx, args,
|
||||
MSG_METHOD_THIS_DOES_NOT_IMPLEMENT_INTERFACE,
|
||||
protoID);
|
||||
ThrowInvalidThis(cx, args, false, protoID);
|
||||
return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
|
||||
args.rval());
|
||||
}
|
||||
|
@ -2748,8 +2742,7 @@ GenericPromiseReturningBindingMethod(JSContext* cx, unsigned argc, JS::Value* vp
|
|||
{
|
||||
nsresult rv = UnwrapObject<void>(obj, self, protoID, info->depth);
|
||||
if (NS_FAILED(rv)) {
|
||||
ThrowInvalidThis(cx, args,
|
||||
GetInvalidThisErrorForMethod(rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO),
|
||||
ThrowInvalidThis(cx, args, rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO,
|
||||
protoID);
|
||||
return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
|
||||
args.rval());
|
||||
|
|
|
@ -61,36 +61,13 @@ UnwrapArg(JS::Handle<JSObject*> src, Interface** ppArg)
|
|||
reinterpret_cast<void**>(ppArg));
|
||||
}
|
||||
|
||||
inline const ErrNum
|
||||
GetInvalidThisErrorForMethod(bool aSecurityError)
|
||||
{
|
||||
return aSecurityError ? MSG_METHOD_THIS_UNWRAPPING_DENIED :
|
||||
MSG_METHOD_THIS_DOES_NOT_IMPLEMENT_INTERFACE;
|
||||
}
|
||||
|
||||
inline const ErrNum
|
||||
GetInvalidThisErrorForGetter(bool aSecurityError)
|
||||
{
|
||||
return aSecurityError ? MSG_GETTER_THIS_UNWRAPPING_DENIED :
|
||||
MSG_GETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE;
|
||||
}
|
||||
|
||||
inline const ErrNum
|
||||
GetInvalidThisErrorForSetter(bool aSecurityError)
|
||||
{
|
||||
return aSecurityError ? MSG_SETTER_THIS_UNWRAPPING_DENIED :
|
||||
MSG_SETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE;
|
||||
}
|
||||
bool
|
||||
ThrowInvalidThis(JSContext* aCx, const JS::CallArgs& aArgs,
|
||||
bool aSecurityError, const char* aInterfaceName);
|
||||
|
||||
bool
|
||||
ThrowInvalidThis(JSContext* aCx, const JS::CallArgs& aArgs,
|
||||
const ErrNum aErrorNumber,
|
||||
const char* aInterfaceName);
|
||||
|
||||
bool
|
||||
ThrowInvalidThis(JSContext* aCx, const JS::CallArgs& aArgs,
|
||||
const ErrNum aErrorNumber,
|
||||
prototypes::ID aProtoId);
|
||||
bool aSecurityError, prototypes::ID aProtoId);
|
||||
|
||||
// Returns true if the JSClass is used for DOM objects.
|
||||
inline bool
|
||||
|
|
|
@ -8105,7 +8105,7 @@ class CGGenericMethod(CGAbstractBindingMethod):
|
|||
"""
|
||||
def __init__(self, descriptor, allowCrossOriginThis=False):
|
||||
unwrapFailureCode = (
|
||||
'return ThrowInvalidThis(cx, args, GetInvalidThisErrorForMethod(%%(securityError)s), "%s");\n' %
|
||||
'return ThrowInvalidThis(cx, args, %%(securityError)s, "%s");\n' %
|
||||
descriptor.interface.identifier.name)
|
||||
name = "genericCrossOriginMethod" if allowCrossOriginThis else "genericMethod"
|
||||
CGAbstractBindingMethod.__init__(self, descriptor, name,
|
||||
|
@ -8136,7 +8136,7 @@ class CGGenericPromiseReturningMethod(CGAbstractBindingMethod):
|
|||
"""
|
||||
def __init__(self, descriptor):
|
||||
unwrapFailureCode = dedent("""
|
||||
ThrowInvalidThis(cx, args, GetInvalidThisErrorForMethod(%%(securityError)s), "%s");\n
|
||||
ThrowInvalidThis(cx, args, %%(securityError)s, "%s");\n
|
||||
return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
|
||||
args.rval());\n""" %
|
||||
descriptor.interface.identifier.name)
|
||||
|
@ -8477,7 +8477,7 @@ class CGGenericGetter(CGAbstractBindingMethod):
|
|||
else:
|
||||
name = "genericGetter"
|
||||
unwrapFailureCode = (
|
||||
'return ThrowInvalidThis(cx, args, GetInvalidThisErrorForGetter(%%(securityError)s), "%s");\n' %
|
||||
'return ThrowInvalidThis(cx, args, %%(securityError)s, "%s");\n' %
|
||||
descriptor.interface.identifier.name)
|
||||
CGAbstractBindingMethod.__init__(self, descriptor, name, JSNativeArguments(),
|
||||
unwrapFailureCode,
|
||||
|
@ -8608,7 +8608,7 @@ class CGGenericSetter(CGAbstractBindingMethod):
|
|||
else:
|
||||
name = "genericSetter"
|
||||
unwrapFailureCode = (
|
||||
'return ThrowInvalidThis(cx, args, GetInvalidThisErrorForSetter(%%(securityError)s), "%s");\n' %
|
||||
'return ThrowInvalidThis(cx, args, %%(securityError)s, "%s");\n' %
|
||||
descriptor.interface.identifier.name)
|
||||
|
||||
CGAbstractBindingMethod.__init__(self, descriptor, name, JSNativeArguments(),
|
||||
|
|
|
@ -29,10 +29,6 @@ MSG_DEF(MSG_NOT_CALLABLE, 1, JSEXN_TYPEERR, "{0} is not callable.")
|
|||
MSG_DEF(MSG_DOES_NOT_IMPLEMENT_INTERFACE, 2, JSEXN_TYPEERR, "{0} does not implement interface {1}.")
|
||||
MSG_DEF(MSG_METHOD_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, JSEXN_TYPEERR, "'{0}' called on an object that does not implement interface {1}.")
|
||||
MSG_DEF(MSG_METHOD_THIS_UNWRAPPING_DENIED, 1, JSEXN_TYPEERR, "Permission to call '{0}' denied.")
|
||||
MSG_DEF(MSG_GETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, JSEXN_TYPEERR, "'{0}' getter called on an object that does not implement interface {1}.")
|
||||
MSG_DEF(MSG_GETTER_THIS_UNWRAPPING_DENIED, 1, JSEXN_TYPEERR, "Permission to call '{0}' getter denied.")
|
||||
MSG_DEF(MSG_SETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, JSEXN_TYPEERR, "'{0}' setter called on an object that does not implement interface {1}.")
|
||||
MSG_DEF(MSG_SETTER_THIS_UNWRAPPING_DENIED, 1, JSEXN_TYPEERR, "Permission to call '{0}' setter denied.")
|
||||
MSG_DEF(MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 1, JSEXN_TYPEERR, "\"this\" object does not implement interface {0}.")
|
||||
MSG_DEF(MSG_NOT_IN_UNION, 2, JSEXN_TYPEERR, "{0} could not be converted to any of: {1}.")
|
||||
MSG_DEF(MSG_ILLEGAL_CONSTRUCTOR, 0, JSEXN_TYPEERR, "Illegal constructor.")
|
||||
|
|
|
@ -18,10 +18,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=882653
|
|||
"'appendChild' called on an object that does not implement interface Node.",
|
||||
"bogus method this object" ],
|
||||
[ 'Object.getOwnPropertyDescriptor(Document.prototype, "documentElement").get.call({})',
|
||||
"'documentElement' getter called on an object that does not implement interface Document.",
|
||||
"'get documentElement' called on an object that does not implement interface Document.",
|
||||
"bogus getter this object" ],
|
||||
[ 'Object.getOwnPropertyDescriptor(Element.prototype, "innerHTML").set.call({})',
|
||||
"'innerHTML' setter called on an object that does not implement interface Element.",
|
||||
"'set innerHTML' called on an object that does not implement interface Element.",
|
||||
"bogus setter this object" ],
|
||||
[ 'document.documentElement.appendChild(5)',
|
||||
"Argument 1 of Node.appendChild is not an object.",
|
||||
|
|
Двоичный файл не отображается.
|
@ -0,0 +1,136 @@
|
|||
"use strict";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var tests = [false /* INPROC */, true /* OOP */];
|
||||
var rootURI = "http://test/chrome/dom/browser-element/mochitest/";
|
||||
var manifestURI = rootURI + "multipleAudioChannels_manifest.webapp";
|
||||
var srcURI = rootURI + "file_browserElement_MultipleAudioChannels.html";
|
||||
var generator = startTest();
|
||||
var app = null;
|
||||
var channelsNum = 2;
|
||||
|
||||
addLoadEvent(() => {
|
||||
SpecialPowers.pushPermissions(
|
||||
[{ "type": "webapps-manage", "allow": 1, "context": document },
|
||||
{ "type": "browser", "allow": 1, "context": document },
|
||||
{ "type": "embed-apps", "allow": 1, "context": document }],
|
||||
function() {
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{'set': [["dom.mozBrowserFramesEnabled", true],
|
||||
["dom.webapps.useCurrentProfile", true],
|
||||
["media.useAudioChannelAPI", true],
|
||||
["b2g.system_manifest_url", "http://mochi.test:8888/manifest.webapp"]]},
|
||||
() => { generator.next(); })
|
||||
});
|
||||
});
|
||||
|
||||
function error(message) {
|
||||
ok(false, message);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function continueTest() {
|
||||
try {
|
||||
generator.next();
|
||||
} catch (e if e instanceof StopIteration) {
|
||||
error("Stop test because of exception!");
|
||||
}
|
||||
}
|
||||
|
||||
function showTestInfo(aOOPCEnabled) {
|
||||
if (aOOPCEnabled) {
|
||||
info("=== Start OOP testing ===");
|
||||
} else {
|
||||
info("=== Start INPROC testing ===");
|
||||
}
|
||||
}
|
||||
|
||||
function uninstallApp(aApp) {
|
||||
if (aApp) {
|
||||
var request = navigator.mozApps.mgmt.uninstall(app);
|
||||
app = null;
|
||||
request.onerror = () => {
|
||||
error("Uninstall app failed!");
|
||||
};
|
||||
request.onsuccess = () => {
|
||||
is(request.result, manifestURI, "App uninstalled.");
|
||||
runNextTest();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function runTest(aOOPCEnabled) {
|
||||
var request = navigator.mozApps.install(manifestURI, {});
|
||||
request.onerror = () => {
|
||||
error("Install app failed!");
|
||||
};
|
||||
|
||||
request.onsuccess = () => {
|
||||
app = request.result;
|
||||
ok(app, "App is installed.");
|
||||
is(app.manifestURL, manifestURI, "App manifest url is correct.");
|
||||
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.setAttribute('mozbrowser', true);
|
||||
iframe.setAttribute('remote', aOOPCEnabled);
|
||||
iframe.setAttribute('mozapp', manifestURI);
|
||||
iframe.src = srcURI;
|
||||
|
||||
iframe.addEventListener('mozbrowserloadend', () => {
|
||||
var channels = iframe.allowedAudioChannels;
|
||||
is(channels.length, channelsNum, "Have two channels.");
|
||||
|
||||
var activeCounter = 0;
|
||||
for (var idx = 0; idx < channelsNum; idx++) {
|
||||
let ac = channels[idx];
|
||||
ok(ac instanceof BrowserElementAudioChannel, "Correct class.");
|
||||
ok("getMuted" in ac, "ac.getMuted exists");
|
||||
ok("onactivestatechanged" in ac, "ac.onactivestatechanged exists");
|
||||
|
||||
if (ac.name == "normal" || ac.name == "content") {
|
||||
ok(true, "Get correct channel type.");
|
||||
} else {
|
||||
error("Get unexpected channel type!");
|
||||
}
|
||||
|
||||
ac.getMuted().onsuccess = (e) => {
|
||||
is(e.target.result, false, "Channel is unmuted.")
|
||||
}
|
||||
|
||||
ac.onactivestatechanged = () => {
|
||||
ok(true, "Receive activestatechanged event from " + ac.name);
|
||||
ac.onactivestatechanged = null;
|
||||
if (++activeCounter == channelsNum) {
|
||||
document.body.removeChild(iframe);
|
||||
uninstallApp(app);
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
document.body.appendChild(iframe);
|
||||
};
|
||||
}
|
||||
|
||||
function runNextTest() {
|
||||
if (tests.length) {
|
||||
var isEnabledOOP = tests.shift();
|
||||
showTestInfo(isEnabledOOP);
|
||||
runTest(isEnabledOOP);
|
||||
} else {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
function startTest() {
|
||||
SpecialPowers.setAllAppsLaunchable(true);
|
||||
SpecialPowers.autoConfirmAppInstall(continueTest);
|
||||
yield undefined;
|
||||
|
||||
SpecialPowers.autoConfirmAppUninstall(continueTest);
|
||||
yield undefined;
|
||||
|
||||
runNextTest();
|
||||
yield undefined;
|
||||
}
|
|
@ -2,9 +2,15 @@
|
|||
skip-if = buildapp == 'mulet' || (buildapp == 'b2g' && (toolkit != 'gonk' || debug))
|
||||
|
||||
support-files =
|
||||
audio.ogg
|
||||
browserElement_MultipleAudioChannels.js
|
||||
browserElement_NotifyChannel.js
|
||||
file_browserElement_MultipleAudioChannels.html
|
||||
file_browserElement_NotifyChannel.html
|
||||
manifest.webapp
|
||||
manifest.webapp^headers^
|
||||
multipleAudioChannels_manifest.webapp
|
||||
multipleAudioChannels_manifest.webapp^headers^
|
||||
|
||||
[test_browserElement_MultipleAudioChannels.html]
|
||||
[test_browserElement_NotifyChannel.html]
|
|
@ -0,0 +1,12 @@
|
|||
<html>
|
||||
<body>
|
||||
<script>
|
||||
var audio1 = new Audio("audio.ogg");
|
||||
var audio2 = new Audio("audio.ogg");
|
||||
audio2.mozAudioChannelType = "content";
|
||||
|
||||
audio1.play();
|
||||
audio2.play();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,7 +1,7 @@
|
|||
[DEFAULT]
|
||||
skip-if = buildapp == 'mulet' || (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) || e10s
|
||||
support-files =
|
||||
../../../browser/base/content/test/general/audio.ogg
|
||||
audio.ogg
|
||||
../../../dom/media/test/short-video.ogv
|
||||
async.js
|
||||
browserElementTestHelpers.js
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name": "Multiple audio channels test",
|
||||
"launch_path": "/index.html",
|
||||
"permissions": {
|
||||
"audio-channel-content": {}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
Content-Type: application/manifest+json
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for multiple audio channels.</title>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/chrome-harness.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.7" src="browserElement_MultipleAudioChannels.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -11,19 +11,26 @@
|
|||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function runTest() {
|
||||
var registration;
|
||||
|
||||
window.onmessage = function(evt) {
|
||||
var msg = evt.data || {};
|
||||
if (msg.type == "test") {
|
||||
ok(msg.result, msg.name);
|
||||
}
|
||||
if (msg.type == "finish") {
|
||||
SimpleTest.finish();
|
||||
registration.unregister().then(function() {
|
||||
SimpleTest.finish();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
navigator.serviceWorker.register('offscreencanvas.js', { scope: "."})
|
||||
// Wait until the service worker is active.
|
||||
.then(navigator.serviceWorker.ready)
|
||||
.then(function(swr) {
|
||||
registration = swr;
|
||||
return navigator.serviceWorker.ready;
|
||||
})
|
||||
// ...and then show the interface for the commands once it's ready.
|
||||
.then(function() {
|
||||
iframe = document.createElement("iframe");
|
||||
|
|
|
@ -233,7 +233,7 @@ EventListenerManager::AddEventListenerInternal(
|
|||
MOZ_ASSERT(// Main thread
|
||||
(NS_IsMainThread() && aEventMessage && aTypeAtom) ||
|
||||
// non-main-thread
|
||||
(!NS_IsMainThread() && aEventMessage && !aTypeString.IsEmpty()) ||
|
||||
(!NS_IsMainThread() && aEventMessage) ||
|
||||
aAllEvents, "Missing type"); // all-events listener
|
||||
|
||||
if (!aListenerHolder || mClearingListeners) {
|
||||
|
|
|
@ -244,9 +244,7 @@ function createToPathHandler(server, path) {
|
|||
// createPingPathHandler() defined below to ensure all headers are sent
|
||||
// and received as expected.
|
||||
function createPingPathHandlers(server, paths, lazyHeaders) {
|
||||
return [
|
||||
createPingPathHandler(server, path, lazyHeaders) for (path of paths)
|
||||
]
|
||||
return Array.from(paths, (path) => createPingPathHandler(server, path, lazyHeaders));
|
||||
}
|
||||
|
||||
// Registers a path handler for the given server that will receive pings as
|
||||
|
|
|
@ -478,7 +478,8 @@ ADTSTrackDemuxer::FastSeek(const media::TimeUnit& aTime)
|
|||
{
|
||||
ADTSLOG("FastSeek(%" PRId64 ") avgFrameLen=%f mNumParsedFrames=%" PRIu64
|
||||
" mFrameIndex=%" PRId64 " mOffset=%" PRIu64,
|
||||
aTime, AverageFrameLength(), mNumParsedFrames, mFrameIndex, mOffset);
|
||||
aTime.ToMicroseconds(), AverageFrameLength(), mNumParsedFrames,
|
||||
mFrameIndex, mOffset);
|
||||
|
||||
const int64_t firstFrameOffset = mParser->FirstFrame().Offset();
|
||||
if (!aTime.ToMicroseconds()) {
|
||||
|
@ -510,7 +511,8 @@ ADTSTrackDemuxer::ScanUntil(const media::TimeUnit& aTime)
|
|||
{
|
||||
ADTSLOG("ScanUntil(%" PRId64 ") avgFrameLen=%f mNumParsedFrames=%" PRIu64
|
||||
" mFrameIndex=%" PRId64 " mOffset=%" PRIu64,
|
||||
aTime, AverageFrameLength(), mNumParsedFrames, mFrameIndex, mOffset);
|
||||
aTime.ToMicroseconds(), AverageFrameLength(), mNumParsedFrames,
|
||||
mFrameIndex, mOffset);
|
||||
|
||||
if (!aTime.ToMicroseconds()) {
|
||||
return FastSeek(aTime);
|
||||
|
@ -523,13 +525,13 @@ ADTSTrackDemuxer::ScanUntil(const media::TimeUnit& aTime)
|
|||
while (SkipNextFrame(FindNextFrame()) && Duration(mFrameIndex + 1) < aTime) {
|
||||
ADTSLOGV("ScanUntil* avgFrameLen=%f mNumParsedFrames=%" PRIu64
|
||||
" mFrameIndex=%" PRId64 " mOffset=%" PRIu64 " Duration=%" PRId64,
|
||||
aTime, AverageFrameLength(), mNumParsedFrames, mFrameIndex,
|
||||
mOffset, Duration(mFrameIndex + 1));
|
||||
AverageFrameLength(), mNumParsedFrames, mFrameIndex,
|
||||
mOffset, Duration(mFrameIndex + 1).ToMicroseconds());
|
||||
}
|
||||
|
||||
ADTSLOG("ScanUntil End avgFrameLen=%f mNumParsedFrames=%" PRIu64
|
||||
" mFrameIndex=%" PRId64 " mOffset=%" PRIu64,
|
||||
aTime, AverageFrameLength(), mNumParsedFrames, mFrameIndex, mOffset);
|
||||
AverageFrameLength(), mNumParsedFrames, mFrameIndex, mOffset);
|
||||
|
||||
return Duration(mFrameIndex);
|
||||
}
|
||||
|
|
|
@ -198,7 +198,8 @@ TimeUnit
|
|||
MP3TrackDemuxer::FastSeek(const TimeUnit& aTime) {
|
||||
MP3LOG("FastSeek(%" PRId64 ") avgFrameLen=%f mNumParsedFrames=%" PRIu64
|
||||
" mFrameIndex=%" PRId64 " mOffset=%" PRIu64,
|
||||
aTime, AverageFrameLength(), mNumParsedFrames, mFrameIndex, mOffset);
|
||||
aTime.ToMicroseconds(), AverageFrameLength(), mNumParsedFrames,
|
||||
mFrameIndex, mOffset);
|
||||
|
||||
const auto& vbr = mParser.VBRInfo();
|
||||
if (!aTime.ToMicroseconds()) {
|
||||
|
@ -234,7 +235,8 @@ TimeUnit
|
|||
MP3TrackDemuxer::ScanUntil(const TimeUnit& aTime) {
|
||||
MP3LOG("ScanUntil(%" PRId64 ") avgFrameLen=%f mNumParsedFrames=%" PRIu64
|
||||
" mFrameIndex=%" PRId64 " mOffset=%" PRIu64,
|
||||
aTime, AverageFrameLength(), mNumParsedFrames, mFrameIndex, mOffset);
|
||||
aTime.ToMicroseconds(), AverageFrameLength(), mNumParsedFrames,
|
||||
mFrameIndex, mOffset);
|
||||
|
||||
if (!aTime.ToMicroseconds()) {
|
||||
return FastSeek(aTime);
|
||||
|
@ -253,13 +255,13 @@ MP3TrackDemuxer::ScanUntil(const TimeUnit& aTime) {
|
|||
nextRange = FindNextFrame();
|
||||
MP3LOGV("ScanUntil* avgFrameLen=%f mNumParsedFrames=%" PRIu64
|
||||
" mFrameIndex=%" PRId64 " mOffset=%" PRIu64 " Duration=%" PRId64,
|
||||
aTime, AverageFrameLength(), mNumParsedFrames, mFrameIndex,
|
||||
mOffset, Duration(mFrameIndex + 1));
|
||||
AverageFrameLength(), mNumParsedFrames,
|
||||
mFrameIndex, mOffset, Duration(mFrameIndex + 1).ToMicroseconds());
|
||||
}
|
||||
|
||||
MP3LOG("ScanUntil End avgFrameLen=%f mNumParsedFrames=%" PRIu64
|
||||
" mFrameIndex=%" PRId64 " mOffset=%" PRIu64,
|
||||
aTime, AverageFrameLength(), mNumParsedFrames, mFrameIndex, mOffset);
|
||||
AverageFrameLength(), mNumParsedFrames, mFrameIndex, mOffset);
|
||||
|
||||
return SeekPosition();
|
||||
}
|
||||
|
|
|
@ -241,8 +241,6 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
|
|||
mSentFirstFrameLoadedEvent(false, "MediaDecoderStateMachine::mSentFirstFrameLoadedEvent"),
|
||||
mSentPlaybackEndedEvent(false),
|
||||
mOutputStreamManager(new OutputStreamManager()),
|
||||
mStreamSink(new DecodedStream(
|
||||
mTaskQueue, mAudioQueue, mVideoQueue, mOutputStreamManager)),
|
||||
mResource(aDecoder->GetResource()),
|
||||
mAudioOffloading(false),
|
||||
mBuffered(mTaskQueue, TimeIntervals(),
|
||||
|
@ -339,6 +337,9 @@ MediaDecoderStateMachine::InitializationTask(MediaDecoder* aDecoder)
|
|||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
|
||||
mStreamSink = new DecodedStream(mTaskQueue, mAudioQueue, mVideoQueue,
|
||||
mOutputStreamManager, mSameOriginMedia.Ref());
|
||||
|
||||
// Connect mirrors.
|
||||
mBuffered.Connect(mReader->CanonicalBuffered());
|
||||
mEstimatedDuration.Connect(aDecoder->CanonicalEstimatedDuration());
|
||||
|
@ -368,12 +369,8 @@ MediaDecoderStateMachine::InitializationTask(MediaDecoder* aDecoder)
|
|||
mWatchManager.Watch(mObservedDuration, &MediaDecoderStateMachine::RecomputeDuration);
|
||||
mWatchManager.Watch(mPlayState, &MediaDecoderStateMachine::PlayStateChanged);
|
||||
mWatchManager.Watch(mLogicallySeeking, &MediaDecoderStateMachine::LogicallySeekingChanged);
|
||||
mWatchManager.Watch(mSameOriginMedia, &MediaDecoderStateMachine::SameOriginMediaChanged);
|
||||
mWatchManager.Watch(mSentFirstFrameLoadedEvent, &MediaDecoderStateMachine::AdjustAudioThresholds);
|
||||
mWatchManager.Watch(mAudioCaptured, &MediaDecoderStateMachine::AdjustAudioThresholds);
|
||||
|
||||
// Propagate mSameOriginMedia to mDecodedStream.
|
||||
SameOriginMediaChanged();
|
||||
}
|
||||
|
||||
media::MediaSink*
|
||||
|
@ -1457,12 +1454,6 @@ void MediaDecoderStateMachine::LogicallySeekingChanged()
|
|||
ScheduleStateMachine();
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::SameOriginMediaChanged()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
mStreamSink->SetSameOrigin(mSameOriginMedia);
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::BufferedRangeUpdated()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
|
@ -2361,13 +2352,6 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
|
|||
// is restarted correctly.
|
||||
StopPlayback();
|
||||
|
||||
if (mState != DECODER_STATE_COMPLETED) {
|
||||
// While we're presenting a frame we can change state. Whatever changed
|
||||
// our state should have scheduled another state machine run.
|
||||
NS_ASSERTION(IsStateMachineScheduled(), "Must have timer scheduled");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mPlayState == MediaDecoder::PLAY_STATE_PLAYING &&
|
||||
!mSentPlaybackEndedEvent)
|
||||
{
|
||||
|
|
|
@ -507,9 +507,6 @@ protected:
|
|||
// Notification method invoked when mLogicallySeeking changes.
|
||||
void LogicallySeekingChanged();
|
||||
|
||||
// Notification method invoked when mSameOriginMedia changes.
|
||||
void SameOriginMediaChanged();
|
||||
|
||||
// Sets internal state which causes playback of media to pause.
|
||||
// The decoder monitor must be held.
|
||||
void StopPlayback();
|
||||
|
|
|
@ -2728,7 +2728,7 @@ MediaStreamGraph::GetInstance(MediaStreamGraph::GraphDriverType aGraphDriverRequ
|
|||
|
||||
STREAM_LOG(LogLevel::Debug,
|
||||
("Starting up MediaStreamGraph %p for channel %s",
|
||||
graph, AudioChannelValues::strings[channel]));
|
||||
graph, AudioChannelValues::strings[channel].value));
|
||||
}
|
||||
|
||||
return graph;
|
||||
|
|
|
@ -568,7 +568,7 @@ GMPStorageParent::GMPStorageParent(const nsCString& aNodeId,
|
|||
GMPParent* aPlugin)
|
||||
: mNodeId(aNodeId)
|
||||
, mPlugin(aPlugin)
|
||||
, mShutdown(false)
|
||||
, mShutdown(true)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -602,6 +602,7 @@ GMPStorageParent::Init()
|
|||
mStorage = MakeUnique<GMPMemoryStorage>();
|
||||
}
|
||||
|
||||
mShutdown = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ private:
|
|||
|
||||
const nsCString mNodeId;
|
||||
RefPtr<GMPParent> mPlugin;
|
||||
// True after Shutdown(), or if Init() has not completed successfully.
|
||||
bool mShutdown;
|
||||
};
|
||||
|
||||
|
|
|
@ -188,11 +188,12 @@ DecodedStreamData::SetPlaying(bool aPlaying)
|
|||
DecodedStream::DecodedStream(AbstractThread* aOwnerThread,
|
||||
MediaQueue<MediaData>& aAudioQueue,
|
||||
MediaQueue<MediaData>& aVideoQueue,
|
||||
OutputStreamManager* aOutputStreamManager)
|
||||
OutputStreamManager* aOutputStreamManager,
|
||||
const bool& aSameOrigin)
|
||||
: mOwnerThread(aOwnerThread)
|
||||
, mOutputStreamManager(aOutputStreamManager)
|
||||
, mPlaying(false)
|
||||
, mSameOrigin(false)
|
||||
, mSameOrigin(aSameOrigin)
|
||||
, mAudioQueue(aAudioQueue)
|
||||
, mVideoQueue(aVideoQueue)
|
||||
{
|
||||
|
@ -430,13 +431,6 @@ DecodedStream::SetPreservesPitch(bool aPreservesPitch)
|
|||
mParams.mPreservesPitch = aPreservesPitch;
|
||||
}
|
||||
|
||||
void
|
||||
DecodedStream::SetSameOrigin(bool aSameOrigin)
|
||||
{
|
||||
AssertOwnerThread();
|
||||
mSameOrigin = aSameOrigin;
|
||||
}
|
||||
|
||||
void
|
||||
DecodedStream::InitTracks()
|
||||
{
|
||||
|
|
|
@ -35,7 +35,8 @@ public:
|
|||
DecodedStream(AbstractThread* aOwnerThread,
|
||||
MediaQueue<MediaData>& aAudioQueue,
|
||||
MediaQueue<MediaData>& aVideoQueue,
|
||||
OutputStreamManager* aOutputStreamManager);
|
||||
OutputStreamManager* aOutputStreamManager,
|
||||
const bool& aSameOrigin);
|
||||
|
||||
// MediaSink functions.
|
||||
const PlaybackParams& GetPlaybackParams() const override;
|
||||
|
@ -60,9 +61,6 @@ public:
|
|||
bool IsStarted() const override;
|
||||
bool IsPlaying() const override;
|
||||
|
||||
// TODO: fix these functions that don't fit into the interface of MediaSink.
|
||||
void SetSameOrigin(bool aSameOrigin);
|
||||
|
||||
protected:
|
||||
virtual ~DecodedStream();
|
||||
|
||||
|
@ -98,7 +96,7 @@ private:
|
|||
RefPtr<GenericPromise> mFinishPromise;
|
||||
|
||||
bool mPlaying;
|
||||
bool mSameOrigin;
|
||||
const bool& mSameOrigin; // valid until Shutdown() is called.
|
||||
PlaybackParams mParams;
|
||||
|
||||
Maybe<int64_t> mStartTime;
|
||||
|
|
|
@ -35,6 +35,22 @@ FFmpegAudioDecoder<LIBAV_VER>::Init()
|
|||
: InitPromise::CreateAndReject(DecoderFailureReason::INIT_ERROR, __func__);
|
||||
}
|
||||
|
||||
void
|
||||
FFmpegAudioDecoder<LIBAV_VER>::InitCodecContext()
|
||||
{
|
||||
MOZ_ASSERT(mCodecContext);
|
||||
// We do not want to set this value to 0 as FFmpeg by default will
|
||||
// use the number of cores, which with our mozlibavutil get_cpu_count
|
||||
// isn't implemented.
|
||||
mCodecContext->thread_count = 1;
|
||||
// FFmpeg takes this as a suggestion for what format to use for audio samples.
|
||||
uint32_t major, minor;
|
||||
FFmpegRuntimeLinker::GetVersion(major, minor);
|
||||
// LibAV 0.8 produces rubbish float interleaved samples, request 16 bits audio.
|
||||
mCodecContext->request_sample_fmt =
|
||||
(major == 53) ? AV_SAMPLE_FMT_S16 : AV_SAMPLE_FMT_FLT;
|
||||
}
|
||||
|
||||
static UniquePtr<AudioDataValue[]>
|
||||
CopyAndPackAudio(AVFrame* aFrame, uint32_t aNumChannels, uint32_t aNumAFrames)
|
||||
{
|
||||
|
|
|
@ -28,6 +28,7 @@ public:
|
|||
RefPtr<InitPromise> Init() override;
|
||||
nsresult Input(MediaRawData* aSample) override;
|
||||
void ProcessDrain() override;
|
||||
void InitCodecContext() override;
|
||||
static AVCodecID GetCodecId(const nsACString& aMimeType);
|
||||
|
||||
private:
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
#include "mozilla/TaskQueue.h"
|
||||
|
||||
#include <string.h>
|
||||
#ifdef __GNUC__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "FFmpegLibs.h"
|
||||
#include "FFmpegLog.h"
|
||||
|
@ -32,7 +34,6 @@ FFmpegDataDecoder<LIBAV_VER>::FFmpegDataDecoder(FlushableTaskQueue* aTaskQueue,
|
|||
, mCodecID(aCodecID)
|
||||
, mMonitor("FFMpegaDataDecoder")
|
||||
, mIsFlushing(false)
|
||||
, mCodecParser(nullptr)
|
||||
{
|
||||
MOZ_COUNT_CTOR(FFmpegDataDecoder);
|
||||
}
|
||||
|
@ -40,31 +41,6 @@ FFmpegDataDecoder<LIBAV_VER>::FFmpegDataDecoder(FlushableTaskQueue* aTaskQueue,
|
|||
FFmpegDataDecoder<LIBAV_VER>::~FFmpegDataDecoder()
|
||||
{
|
||||
MOZ_COUNT_DTOR(FFmpegDataDecoder);
|
||||
if (mCodecParser) {
|
||||
av_parser_close(mCodecParser);
|
||||
mCodecParser = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* FFmpeg calls back to this function with a list of pixel formats it supports.
|
||||
* We choose a pixel format that we support and return it.
|
||||
* For now, we just look for YUV420P as it is the only non-HW accelerated format
|
||||
* supported by FFmpeg's H264 decoder.
|
||||
*/
|
||||
static PixelFormat
|
||||
ChoosePixelFormat(AVCodecContext* aCodecContext, const PixelFormat* aFormats)
|
||||
{
|
||||
FFMPEG_LOG("Choosing FFmpeg pixel format for video decoding.");
|
||||
for (; *aFormats > -1; aFormats++) {
|
||||
if (*aFormats == PIX_FMT_YUV420P || *aFormats == PIX_FMT_YUVJ420P) {
|
||||
FFMPEG_LOG("Requesting pixel format YUV420P.");
|
||||
return PIX_FMT_YUV420P;
|
||||
}
|
||||
}
|
||||
|
||||
NS_WARNING("FFmpeg does not share any supported pixel formats.");
|
||||
return PIX_FMT_NONE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -87,19 +63,7 @@ FFmpegDataDecoder<LIBAV_VER>::InitDecoder()
|
|||
|
||||
mCodecContext->opaque = this;
|
||||
|
||||
// FFmpeg takes this as a suggestion for what format to use for audio samples.
|
||||
uint32_t major, minor;
|
||||
FFmpegRuntimeLinker::GetVersion(major, minor);
|
||||
// LibAV 0.8 produces rubbish float interleaved samples, request 16 bits audio.
|
||||
mCodecContext->request_sample_fmt = major == 53 ?
|
||||
AV_SAMPLE_FMT_S16 : AV_SAMPLE_FMT_FLT;
|
||||
|
||||
// FFmpeg will call back to this to negotiate a video pixel format.
|
||||
mCodecContext->get_format = ChoosePixelFormat;
|
||||
|
||||
mCodecContext->thread_count = PR_GetNumberOfProcessors();
|
||||
mCodecContext->thread_type = FF_THREAD_SLICE | FF_THREAD_FRAME;
|
||||
mCodecContext->thread_safe_callbacks = false;
|
||||
InitCodecContext();
|
||||
|
||||
if (mExtraData) {
|
||||
mCodecContext->extradata_size = mExtraData->Length();
|
||||
|
@ -131,11 +95,6 @@ FFmpegDataDecoder<LIBAV_VER>::InitDecoder()
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mCodecParser = av_parser_init(mCodecID);
|
||||
if (mCodecParser) {
|
||||
mCodecParser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
|
||||
}
|
||||
|
||||
FFMPEG_LOG("FFmpeg init successful.");
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ protected:
|
|||
virtual void ProcessFlush();
|
||||
virtual void ProcessDrain() = 0;
|
||||
virtual void ProcessShutdown();
|
||||
virtual void InitCodecContext() {}
|
||||
AVFrame* PrepareFrame();
|
||||
nsresult InitDecoder();
|
||||
|
||||
|
@ -61,7 +62,6 @@ protected:
|
|||
// not required and so input samples on mTaskQueue need not be processed.
|
||||
// Cleared on mTaskQueue in ProcessDrain().
|
||||
Atomic<bool> mIsFlushing;
|
||||
AVCodecParserContext* mCodecParser;
|
||||
|
||||
private:
|
||||
static bool sFFmpegInitDone;
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче