Merge mozilla-central to fx-team

This commit is contained in:
Carsten "Tomcat" Book 2016-07-17 10:10:30 +02:00
Родитель c6670d980f a0992595d6
Коммит c735a88756
673 изменённых файлов: 9510 добавлений и 3969 удалений

Просмотреть файл

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1267887 - Build skew after updating rust mp4parse
Bug 1286754 - Update the version of rust used on Windows

Просмотреть файл

@ -86,10 +86,10 @@ xpcAccessible::IntlGeneric()
return static_cast<xpcAccessibleGeneric*>(this)->mIntl;
}
inline Accessible*
inline AccessibleOrProxy
xpcAccessibleHyperLink::Intl()
{
return static_cast<xpcAccessibleGeneric*>(this)->mIntl.AsAccessible();
return static_cast<xpcAccessibleGeneric*>(this)->mIntl;
}
inline Accessible*

Просмотреть файл

@ -6,6 +6,7 @@
#include "Accessible-inl.h"
#include "xpcAccessibleDocument.h"
#include "nsNetUtil.h"
using namespace mozilla::a11y;
@ -15,10 +16,20 @@ xpcAccessibleHyperLink::GetStartIndex(int32_t* aStartIndex)
NS_ENSURE_ARG_POINTER(aStartIndex);
*aStartIndex = 0;
if (!Intl())
if (Intl().IsNull())
return NS_ERROR_FAILURE;
*aStartIndex = Intl()->StartOffset();
if (Intl().IsAccessible()) {
*aStartIndex = Intl().AsAccessible()->StartOffset();
} else {
bool isIndexValid = false;
uint32_t startOffset = Intl().AsProxy()->StartOffset(&isIndexValid);
if (!isIndexValid)
return NS_ERROR_FAILURE;
*aStartIndex = startOffset;
}
return NS_OK;
}
@ -28,10 +39,20 @@ xpcAccessibleHyperLink::GetEndIndex(int32_t* aEndIndex)
NS_ENSURE_ARG_POINTER(aEndIndex);
*aEndIndex = 0;
if (!Intl())
if (Intl().IsNull())
return NS_ERROR_FAILURE;
*aEndIndex = Intl()->EndOffset();
if (Intl().IsAccessible()) {
*aEndIndex = Intl().AsAccessible()->EndOffset();
} else {
bool isIndexValid = false;
uint32_t endOffset = Intl().AsProxy()->EndOffset(&isIndexValid);
if (!isIndexValid)
return NS_ERROR_FAILURE;
*aEndIndex = endOffset;
}
return NS_OK;
}
@ -41,10 +62,20 @@ xpcAccessibleHyperLink::GetAnchorCount(int32_t* aAnchorCount)
NS_ENSURE_ARG_POINTER(aAnchorCount);
*aAnchorCount = 0;
if (!Intl())
if (Intl().IsNull())
return NS_ERROR_FAILURE;
*aAnchorCount = Intl()->AnchorCount();
if (Intl().IsAccessible()) {
*aAnchorCount = Intl().AsAccessible()->AnchorCount();
} else {
bool isCountValid = false;
uint32_t anchorCount = Intl().AsProxy()->AnchorCount(&isCountValid);
if (!isCountValid)
return NS_ERROR_FAILURE;
*aAnchorCount = anchorCount;
}
return NS_OK;
}
@ -53,13 +84,31 @@ xpcAccessibleHyperLink::GetURI(int32_t aIndex, nsIURI** aURI)
{
NS_ENSURE_ARG_POINTER(aURI);
if (!Intl())
if (Intl().IsNull())
return NS_ERROR_FAILURE;
if (aIndex < 0 || aIndex >= static_cast<int32_t>(Intl()->AnchorCount()))
if (aIndex < 0)
return NS_ERROR_INVALID_ARG;
RefPtr<nsIURI>(Intl()->AnchorURIAt(aIndex)).forget(aURI);
if (Intl().IsAccessible()) {
if (aIndex >= static_cast<int32_t>(Intl().AsAccessible()->AnchorCount()))
return NS_ERROR_INVALID_ARG;
RefPtr<nsIURI>(Intl().AsAccessible()->AnchorURIAt(aIndex)).forget(aURI);
} else {
nsCString spec;
bool isURIValid = false;
Intl().AsProxy()->AnchorURIAt(aIndex, spec, &isURIValid);
if (!isURIValid)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIURI> uri;
nsresult rv = NS_NewURI(getter_AddRefs(uri), spec);
NS_ENSURE_SUCCESS(rv, rv);
uri.forget(aURI);
}
return NS_OK;
}
@ -70,13 +119,21 @@ xpcAccessibleHyperLink::GetAnchor(int32_t aIndex, nsIAccessible** aAccessible)
NS_ENSURE_ARG_POINTER(aAccessible);
*aAccessible = nullptr;
if (!Intl())
if (Intl().IsNull())
return NS_ERROR_FAILURE;
if (aIndex < 0 || aIndex >= static_cast<int32_t>(Intl()->AnchorCount()))
if (aIndex < 0)
return NS_ERROR_INVALID_ARG;
NS_IF_ADDREF(*aAccessible = ToXPC(Intl()->AnchorAt(aIndex)));
if (Intl().IsAccessible()) {
if (aIndex >= static_cast<int32_t>(Intl().AsAccessible()->AnchorCount()))
return NS_ERROR_INVALID_ARG;
NS_IF_ADDREF(*aAccessible = ToXPC(Intl().AsAccessible()->AnchorAt(aIndex)));
} else {
NS_IF_ADDREF(*aAccessible = ToXPC(Intl().AsProxy()->AnchorAt(aIndex)));
}
return NS_OK;
}
@ -86,9 +143,14 @@ xpcAccessibleHyperLink::GetValid(bool* aValid)
NS_ENSURE_ARG_POINTER(aValid);
*aValid = false;
if (!Intl())
if (Intl().IsNull())
return NS_ERROR_FAILURE;
*aValid = Intl()->IsLinkValid();
if (Intl().IsAccessible()) {
*aValid = Intl().AsAccessible()->IsLinkValid();
} else {
*aValid = Intl().AsProxy()->IsLinkValid();
}
return NS_OK;
}

Просмотреть файл

@ -39,7 +39,7 @@ private:
xpcAccessibleHyperLink(const xpcAccessibleHyperLink&) = delete;
xpcAccessibleHyperLink& operator =(const xpcAccessibleHyperLink&) = delete;
Accessible* Intl();
AccessibleOrProxy Intl();
};
} // namespace a11y

Просмотреть файл

@ -13,7 +13,8 @@
HAS_MISC_RULE = True
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
JETPACK_PACKAGE_MANIFESTS += ['source/test/jetpack-package.ini']
JETPACK_PACKAGE_MANIFESTS += ['source/test/jetpack-package.ini',
'source/test/leak/jetpack-package.ini']
JETPACK_ADDON_MANIFESTS += ['source/test/addons/jetpack-addon.ini']
addons = [

Просмотреть файл

@ -8,6 +8,7 @@ module.metadata = {
};
var { emit, on, once, off, EVENT_TYPE_PATTERN } = require("./core");
const { Cu } = require("chrome");
// This module provides set of high order function for working with event
// streams (streams in a NodeJS style that dispatch data, end and error
@ -26,7 +27,7 @@ var refs = (function() {
})();
function transform(input, f) {
let output = {};
let output = new Output();
// Since event listeners don't prevent `input` to be GC-ed we wanna presrve
// it until `output` can be GC-ed. There for we add implicit reference which
@ -64,7 +65,7 @@ exports.map = map;
// into single event stream. Like flatten but time based rather than order
// based.
function merge(inputs) {
let output = {};
let output = new Output();
let open = 1;
let state = [];
output.state = state;
@ -107,13 +108,18 @@ exports.pipe = pipe;
// Shim signal APIs so other modules can be used as is.
const receive = (input, message) => {
if (input[receive])
input[receive](input, message);
else
emit(input, "data", message);
// Ideally our input will extend Input and already provide a weak value
// getter. If not, opportunistically shim the weak value getter on
// other types passed as the input.
if (!("value" in input)) {
Object.defineProperty(input, "value", WeakValueGetterSetter);
}
input.value = message;
};
receive.toString = () => "@@receive";
@ -151,7 +157,7 @@ const lift = (step, ...inputs) => {
let args = null;
let opened = inputs.length;
let started = false;
const output = {};
const output = new Output();
const init = () => {
args = [...inputs.map(input => input.value)];
output.value = step(...args);
@ -182,7 +188,8 @@ exports.lift = lift;
const merges = inputs => {
let opened = inputs.length;
let output = { value: inputs[0].value };
let output = new Output();
output.value = inputs[0].value;
inputs.forEach((input, index) => {
on(input, "data", data => receive(output, data));
on(input, "end", () => {
@ -225,12 +232,46 @@ Input.end = input => {
};
Input.prototype[end] = Input.end;
// The event channel system caches the last event seen as input.value.
// Unfortunately, if the last event is a DOM object this is a great way
// leak windows. Mitigate this by storing input.value using a weak
// reference. This allows the system to work for normal event processing
// while also allowing the objects to be reclaimed. It means, however,
// input.value cannot be accessed long after the event was dispatched.
const WeakValueGetterSetter = {
get: function() {
return this._weakValue ? this._weakValue.get() : this._simpleValue
},
set: function(v) {
if (v && typeof v === "object") {
this._weakValue = Cu.getWeakReference(v)
this._simpleValue = undefined;
return;
}
this._simpleValue = v;
this._weakValue = undefined;
},
}
Object.defineProperty(Input.prototype, "value", WeakValueGetterSetter);
exports.Input = Input;
// Define an Output type with a weak value getter for the transformation
// functions that produce new channels.
function Output() { }
Object.defineProperty(Output.prototype, "value", WeakValueGetterSetter);
exports.Output = Output;
const $source = "@@source";
const $outputs = "@@outputs";
exports.outputs = $outputs;
// NOTE: Passing DOM objects through a Reactor can cause them to leak
// when they get cached in this.value. We cannot use a weak reference
// in this case because the Reactor design expects to always have both the
// past and present value. If we allow past values to be collected the
// system breaks.
function Reactor(options={}) {
const {onStep, onStart, onEnd} = options;
if (onStep)

Просмотреть файл

@ -7,22 +7,40 @@ module.metadata = {
"stability": "unstable"
};
const { Ci } = require("chrome");
const { Ci, Cu } = require("chrome");
const { observe } = require("../event/chrome");
const { open } = require("../event/dom");
const { windows } = require("../window/utils");
const { filter, merge, map, expand } = require("../event/utils");
function documentMatches(weakWindow, event) {
let window = weakWindow.get();
return window && event.target === window.document;
}
function makeStrictDocumentFilter(window) {
// Note: Do not define a closure within this function. Otherwise
// you may leak the window argument.
let weak = Cu.getWeakReference(window);
return documentMatches.bind(null, weak);
}
function toEventWithDefaultViewTarget({type, target}) {
return { type: type, target: target.defaultView }
}
// Function registers single shot event listeners for relevant window events
// that forward events to exported event stream.
function eventsFor(window) {
// NOTE: Do no use pass a closure from this function into a stream
// transform function. You will capture the window in the
// closure and leak the window until the event stream is
// completely closed.
let interactive = open(window, "DOMContentLoaded", { capture: true });
let complete = open(window, "load", { capture: true });
let states = merge([interactive, complete]);
let changes = filter(states, ({target}) => target === window.document);
return map(changes, function({type, target}) {
return { type: type, target: target.defaultView }
});
let changes = filter(states, makeStrictDocumentFilter(window));
return map(changes, toEventWithDefaultViewTarget);
}
// In addition to observing windows that are open we also observe windows

Просмотреть файл

@ -0,0 +1,6 @@
[DEFAULT]
support-files =
leak-utils.js
[test-leak-window-events.js]
[test-leak-event-dom-closed-window.js]

Просмотреть файл

@ -0,0 +1,80 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { Cu, Ci } = require("chrome");
const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
const { SelfSupportBackend } = Cu.import("resource:///modules/SelfSupportBackend.jsm", {});
const Startup = Cu.import("resource://gre/modules/sdk/system/Startup.js", {}).exports;
// Adapted from the SpecialPowers.exactGC() code. We don't have a
// window to operate on so we cannot use the exact same logic. We
// use 6 GC iterations here as that is what is needed to clean up
// the windows we have tested with.
function gc() {
return new Promise(resolve => {
Cu.forceGC();
Cu.forceCC();
let count = 0;
function genGCCallback() {
Cu.forceCC();
return function() {
if (++count < 5) {
Cu.schedulePreciseGC(genGCCallback());
} else {
resolve();
}
}
}
Cu.schedulePreciseGC(genGCCallback());
});
}
// Execute the given test function and verify that we did not leak windows
// in the process. The test function must return a promise or be a generator.
// If the promise is resolved, or generator completes, with an sdk loader
// object then it will be unloaded after the memory measurements.
exports.asyncWindowLeakTest = function*(assert, asyncTestFunc) {
// SelfSupportBackend periodically tries to open windows. This can
// mess up our window leak detection below, so turn it off.
SelfSupportBackend.uninit();
// Wait for the browser to finish loading.
yield Startup.onceInitialized;
// Track windows that are opened in an array of weak references.
let weakWindows = [];
function windowObserver(subject, topic) {
let supportsWeak = subject.QueryInterface(Ci.nsISupportsWeakReference);
if (supportsWeak) {
weakWindows.push(Cu.getWeakReference(supportsWeak));
}
}
Services.obs.addObserver(windowObserver, "domwindowopened", false);
// Execute the body of the test.
let testLoader = yield asyncTestFunc(assert);
// Stop tracking new windows and attempt to GC any resources allocated
// by the test body.
Services.obs.removeObserver(windowObserver, "domwindowopened", false);
yield gc();
// Check to see if any of the windows we saw survived the GC. We consider
// these leaks.
assert.ok(weakWindows.length > 0, "should see at least one new window");
for (let i = 0; i < weakWindows.length; ++i) {
assert.equal(weakWindows[i].get(), null, "window " + i + " should be GC'd");
}
// Finally, unload the test body's loader if it provided one. We do this
// after our leak detection to avoid free'ing things on unload. Users
// don't tend to unload their addons very often, so we want to find leaks
// that happen while addons are in use.
if (testLoader) {
testLoader.unload();
}
}

Просмотреть файл

@ -0,0 +1,29 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
const { asyncWindowLeakTest } = require("./leak-utils");
const { Loader } = require('sdk/test/loader');
const openWindow = require("sdk/window/utils").open;
exports["test sdk/event/dom does not leak when attached to closed window"] = function*(assert) {
yield asyncWindowLeakTest(assert, _ => {
return new Promise(resolve => {
let loader = Loader(module);
let { open } = loader.require('sdk/event/dom');
let w = openWindow();
w.addEventListener("DOMWindowClose", function windowClosed(evt) {
w.removeEventListener("DOMWindowClose", windowClosed);
// The sdk/event/dom module tries to clean itself up when DOMWindowClose
// is fired. Verify that it doesn't leak if its attached to an
// already closed window either. (See bug 1268898.)
open(w.document, "TestEvent1");
resolve(loader);
});
w.close();
});
});
}
require("sdk/test").run(exports);

Просмотреть файл

@ -0,0 +1,47 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
// Opening new windows in Fennec causes issues
module.metadata = {
engines: {
'Firefox': '*'
}
};
const { asyncWindowLeakTest } = require("./leak-utils.js");
const { Loader } = require("sdk/test/loader");
const { open } = require("sdk/window/utils");
exports["test window/events for leaks"] = function*(assert) {
yield asyncWindowLeakTest(assert, _ => {
return new Promise((resolve, reject) => {
let loader = Loader(module);
let { events } = loader.require("sdk/window/events");
let { on, off } = loader.require("sdk/event/core");
on(events, "data", function handler(e) {
try {
if (e.type === "load") {
e.target.close();
}
else if (e.type === "close") {
off(events, "data", handler);
// Let asyncWindowLeakTest call loader.unload() after the
// leak check.
resolve(loader);
}
} catch (e) {
reject(e);
}
});
// Open a window. This will trigger our data events.
open();
});
});
};
require("sdk/test").run(exports);

Просмотреть файл

@ -28,9 +28,12 @@ function appUpdater()
{
this.updateDeck = document.getElementById("updateDeck");
// Hide the update deck when there is already an update window open to avoid
// syncing issues between them.
if (Services.wm.getMostRecentWindow("Update:Wizard")) {
// Hide the update deck when the update window is already open and it's not
// already applied, to avoid syncing issues between them. Applied updates
// don't have any information to sync between the windows as they both just
// show the "Restart to continue"-type button.
if (Services.wm.getMostRecentWindow("Update:Wizard") &&
!this.isApplied) {
this.updateDeck.hidden = true;
return;
}

Просмотреть файл

@ -1896,8 +1896,10 @@ BrowserGlue.prototype = {
_showSyncStartedDoorhanger: function () {
let bundle = Services.strings.createBundle("chrome://browser/locale/accounts.properties");
let productName = gBrandBundle.GetStringFromName("brandShortName");
let title = bundle.GetStringFromName("syncStartNotification.title");
let body = bundle.GetStringFromName("syncStartNotification.body");
let body = bundle.formatStringFromName("syncStartNotification.body2",
[productName], 1);
let clickCallback = (subject, topic, data) => {
if (topic != "alertclickcallback")

Просмотреть файл

@ -141,34 +141,15 @@ var gMainPane = {
}
}
const Cc = Components.classes, Ci = Components.interfaces;
let brandName = document.getElementById("bundleBrand").getString("brandShortName");
let bundle = document.getElementById("bundlePreferences");
let msg = bundle.getFormattedString(e10sCheckbox.checked ?
"featureEnableRequiresRestart" : "featureDisableRequiresRestart",
[brandName]);
let restartText = bundle.getFormattedString("okToRestartButton", [brandName]);
let revertText = bundle.getString("revertNoRestartButton");
let title = bundle.getFormattedString("shouldRestartTitle", [brandName]);
let prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService);
let buttonFlags = (Services.prompt.BUTTON_POS_0 *
Services.prompt.BUTTON_TITLE_IS_STRING) +
(Services.prompt.BUTTON_POS_1 *
Services.prompt.BUTTON_TITLE_IS_STRING) +
Services.prompt.BUTTON_POS_0_DEFAULT;
let shouldProceed = prompts.confirmEx(window, title, msg,
buttonFlags, revertText, restartText,
null, null, {});
if (shouldProceed) {
let buttonIndex = confirmRestartPrompt(e10sCheckbox.checked, 0,
true, false);
if (buttonIndex == CONFIRM_RESTART_PROMPT_RESTART_NOW) {
const Cc = Components.classes, Ci = Components.interfaces;
let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"]
.createInstance(Ci.nsISupportsPRBool);
Services.obs.notifyObservers(cancelQuit, "quit-application-requested",
"restart");
shouldProceed = !cancelQuit.data;
if (shouldProceed) {
if (!cancelQuit.data) {
for (let prefToChange of prefsToChange) {
prefToChange.value = e10sCheckbox.checked;
}
@ -205,40 +186,20 @@ var gMainPane = {
}
}
const Cc = Components.classes, Ci = Components.interfaces;
let separateProfileModeCheckbox = document.getElementById("separateProfileMode");
let brandName = document.getElementById("bundleBrand").getString("brandShortName");
let bundle = document.getElementById("bundlePreferences");
let msg = bundle.getFormattedString(separateProfileModeCheckbox.checked ?
"featureEnableRequiresRestart" : "featureDisableRequiresRestart",
[brandName]);
let title = bundle.getFormattedString("shouldRestartTitle", [brandName]);
let check = {value: false};
let prompts = Services.prompt;
let flags = prompts.BUTTON_POS_0 * prompts.BUTTON_TITLE_IS_STRING +
prompts.BUTTON_POS_1 * prompts.BUTTON_TITLE_CANCEL +
prompts.BUTTON_POS_2 * prompts.BUTTON_TITLE_IS_STRING;
let button0Title = bundle.getString("restartNowButton");
let button2Title = bundle.getString("restartLaterButton");
let button_index = prompts.confirmEx(window, title, msg, flags,
button0Title, null, button2Title, null, check)
let RESTART_NOW_BUTTON_INDEX = 0;
let CANCEL_BUTTON_INDEX = 1;
let RESTART_LATER_BUTTON_INDEX = 2;
let button_index = confirmRestartPrompt(separateProfileModeCheckbox.checked,
0, false, true);
switch (button_index) {
case CANCEL_BUTTON_INDEX:
case CONFIRM_RESTART_PROMPT_CANCEL:
revertCheckbox();
return;
case RESTART_NOW_BUTTON_INDEX:
let shouldProceed = false;
case CONFIRM_RESTART_PROMPT_RESTART_NOW:
const Cc = Components.classes, Ci = Components.interfaces;
let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"]
.createInstance(Ci.nsISupportsPRBool);
Services.obs.notifyObservers(cancelQuit, "quit-application-requested",
"restart");
shouldProceed = !cancelQuit.data;
if (shouldProceed) {
if (!cancelQuit.data) {
createOrRemoveSpecialDevEditionFile(quitApp);
return;
}
@ -246,7 +207,7 @@ var gMainPane = {
// Revert the checkbox in case we didn't quit
revertCheckbox();
return;
case RESTART_LATER_BUTTON_INDEX:
case CONFIRM_RESTART_PROMPT_RESTART_LATER:
createOrRemoveSpecialDevEditionFile();
return;
}

Просмотреть файл

@ -174,3 +174,69 @@ function friendlyPrefCategoryNameToInternalName(aName) {
function internalPrefCategoryNameToFriendlyName(aName) {
return (aName || "").replace(/^pane./, function(toReplace) { return toReplace[4].toLowerCase(); });
}
// Put up a confirm dialog with "ok to restart", "revert without restarting"
// and "restart later" buttons and returns the index of the button chosen.
// We can choose not to display the "restart later", or "revert" buttons,
// altough the later still lets us revert by using the escape key.
//
// The constants are useful to interpret the return value of the function.
const CONFIRM_RESTART_PROMPT_RESTART_NOW = 0;
const CONFIRM_RESTART_PROMPT_CANCEL = 1;
const CONFIRM_RESTART_PROMPT_RESTART_LATER = 2;
function confirmRestartPrompt(aRestartToEnable, aDefaultButtonIndex,
aWantRevertAsCancelButton,
aWantRestartLaterButton) {
let brandName = document.getElementById("bundleBrand").getString("brandShortName");
let bundle = document.getElementById("bundlePreferences");
let msg = bundle.getFormattedString(aRestartToEnable ?
"featureEnableRequiresRestart" :
"featureDisableRequiresRestart",
[brandName]);
let title = bundle.getFormattedString("shouldRestartTitle", [brandName]);
let prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService);
// Set up the first (index 0) button:
let button0Text = bundle.getFormattedString("okToRestartButton", [brandName]);
let buttonFlags = (Services.prompt.BUTTON_POS_0 *
Services.prompt.BUTTON_TITLE_IS_STRING);
// Set up the second (index 1) button:
let button1Text = null;
if (aWantRevertAsCancelButton) {
button1Text = bundle.getString("revertNoRestartButton");
buttonFlags += (Services.prompt.BUTTON_POS_1 *
Services.prompt.BUTTON_TITLE_IS_STRING);
} else {
buttonFlags += (Services.prompt.BUTTON_POS_1 *
Services.prompt.BUTTON_TITLE_CANCEL);
}
// Set up the third (index 2) button:
let button2Text = null;
if (aWantRestartLaterButton) {
button2Text = bundle.getString("restartLater");
buttonFlags += (Services.prompt.BUTTON_POS_2 *
Services.prompt.BUTTON_TITLE_IS_STRING);
}
switch(aDefaultButtonIndex) {
case 0:
buttonFlags += Services.prompt.BUTTON_POS_0_DEFAULT;
break;
case 1:
buttonFlags += Services.prompt.BUTTON_POS_1_DEFAULT;
break;
case 2:
buttonFlags += Services.prompt.BUTTON_POS_2_DEFAULT;
break;
default:
break;
}
let buttonIndex = prompts.confirmEx(window, title, msg, buttonFlags,
button0Text, button1Text, button2Text,
null, {});
return buttonIndex;
}

Просмотреть файл

@ -370,34 +370,15 @@ var gPrivacyPane = {
return;
}
const Cc = Components.classes, Ci = Components.interfaces;
let brandName = document.getElementById("bundleBrand").getString("brandShortName");
let bundle = document.getElementById("bundlePreferences");
let msg = bundle.getFormattedString(autoStart.checked ?
"featureEnableRequiresRestart" : "featureDisableRequiresRestart",
[brandName]);
let restartText = bundle.getFormattedString("okToRestartButton", [brandName]);
let revertText = bundle.getString("revertNoRestartButton");
let title = bundle.getFormattedString("shouldRestartTitle", [brandName]);
let prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService);
let buttonFlags = (Services.prompt.BUTTON_POS_0 *
Services.prompt.BUTTON_TITLE_IS_STRING) +
(Services.prompt.BUTTON_POS_1 *
Services.prompt.BUTTON_TITLE_IS_STRING) +
Services.prompt.BUTTON_POS_0_DEFAULT;
let shouldProceed = prompts.confirmEx(window, title, msg,
buttonFlags, revertText, restartText,
null, null, {});
if (shouldProceed) {
let buttonIndex = confirmRestartPrompt(autoStart.checked, 1,
true, false);
if (buttonIndex == CONFIRM_RESTART_PROMPT_RESTART_NOW) {
const Cc = Components.classes, Ci = Components.interfaces;
let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"]
.createInstance(Ci.nsISupportsPRBool);
Services.obs.notifyObservers(cancelQuit, "quit-application-requested",
"restart");
shouldProceed = !cancelQuit.data;
if (shouldProceed) {
if (!cancelQuit.data) {
pref.value = autoStart.hasAttribute('checked');
let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"]
.getService(Ci.nsIAppStartup);

Просмотреть файл

@ -6,9 +6,9 @@
"filename": "mozmake.exe"
},
{
"version": "rustc 1.9.0 (e4e8b6668 2016-05-18)",
"size": 82463178,
"digest": "a3c54c6792e75d53ec79caf958db25b651fcf968a37b00949fb327c54a54cad6305a4af302f267082d86d70fcf837ed0f273f85b97706c20b957ff3690889b40",
"version": "rustc 1.10.0 (cfcb716cf 2016-07-03)",
"size": 88820579,
"digest": "3bc772d951bf90b01cdba9dcd0e1d131a98519dff0710bb219784ea43d4d001dbce191071a4b3824933386bb9613f173760c438939eb396b0e0dfdad9a42e4f0",
"algorithm": "sha512",
"filename": "rustc.tar.bz2",
"unpack": true

Просмотреть файл

@ -6,9 +6,9 @@
"filename": "mozmake.exe"
},
{
"version": "rustc 1.9.0 (e4e8b6668 2016-05-18)",
"size": 88486080,
"digest": "a4fb99cd637b236a9c30e111757ca560bc8df1b143324c1d9ab58c32470b9b9a0598e3e0d220278ee157959dcd88421496388e2ed856e6261d9c81f18e6310e9",
"version": "rustc 1.10.0 (cfcb716cf 2016-07-03)",
"size": 94067220,
"digest": "05cabda2a28ce6674f062aab589b4b3758e0cd4a4af364bb9a2e736254baa10d668936b2b7ed0df530c7f5ba8ea1e7f51ff3affc84a6551c46188b2f67f10e05",
"algorithm": "sha512",
"visibility": "public",
"filename": "rustc.tar.bz2",

Просмотреть файл

@ -27,7 +27,8 @@ verificationNotSentBody = We are unable to send a verification mail at this time
# LOCALIZATION NOTE (syncStartNotification.title, syncStartNotification.body)
# These strings are used in a notification shown after Sync is connected.
syncStartNotification.title = Sync enabled
syncStartNotification.body = Firefox will begin syncing momentarily.
# %S is brandShortName
syncStartNotification.body2 = %S will begin syncing momentarily.
# LOCALIZATION NOTE (deviceDisconnectedNotification.title, deviceDisconnectedNotification.body)
# These strings are used in a notification shown after Sync was disconnected remotely.

Просмотреть файл

@ -45,12 +45,14 @@ SEARCH_PATHS = [
'python/futures',
'python/jsmin',
'python/psutil',
'python/pylru',
'python/which',
'python/pystache',
'python/pyyaml/lib',
'python/requests',
'python/slugid',
'build',
'build/pymake',
'config',
'dom/bindings',
'dom/bindings/parser',

Просмотреть файл

@ -137,14 +137,21 @@ def namespace(**kwargs):
# return namespace(foo=value)
# set_config('FOO', delayed_getattr(option, 'foo')
@template
@imports('__sandbox__')
def delayed_getattr(func, key):
@depends(func)
def result(value):
_, deps = __sandbox__._depends.get(func, (None, ()))
def result(value, _=None):
# The @depends function we're being passed may have returned
# None, or an object that simply doesn't have the wanted key.
# In that case, just return None.
return getattr(value, key, None)
return result
# Automatically add a dependency on --help when the given @depends
# function itself depends on --help.
if __sandbox__._help_option in deps:
return depends(func, '--help')(result)
return depends(func)(result)
# Like @depends, but the decorated function is only called if one of the

Просмотреть файл

@ -71,6 +71,8 @@ included_inclnames_to_ignore = set([
'prcvar.h', # NSPR
'prerror.h', # NSPR
'prinit.h', # NSPR
'prio.h', # NSPR
'private/pprio.h', # NSPR
'prlink.h', # NSPR
'prlock.h', # NSPR
'prprf.h', # NSPR

Просмотреть файл

@ -1210,6 +1210,8 @@ wx/log.h
wx/toolbar.h
wx/wx.h
wx/xrc/xmlres.h
xcb/xcb.h
xcb/shm.h
X11/cursorfont.h
X11/extensions/Print.h
X11/extensions/shape.h
@ -1231,6 +1233,7 @@ X11/X.h
X11/XKBlib.h
X11/Xlib.h
X11/Xlibint.h
X11/Xlib-xcb.h
X11/Xlocale.h
X11/Xos.h
X11/Xutil.h

Просмотреть файл

@ -18,3 +18,4 @@ skip-if = e10s && debug # Bug 1252201 - Docshell leak on debug e10s
[browser_responsive_devicewidth.js]
[browser_responsiveui_customuseragent.js]
[browser_responsiveui_window_close.js]
skip-if = (os == 'linux') && e10s && debug # Bug 1277274

Просмотреть файл

@ -19,7 +19,6 @@ const { ActorClassWithSpec } = require("devtools/shared/protocol");
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
const { assert, dumpn, update, fetch } = DevToolsUtils;
const promise = require("promise");
const PromiseDebugging = require("PromiseDebugging");
const xpcInspector = require("xpcInspector");
const ScriptStore = require("./utils/ScriptStore");
const { DevToolsWorker } = require("devtools/shared/worker/worker");

Просмотреть файл

@ -317,12 +317,6 @@ this.WorkerDebuggerLoader = WorkerDebuggerLoader;
// does not provide alternative definitions for them. Consequently, they are
// stubbed out both on the main thread and worker threads.
var PromiseDebugging = {
getState: function () {
throw new Error("PromiseDebugging is not available in workers!");
}
};
var chrome = {
CC: undefined,
Cc: undefined,
@ -496,7 +490,6 @@ this.worker = new WorkerDebuggerLoader({
loadSubScript: loadSubScript,
modules: {
"Debugger": Debugger,
"PromiseDebugging": PromiseDebugging,
"Services": Object.create(null),
"chrome": chrome,
"xpcInspector": xpcInspector

Просмотреть файл

@ -50,7 +50,11 @@ if (Services.prefs.getBoolPref("javascript.options.asyncstack")) {
ok(frame.asyncParent !== null, "Parent frame has async parent");
is(frame.asyncParent.asyncCause, "promise callback",
"Async parent has correct cause");
is(frame.asyncParent.functionDisplayName, "do_promise",
let asyncFrame = frame.asyncParent;
// Skip over self-hosted parts of our Promise implementation.
while (asyncFrame.source === 'self-hosted')
asyncFrame = asyncFrame.parent;
is(asyncFrame.functionDisplayName, "do_promise",
"Async parent has correct function name");
}
}, {
@ -71,7 +75,11 @@ if (Services.prefs.getBoolPref("javascript.options.asyncstack")) {
ok(frame.asyncParent !== null, "Parent frame has async parent");
is(frame.asyncParent.asyncCause, "promise callback",
"Async parent has correct cause");
is(frame.asyncParent.functionDisplayName, "do_promise_script",
let asyncFrame = frame.asyncParent;
// Skip over self-hosted parts of our Promise implementation.
while (asyncFrame.source === 'self-hosted')
asyncFrame = asyncFrame.parent;
is(asyncFrame.functionDisplayName, "do_promise_script",
"Async parent has correct function name");
}
});

Просмотреть файл

@ -91,12 +91,24 @@ if (Services.prefs.getBoolPref("javascript.options.asyncstack")) {
check: function(markers) {
markers = markers.filter(m => m.name == "ConsoleTime");
ok(markers.length > 0, "Promise marker includes stack");
ok(markers[0].stack.functionDisplayName == "testConsoleTime",
"testConsoleTime is on the stack");
let frame = markers[0].endStack;
ok(frame.parent.asyncParent !== null, "Parent frame has async parent");
is(frame.parent.asyncParent.asyncCause, "promise callback",
ok(frame.functionDisplayName == "testConsoleTimeEnd",
"testConsoleTimeEnd is on the stack");
frame = frame.parent;
ok(frame.functionDisplayName == "makePromise/<",
"makePromise/< is on the stack");
let asyncFrame = frame.asyncParent;
ok(asyncFrame !== null, "Frame has async parent");
is(asyncFrame.asyncCause, "promise callback",
"Async parent has correct cause");
is(frame.parent.asyncParent.functionDisplayName, "makePromise",
// Skip over self-hosted parts of our Promise implementation.
while (asyncFrame.source === 'self-hosted') {
asyncFrame = asyncFrame.parent;
}
is(asyncFrame.functionDisplayName, "makePromise",
"Async parent has correct function name");
}
});

Просмотреть файл

@ -34,4 +34,6 @@ FINAL_LIBRARY = 'xul'
MOCHITEST_MANIFESTS += ['test/mochitest.ini']
MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell.ini']

Просмотреть файл

@ -0,0 +1,7 @@
[DEFAULT]
run-if = buildapp == 'b2g' || buildapp == 'mulet'
support-files =
file_empty.html
system_message_chrome_script.js
[test_alarm_permitted_app.html]

Просмотреть файл

@ -1,21 +1,14 @@
[DEFAULT]
run-if = buildapp == 'b2g' || buildapp == 'mulet'
support-files =
file_empty.html
system_message_chrome_script.js
[test_alarm_add_data.html]
skip-if = ((buildapp == 'b2g') && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_alarm_add_date.html]
skip-if = ((buildapp == 'b2g') && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_alarm_add_respectTimezone.html]
skip-if = ((buildapp == 'b2g') && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_alarm_non_permitted_app.html]
[test_alarm_permitted_app.html]
[test_alarm_remove.html]
skip-if = ((buildapp == 'b2g') && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_bug1015540.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_bug1037079.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_bug1090896.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage

Просмотреть файл

@ -2,8 +2,8 @@
<html>
<head>
<title>Test Permitted Application for Alarm API</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
@ -16,8 +16,6 @@
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [["dom.mozAlarms.enabled", true]]}, function() {
SpecialPowers.addPermission("alarms", true, document);
// mozAlarms is installed on all platforms except Android for the moment.
if (navigator.appVersion.indexOf("Android") != -1) {
try {

Просмотреть файл

@ -10,7 +10,7 @@
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(AnimationEffectReadOnly, mParent)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(AnimationEffectReadOnly, mDocument)
NS_IMPL_CYCLE_COLLECTING_ADDREF(AnimationEffectReadOnly)
NS_IMPL_CYCLE_COLLECTING_RELEASE(AnimationEffectReadOnly)

Просмотреть файл

@ -24,12 +24,12 @@ public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(AnimationEffectReadOnly)
explicit AnimationEffectReadOnly(nsISupports* aParent)
: mParent(aParent)
explicit AnimationEffectReadOnly(nsIDocument* aDocument)
: mDocument(aDocument)
{
}
nsISupports* GetParentObject() const { return mParent; }
nsISupports* GetParentObject() const { return mDocument; }
virtual already_AddRefed<AnimationEffectTimingReadOnly> Timing() const = 0;
@ -39,7 +39,7 @@ protected:
virtual ~AnimationEffectReadOnly() = default;
protected:
nsCOMPtr<nsISupports> mParent;
RefPtr<nsIDocument> mDocument;
};
} // namespace dom

Просмотреть файл

@ -130,18 +130,10 @@ AnimationEffectTiming::SetDirection(const PlaybackDirection& aDirection)
}
void
AnimationEffectTiming::SetEasing(JSContext* aCx,
const nsAString& aEasing,
ErrorResult& aRv)
AnimationEffectTiming::SetEasing(const nsAString& aEasing, ErrorResult& aRv)
{
nsIDocument* document = AnimationUtils::GetCurrentRealmDocument(aCx);
if (!document) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
Maybe<ComputedTimingFunction> newFunction =
TimingParams::ParseEasing(aEasing, document, aRv);
TimingParams::ParseEasing(aEasing, mDocument, aRv);
if (aRv.Failed()) {
return;
}

Просмотреть файл

@ -17,10 +17,10 @@ namespace dom {
class AnimationEffectTiming : public AnimationEffectTimingReadOnly
{
public:
AnimationEffectTiming(nsISupports* aParent,
AnimationEffectTiming(nsIDocument* aDocument,
const TimingParams& aTiming,
KeyframeEffect* aEffect)
: AnimationEffectTimingReadOnly(aParent, aTiming)
: AnimationEffectTimingReadOnly(aDocument, aTiming)
, mEffect(aEffect) { }
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
@ -35,7 +35,7 @@ public:
void SetDuration(const UnrestrictedDoubleOrString& aDuration,
ErrorResult& aRv);
void SetDirection(const PlaybackDirection& aDirection);
void SetEasing(JSContext* aCx, const nsAString& aEasing, ErrorResult& aRv);
void SetEasing(const nsAString& aEasing, ErrorResult& aRv);
private:
KeyframeEffect* MOZ_NON_OWNING_REF mEffect;

Просмотреть файл

@ -15,7 +15,7 @@
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(AnimationEffectTimingReadOnly, mParent)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(AnimationEffectTimingReadOnly, mDocument)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AnimationEffectTimingReadOnly, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AnimationEffectTimingReadOnly, Release)

Просмотреть файл

@ -23,9 +23,9 @@ class AnimationEffectTimingReadOnly : public nsWrapperCache
{
public:
AnimationEffectTimingReadOnly() = default;
AnimationEffectTimingReadOnly(nsISupports* aParent,
AnimationEffectTimingReadOnly(nsIDocument* aDocument,
const TimingParams& aTiming)
: mParent(aParent)
: mDocument(aDocument)
, mTiming(aTiming) { }
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AnimationEffectTimingReadOnly)
@ -35,7 +35,7 @@ protected:
virtual ~AnimationEffectTimingReadOnly() = default;
public:
nsISupports* GetParentObject() const { return mParent; }
nsISupports* GetParentObject() const { return mDocument; }
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
double Delay() const { return mTiming.mDelay.ToMilliseconds(); }
@ -53,7 +53,7 @@ public:
virtual void Unlink() { }
protected:
nsCOMPtr<nsISupports> mParent;
RefPtr<nsIDocument> mDocument;
TimingParams mTiming;
};

Просмотреть файл

@ -456,19 +456,13 @@ KeyframeEffectReadOnly::SetKeyframes(JSContext* aContext,
JS::Handle<JSObject*> aKeyframes,
ErrorResult& aRv)
{
nsIDocument* doc = AnimationUtils::GetCurrentRealmDocument(aContext);
if (!doc) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsTArray<Keyframe> keyframes =
KeyframeUtils::GetKeyframesFromObject(aContext, aKeyframes, aRv);
KeyframeUtils::GetKeyframesFromObject(aContext, mDocument, aKeyframes, aRv);
if (aRv.Failed()) {
return;
}
RefPtr<nsStyleContext> styleContext = GetTargetStyleContext(doc);
RefPtr<nsStyleContext> styleContext = GetTargetStyleContext();
SetKeyframes(Move(keyframes), styleContext);
}
@ -944,25 +938,21 @@ KeyframeEffectReadOnly::RequestRestyle(
}
already_AddRefed<nsStyleContext>
KeyframeEffectReadOnly::GetTargetStyleContext(nsIDocument* aDoc)
KeyframeEffectReadOnly::GetTargetStyleContext()
{
if (!mTarget) {
nsIPresShell* shell = GetPresShell();
if (!shell) {
return nullptr;
}
if (!aDoc) {
aDoc = mTarget->mElement->OwnerDoc();
if (!aDoc) {
return nullptr;
}
}
MOZ_ASSERT(mTarget,
"Should only have a presshell when we have a target element");
nsIAtom* pseudo = mTarget->mPseudoType < CSSPseudoElementType::Count
? nsCSSPseudoElements::GetPseudoAtom(mTarget->mPseudoType)
: nullptr;
return nsComputedDOMStyle::GetStyleContextForElement(mTarget->mElement,
pseudo,
aDoc->GetShell());
pseudo, shell);
}
#ifdef DEBUG

Просмотреть файл

@ -400,9 +400,8 @@ protected:
// context. That's because calling GetStyleContextForElement when we are in
// the process of building a style context may trigger various forms of
// infinite recursion.
// If aDoc is nullptr, we will use the owner doc of the target element.
already_AddRefed<nsStyleContext>
GetTargetStyleContext(nsIDocument* aDoc = nullptr);
GetTargetStyleContext();
Maybe<OwningAnimationTarget> mTarget;
RefPtr<Animation> mAnimation;

Просмотреть файл

@ -341,12 +341,14 @@ IsInvalidValuePair(const PropertyValuePair& aPair)
static void
GetKeyframeListFromKeyframeSequence(JSContext* aCx,
nsIDocument* aDocument,
JS::ForOfIterator& aIterator,
nsTArray<Keyframe>& aResult,
ErrorResult& aRv);
static bool
ConvertKeyframeSequence(JSContext* aCx,
nsIDocument* aDocument,
JS::ForOfIterator& aIterator,
nsTArray<Keyframe>& aResult);
@ -387,6 +389,7 @@ BuildSegmentsFromValueEntries(nsStyleContext* aStyleContext,
static void
GetKeyframeListFromPropertyIndexedKeyframe(JSContext* aCx,
nsIDocument* aDocument,
JS::Handle<JS::Value> aValue,
nsTArray<Keyframe>& aResult,
ErrorResult& aRv);
@ -418,6 +421,7 @@ GetCumulativeDistances(const nsTArray<ComputedKeyframeValues>& aValues,
/* static */ nsTArray<Keyframe>
KeyframeUtils::GetKeyframesFromObject(JSContext* aCx,
nsIDocument* aDocument,
JS::Handle<JSObject*> aFrames,
ErrorResult& aRv)
{
@ -441,10 +445,10 @@ KeyframeUtils::GetKeyframesFromObject(JSContext* aCx,
}
if (iter.valueIsIterable()) {
GetKeyframeListFromKeyframeSequence(aCx, iter, keyframes, aRv);
GetKeyframeListFromKeyframeSequence(aCx, aDocument, iter, keyframes, aRv);
} else {
GetKeyframeListFromPropertyIndexedKeyframe(aCx, objectValue, keyframes,
aRv);
GetKeyframeListFromPropertyIndexedKeyframe(aCx, aDocument, objectValue,
keyframes, aRv);
}
if (aRv.Failed()) {
@ -459,14 +463,7 @@ KeyframeUtils::GetKeyframesFromObject(JSContext* aCx,
// Until we implement additive animations we just throw if we encounter any
// set of keyframes that would put us in that situation.
nsIDocument* doc = AnimationUtils::GetCurrentRealmDocument(aCx);
if (!doc) {
aRv.Throw(NS_ERROR_FAILURE);
keyframes.Clear();
return keyframes;
}
if (RequiresAdditiveAnimation(keyframes, doc)) {
if (RequiresAdditiveAnimation(keyframes, aDocument)) {
aRv.Throw(NS_ERROR_DOM_ANIM_MISSING_PROPS_ERR);
keyframes.Clear();
}
@ -705,6 +702,7 @@ KeyframeUtils::IsAnimatableProperty(nsCSSProperty aProperty)
* Converts a JS object to an IDL sequence<Keyframe>.
*
* @param aCx The JSContext corresponding to |aIterator|.
* @param aDocument The document to use when parsing CSS properties.
* @param aIterator An already-initialized ForOfIterator for the JS
* object to iterate over as a sequence.
* @param aResult The array into which the resulting Keyframe objects will be
@ -713,6 +711,7 @@ KeyframeUtils::IsAnimatableProperty(nsCSSProperty aProperty)
*/
static void
GetKeyframeListFromKeyframeSequence(JSContext* aCx,
nsIDocument* aDocument,
JS::ForOfIterator& aIterator,
nsTArray<Keyframe>& aResult,
ErrorResult& aRv)
@ -722,7 +721,7 @@ GetKeyframeListFromKeyframeSequence(JSContext* aCx,
// Convert the object in aIterator to a sequence of keyframes producing
// an array of Keyframe objects.
if (!ConvertKeyframeSequence(aCx, aIterator, aResult)) {
if (!ConvertKeyframeSequence(aCx, aDocument, aIterator, aResult)) {
aRv.Throw(NS_ERROR_FAILURE);
aResult.Clear();
return;
@ -750,16 +749,12 @@ GetKeyframeListFromKeyframeSequence(JSContext* aCx,
*/
static bool
ConvertKeyframeSequence(JSContext* aCx,
nsIDocument* aDocument,
JS::ForOfIterator& aIterator,
nsTArray<Keyframe>& aResult)
{
nsIDocument* doc = AnimationUtils::GetCurrentRealmDocument(aCx);
if (!doc) {
return false;
}
JS::Rooted<JS::Value> value(aCx);
nsCSSParser parser(doc->CSSLoader());
nsCSSParser parser(aDocument->CSSLoader());
for (;;) {
bool done;
@ -795,7 +790,7 @@ ConvertKeyframeSequence(JSContext* aCx,
ErrorResult rv;
keyframe->mTimingFunction =
TimingParams::ParseEasing(keyframeDict.mEasing, doc, rv);
TimingParams::ParseEasing(keyframeDict.mEasing, aDocument, rv);
if (rv.MaybeSetPendingException(aCx)) {
return false;
}
@ -814,7 +809,8 @@ ConvertKeyframeSequence(JSContext* aCx,
for (PropertyValuesPair& pair : propertyValuePairs) {
MOZ_ASSERT(pair.mValues.Length() == 1);
keyframe->mPropertyValues.AppendElement(
MakePropertyValuePair(pair.mProperty, pair.mValues[0], parser, doc));
MakePropertyValuePair(pair.mProperty, pair.mValues[0], parser,
aDocument));
// When we go to convert keyframes into arrays of property values we
// call StyleAnimation::ComputeValues. This should normally return true
@ -1272,6 +1268,7 @@ BuildSegmentsFromValueEntries(nsStyleContext* aStyleContext,
* an array of Keyframe objects.
*
* @param aCx The JSContext for |aValue|.
* @param aDocument The document to use when parsing CSS properties.
* @param aValue The JS object.
* @param aResult The array into which the resulting AnimationProperty
* objects will be appended.
@ -1279,6 +1276,7 @@ BuildSegmentsFromValueEntries(nsStyleContext* aStyleContext,
*/
static void
GetKeyframeListFromPropertyIndexedKeyframe(JSContext* aCx,
nsIDocument* aDocument,
JS::Handle<JS::Value> aValue,
nsTArray<Keyframe>& aResult,
ErrorResult& aRv)
@ -1296,15 +1294,8 @@ GetKeyframeListFromPropertyIndexedKeyframe(JSContext* aCx,
return;
}
// Get the document to use for parsing CSS properties.
nsIDocument* doc = AnimationUtils::GetCurrentRealmDocument(aCx);
if (!doc) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
Maybe<ComputedTimingFunction> easing =
TimingParams::ParseEasing(keyframeDict.mEasing, doc, aRv);
TimingParams::ParseEasing(keyframeDict.mEasing, aDocument, aRv);
if (aRv.Failed()) {
return;
}
@ -1319,7 +1310,7 @@ GetKeyframeListFromPropertyIndexedKeyframe(JSContext* aCx,
}
// Create a set of keyframes for each property.
nsCSSParser parser(doc->CSSLoader());
nsCSSParser parser(aDocument->CSSLoader());
nsClassHashtable<nsFloatHashKey, Keyframe> processedKeyframes;
for (const PropertyValuesPair& pair : propertyValuesPairs) {
size_t count = pair.mValues.Length();
@ -1346,7 +1337,7 @@ GetKeyframeListFromPropertyIndexedKeyframe(JSContext* aCx,
keyframe->mComputedOffset = offset;
}
keyframe->mPropertyValues.AppendElement(
MakePropertyValuePair(pair.mProperty, stringValue, parser, doc));
MakePropertyValuePair(pair.mProperty, stringValue, parser, aDocument));
}
}

Просмотреть файл

@ -43,6 +43,7 @@ public:
* of keyframes to an array of Keyframe objects.
*
* @param aCx The JSContext that corresponds to |aFrames|.
* @param aDocument The document to use when parsing CSS properties.
* @param aFrames The JS value, provided as an optional IDL |object?| value,
* that is the keyframe list specification.
* @param aRv (out) Out-param to hold any error returned by this function.
@ -53,6 +54,7 @@ public:
*/
static nsTArray<Keyframe>
GetKeyframesFromObject(JSContext* aCx,
nsIDocument* aDocument,
JS::Handle<JSObject*> aFrames,
ErrorResult& aRv);

Просмотреть файл

@ -88,6 +88,6 @@ skip-if = (toolkit == 'gonk' && debug)
[mozilla/test_document-timeline-origin-time-range.html]
[mozilla/test_hide_and_show.html]
[mozilla/test_partial_keyframes.html]
[mozilla/test_set-easing.html]
[style/test_animation-seeking-with-current-time.html]
[style/test_animation-seeking-with-start-time.html]
[sandbox/test_set-easing.html]

Просмотреть файл

@ -1,7 +1,7 @@
<!doctype html>
<head>
<meta charset=utf-8>
<title>Tests AnimationTimingFunction::SetEasing in sandbox</title>
<title>Test setting easing in sandbox</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/SpawnTask.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
@ -17,14 +17,17 @@ add_task(function* set_easing() {
div.animate({ opacity: [0, 1] }, 100000 );
const contentScript = function() {
doesThrow(() => {
try {
document.getAnimations()[0].effect.timing.easing = "linear";
}, "AnimationTimingFunction::SetEasing should throw in sandbox.");
ok(true, 'Setting easing should not throw in sandbox');
} catch (e) {
ok(false, 'Setting easing should not throw in sandbox');
}
};
const sandbox = new SpecialPowers.Cu.Sandbox(window);
sandbox.importFunction(document, "document");
sandbox.importFunction(SimpleTest.doesThrow, "doesThrow");
sandbox.importFunction(SimpleTest.ok, "ok");
SpecialPowers.Cu.evalInSandbox(`(${contentScript.toSource()})()`, sandbox);
});

Просмотреть файл

@ -118,8 +118,6 @@
#endif
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/FeatureList.h"
#ifdef MOZ_EME
#include "mozilla/EMEUtils.h"
#include "mozilla/DetailedPromise.h"
@ -1792,11 +1790,7 @@ Navigator::HasFeature(const nsAString& aName, ErrorResult& aRv)
return p.forget();
}
if (IsFeatureDetectible(featureName)) {
p->MaybeResolve(true);
} else {
p->MaybeResolve(JS::UndefinedHandleValue);
}
p->MaybeResolve(JS::UndefinedHandleValue);
return p.forget();
}

Просмотреть файл

@ -1459,9 +1459,6 @@ nsIDocument::nsIDocument()
mUserHasInteracted(false)
{
SetIsDocument();
if (IsStyledByServo()) {
SetFlags(NODE_IS_DIRTY_FOR_SERVO | NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO);
}
PR_INIT_CLIST(&mDOMMediaQueryLists);
}

Просмотреть файл

@ -2454,3 +2454,13 @@ GK_ATOM(nsuri_mathml, "http://www.w3.org/1998/Math/MathML")
GK_ATOM(nsuri_rdf, "http://www.w3.org/1999/02/22-rdf-syntax-ns#")
GK_ATOM(nsuri_xul, "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul")
GK_ATOM(nsuri_svg, "http://www.w3.org/2000/svg")
// MSE
GK_ATOM(onsourceopen, "onsourceopen")
GK_ATOM(onsourceended, "onsourceended")
GK_ATOM(onsourceclosed, "onsourceclosed")
GK_ATOM(onupdatestart, "onupdatestart")
GK_ATOM(onupdate, "onupdate")
GK_ATOM(onupdateend, "onupdateend")
GK_ATOM(onaddsourcebuffer, "onaddsourcebuffer")
GK_ATOM(onremovesourcebuffer, "onremovesourcebuffer")

Просмотреть файл

@ -5,6 +5,7 @@ support-files =
file_bug945152.jar
file_bug945152_worker.js
file_bug1008126_worker.js
mozbrowser_api_utils.js
[test_anonymousContent_xul_window.xul]
[test_bug715041.xul]
@ -12,6 +13,8 @@ support-files =
[test_domrequesthelper.xul]
[test_navigator_resolve_identity_xrays.xul]
support-files = file_navigator_resolve_identity_xrays.xul
[test_navigator_resolve_identity.html]
support-files = file_navigator_resolve_identity.html
[test_sendQueryContentAndSelectionSetEvent.html]
[test_bug1016960.html]
[test_copypaste.xul]
@ -23,3 +26,6 @@ skip-if = buildapp == 'mulet'
[test_bug1008126.html]
[test_sandboxed_blob_uri.html]
[test_websocket_frame.html]
[test_getFeature_with_perm.html]
[test_hasFeature.html]
[test_mozbrowser_apis_allowed.html]

Просмотреть файл

@ -0,0 +1,36 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=985827
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 985827</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
<script type="application/javascript">
function test() {
var is = parent.is;
// Test WebIDL NavigatorProperty objects
var x = navigator.mozContacts;
is(typeof x, "object", "Should have a mozContacts object");
delete navigator.mozContacts;
var y = navigator.mozContacts;
is(x, y, "Should have gotten the same mozContacts object again");
}
test();
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=985827">Mozilla Bug 985827</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</html>

Просмотреть файл

@ -677,14 +677,11 @@ skip-if = (toolkit == 'android') || e10s # Android: Bug 775227, e10s: Bug 122647
skip-if = e10s || os != 'linux' || buildapp != 'browser' # Already tests multiprocess
[test_getAttribute_after_createAttribute.html]
[test_getElementById.html]
[test_getFeature_with_perm.html]
[test_getFeature_without_perm.html]
[test_getTranslationNodes.html]
[test_getTranslationNodes_limit.html]
[test_gsp-qualified.html]
[test_gsp-quirks.html]
[test_gsp-standards.html]
[test_hasFeature.html]
[test_history_document_open.html]
[test_history_state_null.html]
[test_html_colors_quirks.html]
@ -719,7 +716,6 @@ skip-if = (os != 'b2g' && os != 'android') # meta-viewport tag support is mob
skip-if = (os != 'b2g' && os != 'android') # meta-viewport tag support is mobile-only
[test_meta_viewport7.html]
skip-if = (os != 'b2g' && os != 'android') # meta-viewport tag support is mobile-only
[test_mozbrowser_apis_allowed.html]
[test_mozbrowser_apis_blocked.html]
[test_mozfiledataurl.html]
skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT
@ -729,7 +725,6 @@ skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' #TIME
skip-if = buildapp == 'b2g' # b2g(bug 901385, showmodaldialog) b2g-debug(bug 901385, showmodaldialog) b2g-desktop(bug 901385, showmodaldialog)
[test_named_frames.html]
[test_navigator_hardwareConcurrency.html]
[test_navigator_resolve_identity.html]
[test_navigator_language.html]
[test_navigatorPrefOverride.html]
[test_noAudioNotification.html]

Просмотреть файл

@ -20,12 +20,12 @@ const METHODS = {
getCanGoBack: {},
getCanGoForward: {},
getContentDimensions: {},
setInputMethodActive: { alwaysFails: true }, // needs input-manage
setNFCFocus: { alwaysFails: true }, // needs nfc-manager
setInputMethodActive: {},
setNFCFocus: {},
findAll: {},
findNext: {},
clearMatch: {},
executeScript: { alwaysFails: true }, // needs browser:universalxss
executeScript: {},
getWebManifest: {},
mute: {},
unmute: {},
@ -39,7 +39,7 @@ const ATTRIBUTES = [
];
function once(target, eventName, useCapture = false) {
info("Waiting for event: '" + eventName + "' on " + target + ".");
info("Waiting for event: '" + JSON.stringify(eventName) + "' on " + target + ".");
return new Promise(resolve => {
for (let [add, remove] of [
@ -47,11 +47,13 @@ function once(target, eventName, useCapture = false) {
["addMessageListener", "removeMessageListener"],
]) {
if ((add in target) && (remove in target)) {
target[add](eventName, function onEvent(...aArgs) {
info("Got event: '" + eventName + "' on " + target + ".");
target[remove](eventName, onEvent, useCapture);
resolve(aArgs);
}, useCapture);
eventName.forEach(evName => {
target[add](evName, function onEvent(...aArgs) {
info("Got event: '" + evName + "' on " + target + ".");
target[remove](evName, onEvent, useCapture);
resolve(aArgs);
}, useCapture);
});
break;
}
}
@ -64,7 +66,7 @@ function* loadFrame(attributes = {}) {
for (let key in attributes) {
iframe.setAttribute(key, attributes[key]);
}
let loaded = once(iframe, "load");
let loaded = once(iframe, [ "load", "mozbrowserloadend" ]);
document.body.appendChild(iframe);
yield loaded;
return iframe;

Просмотреть файл

@ -6,8 +6,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=979109
<head>
<meta charset="utf-8">
<title>Test for Bug 979109</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=983502">Mozilla Bug 983502</a>
@ -114,23 +114,19 @@ function runNextTest() {
info("About to run " + tests.length + " tests");
SpecialPowers.pushPermissions([
{type: "feature-detection", allow: 1, context: document}
], function() {
ok('getFeature' in navigator, "navigator.getFeature should exist");
ok('hasFeature' in navigator, "navigator.hasFeature should exist");
// B2G specific manifest features.
// Touching navigator before pushPermissions makes it fail.
if (!navigator.userAgent.includes("Android") &&
/Mobile|Tablet/.test(navigator.userAgent)) {
info("Adding B2G specific tests");
tests.push(createManifestTest("manifest.chrome.navigation"));
tests.push(createManifestTest("manifest.precompile"));
tests.push(createManifestTest("manifest.role.homescreen"));
}
runNextTest();
ok(true, "Test DONE");
});
ok('getFeature' in navigator, "navigator.getFeature should exist");
ok('hasFeature' in navigator, "navigator.hasFeature should exist");
// B2G specific manifest features.
// Touching navigator before pushPermissions makes it fail.
if (!navigator.userAgent.includes("Android") &&
/Mobile|Tablet/.test(navigator.userAgent)) {
info("Adding B2G specific tests");
tests.push(createManifestTest("manifest.chrome.navigation"));
tests.push(createManifestTest("manifest.precompile"));
tests.push(createManifestTest("manifest.role.homescreen"));
}
runNextTest();
ok(true, "Test DONE");
SimpleTest.waitForExplicitFinish();

Просмотреть файл

@ -1,21 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=979109
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 979109</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=983502">Mozilla Bug 983502</a>
<script type="application/javascript">
is("getFeature" in navigator, false, "getFeature should not exist without permission");
</script>
</body>
</html>

Просмотреть файл

@ -6,8 +6,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1009645
<head>
<meta charset="utf-8">
<title>Test for Bug 1009645</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1009645">Mozilla Bug 1009645</a>
@ -27,9 +27,9 @@ function testAPIs() {
var APIEndPoints = [
{ name: "MozMobileNetworkInfo", enabled: pref("dom.mobileconnection.enabled") },
// { name: "Navigator.mozBluetooth", enabled: b2gOnly }, // conditional on MOZ_B2G_BT, tricky to test
{ name: "Navigator.mozContacts", enabled: pref("dom.mozContacts.enabled") },
// Bug 1266035 { name: "Navigator.mozContacts", enabled: pref("dom.mozContacts.enabled") },
{ name: "Navigator.getDeviceStorage", enabled: pref("device.storage.enabled") },
{ name: "Navigator.addIdleObserver", enabled: true },
// Bug 1266035 { name: "Navigator.addIdleObserver", enabled: true },
{ name: "Navigator.mozNetworkStats", enabled: pref("dom.mozNetworkStats.enabled") },
{ name: "Navigator.push", enabled: pref("services.push.enabled") },
// { name: "Navigator.mozTime", enabled: b2gOnly }, // conditional on MOZ_TIME_MANAGER, tricky to test

Просмотреть файл

@ -2,10 +2,10 @@
<html>
<head>
<title>Verify mozbrowser APIs are allowed with browser permission</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script>
<script type="text/javascript" src="mozbrowser_api_utils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
</head>
<body>
@ -18,18 +18,12 @@
});
});
add_task(function*() {
yield new Promise(resolve => {
SpecialPowers.pushPermissions([
{ "type": "browser", "allow": 1, "context": document }
], resolve);
});
});
add_task(function*() {
// Create <iframe mozbrowser>
let frame = yield loadFrame({
mozbrowser: "true"
mozbrowser: "true",
// FIXME: Bug 1270790
remote: true
});
// Verify that mozbrowser APIs are accessible

Просмотреть файл

@ -6,32 +6,18 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=985827
<head>
<meta charset="utf-8">
<title>Test for Bug 985827</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
<script type="application/javascript">
/** Test for Bug 985827 **/
function test() {
var is = parent.is;
// Test WebIDL NavigatorProperty objects
var x = navigator.mozContacts;
is(typeof x, "object", "Should have a mozContacts object");
delete navigator.mozContacts;
var y = navigator.mozContacts;
is(x, y, "Should have gotten the same mozContacts object again");
}
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPermissions([
{type: "contacts-read", allow: true, context: document},
{type: "contacts-write", allow: true, context: document},
{type: "contacts-create", allow: true, context: document},
], function() {
addEventListener('load', function() {
var iframe = document.createElement("iframe");
iframe.src = "data:text/html,<script>(" + escape(test.toString()) + ")();</scr" + "ipt>";
var dir = "chrome://mochitests/content/chrome/dom/base/test/";
iframe.src = dir + "file_navigator_resolve_identity.html";
document.body.appendChild(iframe);
iframe.onload = function() { SimpleTest.finish(); };
});

Просмотреть файл

@ -28,27 +28,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=985827
addLoadEvent(function() {
var iframe = document.getElementById("t");
Services.perms.addFromPrincipal(iframe.contentDocument.nodePrincipal,
"contacts-read",
Services.perms.ALLOW_ACTION);
Services.perms.addFromPrincipal(iframe.contentDocument.nodePrincipal,
"contacts-write",
Services.perms.ALLOW_ACTION);
Services.perms.addFromPrincipal(iframe.contentDocument.nodePrincipal,
"contacts-create",
Services.perms.ALLOW_ACTION);
var dir = "chrome://mochitests/content/chrome/dom/base/test/";
iframe.src = dir + "file_navigator_resolve_identity_xrays.xul";
iframe.onload = function() { finish(); };
function finish() {
Services.perms.removeFromPrincipal(document.nodePrincipal,
"contacts-read");
Services.perms.removeFromPrincipal(document.nodePrincipal,
"contacts-write");
Services.perms.removeFromPrincipal(document.nodePrincipal,
"contacts-create");
SimpleTest.finish();
}
});

Просмотреть файл

@ -143,9 +143,12 @@ ThrowNoSetterArg(JSContext* aCx, prototypes::ID aProtoId)
} // namespace dom
struct ErrorResult::Message {
Message() { MOZ_COUNT_CTOR(ErrorResult::Message); }
~Message() { MOZ_COUNT_DTOR(ErrorResult::Message); }
namespace binding_danger {
template<typename CleanupPolicy>
struct TErrorResult<CleanupPolicy>::Message {
Message() { MOZ_COUNT_CTOR(TErrorResult::Message); }
~Message() { MOZ_COUNT_DTOR(TErrorResult::Message); }
nsTArray<nsString> mArgs;
dom::ErrNum mErrorNumber;
@ -156,9 +159,12 @@ struct ErrorResult::Message {
}
};
template<typename CleanupPolicy>
nsTArray<nsString>&
ErrorResult::CreateErrorMessageHelper(const dom::ErrNum errorNumber, nsresult errorType)
TErrorResult<CleanupPolicy>::CreateErrorMessageHelper(const dom::ErrNum errorNumber,
nsresult errorType)
{
AssertInOwningThread();
mResult = errorType;
mMessage = new Message();
@ -166,20 +172,25 @@ ErrorResult::CreateErrorMessageHelper(const dom::ErrNum errorNumber, nsresult er
return mMessage->mArgs;
}
template<typename CleanupPolicy>
void
ErrorResult::SerializeMessage(IPC::Message* aMsg) const
TErrorResult<CleanupPolicy>::SerializeMessage(IPC::Message* aMsg) const
{
using namespace IPC;
AssertInOwningThread();
MOZ_ASSERT(mUnionState == HasMessage);
MOZ_ASSERT(mMessage);
WriteParam(aMsg, mMessage->mArgs);
WriteParam(aMsg, mMessage->mErrorNumber);
}
template<typename CleanupPolicy>
bool
ErrorResult::DeserializeMessage(const IPC::Message* aMsg, PickleIterator* aIter)
TErrorResult<CleanupPolicy>::DeserializeMessage(const IPC::Message* aMsg,
PickleIterator* aIter)
{
using namespace IPC;
AssertInOwningThread();
nsAutoPtr<Message> readMessage(new Message());
if (!ReadParam(aMsg, aIter, &readMessage->mArgs) ||
!ReadParam(aMsg, aIter, &readMessage->mErrorNumber)) {
@ -197,9 +208,11 @@ ErrorResult::DeserializeMessage(const IPC::Message* aMsg, PickleIterator* aIter)
return true;
}
template<typename CleanupPolicy>
void
ErrorResult::SetPendingExceptionWithMessage(JSContext* aCx)
TErrorResult<CleanupPolicy>::SetPendingExceptionWithMessage(JSContext* aCx)
{
AssertInOwningThread();
MOZ_ASSERT(mMessage, "SetPendingExceptionWithMessage() can be called only once");
MOZ_ASSERT(mUnionState == HasMessage);
@ -220,9 +233,11 @@ ErrorResult::SetPendingExceptionWithMessage(JSContext* aCx)
mResult = NS_OK;
}
template<typename CleanupPolicy>
void
ErrorResult::ClearMessage()
TErrorResult<CleanupPolicy>::ClearMessage()
{
AssertInOwningThread();
MOZ_ASSERT(IsErrorWithMessage());
delete mMessage;
mMessage = nullptr;
@ -231,9 +246,11 @@ ErrorResult::ClearMessage()
#endif // DEBUG
}
template<typename CleanupPolicy>
void
ErrorResult::ThrowJSException(JSContext* cx, JS::Handle<JS::Value> exn)
TErrorResult<CleanupPolicy>::ThrowJSException(JSContext* cx, JS::Handle<JS::Value> exn)
{
AssertInOwningThread();
MOZ_ASSERT(mMightHaveUnreportedJSException,
"Why didn't you tell us you planned to throw a JS exception?");
@ -243,7 +260,7 @@ ErrorResult::ThrowJSException(JSContext* cx, JS::Handle<JS::Value> exn)
// don't set it to exn yet, because we don't want to do that until after we
// root.
mJSException.setUndefined();
if (!js::AddRawValueRoot(cx, &mJSException, "ErrorResult::mJSException")) {
if (!js::AddRawValueRoot(cx, &mJSException, "TErrorResult::mJSException")) {
// Don't use NS_ERROR_DOM_JS_EXCEPTION, because that indicates we have
// in fact rooted mJSException.
mResult = NS_ERROR_OUT_OF_MEMORY;
@ -256,9 +273,11 @@ ErrorResult::ThrowJSException(JSContext* cx, JS::Handle<JS::Value> exn)
}
}
template<typename CleanupPolicy>
void
ErrorResult::SetPendingJSException(JSContext* cx)
TErrorResult<CleanupPolicy>::SetPendingJSException(JSContext* cx)
{
AssertInOwningThread();
MOZ_ASSERT(!mMightHaveUnreportedJSException,
"Why didn't you tell us you planned to handle JS exceptions?");
MOZ_ASSERT(mUnionState == HasJSException);
@ -278,7 +297,8 @@ ErrorResult::SetPendingJSException(JSContext* cx)
#endif // DEBUG
}
struct ErrorResult::DOMExceptionInfo {
template<typename CleanupPolicy>
struct TErrorResult<CleanupPolicy>::DOMExceptionInfo {
DOMExceptionInfo(nsresult rv, const nsACString& message)
: mMessage(message)
, mRv(rv)
@ -288,20 +308,25 @@ struct ErrorResult::DOMExceptionInfo {
nsresult mRv;
};
template<typename CleanupPolicy>
void
ErrorResult::SerializeDOMExceptionInfo(IPC::Message* aMsg) const
TErrorResult<CleanupPolicy>::SerializeDOMExceptionInfo(IPC::Message* aMsg) const
{
using namespace IPC;
AssertInOwningThread();
MOZ_ASSERT(mDOMExceptionInfo);
MOZ_ASSERT(mUnionState == HasDOMExceptionInfo);
WriteParam(aMsg, mDOMExceptionInfo->mMessage);
WriteParam(aMsg, mDOMExceptionInfo->mRv);
}
template<typename CleanupPolicy>
bool
ErrorResult::DeserializeDOMExceptionInfo(const IPC::Message* aMsg, PickleIterator* aIter)
TErrorResult<CleanupPolicy>::DeserializeDOMExceptionInfo(const IPC::Message* aMsg,
PickleIterator* aIter)
{
using namespace IPC;
AssertInOwningThread();
nsCString message;
nsresult rv;
if (!ReadParam(aMsg, aIter, &message) ||
@ -318,9 +343,12 @@ ErrorResult::DeserializeDOMExceptionInfo(const IPC::Message* aMsg, PickleIterato
return true;
}
template<typename CleanupPolicy>
void
ErrorResult::ThrowDOMException(nsresult rv, const nsACString& message)
TErrorResult<CleanupPolicy>::ThrowDOMException(nsresult rv,
const nsACString& message)
{
AssertInOwningThread();
ClearUnionData();
mResult = NS_ERROR_DOM_DOMEXCEPTION;
@ -330,9 +358,11 @@ ErrorResult::ThrowDOMException(nsresult rv, const nsACString& message)
#endif
}
template<typename CleanupPolicy>
void
ErrorResult::SetPendingDOMException(JSContext* cx)
TErrorResult<CleanupPolicy>::SetPendingDOMException(JSContext* cx)
{
AssertInOwningThread();
MOZ_ASSERT(mDOMExceptionInfo,
"SetPendingDOMException() can be called only once");
MOZ_ASSERT(mUnionState == HasDOMExceptionInfo);
@ -343,9 +373,11 @@ ErrorResult::SetPendingDOMException(JSContext* cx)
mResult = NS_OK;
}
template<typename CleanupPolicy>
void
ErrorResult::ClearDOMExceptionInfo()
TErrorResult<CleanupPolicy>::ClearDOMExceptionInfo()
{
AssertInOwningThread();
MOZ_ASSERT(IsDOMException());
MOZ_ASSERT(mUnionState == HasDOMExceptionInfo || !mDOMExceptionInfo);
delete mDOMExceptionInfo;
@ -355,9 +387,11 @@ ErrorResult::ClearDOMExceptionInfo()
#endif // DEBUG
}
template<typename CleanupPolicy>
void
ErrorResult::ClearUnionData()
TErrorResult<CleanupPolicy>::ClearUnionData()
{
AssertInOwningThread();
if (IsJSException()) {
JSContext* cx = nsContentUtils::RootingCx();
MOZ_ASSERT(cx);
@ -373,9 +407,11 @@ ErrorResult::ClearUnionData()
}
}
template<typename CleanupPolicy>
void
ErrorResult::SetPendingGenericErrorException(JSContext* cx)
TErrorResult<CleanupPolicy>::SetPendingGenericErrorException(JSContext* cx)
{
AssertInOwningThread();
MOZ_ASSERT(!IsErrorWithMessage());
MOZ_ASSERT(!IsJSException());
MOZ_ASSERT(!IsDOMException());
@ -383,9 +419,12 @@ ErrorResult::SetPendingGenericErrorException(JSContext* cx)
mResult = NS_OK;
}
ErrorResult&
ErrorResult::operator=(ErrorResult&& aRHS)
template<typename CleanupPolicy>
TErrorResult<CleanupPolicy>&
TErrorResult<CleanupPolicy>::operator=(TErrorResult<CleanupPolicy>&& aRHS)
{
AssertInOwningThread();
aRHS.AssertInOwningThread();
// Clear out any union members we may have right now, before we
// start writing to it.
ClearUnionData();
@ -401,7 +440,7 @@ ErrorResult::operator=(ErrorResult&& aRHS)
JSContext* cx = nsContentUtils::RootingCx();
MOZ_ASSERT(cx);
mJSException.setUndefined();
if (!js::AddRawValueRoot(cx, &mJSException, "ErrorResult::mJSException")) {
if (!js::AddRawValueRoot(cx, &mJSException, "TErrorResult::mJSException")) {
MOZ_CRASH("Could not root mJSException, we're about to OOM");
}
mJSException = aRHS.mJSException;
@ -427,9 +466,13 @@ ErrorResult::operator=(ErrorResult&& aRHS)
return *this;
}
template<typename CleanupPolicy>
void
ErrorResult::CloneTo(ErrorResult& aRv) const
TErrorResult<CleanupPolicy>::CloneTo(TErrorResult& aRv) const
{
AssertInOwningThread();
aRv.AssertInOwningThread();
aRv.ClearUnionData();
aRv.mResult = mResult;
#ifdef DEBUG
@ -459,9 +502,11 @@ ErrorResult::CloneTo(ErrorResult& aRv) const
}
}
template<typename CleanupPolicy>
void
ErrorResult::SuppressException()
TErrorResult<CleanupPolicy>::SuppressException()
{
AssertInOwningThread();
WouldReportJSException();
ClearUnionData();
// We don't use AssignErrorCode, because we want to override existing error
@ -469,9 +514,11 @@ ErrorResult::SuppressException()
mResult = NS_OK;
}
template<typename CleanupPolicy>
void
ErrorResult::SetPendingException(JSContext* cx)
TErrorResult<CleanupPolicy>::SetPendingException(JSContext* cx)
{
AssertInOwningThread();
if (IsUncatchableException()) {
// Nuke any existing exception on cx, to make sure we're uncatchable.
JS_ClearPendingException(cx);
@ -501,9 +548,11 @@ ErrorResult::SetPendingException(JSContext* cx)
SetPendingGenericErrorException(cx);
}
template<typename CleanupPolicy>
void
ErrorResult::StealExceptionFromJSContext(JSContext* cx)
TErrorResult<CleanupPolicy>::StealExceptionFromJSContext(JSContext* cx)
{
AssertInOwningThread();
MOZ_ASSERT(mMightHaveUnreportedJSException,
"Why didn't you tell us you planned to throw a JS exception?");
@ -517,9 +566,11 @@ ErrorResult::StealExceptionFromJSContext(JSContext* cx)
JS_ClearPendingException(cx);
}
template<typename CleanupPolicy>
void
ErrorResult::NoteJSContextException(JSContext* aCx)
TErrorResult<CleanupPolicy>::NoteJSContextException(JSContext* aCx)
{
AssertInOwningThread();
if (JS_IsExceptionPending(aCx)) {
mResult = NS_ERROR_DOM_EXCEPTION_ON_JSCONTEXT;
} else {
@ -527,6 +578,12 @@ ErrorResult::NoteJSContextException(JSContext* aCx)
}
}
template class TErrorResult<JustAssertCleanupPolicy>;
template class TErrorResult<AssertAndSuppressCleanupPolicy>;
template class TErrorResult<JustSuppressCleanupPolicy>;
} // namespace binding_danger
namespace dom {
bool
@ -2502,32 +2559,6 @@ ConvertJSValueToByteString(JSContext* cx, JS::Handle<JS::Value> v,
return true;
}
bool
IsInPrivilegedApp(JSContext* aCx, JSObject* aObj)
{
if (!NS_IsMainThread()) {
return GetWorkerPrivateFromContext(aCx)->IsInPrivilegedApp();
}
nsIPrincipal* principal = nsContentUtils::ObjectPrincipal(aObj);
uint16_t appStatus = principal->GetAppStatus();
return (appStatus == nsIPrincipal::APP_STATUS_CERTIFIED ||
appStatus == nsIPrincipal::APP_STATUS_PRIVILEGED) ||
Preferences::GetBool("dom.ignore_webidl_scope_checks", false);
}
bool
IsInCertifiedApp(JSContext* aCx, JSObject* aObj)
{
if (!NS_IsMainThread()) {
return GetWorkerPrivateFromContext(aCx)->IsInCertifiedApp();
}
nsIPrincipal* principal = nsContentUtils::ObjectPrincipal(aObj);
return principal->GetAppStatus() == nsIPrincipal::APP_STATUS_CERTIFIED ||
Preferences::GetBool("dom.ignore_webidl_scope_checks", false);
}
void
FinalizeGlobal(JSFreeOp* aFreeOp, JSObject* aObj)
{
@ -2562,50 +2593,6 @@ EnumerateGlobal(JSContext* aCx, JS::Handle<JSObject*> aObj)
return JS_EnumerateStandardClasses(aCx, aObj);
}
bool
CheckAnyPermissions(JSContext* aCx, JSObject* aObj, const char* const aPermissions[])
{
JS::Rooted<JSObject*> rootedObj(aCx, aObj);
nsPIDOMWindowInner* window = xpc::WindowGlobalOrNull(rootedObj)->AsInner();
if (!window) {
return false;
}
nsCOMPtr<nsIPermissionManager> permMgr = services::GetPermissionManager();
NS_ENSURE_TRUE(permMgr, false);
do {
uint32_t permission = nsIPermissionManager::DENY_ACTION;
permMgr->TestPermissionFromWindow(window, *aPermissions, &permission);
if (permission == nsIPermissionManager::ALLOW_ACTION) {
return true;
}
} while (*(++aPermissions));
return false;
}
bool
CheckAllPermissions(JSContext* aCx, JSObject* aObj, const char* const aPermissions[])
{
JS::Rooted<JSObject*> rootedObj(aCx, aObj);
nsPIDOMWindowInner* window = xpc::WindowGlobalOrNull(rootedObj)->AsInner();
if (!window) {
return false;
}
nsCOMPtr<nsIPermissionManager> permMgr = services::GetPermissionManager();
NS_ENSURE_TRUE(permMgr, false);
do {
uint32_t permission = nsIPermissionManager::DENY_ACTION;
permMgr->TestPermissionFromWindow(window, *aPermissions, &permission);
if (permission != nsIPermissionManager::ALLOW_ACTION) {
return false;
}
} while (*(++aPermissions));
return true;
}
bool
IsNonExposedGlobal(JSContext* aCx, JSObject* aGlobal,
uint32_t aNonExposedGlobals)

Просмотреть файл

@ -106,7 +106,7 @@ IsNonProxyDOMClass(const JSClass* clasp)
return IsNonProxyDOMClass(js::Valueify(clasp));
}
// Returns true if the JSClass is used for DOM interface and interface
// Returns true if the JSClass is used for DOM interface and interface
// prototype objects.
inline bool
IsDOMIfaceAndProtoClass(const JSClass* clasp)
@ -2011,6 +2011,12 @@ private:
};
};
class FastErrorResult :
public mozilla::binding_danger::TErrorResult<
mozilla::binding_danger::JustAssertCleanupPolicy>
{
};
} // namespace binding_detail
enum StringificationBehavior {
@ -2992,20 +2998,6 @@ public:
}
};
/*
* Helper function for testing whether the given object comes from a
* privileged app.
*/
bool
IsInPrivilegedApp(JSContext* aCx, JSObject* aObj);
/*
* Helper function for testing whether the given object comes from a
* certified app.
*/
bool
IsInCertifiedApp(JSContext* aCx, JSObject* aObj);
void
FinalizeGlobal(JSFreeOp* aFop, JSObject* aObj);

Просмотреть файл

@ -57,12 +57,6 @@ DOMInterfaces = {
'concrete': False
},
'AnimationEffectTiming': {
'implicitJSContext': {
'setterOnly': [ 'easing' ]
}
},
'AnimationTimeline': {
'concrete': False
},

Просмотреть файл

@ -1869,18 +1869,6 @@ def isChromeOnly(m):
return m.getExtendedAttribute("ChromeOnly")
def getAvailableInTestFunc(obj):
availableIn = obj.getExtendedAttribute("AvailableIn")
if availableIn is None:
return None
assert isinstance(availableIn, list) and len(availableIn) == 1
if availableIn[0] == "PrivilegedApps":
return "IsInPrivilegedApp"
if availableIn[0] == "CertifiedApps":
return "IsInCertifiedApp"
raise TypeError("Unknown AvailableIn value '%s'" % availableIn[0])
class MemberCondition:
"""
An object representing the condition for a member to actually be
@ -1890,21 +1878,14 @@ class MemberCondition:
pref: The name of the preference.
func: The name of the function.
secureContext: A bool indicating whether a secure context is required.
available: A string indicating where we should be available.
checkAnyPermissions: An integer index for the anypermissions_* to use.
checkAllPermissions: An integer index for the allpermissions_* to use.
nonExposedGlobals: A set of names of globals. Can be empty, in which case
it's treated the same way as None.
"""
def __init__(self, pref=None, func=None, secureContext=False, available=None,
checkAnyPermissions=None, checkAllPermissions=None,
def __init__(self, pref=None, func=None, secureContext=False,
nonExposedGlobals=None):
assert pref is None or isinstance(pref, str)
assert func is None or isinstance(func, str)
assert isinstance(secureContext, bool)
assert available is None or isinstance(available, str)
assert checkAnyPermissions is None or isinstance(checkAnyPermissions, int)
assert checkAllPermissions is None or isinstance(checkAllPermissions, int)
assert nonExposedGlobals is None or isinstance(nonExposedGlobals, set)
self.pref = pref
self.secureContext = secureContext
@ -1914,15 +1895,6 @@ class MemberCondition:
return "nullptr"
return "&" + val
self.func = toFuncPtr(func)
self.available = toFuncPtr(available)
if checkAnyPermissions is None:
self.checkAnyPermissions = "nullptr"
else:
self.checkAnyPermissions = "anypermissions_%i" % checkAnyPermissions
if checkAllPermissions is None:
self.checkAllPermissions = "nullptr"
else:
self.checkAllPermissions = "allpermissions_%i" % checkAllPermissions
if nonExposedGlobals:
# Nonempty set
@ -1935,9 +1907,6 @@ class MemberCondition:
def __eq__(self, other):
return (self.pref == other.pref and self.func == other.func and
self.secureContext == other.secureContext and
self.available == other.available and
self.checkAnyPermissions == other.checkAnyPermissions and
self.checkAllPermissions == other.checkAllPermissions and
self.nonExposedGlobals == other.nonExposedGlobals)
def __ne__(self, other):
@ -1947,9 +1916,6 @@ class MemberCondition:
return (self.pref is not None or
self.secureContext or
self.func != "nullptr" or
self.available != "nullptr" or
self.checkAnyPermissions != "nullptr" or
self.checkAllPermissions != "nullptr" or
self.nonExposedGlobals != "0")
@ -2019,9 +1985,6 @@ class PropertyDefiner:
PropertyDefiner.getStringAttr(interfaceMember,
"Func"),
interfaceMember.getExtendedAttribute("SecureContext") is not None,
getAvailableInTestFunc(interfaceMember),
descriptor.checkAnyPermissionsIndicesForMembers.get(interfaceMember.identifier.name),
descriptor.checkAllPermissionsIndicesForMembers.get(interfaceMember.identifier.name),
nonExposureSet)
def generatePrefableArray(self, array, name, specFormatter, specTerminator,
@ -2065,7 +2028,7 @@ class PropertyDefiner:
disablersTemplate = dedent(
"""
static PrefableDisablers %s_disablers%d = {
true, %s, %s, %s, %s, %s, %s
true, %s, %s, %s
};
""")
prefableWithDisablersTemplate = ' { &%s_disablers%d, &%s_specs[%d] }'
@ -2087,10 +2050,7 @@ class PropertyDefiner:
(name, len(specs),
toStringBool(condition.secureContext),
condition.nonExposedGlobals,
condition.func,
condition.available,
condition.checkAnyPermissions,
condition.checkAllPermissions))
condition.func))
else:
prefableSpecs.append(prefableWithoutDisablersTemplate %
(name, len(specs)))
@ -3334,15 +3294,6 @@ class CGConstructorEnabled(CGAbstractMethod):
body.append(exposedInWorkerCheck)
conditions = getConditionList(iface, "aCx", "aObj")
availableIn = getAvailableInTestFunc(iface)
if availableIn:
conditions.append(CGGeneric("%s(aCx, aObj)" % availableIn))
checkAnyPermissions = self.descriptor.checkAnyPermissionsIndex
if checkAnyPermissions is not None:
conditions.append(CGGeneric("CheckAnyPermissions(aCx, aObj, anypermissions_%i)" % checkAnyPermissions))
checkAllPermissions = self.descriptor.checkAllPermissionsIndex
if checkAllPermissions is not None:
conditions.append(CGGeneric("CheckAllPermissions(aCx, aObj, allpermissions_%i)" % checkAllPermissions))
# We should really have some conditions
assert len(body) or len(conditions)
@ -5261,7 +5212,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
templateBody = fill(
"""
{ // Scope for our GlobalObject, ErrorResult, JSAutoCompartment,
{ // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
// etc.
JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
@ -5276,7 +5227,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
if (!JS_WrapValue(cx, &valueToResolve)) {
$*{exceptionCode}
}
ErrorResult promiseRv;
binding_detail::FastErrorResult promiseRv;
#ifdef SPIDERMONKEY_PROMISE
nsCOMPtr<nsIGlobalObject> global =
do_QueryInterface(promiseGlobal.GetAsSupports());
@ -6971,7 +6922,7 @@ class CGCallGenerator(CGThing):
self.cgRoot.append(call)
if isFallible:
self.cgRoot.prepend(CGGeneric("ErrorResult rv;\n"))
self.cgRoot.prepend(CGGeneric("binding_detail::FastErrorResult rv;\n"))
self.cgRoot.append(CGGeneric(dedent(
"""
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
@ -8486,7 +8437,7 @@ class CGEnumerateHook(CGAbstractBindingMethod):
def generate_code(self):
return CGGeneric(dedent("""
AutoTArray<nsString, 8> names;
ErrorResult rv;
binding_detail::FastErrorResult rv;
self->GetOwnPropertyNames(cx, names, rv);
if (rv.MaybeSetPendingException(cx)) {
return false;
@ -10579,7 +10530,7 @@ class CGEnumerateOwnPropertiesViaGetOwnPropertyNames(CGAbstractBindingMethod):
def generate_code(self):
return CGGeneric(dedent("""
AutoTArray<nsString, 8> names;
ErrorResult rv;
binding_detail::FastErrorResult rv;
self->GetOwnPropertyNames(cx, names, rv);
if (rv.MaybeSetPendingException(cx)) {
return false;
@ -12013,17 +11964,6 @@ class CGDescriptor(CGThing):
if descriptor.concrete and descriptor.wrapperCache:
cgThings.append(CGClassObjectMovedHook(descriptor))
for name in ["anypermissions", "allpermissions"]:
permissions = getattr(descriptor, name)
if len(permissions):
for (k, v) in sorted(permissions.items()):
perms = CGList((CGGeneric('"%s",' % p) for p in k), joiner="\n")
perms.append(CGGeneric("nullptr"))
cgThings.append(CGWrapper(CGIndenter(perms),
pre="static const char* const %s_%i[] = {\n" % (name, v),
post="\n};\n",
defineOnly=True))
# Generate the _ClearCachedFooValue methods before the property arrays that use them.
if descriptor.interface.isJSImplemented():
for m in clearableCachedAttrs(descriptor):
@ -16409,40 +16349,6 @@ class GlobalGenRoots():
# Done.
return curr
@staticmethod
def FeatureList(config):
things = set()
for d in config.getDescriptors():
if not d.interface.isExternal() and d.featureDetectibleThings is not None:
things.update(d.featureDetectibleThings)
things = CGList((CGGeneric(declare='"%s",' % t) for t in sorted(things)), joiner="\n")
things.append(CGGeneric(declare="nullptr"))
things = CGWrapper(CGIndenter(things),
pre="static const char* const FeatureList[] = {\n",
post="\n};\n")
helper_pre = "bool IsFeatureDetectible(const nsAString& aFeature) {\n"
helper = CGWrapper(CGIndenter(things),
pre=helper_pre,
post=dedent("""
const char* const* feature = FeatureList;
while (*feature) {
if (aFeature.EqualsASCII(*feature)) {
return true;
}
++feature;
}
return false;
}
"""))
curr = CGNamespace.build(['mozilla', 'dom'], helper)
curr = CGHeaders([], [], [], [], ["nsString.h"], [], 'FeatureList', curr)
curr = CGIncludeGuard('FeatureList', curr)
return curr
# Code generator for simple events
class CGEventGetter(CGNativeMember):

Просмотреть файл

@ -508,64 +508,11 @@ class Descriptor(DescriptorProvider):
self._binaryNames.setdefault('__stringifier', 'Stringify')
if not self.interface.isExternal():
self.anypermissions = dict()
self.allpermissions = dict()
# Adds a permission list to this descriptor and returns the index to use.
def addPermissions(ifaceOrMember, attribute):
if attribute == "CheckAllPermissions":
permissions = self.allpermissions
else:
permissions = self.anypermissions
checkPermissions = ifaceOrMember.getExtendedAttribute(attribute)
if checkPermissions is None:
return None
# It's a list of whitespace-separated strings
assert(len(checkPermissions) is 1)
assert(checkPermissions[0] is not None)
checkPermissions = checkPermissions[0]
permissionsList = checkPermissions.split()
if len(permissionsList) == 0:
raise TypeError("Need at least one permission name for %s" % attribute)
permissionsList = tuple(sorted(set(permissionsList)))
return permissions.setdefault(permissionsList, len(permissions))
self.checkAnyPermissionsIndex = addPermissions(self.interface, "CheckAnyPermissions")
self.checkAnyPermissionsIndicesForMembers = dict()
self.checkAllPermissionsIndex = addPermissions(self.interface, "CheckAllPermissions")
self.checkAllPermissionsIndicesForMembers = dict()
for m in self.interface.members:
permissionsIndex = addPermissions(m, "CheckAnyPermissions")
if permissionsIndex is not None:
self.checkAnyPermissionsIndicesForMembers[m.identifier.name] = permissionsIndex
allpermissionsIndex = addPermissions(m, "CheckAllPermissions")
if allpermissionsIndex is not None:
self.checkAllPermissionsIndicesForMembers[m.identifier.name] = allpermissionsIndex
def isTestInterface(iface):
return (iface.identifier.name in ["TestInterface",
"TestJSImplInterface",
"TestRenamedInterface"])
self.featureDetectibleThings = set()
if not isTestInterface(self.interface):
if (self.interface.getExtendedAttribute("CheckAnyPermissions") or
self.interface.getExtendedAttribute("CheckAllPermissions") or
self.interface.getExtendedAttribute("AvailableIn") == "PrivilegedApps"):
iface = self.interface.identifier.name
self.featureDetectibleThings.add(iface)
for m in self.interface.members:
self.featureDetectibleThings.add("%s.%s" % (iface, m.identifier.name))
for m in self.interface.members:
if (m.getExtendedAttribute("CheckAnyPermissions") or
m.getExtendedAttribute("CheckAllPermissions") or
m.getExtendedAttribute("AvailableIn") == "PrivilegedApps"):
self.featureDetectibleThings.add("%s.%s" % (self.interface.identifier.name, m.identifier.name))
for member in self.interface.members:
if not member.isAttr() and not member.isMethod():
continue

Просмотреть файл

@ -74,18 +74,6 @@ typedef bool
JS::Handle<JSObject*> obj,
JS::AutoIdVector& props);
// Returns true if aObj's global has any of the permissions named in
// aPermissions set to nsIPermissionManager::ALLOW_ACTION. aPermissions must be
// null-terminated.
bool
CheckAnyPermissions(JSContext* aCx, JSObject* aObj, const char* const aPermissions[]);
// Returns true if aObj's global has all of the permissions named in
// aPermissions set to nsIPermissionManager::ALLOW_ACTION. aPermissions must be
// null-terminated.
bool
CheckAllPermissions(JSContext* aCx, JSObject* aObj, const char* const aPermissions[]);
// Returns true if the given global is of a type whose bit is set in
// aNonExposedGlobals.
bool
@ -138,20 +126,6 @@ struct PrefableDisablers {
!enabledFunc(cx, js::GetGlobalForObjectCrossCompartment(obj))) {
return false;
}
if (availableFunc &&
!availableFunc(cx, js::GetGlobalForObjectCrossCompartment(obj))) {
return false;
}
if (checkAnyPermissions &&
!CheckAnyPermissions(cx, js::GetGlobalForObjectCrossCompartment(obj),
checkAnyPermissions)) {
return false;
}
if (checkAllPermissions &&
!CheckAllPermissions(cx, js::GetGlobalForObjectCrossCompartment(obj),
checkAllPermissions)) {
return false;
}
return true;
}
@ -167,16 +141,8 @@ struct PrefableDisablers {
// A function pointer to a function that can say the property is disabled
// even if "enabled" is set to true. If the pointer is null the value of
// "enabled" is used as-is unless availableFunc overrides.
// "enabled" is used as-is.
const PropertyEnabled enabledFunc;
// A function pointer to a function that can be used to disable a
// property even if "enabled" is true and enabledFunc allowed. This
// is basically a hack to avoid having to codegen PropertyEnabled
// implementations in case when we need to do two separate checks.
const PropertyEnabled availableFunc;
const char* const* const checkAnyPermissions;
const char* const* const checkAllPermissions;
};
template<typename T>

Просмотреть файл

@ -5,9 +5,10 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* A struct for tracking exceptions that need to be thrown to JS.
* A set of structs for tracking exceptions that need to be thrown to JS:
* ErrorResult and IgnoredErrorResult.
*
* Conceptually, an ErrorResult represents either success or an exception in the
* Conceptually, these structs represent either success or an exception in the
* process of being thrown. This means that a failing ErrorResult _must_ be
* handled in one of the following ways before coming off the stack:
*
@ -17,6 +18,8 @@
* MaybeSetPendingException.
* 4) Converted to an exception JS::Value (probably to then reject a Promise
* with) via dom::ToJSValue.
*
* An IgnoredErrorResult will automatically do the first of those four things.
*/
#ifndef mozilla_ErrorResult_h
@ -31,6 +34,7 @@
#include "mozilla/Assertions.h"
#include "mozilla/Move.h"
#include "nsTArray.h"
#include "nsISupportsImpl.h"
namespace IPC {
class Message;
@ -87,9 +91,25 @@ struct StringArrayAppender
} // namespace dom
class ErrorResult {
class ErrorResult;
namespace binding_danger {
/**
* Templated implementation class for various ErrorResult-like things. The
* instantiations differ only in terms of their cleanup policies (used in the
* destructor), which they can specify via the template argument. Note that
* this means it's safe to reinterpret_cast between the instantiations unless
* you plan to invoke the destructor through such a cast pointer.
*
* A cleanup policy consists of two booleans: whether to assert that we've been
* reported or suppressed, and whether to then go ahead and suppress the
* exception.
*/
template<typename CleanupPolicy>
class TErrorResult {
public:
ErrorResult()
TErrorResult()
: mResult(NS_OK)
#ifdef DEBUG
, mMightHaveUnreportedJSException(false)
@ -98,49 +118,58 @@ public:
{
}
#ifdef DEBUG
~ErrorResult() {
// Consumers should have called one of MaybeSetPendingException
// (possibly via ToJSValue), StealNSResult, and SuppressException
MOZ_ASSERT(!Failed());
MOZ_ASSERT(!mMightHaveUnreportedJSException);
MOZ_ASSERT(mUnionState == HasNothing);
}
#endif // DEBUG
~TErrorResult() {
AssertInOwningThread();
ErrorResult(ErrorResult&& aRHS)
if (CleanupPolicy::assertHandled) {
// Consumers should have called one of MaybeSetPendingException
// (possibly via ToJSValue), StealNSResult, and SuppressException
AssertReportedOrSuppressed();
}
if (CleanupPolicy::suppress) {
SuppressException();
}
// And now assert that we're in a good final state.
AssertReportedOrSuppressed();
}
TErrorResult(TErrorResult&& aRHS)
// Initialize mResult and whatever else we need to default-initialize, so
// the ClearUnionData call in our operator= will do the right thing
// (nothing).
: ErrorResult()
: TErrorResult()
{
*this = Move(aRHS);
}
ErrorResult& operator=(ErrorResult&& aRHS);
TErrorResult& operator=(TErrorResult&& aRHS);
explicit ErrorResult(nsresult aRv)
: ErrorResult()
explicit TErrorResult(nsresult aRv)
: TErrorResult()
{
AssignErrorCode(aRv);
}
operator ErrorResult&();
void Throw(nsresult rv) {
MOZ_ASSERT(NS_FAILED(rv), "Please don't try throwing success");
AssignErrorCode(rv);
}
// Duplicate our current state on the given ErrorResult object. Any existing
// errors or messages on the target will be suppressed before cloning. Our
// own error state remains unchanged.
void CloneTo(ErrorResult& aRv) const;
// Duplicate our current state on the given TErrorResult object. Any
// existing errors or messages on the target will be suppressed before
// cloning. Our own error state remains unchanged.
void CloneTo(TErrorResult& aRv) const;
// Use SuppressException when you want to suppress any exception that might be
// on the ErrorResult. After this call, the ErrorResult will be back a "no
// on the TErrorResult. After this call, the TErrorResult will be back a "no
// exception thrown" state.
void SuppressException();
// Use StealNSResult() when you want to safely convert the ErrorResult to an
// nsresult that you will then return to a caller. This will
// Use StealNSResult() when you want to safely convert the TErrorResult to
// an nsresult that you will then return to a caller. This will
// SuppressException(), since there will no longer be a way to report it.
nsresult StealNSResult() {
nsresult rv = ErrorCode();
@ -148,11 +177,11 @@ public:
return rv;
}
// Use MaybeSetPendingException to convert an ErrorResult to a pending
// Use MaybeSetPendingException to convert a TErrorResult to a pending
// exception on the given JSContext. This is the normal "throw an exception"
// codepath.
//
// The return value is false if the ErrorResult represents success, true
// The return value is false if the TErrorResult represents success, true
// otherwise. This does mean that in JSAPI method implementations you can't
// just use this as |return rv.MaybeSetPendingException(cx)| (though you could
// |return !rv.MaybeSetPendingException(cx)|), but in practice pretty much any
@ -173,7 +202,7 @@ public:
// considered equivalent to a JSAPI failure in terms of what callers should do
// after true is returned.
//
// After this call, the ErrorResult will no longer return true from Failed(),
// After this call, the TErrorResult will no longer return true from Failed(),
// since the exception will have moved to the JSContext.
bool MaybeSetPendingException(JSContext* cx)
{
@ -187,7 +216,7 @@ public:
}
// Use StealExceptionFromJSContext to convert a pending exception on a
// JSContext to an ErrorResult. This function must be called only when a
// JSContext to a TErrorResult. This function must be called only when a
// JSAPI operation failed. It assumes that lack of pending exception on the
// JSContext means an uncatchable exception was thrown.
//
@ -215,11 +244,11 @@ public:
bool IsErrorWithMessage() const { return ErrorCode() == NS_ERROR_TYPE_ERR || ErrorCode() == NS_ERROR_RANGE_ERR; }
// Facilities for throwing a preexisting JS exception value via this
// ErrorResult. The contract is that any code which might end up calling
// TErrorResult. The contract is that any code which might end up calling
// ThrowJSException() or StealExceptionFromJSContext() must call
// MightThrowJSException() even if no exception is being thrown. Code that
// conditionally calls ToJSValue on this ErrorResult only if Failed() must
// first call WouldReportJSException even if this ErrorResult has not failed.
// conditionally calls ToJSValue on this TErrorResult only if Failed() must
// first call WouldReportJSException even if this TErrorResult has not failed.
//
// The exn argument to ThrowJSException can be in any compartment. It does
// not have to be in the compartment of cx. If someone later uses it, they
@ -235,12 +264,12 @@ public:
void ThrowDOMException(nsresult rv, const nsACString& message = EmptyCString());
bool IsDOMException() const { return ErrorCode() == NS_ERROR_DOM_DOMEXCEPTION; }
// Flag on the ErrorResult that whatever needs throwing has been
// Flag on the TErrorResult that whatever needs throwing has been
// thrown on the JSContext already and we should not mess with it.
// If nothing was thrown, this becomes an uncatchable exception.
void NoteJSContextException(JSContext* aCx);
// Check whether the ErrorResult says to just throw whatever is on
// Check whether the TErrorResult says to just throw whatever is on
// the JSContext already.
bool IsJSContextException() {
return ErrorCode() == NS_ERROR_DOM_EXCEPTION_ON_JSCONTEXT;
@ -306,6 +335,7 @@ private:
};
#endif // DEBUG
friend struct IPC::ParamTraits<TErrorResult>;
friend struct IPC::ParamTraits<ErrorResult>;
void SerializeMessage(IPC::Message* aMsg) const;
bool DeserializeMessage(const IPC::Message* aMsg, PickleIterator* aIter);
@ -313,7 +343,7 @@ private:
void SerializeDOMExceptionInfo(IPC::Message* aMsg) const;
bool DeserializeDOMExceptionInfo(const IPC::Message* aMsg, PickleIterator* aIter);
// Helper method that creates a new Message for this ErrorResult,
// Helper method that creates a new Message for this TErrorResult,
// and returns the arguments array from that Message.
nsTArray<nsString>& CreateErrorMessageHelper(const dom::ErrNum errorNumber, nsresult errorType);
@ -336,6 +366,12 @@ private:
#endif // DEBUG
}
MOZ_ALWAYS_INLINE void AssertInOwningThread() const {
#ifdef DEBUG
NS_ASSERT_OWNINGTHREAD(TErrorResult);
#endif
}
void AssignErrorCode(nsresult aRv) {
MOZ_ASSERT(aRv != NS_ERROR_TYPE_ERR, "Use ThrowTypeError()");
MOZ_ASSERT(aRv != NS_ERROR_RANGE_ERR, "Use ThrowRangeError()");
@ -371,6 +407,12 @@ private:
void SetPendingDOMException(JSContext* cx);
void SetPendingGenericErrorException(JSContext* cx);
MOZ_ALWAYS_INLINE void AssertReportedOrSuppressed()
{
MOZ_ASSERT(!Failed());
MOZ_ASSERT(!mMightHaveUnreportedJSException);
MOZ_ASSERT(mUnionState == HasNothing);
}
// Special values of mResult:
// NS_ERROR_TYPE_ERR -- ThrowTypeError() called on us.
@ -404,22 +446,85 @@ private:
// we should have something, if we have already cleaned up the
// something.
UnionState mUnionState;
// The thread that created this TErrorResult
NS_DECL_OWNINGTHREAD;
#endif
// Not to be implemented, to make sure people always pass this by
// reference, not by value.
TErrorResult(const TErrorResult&) = delete;
void operator=(const TErrorResult&) = delete;
};
struct JustAssertCleanupPolicy {
static const bool assertHandled = true;
static const bool suppress = false;
};
struct AssertAndSuppressCleanupPolicy {
static const bool assertHandled = true;
static const bool suppress = true;
};
struct JustSuppressCleanupPolicy {
static const bool assertHandled = false;
static const bool suppress = true;
};
} // namespace binding_danger
// A class people should normally use on the stack when they plan to actually
// do something with the exception.
class ErrorResult :
public binding_danger::TErrorResult<binding_danger::AssertAndSuppressCleanupPolicy>
{
typedef binding_danger::TErrorResult<binding_danger::AssertAndSuppressCleanupPolicy> BaseErrorResult;
public:
ErrorResult()
: BaseErrorResult()
{}
ErrorResult(ErrorResult&& aRHS)
: BaseErrorResult(Move(aRHS))
{}
explicit ErrorResult(nsresult aRv)
: BaseErrorResult(aRv)
{}
void operator=(nsresult rv)
{
BaseErrorResult::operator=(rv);
}
ErrorResult& operator=(ErrorResult&& aRHS)
{
BaseErrorResult::operator=(Move(aRHS));
return *this;
}
private:
// Not to be implemented, to make sure people always pass this by
// reference, not by value.
ErrorResult(const ErrorResult&) = delete;
void operator=(const ErrorResult&) = delete;
};
// A class for use when an ErrorResult should just automatically be ignored.
class IgnoredErrorResult : public ErrorResult
template<typename CleanupPolicy>
binding_danger::TErrorResult<CleanupPolicy>::operator ErrorResult&()
{
return *static_cast<ErrorResult*>(
reinterpret_cast<TErrorResult<AssertAndSuppressCleanupPolicy>*>(this));
}
// A class for use when an ErrorResult should just automatically be ignored.
// This doesn't inherit from ErrorResult so we don't make two separate calls to
// SuppressException.
class IgnoredErrorResult :
public binding_danger::TErrorResult<binding_danger::JustSuppressCleanupPolicy>
{
public:
~IgnoredErrorResult()
{
SuppressException();
}
};
/******************************************************************************

Просмотреть файл

@ -127,7 +127,6 @@ class WebIDLCodegenManager(LoggingMixin):
# Global parser derived declaration files.
GLOBAL_DECLARE_FILES = {
'FeatureList.h',
'GeneratedAtomList.h',
'GeneratedEventList.h',
'PrototypeList.h',

Просмотреть файл

@ -1261,10 +1261,7 @@ class IDLInterfaceOrNamespace(IDLObjectWithScope, IDLExposureMixins):
member.getExtendedAttribute("ChromeOnly") or
member.getExtendedAttribute("Pref") or
member.getExtendedAttribute("Func") or
member.getExtendedAttribute("SecureContext") or
member.getExtendedAttribute("AvailableIn") or
member.getExtendedAttribute("CheckAnyPermissions") or
member.getExtendedAttribute("CheckAllPermissions")):
member.getExtendedAttribute("SecureContext")):
raise WebIDLError("[Alias] must not be used on a "
"conditionally exposed operation",
[member.location])
@ -1296,14 +1293,6 @@ class IDLInterfaceOrNamespace(IDLObjectWithScope, IDLExposureMixins):
self.parentScope.primaryGlobalName,
[self.location])
for attribute in ["CheckAnyPermissions", "CheckAllPermissions"]:
if (self.getExtendedAttribute(attribute) and
self._exposureGlobalNames != set([self.parentScope.primaryGlobalName])):
raise WebIDLError("[%s] used on an interface that is "
"not %s-only" %
(attribute, self.parentScope.primaryGlobalName),
[self.location])
# Conditional exposure makes no sense for interfaces with no
# interface object, unless they're navigator properties.
if (self.isExposedConditionally() and
@ -1720,10 +1709,7 @@ class IDLInterface(IDLInterfaceOrNamespace):
identifier == "JSImplementation" or
identifier == "HeaderFile" or
identifier == "NavigatorProperty" or
identifier == "AvailableIn" or
identifier == "Func" or
identifier == "CheckAnyPermissions" or
identifier == "CheckAllPermissions" or
identifier == "Deprecated"):
# Known extended attributes that take a string value
if not attr.hasValue():
@ -3550,14 +3536,6 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
"%s-only" % self._globalScope.primaryGlobalName,
[self.location])
for attribute in ["CheckAnyPermissions", "CheckAllPermissions"]:
if (self.getExtendedAttribute(attribute) and
self.exposureSet != set([self._globalScope.primaryGlobalName])):
raise WebIDLError("[%s] used on an interface member that is "
"not %s-only" %
(attribute, self.parentScope.primaryGlobalName),
[self.location])
if self.isAttr() or self.isMethod():
if self.affects == "Everything" and self.dependsOn != "Everything":
raise WebIDLError("Interface member is flagged as affecting "
@ -3974,10 +3952,7 @@ class IDLConst(IDLInterfaceMember):
elif (identifier == "Pref" or
identifier == "ChromeOnly" or
identifier == "Func" or
identifier == "SecureContext" or
identifier == "AvailableIn" or
identifier == "CheckAnyPermissions" or
identifier == "CheckAllPermissions"):
identifier == "SecureContext"):
# Known attributes that we don't need to do anything with here
pass
else:
@ -4317,11 +4292,8 @@ class IDLAttribute(IDLInterfaceMember):
identifier == "Func" or
identifier == "SecureContext" or
identifier == "Frozen" or
identifier == "AvailableIn" or
identifier == "NewObject" or
identifier == "UnsafeInPrerendering" or
identifier == "CheckAnyPermissions" or
identifier == "CheckAllPermissions" or
identifier == "BinaryName"):
# Known attributes that we don't need to do anything with here
pass
@ -5043,9 +5015,6 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
identifier == "Deprecated" or
identifier == "Func" or
identifier == "SecureContext" or
identifier == "AvailableIn" or
identifier == "CheckAnyPermissions" or
identifier == "CheckAllPermissions" or
identifier == "BinaryName" or
identifier == "StaticClassOverride"):
# Known attributes that we don't need to do anything with here

Просмотреть файл

@ -11,7 +11,7 @@ typedef CustomEventInit TestDictionaryTypedef;
interface TestExternalInterface;
[AvailableIn=PrivilegedApps, Pref="xyz"]
[Pref="xyz"]
interface TestRenamedInterface {
};
@ -135,7 +135,6 @@ interface OnlyForUseInConstructor {
Constructor(ArrayBuffer arrayBuf),
Constructor(Uint8Array typedArr),
// Constructor(long arg1, long arg2, (TestInterface or OnlyForUseInConstructor) arg3),
AvailableIn=CertifiedApps,
NamedConstructor=Test,
NamedConstructor=Test(DOMString str),
NamedConstructor=Test2(DictForConstructor dict, any any1, object obj1,
@ -887,14 +886,6 @@ interface TestInterface {
void prefable19();
[Pref="abc.def", Func="TestFuncControlledMember", ChromeOnly]
void prefable20();
[Func="TestFuncControlledMember", AvailableIn=CertifiedApps]
void prefable21();
[Func="TestFuncControlledMember", AvailableIn=CertifiedApps]
void prefable22();
[Pref="abc.def", Func="TestFuncControlledMember", AvailableIn=CertifiedApps]
void prefable23();
[Pref="abc.def", Func="TestFuncControlledMember", AvailableIn=PrivilegedApps]
void prefable24();
// Conditionally exposed methods/attributes involving [SecureContext]
[SecureContext]

Просмотреть файл

@ -733,14 +733,6 @@ interface TestJSImplInterface {
void prefable19();
[Pref="abc.def", Func="TestFuncControlledMember", ChromeOnly]
void prefable20();
[Func="TestFuncControlledMember", AvailableIn=CertifiedApps]
void prefable21();
[Func="TestFuncControlledMember", AvailableIn=CertifiedApps]
void prefable22();
[Pref="abc.def", Func="TestFuncControlledMember", AvailableIn=CertifiedApps]
void prefable23();
[Pref="abc.def", Func="TestFuncControlledMember", AvailableIn=PrivilegedApps]
void prefable24();
// Conditionally exposed methods/attributes involving [SecureContext]
[SecureContext]

Просмотреть файл

@ -1,13 +1,15 @@
[DEFAULT]
skip-if = buildapp == 'b2g'
support-files =
file_bug707564.html
file_bug707564-2.html
!/dom/bindings/test/file_bug707564.html
!/dom/bindings/test/file_bug775543.html
!/dom/bindings/test/file_document_location_set_via_xray.html
!/dom/bindings/test/file_dom_xrays.html
!/dom/bindings/test/file_proxies_via_xray.html
[test_bug707564-chrome.html]
[test_bug707564.html]
[test_bug775543.html]
[test_document_location_set_via_xray.html]
[test_dom_xrays.html]

Просмотреть файл

@ -6,8 +6,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=707564
<head>
<meta charset="utf-8">
<title>Test for Bug 707564</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
<script type="application/javascript">
/** Test for Bug 707564 **/

Просмотреть файл

@ -1,8 +1,6 @@
[DEFAULT]
support-files =
file_InstanceOf.html
file_bug707564.html
file_bug707564-2.html
file_bug775543.html
file_document_location_set_via_xray.html
file_dom_xrays.html
@ -14,7 +12,6 @@ support-files =
[test_ByteString.html]
[test_InstanceOf.html]
[test_bug560072.html]
[test_bug707564.html]
[test_bug742191.html]
[test_bug759621.html]
[test_bug773326.html]

Просмотреть файл

@ -1,66 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=707564
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 707564</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=707564">Mozilla Bug 707564</a>
<p id="display"></p>
<div id="content" style="display: none">
<iframe id="t1" src="http://example.org/tests/dom/bindings/test/file_bug707564.html"></iframe>
<iframe id="t2"></iframe>
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 775543 **/
function test()
{
var nav = document.getElementById("t1").contentWindow.navigator;
is(nav.foopy, undefined, "We should have an Xray now");
is(nav.wrappedJSObject.foopy, 5, "We should have the right navigator object");
var props = Object.getOwnPropertyNames(Object.getPrototypeOf(nav));
isnot(props.indexOf("mozContacts"), -1,
"Should enumerate a mozContacts property on navigator xray");
var nav = document.getElementById("t2").contentWindow.navigator;
is(nav.foopy, undefined, "We should have an Xray now again");
is(nav.wrappedJSObject.foopy, 5, "We should have the right navigator object again");
var found = false;
for (var name in nav) {
if (name == "mozContacts") {
found = true;
}
}
ok(found, "Should enumerate a mozContacts property on navigator xray via for...in");
SimpleTest.finish();
}
onload = test;
onload = function() {
var iframe1 = document.getElementById("t1");
SpecialPowers.pushPermissions([
{type: "contacts-read", allow: true, context: iframe1.contentDocument},
{type: "contacts-write", allow: true, context: iframe1.contentDocument},
{type: "contacts-create", allow: true, context: iframe1.contentDocument},
], function() {
iframe1.src = "http://example.org/tests/dom/bindings/test/file_bug707564.html";
iframe1.onload = function() {
var iframe2 = document.getElementById("t2");
iframe2.src = "http://example.org/tests/dom/bindings/test/file_bug707564.html";
iframe2.onload = test;
};
});
};
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -1,8 +1,8 @@
<!DOCTYPE HTML>
<html>
<head>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
</head>
<body>
<iframe></iframe>
@ -15,13 +15,8 @@ function run_tests() {
}
SimpleTest.waitForExplicitFinish();
onload = function() {
SpecialPowers.pushPermissions([
{type: "contacts-read", allow: true, context: document},
{type: "contacts-write", allow: true, context: document},
{type: "contacts-create", allow: true, context: document},
], run_tests);
};
addEventListener('load', run_tests);
</script>
</pre>

Просмотреть файл

@ -25,7 +25,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1107592
"Should have the right message in test " + testNumber);
is(exn.code, code, "Should have the right .code in test " + testNumber);
if (message === "") {
is(exn.name, "NS_ERROR_UNEXPECTED",
is(exn.name, "InternalError",
"Should have one of our synthetic exceptions in test " + testNumber);
}
is(exn.stack, stack, "Should have the right stack in test " + testNumber);
@ -41,79 +41,88 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1107592
var isE10S = !SpecialPowers.isMainProcess();
var asyncStack = SpecialPowers.getBoolPref("javascript.options.asyncstack");
var ourFile = location.href;
var parentFrame = (asyncStack && !isE10S) ? `Async*@${ourFile}:121:3
var unwrapError = "Promise rejection value is a non-unwrappable cross-compartment wrapper.";
var parentFrame = (asyncStack && !isE10S) ? `Async*@${ourFile}:130:3
` : "";
Promise.all([
t.testPromiseWithThrowingChromePromiseInit().then(
ensurePromiseFail.bind(null, 1),
checkExn.bind(null, 48, "NS_ERROR_UNEXPECTED", "", undefined,
ourFile, 1,
`doTest@${ourFile}:48:7
checkExn.bind(null, 49, "InternalError", unwrapError,
undefined, ourFile, 1,
`doTest@${ourFile}:49:7
` +
parentFrame)),
t.testPromiseWithThrowingContentPromiseInit(function() {
thereIsNoSuchContentFunction1();
}).then(
ensurePromiseFail.bind(null, 2),
checkExn.bind(null, 56, "ReferenceError",
checkExn.bind(null, 57, "ReferenceError",
"thereIsNoSuchContentFunction1 is not defined",
undefined, ourFile, 2,
`doTest/<@${ourFile}:56:11
doTest@${ourFile}:55:7
`doTest/<@${ourFile}:57:11
doTest@${ourFile}:56:7
` +
parentFrame)),
t.testPromiseWithThrowingChromeThenFunction().then(
ensurePromiseFail.bind(null, 3),
checkExn.bind(null, 0, "NS_ERROR_UNEXPECTED", "", undefined, "", 3, "")),
checkExn.bind(null, 0, "InternalError", unwrapError, undefined, "", 3, asyncStack ? (`Async*doTest@${ourFile}:67:7
` +
parentFrame) : "")),
t.testPromiseWithThrowingContentThenFunction(function() {
thereIsNoSuchContentFunction2();
}).then(
ensurePromiseFail.bind(null, 4),
checkExn.bind(null, 70, "ReferenceError",
checkExn.bind(null, 73, "ReferenceError",
"thereIsNoSuchContentFunction2 is not defined",
undefined, ourFile, 4,
`doTest/<@${ourFile}:70:11
`doTest/<@${ourFile}:73:11
` +
(asyncStack ? `Async*doTest@${ourFile}:69:7
(asyncStack ? `Async*doTest@${ourFile}:72:7
` : "") +
parentFrame)),
t.testPromiseWithThrowingChromeThenable().then(
ensurePromiseFail.bind(null, 5),
checkExn.bind(null, 0, "NS_ERROR_UNEXPECTED", "", undefined, "", 5, "")),
checkExn.bind(null, 0, "InternalError", unwrapError, undefined, "", 5, asyncStack ? (`Async*doTest@${ourFile}:84:7
` +
parentFrame) : "")),
t.testPromiseWithThrowingContentThenable({
then: function() { thereIsNoSuchContentFunction3(); }
}).then(
ensurePromiseFail.bind(null, 6),
checkExn.bind(null, 85, "ReferenceError",
checkExn.bind(null, 90, "ReferenceError",
"thereIsNoSuchContentFunction3 is not defined",
undefined, ourFile, 6,
`doTest/<.then@${ourFile}:85:32
`)),
`doTest/<.then@${ourFile}:90:32
` + (asyncStack ? `Async*doTest@${ourFile}:89:7\n` + parentFrame : ""))),
t.testPromiseWithDOMExceptionThrowingPromiseInit().then(
ensurePromiseFail.bind(null, 7),
checkExn.bind(null, 93, "NotFoundError",
checkExn.bind(null, 98, "NotFoundError",
"We are a second DOMException",
DOMException.NOT_FOUND_ERR, ourFile, 7,
`doTest@${ourFile}:93:7
`doTest@${ourFile}:98:7
` +
parentFrame)),
t.testPromiseWithDOMExceptionThrowingThenFunction().then(
ensurePromiseFail.bind(null, 8),
checkExn.bind(null, asyncStack ? 101 : 0, "NetworkError",
checkExn.bind(null, asyncStack ? 106 : 0, "NetworkError",
"We are a third DOMException",
DOMException.NETWORK_ERR, asyncStack ? ourFile : "", 8,
(asyncStack ? `Async*doTest@${ourFile}:101:7
(asyncStack ? `Async*doTest@${ourFile}:106:7
` +
parentFrame : ""))),
t.testPromiseWithDOMExceptionThrowingThenable().then(
ensurePromiseFail.bind(null, 9),
checkExn.bind(null, 0, "TypeMismatchError",
checkExn.bind(null, asyncStack ? 114 : 0, "TypeMismatchError",
"We are a fourth DOMException",
DOMException.TYPE_MISMATCH_ERR, "", 9, "")),
DOMException.TYPE_MISMATCH_ERR,
asyncStack ? ourFile : "", 9,
(asyncStack ? `Async*doTest@${ourFile}:114:7
` +
parentFrame : ""))),
]).then(SimpleTest.finish,
function() {
ok(false, "One of our catch statements totally failed");
function(err) {
ok(false, "One of our catch statements totally failed with err" + err + ', stack: ' + (err ? err.stack : ''));
SimpleTest.finish();
});
}

Просмотреть файл

@ -109,6 +109,7 @@ const browserElementTestHelpers = {
// Some basically-empty pages from different domains you can load.
'emptyPage1': 'http://example.com' + _getPath() + '/file_empty.html',
'fileEmptyPage1': 'file_empty.html',
'emptyPage2': 'http://example.org' + _getPath() + '/file_empty.html',
'emptyPage3': 'http://test1.example.org' + _getPath() + '/file_empty.html',
'focusPage': 'http://example.org' + _getPath() + '/file_focus.html',

Просмотреть файл

@ -2,9 +2,8 @@
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
var fileURL = 'http://example.org/tests/dom/browser-element/mochitest/file_browserElement_ActiveStateChange.html';
var fileURL = 'chrome://mochitests/content/chrome/dom/browser-element/mochitest/file_browserElement_ActiveStateChange.html';
var generator = runTests();
var testFrame;
var ac;
@ -78,7 +77,7 @@ function setupTestFrame() {
testFrame.removeEventListener('mozbrowserloadend', loadend);
ok("allowedAudioChannels" in testFrame, "allowedAudioChannels exist");
var channels = testFrame.allowedAudioChannels;
is(channels.length, 1, "1 audio channel by default");
is(channels.length, 9, "9 audio channel by default");
ac = channels[0];

Просмотреть файл

@ -7,13 +7,12 @@
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
function noaudio() {
info("Test : no-audio");
var iframe = document.createElement('iframe');
iframe.setAttribute('mozbrowser', 'true');
iframe.src = 'http://example.org/tests/dom/browser-element/mochitest/file_empty.html';
iframe.src = 'chrome://mochitests/content/chrome/dom/browser-element/mochitest/file_empty.html';
function noaudio_loadend() {
ok("mute" in iframe, "iframe.mute exists");
@ -24,7 +23,7 @@ function noaudio() {
ok("allowedAudioChannels" in iframe, "allowedAudioChannels exist");
var channels = iframe.allowedAudioChannels;
is(channels.length, 1, "1 audio channel by default");
is(channels.length, 9, "9 audio channel by default");
var ac = channels[0];
@ -146,7 +145,7 @@ function audio() {
info("Test : audio");
var iframe = document.createElement('iframe');
iframe.setAttribute('mozbrowser', 'true');
iframe.src = 'http://example.org/tests/dom/browser-element/mochitest/iframe_file_audio.html';
iframe.src = 'chrome://mochitests/content/chrome/dom/browser-element/mochitest/iframe_file_audio.html';
function audio_loadend() {
ok("mute" in iframe, "iframe.mute exists");
@ -157,7 +156,7 @@ function audio() {
ok("allowedAudioChannels" in iframe, "allowedAudioChannels exist");
var channels = iframe.allowedAudioChannels;
is(channels.length, 1, "1 audio channel by default");
is(channels.length, 9, "9 audio channel by default");
var ac = channels[0];

Просмотреть файл

@ -2,9 +2,8 @@
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
var fileURL = 'http://example.org/tests/dom/browser-element/mochitest/file_browserElement_AudioChannelMutedByDefault.html';
var fileURL = 'chrome://mochitests/content/chrome/dom/browser-element/mochitest/file_browserElement_AudioChannelMutedByDefault.html';
var testFrame;
var ac;
@ -78,7 +77,7 @@ function setupTestFrame() {
testFrame.removeEventListener('mozbrowserloadend', loadend);
ok("allowedAudioChannels" in testFrame, "allowedAudioChannels exist");
var channels = testFrame.allowedAudioChannels;
is(channels.length, 1, "1 audio channel by default");
is(channels.length, 9, "9 audio channel by default");
ac = channels[0];
ok(ac instanceof BrowserElementAudioChannel, "Correct class");

Просмотреть файл

@ -2,9 +2,8 @@
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
var fileURL = 'http://example.org/tests/dom/browser-element/mochitest/file_browserElement_AudioChannelSeeking.html';
var fileURL = 'chrome://mochitests/content/chrome/dom/browser-element/mochitest/file_browserElement_AudioChannelSeeking.html';
var generator = runTests();
var testFrame;
var ac;
@ -104,7 +103,7 @@ function setupTestFrame() {
testFrame.removeEventListener('mozbrowserloadend', loadend);
ok("allowedAudioChannels" in testFrame, "allowedAudioChannels exist");
var channels = testFrame.allowedAudioChannels;
is(channels.length, 1, "1 audio channel by default");
is(channels.length, 9, "9 audio channel by default");
ac = channels[0];
ok(ac instanceof BrowserElementAudioChannel, "Correct class");

Просмотреть файл

@ -7,7 +7,6 @@
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
function runTests() {
var iframe = document.createElement('iframe');
@ -22,6 +21,7 @@ function runTests() {
} else if (/DONE/.exec(message)) {
ok(true, "Messaging from app complete");
iframe.removeEventListener('mozbrowsershowmodalprompt', listener);
SimpleTest.finish();
}
}
@ -34,7 +34,7 @@ function runTests() {
ok("allowedAudioChannels" in iframe, "allowedAudioChannels exist");
var channels = iframe.allowedAudioChannels;
is(channels.length, 1, "1 audio channel by default");
is(channels.length, 9, "9 audio channel by default");
var ac = channels[0];
@ -51,7 +51,6 @@ function runTests() {
ac.onactivestatechanged = function() {
ok(true, "activestatechanged event received.");
ac.onactivestatechanged = null;
SimpleTest.finish();
}
}
@ -59,15 +58,7 @@ function runTests() {
iframe.addEventListener('mozbrowsershowmodalprompt', listener, false);
document.body.appendChild(iframe);
var context = { 'url': 'http://example.org',
'appId': SpecialPowers.Ci.nsIScriptSecurityManager.NO_APP_ID,
'isInIsolatedMozBrowserElement': true };
SpecialPowers.pushPermissions([
{'type': 'browser', 'allow': 1, 'context': context},
{'type': 'embed-apps', 'allow': 1, 'context': context}
], function() {
iframe.src = 'http://example.org/tests/dom/browser-element/mochitest/file_browserElement_AudioChannel_nested.html';
});
iframe.src = 'chrome://mochitests/content/chrome/dom/browser-element/mochitest/file_browserElement_AudioChannel_nested.html';
}
addEventListener('testready', function() {

Просмотреть файл

@ -8,7 +8,6 @@ const { Services } = SpecialPowers.Cu.import('resource://gre/modules/Services.js
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
/**
* Content script passed to the child iframe
@ -65,7 +64,7 @@ function runTest() {
});
// Load a simple page to get the process started.
iframe.src = browserElementTestHelpers.emptyPage1;
iframe.src = browserElementTestHelpers.fileEmptyPage1;
}
addEventListener('testready', function() {

Просмотреть файл

@ -7,7 +7,6 @@
"use strict";
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
var iframe;
function addOneShotIframeEventListener(event, fn) {

Просмотреть файл

@ -7,7 +7,6 @@
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
var iframe;
var numPendingTests = 0;

Просмотреть файл

@ -7,7 +7,6 @@
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
function runTest() {
var iframe1 = document.createElement('iframe');

Просмотреть файл

@ -6,7 +6,6 @@
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
var iframe;

Просмотреть файл

@ -7,7 +7,6 @@
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
function runTest() {

Просмотреть файл

@ -6,7 +6,6 @@
"use strict";
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
var resizeContent = function() {
var innerBox = content.document.getElementById('abox');

Просмотреть файл

@ -6,7 +6,6 @@
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
function runTest() {
var iframe1 = document.createElement('iframe');

Просмотреть файл

@ -6,7 +6,6 @@
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
function runTest() {
var dppxPref = 'layout.css.devPixelsPerPx';

Просмотреть файл

@ -6,7 +6,6 @@
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
function runTest() {
var iframe = document.createElement('iframe');

Просмотреть файл

@ -2,9 +2,8 @@
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
var fileURL = 'http://example.org/tests/dom/browser-element/mochitest/file_browserElement_NoAudioTrack.html';
var fileURL = 'chrome://mochitests/content/chrome/dom/browser-element/mochitest/file_browserElement_NoAudioTrack.html';
var generator = runTests();
var testFrame;
@ -67,7 +66,7 @@ function setupTestFrame() {
testFrame.removeEventListener('mozbrowserloadend', loadend);
ok("allowedAudioChannels" in testFrame, "allowedAudioChannels exist");
var channels = testFrame.allowedAudioChannels;
is(channels.length, 1, "1 audio channel by default");
is(channels.length, 9, "9 audio channel by default");
var ac = channels[0];
ok(ac instanceof BrowserElementAudioChannel, "Correct class");

Просмотреть файл

@ -20,7 +20,6 @@
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
function runTest() {
// We're going to open a remote frame if OOP off by default. If OOP is on by

Просмотреть файл

@ -7,7 +7,6 @@
"use strict";
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
var iframe;
function addOneShotIframeEventListener(event, fn) {
@ -22,6 +21,8 @@ function addOneShotIframeEventListener(event, fn) {
function runTest() {
iframe = document.createElement('iframe');
iframe.setAttribute('mozbrowser', 'true');
// FIXME: Bug 1270790
iframe.setAttribute('remote', 'true');
addOneShotIframeEventListener('mozbrowserloadend', function() {
SimpleTest.executeSoon(test2);

Просмотреть файл

@ -8,7 +8,6 @@
SimpleTest.waitForExplicitFinish();
SimpleTest.requestFlakyTimeout("untriaged");
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
var iframe;
var gotConfirmRepost = false;

Просмотреть файл

@ -6,7 +6,6 @@
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
function runTest() {
var iframe = document.createElement("iframe");
@ -79,21 +78,7 @@ function runTest() {
}
});
iframe.src = "data:text/html,<html><body>" +
"<button>send[Mouse|Touch]Event</button>" +
"</body><script>" +
"function changeHash(e) {" +
" document.location.hash = e.type;" +
"};" +
"window.addEventListener('mousedown', changeHash);" +
"window.addEventListener('mousemove', changeHash);" +
"window.addEventListener('mouseup', changeHash);" +
"window.addEventListener('click', changeHash, true);" +
"window.addEventListener('touchstart', changeHash);" +
"window.addEventListener('touchmove', changeHash);" +
"window.addEventListener('touchend', changeHash);" +
"window.addEventListener('touchcancel', changeHash);" +
"</script></html>";
iframe.src = "file_browserElement_SendEvent.html";
}

Просмотреть файл

@ -7,7 +7,6 @@
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
// We'll need to get the appId from the current document,
// it's either SpecialPowers.Ci.nsIScriptSecurityManager.NO_APP_ID when
@ -67,21 +66,19 @@ function createFrames() {
// Create an input field to receive string from input method iframes.
gInputFrame = document.createElement('iframe');
gInputFrame.setAttribute('mozbrowser', 'true');
gInputFrame.src =
'data:text/html,<input autofocus value="hello" />' +
'<p>This is targetted mozbrowser frame.</p>';
gInputFrame.src = 'file_browserElement_SetInputMethodActive.html';
document.body.appendChild(gInputFrame);
gInputFrame.addEventListener('mozbrowserloadend', countLoadend);
for (let i = 0; i < 2; i++) {
let frame = gInputMethodFrames[i] = document.createElement('iframe');
frame.setAttribute('mozbrowser', 'true');
if (currentAppManifestURL) {
frame.setAttribute('mozapp', currentAppManifestURL);
}
frame.src = 'file_empty.html#' + i;
document.body.appendChild(frame);
let frame = gInputMethodFrames[i] = document.createElement('iframe');
frame.setAttribute('mozbrowser', 'true');
if (currentAppManifestURL) {
frame.setAttribute('mozapp', currentAppManifestURL);
}
frame.addEventListener('mozbrowserloadend', countLoadend);
frame.src = 'file_empty.html#' + i;
document.body.appendChild(frame);
}
}

Просмотреть файл

@ -6,7 +6,6 @@
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
function hasSetNFCFocus() {
return new Promise((resolve, reject) => {
@ -22,9 +21,7 @@ function hasSetNFCFocus() {
}
function runTest() {
SpecialPowers.pushPermissions(
[{ 'type': 'nfc-manager', 'allow': 1, 'context': document }],
() => hasSetNFCFocus().then(SimpleTest.finish));
hasSetNFCFocus().then(SimpleTest.finish);
}
addEventListener('testready', runTest);

Просмотреть файл

@ -7,7 +7,6 @@
SimpleTest.waitForExplicitFinish();
SimpleTest.requestFlakyTimeout("untriaged");
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
var iframeScript = function() {
content.document.addEventListener("visibilitychange", function() {

Просмотреть файл

@ -12,18 +12,10 @@
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
var iframe;
function runTest() {
var principal = SpecialPowers.wrap(document).nodePrincipal;
SpecialPowers.addPermission("browser", true, {url: SpecialPowers.wrap(principal.URI).spec,
originAttributes: {
appId: principal.appId,
inIsolatedMozBrowser: true
}});
iframe = document.createElement('iframe');
iframe.setAttribute('mozbrowser', 'true');
@ -75,13 +67,6 @@ function finish() {
// expected, but if we don't remove our listener, then we'll end up causing
// the /next/ test to fail!
iframe.removeEventListener('mozbrowsershowmodalprompt', checkMessage);
var principal = SpecialPowers.wrap(document).nodePrincipal;
SpecialPowers.removePermission("browser", {url: SpecialPowers.wrap(principal.URI).spec,
originAttributes: {
appId: principal.appId,
inIsolatedMozBrowser: true
}});
SimpleTest.finish();
}

Просмотреть файл

@ -8,16 +8,8 @@
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
function runTest() {
var principal = SpecialPowers.wrap(document).nodePrincipal;
SpecialPowers.addPermission("browser", true, {url: SpecialPowers.wrap(principal.URI).spec,
originAttributes: {
appId: principal.appId,
inIsolatedMozBrowser: true
}});
var iframe = document.createElement('iframe');
iframe.setAttribute('mozbrowser', 'true');
@ -57,13 +49,6 @@ function runTest() {
}
function finish() {
var principal = SpecialPowers.wrap(document).nodePrincipal;
SpecialPowers.removePermission("browser", {url: SpecialPowers.wrap(principal.URI).spec,
originAttributes: {
appId: principal.appId,
inIsolatedMozBrowser: true
}});
SimpleTest.finish();
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше