merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2016-10-17 11:19:02 +02:00
commit d6850a3a86
707 changed files with 14776 additions and 5809 deletions

View File

@ -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 1261019 - Clobber on OS X to fix bustage caused by removed files
Bug 1306438 and bug 1304815 - Rust update and related changes require clobber

View File

@ -480,8 +480,6 @@ EXTRA_JS_MODULES.commonjs.sdk.system += [
EXTRA_JS_MODULES.commonjs.sdk.system.child_process += [
'source/lib/sdk/system/child_process/subprocess.js',
'source/lib/sdk/system/child_process/subprocess_worker_unix.js',
'source/lib/sdk/system/child_process/subprocess_worker_win.js',
]
EXTRA_JS_MODULES.commonjs.sdk.tab += [

View File

@ -298,8 +298,11 @@ function loadSandbox(uri) {
}
function unloadSandbox(sandbox) {
if ("nukeSandbox" in Cu)
Cu.nukeSandbox(sandbox);
if ("nukeSandbox" in Cu) {
try {
Cu.nukeSandbox(sandbox);
} catch (e) {}
}
}
function setTimeout(callback, delay) {
@ -346,6 +349,7 @@ function nukeModules() {
// Bug 775067: From FF17 we can kill all CCW from a given sandbox
unloadSandbox(sandbox);
}
unloadSandbox(loader.sharedGlobalSandbox);
loader = null;
// both `toolkit/loader` and `system/xul-app` are loaded as JSM's via

View File

@ -157,11 +157,21 @@ Bootstrap.prototype = {
setTimeout(() => {
for (let uri of Object.keys(loader.sandboxes)) {
Cu.nukeSandbox(loader.sandboxes[uri]);
try {
Cu.nukeSandbox(loader.sandboxes[uri]);
} catch (e) {
// This will throw for shared sandboxes.
}
delete loader.sandboxes[uri];
delete loader.modules[uri];
}
try {
Cu.nukeSandbox(loader.sharedGlobalSandbox);
} catch (e) {
Cu.reportError(e);
}
resolve();
}, 1000);
}

View File

@ -61,7 +61,10 @@ var Child = Class({
stream.write(data);
}
},
done: function (result) {
done: function (result, error) {
if (error)
return handleError(error);
// Only emit if child is not killed; otherwise,
// the `kill` method will handle this
if (!child.killed) {
@ -170,7 +173,7 @@ function exec (cmd, ...args) {
if (isWindows) {
file = 'C:\\Windows\\System32\\cmd.exe';
cmdArgs = ['/s', '/c', (cmd || '').split(' ')];
cmdArgs = ['/S/C', cmd || ''];
}
else {
file = '/bin/sh';

View File

@ -1,36 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is subprocess.jsm.
-
- The Initial Developer of this code is Jan Gerber.
- Portions created by Jan Gerber <j@mailb.org>
- are Copyright (C) 2011 Jan Gerber.
- All Rights Reserved.
-
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- either the GNU General Public License Version 2 or later (the "GPL"), or
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- in which case the provisions of the GPL or the LGPL are applicable instead
- of those above. If you wish to allow use of your version of this file only
- under the terms of either the GPL or the LGPL, and not to allow others to
- use your version of this file under the terms of the MPL, indicate your
- decision by deleting the provisions above and replace them with the notice
- and other provisions required by the LGPL or the GPL. If you do not delete
- the provisions above, a recipient may use your version of this file under
- the terms of any one of the MPL, the GPL or the LGPL.
-
- ***** END LICENSE BLOCK ***** -->

View File

@ -1,129 +0,0 @@
# subprocess
Created by [Jan Gerber](j@mailb.org), with contributions from [Patrick Brunschwig](patrick@enigmail.net), subprocess.jsm is used as the underlying library, supporting the Addon-SDK's implementation of Node's `child-process` API.
`subprocess.jsm` is originally from [http://hg.mozilla.org/ipccode/](http://hg.mozilla.org/ipccode/).
How to Use subprocess.jsm in your Add-on
----------------------------------------
1. copy subprocess.jsm and subprocess_worker_*.js into the modules/ directory
of your add-on.
2. add this line to chrome.manifest:
resource EXTENSION modules/
3. import it where needed:
Components.utils.import("resource://EXTENSION/subprocess.jsm");
This object allows to start a process, and read/write data to/from it
using stdin/stdout/stderr streams.
Usage example:
var p = subprocess.call({
command: '/bin/foo',
arguments: ['-v', 'foo'],
environment: [ "XYZ=abc", "MYVAR=def" ],
charset: 'UTF-8',
workdir: '/home/foo',
//stdin: "some value to write to stdin\nfoobar",
stdin: function(stdin) {
stdin.write("some value to write to stdin\nfoobar");
stdin.close();
},
stdout: function(data) {
dump("got data on stdout:" + data + "\n");
},
stderr: function(data) {
dump("got data on stderr:" + data + "\n");
},
done: function(result) {
dump("process terminated with " + result.exitCode + "\n");
},
mergeStderr: false
});
p.wait(); // wait for the subprocess to terminate,
// this will block the main thread,
// only do if you can wait that long
Description of subprocess.call(...) Parameters
----------------------------------------------
Apart from <command>, all arguments are optional.
command: either a |nsIFile| object pointing to an executable file or a
String containing the platform-dependent path to an executable
file.
arguments: optional string array containing the arguments to the command.
environment: optional string array containing environment variables to pass
to the command. The array elements must have the form
"VAR=data". Please note that if environment is defined, it
replaces any existing environment variables for the subprocess.
charset: Output is decoded with given charset and a string is returned.
If charset is undefined, "UTF-8" is used as default.
To get binary data, set this to null and the returned string
is not decoded in any way.
workdir: Optional; either a |nsIFile| object or string containing the
platform-dependent path to a directory to become the current
working directory of the subprocess.
stdin: Optional input data for the process to be passed on standard
input. stdin can either be a string or a function.
A |string| gets written to stdin and stdin gets closed;
A |function| gets passed an object with write and close function.
Please note that the write() function will return almost immediately;
data is always written asynchronously on a separate thread.
stdout: An optional function that can receive output data from the
process. The stdout-function is called asynchronously; it can be
called mutliple times during the execution of a process.
At a minimum at each occurance of \n or \r.
Please note that null-characters might need to be escaped
with something like 'data.replace(/\0/g, "\\0");'.
stderr: An optional function that can receive stderr data from the
process. The stderr-function is called asynchronously; it can be
called mutliple times during the execution of a process. Please
note that null-characters might need to be escaped with
something like 'data.replace(/\0/g, "\\0");'.
(on windows it only gets called once right now)
done: Optional function that is called when the process has terminated.
The exit code from the process available via result.exitCode. If
stdout is not defined, then the output from stdout is available
via result.stdout. stderr data is in result.stderr
mergeStderr: Optional boolean value. If true, stderr is merged with stdout;
no data will be provided to stderr.
Description of object returned by subprocess.call(...)
------------------------------------------------------
The object returned by subprocess.call offers a few methods that can be
executed:
wait(): waits for the subprocess to terminate. It is not required to use
wait; done will be called in any case when the subprocess terminated.
kill(): kill the subprocess. Any open pipes will be closed and
done will be called.
Other methods exported by subprocess
------------------------------------
The following functions help debugging and provide logging facilities.
registerDebugHandler(functionRef): register a handler that is called to get
debugging information
registerLogHandler(functionRef): register a handler that is called to get error
messages
example:
subprocess.registerLogHandler( function(s) { dump(s); } );

File diff suppressed because it is too large Load Diff

View File

@ -1,278 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "MPL"); you may not use this file
* except in compliance with the MPL. You may obtain a copy of
* the MPL at http://www.mozilla.org/MPL/
*
* Software distributed under the MPL is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the MPL for the specific language governing
* rights and limitations under the MPL.
*
* The Original Code is subprocess.jsm.
*
* The Initial Developer of this code is Patrick Brunschwig.
* Portions created by Patrick Brunschwig <patrick@enigmail.net>
* are Copyright (C) 2011 Patrick Brunschwig.
* All Rights Reserved.
*
* Contributor(s):
* Jan Gerber <j@mailb.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
* ***** END LICENSE BLOCK ***** */
/*
* ChromeWorker Object subprocess.jsm on Unix-like systems (Linux, Mac OS X, ...)
* to process stdin/stdout/stderr on separate threads.
*
*/
// Being a ChromeWorker object, implicitly uses the following:
// Cu.import("resource://gre/modules/ctypes.jsm");
'use strict';
const BufferSize = 1024;
var libc = null;
var libcFunc = {};
/*
struct pollfd {
int fd; // file descriptor
short events; // events to look for
short revents; // events returned
};
*/
var pollfd = new ctypes.StructType("pollfd",
[ {'fd': ctypes.int},
{'events': ctypes.short},
{'revents': ctypes.short}
]);
var WriteBuffer = ctypes.uint8_t.array(BufferSize);
var ReadBuffer = ctypes.char.array(BufferSize);
const POLLIN = 0x0001;
const POLLOUT = 0x0004;
const POLLERR = 0x0008; // some poll error occurred
const POLLHUP = 0x0010; // file descriptor was "hung up"
const POLLNVAL = 0x0020; // requested events "invalid"
const WNOHANG = 0x01;
const pid_t = ctypes.int32_t;
const INDEFINITE = -1;
const NOWAIT = 0;
const WAITTIME = 200 // wait time for poll() in ms
function initLibc(libName) {
postMessage({msg: "debug", data: "initialising library with "+ libName});
libc = ctypes.open(libName);
libcFunc.pollFds = pollfd.array(1);
// int poll(struct pollfd fds[], nfds_t nfds, int timeout);
libcFunc.poll = libc.declare("poll",
ctypes.default_abi,
ctypes.int,
libcFunc.pollFds,
ctypes.unsigned_int,
ctypes.int);
//ssize_t write(int fd, const void *buf, size_t count);
// NOTE: buf is declared as array of unsigned int8 instead of char to avoid
// implicit charset conversion
libcFunc.write = libc.declare("write",
ctypes.default_abi,
ctypes.int,
ctypes.int,
WriteBuffer,
ctypes.int);
//int read(int fd, void *buf, size_t count);
libcFunc.read = libc.declare("read",
ctypes.default_abi,
ctypes.int,
ctypes.int,
ReadBuffer,
ctypes.int);
//int pipe(int pipefd[2]);
libcFunc.pipefd = ctypes.int.array(2);
//int close(int fd);
libcFunc.close = libc.declare("close",
ctypes.default_abi,
ctypes.int,
ctypes.int);
//pid_t waitpid(pid_t pid, int *status, int options);
libcFunc.waitpid = libc.declare("waitpid",
ctypes.default_abi,
pid_t,
pid_t,
ctypes.int.ptr,
ctypes.int);
}
function closePipe(pipe) {
libcFunc.close(pipe);
}
function writePipe(pipe, data) {
postMessage({msg: "debug", data: "trying to write to "+pipe});
let numChunks = Math.floor(data.length / BufferSize);
let pData = new WriteBuffer();
for (var chunk = 0; chunk <= numChunks; chunk ++) {
let numBytes = chunk < numChunks ? BufferSize : data.length - chunk * BufferSize;
for (var i=0; i < numBytes; i++) {
pData[i] = data.charCodeAt(chunk * BufferSize + i) % 256;
}
let bytesWritten = libcFunc.write(pipe, pData, numBytes);
if (bytesWritten != numBytes) {
closePipe(pipe);
postMessage({ msg: "error", data: "error: wrote "+bytesWritten+" instead of "+numBytes+" bytes"});
close();
}
}
postMessage({msg: "info", data: "wrote "+data.length+" bytes of data"});
}
function readString(data, length, charset) {
var string = '', bytes = [];
for(var i = 0;i < length; i++) {
if(data[i] == 0 && charset != "null") // stop on NULL character for non-binary data
break;
bytes.push(data[i]);
}
return bytes;
}
function readPipe(pipe, charset, pid) {
var p = new libcFunc.pollFds;
p[0].fd = pipe;
p[0].events = POLLIN | POLLERR | POLLHUP;
p[0].revents = 0;
var pollTimeout = WAITTIME;
var exitCode = -1;
var readCount = 0;
var result, status = ctypes.int();
result = 0;
const i=0;
while (true) {
if (result == 0) {
result = libcFunc.waitpid(pid, status.address(), WNOHANG);
if (result > 0) {
pollTimeout = NOWAIT;
exitCode = parseInt(status.value);
postMessage({msg: "debug", data: "waitpid signaled subprocess stop, exitcode="+status.value });
}
}
var r = libcFunc.poll(p, 1, pollTimeout);
if (r > 0) {
if (p[i].revents & POLLIN) {
postMessage({msg: "debug", data: "reading next chunk"});
readCount = readPolledFd(p[i].fd, charset);
if (readCount == 0) break;
}
if (p[i].revents & POLLHUP) {
postMessage({msg: "debug", data: "poll returned HUP"});
break;
}
else if (p[i].revents & POLLERR) {
postMessage({msg: "error", data: "poll returned error"});
break;
}
else if (p[i].revents != POLLIN) {
postMessage({msg: "error", data: "poll returned "+p[i]});
break;
}
}
else
if (pollTimeout == 0 || r < 0) break;
}
// continue reading until the buffer is empty
while (readCount > 0) {
readCount = readPolledFd(pipe, charset);
}
libcFunc.close(pipe);
postMessage({msg: "done", data: exitCode });
libc.close();
close();
}
function readPolledFd(pipe, charset) {
var line = new ReadBuffer();
var r = libcFunc.read(pipe, line, BufferSize);
if (r > 0) {
var c = readString(line, r, charset);
postMessage({msg: "data", data: c, count: c.length});
}
return r;
}
onmessage = function (event) {
switch (event.data.msg) {
case "init":
initLibc(event.data.libc);
break;
case "read":
initLibc(event.data.libc);
readPipe(event.data.pipe, event.data.charset, event.data.pid);
break;
case "write":
// data contents:
// msg: 'write'
// data: the data (string) to write
// pipe: ptr to pipe
writePipe(event.data.pipe, event.data.data);
postMessage({msg: "info", data: "WriteOK"});
break;
case "close":
postMessage({msg: "debug", data: "closing stdin\n"});
closePipe(event.data.pipe);
postMessage({msg: "info", data: "ClosedOK"});
break;
case "stop":
libc.close(); // do not use libc after this point
close();
break;
default:
throw("error: Unknown command"+event.data.msg+"\n");
}
return;
};

View File

@ -1,237 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "MPL"); you may not use this file
* except in compliance with the MPL. You may obtain a copy of
* the MPL at http://www.mozilla.org/MPL/
*
* Software distributed under the MPL is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the MPL for the specific language governing
* rights and limitations under the MPL.
*
* The Original Code is subprocess.jsm.
*
* The Initial Developer of this code is Patrick Brunschwig.
* Portions created by Patrick Brunschwig <patrick@enigmail.net>
* are Copyright (C) 2011 Patrick Brunschwig.
* All Rights Reserved.
*
* Contributor(s):
* Jan Gerber <j@mailb.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
* ***** END LICENSE BLOCK ***** */
/*
* ChromeWorker Object subprocess.jsm on Windows to process stdin/stdout/stderr
* on separate threads.
*
*/
// Being a ChromeWorker object, implicitly uses the following:
// Cu.import("resource://gre/modules/ctypes.jsm");
'use strict';
const BufferSize = 1024;
const BOOL = ctypes.bool;
const HANDLE = ctypes.size_t;
const DWORD = ctypes.uint32_t;
const LPDWORD = DWORD.ptr;
const PVOID = ctypes.voidptr_t;
const LPVOID = PVOID;
/*
typedef struct _OVERLAPPED {
ULONG_PTR Internal;
ULONG_PTR InternalHigh;
union {
struct {
DWORD Offset;
DWORD OffsetHigh;
};
PVOID Pointer;
};
HANDLE hEvent;
} OVERLAPPED, *LPOVERLAPPED;
*/
const OVERLAPPED = new ctypes.StructType("OVERLAPPED");
var ReadFileBuffer = ctypes.char.array(BufferSize);
var WriteFileBuffer = ctypes.uint8_t.array(BufferSize);
var kernel32dll = null;
var libFunc = {};
function initLib(libName) {
if (ctypes.size_t.size == 8) {
var WinABI = ctypes.default_abi;
} else {
var WinABI = ctypes.winapi_abi;
}
kernel32dll = ctypes.open(libName);
/*
BOOL WINAPI WriteFile(
__in HANDLE hFile,
__in LPCVOID lpBuffer,
__in DWORD nNumberOfBytesToWrite,
__out_opt LPDWORD lpNumberOfBytesWritten,
__inout_opt LPOVERLAPPED lpOverlapped
);
NOTE: lpBuffer is declared as array of unsigned int8 instead of char to avoid
implicit charset conversion
*/
libFunc.WriteFile = kernel32dll.declare("WriteFile",
WinABI,
BOOL,
HANDLE,
WriteFileBuffer,
DWORD,
LPDWORD,
OVERLAPPED.ptr
);
/*
BOOL WINAPI ReadFile(
__in HANDLE hFile,
__out LPVOID ReadFileBuffer,
__in DWORD nNumberOfBytesToRead,
__out_opt LPDWORD lpNumberOfBytesRead,
__inout_opt LPOVERLAPPED lpOverlapped
);
*/
libFunc.ReadFile = kernel32dll.declare("ReadFile",
WinABI,
BOOL,
HANDLE,
ReadFileBuffer,
DWORD,
LPDWORD,
OVERLAPPED.ptr
);
/*
BOOL WINAPI CloseHandle(
__in HANDLE hObject
);
*/
libFunc.CloseHandle = kernel32dll.declare("CloseHandle",
WinABI,
BOOL,
HANDLE
);
}
function writePipe(pipe, data) {
var bytesWritten = DWORD(0);
var pData = new WriteFileBuffer();
var numChunks = Math.floor(data.length / BufferSize);
for (var chunk = 0; chunk <= numChunks; chunk ++) {
var numBytes = chunk < numChunks ? BufferSize : data.length - chunk * BufferSize;
for (var i=0; i < numBytes; i++) {
pData[i] = data.charCodeAt(chunk * BufferSize + i) % 256;
}
var r = libFunc.WriteFile(pipe, pData, numBytes, bytesWritten.address(), null);
if (bytesWritten.value != numBytes)
throw("error: wrote "+bytesWritten.value+" instead of "+numBytes+" bytes");
}
postMessage("wrote "+data.length+" bytes of data");
}
function readString(data, length, charset) {
var string = '', bytes = [];
for(var i = 0;i < length; i++) {
if(data[i] == 0 && charset != "null") // stop on NULL character for non-binary data
break;
bytes.push(data[i]);
}
return bytes;
}
function readPipe(pipe, charset) {
while (true) {
var bytesRead = DWORD(0);
var line = new ReadFileBuffer();
var r = libFunc.ReadFile(pipe, line, BufferSize, bytesRead.address(), null);
if (!r) {
// stop if we get an error (such as EOF reached)
postMessage({msg: "info", data: "ReadFile failed"});
break;
}
if (bytesRead.value > 0) {
var c = readString(line, bytesRead.value, charset);
postMessage({msg: "data", data: c, count: c.length});
}
else {
break;
}
}
libFunc.CloseHandle(pipe);
postMessage({msg: "done"});
kernel32dll.close();
close();
}
onmessage = function (event) {
let pipePtr;
switch (event.data.msg) {
case "init":
initLib(event.data.libc);
break;
case "write":
// data contents:
// msg: 'write'
// data: the data (string) to write
// pipe: ptr to pipe
pipePtr = HANDLE.ptr(event.data.pipe);
writePipe(pipePtr.contents, event.data.data);
postMessage("WriteOK");
break;
case "read":
initLib(event.data.libc);
pipePtr = HANDLE.ptr(event.data.pipe);
readPipe(pipePtr.contents, event.data.charset);
break;
case "close":
pipePtr = HANDLE.ptr(event.data.pipe);
postMessage("closing stdin\n");
if (libFunc.CloseHandle(pipePtr.contents)) {
postMessage("ClosedOK");
}
else
postMessage("Could not close stdin handle");
break;
case "stop":
kernel32dll.close();
close();
break;
default:
throw("error: Unknown command"+event.data.msg+"\n");
}
return;
};

View File

@ -35,5 +35,12 @@ Object.defineProperty(exports, 'define', {
factory = Array.slice(arguments).pop();
factory.call(sandbox, sandbox.require, sandbox.exports, sandbox.module);
}
}
},
set: function(value) {
Object.defineProperty(this, 'define', {
configurable: true,
enumerable: true,
value,
});
},
});

View File

@ -36,21 +36,55 @@ const { join: pathJoin, normalize, dirname } = Cu.import("resource://gre/modules
XPCOMUtils.defineLazyGetter(this, "XulApp", () => {
let xulappURI = module.uri.replace("toolkit/loader.js",
"sdk/system/xul-app.jsm");
"sdk/system/xul-app.jsm");
return Cu.import(xulappURI, {});
});
// Define some shortcuts.
const bind = Function.call.bind(Function.bind);
const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
const define = Object.defineProperties;
const prototypeOf = Object.getPrototypeOf;
const create = Object.create;
const keys = Object.keys;
const getOwnIdentifiers = x => [...Object.getOwnPropertyNames(x),
...Object.getOwnPropertySymbols(x)];
const NODE_MODULES = ["assert", "buffer_ieee754", "buffer", "child_process", "cluster", "console", "constants", "crypto", "_debugger", "dgram", "dns", "domain", "events", "freelist", "fs", "http", "https", "_linklist", "module", "net", "os", "path", "punycode", "querystring", "readline", "repl", "stream", "string_decoder", "sys", "timers", "tls", "tty", "url", "util", "vm", "zlib"];
const NODE_MODULES = new Set([
"assert",
"buffer_ieee754",
"buffer",
"child_process",
"cluster",
"console",
"constants",
"crypto",
"_debugger",
"dgram",
"dns",
"domain",
"events",
"freelist",
"fs",
"http",
"https",
"_linklist",
"module",
"net",
"os",
"path",
"punycode",
"querystring",
"readline",
"repl",
"stream",
"string_decoder",
"sys",
"timers",
"tls",
"tty",
"url",
"util",
"vm",
"zlib",
]);
const COMPONENT_ERROR = '`Components` is not available in this context.\n' +
'Functionality provided by Components may be available in an SDK\n' +
@ -122,7 +156,7 @@ const override = iced(function override(target, source) {
getOwnIdentifiers(extension).forEach(function(name) {
properties[name] = extension[name];
});
return define({}, properties);
return Object.defineProperties({}, properties);
});
Loader.override = override;
@ -193,7 +227,7 @@ function readURI(uri) {
}
// Combines all arguments into a resolved, normalized path
function join (...paths) {
function join(...paths) {
let joined = pathJoin(...paths);
let resolved = normalize(joined);
@ -301,7 +335,7 @@ const load = iced(function load(loader, module) {
});
let sandbox;
if (loader.sharedGlobalSandbox &&
if ((loader.useSharedGlobalSandbox || isSystemURI(module.uri)) &&
loader.sharedGlobalBlocklist.indexOf(module.id) == -1) {
// Create a new object in this sandbox, that will be used as
// the scope object for this particular module
@ -309,13 +343,14 @@ const load = iced(function load(loader, module) {
// Inject all expected globals in the scope object
getOwnIdentifiers(globals).forEach(function(name) {
descriptors[name] = getOwnPropertyDescriptor(globals, name)
descriptors[name].configurable = true;
});
define(sandbox, descriptors);
Object.defineProperties(sandbox, descriptors);
}
else {
sandbox = Sandbox({
name: module.uri,
prototype: create(globals, descriptors),
prototype: Object.create(globals, descriptors),
wantXrays: false,
wantGlobalProperties: module.id == "sdk/indexed-db" ? ["indexedDB"] : [],
invisibleToDebugger: loader.invisibleToDebugger,
@ -359,7 +394,7 @@ const load = iced(function load(loader, module) {
let prototype = typeof(error) === "object" ? error.constructor.prototype :
Error.prototype;
throw create(prototype, {
throw Object.create(prototype, {
message: { value: message, writable: true, configurable: true },
fileName: { value: fileName, writable: true, configurable: true },
lineNumber: { value: lineNumber, writable: true, configurable: true },
@ -368,7 +403,7 @@ const load = iced(function load(loader, module) {
});
}
if(loadModuleHook) {
if (loadModuleHook) {
module = loadModuleHook(module, require);
}
@ -387,7 +422,7 @@ const load = iced(function load(loader, module) {
Loader.load = load;
// Utility function to normalize module `uri`s so they have `.js` extension.
function normalizeExt (uri) {
function normalizeExt(uri) {
return isJSURI(uri) ? uri :
isJSONURI(uri) ? uri :
isJSMURI(uri) ? uri :
@ -396,7 +431,7 @@ function normalizeExt (uri) {
// Strips `rootURI` from `string` -- used to remove absolute resourceURI
// from a relative path
function stripBase (rootURI, string) {
function stripBase(rootURI, string) {
return string.replace(rootURI, './');
}
@ -404,15 +439,14 @@ function stripBase (rootURI, string) {
// `requirer.uri` but in some cases it may be `baseURI`. In order to
// avoid complexity we require `baseURI` with a trailing `/`.
const resolve = iced(function resolve(id, base) {
if (!isRelative(id)) return id;
let basePaths = base.split('/');
// Pop the last element in the `base`, because it is from a
// relative file
// '../mod.js' from '/path/to/file.js' should resolve to '/path/mod.js'
basePaths.pop();
if (!basePaths.length)
if (!isRelative(id))
return id;
let baseDir = dirname(base);
if (!baseDir)
return normalize(id);
let resolved = join(basePaths.join('/'), id);
let resolved = join(baseDir, id);
// Joining and normalizing removes the './' from relative files.
// We need to ensure the resolution still has the root
@ -423,6 +457,78 @@ const resolve = iced(function resolve(id, base) {
});
Loader.resolve = resolve;
// Attempts to load `path` and then `path.js`
// Returns `path` with valid file, or `undefined` otherwise
function resolveAsFile(path) {
let found;
// As per node's loader spec,
// we first should try and load 'path' (with no extension)
// before trying 'path.js'. We will not support this feature
// due to performance, but may add it if necessary for adoption.
try {
// Append '.js' to path name unless it's another support filetype
path = normalizeExt(path);
readURI(path);
found = path;
} catch (e) {}
return found;
}
// Attempts to load `path/package.json`'s `main` entry,
// followed by `path/index.js`, or `undefined` otherwise
function resolveAsDirectory(path) {
try {
// If `path/package.json` exists, parse the `main` entry
// and attempt to load that
let main = getManifestMain(JSON.parse(readURI(path + '/package.json')));
if (main != null) {
let tmpPath = join(path, main);
let found = resolveAsFile(tmpPath);
if (found)
return found
}
} catch (e) {}
try {
let tmpPath = path + '/index.js';
readURI(tmpPath);
return tmpPath;
} catch (e) {}
return null;
}
function resolveRelative(rootURI, modulesDir, id) {
let fullId = join(rootURI, modulesDir, id);
let resolvedPath;
if ((resolvedPath = resolveAsFile(fullId)))
return stripBase(rootURI, resolvedPath);
if ((resolvedPath = resolveAsDirectory(fullId)))
return stripBase(rootURI, resolvedPath);
return null;
}
// From `resolve` module
// https://github.com/substack/node-resolve/blob/master/lib/node-modules-paths.js
function* getNodeModulePaths(start) {
// Configurable in node -- do we need this to be configurable?
let moduleDir = 'node_modules';
let parts = start.split('/');
while (parts.length) {
let leaf = parts.pop();
if (leaf !== moduleDir)
yield join(...parts, leaf, moduleDir);
}
yield moduleDir;
}
// Node-style module lookup
// Takes an id and path and attempts to load a file using node's resolving
// algorithm.
@ -434,39 +540,31 @@ const nodeResolve = iced(function nodeResolve(id, requirer, { rootURI }) {
// If this is already an absolute URI then there is no resolution to do
if (isAbsoluteURI(id))
return void 0;
return null;
// we assume that extensions are correct, i.e., a directory doesnt't have '.js'
// and a js file isn't named 'file.json.js'
let fullId = join(rootURI, id);
let resolvedPath;
if ((resolvedPath = loadAsFile(fullId)))
return stripBase(rootURI, resolvedPath);
if ((resolvedPath = loadAsDirectory(fullId)))
return stripBase(rootURI, resolvedPath);
if ((resolvedPath = resolveRelative(rootURI, "", id)))
return resolvedPath;
// If the requirer is an absolute URI then the node module resolution below
// won't work correctly as we prefix everything with rootURI
if (isAbsoluteURI(requirer))
return void 0;
return null;
// If manifest has dependencies, attempt to look up node modules
// in the `dependencies` list
let dirs = getNodeModulePaths(dirname(requirer)).map(dir => join(rootURI, dir, id));
for (let i = 0; i < dirs.length; i++) {
if ((resolvedPath = loadAsFile(dirs[i])))
return stripBase(rootURI, resolvedPath);
if ((resolvedPath = loadAsDirectory(dirs[i])))
return stripBase(rootURI, resolvedPath);
for (let modulesDir of getNodeModulePaths(dirname(requirer))) {
if ((resolvedPath = resolveRelative(rootURI, modulesDir, id)))
return resolvedPath;
}
// We would not find lookup for things like `sdk/tabs`, as that's part of
// the alias mapping. If during `generateMap`, the runtime lookup resolves
// with `resolveURI` -- if during runtime, then `resolve` will throw.
return void 0;
return null;
});
// String (`${rootURI}:${requirer}:${id}`) -> resolvedPath
@ -488,100 +586,18 @@ const nodeResolveWithCache = iced(function cacheNodeResolutions(id, requirer, {
});
Loader.nodeResolve = nodeResolveWithCache;
// Attempts to load `path` and then `path.js`
// Returns `path` with valid file, or `undefined` otherwise
function loadAsFile (path) {
let found;
// As per node's loader spec,
// we first should try and load 'path' (with no extension)
// before trying 'path.js'. We will not support this feature
// due to performance, but may add it if necessary for adoption.
try {
// Append '.js' to path name unless it's another support filetype
path = normalizeExt(path);
readURI(path);
found = path;
} catch (e) {}
return found;
}
// Attempts to load `path/package.json`'s `main` entry,
// followed by `path/index.js`, or `undefined` otherwise
function loadAsDirectory (path) {
try {
// If `path/package.json` exists, parse the `main` entry
// and attempt to load that
let main = getManifestMain(JSON.parse(readURI(path + '/package.json')));
if (main != null) {
let tmpPath = join(path, main);
let found = loadAsFile(tmpPath);
if (found)
return found
}
try {
let tmpPath = path + '/index.js';
readURI(tmpPath);
return tmpPath;
} catch (e) {}
} catch (e) {
try {
let tmpPath = path + '/index.js';
readURI(tmpPath);
return tmpPath;
} catch (e) {}
}
return void 0;
}
// From `resolve` module
// https://github.com/substack/node-resolve/blob/master/lib/node-modules-paths.js
function getNodeModulePaths (start) {
// Configurable in node -- do we need this to be configurable?
let moduleDir = 'node_modules';
let parts = start.split('/');
let dirs = [];
for (let i = parts.length - 1; i >= 0; i--) {
if (parts[i] === moduleDir) continue;
let dir = join(parts.slice(0, i + 1).join('/'), moduleDir);
dirs.push(dir);
}
dirs.push(moduleDir);
return dirs;
}
function addTrailingSlash (path) {
return !path ? null : !path.endsWith('/') ? path + '/' : path;
}
// Utility function to determine of module id `name` is a built in
// module in node (fs, path, etc.);
function isNodeModule (name) {
return !!~NODE_MODULES.indexOf(name);
}
// Make mapping array that is sorted from longest path to shortest path
// to allow overlays. Used by `resolveURI`, returns an array
function sortPaths (paths) {
return keys(paths).
sort((a, b) => (b.length - a.length)).
map((path) => [ path, paths[path] ]);
function addTrailingSlash(path) {
return path.replace(/\/*$/, "/");
}
const resolveURI = iced(function resolveURI(id, mapping) {
let count = mapping.length, index = 0;
// Do not resolve if already a resource URI
if (isAbsoluteURI(id)) return normalizeExt(id);
while (index < count) {
let [ path, uri ] = mapping[index++];
if (isAbsoluteURI(id))
return normalizeExt(id);
for (let [path, uri] of mapping) {
// Strip off any trailing slashes to make comparisons simpler
let stripped = path.endsWith('/') ? path.slice(0, -1) : path;
let stripped = path.replace(/\/+$/, "");
// We only want to match path segments explicitly. Examples:
// * "foo/bar" matches for "foo/bar"
@ -592,13 +608,11 @@ const resolveURI = iced(function resolveURI(id, mapping) {
//
// Check for an empty path, an exact match, or a substring match
// with the next character being a forward slash.
if(stripped === "" ||
(id.indexOf(stripped) === 0 &&
(id.length === path.length || id[stripped.length] === '/'))) {
if(stripped === "" || id === stripped || id.startsWith(stripped + "/")) {
return normalizeExt(id.replace(path, uri));
}
}
return void 0; // otherwise we raise a warning, see bug 910304
return null;
});
Loader.resolveURI = resolveURI;
@ -613,6 +627,14 @@ const Require = iced(function Require(loader, requirer) {
requireHook
} = loader;
if (isSystemURI(requirer.uri)) {
// Built-in modules don't require the expensive module resolution
// algorithm used by SDK add-ons, so give them the more efficient standard
// resolve instead.
isNative = false;
loaderResolve = Loader.resolve;
}
function require(id) {
if (!id) // Throw if `id` is not passed.
throw Error('You must provide a module name when calling require() from '
@ -704,19 +726,16 @@ const Require = iced(function Require(loader, requirer) {
let { overrides } = manifest.jetpack;
for (let key in overrides) {
// ignore any overrides using relative keys
if (/^[\.\/]/.test(key)) {
if (/^[.\/]/.test(key)) {
continue;
}
// If the override is for x -> y,
// then using require("x/lib/z") to get reqire("y/lib/z")
// should also work
if (id == key || (id.substr(0, key.length + 1) == (key + "/"))) {
if (id == key || id.startsWith(key + "/")) {
id = overrides[key] + id.substr(key.length);
id = id.replace(/^[\.\/]+/, "./");
if (id.substr(0, 2) == "./") {
id = "" + id.substr(2);
}
id = id.replace(/^[.\/]+/, "");
}
}
@ -728,7 +747,7 @@ const Require = iced(function Require(loader, requirer) {
// If no requireMap was provided, or resolution not found in
// the requireMap, and not a npm dependency, attempt a runtime lookup
if (!requirement && !isNodeModule(id)) {
if (!requirement && !NODE_MODULES.has(id)) {
// If `isNative` defined, this is using the new, native-style
// loader, not cuddlefish, so lets resolve using node's algorithm
// and get back a path that needs to be resolved via paths mapping
@ -747,9 +766,15 @@ const Require = iced(function Require(loader, requirer) {
requirement = isRelative(id) ? Loader.resolve(id, requirer.id) : id;
}
}
else {
else if (modules[id]) {
uri = requirement = id;
}
else if (requirer) {
// Resolve `id` to its requirer if it's relative.
requirement = requirer ? loaderResolve(id, requirer.id) : id;
requirement = loaderResolve(id, requirer.id);
}
else {
requirement = id;
}
// Resolves `uri` of module using loaders resolve function.
@ -790,9 +815,9 @@ Loader.main = main;
// Makes module object that is made available to CommonJS modules when they
// are evaluated, along with `exports` and `require`.
const Module = iced(function Module(id, uri) {
return create(null, {
return Object.create(null, {
id: { enumerable: true, value: id },
exports: { enumerable: true, writable: true, value: create(null),
exports: { enumerable: true, writable: true, value: Object.create(null),
configurable: true },
uri: { value: uri }
});
@ -878,9 +903,12 @@ function Loader(options) {
// which loader is unloaded. Please note that we intentionally don't
// use `loader` as subject to prevent a loader access leakage through
// observer notifications.
let destructor = freeze(create(null));
let destructor = freeze(Object.create(null));
let mapping = sortPaths(paths);
// Make mapping array that is sorted from longest path to shortest path.
let mapping = Object.keys(paths)
.sort((a, b) => b.length - a.length)
.map(path => [path, paths[path]]);
// Define pseudo modules.
modules = override({
@ -895,7 +923,8 @@ function Loader(options) {
}, modules);
const builtinModuleExports = modules;
modules = keys(modules).reduce(function(result, id) {
modules = {};
for (let id of Object.keys(builtinModuleExports)) {
// We resolve `uri` from `id` since modules are cached by `uri`.
let uri = resolveURI(id, mapping);
// In native loader, the mapping will not contain values for
@ -913,29 +942,25 @@ function Loader(options) {
}
});
result[uri] = freeze(module);
return result;
}, {});
let sharedGlobalSandbox;
if (sharedGlobal) {
// Create the unique sandbox we will be using for all modules,
// so that we prevent creating a new comportment per module.
// The side effect is that all modules will share the same
// global objects.
sharedGlobalSandbox = Sandbox({
name: "Addon-SDK",
wantXrays: false,
wantGlobalProperties: [],
invisibleToDebugger: options.invisibleToDebugger || false,
metadata: {
addonID: options.id,
URI: "Addon-SDK"
},
prototype: options.sandboxPrototype || {}
});
modules[uri] = freeze(module);
}
// Create the unique sandbox we will be using for all modules,
// so that we prevent creating a new comportment per module.
// The side effect is that all modules will share the same
// global objects.
let sharedGlobalSandbox = Sandbox({
name: "Addon-SDK",
wantXrays: false,
wantGlobalProperties: [],
invisibleToDebugger: options.invisibleToDebugger || false,
metadata: {
addonID: options.id,
URI: "Addon-SDK"
},
prototype: options.sandboxPrototype || {}
});
// Loader object is just a representation of a environment
// state. We freeze it and mark make it's properties non-enumerable
// as they are pure implementation detail that no one should rely upon.
@ -946,6 +971,7 @@ function Loader(options) {
// Map of module objects indexed by module URIs.
modules: { enumerable: false, value: modules },
metadata: { enumerable: false, value: metadata },
useSharedGlobalSandbox: { enumerable: false, value: !!sharedGlobal },
sharedGlobalSandbox: { enumerable: false, value: sharedGlobalSandbox },
sharedGlobalBlocklist: { enumerable: false, value: sharedGlobalBlocklist },
sharedGlobalBlacklist: { enumerable: false, value: sharedGlobalBlocklist },
@ -981,151 +1007,26 @@ function Loader(options) {
returnObj.rootURI = { enumerable: false, value: addTrailingSlash(rootURI) };
}
return freeze(create(null, returnObj));
return freeze(Object.create(null, returnObj));
};
Loader.Loader = Loader;
var isJSONURI = uri => uri.substr(-5) === '.json';
var isJSMURI = uri => uri.substr(-4) === '.jsm';
var isJSURI = uri => uri.substr(-3) === '.js';
var isAbsoluteURI = uri => uri.indexOf("resource://") >= 0 ||
uri.indexOf("chrome://") >= 0 ||
uri.indexOf("file://") >= 0
var isRelative = id => id[0] === '.'
var isSystemURI = uri => /^resource:\/\/(gre|devtools|testing-common)\//.test(uri);
const generateMap = iced(function generateMap(options, callback) {
let { rootURI, resolve, paths } = override({
paths: {},
resolve: Loader.nodeResolve
}, options);
rootURI = addTrailingSlash(rootURI);
let manifest;
let manifestURI = join(rootURI, 'package.json');
if (rootURI)
manifest = JSON.parse(readURI(manifestURI));
else
throw new Error('No `rootURI` given to generate map');
let main = getManifestMain(manifest);
findAllModuleIncludes(main, {
resolve: resolve,
manifest: manifest,
rootURI: rootURI
}, {}, callback);
});
Loader.generateMap = generateMap;
var isJSONURI = uri => uri.endsWith('.json');
var isJSMURI = uri => uri.endsWith('.jsm');
var isJSURI = uri => uri.endsWith('.js');
var isAbsoluteURI = uri => uri.startsWith("resource://") ||
uri.startsWith("chrome://") ||
uri.startsWith("file://");
var isRelative = id => id.startsWith(".");
// Default `main` entry to './index.js' and ensure is relative,
// since node allows 'lib/index.js' without relative `./`
function getManifestMain (manifest) {
function getManifestMain(manifest) {
let main = manifest.main || './index.js';
return isRelative(main) ? main : './' + main;
}
function findAllModuleIncludes (uri, options, results, callback) {
let { resolve, manifest, rootURI } = options;
results = results || {};
// Abort if JSON or JSM
if (isJSONURI(uri) || isJSMURI(uri)) {
callback(results);
return;
}
findModuleIncludes(join(rootURI, uri), modules => {
// If no modules are included in the file, just call callback immediately
if (!modules.length) {
callback(results);
return;
}
results[uri] = modules.reduce((agg, mod) => {
let resolved = resolve(mod, uri, { manifest: manifest, rootURI: rootURI });
// If resolution found, store the resolution; otherwise,
// skip storing it as runtime lookup will handle this
if (!resolved)
return agg;
agg[mod] = resolved;
return agg;
}, {});
let includes = keys(results[uri]);
let count = 0;
let subcallback = () => { if (++count >= includes.length) callback(results) };
includes.map(id => {
let moduleURI = results[uri][id];
if (!results[moduleURI])
findAllModuleIncludes(moduleURI, options, results, subcallback);
else
subcallback();
});
});
}
// From Substack's detector
// https://github.com/substack/node-detective
//
// Given a resource URI or source, return an array of strings passed into
// the require statements from the source
function findModuleIncludes (uri, callback) {
let src = isAbsoluteURI(uri) ? readURI(uri) : uri;
let modules = [];
walk(src, function (node) {
if (isRequire(node))
modules.push(node.arguments[0].value);
});
callback(modules);
}
function walk (src, callback) {
// Import Reflect.jsm from here to prevent loading it until someone uses it
let { Reflect } = Cu.import("resource://gre/modules/reflect.jsm", {});
let nodes = Reflect.parse(src);
traverse(nodes, callback);
}
function traverse (node, cb) {
if (Array.isArray(node)) {
node.map(x => {
if (x != null) {
x.parent = node;
traverse(x, cb);
}
});
}
else if (node && typeof node === 'object') {
cb(node);
keys(node).map(key => {
if (key === 'parent' || !node[key]) return;
if (typeof node[key] === "object")
node[key].parent = node;
traverse(node[key], cb);
});
}
}
// From Substack's detector
// https://github.com/substack/node-detective
// Check an AST node to see if its a require statement.
// A modification added to only evaluate to true if it actually
// has a value being passed in as an argument
function isRequire (node) {
var c = node.callee;
return c
&& node.type === 'CallExpression'
&& c.type === 'Identifier'
&& c.name === 'require'
&& node.arguments.length
&& node.arguments[0].type === 'Literal';
}
module.exports = iced(Loader);
});

View File

@ -22,7 +22,7 @@ if (app.is("Firefox")) {
exec(isWindows ? "DIR /A-D" : "ls -al", {
cwd: PROFILE_DIR
}, (err, stdout, stderr) => {
assert.ok(!err, "no errors");
assert.equal(err, null, "no errors");
assert.equal(stderr, "", "stderr is empty");
assert.ok(/extensions\.ini/.test(stdout), "stdout output of `ls -al` finds files");

View File

@ -121,8 +121,8 @@ exports.testExecFileCallbackSuccess = function (assert, done) {
exports.testExecFileCallbackError = function (assert, done) {
execFile('not-real-command', { cwd: PROFILE_DIR }, function (err, stdout, stderr) {
assert.ok(/NS_ERROR_FILE_UNRECOGNIZED_PATH/.test(err.message),
'error contains error message');
assert.ok(/Executable not found/.test(err.message),
`error '${err.message}' contains error message`);
assert.ok(err.lineNumber >= 0, 'error contains lineNumber');
assert.ok(/resource:\/\//.test(err.fileName), 'error contains fileName');
assert.equal(stdout, '', 'stdout is empty');

View File

@ -66,12 +66,7 @@ exports["test dead object errors"] = function(assert, done) {
loader.unload();
// in order to get a dead object error on this module, we need to nuke
// the relative sandbox; unload the loader is not enough
let url = Object.keys(loader.sandboxes).
find(url => url.endsWith("/sdk/content/events.js"));
nuke(loader.sandboxes[url]);
nuke(loader.sharedGlobalSandbox);
system.on("console-api-log-event", onMessage, true);

View File

@ -4,7 +4,7 @@
'use strict';
var {
Loader, main, unload, parseStack, generateMap, resolve, join,
Loader, main, unload, parseStack, resolve, join,
Require, Module
} = require('toolkit/loader');
var { readURI } = require('sdk/net/url');

View File

@ -4,7 +4,7 @@
'use strict';
var {
Loader, main, unload, parseStack, generateMap, resolve, nodeResolve
Loader, main, unload, parseStack, resolve, nodeResolve
} = require('toolkit/loader');
var { readURI } = require('sdk/net/url');
var { all } = require('sdk/core/promise');
@ -70,19 +70,6 @@ exports['test bundle'] = function (assert, done) {
};
*/
exports['test generateMap()'] = function (assert, done) {
getJSON('/fixtures/native-addon-test/expectedmap.json').then(expected => {
generateMap({
rootURI: root + '/fixtures/native-addon-test/'
}, map => {
assert.deepEqual(map, expected, 'generateMap returns expected mappings');
assert.equal(map['./index.js']['./dir/a'], './dir/a.js',
'sanity check on correct mappings');
done();
});
}).then(null, (reason) => console.error(reason));
};
exports['test JSM loading'] = function (assert, done) {
getJSON('/fixtures/jsm-package/package.json').then(manifest => {
let rootURI = root + '/fixtures/jsm-package/';

View File

@ -24,9 +24,9 @@
"size" : 12072532
},
{
"version": "rustc 1.11.0 (9b21dcd6a 2016-08-15) repack",
"size": 131489924,
"digest": "59f7463a0da38f324daa4ffc2678d78afb4fe0df13248c1d215bcb996ec05e8521155563cde9a8b719a9b98c5feeaf97cc9e8d52c9b95f6b44728870d908d5b6",
"version": "rustc 1.12.0 (3191fbae9 2016-09-23) repack",
"size": 102403884,
"digest": "a7c1512d955d3030bcc1ebddfbf512f7b11b66e31634726deab78d0403fc0ceadd603d32b08c1a5025d3e9ee4ff48ddcf5eaba33468bb2161cfb9fb1a557affa",
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true

View File

@ -16,9 +16,9 @@
"unpack": true
},
{
"version": "rustc 1.11.0 (9b21dcd6a 2016-08-15) repack",
"size": 131489924,
"digest": "59f7463a0da38f324daa4ffc2678d78afb4fe0df13248c1d215bcb996ec05e8521155563cde9a8b719a9b98c5feeaf97cc9e8d52c9b95f6b44728870d908d5b6",
"version": "rustc 1.12.0 (3191fbae9 2016-09-23) repack",
"size": 102403884,
"digest": "a7c1512d955d3030bcc1ebddfbf512f7b11b66e31634726deab78d0403fc0ceadd603d32b08c1a5025d3e9ee4ff48ddcf5eaba33468bb2161cfb9fb1a557affa",
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true

View File

@ -16,9 +16,9 @@
"unpack": true
},
{
"version": "gecko rustc 1.11.0 (9b21dcd6a 2016-08-15) x86_64+i586",
"size": 99378568,
"digest": "ea5ae0a37ab8c583ef3f9a97c45baf0644feed95f1e6191a4456fd42bbd45b218fe4bc528747a63af55ce67c4b6155bd50f312746628b30e41c421f4d54e5417",
"version": "rustc 1.12.0 (3191fbae9 2016-09-23) repack x86_64+i586",
"size": 102403884,
"digest": "a7c1512d955d3030bcc1ebddfbf512f7b11b66e31634726deab78d0403fc0ceadd603d32b08c1a5025d3e9ee4ff48ddcf5eaba33468bb2161cfb9fb1a557affa",
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true

View File

@ -24,9 +24,9 @@
"size" : 12072532
},
{
"version": "rustc 1.11.0 (9b21dcd6a 2016-08-15) repack",
"size": 131489924,
"digest": "59f7463a0da38f324daa4ffc2678d78afb4fe0df13248c1d215bcb996ec05e8521155563cde9a8b719a9b98c5feeaf97cc9e8d52c9b95f6b44728870d908d5b6",
"version": "rustc 1.12.0 (3191fbae9 2016-09-23) repack",
"size": 102403884,
"digest": "a7c1512d955d3030bcc1ebddfbf512f7b11b66e31634726deab78d0403fc0ceadd603d32b08c1a5025d3e9ee4ff48ddcf5eaba33468bb2161cfb9fb1a557affa",
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true

View File

@ -16,9 +16,9 @@
"unpack": true
},
{
"version": "rustc 1.11.0 (9b21dcd6a 2016-08-15) repack",
"size": 131489924,
"digest": "59f7463a0da38f324daa4ffc2678d78afb4fe0df13248c1d215bcb996ec05e8521155563cde9a8b719a9b98c5feeaf97cc9e8d52c9b95f6b44728870d908d5b6",
"version": "rustc 1.12.0 (3191fbae9 2016-09-23) repack",
"size": 102403884,
"digest": "a7c1512d955d3030bcc1ebddfbf512f7b11b66e31634726deab78d0403fc0ceadd603d32b08c1a5025d3e9ee4ff48ddcf5eaba33468bb2161cfb9fb1a557affa",
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true

View File

@ -55,9 +55,9 @@
"filename": "genisoimage.tar.xz"
},
{
"version": "rustc 1.11.0 (9b21dcd6a 2016-08-15) repack",
"size": 171059204,
"digest": "7554ac993f55818827c80dab90135209e57db70c7c9131bef4309aff3b8d7452c4c0de663df7e8c46bd5702455c36292ade6c7a8007e567c4588c7f91aa88b57",
"version": "rustc 1.12.0 (3191fbae9 2016-09-23) repack",
"size": 179757256,
"digest": "26bbd6a34beab36620634f7eafe63281e3398ae4673b3a4d49e1da4eae0467bc6efc2471ef842682db527ad137e702b74c68f278025c60c8bb69d244cff1e6b6",
"algorithm": "sha512",
"filename": "rustc.tar.xz",
"unpack": true

View File

@ -8,9 +8,9 @@
"unpack": true
},
{
"version": "rustc 1.11.0 (9b21dcd6a 2016-08-15) repack",
"size": 146060042,
"digest": "c7c5556af0dea1f97a737e4634496d407a5e0f7d14a7013746ad41ef188bab03be60cea59ed63d733dcb03bf11b05d8bf637dc0261f15cd5b0ab46d1199243cf",
"version": "rustc 1.12.0 (3191fbae9 2016-09-23) repack",
"size": 152905062,
"digest": "1fb64d68ad41e5ca444a5a91f752efec154957d22bdf078adbc7b6a1cdbeefbadbc618de96cc46540a33849d43ac95a520a463d4f852e1a5a1f636d7079d969f",
"algorithm": "sha512",
"filename": "rustc.tar.bz2",
"unpack": true

View File

@ -6,9 +6,9 @@
"filename": "mozmake.exe"
},
{
"version": "rustc 1.11.0 (9b21dcd6a 2016-08-15) repack",
"size": 86199150,
"digest": "fec209dc85a098817c892655fbfda2bd6961199b1c28422994a50daddcb219608673b87dde30b3380555400cf4484863a12d431a6a25ef01cb9b1b32bef48f8b",
"version": "rustc 1.12.0 (3191fbae9 2016-09-23) repack",
"size": 89434100,
"digest": "4da0efd2c36c77f29846f328d9f3c095a7b7e0dfd94f76b3159d441aae02b25007a475a979fb5bf313cf8fecb22fec81684871809effcb6b514419bc3854f398",
"algorithm": "sha512",
"filename": "rustc.tar.bz2",
"unpack": true

View File

@ -6,9 +6,9 @@
"filename": "mozmake.exe"
},
{
"version": "rustc 1.11.0 (9b21dcd6a 2016-08-15) repack",
"size": 86199150,
"digest": "fec209dc85a098817c892655fbfda2bd6961199b1c28422994a50daddcb219608673b87dde30b3380555400cf4484863a12d431a6a25ef01cb9b1b32bef48f8b",
"version": "rustc 1.12.0 (3191fbae9 2016-09-23) repack",
"size": 89434100,
"digest": "4da0efd2c36c77f29846f328d9f3c095a7b7e0dfd94f76b3159d441aae02b25007a475a979fb5bf313cf8fecb22fec81684871809effcb6b514419bc3854f398",
"algorithm": "sha512",
"filename": "rustc.tar.bz2",
"unpack": true

View File

@ -6,9 +6,9 @@
"filename": "mozmake.exe"
},
{
"version": "rustc 1.11.0 (9b21dcd6a 2016-08-15) repack",
"size": 91329933,
"digest": "db97f0186db432c57698e287798940abb5946c8903f990b087ea977fb938e83f2f9ca1bf90377bc575563af3144d429cc897a36750a1978a288a42b132c3d25d",
"version": "rustc 1.12.0 (3191fbae9 2016-09-23) repack",
"size": 94812923,
"digest": "f8ff01a44caf38711c352e49c06e8ef6bbac7836bed1050bb043f89ba70f70a11c88001f453baec0cbc56a013efb0fd6b16d612923d07e29b5d8d4512dbaab07",
"algorithm": "sha512",
"visibility": "public",
"filename": "rustc.tar.bz2",

View File

@ -6,9 +6,9 @@
"filename": "mozmake.exe"
},
{
"version": "rustc 1.11.0 (9b21dcd6a 2016-08-15) repack",
"size": 91329933,
"digest": "db97f0186db432c57698e287798940abb5946c8903f990b087ea977fb938e83f2f9ca1bf90377bc575563af3144d429cc897a36750a1978a288a42b132c3d25d",
"version": "rustc 1.12.0 (3191fbae9 2016-09-23) repack",
"size": 94812923,
"digest": "f8ff01a44caf38711c352e49c06e8ef6bbac7836bed1050bb043f89ba70f70a11c88001f453baec0cbc56a013efb0fd6b16d612923d07e29b5d8d4512dbaab07",
"algorithm": "sha512",
"visibility": "public",
"filename": "rustc.tar.bz2",

View File

@ -73,10 +73,10 @@ this.ContentWebRTC = {
let devices = contentWindow.pendingGetUserMediaRequests.get(callID);
forgetGUMRequest(contentWindow, callID);
let allowedDevices = Cc["@mozilla.org/supports-array;1"]
.createInstance(Ci.nsISupportsArray);
let allowedDevices = Cc["@mozilla.org/array;1"]
.createInstance(Ci.nsIMutableArray);
for (let deviceIndex of aMessage.data.devices)
allowedDevices.AppendElement(devices[deviceIndex]);
allowedDevices.appendElement(devices[deviceIndex], /*weak =*/ false);
Services.obs.notifyObservers(allowedDevices, "getUserMedia:response:allow", callID);
break;
@ -261,8 +261,8 @@ function forgetPendingListsEventually(aContentWindow) {
}
function updateIndicators() {
let contentWindowSupportsArray = MediaManagerService.activeMediaCaptureWindows;
let count = contentWindowSupportsArray.Count();
let contentWindowArray = MediaManagerService.activeMediaCaptureWindows;
let count = contentWindowArray.length;
let state = {
showGlobalIndicator: count > 0,
@ -280,7 +280,7 @@ function updateIndicators() {
// sending duplicate notifications.
let contentWindows = new Set();
for (let i = 0; i < count; ++i) {
contentWindows.add(contentWindowSupportsArray.GetElementAt(i).top);
contentWindows.add(contentWindowArray.queryElementAt(i, Ci.nsISupports).top);
}
for (let contentWindow of contentWindows) {

View File

@ -87,7 +87,7 @@ browser.jar:
skin/classic/browser/places/autocomplete-star.png (places/autocomplete-star.png)
skin/classic/browser/places/autocomplete-star@2x.png (places/autocomplete-star@2x.png)
* skin/classic/browser/places/places.css (places/places.css)
* skin/classic/browser/places/organizer.css (places/organizer.css)
skin/classic/browser/places/organizer.css (places/organizer.css)
skin/classic/browser/places/query.png (places/query.png)
skin/classic/browser/places/query@2x.png (places/query@2x.png)
skin/classic/browser/places/bookmarksMenu.png (places/bookmarksMenu.png)

View File

@ -2,8 +2,6 @@
* 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/. */
%include ../shared.inc
/* Places Organizer Sidebars */
#placesList > treechildren::-moz-tree-row {
@ -19,27 +17,11 @@
}
#placesList > treechildren::-moz-tree-row(selected) {
background: @sidebarItemBackground@;
border-top: @sidebarItemBorderTop@;
border-bottom: @sidebarItemBorderBottom@;
-moz-appearance: -moz-mac-source-list-selection;
}
#placesList > treechildren::-moz-tree-row(selected,focus) {
background: @sidebarItemFocusedBackground@;
border-top: @sidebarItemFocusedBorderTop@;
border-bottom: @sidebarItemFocusedBorderBottom@;
}
#placesList:-moz-system-metric(mac-graphite-theme) > treechildren::-moz-tree-row(selected) {
background: @sidebarItemGraphiteBackground@;
border-top: @sidebarItemGraphiteBorderTop@;
border-bottom: @sidebarItemGraphiteBorderBottom@;
}
#placesList:-moz-system-metric(mac-graphite-theme) > treechildren::-moz-tree-row(selected,focus) {
background: @sidebarItemGraphiteFocusedBackground@;
border-top: @sidebarItemGraphiteFocusedBorderTop@;
border-bottom: @sidebarItemGraphiteFocusedBorderBottom@;
-moz-appearance: -moz-mac-active-source-list-selection;
}
#placesList > treechildren::-moz-tree-row(History),
@ -80,30 +62,6 @@
}
@media (-moz-mac-yosemite-theme) {
#placesList > treechildren::-moz-tree-row(selected) {
background: @sidebarItemBackgroundYosemite@;
border-top: none;
border-bottom: none;
}
#placesList > treechildren::-moz-tree-row(selected,focus) {
background: @sidebarItemFocusedBackgroundYosemite@;
border-top: none;
border-bottom: none;
}
#placesList > treechildren:-moz-system-metric(mac-graphite-theme)::-moz-tree-row(selected) {
background: @sidebarItemGraphiteBackgroundYosemite@;
border-top: none;
border-bottom: none;
}
#placesList > treechildren:-moz-system-metric(mac-graphite-theme)::-moz-tree-row(selected,focus) {
background: @sidebarItemGraphiteFocusedBackgroundYosemite@;
border-top: none;
border-bottom: none;
}
#placesList > treechildren::-moz-tree-cell-text(selected) {
color: -moz-dialogtext;
font-weight: 500;

View File

@ -17,47 +17,35 @@
.sidebar-placesTree,
.sidebar-placesTreechildren::-moz-tree-row {
background-color: transparent;
border-color: transparent;
padding-bottom: 1px;
-moz-appearance: none;
margin: 0;
height: 24px;
border: none;
font-size: 12px;
}
.sidebar-placesTree {
-moz-appearance: -moz-mac-source-list;
}
.sidebar-placesTreechildren {
border-top: 1px solid #bebebe;
}
.sidebar-placesTreechildren::-moz-tree-separator {
border-top: 1px solid #505d6d;
margin: 0 10px;
}
.sidebar-placesTree {
border-top: 1px solid #bebebe;
.sidebar-placesTreechildren::-moz-tree-row {
background-color: transparent;
}
.sidebar-placesTreechildren::-moz-tree-row(selected) {
background: @sidebarItemBackground@;
border-top: @sidebarItemBorderTop@;
border-bottom: @sidebarItemBorderBottom@;
-moz-appearance: -moz-mac-source-list-selection;
}
.sidebar-placesTreechildren::-moz-tree-row(selected,focus) {
background: @sidebarItemFocusedBackground@;
border-top: @sidebarItemFocusedBorderTop@;
border-bottom: @sidebarItemFocusedBorderBottom@;
}
.sidebar-placesTreechildren:-moz-system-metric(mac-graphite-theme)::-moz-tree-row(selected) {
background: @sidebarItemGraphiteBackground@;
border-top: @sidebarItemGraphiteBorderTop@;
border-bottom: @sidebarItemGraphiteBorderBottom@;
}
.sidebar-placesTreechildren:-moz-system-metric(mac-graphite-theme)::-moz-tree-row(selected,focus) {
background: @sidebarItemGraphiteFocusedBackground@;
border-top: @sidebarItemGraphiteFocusedBorderTop@;
border-bottom: @sidebarItemGraphiteFocusedBorderBottom@;
-moz-appearance: -moz-mac-active-source-list-selection;
}
.sidebar-placesTreechildren::-moz-tree-cell-text {
@ -92,30 +80,6 @@
}
@media (-moz-mac-yosemite-theme) {
.sidebar-placesTreechildren::-moz-tree-row(selected) {
background: @sidebarItemBackgroundYosemite@;
border-top: none;
border-bottom: none;
}
.sidebar-placesTreechildren::-moz-tree-row(selected,focus) {
background: @sidebarItemFocusedBackgroundYosemite@;
border-top: none;
border-bottom: none;
}
.sidebar-placesTreechildren:-moz-system-metric(mac-graphite-theme)::-moz-tree-row(selected) {
background: @sidebarItemGraphiteBackgroundYosemite@;
border-top: none;
border-bottom: none;
}
.sidebar-placesTreechildren:-moz-system-metric(mac-graphite-theme)::-moz-tree-row(selected,focus) {
background: @sidebarItemGraphiteFocusedBackgroundYosemite@;
border-top: none;
border-bottom: none;
}
.sidebar-placesTreechildren::-moz-tree-cell-text(selected) {
color: -moz-dialogtext;
font-weight: 500;

View File

@ -2,12 +2,12 @@
* 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/. */
%include ../shared.inc
%include ../../shared/syncedtabs/sidebar.inc.css
/* These styles are intended to mimic XUL trees and the XUL search box. */
html {
.content-container {
-moz-appearance: -moz-mac-source-list;
}
.item {
@ -27,15 +27,11 @@ html {
}
.item.selected > .item-title-container {
background: @sidebarItemBackground@;
border-top: @sidebarItemBorderTop@;
border-bottom: @sidebarItemBorderBottom@;
-moz-appearance: -moz-mac-source-list-selection;
}
.item.selected:focus > .item-title-container {
background: @sidebarItemFocusedBackground@;
border-top: @sidebarItemFocusedBorderTop@;
border-bottom: @sidebarItemFocusedBorderBottom@;
-moz-appearance: -moz-mac-active-source-list-selection;
}
.item.client .item-twisty-container {
@ -57,38 +53,6 @@ html {
}
@media (-moz-mac-yosemite-theme) {
.item.selected > .item-title-container {
font-weight: 500;
}
.item.selected > .item-title-container {
background-image: none;
background-color: @sidebarItemBackgroundYosemite@;
border-top: none;
border-bottom: none;
}
.item.selected:focus > .item-title-container {
background-image: none;
background-color: @sidebarItemFocusedBackgroundYosemite@;
border-top: none;
border-bottom: none;
}
.item.selected:-moz-system-metric(mac-graphite-theme) > .item-title-container {
background-image: none;
background-color: @sidebarItemGraphiteBackgroundYosemite@;
border-top: none;
border-bottom: none;
}
.item.selected:focus:-moz-system-metric(mac-graphite-theme) > .item-title-container {
background-image: none;
background-color: @sidebarItemGraphiteFocusedBackgroundYosemite@;
border-top: none;
border-bottom: none;
}
.item.selected > .item-title-container {
color: -moz-dialogtext;
font-weight: 500;
@ -99,7 +63,6 @@ html {
}
}
.sidebar-search-container {
border-bottom: 1px solid #bdbdbd;
}

View File

@ -21,11 +21,6 @@ def generate(args):
else:
raise Exception("File not found: %s" % arg)
elif os.path.splitext(arg)[1] == conf.LIB_SUFFIX:
# We want to skip static libraries with the name foo-rs-prelink
# as they are individually linked for every final library, and
# thus should not be included in the descriptor file
if '-rs-prelink' in os.path.basename(arg):
continue
if os.path.exists(arg) or os.path.exists(arg + conf.LIBS_DESC_SUFFIX):
desc['LIBS'].append(os.path.abspath(arg))
else:

View File

@ -796,7 +796,7 @@ endif
# symlinks back to the originals. The symlinks are a no-op for stabs debugging,
# so no need to conditionalize on OS version or debugging format.
$(SHARED_LIBRARY): $(OBJS) $(RESFILE) $(STATIC_LIBS_DEPS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
$(SHARED_LIBRARY): $(OBJS) $(RESFILE) $(RUST_STATIC_LIB_FOR_SHARED_LIB) $(STATIC_LIBS_DEPS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
$(REPORT_BUILD)
ifndef INCREMENTAL_LINKER
$(RM) $@
@ -805,10 +805,10 @@ ifdef DTRACE_LIB_DEPENDENT
ifndef XP_MACOSX
dtrace -x nolibs -G -C -s $(MOZILLA_DTRACE_SRC) -o $(DTRACE_PROBE_OBJ) $(shell $(EXPAND_LIBS) $(MOZILLA_PROBE_LIBS))
endif
$(EXPAND_MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(SUB_SHLOBJS) $(DTRACE_PROBE_OBJ) $(MOZILLA_PROBE_LIBS) $(RESFILE) $(LDFLAGS) $(WRAP_LDFLAGS) $(STATIC_LIBS) $(SHARED_LIBS) $(EXTRA_DSO_LDOPTS) $(MOZ_GLUE_LDFLAGS) $(EXTRA_LIBS) $(OS_LIBS) $(SHLIB_LDENDFILE)
$(EXPAND_MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(SUB_SHLOBJS) $(DTRACE_PROBE_OBJ) $(MOZILLA_PROBE_LIBS) $(RESFILE) $(LDFLAGS) $(WRAP_LDFLAGS) $(STATIC_LIBS) $(RUST_STATIC_LIB_FOR_SHARED_LIB) $(SHARED_LIBS) $(EXTRA_DSO_LDOPTS) $(MOZ_GLUE_LDFLAGS) $(EXTRA_LIBS) $(OS_LIBS) $(SHLIB_LDENDFILE)
@$(RM) $(DTRACE_PROBE_OBJ)
else # ! DTRACE_LIB_DEPENDENT
$(EXPAND_MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(SUB_SHLOBJS) $(RESFILE) $(LDFLAGS) $(WRAP_LDFLAGS) $(STATIC_LIBS) $(SHARED_LIBS) $(EXTRA_DSO_LDOPTS) $(MOZ_GLUE_LDFLAGS) $(EXTRA_LIBS) $(OS_LIBS) $(SHLIB_LDENDFILE)
$(EXPAND_MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(SUB_SHLOBJS) $(RESFILE) $(LDFLAGS) $(WRAP_LDFLAGS) $(STATIC_LIBS) $(RUST_STATIC_LIB_FOR_SHARED_LIB) $(SHARED_LIBS) $(EXTRA_DSO_LDOPTS) $(MOZ_GLUE_LDFLAGS) $(EXTRA_LIBS) $(OS_LIBS) $(SHLIB_LDENDFILE)
endif # DTRACE_LIB_DEPENDENT
$(call CHECK_BINARY,$@)
@ -898,7 +898,7 @@ $(ASOBJS):
endif
ifdef MOZ_RUST
ifdef CARGO_FILE
ifdef RUST_LIBRARY_FILE
ifdef MOZ_DEBUG
cargo_build_flags =
@ -927,30 +927,6 @@ force-cargo-build:
$(RUST_LIBRARY_FILE): force-cargo-build
endif # CARGO_FILE
ifdef RUST_PRELINK
# Make target for building a prelinked rust library. This merges rust .rlibs
# together into a single .a file which is used within the FINAL_LIBRARY.
#
# RUST_PRELINK_FLAGS, RUST_PRELINK_SRC, and RUST_PRELINK_DEPS are set in
# recursivemake.py, and together tell rustc how to find the libraries to link
# together, but we compute the optimization flags below
RUST_PRELINK_FLAGS += -g
RUST_PRELINK_FLAGS += -C panic=abort
ifdef MOZ_DEBUG
RUST_PRELINK_FLAGS += -C opt-level=1
RUST_PRELINK_FLAGS += -C debug-assertions
else
RUST_PRELINK_FLAGS += -C opt-level=2
RUST_PRELINK_FLAGS += -C lto
endif
$(RUST_PRELINK): $(RUST_PRELINK_DEPS) $(RUST_PRELINK_SRC)
$(REPORT_BUILD)
$(RUSTC) -o $@ --crate-type staticlib --target $(RUST_TARGET) $(RUST_PRELINK_FLAGS) $(RUST_PRELINK_SRC)
endif # RUST_PRELINK
endif # MOZ_RUST
$(SOBJS):

View File

@ -98,15 +98,6 @@ LoadContext::GetNestedFrameId(uint64_t* aId)
return NS_OK;
}
NS_IMETHODIMP
LoadContext::IsAppOfType(uint32_t, bool*)
{
MOZ_ASSERT(mIsNotNull);
// don't expect we need this in parent (Thunderbird/SeaMonkey specific?)
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
LoadContext::GetIsContent(bool* aIsContent)
{

View File

@ -9738,6 +9738,20 @@ nsDocShell::InternalLoad(nsIURI* aURI,
nsIDocShell** aDocShell,
nsIRequest** aRequest)
{
// In most cases both principals (aTriggeringPrincipal and aPrincipalToInherit)
// are both null or both non-null. For the exceptional cases let's make sure that:
// * if aTriggeringPrincipal is null then either aPrincipalToInherit is null or
// it's a NullPrincipal
// * if aPrincipalToInherit is null then either aTriggeringPrincipal is null or
// it's a NullPrincipal or INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL is set.
MOZ_ASSERT(aTriggeringPrincipal ||
(!aPrincipalToInherit ||
aPrincipalToInherit->GetIsNullPrincipal()));
MOZ_ASSERT(aPrincipalToInherit ||
(!aTriggeringPrincipal ||
aTriggeringPrincipal->GetIsNullPrincipal() ||
(aFlags & INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL)));
nsresult rv = NS_OK;
mOriginalUriString.Truncate();
@ -9929,12 +9943,26 @@ nsDocShell::InternalLoad(nsIURI* aURI,
{
bool inherits;
// One more twist: Don't inherit the principal for external loads.
if (aLoadType != LOAD_NORMAL_EXTERNAL && !principalToInherit &&
(aFlags & INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL) &&
if (!principalToInherit &&
NS_SUCCEEDED(nsContentUtils::URIInheritsSecurityContext(aURI,
&inherits)) &&
inherits) {
principalToInherit = GetInheritedPrincipal(true);
if (aLoadType != LOAD_NORMAL_EXTERNAL &&
(aFlags & INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL)) {
principalToInherit = GetInheritedPrincipal(true);
}
// In case we don't have a principalToInherit and the TriggeringPrincipal
// either already is a SystemPrincipal or would fall back to become
// a SystemPrincipal within the loadInfo then we should explicitly set
// the principalToInherit to a freshly created NullPrincipal.
if (!principalToInherit &&
(nsContentUtils::IsSystemPrincipal(aTriggeringPrincipal) ||
(!aTriggeringPrincipal && !aReferrer))) {
// We're going to default to inheriting our system triggering principal,
// more or less by accident. This doesn't seem like a good idea.
principalToInherit = nsNullPrincipal::CreateWithInheritedAttributes(this);
}
}
}
@ -12300,7 +12328,7 @@ nsDocShell::AddToSessionHistory(nsIURI* aURI, nsIChannel* aChannel,
pAttrs.InheritFromNecko(nAttrs);
principalToInherit = nsNullPrincipal::Create(pAttrs);
}
} else if (loadInfo->GetForceInheritPrincipal()) {
} else {
principalToInherit = loadInfo->PrincipalToInherit();
}
}
@ -13556,24 +13584,6 @@ nsDocShell::GetNestedFrameId(uint64_t* aId)
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::IsAppOfType(uint32_t aAppType, bool* aIsOfType)
{
RefPtr<nsDocShell> shell = this;
while (shell) {
uint32_t type;
shell->GetAppType(&type);
if (type == aAppType) {
*aIsOfType = true;
return NS_OK;
}
shell = shell->GetParentDocshell();
}
*aIsOfType = false;
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::IsTrackingProtectionOn(bool* aIsTrackingProtectionOn)
{

View File

@ -224,7 +224,6 @@ public:
NS_IMETHOD GetTopWindow(mozIDOMWindowProxy**) override;
NS_IMETHOD GetTopFrameElement(nsIDOMElement**) override;
NS_IMETHOD GetNestedFrameId(uint64_t*) override;
NS_IMETHOD IsAppOfType(uint32_t, bool*) override;
NS_IMETHOD GetIsContent(bool*) override;
NS_IMETHOD GetUsePrivateBrowsing(bool*) override;
NS_IMETHOD SetUsePrivateBrowsing(bool) override;
@ -296,9 +295,10 @@ private:
friend void mozilla::TimelineConsumers::AddConsumer(nsDocShell*);
friend void mozilla::TimelineConsumers::RemoveConsumer(nsDocShell*);
friend void mozilla::TimelineConsumers::AddMarkerForDocShell(
nsDocShell*, const char*, MarkerTracingType);
nsDocShell*, const char*, MarkerTracingType, MarkerStackRequest);
friend void mozilla::TimelineConsumers::AddMarkerForDocShell(
nsDocShell*, const char*, const TimeStamp&, MarkerTracingType);
nsDocShell*, const char*, const TimeStamp&, MarkerTracingType,
MarkerStackRequest);
friend void mozilla::TimelineConsumers::AddMarkerForDocShell(
nsDocShell*, UniquePtr<AbstractTimelineMarker>&&);
friend void mozilla::TimelineConsumers::PopMarkers(nsDocShell*,

View File

@ -132,8 +132,35 @@ interface nsIDocShell : nsIDocShellTreeItem
* ignored.
* @param aReferrer - Referring URI
* @param aReferrerPolicy - Referrer policy
* @param aTriggeringPrincipal - Principal that initiated that load
* @param aPrincipalToInherit - Principal to be inherited for that load
* @param aTriggeringPrincipal - Principal that initiated that load. If passing
* null for this argument, then internally a
* principal is created from aReferrer. If
* aReferrer is also null, then the
* triggeringPrincipal defaults to the
* SystemPrincipal. Please note that this is the
* principal that is used for security checks. If
* the argument aURI is provided by the web, then
* please pass an explicit triggeringPrincipal to
* avoid the fallback to SystemPrincipal and
* hence a potential security risk.
* If aTriggeringPrincipal is null then either
* aPrincipalToInherit is null or it's
* a NullPrincipal.
* @param aPrincipalToInherit - Principal to be inherited for that load. If
* passing null for this argument, then internally
* the triggeringPrincipal is also used for the
* principalToInherit. There are cases where those
* two principals need to be different though.
* E.g. the system might initiate a load for
* 'about:blank', hence SystemPrincipal is passed
* for aTriggeringPrincipal. But the principal to
* be inherited for that load should be a
* NullPrincipal and not the SystemPrincipal.
* In that case, please pass a non null
* principalToInherit.
* If aPrincipalToInherit is null then either
* aTriggeringPrincipal is null or
* INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL is set.
* @param aFlags - Any of the load flags defined within above.
* @param aStopActiveDoc - Flag indicating whether loading the current
* document should be stopped.

View File

@ -60,17 +60,6 @@ interface nsILoadContext : nsISupports
*/
readonly attribute unsigned long long nestedFrameId;
/**
* Check whether the load is happening in a particular type of application.
*
* @param an application type. For now, the constants to be passed here are
* the nsIDocShell APP_TYPE_* constants.
*
* @return whether there is some ancestor of the associatedWindow that is of
* the given app type.
*/
boolean isAppOfType(in unsigned long appType);
/**
* True if the load context is content (as opposed to chrome). This is
* determined based on the type of window the load is performed in, NOT based

View File

@ -173,11 +173,12 @@ TimelineConsumers::IsEmpty()
void
TimelineConsumers::AddMarkerForDocShell(nsDocShell* aDocShell,
const char* aName,
MarkerTracingType aTracingType)
MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest)
{
MOZ_ASSERT(NS_IsMainThread());
if (HasConsumer(aDocShell)) {
aDocShell->mObserved->AddMarker(Move(MakeUnique<TimelineMarker>(aName, aTracingType)));
aDocShell->mObserved->AddMarker(Move(MakeUnique<TimelineMarker>(aName, aTracingType, aStackRequest)));
}
}
@ -185,11 +186,12 @@ void
TimelineConsumers::AddMarkerForDocShell(nsDocShell* aDocShell,
const char* aName,
const TimeStamp& aTime,
MarkerTracingType aTracingType)
MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest)
{
MOZ_ASSERT(NS_IsMainThread());
if (HasConsumer(aDocShell)) {
aDocShell->mObserved->AddMarker(Move(MakeUnique<TimelineMarker>(aName, aTime, aTracingType)));
aDocShell->mObserved->AddMarker(Move(MakeUnique<TimelineMarker>(aName, aTime, aTracingType, aStackRequest)));
}
}
@ -206,20 +208,22 @@ TimelineConsumers::AddMarkerForDocShell(nsDocShell* aDocShell,
void
TimelineConsumers::AddMarkerForDocShell(nsIDocShell* aDocShell,
const char* aName,
MarkerTracingType aTracingType)
MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest)
{
MOZ_ASSERT(NS_IsMainThread());
AddMarkerForDocShell(static_cast<nsDocShell*>(aDocShell), aName, aTracingType);
AddMarkerForDocShell(static_cast<nsDocShell*>(aDocShell), aName, aTracingType, aStackRequest);
}
void
TimelineConsumers::AddMarkerForDocShell(nsIDocShell* aDocShell,
const char* aName,
const TimeStamp& aTime,
MarkerTracingType aTracingType)
MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest)
{
MOZ_ASSERT(NS_IsMainThread());
AddMarkerForDocShell(static_cast<nsDocShell*>(aDocShell), aName, aTime, aTracingType);
AddMarkerForDocShell(static_cast<nsDocShell*>(aDocShell), aName, aTime, aTracingType, aStackRequest);
}
void

View File

@ -71,19 +71,23 @@ public:
// Main thread only.
void AddMarkerForDocShell(nsDocShell* aDocShell,
const char* aName,
MarkerTracingType aTracingType);
MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest = MarkerStackRequest::STACK);
void AddMarkerForDocShell(nsIDocShell* aDocShell,
const char* aName,
MarkerTracingType aTracingType);
MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest = MarkerStackRequest::STACK);
void AddMarkerForDocShell(nsDocShell* aDocShell,
const char* aName,
const TimeStamp& aTime,
MarkerTracingType aTracingType);
MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest = MarkerStackRequest::STACK);
void AddMarkerForDocShell(nsIDocShell* aDocShell,
const char* aName,
const TimeStamp& aTime,
MarkerTracingType aTracingType);
MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest = MarkerStackRequest::STACK);
// These methods register and receive ownership of an already created marker,
// relevant for a specific docshell.

View File

@ -157,10 +157,6 @@ this.AppsUtils = {
usePrivateBrowsing: false,
isContent: false,
isAppOfType: function(appType) {
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsILoadContext,
Ci.nsIInterfaceRequestor,
Ci.nsISupports]),

View File

@ -4,9 +4,9 @@
* 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/. */
#include "mozilla/dom/CustomElementsRegistry.h"
#include "mozilla/dom/CustomElementRegistry.h"
#include "mozilla/dom/CustomElementsRegistryBinding.h"
#include "mozilla/dom/CustomElementRegistryBinding.h"
#include "mozilla/dom/HTMLElementBinding.h"
#include "mozilla/dom/WebComponentsBinding.h"
#include "nsIParserService.h"
@ -99,16 +99,16 @@ CustomElementData::RunCallbackQueue()
}
// Only needed for refcounted objects.
NS_IMPL_CYCLE_COLLECTION_CLASS(CustomElementsRegistry)
NS_IMPL_CYCLE_COLLECTION_CLASS(CustomElementRegistry)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CustomElementsRegistry)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CustomElementRegistry)
tmp->mCustomDefinitions.Clear();
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWhenDefinedPromiseMap)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CustomElementsRegistry)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CustomElementRegistry)
for (auto iter = tmp->mCustomDefinitions.Iter(); !iter.Done(); iter.Next()) {
nsAutoPtr<LifecycleCallbacks>& callbacks = iter.UserData()->mCallbacks;
@ -141,7 +141,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CustomElementsRegistry)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(CustomElementsRegistry)
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(CustomElementRegistry)
for (auto iter = tmp->mCustomDefinitions.Iter(); !iter.Done(); iter.Next()) {
aCallbacks.Trace(&iter.UserData()->mConstructor,
"mCustomDefinitions constructor",
@ -153,16 +153,16 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(CustomElementsRegistry)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(CustomElementsRegistry)
NS_IMPL_CYCLE_COLLECTING_RELEASE(CustomElementsRegistry)
NS_IMPL_CYCLE_COLLECTING_ADDREF(CustomElementRegistry)
NS_IMPL_CYCLE_COLLECTING_RELEASE(CustomElementRegistry)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CustomElementsRegistry)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CustomElementRegistry)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
/* static */ bool
CustomElementsRegistry::IsCustomElementsEnabled(JSContext* aCx, JSObject* aObject)
CustomElementRegistry::IsCustomElementEnabled(JSContext* aCx, JSObject* aObject)
{
JS::Rooted<JSObject*> obj(aCx, aObject);
if (Preferences::GetBool("dom.webcomponents.customelements.enabled") ||
@ -173,8 +173,8 @@ CustomElementsRegistry::IsCustomElementsEnabled(JSContext* aCx, JSObject* aObjec
return false;
}
/* static */ already_AddRefed<CustomElementsRegistry>
CustomElementsRegistry::Create(nsPIDOMWindowInner* aWindow)
/* static */ already_AddRefed<CustomElementRegistry>
CustomElementRegistry::Create(nsPIDOMWindowInner* aWindow)
{
MOZ_ASSERT(aWindow);
MOZ_ASSERT(aWindow->IsInnerWindow());
@ -188,13 +188,13 @@ CustomElementsRegistry::Create(nsPIDOMWindowInner* aWindow)
return nullptr;
}
RefPtr<CustomElementsRegistry> customElementsRegistry =
new CustomElementsRegistry(aWindow);
return customElementsRegistry.forget();
RefPtr<CustomElementRegistry> customElementRegistry =
new CustomElementRegistry(aWindow);
return customElementRegistry.forget();
}
/* static */ void
CustomElementsRegistry::ProcessTopElementQueue()
CustomElementRegistry::ProcessTopElementQueue()
{
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
@ -222,15 +222,15 @@ CustomElementsRegistry::ProcessTopElementQueue()
}
/* static */ void
CustomElementsRegistry::XPCOMShutdown()
CustomElementRegistry::XPCOMShutdown()
{
sProcessingStack.reset();
}
/* static */ Maybe<nsTArray<RefPtr<CustomElementData>>>
CustomElementsRegistry::sProcessingStack;
CustomElementRegistry::sProcessingStack;
CustomElementsRegistry::CustomElementsRegistry(nsPIDOMWindowInner* aWindow)
CustomElementRegistry::CustomElementRegistry(nsPIDOMWindowInner* aWindow)
: mWindow(aWindow)
, mIsCustomDefinitionRunning(false)
{
@ -243,14 +243,14 @@ CustomElementsRegistry::CustomElementsRegistry(nsPIDOMWindowInner* aWindow)
}
}
CustomElementsRegistry::~CustomElementsRegistry()
CustomElementRegistry::~CustomElementRegistry()
{
mozilla::DropJSObjects(this);
}
CustomElementDefinition*
CustomElementsRegistry::LookupCustomElementDefinition(const nsAString& aLocalName,
const nsAString* aIs) const
CustomElementRegistry::LookupCustomElementDefinition(const nsAString& aLocalName,
const nsAString* aIs) const
{
nsCOMPtr<nsIAtom> localNameAtom = NS_Atomize(aLocalName);
nsCOMPtr<nsIAtom> typeAtom = aIs ? NS_Atomize(*aIs) : localNameAtom;
@ -264,7 +264,7 @@ CustomElementsRegistry::LookupCustomElementDefinition(const nsAString& aLocalNam
}
void
CustomElementsRegistry::RegisterUnresolvedElement(Element* aElement, nsIAtom* aTypeName)
CustomElementRegistry::RegisterUnresolvedElement(Element* aElement, nsIAtom* aTypeName)
{
mozilla::dom::NodeInfo* info = aElement->NodeInfo();
@ -289,8 +289,8 @@ CustomElementsRegistry::RegisterUnresolvedElement(Element* aElement, nsIAtom* aT
}
void
CustomElementsRegistry::SetupCustomElement(Element* aElement,
const nsAString* aTypeExtension)
CustomElementRegistry::SetupCustomElement(Element* aElement,
const nsAString* aTypeExtension)
{
nsCOMPtr<nsIAtom> tagAtom = aElement->NodeInfo()->NameAtom();
nsCOMPtr<nsIAtom> typeAtom = aTypeExtension ?
@ -326,10 +326,10 @@ CustomElementsRegistry::SetupCustomElement(Element* aElement,
}
void
CustomElementsRegistry::EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
Element* aCustomElement,
LifecycleCallbackArgs* aArgs,
CustomElementDefinition* aDefinition)
CustomElementRegistry::EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
Element* aCustomElement,
LifecycleCallbackArgs* aArgs,
CustomElementDefinition* aDefinition)
{
CustomElementData* elementData = aCustomElement->GetCustomElementData();
@ -443,15 +443,15 @@ CustomElementsRegistry::EnqueueLifecycleCallback(nsIDocument::ElementCallbackTyp
// Create a script runner to process the top of the processing
// stack as soon as it is safe to run script.
nsCOMPtr<nsIRunnable> runnable =
NS_NewRunnableFunction(&CustomElementsRegistry::ProcessTopElementQueue);
NS_NewRunnableFunction(&CustomElementRegistry::ProcessTopElementQueue);
nsContentUtils::AddScriptRunner(runnable);
}
}
}
void
CustomElementsRegistry::GetCustomPrototype(nsIAtom* aAtom,
JS::MutableHandle<JSObject*> aPrototype)
CustomElementRegistry::GetCustomPrototype(nsIAtom* aAtom,
JS::MutableHandle<JSObject*> aPrototype)
{
mozilla::dom::CustomElementDefinition* definition = mCustomDefinitions.Get(aAtom);
if (definition) {
@ -462,9 +462,9 @@ CustomElementsRegistry::GetCustomPrototype(nsIAtom* aAtom,
}
void
CustomElementsRegistry::UpgradeCandidates(JSContext* aCx,
nsIAtom* aKey,
CustomElementDefinition* aDefinition)
CustomElementRegistry::UpgradeCandidates(JSContext* aCx,
nsIAtom* aKey,
CustomElementDefinition* aDefinition)
{
nsAutoPtr<nsTArray<nsWeakPtr>> candidates;
mCandidatesMap.RemoveAndForget(aKey, candidates);
@ -509,12 +509,12 @@ CustomElementsRegistry::UpgradeCandidates(JSContext* aCx,
}
JSObject*
CustomElementsRegistry::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
CustomElementRegistry::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return CustomElementsRegistryBinding::Wrap(aCx, this, aGivenProto);
return CustomElementRegistryBinding::Wrap(aCx, this, aGivenProto);
}
nsISupports* CustomElementsRegistry::GetParentObject() const
nsISupports* CustomElementRegistry::GetParentObject() const
{
return mWindow;
}
@ -558,10 +558,10 @@ CheckLifeCycleCallbacks(JSContext* aCx,
// https://html.spec.whatwg.org/multipage/scripting.html#element-definition
void
CustomElementsRegistry::Define(const nsAString& aName,
Function& aFunctionConstructor,
const ElementDefinitionOptions& aOptions,
ErrorResult& aRv)
CustomElementRegistry::Define(const nsAString& aName,
Function& aFunctionConstructor,
const ElementDefinitionOptions& aOptions,
ErrorResult& aRv)
{
aRv.MightThrowJSException();
@ -589,7 +589,7 @@ CustomElementsRegistry::Define(const nsAString& aName,
}
if (!JS::IsConstructor(constructorUnwrapped)) {
aRv.ThrowTypeError<MSG_NOT_CONSTRUCTOR>(NS_LITERAL_STRING("Argument 2 of CustomElementsRegistry.define"));
aRv.ThrowTypeError<MSG_NOT_CONSTRUCTOR>(NS_LITERAL_STRING("Argument 2 of CustomElementRegistry.define"));
return;
}
@ -604,7 +604,7 @@ CustomElementsRegistry::Define(const nsAString& aName,
}
/**
* 3. If this CustomElementsRegistry contains an entry with name name, then
* 3. If this CustomElementRegistry contains an entry with name name, then
* throw a "NotSupportedError" DOMException and abort these steps.
*/
if (mCustomDefinitions.Get(nameAtom)) {
@ -613,7 +613,7 @@ CustomElementsRegistry::Define(const nsAString& aName,
}
/**
* 4. If this CustomElementsRegistry contains an entry with constructor constructor,
* 4. If this CustomElementRegistry contains an entry with constructor constructor,
* then throw a "NotSupportedError" DOMException and abort these steps.
*/
// TODO: Step 3 of HTMLConstructor also needs a way to look up definition by
@ -772,7 +772,7 @@ CustomElementsRegistry::Define(const nsAString& aName,
0 /* TODO dependent on HTML imports. Bug 877072 */);
/**
* 12. Add definition to this CustomElementsRegistry.
* 12. Add definition to this CustomElementRegistry.
*/
mCustomDefinitions.Put(nameAtom, definition);
@ -783,11 +783,11 @@ CustomElementsRegistry::Define(const nsAString& aName,
UpgradeCandidates(cx, nameAtom, definition);
/**
* 16. If this CustomElementsRegistry's when-defined promise map contains an
* 16. If this CustomElementRegistry's when-defined promise map contains an
* entry with key name:
* 1. Let promise be the value of that entry.
* 2. Resolve promise with undefined.
* 3. Delete the entry with key name from this CustomElementsRegistry's
* 3. Delete the entry with key name from this CustomElementRegistry's
* when-defined promise map.
*/
RefPtr<Promise> promise;
@ -799,8 +799,8 @@ CustomElementsRegistry::Define(const nsAString& aName,
}
void
CustomElementsRegistry::Get(JSContext* aCx, const nsAString& aName,
JS::MutableHandle<JS::Value> aRetVal)
CustomElementRegistry::Get(JSContext* aCx, const nsAString& aName,
JS::MutableHandle<JS::Value> aRetVal)
{
nsCOMPtr<nsIAtom> nameAtom(NS_Atomize(aName));
CustomElementDefinition* data = mCustomDefinitions.Get(nameAtom);
@ -815,7 +815,7 @@ CustomElementsRegistry::Get(JSContext* aCx, const nsAString& aName,
}
already_AddRefed<Promise>
CustomElementsRegistry::WhenDefined(const nsAString& aName, ErrorResult& aRv)
CustomElementRegistry::WhenDefined(const nsAString& aName, ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mWindow);
RefPtr<Promise> promise = Promise::Create(global, aRv);

View File

@ -4,8 +4,8 @@
* 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/. */
#ifndef mozilla_dom_CustomElementsRegistry_h
#define mozilla_dom_CustomElementsRegistry_h
#ifndef mozilla_dom_CustomElementRegistry_h
#define mozilla_dom_CustomElementRegistry_h
#include "js/TypeDecls.h"
#include "mozilla/Attributes.h"
@ -129,19 +129,19 @@ struct CustomElementDefinition
uint32_t mDocOrder;
};
class CustomElementsRegistry final : public nsISupports,
public nsWrapperCache
class CustomElementRegistry final : public nsISupports,
public nsWrapperCache
{
// Allow nsDocument to access mCustomDefinitions and mCandidatesMap.
friend class ::nsDocument;
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CustomElementsRegistry)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CustomElementRegistry)
public:
static bool IsCustomElementsEnabled(JSContext* aCx, JSObject* aObject);
static already_AddRefed<CustomElementsRegistry> Create(nsPIDOMWindowInner* aWindow);
static bool IsCustomElementEnabled(JSContext* aCx, JSObject* aObject);
static already_AddRefed<CustomElementRegistry> Create(nsPIDOMWindowInner* aWindow);
static void ProcessTopElementQueue();
static void XPCOMShutdown();
@ -169,8 +169,8 @@ public:
JS::MutableHandle<JSObject*> aPrototype);
private:
explicit CustomElementsRegistry(nsPIDOMWindowInner* aWindow);
~CustomElementsRegistry();
explicit CustomElementRegistry(nsPIDOMWindowInner* aWindow);
~CustomElementRegistry();
/**
* Registers an unresolved custom element that is a candidate for
@ -221,7 +221,7 @@ private:
private:
class MOZ_RAII AutoSetRunningFlag final {
public:
explicit AutoSetRunningFlag(CustomElementsRegistry* aRegistry)
explicit AutoSetRunningFlag(CustomElementRegistry* aRegistry)
: mRegistry(aRegistry)
{
MOZ_ASSERT(!mRegistry->mIsCustomDefinitionRunning,
@ -234,7 +234,7 @@ private:
}
private:
CustomElementsRegistry* mRegistry;
CustomElementRegistry* mRegistry;
};
public:
@ -255,4 +255,4 @@ public:
} // namespace mozilla
#endif // mozilla_dom_CustomElementsRegistry_h
#endif // mozilla_dom_CustomElementRegistry_h

View File

@ -2813,9 +2813,9 @@ Element::DescribeAttribute(uint32_t index, nsAString& aOutDescription) const
aOutDescription.AppendLiteral("=\"");
nsAutoString value;
mAttrsAndChildren.AttrAt(index)->ToString(value);
for (int i = value.Length(); i >= 0; --i) {
if (value[i] == char16_t('"'))
value.Insert(char16_t('\\'), uint32_t(i));
for (uint32_t i = value.Length(); i > 0; --i) {
if (value[i - 1] == char16_t('"'))
value.Insert(char16_t('\\'), i - 1);
}
aOutDescription.Append(value);
aOutDescription.Append('"');
@ -3723,7 +3723,8 @@ Element::InsertAdjacent(const nsAString& aWhere,
}
parent->InsertBefore(*aNode, this, aError);
} else if (aWhere.LowerCaseEqualsLiteral("afterbegin")) {
static_cast<nsINode*>(this)->InsertBefore(*aNode, GetFirstChild(), aError);
nsCOMPtr<nsINode> refNode = GetFirstChild();
static_cast<nsINode*>(this)->InsertBefore(*aNode, refNode, aError);
} else if (aWhere.LowerCaseEqualsLiteral("beforeend")) {
static_cast<nsINode*>(this)->AppendChild(*aNode, aError);
} else if (aWhere.LowerCaseEqualsLiteral("afterend")) {
@ -3731,7 +3732,8 @@ Element::InsertAdjacent(const nsAString& aWhere,
if (!parent) {
return nullptr;
}
parent->InsertBefore(*aNode, GetNextSibling(), aError);
nsCOMPtr<nsINode> refNode = GetNextSibling();
parent->InsertBefore(*aNode, refNode, aError);
} else {
aError.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return nullptr;

View File

@ -136,7 +136,7 @@ class EventStateManager;
namespace dom {
class Animation;
class CustomElementsRegistry;
class CustomElementRegistry;
class Link;
class UndoManager;
class DOMRect;
@ -427,7 +427,7 @@ private:
friend class ::nsFocusManager;
// Allow CusomtElementRegistry to call AddStates.
friend class CustomElementsRegistry;
friend class CustomElementRegistry;
// Also need to allow Link to call UpdateLinkState.
friend class Link;
@ -748,17 +748,15 @@ public:
aError.Throw(NS_ERROR_DOM_INVALID_POINTER_ERR);
return;
}
nsIPresShell::PointerCaptureInfo* pointerCaptureInfo = nullptr;
if (nsIPresShell::gPointerCaptureList->Get(aPointerId, &pointerCaptureInfo) &&
pointerCaptureInfo && pointerCaptureInfo->mPendingContent == this) {
if (HasPointerCapture(aPointerId)) {
nsIPresShell::ReleasePointerCapturingContent(aPointerId);
}
}
bool HasPointerCapture(long aPointerId)
{
nsIPresShell::PointerCaptureInfo* pointerCaptureInfo = nullptr;
if (nsIPresShell::gPointerCaptureList->Get(aPointerId, &pointerCaptureInfo) &&
pointerCaptureInfo && pointerCaptureInfo->mPendingContent == this) {
nsIPresShell::PointerCaptureInfo* pointerCaptureInfo =
nsIPresShell::GetPointerCaptureInfo(aPointerId);
if (pointerCaptureInfo && pointerCaptureInfo->mPendingContent == this) {
return true;
}
return false;

View File

@ -157,7 +157,7 @@ EXPORTS.mozilla.dom += [
'ChromeNodeList.h',
'ChromeUtils.h',
'Comment.h',
'CustomElementsRegistry.h',
'CustomElementRegistry.h',
'DirectionalityUtils.h',
'DocumentFragment.h',
'DocumentType.h',
@ -222,7 +222,7 @@ UNIFIED_SOURCES += [
'ChromeUtils.cpp',
'Comment.cpp',
'Crypto.cpp',
'CustomElementsRegistry.cpp',
'CustomElementRegistry.cpp',
'DirectionalityUtils.cpp',
'DocumentFragment.cpp',
'DocumentType.cpp',

View File

@ -38,7 +38,7 @@
#include "mozilla/DebugOnly.h"
#include "mozilla/LoadInfo.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/CustomElementsRegistry.h"
#include "mozilla/dom/CustomElementRegistry.h"
#include "mozilla/dom/DocumentFragment.h"
#include "mozilla/dom/DOMTypes.h"
#include "mozilla/dom/Element.h"
@ -67,6 +67,7 @@
#include "mozilla/Preferences.h"
#include "mozilla/dom/Selection.h"
#include "mozilla/TextEvents.h"
#include "nsArrayUtils.h"
#include "nsAString.h"
#include "nsAttrName.h"
#include "nsAttrValue.h"
@ -7693,11 +7694,11 @@ nsContentUtils::TransferableToIPCTransferable(nsITransferable* aTransferable,
MOZ_ASSERT((aChild && !aParent) || (!aChild && aParent));
if (aTransferable) {
nsCOMPtr<nsISupportsArray> flavorList;
nsCOMPtr<nsIArray> flavorList;
aTransferable->FlavorsTransferableCanExport(getter_AddRefs(flavorList));
if (flavorList) {
uint32_t flavorCount = 0;
flavorList->Count(&flavorCount);
flavorList->GetLength(&flavorCount);
for (uint32_t j = 0; j < flavorCount; ++j) {
nsCOMPtr<nsISupportsCString> flavor = do_QueryElementAt(flavorList, j);
if (!flavor) {
@ -9537,7 +9538,7 @@ nsContentUtils::LookupCustomElementDefinition(nsIDocument* aDoc,
return nullptr;
}
RefPtr<CustomElementsRegistry> registry(window->CustomElements());
RefPtr<CustomElementRegistry> registry(window->CustomElements());
if (!registry) {
return nullptr;
}
@ -9570,7 +9571,7 @@ nsContentUtils::SetupCustomElement(Element* aElement,
return;
}
RefPtr<CustomElementsRegistry> registry(window->CustomElements());
RefPtr<CustomElementRegistry> registry(window->CustomElements());
if (!registry) {
return;
}
@ -9599,7 +9600,7 @@ nsContentUtils::EnqueueLifecycleCallback(nsIDocument* aDoc,
return;
}
RefPtr<CustomElementsRegistry> registry(window->CustomElements());
RefPtr<CustomElementRegistry> registry(window->CustomElements());
if (!registry) {
return;
}
@ -9628,7 +9629,7 @@ nsContentUtils::GetCustomPrototype(nsIDocument* aDoc,
return;
}
RefPtr<CustomElementsRegistry> registry(window->CustomElements());
RefPtr<CustomElementRegistry> registry(window->CustomElements());
if (!registry) {
return;
}

View File

@ -219,8 +219,8 @@
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/UndoManager.h"
#include "mozilla/dom/WebComponentsBinding.h"
#include "mozilla/dom/CustomElementsRegistryBinding.h"
#include "mozilla/dom/CustomElementsRegistry.h"
#include "mozilla/dom/CustomElementRegistryBinding.h"
#include "mozilla/dom/CustomElementRegistry.h"
#include "nsFrame.h"
#include "nsDOMCaretPosition.h"
#include "nsIDOMHTMLTextAreaElement.h"
@ -5374,8 +5374,8 @@ bool IsLowercaseASCII(const nsAString& aValue)
return true;
}
already_AddRefed<mozilla::dom::CustomElementsRegistry>
nsDocument::GetCustomElementsRegistry()
already_AddRefed<mozilla::dom::CustomElementRegistry>
nsDocument::GetCustomElementRegistry()
{
nsAutoString contentType;
GetContentType(contentType);
@ -5391,7 +5391,7 @@ nsDocument::GetCustomElementsRegistry()
return nullptr;
}
RefPtr<CustomElementsRegistry> registry = window->CustomElements();
RefPtr<CustomElementRegistry> registry = window->CustomElements();
if (!registry) {
return nullptr;
}
@ -5690,7 +5690,7 @@ nsDocument::CustomElementConstructor(JSContext* aCx, unsigned aArgc, JS::Value*
return true;
}
RefPtr<mozilla::dom::CustomElementsRegistry> registry = window->CustomElements();
RefPtr<mozilla::dom::CustomElementRegistry> registry = window->CustomElements();
if (!registry) {
return true;
}
@ -5758,7 +5758,7 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& rv)
{
RefPtr<CustomElementsRegistry> registry(GetCustomElementsRegistry());
RefPtr<CustomElementRegistry> registry(GetCustomElementRegistry());
if (!registry) {
rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return;
@ -8812,7 +8812,10 @@ nsDocument::OnPageHide(bool aPersisted,
nullptr);
}
DispatchPageTransition(target, NS_LITERAL_STRING("pagehide"), aPersisted);
{
PageUnloadingEventTimeStamp timeStamp(this);
DispatchPageTransition(target, NS_LITERAL_STRING("pagehide"), aPersisted);
}
mVisible = false;

View File

@ -68,7 +68,7 @@
#include "jsfriendapi.h"
#include "ImportManager.h"
#include "mozilla/LinkedList.h"
#include "CustomElementsRegistry.h"
#include "CustomElementRegistry.h"
#define XML_DECLARATION_BITS_DECLARATION_EXISTS (1 << 0)
#define XML_DECLARATION_BITS_ENCODING_EXISTS (1 << 1)
@ -1364,8 +1364,8 @@ private:
ErrorResult& rv);
public:
virtual already_AddRefed<mozilla::dom::CustomElementsRegistry>
GetCustomElementsRegistry() override;
virtual already_AddRefed<mozilla::dom::CustomElementRegistry>
GetCustomElementRegistry() override;
static bool IsWebComponentsEnabled(JSContext* aCx, JSObject* aObject);

View File

@ -49,9 +49,7 @@
#include "mozilla/dom/Element.h"
#include "mozilla/dom/ShadowRoot.h"
#include "mozilla/dom/EncodingUtils.h"
#include "nsContainerFrame.h"
#include "nsBlockFrame.h"
#include "nsComputedDOMStyle.h"
#include "nsLayoutUtils.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -324,85 +322,6 @@ nsDocumentEncoder::IncludeInContext(nsINode *aNode)
return false;
}
static
bool
LineHasNonEmptyContentWorker(nsIFrame* aFrame)
{
// Look for non-empty frames, but ignore inline and br frames.
// For inline frames, descend into the children, if any.
if (aFrame->GetType() == nsGkAtoms::inlineFrame) {
for (nsIFrame* child : aFrame->PrincipalChildList()) {
if (LineHasNonEmptyContentWorker(child)) {
return true;
}
}
} else {
if (aFrame->GetType() != nsGkAtoms::brFrame &&
!aFrame->IsEmpty()) {
return true;
}
}
return false;
}
static
bool
LineHasNonEmptyContent(nsLineBox* aLine)
{
int32_t count = aLine->GetChildCount();
for (nsIFrame* frame = aLine->mFirstChild; count > 0;
--count, frame = frame->GetNextSibling()) {
if (LineHasNonEmptyContentWorker(frame)) {
return true;
}
}
return false;
}
static
bool
IsInvisibleBreak(nsINode *aNode)
{
if (!aNode->IsElement() || !aNode->IsEditable()) {
return false;
}
nsIFrame* frame = aNode->AsElement()->GetPrimaryFrame();
if (!frame || frame->GetType() != nsGkAtoms::brFrame) {
return false;
}
nsContainerFrame* f = frame->GetParent();
while (f && f->IsFrameOfType(nsBox::eLineParticipant)) {
f = f->GetParent();
}
nsBlockFrame* blockAncestor = do_QueryFrame(f);
if (!blockAncestor) {
// The container frame doesn't support line breaking.
return false;
}
bool valid = false;
nsBlockInFlowLineIterator iter(blockAncestor, frame, &valid);
if (!valid) {
return false;
}
bool lineNonEmpty = LineHasNonEmptyContent(iter.GetLine());
while (iter.Next()) {
auto currentLine = iter.GetLine();
// Completely skip empty lines.
if (!currentLine->IsEmpty()) {
// If we come across an inline line, the BR has caused a visible line break.
if (currentLine->IsInline()) {
return false;
}
}
}
return lineNonEmpty;
}
nsresult
nsDocumentEncoder::SerializeNodeStart(nsINode* aNode,
int32_t aStartOffset,
@ -437,7 +356,7 @@ nsDocumentEncoder::SerializeNodeStart(nsINode* aNode,
if (node->IsElement()) {
if ((mFlags & (nsIDocumentEncoder::OutputPreformatted |
nsIDocumentEncoder::OutputDropInvisibleBreak)) &&
IsInvisibleBreak(node)) {
nsLayoutUtils::IsInvisibleBreak(node)) {
return NS_OK;
}
Element* originalElement =

View File

@ -3799,12 +3799,12 @@ nsGlobalWindow::GetHistory(ErrorResult& aError)
return mHistory;
}
CustomElementsRegistry*
CustomElementRegistry*
nsGlobalWindow::CustomElements()
{
MOZ_RELEASE_ASSERT(IsInnerWindow());
if (!mCustomElements) {
mCustomElements = CustomElementsRegistry::Create(AsInner());
mCustomElements = CustomElementRegistry::Create(AsInner());
}
return mCustomElements;

View File

@ -105,7 +105,7 @@ class BarProp;
struct ChannelPixelLayout;
class Console;
class Crypto;
class CustomElementsRegistry;
class CustomElementRegistry;
class External;
class Function;
class Gamepad;
@ -812,7 +812,6 @@ public:
// Update the VR displays for this window
bool UpdateVRDisplays(nsTArray<RefPtr<mozilla::dom::VRDisplay>>& aDisplays);
// Inner windows only.
// Called to inform that the set of active VR displays has changed.
void NotifyActiveVRDisplaysChanged();
@ -887,7 +886,7 @@ public:
mozilla::dom::Location* GetLocation(mozilla::ErrorResult& aError);
nsIDOMLocation* GetLocation() override;
nsHistory* GetHistory(mozilla::ErrorResult& aError);
mozilla::dom::CustomElementsRegistry* CustomElements() override;
mozilla::dom::CustomElementRegistry* CustomElements() override;
mozilla::dom::BarProp* GetLocationbar(mozilla::ErrorResult& aError);
mozilla::dom::BarProp* GetMenubar(mozilla::ErrorResult& aError);
mozilla::dom::BarProp* GetPersonalbar(mozilla::ErrorResult& aError);
@ -1889,7 +1888,7 @@ protected:
uint32_t mTimeoutFiringDepth;
RefPtr<mozilla::dom::Location> mLocation;
RefPtr<nsHistory> mHistory;
RefPtr<mozilla::dom::CustomElementsRegistry> mCustomElements;
RefPtr<mozilla::dom::CustomElementRegistry> mCustomElements;
// These member variables are used on both inner and the outer windows.
nsCOMPtr<nsIPrincipal> mDocumentPrincipal;

View File

@ -33,6 +33,7 @@ using mozilla::dom::BlobImpl;
using mozilla::dom::MediaSource;
using mozilla::ErrorResult;
using mozilla::net::LoadInfo;
using mozilla::Move;
// -----------------------------------------------------------------------
// Hash table
@ -615,7 +616,7 @@ nsHostObjectProtocolHandler::RemoveDataEntry(const nsACString& aUri,
}
if (!info->mURIs.IsEmpty()) {
ReleasingTimerHolder::Create(Move(info->mURIs));
mozilla::ReleasingTimerHolder::Create(Move(info->mURIs));
}
gDataTable->Remove(aUri);

View File

@ -37,6 +37,7 @@
#include "mozilla/LinkedList.h"
#include "mozilla/StyleBackendType.h"
#include "mozilla/StyleSheet.h"
#include "mozilla/TimeStamp.h"
#include <bitset> // for member
#ifdef MOZILLA_INTERNAL_API
@ -216,6 +217,33 @@ public:
nsIDocument();
#endif
// This helper class must be set when we dispatch beforeunload and unload
// events in order to avoid unterminate sync XHRs.
class MOZ_RAII PageUnloadingEventTimeStamp
{
nsCOMPtr<nsIDocument> mDocument;
bool mSet;
public:
explicit PageUnloadingEventTimeStamp(nsIDocument* aDocument)
: mDocument(aDocument)
, mSet(false)
{
MOZ_ASSERT(aDocument);
if (mDocument->mPageUnloadingEventTimeStamp.IsNull()) {
mDocument->SetPageUnloadingEventTimeStamp();
mSet = true;
}
}
~PageUnloadingEventTimeStamp()
{
if (mSet) {
mDocument->CleanUnloadEventsTimeStamp();
}
}
};
/**
* Let the document know that we're starting to load data into it.
* @param aCommand The parser command. Must not be null.
@ -936,9 +964,40 @@ public:
nsresult GetOrCreateId(nsAString& aId);
void SetId(const nsAString& aId);
mozilla::TimeStamp GetPageUnloadingEventTimeStamp() const
{
if (!mParentDocument) {
return mPageUnloadingEventTimeStamp;
}
mozilla::TimeStamp parentTimeStamp(mParentDocument->GetPageUnloadingEventTimeStamp());
if (parentTimeStamp.IsNull()) {
return mPageUnloadingEventTimeStamp;
}
if (!mPageUnloadingEventTimeStamp ||
parentTimeStamp < mPageUnloadingEventTimeStamp) {
return parentTimeStamp;
}
return mPageUnloadingEventTimeStamp;
}
protected:
virtual Element *GetRootElementInternal() const = 0;
void SetPageUnloadingEventTimeStamp()
{
MOZ_ASSERT(!mPageUnloadingEventTimeStamp);
mPageUnloadingEventTimeStamp = mozilla::TimeStamp::NowLoRes();
}
void CleanUnloadEventsTimeStamp()
{
MOZ_ASSERT(mPageUnloadingEventTimeStamp);
mPageUnloadingEventTimeStamp = mozilla::TimeStamp();
}
private:
class SelectorCacheKey
{
@ -2515,8 +2574,8 @@ public:
const mozilla::dom::ElementRegistrationOptions& aOptions,
JS::MutableHandle<JSObject*> aRetval,
mozilla::ErrorResult& rv) = 0;
virtual already_AddRefed<mozilla::dom::CustomElementsRegistry>
GetCustomElementsRegistry() = 0;
virtual already_AddRefed<mozilla::dom::CustomElementRegistry>
GetCustomElementRegistry() = 0;
already_AddRefed<nsContentList>
GetElementsByTagName(const nsAString& aTagName)
@ -3242,6 +3301,8 @@ protected:
// Whether the user has interacted with the document or not:
bool mUserHasInteracted;
mozilla::TimeStamp mPageUnloadingEventTimeStamp;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocument, NS_IDOCUMENT_IID)

View File

@ -746,10 +746,17 @@ nsImageLoadingContent::LoadImage(const nsAString& aNewURI,
return NS_OK;
}
// Pending load/error events need to be canceled in some situations. This
// is not documented in the spec, but can cause site compat problems if not
// done. See bug 1309461 and https://github.com/whatwg/html/issues/1872.
CancelPendingEvent();
if (aNewURI.IsEmpty()) {
// Cancel image requests and then fire only error event per spec.
CancelImageRequests(aNotify);
FireEvent(NS_LITERAL_STRING("error"));
// Mark error event as cancelable only for src="" case, since only this
// error causes site compat problem (bug 1308069) for now.
FireEvent(NS_LITERAL_STRING("error"), true);
return NS_OK;
}
@ -781,6 +788,11 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
nsIDocument* aDocument,
nsLoadFlags aLoadFlags)
{
// Pending load/error events need to be canceled in some situations. This
// is not documented in the spec, but can cause site compat problems if not
// done. See bug 1309461 and https://github.com/whatwg/html/issues/1872.
CancelPendingEvent();
// Fire loadstart event if required
if (aLoadStart) {
FireEvent(NS_LITERAL_STRING("loadstart"));
@ -1143,7 +1155,7 @@ nsImageLoadingContent::StringToURI(const nsAString& aSpec,
}
nsresult
nsImageLoadingContent::FireEvent(const nsAString& aEventType)
nsImageLoadingContent::FireEvent(const nsAString& aEventType, bool aIsCancelable)
{
if (nsContentUtils::DocumentInactiveForImageLoads(GetOurOwnerDoc())) {
// Don't bother to fire any events, especially error events.
@ -1160,9 +1172,30 @@ nsImageLoadingContent::FireEvent(const nsAString& aEventType)
new LoadBlockingAsyncEventDispatcher(thisNode, aEventType, false, false);
loadBlockingAsyncDispatcher->PostDOMEvent();
if (aIsCancelable) {
mPendingEvent = loadBlockingAsyncDispatcher;
}
return NS_OK;
}
void
nsImageLoadingContent::AsyncEventRunning(AsyncEventDispatcher* aEvent)
{
if (mPendingEvent == aEvent) {
mPendingEvent = nullptr;
}
}
void
nsImageLoadingContent::CancelPendingEvent()
{
if (mPendingEvent) {
mPendingEvent->Cancel();
mPendingEvent = nullptr;
}
}
RefPtr<imgRequestProxy>&
nsImageLoadingContent::PrepareNextRequest(ImageLoadType aImageLoadType)
{

View File

@ -32,6 +32,10 @@ class nsPresContext;
class nsIContent;
class imgRequestProxy;
namespace mozilla {
class AsyncEventDispatcher;
} // namespace mozilla
#ifdef LoadImage
// Undefine LoadImage to prevent naming conflict with Windows.
#undef LoadImage
@ -213,6 +217,8 @@ protected:
// The nsContentPolicyType we would use for this ImageLoadType
static nsContentPolicyType PolicyTypeForLoad(ImageLoadType aImageLoadType);
void AsyncEventRunning(mozilla::AsyncEventDispatcher* aEvent);
private:
/**
* Struct used to manage the image observers.
@ -260,8 +266,16 @@ private:
*
* @param aEventType "loadstart", "loadend", "load", or "error" depending on
* how things went
* @param aIsCancelable true if event is cancelable.
*/
nsresult FireEvent(const nsAString& aEventType);
nsresult FireEvent(const nsAString& aEventType, bool aIsCancelable = false);
/**
* Method to cancel and null-out pending event if they exist.
*/
void CancelPendingEvent();
RefPtr<mozilla::AsyncEventDispatcher> mPendingEvent;
protected:
/**

View File

@ -45,7 +45,7 @@ class AudioContext;
class Element;
class Performance;
class ServiceWorkerRegistration;
class CustomElementsRegistry;
class CustomElementRegistry;
} // namespace dom
} // namespace mozilla
@ -95,7 +95,7 @@ public:
const nsPIDOMWindowOuter* AsOuter() const;
virtual nsPIDOMWindowOuter* GetPrivateRoot() = 0;
virtual mozilla::dom::CustomElementsRegistry* CustomElements() = 0;
virtual mozilla::dom::CustomElementRegistry* CustomElements() = 0;
// Outer windows only.
virtual void ActivateOrDeactivate(bool aActivate) = 0;

View File

@ -1419,7 +1419,8 @@ nsTreeSanitizer::SanitizeChildren(nsINode* aRoot)
nsCOMPtr<nsIContent> child; // Must keep the child alive during move
ErrorResult rv;
while ((child = node->GetFirstChild())) {
parent->InsertBefore(*child, node, rv);
nsCOMPtr<nsINode> refNode = node;
parent->InsertBefore(*child, refNode, rv);
if (rv.Failed()) {
break;
}

View File

@ -631,6 +631,7 @@ skip-if = buildapp == 'b2g'
[test_bug1281963.html]
[test_bug1295852.html]
[test_bug1307730.html]
[test_bug1308069.html]
[test_caretPositionFromPoint.html]
[test_change_policy.html]
skip-if = buildapp == 'b2g' #no ssl support

View File

@ -0,0 +1,87 @@
<!DOCTYPE html>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1308069
-->
<head>
<title>Bug 1308069</title>
<script 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=1308069">Mozilla Bug 1308069</a>
<script class="testbody" type="text/javascript">
function testClearPendingErrorEvent() {
return new Promise(function(aResolve, aReject) {
var hasErrorEvent = false;
var imgTarget = new Image();
var imgForChangingTargetSrc = new Image();
// Queue an error event for changing imgTarget's src.
imgForChangingTargetSrc.src = '';
imgForChangingTargetSrc.onerror = function() {
// This clears imgTarget's pending error event.
imgTarget.src = 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96"><path d="M10,10L32,90L90,32z" fill="lightgreen"/></svg>';
// Queue an error event for checking and resolving promise.
var imgForCheckingAndResolvingPromise = new Image();
imgForCheckingAndResolvingPromise.src = '';
imgForCheckingAndResolvingPromise.onerror = function() {
ok(!hasErrorEvent,
'Should not receive an error event since the pending error event ' +
'should be cleared before it fired');
aResolve();
};
};
// Setting src to empty string queues an error event.
imgTarget.src = '';
imgTarget.onerror = function() {
hasErrorEvent = true;
};
});
}
function testReplacePendingErrorEvent() {
return new Promise(function(aResolve) {
var numOfErrorEvent = 0;
var imgTarget = new Image();
var imgForChangingTargetSrc = new Image();
// Queue an error event for changing imgTarget's src.
imgForChangingTargetSrc.src = '';
imgForChangingTargetSrc.onerror = function() {
// This clears pending error event and fires a new one.
imgTarget.src = '';
// Queue an error event for checking and resolving promise.
var imgForCheckingAndResolvingPromise = new Image();
imgForCheckingAndResolvingPromise.src = '';
imgForCheckingAndResolvingPromise.onerror = function() {
is(numOfErrorEvent, 1,
'Should only receive one error event since the first pending error ' +
'event should be cleared before it fired');
aResolve();
};
};
// Setting src to empty string queues an error event.
imgTarget.src = '';
imgTarget.onerror = function() {
numOfErrorEvent++;
};
});
}
SimpleTest.waitForExplicitFinish();
Promise.resolve()
.then(() => testClearPendingErrorEvent())
.then(() => testReplacePendingErrorEvent())
.catch((err) => ok(false, "promise rejected: " + err))
.then(() => SimpleTest.finish());
</script>
</body>
</html>

View File

@ -1281,46 +1281,40 @@ FindEnumStringIndexImpl(const CharT* chars, size_t length, const EnumEntry* valu
}
template<bool InvalidValueFatal>
inline int
inline bool
FindEnumStringIndex(JSContext* cx, JS::Handle<JS::Value> v, const EnumEntry* values,
const char* type, const char* sourceDescription, bool* ok)
const char* type, const char* sourceDescription, int* index)
{
// JS_StringEqualsAscii is slow as molasses, so don't use it here.
JS::RootedString str(cx, JS::ToString(cx, v));
if (!str) {
*ok = false;
return 0;
return false;
}
{
int index;
size_t length;
JS::AutoCheckCannotGC nogc;
if (js::StringHasLatin1Chars(str)) {
const JS::Latin1Char* chars = JS_GetLatin1StringCharsAndLength(cx, nogc, str,
&length);
if (!chars) {
*ok = false;
return 0;
return false;
}
index = FindEnumStringIndexImpl(chars, length, values);
*index = FindEnumStringIndexImpl(chars, length, values);
} else {
const char16_t* chars = JS_GetTwoByteStringCharsAndLength(cx, nogc, str,
&length);
if (!chars) {
*ok = false;
return 0;
return false;
}
index = FindEnumStringIndexImpl(chars, length, values);
*index = FindEnumStringIndexImpl(chars, length, values);
}
if (index >= 0) {
*ok = true;
return index;
if (*index >= 0) {
return true;
}
}
*ok = EnumValueNotFound<InvalidValueFatal>(cx, str, type, sourceDescription);
return -1;
return EnumValueNotFound<InvalidValueFatal>(cx, str, type, sourceDescription);
}
inline nsWrapperCache*

View File

@ -5597,9 +5597,8 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
template = fill(
"""
{
bool ok;
int index = FindEnumStringIndex<${invalidEnumValueFatal}>(cx, $${val}, ${values}, "${enumtype}", "${sourceDescription}", &ok);
if (!ok) {
int index;
if (!FindEnumStringIndex<${invalidEnumValueFatal}>(cx, $${val}, ${values}, "${enumtype}", "${sourceDescription}", &index)) {
$*{exceptionCode}
}
$*{handleInvalidEnumValueCode}

View File

@ -1,9 +1,7 @@
[DEFAULT]
# Both the "inproc" and "oop" versions of OpenMixedProcess open remote frames,
# so we don't run that test on platforms which don't support OOP tests.
# OOP tests don't work on native-fennec (bug 774939).
# Bug 960345 - Disabled on OSX debug for frequent crashes.
skip-if = os == "android" || (toolkit == "cocoa" && debug) || buildapp == 'mulet' || (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) || e10s
skip-if = os == "android" || e10s
support-files =
browserElement_OpenMixedProcess.js
file_browserElement_ExecuteScript.html

View File

@ -4745,7 +4745,7 @@ var ctx = canvas.getContext('2d');
ctx.fillStyle = '#0f0';
try { ctx.fillStyle = 'hsl(0, 100%, 100%, 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
try { ctx.fillStyle = 'hsl(0, 100%, 100%,)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
ctx.fillRect(0, 0, 100, 50);
isPixel(ctx, 50,25, 0,255,0,255, 0);
@ -4874,7 +4874,7 @@ var ctx = canvas.getContext('2d');
ctx.fillStyle = '#0f0';
try { ctx.fillStyle = 'rgb(255.0, 0, 0)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
try { ctx.fillStyle = 'rgb(255.0, 0%, 0)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
ctx.fillRect(0, 0, 100, 50);
isPixel(ctx, 50,25, 0,255,0,255, 0);
@ -4896,7 +4896,7 @@ var ctx = canvas.getContext('2d');
ctx.fillStyle = '#0f0';
try { ctx.fillStyle = 'rgb(255, 0.0, 0)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
try { ctx.fillStyle = 'rgb(255%, 0.0, 0)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
ctx.fillRect(0, 0, 100, 50);
isPixel(ctx, 50,25, 0,255,0,255, 0);
@ -4962,7 +4962,7 @@ var ctx = canvas.getContext('2d');
ctx.fillStyle = '#0f0';
try { ctx.fillStyle = 'rgb(255 0 0)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
try { ctx.fillStyle = 'rgb(255, 0 0)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
ctx.fillRect(0, 0, 100, 50);
isPixel(ctx, 50,25, 0,255,0,255, 0);
@ -5006,7 +5006,7 @@ var ctx = canvas.getContext('2d');
ctx.fillStyle = '#0f0';
try { ctx.fillStyle = 'rgb(255, 0, 0, 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
try { ctx.fillStyle = 'rgb(255, 0, 0, 1,)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
ctx.fillRect(0, 0, 100, 50);
isPixel(ctx, 50,25, 0,255,0,255, 0);
@ -5028,7 +5028,7 @@ var ctx = canvas.getContext('2d');
ctx.fillStyle = '#0f0';
try { ctx.fillStyle = 'rgba(255, 0, 0)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
try { ctx.fillStyle = 'rgba(255, 0, 0,)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
ctx.fillRect(0, 0, 100, 50);
isPixel(ctx, 50,25, 0,255,0,255, 0);
@ -5050,7 +5050,7 @@ var ctx = canvas.getContext('2d');
ctx.fillStyle = '#0f0';
try { ctx.fillStyle = 'rgba(255.0, 0, 0, 1)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
try { ctx.fillStyle = 'rgba(255.0, 0, 0, 1,)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
ctx.fillRect(0, 0, 100, 50);
isPixel(ctx, 50,25, 0,255,0,255, 0);
@ -5094,7 +5094,7 @@ var ctx = canvas.getContext('2d');
ctx.fillStyle = '#0f0';
try { ctx.fillStyle = 'rgba(255, 0, 0, 100%)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
try { ctx.fillStyle = 'rgba(255, 0, 0, 100.%)'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does
ctx.fillRect(0, 0, 100, 50);
isPixel(ctx, 50,25, 0,255,0,255, 0);

View File

@ -39,6 +39,7 @@ AsyncEventDispatcher::Run()
if (mCanceled) {
return NS_OK;
}
mTarget->AsyncEventRunning(this);
RefPtr<Event> event = mEvent ? mEvent->InternalDOMEvent() : nullptr;
if (!event) {
event = NS_NewDOMEvent(mTarget, nullptr, nullptr);

View File

@ -16,6 +16,7 @@ class nsIGlobalObject;
namespace mozilla {
class AsyncEventDispatcher;
class ErrorResult;
class EventListenerManager;
@ -91,6 +92,9 @@ public:
*/
virtual EventListenerManager* GetExistingListenerManager() const = 0;
// Called from AsyncEventDispatcher to notify it is running.
virtual void AsyncEventRunning(AsyncEventDispatcher* aEvent) {}
virtual bool IsApzAware() const;
protected:

View File

@ -166,6 +166,12 @@ HTMLImageElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const
nsGenericHTMLElement::IsInteractiveHTMLContent(aIgnoreTabindex);
}
void
HTMLImageElement::AsyncEventRunning(AsyncEventDispatcher* aEvent)
{
nsImageLoadingContent::AsyncEventRunning(aEvent);
}
nsresult
HTMLImageElement::GetCurrentSrc(nsAString& aValue)
{

View File

@ -49,6 +49,9 @@ public:
// Element
virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override;
// EventTarget
virtual void AsyncEventRunning(AsyncEventDispatcher* aEvent) override;
// nsIDOMHTMLImageElement
NS_DECL_NSIDOMHTMLIMAGEELEMENT

View File

@ -3671,6 +3671,12 @@ HTMLInputElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const
nsGenericHTMLFormElementWithState::IsInteractiveHTMLContent(aIgnoreTabindex);
}
void
HTMLInputElement::AsyncEventRunning(AsyncEventDispatcher* aEvent)
{
nsImageLoadingContent::AsyncEventRunning(aEvent);
}
NS_IMETHODIMP
HTMLInputElement::Select()
{

View File

@ -142,6 +142,9 @@ public:
// Element
virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override;
// EventTarget
virtual void AsyncEventRunning(AsyncEventDispatcher* aEvent) override;
// nsIDOMHTMLInputElement
NS_DECL_NSIDOMHTMLINPUTELEMENT

View File

@ -59,6 +59,12 @@ HTMLObjectElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const
nsGenericHTMLFormElement::IsInteractiveHTMLContent(aIgnoreTabindex);
}
void
HTMLObjectElement::AsyncEventRunning(AsyncEventDispatcher* aEvent)
{
nsImageLoadingContent::AsyncEventRunning(aEvent);
}
bool
HTMLObjectElement::IsDoneAddingChildren()
{

View File

@ -48,6 +48,9 @@ public:
// Element
virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override;
// EventTarget
virtual void AsyncEventRunning(AsyncEventDispatcher* aEvent) override;
// nsIDOMHTMLObjectElement
NS_DECL_NSIDOMHTMLOBJECTELEMENT

View File

@ -587,7 +587,8 @@ HTMLSelectElement::Add(nsGenericHTMLElement& aElement,
// If the before parameter is not null, we are equivalent to the
// insertBefore method on the parent of before.
parent->InsertBefore(aElement, aBefore, aError);
nsCOMPtr<nsINode> refNode = aBefore;
parent->InsertBefore(aElement, refNode, aError);
}
NS_IMETHODIMP

View File

@ -108,6 +108,12 @@ HTMLSharedObjectElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
#endif // #ifdef XP_MACOSX
void
HTMLSharedObjectElement::AsyncEventRunning(AsyncEventDispatcher* aEvent)
{
nsImageLoadingContent::AsyncEventRunning(aEvent);
}
nsresult
HTMLSharedObjectElement::BindToTree(nsIDocument *aDocument,
nsIContent *aParent,

View File

@ -43,6 +43,9 @@ public:
// Can't use macro for nsIDOMHTMLEmbedElement because it has conflicts with
// NS_DECL_NSIDOMHTMLAPPLETELEMENT.
// EventTarget
virtual void AsyncEventRunning(AsyncEventDispatcher* aEvent) override;
// nsIDOMHTMLEmbedElement
NS_IMETHOD GetSrc(nsAString &aSrc) override;
NS_IMETHOD SetSrc(const nsAString &aSrc) override;

View File

@ -412,7 +412,8 @@ HTMLTableElement::CreateTHead()
}
ErrorResult rv;
nsINode::InsertBefore(*head, nsINode::GetFirstChild(), rv);
nsCOMPtr<nsINode> refNode = nsINode::GetFirstChild();
nsINode::InsertBefore(*head, refNode, rv);
}
return head.forget();
}
@ -503,7 +504,7 @@ HTMLTableElement::CreateTBody()
NS_NewHTMLTableSectionElement(nodeInfo.forget());
MOZ_ASSERT(newBody);
nsIContent* referenceNode = nullptr;
nsCOMPtr<nsIContent> referenceNode = nullptr;
for (nsIContent* child = nsINode::GetLastChild();
child;
child = child->GetPreviousSibling()) {
@ -615,7 +616,8 @@ HTMLTableElement::InsertRow(int32_t aIndex, ErrorResult& aError)
HTMLTableSectionElement* section =
static_cast<HTMLTableSectionElement*>(rowGroup.get());
nsIHTMLCollection* rows = section->Rows();
rowGroup->InsertBefore(*newRow, rows->Item(0), aError);
nsCOMPtr<nsINode> refNode = rows->Item(0);
rowGroup->InsertBefore(*newRow, refNode, aError);
}
}
}

View File

@ -59,7 +59,8 @@ public:
DeleteTHead();
if (aTHead) {
nsINode::InsertBefore(*aTHead, nsINode::GetFirstChild(), aError);
nsCOMPtr<nsINode> refNode = nsINode::GetFirstChild();
nsINode::InsertBefore(*aTHead, refNode, aError);
}
}
already_AddRefed<nsGenericHTMLElement> CreateTHead();

View File

@ -91,7 +91,8 @@ HTMLTableSectionElement::InsertRow(int32_t aIndex, ErrorResult& aError)
}
if (doInsert) {
nsINode::InsertBefore(*rowContent, rows->Item(aIndex), aError);
nsCOMPtr<nsINode> refNode = rows->Item(aIndex);
nsINode::InsertBefore(*rowContent, refNode, aError);
} else {
nsINode::AppendChild(*rowContent, aError);
}

View File

@ -443,7 +443,8 @@ UndoContentInsert::RedoTransaction()
}
IgnoredErrorResult error;
mContent->InsertBefore(*mChild, mNextNode, error);
nsCOMPtr<nsIContent> refNode = mNextNode;
mContent->InsertBefore(*mChild, refNode, error);
return NS_OK;
}
@ -537,7 +538,8 @@ UndoContentRemove::UndoTransaction()
}
IgnoredErrorResult error;
mContent->InsertBefore(*mChild, mNextNode, error);
nsCOMPtr<nsIContent> refNode = mNextNode;
mContent->InsertBefore(*mChild, refNode, error);
return NS_OK;
}

View File

@ -3098,10 +3098,16 @@ TabChild::DidRequestComposite(const TimeStamp& aCompositeReqStart,
RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
if (timelines && timelines->HasConsumer(docShell)) {
// Since we're assuming that it's impossible for content JS to directly
// trigger a synchronous paint, we can avoid capturing a stack trace here,
// which means we won't run into JS engine reentrancy issues like bug
// 1310014.
timelines->AddMarkerForDocShell(docShell,
"CompositeForwardTransaction", aCompositeReqStart, MarkerTracingType::START);
"CompositeForwardTransaction", aCompositeReqStart,
MarkerTracingType::START, MarkerStackRequest::NO_STACK);
timelines->AddMarkerForDocShell(docShell,
"CompositeForwardTransaction", aCompositeReqEnd, MarkerTracingType::END);
"CompositeForwardTransaction", aCompositeReqEnd,
MarkerTracingType::END, MarkerStackRequest::NO_STACK);
}
}

View File

@ -3189,7 +3189,6 @@ public:
return NS_OK;
}
NS_IMETHOD GetNestedFrameId(uint64_t*) NO_IMPL
NS_IMETHOD IsAppOfType(uint32_t, bool*) NO_IMPL
NS_IMETHOD GetIsContent(bool*) NO_IMPL
NS_IMETHOD GetUsePrivateBrowsing(bool*) NO_IMPL
NS_IMETHOD SetUsePrivateBrowsing(bool) NO_IMPL

View File

@ -98,6 +98,8 @@ PEColorNotColor=Expected color but found %1$S.
PEColorComponentEOF=color component
PEExpectedPercent=Expected a percentage but found %1$S.
PEExpectedInt=Expected an integer but found %1$S.
PEExpectedNumberOrAngle=Expected a number or an angle but found %1$S.
PEExpectedNumberOrPercent=Expected a number or a percentage but found %1$S.
PEColorBadRGBContents=Expected number or percentage in rgb() but found %1$S.
PEColorComponentBadTerm=Expected %2$S but found %1$S.
PEColorHueEOF=hue

View File

@ -30,19 +30,43 @@ var validThemeColors = [
'#f00',
'#ff0000',
'rgb(255,0,0)',
'rgb(255,0,0,1)',
'rgb(255,0,0,1.0)',
'rgb(255,0,0,100%)',
'rgb(255 0 0)',
'rgb(255 0 0 / 1)',
'rgb(255 0 0 / 1.0)',
'rgb(255 0 0 / 100%)',
'rgb(100%, 0%, 0%)',
'rgb(255,0,0)',
'rgb(100%, 0%, 0%, 1)',
'rgb(100%, 0%, 0%, 1.0)',
'rgb(100%, 0%, 0%, 100%)',
'rgb(100% 0% 0%)',
'rgb(100% 0% 0% / 1)',
'rgb(100%, 0%, 0%, 1.0)',
'rgb(100%, 0%, 0%, 100%)',
'rgb(300,0,0)',
'rgb(300 0 0)',
'rgb(255,-10,0)',
'rgb(110%, 0%, 0%)',
'rgb(255,0,0)',
'rgba(255,0,0)',
'rgba(255,0,0,1)',
'rgb(100%,0%,0%)',
'rgba(255 0 0 / 1)',
'rgba(100%,0%,0%,1)',
'rgba(0,0,255,0.5)',
'rgba(100%, 50%, 0%, 0.1)',
'hsl(120, 100%, 50%)',
'hsla(120, 100%, 50%, 1)',
'hsl(120 100% 50%)',
'hsl(120, 100%, 50%, 1.0)',
'hsl(120 100% 50% / 1.0)',
'hsla(120, 100%, 50%)',
'hsla(120 100% 50%)',
'hsla(120, 100%, 50%, 1.0)',
'hsla(120 100% 50% / 1.0)',
'hsl(120deg, 100%, 50%)',
'hsl(133.33333333grad, 100%, 50%)',
'hsl(2.0943951024rad, 100%, 50%)',
'hsl(0.3333333333turn, 100%, 50%)',
];
validThemeColors.forEach(background_color => {
@ -58,15 +82,15 @@ var invalidThemeColors = [
'marooon',
'f000000',
'#ff00000',
'rgb(255 0 0)',
'rgb(100, 0%, 0%)',
'rgb(255,0)',
'rgb(300 0 0)',
'rbg(255,-10,0)',
'rgb(110, 0%, 0%)',
'(255,0,0) }',
'rgba(255)',
' rgb(100%,0%,0%) }',
'hsl(120, 100%, 50)',
'hsl(120, 100%, 50.0)',
'hsl 120, 100%, 50%',
'hsla{120, 100%, 50%, 1}',
]

View File

@ -30,19 +30,43 @@ var validThemeColors = [
'#f00',
'#ff0000',
'rgb(255,0,0)',
'rgb(255,0,0,1)',
'rgb(255,0,0,1.0)',
'rgb(255,0,0,100%)',
'rgb(255 0 0)',
'rgb(255 0 0 / 1)',
'rgb(255 0 0 / 1.0)',
'rgb(255 0 0 / 100%)',
'rgb(100%, 0%, 0%)',
'rgb(255,0,0)',
'rgb(100%, 0%, 0%, 1)',
'rgb(100%, 0%, 0%, 1.0)',
'rgb(100%, 0%, 0%, 100%)',
'rgb(100% 0% 0%)',
'rgb(100% 0% 0% / 1)',
'rgb(100%, 0%, 0%, 1.0)',
'rgb(100%, 0%, 0%, 100%)',
'rgb(300,0,0)',
'rgb(300 0 0)',
'rgb(255,-10,0)',
'rgb(110%, 0%, 0%)',
'rgb(255,0,0)',
'rgba(255,0,0)',
'rgba(255,0,0,1)',
'rgb(100%,0%,0%)',
'rgba(255 0 0 / 1)',
'rgba(100%,0%,0%,1)',
'rgba(0,0,255,0.5)',
'rgba(100%, 50%, 0%, 0.1)',
'hsl(120, 100%, 50%)',
'hsla(120, 100%, 50%, 1)',
'hsl(120 100% 50%)',
'hsl(120, 100%, 50%, 1.0)',
'hsl(120 100% 50% / 1.0)',
'hsla(120, 100%, 50%)',
'hsla(120 100% 50%)',
'hsla(120, 100%, 50%, 1.0)',
'hsla(120 100% 50% / 1.0)',
'hsl(120deg, 100%, 50%)',
'hsl(133.33333333grad, 100%, 50%)',
'hsl(2.0943951024rad, 100%, 50%)',
'hsl(0.3333333333turn, 100%, 50%)',
];
validThemeColors.forEach(theme_color => {
@ -58,15 +82,15 @@ var invalidThemeColors = [
'marooon',
'f000000',
'#ff00000',
'rgb(255 0 0)',
'rgb(100, 0%, 0%)',
'rgb(255,0)',
'rgb(300 0 0)',
'rbg(255,-10,0)',
'rgb(110, 0%, 0%)',
'(255,0,0) }',
'rgba(255)',
' rgb(100%,0%,0%) }',
'hsl(120, 100%, 50)',
'hsl(120, 100%, 50.0)',
'hsl 120, 100%, 50%',
'hsla{120, 100%, 50%, 1}',
]

View File

@ -585,6 +585,32 @@ AudioCallbackDriver::~AudioCallbackDriver()
MOZ_ASSERT(mPromisesForOperation.IsEmpty());
}
bool IsMacbookOrMacbookAir()
{
#ifdef XP_MACOSX
size_t len = 0;
sysctlbyname("hw.model", NULL, &len, NULL, 0);
if (len) {
UniquePtr<char[]> model(new char[len]);
// This string can be
// MacBook%d,%d for a normal MacBook
// MacBookPro%d,%d for a MacBook Pro
// MacBookAir%d,%d for a Macbook Air
sysctlbyname("hw.model", model.get(), &len, NULL, 0);
char* substring = strstr(model.get(), "MacBook");
if (substring) {
const size_t offset = strlen("MacBook");
if (strncmp(model.get() + offset, "Air", len - offset) ||
isdigit(model[offset + 1])) {
return true;
}
}
return false;
}
#endif
return false;
}
void
AudioCallbackDriver::Init()
{
@ -638,6 +664,13 @@ AudioCallbackDriver::Init()
}
}
// Macbook and MacBook air don't have enough CPU to run very low latency
// MediaStreamGraphs, cap the minimal latency to 512 frames int this case.
if (IsMacbookOrMacbookAir()) {
latency_frames = std::max((uint32_t) 512, latency_frames);
}
input = output;
input.channels = mInputChannels; // change to support optional stereo capture

View File

@ -10,6 +10,7 @@
#include "mozilla/dom/MediaStreamTrack.h"
#include "GetUserMediaRequest.h"
#include "MediaStreamListener.h"
#include "nsArray.h"
#include "nsContentUtils.h"
#include "nsHashPropertyBag.h"
#ifdef MOZ_WIDGET_GONK
@ -20,7 +21,6 @@
#include "nsIScriptGlobalObject.h"
#include "nsIPermissionManager.h"
#include "nsIPopupWindowManager.h"
#include "nsISupportsArray.h"
#include "nsIDocShell.h"
#include "nsIDocument.h"
#include "nsISupportsPrimitives.h"
@ -2400,14 +2400,10 @@ if (privileged) {
return;
}
nsCOMPtr<nsISupportsArray> devicesCopy; // before we give up devices below
nsCOMPtr<nsIMutableArray> devicesCopy = nsArray::Create(); // before we give up devices below
if (!askPermission) {
nsresult rv = NS_NewISupportsArray(getter_AddRefs(devicesCopy));
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
for (auto& device : **devices) {
rv = devicesCopy->AppendElement(device);
nsresult rv = devicesCopy->AppendElement(device, /*weak =*/ false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
@ -3025,15 +3021,15 @@ MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
if (aSubject) {
// A particular device or devices were chosen by the user.
// NOTE: does not allow setting a device to null; assumes nullptr
nsCOMPtr<nsISupportsArray> array(do_QueryInterface(aSubject));
nsCOMPtr<nsIArray> array(do_QueryInterface(aSubject));
MOZ_ASSERT(array);
uint32_t len = 0;
array->Count(&len);
array->GetLength(&len);
bool videoFound = false, audioFound = false;
for (uint32_t i = 0; i < len; i++) {
nsCOMPtr<nsISupports> supports;
array->GetElementAt(i,getter_AddRefs(supports));
nsCOMPtr<nsIMediaDevice> device(do_QueryInterface(supports));
nsCOMPtr<nsIMediaDevice> device;
array->QueryElementAt(i, NS_GET_IID(nsIMediaDevice),
getter_AddRefs(device));
MOZ_ASSERT(device); // shouldn't be returning anything else...
if (device) {
nsString type;
@ -3127,14 +3123,11 @@ MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
}
nsresult
MediaManager::GetActiveMediaCaptureWindows(nsISupportsArray** aArray)
MediaManager::GetActiveMediaCaptureWindows(nsIArray** aArray)
{
MOZ_ASSERT(aArray);
nsISupportsArray* array;
nsresult rv = NS_NewISupportsArray(&array); // AddRefs
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIMutableArray> array = nsArray::Create();
for (auto iter = mActiveWindows.Iter(); !iter.Done(); iter.Next()) {
const uint64_t& id = iter.Key();
@ -3165,11 +3158,11 @@ MediaManager::GetActiveMediaCaptureWindows(nsISupportsArray** aArray)
}
}
if (capturing) {
array->AppendElement(window);
array->AppendElement(window, /*weak =*/ false);
}
}
*aArray = array;
array.forget(aArray);
return NS_OK;
}
@ -3328,14 +3321,14 @@ MediaManager::IterateWindowListeners(nsPIDOMWindowInner* aWindow,
void
MediaManager::StopMediaStreams()
{
nsCOMPtr<nsISupportsArray> array;
nsCOMPtr<nsIArray> array;
GetActiveMediaCaptureWindows(getter_AddRefs(array));
uint32_t len;
array->Count(&len);
array->GetLength(&len);
for (uint32_t i = 0; i < len; i++) {
nsCOMPtr<nsISupports> window;
array->GetElementAt(i, getter_AddRefs(window));
nsCOMPtr<nsPIDOMWindowInner> win(do_QueryInterface(window));
nsCOMPtr<nsPIDOMWindowInner> win;
array->QueryElementAt(i, NS_GET_IID(nsPIDOMWindowInner),
getter_AddRefs(win));
if (win) {
OnNavigation(win->WindowID());
}
@ -3347,14 +3340,14 @@ MediaManager::IsActivelyCapturingOrHasAPermission(uint64_t aWindowId)
{
// Does page currently have a gUM stream active?
nsCOMPtr<nsISupportsArray> array;
nsCOMPtr<nsIArray> array;
GetActiveMediaCaptureWindows(getter_AddRefs(array));
uint32_t len;
array->Count(&len);
array->GetLength(&len);
for (uint32_t i = 0; i < len; i++) {
nsCOMPtr<nsISupports> window;
array->GetElementAt(i, getter_AddRefs(window));
nsCOMPtr<nsPIDOMWindowInner> win(do_QueryInterface(window));
nsCOMPtr<nsPIDOMWindowInner> win;
array->QueryElementAt(i, NS_GET_IID(nsPIDOMWindowInner),
getter_AddRefs(win));
if (win && win->WindowID() == aWindowId) {
return true;
}

View File

@ -5,12 +5,12 @@
#include "MediaManager.h"
#include "MediaPermissionGonk.h"
#include "nsArray.h"
#include "nsCOMPtr.h"
#include "nsIContentPermissionPrompt.h"
#include "nsIDocument.h"
#include "nsIDOMNavigatorUserMedia.h"
#include "nsIStringEnumerator.h"
#include "nsISupportsArray.h"
#include "nsJSUtils.h"
#include "nsQueryObject.h"
#include "nsPIDOMWindow.h"
@ -67,12 +67,10 @@ static nsresult
NotifyPermissionAllow(const nsAString &aCallID, nsTArray<nsCOMPtr<nsIMediaDevice> > &aDevices)
{
nsresult rv;
nsCOMPtr<nsISupportsArray> array;
rv = NS_NewISupportsArray(getter_AddRefs(array));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIMutableArray> array = nsArray::Create();
for (uint32_t i = 0; i < aDevices.Length(); ++i) {
rv = array->AppendElement(aDevices.ElementAt(i));
rv = array->AppendElement(aDevices.ElementAt(i), /*weak =*/ false);
NS_ENSURE_SUCCESS(rv, rv);
}

View File

@ -65,11 +65,6 @@ MediaKeySystemAccessManager::Request(DetailedPromise* aPromise,
const nsAString& aKeySystem,
const Sequence<MediaKeySystemConfiguration>& aConfigs)
{
if (aKeySystem.IsEmpty() || aConfigs.IsEmpty()) {
aPromise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR,
NS_LITERAL_CSTRING("Invalid keysystem type or invalid options sequence"));
return;
}
Request(aPromise, aKeySystem, aConfigs, RequestType::Initial);
}

View File

@ -4,7 +4,7 @@
#include "nsISupports.idl"
interface nsISupportsArray;
interface nsIArray;
interface nsIDOMWindow;
%{C++
@ -16,7 +16,7 @@ interface nsIDOMWindow;
interface nsIMediaManagerService : nsISupports
{
/* return a array of inner windows that have active captures */
readonly attribute nsISupportsArray activeMediaCaptureWindows;
readonly attribute nsIArray activeMediaCaptureWindows;
/* Get the capture state for the given window and all descendant windows (iframes, etc) */
void mediaCaptureWindowState(in nsIDOMWindow aWindow, out boolean aVideo, out boolean aAudio,

View File

@ -131,7 +131,8 @@ DesktopNotification::PostDesktopNotification()
EmptyString(),
EmptyString(),
principal,
inPrivateBrowsing);
inPrivateBrowsing,
false /* requireInteraction */);
NS_ENSURE_SUCCESS(rv, rv);
return alerts->ShowAlert(alert, mObserver);
}

View File

@ -928,6 +928,21 @@ NotificationTask::Run()
return NS_OK;
}
bool
Notification::RequireInteractionEnabled(JSContext* aCx, JSObject* aOjb)
{
if (NS_IsMainThread()) {
return Preferences::GetBool("dom.webnotifications.requireinteraction.enabled", false);
}
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
if (!workerPrivate) {
return false;
}
return workerPrivate->DOMWorkerNotificationRIEnabled();
}
// static
bool
Notification::PrefEnabled(JSContext* aCx, JSObject* aObj)
@ -959,11 +974,13 @@ Notification::Notification(nsIGlobalObject* aGlobal, const nsAString& aID,
const nsAString& aTitle, const nsAString& aBody,
NotificationDirection aDir, const nsAString& aLang,
const nsAString& aTag, const nsAString& aIconUrl,
bool aRequireInteraction,
const NotificationBehavior& aBehavior)
: DOMEventTargetHelper(),
mWorkerPrivate(nullptr), mObserver(nullptr),
mID(aID), mTitle(aTitle), mBody(aBody), mDir(aDir), mLang(aLang),
mTag(aTag), mIconUrl(aIconUrl), mBehavior(aBehavior), mData(JS::NullValue()),
mTag(aTag), mIconUrl(aIconUrl), mRequireInteraction(aRequireInteraction),
mBehavior(aBehavior), mData(JS::NullValue()),
mIsClosed(false), mIsStored(false), mTaskCount(0)
{
if (NS_IsMainThread()) {
@ -1186,6 +1203,7 @@ Notification::CreateInternal(nsIGlobalObject* aGlobal,
aOptions.mLang,
aOptions.mTag,
aOptions.mIcon,
aOptions.mRequireInteraction,
aOptions.mMozbehavior);
rv = notification->Init();
NS_ENSURE_SUCCESS(rv, nullptr);
@ -1818,6 +1836,11 @@ Notification::ShowInternal()
uniqueCookie.AppendInt(sCount++);
bool inPrivateBrowsing = IsInPrivateBrowsing();
bool requireInteraction = mRequireInteraction;
if (!Preferences::GetBool("dom.webnotifications.requireinteraction.enabled", false)) {
requireInteraction = false;
}
nsAutoString alertName;
GetAlertName(alertName);
nsCOMPtr<nsIAlertNotification> alert =
@ -1831,7 +1854,8 @@ Notification::ShowInternal()
mLang,
mDataAsBase64,
GetPrincipal(),
inPrivateBrowsing);
inPrivateBrowsing,
requireInteraction);
NS_ENSURE_SUCCESS_VOID(rv);
if (isPersistent) {
@ -2361,6 +2385,12 @@ Notification::GetOrigin(nsIPrincipal* aPrincipal, nsString& aOrigin)
return NS_OK;
}
bool
Notification::RequireInteraction() const
{
return mRequireInteraction;
}
void
Notification::GetData(JSContext* aCx,
JS::MutableHandle<JS::Value> aRetval)
@ -2692,7 +2722,7 @@ Notification::ShowPersistentNotification(JSContext* aCx,
// which leads to uglier code.
NotificationPermission permission = GetPermission(aGlobal, aRv);
// "If permission for notifications origin is not "granted", reject promise with a TypeError exception, and terminate these substeps."
// "If permission for notification's origin is not "granted", reject promise with a TypeError exception, and terminate these substeps."
if (NS_WARN_IF(aRv.Failed()) || permission == NotificationPermission::Denied) {
ErrorResult result;
result.ThrowTypeError<MSG_NOTIFICATION_PERMISSION_DENIED>();

View File

@ -155,6 +155,7 @@ public:
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(Notification, DOMEventTargetHelper)
NS_DECL_NSIOBSERVER
static bool RequireInteractionEnabled(JSContext* aCx, JSObject* aObj);
static bool PrefEnabled(JSContext* aCx, JSObject* aObj);
// Returns if Notification.get() is allowed for the current global.
static bool IsGetEnabled(JSContext* aCx, JSObject* aObj);
@ -280,6 +281,8 @@ public:
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
bool RequireInteraction() const;
void GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval);
void InitFromJSVal(JSContext* aCx, JS::Handle<JS::Value> aData, ErrorResult& aRv);
@ -329,6 +332,7 @@ protected:
const nsAString& aTitle, const nsAString& aBody,
NotificationDirection aDir, const nsAString& aLang,
const nsAString& aTag, const nsAString& aIconUrl,
bool aRequireNotification,
const NotificationBehavior& aBehavior);
static already_AddRefed<Notification> CreateInternal(nsIGlobalObject* aGlobal,
@ -397,6 +401,7 @@ protected:
const nsString mLang;
const nsString mTag;
const nsString mIconUrl;
const bool mRequireInteraction;
nsString mDataAsBase64;
const NotificationBehavior mBehavior;

View File

@ -43,7 +43,7 @@ private:
virtual ~PresentationReceiver();
bool Init();
MOZ_IS_CLASS_INIT bool Init();
void Shutdown();

View File

@ -965,7 +965,8 @@ nsCSPContext::SendReports(nsISupports* aBlockedContentSource,
// wire in the string input stream to send the report
nsCOMPtr<nsIStringInputStream> sis(do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID));
NS_ASSERTION(sis, "nsIStringInputStream is needed but not available to send CSP violation reports");
rv = sis->SetData(NS_ConvertUTF16toUTF8(csp_report).get(), csp_report.Length());
nsAutoCString utf8CSPReport = NS_ConvertUTF16toUTF8(csp_report);
rv = sis->SetData(utf8CSPReport.get(), utf8CSPReport.Length());
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIUploadChannel> uploadChannel(do_QueryInterface(reportChannel));

View File

@ -121,7 +121,9 @@ function run_test() {
});
// test that eval violations cause a report.
makeTest(1, {"blocked-uri": "self"}, false,
makeTest(1, {"blocked-uri": "self",
// JSON script-sample is UTF8 encoded
"script-sample" : "\xc2\xa3\xc2\xa5\xc2\xb5\xe5\x8c\x97\xf0\xa0\x9d\xb9"}, false,
function(csp) {
let evalOK = true, oReportViolation = {'value': false};
evalOK = csp.getAllowsEval(oReportViolation);
@ -135,7 +137,10 @@ function run_test() {
// force the logging, since the getter doesn't.
csp.logViolationDetails(Ci.nsIContentSecurityPolicy.VIOLATION_TYPE_EVAL,
selfuri.asciiSpec,
"script sample",
// sending UTF-16 script sample to make sure
// csp report in JSON is not cut-off, please
// note that JSON is UTF8 encoded.
"\u00a3\u00a5\u00b5\u5317\ud841\udf79",
1);
}
});

View File

@ -94,6 +94,15 @@ SVGFEImageElement::LoadSVGImage(bool aForce, bool aNotify)
return LoadImage(href, aForce, aNotify, eImageLoadType_Normal);
}
//----------------------------------------------------------------------
// EventTarget methods:
void
SVGFEImageElement::AsyncEventRunning(AsyncEventDispatcher* aEvent)
{
nsImageLoadingContent::AsyncEventRunning(aEvent);
}
//----------------------------------------------------------------------
// nsIContent methods:

View File

@ -38,6 +38,9 @@ public:
// interfaces:
NS_DECL_ISUPPORTS_INHERITED
// EventTarget
virtual void AsyncEventRunning(AsyncEventDispatcher* aEvent) override;
virtual FilterPrimitiveDescription
GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
const IntRect& aFilterSubregion,

View File

@ -136,6 +136,15 @@ SVGImageElement::LoadSVGImage(bool aForce, bool aNotify)
return LoadImage(href, aForce, aNotify, eImageLoadType_Normal);
}
//----------------------------------------------------------------------
// EventTarget methods:
void
SVGImageElement::AsyncEventRunning(AsyncEventDispatcher* aEvent)
{
nsImageLoadingContent::AsyncEventRunning(aEvent);
}
//----------------------------------------------------------------------
// nsIContent methods:

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