зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to fx-team
This commit is contained in:
Коммит
c735a88756
2
CLOBBER
2
CLOBBER
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче