mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 05:45:37 +00:00
Merge latest green b2g-inbound changeset and mozilla-central; a=merge
This commit is contained in:
commit
acd103862f
@ -9,9 +9,14 @@
|
|||||||
display: none;
|
display: none;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
box-shadow: 1px 1px 1px #444;
|
box-shadow: 1px 1px 1px #444;
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#virtual-cursor-inset {
|
#virtual-cursor-box.show {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#virtual-cursor-box > div {
|
||||||
border-radius: 1px;
|
border-radius: 1px;
|
||||||
box-shadow: inset 1px 1px 1px #444;
|
box-shadow: inset 1px 1px 1px #444;
|
||||||
display: block;
|
display: block;
|
||||||
|
@ -394,23 +394,19 @@ this.AccessFu = { // jshint ignore:line
|
|||||||
_processedMessageManagers: [],
|
_processedMessageManagers: [],
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adjusts the given bounds relative to the given browser. Converts from
|
* Adjusts the given bounds relative to the given browser.
|
||||||
* screen or device pixels to either device or CSS pixels.
|
|
||||||
* @param {Rect} aJsonBounds the bounds to adjust
|
* @param {Rect} aJsonBounds the bounds to adjust
|
||||||
* @param {browser} aBrowser the browser we want the bounds relative to
|
* @param {browser} aBrowser the browser we want the bounds relative to
|
||||||
* @param {bool} aToCSSPixels whether to convert to CSS pixels (as opposed to
|
* @param {bool} aToCSSPixels whether to convert to CSS pixels (as opposed to
|
||||||
* device pixels)
|
* device pixels)
|
||||||
* @param {bool} aFromDevicePixels whether to convert from device pixels (as
|
|
||||||
* opposed to screen pixels)
|
|
||||||
*/
|
*/
|
||||||
adjustContentBounds:
|
adjustContentBounds:
|
||||||
function(aJsonBounds, aBrowser, aToCSSPixels, aFromDevicePixels) {
|
function(aJsonBounds, aBrowser, aToCSSPixels) {
|
||||||
let bounds = new Rect(aJsonBounds.left, aJsonBounds.top,
|
let bounds = new Rect(aJsonBounds.left, aJsonBounds.top,
|
||||||
aJsonBounds.right - aJsonBounds.left,
|
aJsonBounds.right - aJsonBounds.left,
|
||||||
aJsonBounds.bottom - aJsonBounds.top);
|
aJsonBounds.bottom - aJsonBounds.top);
|
||||||
let win = Utils.win;
|
let win = Utils.win;
|
||||||
let dpr = win.devicePixelRatio;
|
let dpr = win.devicePixelRatio;
|
||||||
let vp = Utils.getViewport(win);
|
|
||||||
let offset = { left: -win.mozInnerScreenX, top: -win.mozInnerScreenY };
|
let offset = { left: -win.mozInnerScreenX, top: -win.mozInnerScreenY };
|
||||||
|
|
||||||
if (!aBrowser.contentWindow) {
|
if (!aBrowser.contentWindow) {
|
||||||
@ -421,16 +417,6 @@ this.AccessFu = { // jshint ignore:line
|
|||||||
offset.left += clientRect.left + win.mozInnerScreenX;
|
offset.left += clientRect.left + win.mozInnerScreenX;
|
||||||
offset.top += clientRect.top + win.mozInnerScreenY;
|
offset.top += clientRect.top + win.mozInnerScreenY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Here we scale from screen pixels to layout device pixels by dividing by
|
|
||||||
// the resolution (caused by pinch-zooming). The resolution is the
|
|
||||||
// viewport zoom divided by the devicePixelRatio. If there's no viewport,
|
|
||||||
// then we're on a platform without pinch-zooming and we can just ignore
|
|
||||||
// this.
|
|
||||||
if (!aFromDevicePixels && vp) {
|
|
||||||
bounds = bounds.scale(vp.zoom / dpr, vp.zoom / dpr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the offset; the offset is in CSS pixels, so multiply the
|
// Add the offset; the offset is in CSS pixels, so multiply the
|
||||||
// devicePixelRatio back in before adding to preserve unit consistency.
|
// devicePixelRatio back in before adding to preserve unit consistency.
|
||||||
bounds = bounds.translate(offset.left * dpr, offset.top * dpr);
|
bounds = bounds.translate(offset.left * dpr, offset.top * dpr);
|
||||||
@ -545,11 +531,10 @@ var Output = {
|
|||||||
highlightBox.id = 'virtual-cursor-box';
|
highlightBox.id = 'virtual-cursor-box';
|
||||||
|
|
||||||
// Add highlight inset for inner shadow
|
// Add highlight inset for inner shadow
|
||||||
let inset = Utils.win.document.
|
highlightBox.appendChild(
|
||||||
createElementNS('http://www.w3.org/1999/xhtml', 'div');
|
Utils.win.document.createElementNS(
|
||||||
inset.id = 'virtual-cursor-inset';
|
'http://www.w3.org/1999/xhtml', 'div'));
|
||||||
|
|
||||||
highlightBox.appendChild(inset);
|
|
||||||
this.highlightBox = Cu.getWeakReference(highlightBox);
|
this.highlightBox = Cu.getWeakReference(highlightBox);
|
||||||
} else {
|
} else {
|
||||||
highlightBox = this.highlightBox.get();
|
highlightBox = this.highlightBox.get();
|
||||||
@ -559,12 +544,12 @@ var Output = {
|
|||||||
let r = AccessFu.adjustContentBounds(aDetail.bounds, aBrowser, true);
|
let r = AccessFu.adjustContentBounds(aDetail.bounds, aBrowser, true);
|
||||||
|
|
||||||
// First hide it to avoid flickering when changing the style.
|
// First hide it to avoid flickering when changing the style.
|
||||||
highlightBox.style.display = 'none';
|
highlightBox.classList.remove('show');
|
||||||
highlightBox.style.top = (r.top - padding) + 'px';
|
highlightBox.style.top = (r.top - padding) + 'px';
|
||||||
highlightBox.style.left = (r.left - padding) + 'px';
|
highlightBox.style.left = (r.left - padding) + 'px';
|
||||||
highlightBox.style.width = (r.width + padding*2) + 'px';
|
highlightBox.style.width = (r.width + padding*2) + 'px';
|
||||||
highlightBox.style.height = (r.height + padding*2) + 'px';
|
highlightBox.style.height = (r.height + padding*2) + 'px';
|
||||||
highlightBox.style.display = 'block';
|
highlightBox.classList.add('show');
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -572,7 +557,7 @@ var Output = {
|
|||||||
{
|
{
|
||||||
let highlightBox = this.highlightBox ? this.highlightBox.get() : null;
|
let highlightBox = this.highlightBox ? this.highlightBox.get() : null;
|
||||||
if (highlightBox) {
|
if (highlightBox) {
|
||||||
highlightBox.style.display = 'none';
|
highlightBox.classList.remove('show');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -889,8 +874,7 @@ var Input = {
|
|||||||
activateContextMenu: function activateContextMenu(aDetails) {
|
activateContextMenu: function activateContextMenu(aDetails) {
|
||||||
if (Utils.MozBuildApp === 'mobile/android') {
|
if (Utils.MozBuildApp === 'mobile/android') {
|
||||||
let p = AccessFu.adjustContentBounds(aDetails.bounds,
|
let p = AccessFu.adjustContentBounds(aDetails.bounds,
|
||||||
Utils.CurrentBrowser,
|
Utils.CurrentBrowser, true).center();
|
||||||
true, true).center();
|
|
||||||
Services.obs.notifyObservers(null, 'Gesture:LongPress',
|
Services.obs.notifyObservers(null, 'Gesture:LongPress',
|
||||||
JSON.stringify({x: p.x, y: p.y}));
|
JSON.stringify({x: p.x, y: p.y}));
|
||||||
}
|
}
|
||||||
@ -915,8 +899,8 @@ var Input = {
|
|||||||
doScroll: function doScroll(aDetails) {
|
doScroll: function doScroll(aDetails) {
|
||||||
let horizontal = aDetails.horizontal;
|
let horizontal = aDetails.horizontal;
|
||||||
let page = aDetails.page;
|
let page = aDetails.page;
|
||||||
let p = AccessFu.adjustContentBounds(aDetails.bounds, Utils.CurrentBrowser,
|
let p = AccessFu.adjustContentBounds(
|
||||||
true, true).center();
|
aDetails.bounds, Utils.CurrentBrowser, true).center();
|
||||||
Utils.winUtils.sendWheelEvent(p.x, p.y,
|
Utils.winUtils.sendWheelEvent(p.x, p.y,
|
||||||
horizontal ? page : 0, horizontal ? 0 : page, 0,
|
horizontal ? page : 0, horizontal ? 0 : page, 0,
|
||||||
Utils.win.WheelEvent.DOM_DELTA_PAGE, 0, 0, 0, 0);
|
Utils.win.WheelEvent.DOM_DELTA_PAGE, 0, 0, 0, 0);
|
||||||
|
@ -255,15 +255,6 @@ this.Utils = { // jshint ignore:line
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getViewport: function getViewport(aWindow) {
|
|
||||||
switch (this.MozBuildApp) {
|
|
||||||
case 'mobile/android':
|
|
||||||
return aWindow.BrowserApp.selectedTab.getViewport();
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getState: function getState(aAccessibleOrEvent) {
|
getState: function getState(aAccessibleOrEvent) {
|
||||||
if (aAccessibleOrEvent instanceof Ci.nsIAccessibleStateChangeEvent) {
|
if (aAccessibleOrEvent instanceof Ci.nsIAccessibleStateChangeEvent) {
|
||||||
return new State(
|
return new State(
|
||||||
@ -302,18 +293,37 @@ this.Utils = { // jshint ignore:line
|
|||||||
return doc.QueryInterface(Ci.nsIAccessibleDocument).virtualCursor;
|
return doc.QueryInterface(Ci.nsIAccessibleDocument).virtualCursor;
|
||||||
},
|
},
|
||||||
|
|
||||||
getBounds: function getBounds(aAccessible) {
|
getContentResolution: function _getContentResolution(aAccessible) {
|
||||||
let objX = {}, objY = {}, objW = {}, objH = {};
|
let resX = { value: 1 }, resY = { value: 1 };
|
||||||
aAccessible.getBounds(objX, objY, objW, objH);
|
aAccessible.document.window.QueryInterface(
|
||||||
return new Rect(objX.value, objY.value, objW.value, objH.value);
|
Ci.nsIInterfaceRequestor).getInterface(
|
||||||
|
Ci.nsIDOMWindowUtils).getResolution(resX, resY);
|
||||||
|
return [resX.value, resY.value];
|
||||||
},
|
},
|
||||||
|
|
||||||
getTextBounds: function getTextBounds(aAccessible, aStart, aEnd) {
|
getBounds: function getBounds(aAccessible, aPreserveContentScale) {
|
||||||
let accText = aAccessible.QueryInterface(Ci.nsIAccessibleText);
|
let objX = {}, objY = {}, objW = {}, objH = {};
|
||||||
let objX = {}, objY = {}, objW = {}, objH = {};
|
aAccessible.getBounds(objX, objY, objW, objH);
|
||||||
accText.getRangeExtents(aStart, aEnd, objX, objY, objW, objH,
|
|
||||||
Ci.nsIAccessibleCoordinateType.COORDTYPE_SCREEN_RELATIVE);
|
let [scaleX, scaleY] = aPreserveContentScale ? [1, 1] :
|
||||||
return new Rect(objX.value, objY.value, objW.value, objH.value);
|
this.getContentResolution(aAccessible);
|
||||||
|
|
||||||
|
return new Rect(objX.value, objY.value, objW.value, objH.value).scale(
|
||||||
|
scaleX, scaleY);
|
||||||
|
},
|
||||||
|
|
||||||
|
getTextBounds: function getTextBounds(aAccessible, aStart, aEnd,
|
||||||
|
aPreserveContentScale) {
|
||||||
|
let accText = aAccessible.QueryInterface(Ci.nsIAccessibleText);
|
||||||
|
let objX = {}, objY = {}, objW = {}, objH = {};
|
||||||
|
accText.getRangeExtents(aStart, aEnd, objX, objY, objW, objH,
|
||||||
|
Ci.nsIAccessibleCoordinateType.COORDTYPE_SCREEN_RELATIVE);
|
||||||
|
|
||||||
|
let [scaleX, scaleY] = aPreserveContentScale ? [1, 1] :
|
||||||
|
this.getContentResolution(aAccessible);
|
||||||
|
|
||||||
|
return new Rect(objX.value, objY.value, objW.value, objH.value).scale(
|
||||||
|
scaleX, scaleY);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,14 +65,10 @@ function forwardToChild(aMessage, aListener, aVCPosition) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function activateContextMenu(aMessage) {
|
function activateContextMenu(aMessage) {
|
||||||
function sendContextMenuCoordinates(aAccessible) {
|
|
||||||
let bounds = Utils.getBounds(aAccessible);
|
|
||||||
sendAsyncMessage('AccessFu:ActivateContextMenu', {bounds: bounds});
|
|
||||||
}
|
|
||||||
|
|
||||||
let position = Utils.getVirtualCursor(content.document).position;
|
let position = Utils.getVirtualCursor(content.document).position;
|
||||||
if (!forwardToChild(aMessage, activateContextMenu, position)) {
|
if (!forwardToChild(aMessage, activateContextMenu, position)) {
|
||||||
sendContextMenuCoordinates(position);
|
sendAsyncMessage('AccessFu:ActivateContextMenu',
|
||||||
|
{ bounds: Utils.getBounds(position, true) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,16 +81,12 @@ function presentCaretChange(aText, aOldOffset, aNewOffset) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function scroll(aMessage) {
|
function scroll(aMessage) {
|
||||||
function sendScrollCoordinates(aAccessible) {
|
|
||||||
let bounds = Utils.getBounds(aAccessible);
|
|
||||||
sendAsyncMessage('AccessFu:DoScroll',
|
|
||||||
{ bounds: bounds,
|
|
||||||
page: aMessage.json.page,
|
|
||||||
horizontal: aMessage.json.horizontal });
|
|
||||||
}
|
|
||||||
|
|
||||||
let position = Utils.getVirtualCursor(content.document).position;
|
let position = Utils.getVirtualCursor(content.document).position;
|
||||||
if (!forwardToChild(aMessage, scroll, position)) {
|
if (!forwardToChild(aMessage, scroll, position)) {
|
||||||
|
sendAsyncMessage('AccessFu:DoScroll',
|
||||||
|
{ bounds: Utils.getBounds(position, true),
|
||||||
|
page: aMessage.json.page,
|
||||||
|
horizontal: aMessage.json.horizontal });
|
||||||
sendScrollCoordinates(position);
|
sendScrollCoordinates(position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -407,18 +407,18 @@ const nodeResolve = iced(function nodeResolve(id, requirer, { rootURI }) {
|
|||||||
let fullId = join(rootURI, id);
|
let fullId = join(rootURI, id);
|
||||||
|
|
||||||
let resolvedPath;
|
let resolvedPath;
|
||||||
if (resolvedPath = loadAsFile(fullId))
|
if ((resolvedPath = loadAsFile(fullId)))
|
||||||
return stripBase(rootURI, resolvedPath);
|
return stripBase(rootURI, resolvedPath);
|
||||||
else if (resolvedPath = loadAsDirectory(fullId))
|
else if ((resolvedPath = loadAsDirectory(fullId)))
|
||||||
return stripBase(rootURI, resolvedPath);
|
return stripBase(rootURI, resolvedPath);
|
||||||
// If manifest has dependencies, attempt to look up node modules
|
// If manifest has dependencies, attempt to look up node modules
|
||||||
// in the `dependencies` list
|
// in the `dependencies` list
|
||||||
else {
|
else {
|
||||||
let dirs = getNodeModulePaths(dirname(join(rootURI, requirer))).map(dir => join(dir, id));
|
let dirs = getNodeModulePaths(dirname(join(rootURI, requirer))).map(dir => join(dir, id));
|
||||||
for (let i = 0; i < dirs.length; i++) {
|
for (let i = 0; i < dirs.length; i++) {
|
||||||
if (resolvedPath = loadAsFile(dirs[i]))
|
if ((resolvedPath = loadAsFile(dirs[i])))
|
||||||
return stripBase(rootURI, resolvedPath);
|
return stripBase(rootURI, resolvedPath);
|
||||||
if (resolvedPath = loadAsDirectory(dirs[i]))
|
if ((resolvedPath = loadAsDirectory(dirs[i])))
|
||||||
return stripBase(rootURI, resolvedPath);
|
return stripBase(rootURI, resolvedPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -459,7 +459,7 @@ function loadAsDirectory (path) {
|
|||||||
let main = getManifestMain(JSON.parse(readURI(path + '/package.json')));
|
let main = getManifestMain(JSON.parse(readURI(path + '/package.json')));
|
||||||
if (main != null) {
|
if (main != null) {
|
||||||
let tmpPath = join(path, main);
|
let tmpPath = join(path, main);
|
||||||
if (found = loadAsFile(tmpPath))
|
if ((found = loadAsFile(tmpPath)))
|
||||||
return found
|
return found
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
@ -1201,8 +1201,7 @@ const kTransferContractId = "@mozilla.org/transfer;1";
|
|||||||
|
|
||||||
// Override Toolkit's nsITransfer implementation with the one from the
|
// Override Toolkit's nsITransfer implementation with the one from the
|
||||||
// JavaScript API for downloads. This will eventually be removed when
|
// JavaScript API for downloads. This will eventually be removed when
|
||||||
// nsIDownloadManager will not be available anymore (bug 851471). The
|
// nsIDownloadManager will not be available anymore (bug 851471).
|
||||||
// old code in this module will be removed in bug 899110.
|
|
||||||
Components.manager.QueryInterface(Ci.nsIComponentRegistrar)
|
Components.manager.QueryInterface(Ci.nsIComponentRegistrar)
|
||||||
.registerFactory(kTransferCid, "",
|
.registerFactory(kTransferCid, "",
|
||||||
kTransferContractId, null);
|
kTransferContractId, null);
|
||||||
|
@ -980,7 +980,11 @@ pref("browser.safebrowsing.reportMalwareURL", "http://%LOCALE%.malware-report.mo
|
|||||||
pref("browser.safebrowsing.reportMalwareErrorURL", "http://%LOCALE%.malware-error.mozilla.com/?hl=%LOCALE%");
|
pref("browser.safebrowsing.reportMalwareErrorURL", "http://%LOCALE%.malware-error.mozilla.com/?hl=%LOCALE%");
|
||||||
|
|
||||||
pref("browser.safebrowsing.malware.reportURL", "https://safebrowsing.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
|
pref("browser.safebrowsing.malware.reportURL", "https://safebrowsing.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
|
||||||
|
|
||||||
|
// Turn off remote lookups in beta and stable channel.
|
||||||
|
#ifndef RELEASE_BUILD
|
||||||
pref("browser.safebrowsing.appRepURL", "https://sb-ssl.google.com/safebrowsing/clientreport/download?key=%GOOGLE_API_KEY%");
|
pref("browser.safebrowsing.appRepURL", "https://sb-ssl.google.com/safebrowsing/clientreport/download?key=%GOOGLE_API_KEY%");
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef MOZILLA_OFFICIAL
|
#ifdef MOZILLA_OFFICIAL
|
||||||
// Normally the "client ID" sent in updates is appinfo.name, but for
|
// Normally the "client ID" sent in updates is appinfo.name, but for
|
||||||
|
@ -438,6 +438,13 @@ var gPopupBlockerObserver = {
|
|||||||
// Hide the icon in the location bar (if the location bar exists)
|
// Hide the icon in the location bar (if the location bar exists)
|
||||||
if (gURLBar)
|
if (gURLBar)
|
||||||
this._reportButton.hidden = true;
|
this._reportButton.hidden = true;
|
||||||
|
|
||||||
|
// Hide the notification box (if it's visible).
|
||||||
|
var notificationBox = gBrowser.getNotificationBox();
|
||||||
|
var notification = notificationBox.getNotificationWithValue("popup-blocked");
|
||||||
|
if (notification) {
|
||||||
|
notificationBox.removeNotification(notification, false);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,7 +293,14 @@ AppCacheUtils.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
clearAll: function ACU_clearAll() {
|
clearAll: function ACU_clearAll() {
|
||||||
Services.cache.evictEntries(Ci.nsICache.STORE_OFFLINE);
|
if (!Services.prefs.getBoolPref("browser.cache.disk.enable")) {
|
||||||
|
throw new Error(l10n.GetStringFromName("cacheDisabled"));
|
||||||
|
}
|
||||||
|
|
||||||
|
let appCacheStorage = Services.cache2.appCacheStorage(LoadContextInfo.default, null);
|
||||||
|
appCacheStorage.asyncEvictStorage({
|
||||||
|
onCacheEntryDoomed: function(result) {}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_getManifestURI: function ACU__getManifestURI() {
|
_getManifestURI: function ACU__getManifestURI() {
|
||||||
|
@ -15,7 +15,7 @@ let test = asyncTest(function*() {
|
|||||||
|
|
||||||
info("Creating the test document");
|
info("Creating the test document");
|
||||||
content.document.body.innerHTML = '<style type="text/css"> ' +
|
content.document.body.innerHTML = '<style type="text/css"> ' +
|
||||||
'span { font-variant: small-caps; color: #000000; } ' +
|
'span { font-variant-caps: small-caps; color: #000000; } ' +
|
||||||
'.nomatches {color: #ff0000;}</style> <div id="first" style="margin: 10em; ' +
|
'.nomatches {color: #ff0000;}</style> <div id="first" style="margin: 10em; ' +
|
||||||
'font-size: 14pt; font-family: helvetica, sans-serif; color: #AAA">\n' +
|
'font-size: 14pt; font-family: helvetica, sans-serif; color: #AAA">\n' +
|
||||||
'<h1>Some header text</h1>\n' +
|
'<h1>Some header text</h1>\n' +
|
||||||
@ -58,7 +58,7 @@ function checkCopySelection(view) {
|
|||||||
|
|
||||||
let expectedPattern = "font-family: helvetica,sans-serif;[\\r\\n]+" +
|
let expectedPattern = "font-family: helvetica,sans-serif;[\\r\\n]+" +
|
||||||
"font-size: 16px;[\\r\\n]+" +
|
"font-size: 16px;[\\r\\n]+" +
|
||||||
"font-variant: small-caps;[\\r\\n]*";
|
"font-variant-caps: small-caps;[\\r\\n]*";
|
||||||
|
|
||||||
return waitForClipboard(() => {
|
return waitForClipboard(() => {
|
||||||
fireCopyEvent(props[0]);
|
fireCopyEvent(props[0]);
|
||||||
@ -80,7 +80,7 @@ function checkSelectAll(view) {
|
|||||||
let expectedPattern = "color: #FF0;[\\r\\n]+" +
|
let expectedPattern = "color: #FF0;[\\r\\n]+" +
|
||||||
"font-family: helvetica,sans-serif;[\\r\\n]+" +
|
"font-family: helvetica,sans-serif;[\\r\\n]+" +
|
||||||
"font-size: 16px;[\\r\\n]+" +
|
"font-size: 16px;[\\r\\n]+" +
|
||||||
"font-variant: small-caps;[\\r\\n]*";
|
"font-variant-caps: small-caps;[\\r\\n]*";
|
||||||
|
|
||||||
return waitForClipboard(() => {
|
return waitForClipboard(() => {
|
||||||
fireCopyEvent(prop);
|
fireCopyEvent(prop);
|
||||||
|
@ -816,6 +816,7 @@ bin/libfreebl_32int64_3.so
|
|||||||
@BINPATH@/webapprt/components/PaymentUIGlue.js
|
@BINPATH@/webapprt/components/PaymentUIGlue.js
|
||||||
@BINPATH@/webapprt/components/components.manifest
|
@BINPATH@/webapprt/components/components.manifest
|
||||||
@BINPATH@/webapprt/defaults/preferences/prefs.js
|
@BINPATH@/webapprt/defaults/preferences/prefs.js
|
||||||
|
@BINPATH@/webapprt/modules/DownloadView.jsm
|
||||||
@BINPATH@/webapprt/modules/Startup.jsm
|
@BINPATH@/webapprt/modules/Startup.jsm
|
||||||
@BINPATH@/webapprt/modules/WebappRT.jsm
|
@BINPATH@/webapprt/modules/WebappRT.jsm
|
||||||
@BINPATH@/webapprt/modules/WebappManager.jsm
|
@BINPATH@/webapprt/modules/WebappManager.jsm
|
||||||
|
@ -28,12 +28,43 @@ leak:GI___strdup
|
|||||||
|
|
||||||
|
|
||||||
###
|
###
|
||||||
### Many leaks only affect some test suites. The suite annotations are not checked.
|
### Bug 979928 - WebRTC leaks. m2, m3.
|
||||||
###
|
###
|
||||||
|
|
||||||
# Bug 979928 - WebRTC is leaky. m2, m3
|
# WebRTC leaks added for Mochitest 2.
|
||||||
leak:/media/mtransport/
|
leak:NR_reg_init
|
||||||
leak:/media/webrtc/signaling/
|
leak:fsmdef_init
|
||||||
|
leak:r_log_register
|
||||||
|
leak:nr_reg_set
|
||||||
|
leak:ccsnap_device_init
|
||||||
|
leak:ccsnap_line_init
|
||||||
|
leak:media/webrtc/signaling/src/sipcc/core/common/init.c
|
||||||
|
leak:cprPostMessage
|
||||||
|
leak:mozilla::NrIceStunServer::Create
|
||||||
|
|
||||||
|
# Additional WebRTC leak suppressions added for Mochitest 3.
|
||||||
|
leak:mozilla::TransportLayerDtls::Setup
|
||||||
|
leak:mozilla::NrIceTurnServer::Create
|
||||||
|
# There are about 228KB of leaks from the call to |pmsg->sdp = cpr_malloc(sdp_size);|
|
||||||
|
# in send_message_helper.
|
||||||
|
leak:send_message_helper
|
||||||
|
leak:fsmdef_ev_createoffer
|
||||||
|
leak:fsmdef_ev_setremotedesc
|
||||||
|
leak:fsmdef_ev_setlocaldesc
|
||||||
|
leak:fsmdef_ev_createanswer
|
||||||
|
# About 70KB of leaks under this stack.
|
||||||
|
leak:vcmRxAllocICE_s
|
||||||
|
leak:vcmRxStartICE_m
|
||||||
|
# About 50KB of leaks under this stack.
|
||||||
|
leak:ccsnap_EscapeStrToLocaleStr
|
||||||
|
leak:gsmsdp_add_default_audio_formats_to_local_sdp
|
||||||
|
leak:gsmsdp_add_default_video_formats_to_local_sdp
|
||||||
|
leak:CCAPI_CallInfo_getMediaStreams
|
||||||
|
|
||||||
|
|
||||||
|
###
|
||||||
|
### Many leaks only affect some test suites. The suite annotations are not checked.
|
||||||
|
###
|
||||||
|
|
||||||
# Bug 981195 - Small leak in the parser. m4
|
# Bug 981195 - Small leak in the parser. m4
|
||||||
leak:TypeCompartment::fixObjectType
|
leak:TypeCompartment::fixObjectType
|
||||||
|
@ -728,7 +728,7 @@ public:
|
|||||||
int32_t ScrollTop()
|
int32_t ScrollTop()
|
||||||
{
|
{
|
||||||
nsIScrollableFrame* sf = GetScrollFrame();
|
nsIScrollableFrame* sf = GetScrollFrame();
|
||||||
return sf ? sf->GetScrollPositionCSSPixels().y : 0;
|
return sf ? sf->GetScrollPositionCSSPixels().y.value : 0;
|
||||||
}
|
}
|
||||||
void SetScrollTop(int32_t aScrollTop)
|
void SetScrollTop(int32_t aScrollTop)
|
||||||
{
|
{
|
||||||
@ -741,7 +741,7 @@ public:
|
|||||||
int32_t ScrollLeft()
|
int32_t ScrollLeft()
|
||||||
{
|
{
|
||||||
nsIScrollableFrame* sf = GetScrollFrame();
|
nsIScrollableFrame* sf = GetScrollFrame();
|
||||||
return sf ? sf->GetScrollPositionCSSPixels().x : 0;
|
return sf ? sf->GetScrollPositionCSSPixels().x.value : 0;
|
||||||
}
|
}
|
||||||
void SetScrollLeft(int32_t aScrollLeft)
|
void SetScrollLeft(int32_t aScrollLeft)
|
||||||
{
|
{
|
||||||
|
@ -405,15 +405,6 @@ public:
|
|||||||
static bool CanCallerAccess(nsPIDOMWindow* aWindow);
|
static bool CanCallerAccess(nsPIDOMWindow* aWindow);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the window through the JS context that's currently on the stack.
|
|
||||||
* If there's no JS context currently on the stack, returns null.
|
|
||||||
*/
|
|
||||||
static nsPIDOMWindow *GetWindowFromCaller();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The two GetDocumentFrom* functions below allow a caller to get at a
|
|
||||||
* document that is relevant to the currently executing script.
|
|
||||||
*
|
|
||||||
* GetDocumentFromCaller gets its document by looking at the last called
|
* GetDocumentFromCaller gets its document by looking at the last called
|
||||||
* function and finding the document that the function itself relates to.
|
* function and finding the document that the function itself relates to.
|
||||||
* For example, consider two windows A and B in the same origin. B has a
|
* For example, consider two windows A and B in the same origin. B has a
|
||||||
@ -421,28 +412,10 @@ public:
|
|||||||
* If a script in window A were to call B's function, GetDocumentFromCaller
|
* If a script in window A were to call B's function, GetDocumentFromCaller
|
||||||
* would find that function (in B) and return B's document.
|
* would find that function (in B) and return B's document.
|
||||||
*
|
*
|
||||||
* GetDocumentFromContext gets its document by looking at the currently
|
|
||||||
* executing context's global object and returning its document. Thus,
|
|
||||||
* given the example above, GetDocumentFromCaller would see that the
|
|
||||||
* currently executing script was in window A, and return A's document.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Get the document from the currently executing function. This will return
|
|
||||||
* the document that the currently executing function is in/from.
|
|
||||||
*
|
|
||||||
* @return The document or null if no JS Context.
|
* @return The document or null if no JS Context.
|
||||||
*/
|
*/
|
||||||
static nsIDocument* GetDocumentFromCaller();
|
static nsIDocument* GetDocumentFromCaller();
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the document through the JS context that's currently on the stack.
|
|
||||||
* If there's no JS context currently on the stack it will return null.
|
|
||||||
* This will return the document of the calling script.
|
|
||||||
*
|
|
||||||
* @return The document or null if no JS context
|
|
||||||
*/
|
|
||||||
static nsIDocument* GetDocumentFromContext();
|
|
||||||
|
|
||||||
// Check if a node is in the document prolog, i.e. before the document
|
// Check if a node is in the document prolog, i.e. before the document
|
||||||
// element.
|
// element.
|
||||||
static bool InProlog(nsINode *aNode);
|
static bool InProlog(nsINode *aNode);
|
||||||
@ -2279,9 +2252,7 @@ private:
|
|||||||
|
|
||||||
static bool sInitialized;
|
static bool sInitialized;
|
||||||
static uint32_t sScriptBlockerCount;
|
static uint32_t sScriptBlockerCount;
|
||||||
#ifdef DEBUG
|
|
||||||
static uint32_t sDOMNodeRemovedSuppressCount;
|
static uint32_t sDOMNodeRemovedSuppressCount;
|
||||||
#endif
|
|
||||||
static uint32_t sMicroTaskLevel;
|
static uint32_t sMicroTaskLevel;
|
||||||
// Not an nsCOMArray because removing elements from those is slower
|
// Not an nsCOMArray because removing elements from those is slower
|
||||||
static nsTArray< nsCOMPtr<nsIRunnable> >* sBlockedScriptRunners;
|
static nsTArray< nsCOMPtr<nsIRunnable> >* sBlockedScriptRunners;
|
||||||
@ -2338,14 +2309,10 @@ class MOZ_STACK_CLASS nsAutoScriptBlockerSuppressNodeRemoved :
|
|||||||
public nsAutoScriptBlocker {
|
public nsAutoScriptBlocker {
|
||||||
public:
|
public:
|
||||||
nsAutoScriptBlockerSuppressNodeRemoved() {
|
nsAutoScriptBlockerSuppressNodeRemoved() {
|
||||||
#ifdef DEBUG
|
|
||||||
++nsContentUtils::sDOMNodeRemovedSuppressCount;
|
++nsContentUtils::sDOMNodeRemovedSuppressCount;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
~nsAutoScriptBlockerSuppressNodeRemoved() {
|
~nsAutoScriptBlockerSuppressNodeRemoved() {
|
||||||
#ifdef DEBUG
|
|
||||||
--nsContentUtils::sDOMNodeRemovedSuppressCount;
|
--nsContentUtils::sDOMNodeRemovedSuppressCount;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -686,7 +686,7 @@ WebSocket::Init(JSContext* aCx,
|
|||||||
// Confirmed we are opening plain ws:// and want to prevent this from a
|
// Confirmed we are opening plain ws:// and want to prevent this from a
|
||||||
// secure context (e.g. https). Check the principal's uri to determine if
|
// secure context (e.g. https). Check the principal's uri to determine if
|
||||||
// we were loaded from https.
|
// we were loaded from https.
|
||||||
nsCOMPtr<nsIGlobalObject> globalObject(BrokenGetEntryGlobal());
|
nsCOMPtr<nsIGlobalObject> globalObject(GetEntryGlobal());
|
||||||
if (globalObject) {
|
if (globalObject) {
|
||||||
nsCOMPtr<nsIPrincipal> principal(globalObject->PrincipalOrNull());
|
nsCOMPtr<nsIPrincipal> principal(globalObject->PrincipalOrNull());
|
||||||
if (principal) {
|
if (principal) {
|
||||||
|
@ -214,9 +214,7 @@ nsILineBreaker *nsContentUtils::sLineBreaker;
|
|||||||
nsIWordBreaker *nsContentUtils::sWordBreaker;
|
nsIWordBreaker *nsContentUtils::sWordBreaker;
|
||||||
nsIBidiKeyboard *nsContentUtils::sBidiKeyboard = nullptr;
|
nsIBidiKeyboard *nsContentUtils::sBidiKeyboard = nullptr;
|
||||||
uint32_t nsContentUtils::sScriptBlockerCount = 0;
|
uint32_t nsContentUtils::sScriptBlockerCount = 0;
|
||||||
#ifdef DEBUG
|
|
||||||
uint32_t nsContentUtils::sDOMNodeRemovedSuppressCount = 0;
|
uint32_t nsContentUtils::sDOMNodeRemovedSuppressCount = 0;
|
||||||
#endif
|
|
||||||
uint32_t nsContentUtils::sMicroTaskLevel = 0;
|
uint32_t nsContentUtils::sMicroTaskLevel = 0;
|
||||||
nsTArray< nsCOMPtr<nsIRunnable> >* nsContentUtils::sBlockedScriptRunners = nullptr;
|
nsTArray< nsCOMPtr<nsIRunnable> >* nsContentUtils::sBlockedScriptRunners = nullptr;
|
||||||
uint32_t nsContentUtils::sRunnersCountAtFirstBlocker = 0;
|
uint32_t nsContentUtils::sRunnersCountAtFirstBlocker = 0;
|
||||||
@ -1953,19 +1951,6 @@ nsContentUtils::TraceSafeJSContext(JSTracer* aTrc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsPIDOMWindow *
|
|
||||||
nsContentUtils::GetWindowFromCaller()
|
|
||||||
{
|
|
||||||
JSContext *cx = GetCurrentJSContext();
|
|
||||||
if (cx) {
|
|
||||||
nsCOMPtr<nsPIDOMWindow> win =
|
|
||||||
do_QueryInterface(nsJSUtils::GetDynamicScriptGlobal(cx));
|
|
||||||
return win;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIDocument*
|
nsIDocument*
|
||||||
nsContentUtils::GetDocumentFromCaller()
|
nsContentUtils::GetDocumentFromCaller()
|
||||||
{
|
{
|
||||||
@ -1980,24 +1965,6 @@ nsContentUtils::GetDocumentFromCaller()
|
|||||||
return win->GetExtantDoc();
|
return win->GetExtantDoc();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIDocument*
|
|
||||||
nsContentUtils::GetDocumentFromContext()
|
|
||||||
{
|
|
||||||
JSContext *cx = GetCurrentJSContext();
|
|
||||||
if (cx) {
|
|
||||||
nsIScriptGlobalObject *sgo = nsJSUtils::GetDynamicScriptGlobal(cx);
|
|
||||||
|
|
||||||
if (sgo) {
|
|
||||||
nsCOMPtr<nsPIDOMWindow> pwin = do_QueryInterface(sgo);
|
|
||||||
if (pwin) {
|
|
||||||
return pwin->GetExtantDoc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
nsContentUtils::IsCallerChrome()
|
nsContentUtils::IsCallerChrome()
|
||||||
{
|
{
|
||||||
@ -3920,30 +3887,27 @@ nsContentUtils::MaybeFireNodeRemoved(nsINode* aChild, nsINode* aParent,
|
|||||||
NS_PRECONDITION(aChild->GetParentNode() == aParent, "Wrong parent");
|
NS_PRECONDITION(aChild->GetParentNode() == aParent, "Wrong parent");
|
||||||
NS_PRECONDITION(aChild->OwnerDoc() == aOwnerDoc, "Wrong owner-doc");
|
NS_PRECONDITION(aChild->OwnerDoc() == aOwnerDoc, "Wrong owner-doc");
|
||||||
|
|
||||||
// This checks that IsSafeToRunScript is true since we don't want to fire
|
|
||||||
// events when that is false. We can't rely on EventDispatcher to assert
|
|
||||||
// this in this situation since most of the time there are no mutation
|
|
||||||
// event listeners, in which case we won't even attempt to dispatch events.
|
|
||||||
// However this also allows for two exceptions. First off, we don't assert
|
|
||||||
// if the mutation happens to native anonymous content since we never fire
|
|
||||||
// mutation events on such content anyway.
|
|
||||||
// Second, we don't assert if sDOMNodeRemovedSuppressCount is true since
|
|
||||||
// that is a know case when we'd normally fire a mutation event, but can't
|
|
||||||
// make that safe and so we suppress it at this time. Ideally this should
|
|
||||||
// go away eventually.
|
|
||||||
NS_ASSERTION((aChild->IsNodeOfType(nsINode::eCONTENT) &&
|
|
||||||
static_cast<nsIContent*>(aChild)->
|
|
||||||
IsInNativeAnonymousSubtree()) ||
|
|
||||||
IsSafeToRunScript() ||
|
|
||||||
sDOMNodeRemovedSuppressCount,
|
|
||||||
"Want to fire DOMNodeRemoved event, but it's not safe");
|
|
||||||
|
|
||||||
// Having an explicit check here since it's an easy mistake to fall into,
|
// Having an explicit check here since it's an easy mistake to fall into,
|
||||||
// and there might be existing code with problems. We'd rather be safe
|
// and there might be existing code with problems. We'd rather be safe
|
||||||
// than fire DOMNodeRemoved in all corner cases. We also rely on it for
|
// than fire DOMNodeRemoved in all corner cases. We also rely on it for
|
||||||
// nsAutoScriptBlockerSuppressNodeRemoved.
|
// nsAutoScriptBlockerSuppressNodeRemoved.
|
||||||
if (!IsSafeToRunScript()) {
|
if (!IsSafeToRunScript()) {
|
||||||
WarnScriptWasIgnored(aOwnerDoc);
|
// This checks that IsSafeToRunScript is true since we don't want to fire
|
||||||
|
// events when that is false. We can't rely on EventDispatcher to assert
|
||||||
|
// this in this situation since most of the time there are no mutation
|
||||||
|
// event listeners, in which case we won't even attempt to dispatch events.
|
||||||
|
// However this also allows for two exceptions. First off, we don't assert
|
||||||
|
// if the mutation happens to native anonymous content since we never fire
|
||||||
|
// mutation events on such content anyway.
|
||||||
|
// Second, we don't assert if sDOMNodeRemovedSuppressCount is true since
|
||||||
|
// that is a know case when we'd normally fire a mutation event, but can't
|
||||||
|
// make that safe and so we suppress it at this time. Ideally this should
|
||||||
|
// go away eventually.
|
||||||
|
if (!(aChild->IsContent() && aChild->AsContent()->IsInNativeAnonymousSubtree()) &&
|
||||||
|
!sDOMNodeRemovedSuppressCount) {
|
||||||
|
NS_ERROR("Want to fire DOMNodeRemoved event, but it's not safe");
|
||||||
|
WarnScriptWasIgnored(aOwnerDoc);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1429,10 +1429,10 @@ nsHTMLDocument::Open(JSContext* cx,
|
|||||||
return ret.forget();
|
return ret.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: We want to use GetDocumentFromContext here because this document
|
// Note: We want to use GetEntryDocument here because this document
|
||||||
// should inherit the security information of the document that's opening us,
|
// should inherit the security information of the document that's opening us,
|
||||||
// (since if it's secure, then it's presumably trusted).
|
// (since if it's secure, then it's presumably trusted).
|
||||||
nsCOMPtr<nsIDocument> callerDoc = nsContentUtils::GetDocumentFromContext();
|
nsCOMPtr<nsIDocument> callerDoc = GetEntryDocument();
|
||||||
if (!callerDoc) {
|
if (!callerDoc) {
|
||||||
// If we're called from C++ or in some other way without an originating
|
// If we're called from C++ or in some other way without an originating
|
||||||
// document we can't do a document.open w/o changing the principal of the
|
// document we can't do a document.open w/o changing the principal of the
|
||||||
|
@ -128,14 +128,15 @@ GMPChild::Init(const std::string& aPluginPath,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MOZ_CRASHREPORTER
|
||||||
|
SendPCrashReporterConstructor(CrashReporter::CurrentThreadId());
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX)
|
#if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX)
|
||||||
mPluginPath = aPluginPath;
|
mPluginPath = aPluginPath;
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MOZ_CRASHREPORTER
|
|
||||||
SendPCrashReporterConstructor(CrashReporter::CurrentThreadId());
|
|
||||||
#endif
|
|
||||||
#if defined(XP_WIN)
|
#if defined(XP_WIN)
|
||||||
mozilla::SandboxTarget::Instance()->StartSandbox();
|
mozilla::SandboxTarget::Instance()->StartSandbox();
|
||||||
#endif
|
#endif
|
||||||
|
@ -75,6 +75,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
ResourceQueue() :
|
ResourceQueue() :
|
||||||
nsDeque(new ResourceQueueDeallocator()),
|
nsDeque(new ResourceQueueDeallocator()),
|
||||||
|
mLogicalLength(0),
|
||||||
mOffset(0)
|
mOffset(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -87,12 +88,7 @@ private:
|
|||||||
// Returns the length of all items in the queue plus the offset.
|
// Returns the length of all items in the queue plus the offset.
|
||||||
// This is the logical length of the resource.
|
// This is the logical length of the resource.
|
||||||
inline uint64_t GetLength() {
|
inline uint64_t GetLength() {
|
||||||
uint64_t s = mOffset;
|
return mLogicalLength;
|
||||||
for (uint32_t i = 0; i < GetSize(); ++i) {
|
|
||||||
ResourceItem* item = ResourceAt(i);
|
|
||||||
s += item->mData.Length();
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copies aCount bytes from aOffset in the queue into aDest.
|
// Copies aCount bytes from aOffset in the queue into aDest.
|
||||||
@ -113,6 +109,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline void PushBack(ResourceItem* aItem) {
|
inline void PushBack(ResourceItem* aItem) {
|
||||||
|
mLogicalLength += aItem->mData.Length();
|
||||||
nsDeque::Push(aItem);
|
nsDeque::Push(aItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,8 +181,10 @@ private:
|
|||||||
return static_cast<ResourceItem*>(nsDeque::PopFront());
|
return static_cast<ResourceItem*>(nsDeque::PopFront());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logical offset into the resource of the first element
|
// Logical length of the resource.
|
||||||
// in the queue.
|
uint64_t mLogicalLength;
|
||||||
|
|
||||||
|
// Logical offset into the resource of the first element in the queue.
|
||||||
uint64_t mOffset;
|
uint64_t mOffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -67,9 +67,6 @@ EXPORTS += [
|
|||||||
'AudioCompactor.h',
|
'AudioCompactor.h',
|
||||||
'AudioEventTimeline.h',
|
'AudioEventTimeline.h',
|
||||||
'AudioMixer.h',
|
'AudioMixer.h',
|
||||||
'AudioNodeEngine.h',
|
|
||||||
'AudioNodeExternalInputStream.h',
|
|
||||||
'AudioNodeStream.h',
|
|
||||||
'AudioSampleFormat.h',
|
'AudioSampleFormat.h',
|
||||||
'AudioSegment.h',
|
'AudioSegment.h',
|
||||||
'AudioStream.h',
|
'AudioStream.h',
|
||||||
@ -130,9 +127,6 @@ EXPORTS.mozilla.dom += [
|
|||||||
UNIFIED_SOURCES += [
|
UNIFIED_SOURCES += [
|
||||||
'AudioChannelFormat.cpp',
|
'AudioChannelFormat.cpp',
|
||||||
'AudioCompactor.cpp',
|
'AudioCompactor.cpp',
|
||||||
'AudioNodeEngine.cpp',
|
|
||||||
'AudioNodeExternalInputStream.cpp',
|
|
||||||
'AudioNodeStream.cpp',
|
|
||||||
'AudioSegment.cpp',
|
'AudioSegment.cpp',
|
||||||
'AudioSink.cpp',
|
'AudioSink.cpp',
|
||||||
'AudioStream.cpp',
|
'AudioStream.cpp',
|
||||||
@ -185,10 +179,6 @@ SOURCES += [
|
|||||||
|
|
||||||
FAIL_ON_WARNINGS = True
|
FAIL_ON_WARNINGS = True
|
||||||
|
|
||||||
if CONFIG['CPU_ARCH'] == 'arm' and CONFIG['BUILD_ARM_NEON']:
|
|
||||||
SOURCES += ['AudioNodeEngineNEON.cpp']
|
|
||||||
SOURCES['AudioNodeEngineNEON.cpp'].flags += ['-mfpu=neon']
|
|
||||||
|
|
||||||
MSVC_ENABLE_PGO = True
|
MSVC_ENABLE_PGO = True
|
||||||
|
|
||||||
include('/ipc/chromium/chromium-config.mozbuild')
|
include('/ipc/chromium/chromium-config.mozbuild')
|
||||||
|
@ -19,6 +19,9 @@ BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
|
|||||||
|
|
||||||
EXPORTS += [
|
EXPORTS += [
|
||||||
'AudioContext.h',
|
'AudioContext.h',
|
||||||
|
'AudioNodeEngine.h',
|
||||||
|
'AudioNodeExternalInputStream.h',
|
||||||
|
'AudioNodeStream.h',
|
||||||
'AudioParamTimeline.h',
|
'AudioParamTimeline.h',
|
||||||
'MediaBufferDecoder.h',
|
'MediaBufferDecoder.h',
|
||||||
'ThreeDPoint.h',
|
'ThreeDPoint.h',
|
||||||
@ -65,6 +68,9 @@ UNIFIED_SOURCES += [
|
|||||||
'AudioDestinationNode.cpp',
|
'AudioDestinationNode.cpp',
|
||||||
'AudioListener.cpp',
|
'AudioListener.cpp',
|
||||||
'AudioNode.cpp',
|
'AudioNode.cpp',
|
||||||
|
'AudioNodeEngine.cpp',
|
||||||
|
'AudioNodeExternalInputStream.cpp',
|
||||||
|
'AudioNodeStream.cpp',
|
||||||
'AudioParam.cpp',
|
'AudioParam.cpp',
|
||||||
'AudioProcessingEvent.cpp',
|
'AudioProcessingEvent.cpp',
|
||||||
'BiquadFilterNode.cpp',
|
'BiquadFilterNode.cpp',
|
||||||
@ -90,8 +96,15 @@ UNIFIED_SOURCES += [
|
|||||||
'WebAudioUtils.cpp',
|
'WebAudioUtils.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if CONFIG['CPU_ARCH'] == 'arm' and CONFIG['BUILD_ARM_NEON']:
|
||||||
|
SOURCES += ['AudioNodeEngineNEON.cpp']
|
||||||
|
SOURCES['AudioNodeEngineNEON.cpp'].flags += ['-mfpu=neon']
|
||||||
|
|
||||||
FAIL_ON_WARNINGS = True
|
FAIL_ON_WARNINGS = True
|
||||||
|
|
||||||
include('/ipc/chromium/chromium-config.mozbuild')
|
include('/ipc/chromium/chromium-config.mozbuild')
|
||||||
|
|
||||||
FINAL_LIBRARY = 'xul'
|
FINAL_LIBRARY = 'xul'
|
||||||
|
LOCAL_INCLUDES += [
|
||||||
|
'..'
|
||||||
|
]
|
||||||
|
@ -128,6 +128,7 @@ skip-if = (toolkit == 'gonk' && !debug)
|
|||||||
[test_periodicWave.html]
|
[test_periodicWave.html]
|
||||||
[test_scriptProcessorNode.html]
|
[test_scriptProcessorNode.html]
|
||||||
[test_scriptProcessorNodeChannelCount.html]
|
[test_scriptProcessorNodeChannelCount.html]
|
||||||
|
[test_scriptProcessorNodePassThrough.html]
|
||||||
[test_scriptProcessorNode_playbackTime1.html]
|
[test_scriptProcessorNode_playbackTime1.html]
|
||||||
[test_scriptProcessorNodeZeroInputOutput.html]
|
[test_scriptProcessorNodeZeroInputOutput.html]
|
||||||
[test_scriptProcessorNodeNotConnected.html]
|
[test_scriptProcessorNodeNotConnected.html]
|
||||||
|
@ -26,7 +26,7 @@ addLoadEvent(function() {
|
|||||||
for (var i = 0; i < 2048; ++i) {
|
for (var i = 0; i < 2048; ++i) {
|
||||||
// Make sure our first sample won't be zero
|
// Make sure our first sample won't be zero
|
||||||
e.outputBuffer.getChannelData(0)[i] = Math.sin(440 * 2 * Math.PI * (i + 1) / context.sampleRate);
|
e.outputBuffer.getChannelData(0)[i] = Math.sin(440 * 2 * Math.PI * (i + 1) / context.sampleRate);
|
||||||
e.outputBuffer.getChannelData(0)[i] = Math.sin(880 * 2 * Math.PI * (i + 1) / context.sampleRate);
|
e.outputBuffer.getChannelData(1)[i] = Math.sin(880 * 2 * Math.PI * (i + 1) / context.sampleRate);
|
||||||
}
|
}
|
||||||
// Remember our generated audio
|
// Remember our generated audio
|
||||||
buffer = e.outputBuffer;
|
buffer = e.outputBuffer;
|
||||||
|
@ -0,0 +1,103 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Test ScriptProcessorNode with passthrough</title>
|
||||||
|
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<script type="text/javascript" src="webaudio.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre id="test">
|
||||||
|
<script class="testbody" type="text/javascript">
|
||||||
|
|
||||||
|
// We do not use our generic graph test framework here because
|
||||||
|
// the testing logic here is sort of complicated, and would
|
||||||
|
// not be easy to map to OfflineAudioContext, as ScriptProcessorNodes
|
||||||
|
// can experience delays.
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
addLoadEvent(function() {
|
||||||
|
var context = new AudioContext();
|
||||||
|
var buffer = null;
|
||||||
|
|
||||||
|
var sourceSP = context.createScriptProcessor(2048);
|
||||||
|
sourceSP.addEventListener("audioprocess", function(e) {
|
||||||
|
// generate the audio
|
||||||
|
for (var i = 0; i < 2048; ++i) {
|
||||||
|
// Make sure our first sample won't be zero
|
||||||
|
e.outputBuffer.getChannelData(0)[i] = Math.sin(440 * 2 * Math.PI * (i + 1) / context.sampleRate);
|
||||||
|
e.outputBuffer.getChannelData(1)[i] = Math.sin(880 * 2 * Math.PI * (i + 1) / context.sampleRate);
|
||||||
|
}
|
||||||
|
// Remember our generated audio
|
||||||
|
buffer = e.outputBuffer;
|
||||||
|
|
||||||
|
sourceSP.removeEventListener("audioprocess", arguments.callee);
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
function findFirstNonZeroSample(buffer) {
|
||||||
|
for (var i = 0; i < buffer.length; ++i) {
|
||||||
|
if (buffer.getChannelData(0)[i] != 0) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sp = context.createScriptProcessor(2048);
|
||||||
|
sourceSP.connect(sp);
|
||||||
|
|
||||||
|
var spWrapped = SpecialPowers.wrap(sp);
|
||||||
|
ok("passThrough" in spWrapped, "ScriptProcessorNode should support the passThrough API");
|
||||||
|
spWrapped.passThrough = true;
|
||||||
|
|
||||||
|
sp.onaudioprocess = function() {
|
||||||
|
ok(false, "The audioprocess event must never be dispatched on the passthrough ScriptProcessorNode");
|
||||||
|
};
|
||||||
|
|
||||||
|
var sp2 = context.createScriptProcessor(2048);
|
||||||
|
sp.connect(sp2);
|
||||||
|
sp2.connect(context.destination);
|
||||||
|
|
||||||
|
var emptyBuffer = context.createBuffer(1, 2048, context.sampleRate);
|
||||||
|
|
||||||
|
sp2.onaudioprocess = function(e) {
|
||||||
|
// Because of the initial latency added by the second script processor node,
|
||||||
|
// we will never see any generated audio frames in the first callback.
|
||||||
|
compareChannels(e.inputBuffer.getChannelData(0), emptyBuffer.getChannelData(0));
|
||||||
|
compareChannels(e.inputBuffer.getChannelData(1), emptyBuffer.getChannelData(0));
|
||||||
|
|
||||||
|
sp2.onaudioprocess = function(e) {
|
||||||
|
var firstNonZero = findFirstNonZeroSample(e.inputBuffer);
|
||||||
|
ok(firstNonZero <= 2048, "First non-zero sample within range");
|
||||||
|
|
||||||
|
compareChannels(e.inputBuffer.getChannelData(0), emptyBuffer.getChannelData(0), firstNonZero);
|
||||||
|
compareChannels(e.inputBuffer.getChannelData(1), emptyBuffer.getChannelData(0), firstNonZero);
|
||||||
|
compareChannels(e.inputBuffer.getChannelData(0), buffer.getChannelData(0), 2048 - firstNonZero, firstNonZero, 0);
|
||||||
|
compareChannels(e.inputBuffer.getChannelData(1), buffer.getChannelData(1), 2048 - firstNonZero, firstNonZero, 0);
|
||||||
|
|
||||||
|
if (firstNonZero == 0) {
|
||||||
|
// If we did not experience any delays, the test is done!
|
||||||
|
sp2.onaudioprocess = null;
|
||||||
|
|
||||||
|
SimpleTest.finish();
|
||||||
|
} else if (firstNonZero != 2048) {
|
||||||
|
// In case we just saw a zero buffer this time, wait one more round
|
||||||
|
sp2.onaudioprocess = function(e) {
|
||||||
|
compareChannels(e.inputBuffer.getChannelData(0), buffer.getChannelData(0), firstNonZero, 0, 2048 - firstNonZero);
|
||||||
|
compareChannels(e.inputBuffer.getChannelData(1), buffer.getChannelData(1), firstNonZero, 0, 2048 - firstNonZero);
|
||||||
|
compareChannels(e.inputBuffer.getChannelData(0), emptyBuffer.getChannelData(0), undefined, firstNonZero);
|
||||||
|
compareChannels(e.inputBuffer.getChannelData(1), emptyBuffer.getChannelData(0), undefined, firstNonZero);
|
||||||
|
|
||||||
|
sp2.onaudioprocess = null;
|
||||||
|
|
||||||
|
SimpleTest.finish();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -60,7 +60,7 @@ void WebMBufferedParser::Append(const unsigned char* aBuffer, uint32_t aLength,
|
|||||||
// and return to CLUSTER_SYNC.
|
// and return to CLUSTER_SYNC.
|
||||||
if (mClusterIDPos == sizeof(CLUSTER_ID)) {
|
if (mClusterIDPos == sizeof(CLUSTER_ID)) {
|
||||||
mClusterIDPos = 0;
|
mClusterIDPos = 0;
|
||||||
mClusterOffset = mCurrentOffset + (p - aBuffer) - 1;
|
mClusterOffset = mCurrentOffset + (p - aBuffer) - sizeof(CLUSTER_ID);
|
||||||
mState = READ_VINT;
|
mState = READ_VINT;
|
||||||
mNextState = TIMECODE_SYNC;
|
mNextState = TIMECODE_SYNC;
|
||||||
}
|
}
|
||||||
|
@ -1965,16 +1965,16 @@ Navigator::GetMozCameras(ErrorResult& aRv)
|
|||||||
return mCameraManager;
|
return mCameraManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<workers::ServiceWorkerContainer>
|
already_AddRefed<ServiceWorkerContainer>
|
||||||
Navigator::ServiceWorker()
|
Navigator::ServiceWorker()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mWindow);
|
MOZ_ASSERT(mWindow);
|
||||||
|
|
||||||
if (!mServiceWorkerContainer) {
|
if (!mServiceWorkerContainer) {
|
||||||
mServiceWorkerContainer = new workers::ServiceWorkerContainer(mWindow);
|
mServiceWorkerContainer = new ServiceWorkerContainer(mWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<workers::ServiceWorkerContainer> ref = mServiceWorkerContainer;
|
nsRefPtr<ServiceWorkerContainer> ref = mServiceWorkerContainer;
|
||||||
return ref.forget();
|
return ref.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ struct MediaStreamConstraints;
|
|||||||
class WakeLock;
|
class WakeLock;
|
||||||
class ArrayBufferViewOrBlobOrStringOrFormData;
|
class ArrayBufferViewOrBlobOrStringOrFormData;
|
||||||
struct MobileIdOptions;
|
struct MobileIdOptions;
|
||||||
|
class ServiceWorkerContainer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,10 +105,6 @@ class AudioChannelManager;
|
|||||||
#endif
|
#endif
|
||||||
} // namespace system
|
} // namespace system
|
||||||
|
|
||||||
namespace workers {
|
|
||||||
class ServiceWorkerContainer;
|
|
||||||
} // namespace workers
|
|
||||||
|
|
||||||
class Navigator : public nsIDOMNavigator
|
class Navigator : public nsIDOMNavigator
|
||||||
, public nsIMozNavigatorNetwork
|
, public nsIMozNavigatorNetwork
|
||||||
, public nsWrapperCache
|
, public nsWrapperCache
|
||||||
@ -262,7 +259,7 @@ public:
|
|||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
#endif // MOZ_MEDIA_NAVIGATOR
|
#endif // MOZ_MEDIA_NAVIGATOR
|
||||||
|
|
||||||
already_AddRefed<workers::ServiceWorkerContainer> ServiceWorker();
|
already_AddRefed<ServiceWorkerContainer> ServiceWorker();
|
||||||
|
|
||||||
bool DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
|
bool DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
|
||||||
JS::Handle<jsid> aId,
|
JS::Handle<jsid> aId,
|
||||||
@ -340,7 +337,7 @@ private:
|
|||||||
nsCOMPtr<nsIDOMNavigatorSystemMessages> mMessagesManager;
|
nsCOMPtr<nsIDOMNavigatorSystemMessages> mMessagesManager;
|
||||||
nsTArray<nsRefPtr<nsDOMDeviceStorage> > mDeviceStorageStores;
|
nsTArray<nsRefPtr<nsDOMDeviceStorage> > mDeviceStorageStores;
|
||||||
nsRefPtr<time::TimeManager> mTimeManager;
|
nsRefPtr<time::TimeManager> mTimeManager;
|
||||||
nsRefPtr<workers::ServiceWorkerContainer> mServiceWorkerContainer;
|
nsRefPtr<ServiceWorkerContainer> mServiceWorkerContainer;
|
||||||
nsCOMPtr<nsPIDOMWindow> mWindow;
|
nsCOMPtr<nsPIDOMWindow> mWindow;
|
||||||
|
|
||||||
// Hashtable for saving cached objects newresolve created, so we don't create
|
// Hashtable for saving cached objects newresolve created, so we don't create
|
||||||
|
@ -122,27 +122,18 @@ ScriptSettingsStackEntry::~ScriptSettingsStackEntry()
|
|||||||
ScriptSettingsStack::Pop(this);
|
ScriptSettingsStack::Pop(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This mostly gets the entry global, but doesn't entirely match the spec in
|
|
||||||
// certain edge cases. It's good enough for some purposes, but not others. If
|
|
||||||
// you want to call this function, ping bholley and describe your use-case.
|
|
||||||
nsIGlobalObject*
|
nsIGlobalObject*
|
||||||
BrokenGetEntryGlobal()
|
GetEntryGlobal()
|
||||||
{
|
{
|
||||||
// We need the current JSContext in order to check the JS for
|
return ScriptSettingsStack::EntryGlobal();
|
||||||
// scripted frames that may have appeared since anyone last
|
|
||||||
// manipulated the stack. If it's null, that means that there
|
|
||||||
// must be no entry global on the stack.
|
|
||||||
JSContext *cx = nsContentUtils::GetCurrentJSContextForThread();
|
|
||||||
if (!cx) {
|
|
||||||
MOZ_ASSERT(ScriptSettingsStack::EntryGlobal() == nullptr);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nsJSUtils::GetDynamicScriptGlobal(cx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: When we're ready to expose it, GetEntryGlobal will look similar to
|
nsIDocument*
|
||||||
// GetIncumbentGlobal below.
|
GetEntryDocument()
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsPIDOMWindow> entryWin = do_QueryInterface(GetEntryGlobal());
|
||||||
|
return entryWin ? entryWin->GetExtantDoc() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
nsIGlobalObject*
|
nsIGlobalObject*
|
||||||
GetIncumbentGlobal()
|
GetIncumbentGlobal()
|
||||||
@ -171,6 +162,22 @@ GetIncumbentGlobal()
|
|||||||
return ScriptSettingsStack::IncumbentGlobal();
|
return ScriptSettingsStack::IncumbentGlobal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsIGlobalObject*
|
||||||
|
GetCurrentGlobal()
|
||||||
|
{
|
||||||
|
JSContext *cx = nsContentUtils::GetCurrentJSContextForThread();
|
||||||
|
if (!cx) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSObject *global = JS::CurrentGlobalOrNull(cx);
|
||||||
|
if (!global) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xpc::GetNativeForGlobal(global);
|
||||||
|
}
|
||||||
|
|
||||||
nsIPrincipal*
|
nsIPrincipal*
|
||||||
GetWebIDLCallerPrincipal()
|
GetWebIDLCallerPrincipal()
|
||||||
{
|
{
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
class nsPIDOMWindow;
|
class nsPIDOMWindow;
|
||||||
class nsGlobalWindow;
|
class nsGlobalWindow;
|
||||||
class nsIScriptContext;
|
class nsIScriptContext;
|
||||||
|
class nsIDocument;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
@ -63,17 +64,57 @@ private:
|
|||||||
void InitScriptSettings();
|
void InitScriptSettings();
|
||||||
void DestroyScriptSettings();
|
void DestroyScriptSettings();
|
||||||
|
|
||||||
// This mostly gets the entry global, but doesn't entirely match the spec in
|
// To implement a web-compatible browser, it is often necessary to obtain the
|
||||||
// certain edge cases. It's good enough for some purposes, but not others. If
|
// global object that is "associated" with the currently-running code. This
|
||||||
// you want to call this function, ping bholley and describe your use-case.
|
// process is made more complicated by the fact that, historically, different
|
||||||
nsIGlobalObject* BrokenGetEntryGlobal();
|
// algorithms have operated with different definitions of the "associated"
|
||||||
|
// global.
|
||||||
|
//
|
||||||
|
// HTML5 formalizes this into two concepts: the "incumbent global" and the
|
||||||
|
// "entry global". The incumbent global corresponds to the global of the
|
||||||
|
// current script being executed, whereas the entry global corresponds to the
|
||||||
|
// global of the script where the current JS execution began.
|
||||||
|
//
|
||||||
|
// There is also a potentially-distinct third global that is determined by the
|
||||||
|
// current compartment. This roughly corresponds with the notion of Realms in
|
||||||
|
// ECMAScript.
|
||||||
|
//
|
||||||
|
// Suppose some event triggers an event listener in window |A|, which invokes a
|
||||||
|
// scripted function in window |B|, which invokes the |window.location.href|
|
||||||
|
// setter in window |C|. The entry global would be |A|, the incumbent global
|
||||||
|
// would be |B|, and the current compartment would be that of |C|.
|
||||||
|
//
|
||||||
|
// In general, it's best to use to use the most-closely-associated global
|
||||||
|
// unless the spec says to do otherwise. In 95% of the cases, the global of
|
||||||
|
// the current compartment (GetCurrentGlobal()) is the right thing. For
|
||||||
|
// example, WebIDL constructors (new C.XMLHttpRequest()) are initialized with
|
||||||
|
// the global of the current compartment (i.e. |C|).
|
||||||
|
//
|
||||||
|
// The incumbent global is very similar, but differs in a few edge cases. For
|
||||||
|
// example, if window |B| does |C.location.href = "..."|, the incumbent global
|
||||||
|
// used for the navigation algorithm is B, because no script from |C| was ever run.
|
||||||
|
//
|
||||||
|
// The entry global is used for various things like computing base URIs, mostly
|
||||||
|
// for historical reasons.
|
||||||
|
//
|
||||||
|
// Note that all of these functions return bonafide global objects. This means
|
||||||
|
// that, for Windows, they always return the inner.
|
||||||
|
|
||||||
// Note: We don't yet expose GetEntryGlobal, because in order for it to be
|
// Returns the global associated with the top-most Candidate Entry Point on
|
||||||
// correct, we first need to replace a bunch of explicit cx pushing in the
|
// the Script Settings Stack. See the HTML spec. This may be null.
|
||||||
// browser with AutoEntryScript. But GetIncumbentGlobal is simpler, because it
|
nsIGlobalObject* GetEntryGlobal();
|
||||||
// can mostly be inferred from the JS stack.
|
|
||||||
|
// If the entry global is a window, returns its extant document. Otherwise,
|
||||||
|
// returns null.
|
||||||
|
nsIDocument* GetEntryDocument();
|
||||||
|
|
||||||
|
// Returns the global associated with the top-most entry of the the Script
|
||||||
|
// Settings Stack. See the HTML spec. This may be null.
|
||||||
nsIGlobalObject* GetIncumbentGlobal();
|
nsIGlobalObject* GetIncumbentGlobal();
|
||||||
|
|
||||||
|
// Returns the global associated with the current compartment. This may be null.
|
||||||
|
nsIGlobalObject* GetCurrentGlobal();
|
||||||
|
|
||||||
// JS-implemented WebIDL presents an interesting situation with respect to the
|
// JS-implemented WebIDL presents an interesting situation with respect to the
|
||||||
// subject principal. A regular C++-implemented API can simply examine the
|
// subject principal. A regular C++-implemented API can simply examine the
|
||||||
// compartment of the most-recently-executed script, and use that to infer the
|
// compartment of the most-recently-executed script, and use that to infer the
|
||||||
|
@ -2501,11 +2501,6 @@ OldBindingConstructorEnabled(const nsGlobalNameStruct *aStruct,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't expose CSSFontFeatureValuesRule unless the pref is enabled
|
|
||||||
if (aStruct->mDOMClassInfoID == eDOMClassInfo_CSSFontFeatureValuesRule_id) {
|
|
||||||
return nsCSSFontFeatureValuesRule::PrefEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,7 +420,7 @@ nsFocusManager::GetLastFocusMethod(nsIDOMWindow* aWindow, uint32_t* aLastFocusMe
|
|||||||
{
|
{
|
||||||
// the focus method is stored on the inner window
|
// the focus method is stored on the inner window
|
||||||
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(aWindow));
|
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(aWindow));
|
||||||
if (window)
|
if (window && window->IsOuterWindow())
|
||||||
window = window->GetCurrentInnerWindow();
|
window = window->GetCurrentInnerWindow();
|
||||||
if (!window)
|
if (!window)
|
||||||
window = mFocusedWindow;
|
window = mFocusedWindow;
|
||||||
|
@ -1482,10 +1482,11 @@ nsGlobalWindow::CleanUp()
|
|||||||
mChromeEventHandler = nullptr; // Forces Release
|
mChromeEventHandler = nullptr; // Forces Release
|
||||||
mParentTarget = nullptr;
|
mParentTarget = nullptr;
|
||||||
|
|
||||||
nsGlobalWindow *inner = GetCurrentInnerWindowInternal();
|
if (IsOuterWindow()) {
|
||||||
|
nsGlobalWindow* inner = GetCurrentInnerWindowInternal();
|
||||||
if (inner) {
|
if (inner) {
|
||||||
inner->CleanUp();
|
inner->CleanUp();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsInnerWindow()) {
|
if (IsInnerWindow()) {
|
||||||
@ -5915,15 +5916,8 @@ nsGlobalWindow::RefreshCompartmentPrincipal()
|
|||||||
static already_AddRefed<nsIDocShellTreeItem>
|
static already_AddRefed<nsIDocShellTreeItem>
|
||||||
GetCallerDocShellTreeItem()
|
GetCallerDocShellTreeItem()
|
||||||
{
|
{
|
||||||
JSContext *cx = nsContentUtils::GetCurrentJSContext();
|
nsCOMPtr<nsIWebNavigation> callerWebNav = do_GetInterface(GetEntryGlobal());
|
||||||
nsCOMPtr<nsIDocShellTreeItem> callerItem;
|
nsCOMPtr<nsIDocShellTreeItem> callerItem = do_QueryInterface(callerWebNav);
|
||||||
|
|
||||||
if (cx) {
|
|
||||||
nsCOMPtr<nsIWebNavigation> callerWebNav =
|
|
||||||
do_GetInterface(nsJSUtils::GetDynamicScriptGlobal(cx));
|
|
||||||
|
|
||||||
callerItem = do_QueryInterface(callerWebNav);
|
|
||||||
}
|
|
||||||
|
|
||||||
return callerItem.forget();
|
return callerItem.forget();
|
||||||
}
|
}
|
||||||
@ -6557,7 +6551,7 @@ nsGlobalWindow::Focus(ErrorResult& aError)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIDOMWindow *caller = nsContentUtils::GetWindowFromCaller();
|
nsCOMPtr<nsIDOMWindow> caller = do_QueryInterface(GetEntryGlobal());
|
||||||
nsCOMPtr<nsIDOMWindow> opener;
|
nsCOMPtr<nsIDOMWindow> opener;
|
||||||
GetOpener(getter_AddRefs(opener));
|
GetOpener(getter_AddRefs(opener));
|
||||||
|
|
||||||
@ -7535,20 +7529,7 @@ nsGlobalWindow::FireAbuseEvents(bool aBlocked, bool aWindow,
|
|||||||
|
|
||||||
nsIURI *baseURL = nullptr;
|
nsIURI *baseURL = nullptr;
|
||||||
|
|
||||||
JSContext *cx = nsContentUtils::GetCurrentJSContext();
|
nsCOMPtr<nsIDocument> doc = GetEntryDocument();
|
||||||
nsCOMPtr<nsPIDOMWindow> contextWindow;
|
|
||||||
|
|
||||||
if (cx) {
|
|
||||||
nsIScriptContext *currentCX = nsJSUtils::GetDynamicScriptContext(cx);
|
|
||||||
if (currentCX) {
|
|
||||||
contextWindow = do_QueryInterface(currentCX->GetGlobalObject());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!contextWindow) {
|
|
||||||
contextWindow = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDocument> doc = contextWindow->GetDoc();
|
|
||||||
if (doc)
|
if (doc)
|
||||||
baseURL = doc->GetDocBaseURI();
|
baseURL = doc->GetDocBaseURI();
|
||||||
|
|
||||||
@ -8253,7 +8234,7 @@ nsGlobalWindow::PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
|||||||
nsCOMPtr<nsIPrincipal> providedPrincipal;
|
nsCOMPtr<nsIPrincipal> providedPrincipal;
|
||||||
|
|
||||||
if (aTargetOrigin.EqualsASCII("/")) {
|
if (aTargetOrigin.EqualsASCII("/")) {
|
||||||
providedPrincipal = BrokenGetEntryGlobal()->PrincipalOrNull();
|
providedPrincipal = GetEntryGlobal()->PrincipalOrNull();
|
||||||
if (NS_WARN_IF(!providedPrincipal))
|
if (NS_WARN_IF(!providedPrincipal))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -12803,11 +12784,7 @@ nsGlobalWindow::GetScrollFrame()
|
|||||||
nsresult
|
nsresult
|
||||||
nsGlobalWindow::SecurityCheckURL(const char *aURL)
|
nsGlobalWindow::SecurityCheckURL(const char *aURL)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsPIDOMWindow> sourceWindow;
|
nsCOMPtr<nsPIDOMWindow> sourceWindow = do_QueryInterface(GetEntryGlobal());
|
||||||
JSContext* topCx = nsContentUtils::GetCurrentJSContext();
|
|
||||||
if (topCx) {
|
|
||||||
sourceWindow = do_QueryInterface(nsJSUtils::GetDynamicScriptGlobal(topCx));
|
|
||||||
}
|
|
||||||
if (!sourceWindow) {
|
if (!sourceWindow) {
|
||||||
sourceWindow = this;
|
sourceWindow = this;
|
||||||
}
|
}
|
||||||
|
@ -599,6 +599,7 @@ public:
|
|||||||
|
|
||||||
nsGlobalWindow *GetCurrentInnerWindowInternal() const
|
nsGlobalWindow *GetCurrentInnerWindowInternal() const
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(IsOuterWindow());
|
||||||
return static_cast<nsGlobalWindow *>(mInnerWindow);
|
return static_cast<nsGlobalWindow *>(mInnerWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,46 +557,38 @@ NS_ScriptErrorReporter(JSContext *cx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX this means we are not going to get error reports on non DOM contexts
|
|
||||||
nsIScriptContext *context = nsJSUtils::GetDynamicScriptContext(cx);
|
|
||||||
|
|
||||||
JS::Rooted<JS::Value> exception(cx);
|
JS::Rooted<JS::Value> exception(cx);
|
||||||
::JS_GetPendingException(cx, &exception);
|
::JS_GetPendingException(cx, &exception);
|
||||||
|
|
||||||
// Note: we must do this before running any more code on cx (if cx is the
|
// Note: we must do this before running any more code on cx.
|
||||||
// dynamic script context).
|
|
||||||
::JS_ClearPendingException(cx);
|
::JS_ClearPendingException(cx);
|
||||||
|
|
||||||
if (context) {
|
MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext());
|
||||||
nsIScriptGlobalObject *globalObject = context->GetGlobalObject();
|
nsCOMPtr<nsIGlobalObject> globalObject = GetEntryGlobal();
|
||||||
|
if (globalObject) {
|
||||||
|
|
||||||
if (globalObject) {
|
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(globalObject);
|
||||||
|
MOZ_ASSERT_IF(win, win->IsInnerWindow());
|
||||||
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(globalObject);
|
nsCOMPtr<nsIScriptObjectPrincipal> scriptPrincipal =
|
||||||
if (win) {
|
do_QueryInterface(globalObject);
|
||||||
win = win->GetCurrentInnerWindow();
|
NS_ASSERTION(scriptPrincipal, "Global objects must implement "
|
||||||
}
|
"nsIScriptObjectPrincipal");
|
||||||
nsCOMPtr<nsIScriptObjectPrincipal> scriptPrincipal =
|
nsContentUtils::AddScriptRunner(
|
||||||
do_QueryInterface(globalObject);
|
new ScriptErrorEvent(JS_GetRuntime(cx),
|
||||||
NS_ASSERTION(scriptPrincipal, "Global objects must implement "
|
report,
|
||||||
"nsIScriptObjectPrincipal");
|
message,
|
||||||
nsContentUtils::AddScriptRunner(
|
nsJSPrincipals::get(report->originPrincipals),
|
||||||
new ScriptErrorEvent(JS_GetRuntime(cx),
|
scriptPrincipal->GetPrincipal(),
|
||||||
report,
|
win,
|
||||||
message,
|
exception,
|
||||||
nsJSPrincipals::get(report->originPrincipals),
|
/* We do not try to report Out Of Memory via a dom
|
||||||
scriptPrincipal->GetPrincipal(),
|
* event because the dom event handler would
|
||||||
win,
|
* encounter an OOM exception trying to process the
|
||||||
exception,
|
* event, and then we'd need to generate a new OOM
|
||||||
/* We do not try to report Out Of Memory via a dom
|
* event for that new OOM instance -- this isn't
|
||||||
* event because the dom event handler would
|
* pretty.
|
||||||
* encounter an OOM exception trying to process the
|
*/
|
||||||
* event, and then we'd need to generate a new OOM
|
report->errorNumber != JSMSG_OUT_OF_MEMORY));
|
||||||
* event for that new OOM instance -- this isn't
|
|
||||||
* pretty.
|
|
||||||
*/
|
|
||||||
report->errorNumber != JSMSG_OUT_OF_MEMORY));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nsContentUtils::DOMWindowDumpEnabled()) {
|
if (nsContentUtils::DOMWindowDumpEnabled()) {
|
||||||
|
@ -63,21 +63,6 @@ nsJSUtils::GetStaticScriptContext(JSObject* aObj)
|
|||||||
return nativeGlobal->GetScriptContext();
|
return nativeGlobal->GetScriptContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIScriptGlobalObject *
|
|
||||||
nsJSUtils::GetDynamicScriptGlobal(JSContext* aContext)
|
|
||||||
{
|
|
||||||
nsIScriptContext *scriptCX = GetDynamicScriptContext(aContext);
|
|
||||||
if (!scriptCX)
|
|
||||||
return nullptr;
|
|
||||||
return scriptCX->GetGlobalObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIScriptContext *
|
|
||||||
nsJSUtils::GetDynamicScriptContext(JSContext *aContext)
|
|
||||||
{
|
|
||||||
return GetScriptContextFromJSContext(aContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
nsJSUtils::GetCurrentlyRunningCodeInnerWindowID(JSContext *aContext)
|
nsJSUtils::GetCurrentlyRunningCodeInnerWindowID(JSContext *aContext)
|
||||||
{
|
{
|
||||||
|
@ -32,10 +32,6 @@ public:
|
|||||||
|
|
||||||
static nsIScriptContext *GetStaticScriptContext(JSObject* aObj);
|
static nsIScriptContext *GetStaticScriptContext(JSObject* aObj);
|
||||||
|
|
||||||
static nsIScriptGlobalObject *GetDynamicScriptGlobal(JSContext *aContext);
|
|
||||||
|
|
||||||
static nsIScriptContext *GetDynamicScriptContext(JSContext *aContext);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the inner window ID based on the given JSContext.
|
* Retrieve the inner window ID based on the given JSContext.
|
||||||
*
|
*
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "nsITextToSubURI.h"
|
#include "nsITextToSubURI.h"
|
||||||
#include "nsJSUtils.h"
|
#include "nsJSUtils.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
|
#include "nsGlobalWindow.h"
|
||||||
#include "mozilla/Likely.h"
|
#include "mozilla/Likely.h"
|
||||||
#include "nsCycleCollectionParticipant.h"
|
#include "nsCycleCollectionParticipant.h"
|
||||||
#include "nsNullPrincipal.h"
|
#include "nsNullPrincipal.h"
|
||||||
@ -42,15 +43,8 @@ GetDocumentCharacterSetForURI(const nsAString& aHref, nsACString& aCharset)
|
|||||||
{
|
{
|
||||||
aCharset.Truncate();
|
aCharset.Truncate();
|
||||||
|
|
||||||
JSContext *cx = nsContentUtils::GetCurrentJSContext();
|
if (nsIDocument* doc = GetEntryDocument()) {
|
||||||
if (cx) {
|
aCharset = doc->GetDocumentCharacterSet();
|
||||||
nsCOMPtr<nsPIDOMWindow> window =
|
|
||||||
do_QueryInterface(nsJSUtils::GetDynamicScriptGlobal(cx));
|
|
||||||
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
|
|
||||||
|
|
||||||
if (nsIDocument* doc = window->GetDoc()) {
|
|
||||||
aCharset = doc->GetDocumentCharacterSet();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -545,23 +539,23 @@ nsLocation::SetHrefWithBase(const nsAString& aHref, nsIURI* aBase,
|
|||||||
* anywhere else. This is part of solution for bug # 39938, 72197
|
* anywhere else. This is part of solution for bug # 39938, 72197
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
bool inScriptTag=false;
|
bool inScriptTag = false;
|
||||||
JSContext *cx = nsContentUtils::GetCurrentJSContext();
|
nsIScriptContext* scriptContext = nullptr;
|
||||||
if (cx) {
|
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(GetEntryGlobal());
|
||||||
nsIScriptContext *scriptContext =
|
if (win) {
|
||||||
nsJSUtils::GetDynamicScriptContext(cx);
|
scriptContext = static_cast<nsGlobalWindow*>(win.get())->GetContextInternal();
|
||||||
|
}
|
||||||
|
|
||||||
if (scriptContext) {
|
if (scriptContext) {
|
||||||
if (scriptContext->GetProcessingScriptTag()) {
|
if (scriptContext->GetProcessingScriptTag()) {
|
||||||
// Now check to make sure that the script is running in our window,
|
// Now check to make sure that the script is running in our window,
|
||||||
// since we only want to replace if the location is set by a
|
// since we only want to replace if the location is set by a
|
||||||
// <script> tag in the same window. See bug 178729.
|
// <script> tag in the same window. See bug 178729.
|
||||||
nsCOMPtr<nsIScriptGlobalObject> ourGlobal =
|
nsCOMPtr<nsIScriptGlobalObject> ourGlobal =
|
||||||
docShell ? docShell->GetScriptGlobalObject() : nullptr;
|
docShell ? docShell->GetScriptGlobalObject() : nullptr;
|
||||||
inScriptTag = (ourGlobal == scriptContext->GetGlobalObject());
|
inScriptTag = (ourGlobal == scriptContext->GetGlobalObject());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} //cx
|
}
|
||||||
|
|
||||||
return SetURI(newUri, aReplace || inScriptTag);
|
return SetURI(newUri, aReplace || inScriptTag);
|
||||||
}
|
}
|
||||||
@ -1020,22 +1014,20 @@ nsLocation::ValueOf(nsIDOMLocation** aReturn)
|
|||||||
nsresult
|
nsresult
|
||||||
nsLocation::GetSourceBaseURL(JSContext* cx, nsIURI** sourceURL)
|
nsLocation::GetSourceBaseURL(JSContext* cx, nsIURI** sourceURL)
|
||||||
{
|
{
|
||||||
|
|
||||||
*sourceURL = nullptr;
|
*sourceURL = nullptr;
|
||||||
nsCOMPtr<nsIScriptGlobalObject> sgo = nsJSUtils::GetDynamicScriptGlobal(cx);
|
nsIDocument* doc = GetEntryDocument();
|
||||||
// If this JS context doesn't have an associated DOM window, we effectively
|
// If there's no entry document, we either have no Script Entry Point or one
|
||||||
// have no script entry point stack. This doesn't generally happen with the DOM,
|
// that isn't a DOM Window. This doesn't generally happen with the DOM,
|
||||||
// but can sometimes happen with extension code in certain IPC configurations.
|
// but can sometimes happen with extension code in certain IPC configurations.
|
||||||
// If this happens, try falling back on the current document associated with
|
// If this happens, try falling back on the current document associated with
|
||||||
// the docshell. If that fails, just return null and hope that the caller passed
|
// the docshell. If that fails, just return null and hope that the caller passed
|
||||||
// an absolute URI.
|
// an absolute URI.
|
||||||
if (!sgo && GetDocShell()) {
|
if (!doc && GetDocShell()) {
|
||||||
sgo = GetDocShell()->GetScriptGlobalObject();
|
nsCOMPtr<nsPIDOMWindow> docShellWin = do_QueryInterface(GetDocShell()->GetScriptGlobalObject());
|
||||||
|
if (docShellWin) {
|
||||||
|
doc = docShellWin->GetDoc();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
NS_ENSURE_TRUE(sgo, NS_OK);
|
|
||||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(sgo);
|
|
||||||
NS_ENSURE_TRUE(window, NS_ERROR_UNEXPECTED);
|
|
||||||
nsIDocument* doc = window->GetDoc();
|
|
||||||
NS_ENSURE_TRUE(doc, NS_OK);
|
NS_ENSURE_TRUE(doc, NS_OK);
|
||||||
*sourceURL = doc->GetBaseURI().take();
|
*sourceURL = doc->GetBaseURI().take();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -192,12 +192,7 @@ public:
|
|||||||
|
|
||||||
bool IsLoadingOrRunningTimeout() const
|
bool IsLoadingOrRunningTimeout() const
|
||||||
{
|
{
|
||||||
const nsPIDOMWindow *win = GetCurrentInnerWindow();
|
const nsPIDOMWindow* win = IsInnerWindow() ? this : GetCurrentInnerWindow();
|
||||||
|
|
||||||
if (!win) {
|
|
||||||
win = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
return !win->mIsDocumentLoaded || win->mRunningTimeout;
|
return !win->mIsDocumentLoaded || win->mRunningTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,6 +294,7 @@ public:
|
|||||||
|
|
||||||
nsPIDOMWindow *GetCurrentInnerWindow() const
|
nsPIDOMWindow *GetCurrentInnerWindow() const
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(IsOuterWindow());
|
||||||
return mInnerWindow;
|
return mInnerWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,8 @@ AddNonJSSizeOfWindowAndItsDescendents(nsGlobalWindow* aWindow,
|
|||||||
|
|
||||||
// Measure the inner window, if there is one.
|
// Measure the inner window, if there is one.
|
||||||
nsWindowSizes innerWindowSizes(moz_malloc_size_of);
|
nsWindowSizes innerWindowSizes(moz_malloc_size_of);
|
||||||
nsGlobalWindow* inner = aWindow->GetCurrentInnerWindowInternal();
|
nsGlobalWindow* inner = aWindow->IsOuterWindow() ? aWindow->GetCurrentInnerWindowInternal()
|
||||||
|
: nullptr;
|
||||||
if (inner) {
|
if (inner) {
|
||||||
inner->AddSizeOfIncludingThis(&innerWindowSizes);
|
inner->AddSizeOfIncludingThis(&innerWindowSizes);
|
||||||
innerWindowSizes.addToTabSizes(aSizes);
|
innerWindowSizes.addToTabSizes(aSizes);
|
||||||
|
@ -2645,5 +2645,12 @@ AssertReturnTypeMatchesJitinfo(const JSJitInfo* aJitInfo,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool
|
||||||
|
CallerSubsumes(JSObject *aObject)
|
||||||
|
{
|
||||||
|
nsIPrincipal* objPrin = nsContentUtils::ObjectPrincipal(js::UncheckedUnwrap(aObject));
|
||||||
|
return nsContentUtils::SubjectPrincipal()->Subsumes(objPrin);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
@ -2937,6 +2937,18 @@ AssertReturnTypeMatchesJitinfo(const JSJitInfo* aJitinfo,
|
|||||||
bool
|
bool
|
||||||
CheckPermissions(JSContext* aCx, JSObject* aObj, const char* const aPermissions[]);
|
CheckPermissions(JSContext* aCx, JSObject* aObj, const char* const aPermissions[]);
|
||||||
|
|
||||||
|
bool
|
||||||
|
CallerSubsumes(JSObject* aObject);
|
||||||
|
|
||||||
|
MOZ_ALWAYS_INLINE bool
|
||||||
|
CallerSubsumes(JS::Handle<JS::Value> aValue)
|
||||||
|
{
|
||||||
|
if (!aValue.isObject()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return CallerSubsumes(&aValue.toObject());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
@ -1053,11 +1053,6 @@ DOMInterfaces = {
|
|||||||
'headerFile': 'mozilla/dom/workers/bindings/ServiceWorker.h',
|
'headerFile': 'mozilla/dom/workers/bindings/ServiceWorker.h',
|
||||||
},
|
},
|
||||||
|
|
||||||
'ServiceWorkerContainer': {
|
|
||||||
'nativeType': 'mozilla::dom::workers::ServiceWorkerContainer',
|
|
||||||
'headerFile': 'mozilla/dom/ServiceWorkerContainer.h',
|
|
||||||
},
|
|
||||||
|
|
||||||
'ServiceWorkerGlobalScope': {
|
'ServiceWorkerGlobalScope': {
|
||||||
'headerFile': 'mozilla/dom/WorkerScope.h',
|
'headerFile': 'mozilla/dom/WorkerScope.h',
|
||||||
'workers': True,
|
'workers': True,
|
||||||
|
@ -3572,6 +3572,9 @@ class JSToNativeConversionInfo():
|
|||||||
for whether we have a JS::Value. Only used when
|
for whether we have a JS::Value. Only used when
|
||||||
defaultValue is not None or when True is passed for
|
defaultValue is not None or when True is passed for
|
||||||
checkForValue to instantiateJSToNativeConversion.
|
checkForValue to instantiateJSToNativeConversion.
|
||||||
|
${passedToJSImpl} replaced by an expression that evaluates to a boolean
|
||||||
|
for whether this value is being passed to a JS-
|
||||||
|
implemented interface.
|
||||||
|
|
||||||
declType: A CGThing representing the native C++ type we're converting
|
declType: A CGThing representing the native C++ type we're converting
|
||||||
to. This is allowed to be None if the conversion code is
|
to. This is allowed to be None if the conversion code is
|
||||||
@ -3827,7 +3830,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||||||
return templateBody
|
return templateBody
|
||||||
|
|
||||||
# A helper function for converting things that look like a JSObject*.
|
# A helper function for converting things that look like a JSObject*.
|
||||||
def handleJSObjectType(type, isMember, failureCode):
|
def handleJSObjectType(type, isMember, failureCode, exceptionCode, sourceDescription):
|
||||||
if not isMember:
|
if not isMember:
|
||||||
if isOptional:
|
if isOptional:
|
||||||
# We have a specialization of Optional that will use a
|
# We have a specialization of Optional that will use a
|
||||||
@ -3843,6 +3846,19 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||||||
declType = CGGeneric("JSObject*")
|
declType = CGGeneric("JSObject*")
|
||||||
declArgs = None
|
declArgs = None
|
||||||
templateBody = "${declName} = &${val}.toObject();\n"
|
templateBody = "${declName} = &${val}.toObject();\n"
|
||||||
|
|
||||||
|
# For JS-implemented APIs, we refuse to allow passing objects that the
|
||||||
|
# API consumer does not subsume.
|
||||||
|
if not isinstance(descriptorProvider, Descriptor) or descriptorProvider.interface.isJSImplemented():
|
||||||
|
templateBody = fill("""
|
||||||
|
if ($${passedToJSImpl} && !CallerSubsumes($${val})) {
|
||||||
|
ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "${sourceDescription}");
|
||||||
|
$*{exceptionCode}
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
sourceDescription=sourceDescription,
|
||||||
|
exceptionCode=exceptionCode) + templateBody
|
||||||
|
|
||||||
setToNullCode = "${declName} = nullptr;\n"
|
setToNullCode = "${declName} = nullptr;\n"
|
||||||
template = wrapObjectTemplate(templateBody, type, setToNullCode,
|
template = wrapObjectTemplate(templateBody, type, setToNullCode,
|
||||||
failureCode)
|
failureCode)
|
||||||
@ -3917,7 +3933,8 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||||||
# We only need holderName here to handle isExternal()
|
# We only need holderName here to handle isExternal()
|
||||||
# interfaces, which use an internal holder for the
|
# interfaces, which use an internal holder for the
|
||||||
# conversion even when forceOwningType ends up true.
|
# conversion even when forceOwningType ends up true.
|
||||||
"holderName": "tempHolder"
|
"holderName": "tempHolder",
|
||||||
|
"passedToJSImpl": "${passedToJSImpl}"
|
||||||
})
|
})
|
||||||
|
|
||||||
# NOTE: Keep this in sync with variadic conversions as needed
|
# NOTE: Keep this in sync with variadic conversions as needed
|
||||||
@ -4021,7 +4038,8 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||||||
# We only need holderName here to handle isExternal()
|
# We only need holderName here to handle isExternal()
|
||||||
# interfaces, which use an internal holder for the
|
# interfaces, which use an internal holder for the
|
||||||
# conversion even when forceOwningType ends up true.
|
# conversion even when forceOwningType ends up true.
|
||||||
"holderName": "tempHolder"
|
"holderName": "tempHolder",
|
||||||
|
"passedToJSImpl": "${passedToJSImpl}"
|
||||||
})
|
})
|
||||||
|
|
||||||
templateBody = fill(
|
templateBody = fill(
|
||||||
@ -4114,7 +4132,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||||||
for memberType in interfaceMemberTypes:
|
for memberType in interfaceMemberTypes:
|
||||||
name = getUnionMemberName(memberType)
|
name = getUnionMemberName(memberType)
|
||||||
interfaceObject.append(
|
interfaceObject.append(
|
||||||
CGGeneric("(failed = !%s.TrySetTo%s(cx, ${val}, tryNext)) || !tryNext" %
|
CGGeneric("(failed = !%s.TrySetTo%s(cx, ${val}, tryNext, ${passedToJSImpl})) || !tryNext" %
|
||||||
(unionArgumentObj, name)))
|
(unionArgumentObj, name)))
|
||||||
names.append(name)
|
names.append(name)
|
||||||
interfaceObject = CGWrapper(CGList(interfaceObject, " ||\n"),
|
interfaceObject = CGWrapper(CGList(interfaceObject, " ||\n"),
|
||||||
@ -4127,7 +4145,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||||||
assert len(arrayObjectMemberTypes) == 1
|
assert len(arrayObjectMemberTypes) == 1
|
||||||
name = getUnionMemberName(arrayObjectMemberTypes[0])
|
name = getUnionMemberName(arrayObjectMemberTypes[0])
|
||||||
arrayObject = CGGeneric(
|
arrayObject = CGGeneric(
|
||||||
"done = (failed = !%s.TrySetTo%s(cx, ${val}, tryNext)) || !tryNext;\n" %
|
"done = (failed = !%s.TrySetTo%s(cx, ${val}, tryNext, ${passedToJSImpl})) || !tryNext;\n" %
|
||||||
(unionArgumentObj, name))
|
(unionArgumentObj, name))
|
||||||
names.append(name)
|
names.append(name)
|
||||||
else:
|
else:
|
||||||
@ -4151,7 +4169,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||||||
memberType = callbackMemberTypes[0]
|
memberType = callbackMemberTypes[0]
|
||||||
name = getUnionMemberName(memberType)
|
name = getUnionMemberName(memberType)
|
||||||
callbackObject = CGGeneric(
|
callbackObject = CGGeneric(
|
||||||
"done = (failed = !%s.TrySetTo%s(cx, ${val}, tryNext)) || !tryNext;\n" %
|
"done = (failed = !%s.TrySetTo%s(cx, ${val}, tryNext, ${passedToJSImpl})) || !tryNext;\n" %
|
||||||
(unionArgumentObj, name))
|
(unionArgumentObj, name))
|
||||||
names.append(name)
|
names.append(name)
|
||||||
else:
|
else:
|
||||||
@ -4162,7 +4180,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||||||
assert len(dictionaryMemberTypes) == 1
|
assert len(dictionaryMemberTypes) == 1
|
||||||
name = getUnionMemberName(dictionaryMemberTypes[0])
|
name = getUnionMemberName(dictionaryMemberTypes[0])
|
||||||
setDictionary = CGGeneric(
|
setDictionary = CGGeneric(
|
||||||
"done = (failed = !%s.TrySetTo%s(cx, ${val}, tryNext)) || !tryNext;\n" %
|
"done = (failed = !%s.TrySetTo%s(cx, ${val}, tryNext, ${passedToJSImpl})) || !tryNext;\n" %
|
||||||
(unionArgumentObj, name))
|
(unionArgumentObj, name))
|
||||||
names.append(name)
|
names.append(name)
|
||||||
else:
|
else:
|
||||||
@ -4173,7 +4191,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||||||
assert len(mozMapMemberTypes) == 1
|
assert len(mozMapMemberTypes) == 1
|
||||||
name = getUnionMemberName(mozMapMemberTypes[0])
|
name = getUnionMemberName(mozMapMemberTypes[0])
|
||||||
mozMapObject = CGGeneric(
|
mozMapObject = CGGeneric(
|
||||||
"done = (failed = !%s.TrySetTo%s(cx, ${val}, tryNext)) || !tryNext;\n" %
|
"done = (failed = !%s.TrySetTo%s(cx, ${val}, tryNext, ${passedToJSImpl})) || !tryNext;\n" %
|
||||||
(unionArgumentObj, name))
|
(unionArgumentObj, name))
|
||||||
names.append(name)
|
names.append(name)
|
||||||
else:
|
else:
|
||||||
@ -4185,8 +4203,10 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||||||
# Very important to NOT construct a temporary Rooted here, since the
|
# Very important to NOT construct a temporary Rooted here, since the
|
||||||
# SetToObject call can call a Rooted constructor and we need to keep
|
# SetToObject call can call a Rooted constructor and we need to keep
|
||||||
# stack discipline for Rooted.
|
# stack discipline for Rooted.
|
||||||
object = CGGeneric("%s.SetToObject(cx, &${val}.toObject());\n"
|
object = CGGeneric("if (!%s.SetToObject(cx, &${val}.toObject(), ${passedToJSImpl})) {\n"
|
||||||
"done = true;\n" % unionArgumentObj)
|
"%s"
|
||||||
|
"}\n"
|
||||||
|
"done = true;\n" % (unionArgumentObj, indent(exceptionCode)))
|
||||||
names.append(objectMemberTypes[0].name)
|
names.append(objectMemberTypes[0].name)
|
||||||
else:
|
else:
|
||||||
object = None
|
object = None
|
||||||
@ -4425,7 +4445,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||||||
if descriptor.nativeType == 'JSObject':
|
if descriptor.nativeType == 'JSObject':
|
||||||
# XXXbz Workers code does this sometimes
|
# XXXbz Workers code does this sometimes
|
||||||
assert descriptor.workers
|
assert descriptor.workers
|
||||||
return handleJSObjectType(type, isMember, failureCode)
|
return handleJSObjectType(type, isMember, failureCode, exceptionCode, sourceDescription)
|
||||||
|
|
||||||
if descriptor.interface.isCallback():
|
if descriptor.interface.isCallback():
|
||||||
name = descriptor.interface.identifier.name
|
name = descriptor.interface.identifier.name
|
||||||
@ -4507,7 +4527,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||||||
isCallbackReturnValue,
|
isCallbackReturnValue,
|
||||||
firstCap(sourceDescription)))
|
firstCap(sourceDescription)))
|
||||||
elif descriptor.workers:
|
elif descriptor.workers:
|
||||||
return handleJSObjectType(type, isMember, failureCode)
|
return handleJSObjectType(type, isMember, failureCode, exceptionCode, sourceDescription)
|
||||||
else:
|
else:
|
||||||
# Either external, or new-binding non-castable. We always have a
|
# Either external, or new-binding non-castable. We always have a
|
||||||
# holder for these, because we don't actually know whether we have
|
# holder for these, because we don't actually know whether we have
|
||||||
@ -4826,6 +4846,19 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||||||
|
|
||||||
assert not isOptional
|
assert not isOptional
|
||||||
templateBody = "${declName} = ${val};\n"
|
templateBody = "${declName} = ${val};\n"
|
||||||
|
|
||||||
|
# For JS-implemented APIs, we refuse to allow passing objects that the
|
||||||
|
# API consumer does not subsume.
|
||||||
|
if not isinstance(descriptorProvider, Descriptor) or descriptorProvider.interface.isJSImplemented():
|
||||||
|
templateBody = fill("""
|
||||||
|
if ($${passedToJSImpl} && !CallerSubsumes($${val})) {
|
||||||
|
ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "${sourceDescription}");
|
||||||
|
$*{exceptionCode}
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
sourceDescription=sourceDescription,
|
||||||
|
exceptionCode=exceptionCode) + templateBody
|
||||||
|
|
||||||
# We may not have a default value if we're being converted for
|
# We may not have a default value if we're being converted for
|
||||||
# a setter, say.
|
# a setter, say.
|
||||||
if defaultValue:
|
if defaultValue:
|
||||||
@ -4841,7 +4874,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||||||
|
|
||||||
if type.isObject():
|
if type.isObject():
|
||||||
assert not isEnforceRange and not isClamp
|
assert not isEnforceRange and not isClamp
|
||||||
return handleJSObjectType(type, isMember, failureCode)
|
return handleJSObjectType(type, isMember, failureCode, exceptionCode, sourceDescription)
|
||||||
|
|
||||||
if type.isDictionary():
|
if type.isDictionary():
|
||||||
# There are no nullable dictionaries
|
# There are no nullable dictionaries
|
||||||
@ -4891,7 +4924,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||||||
if type.nullable():
|
if type.nullable():
|
||||||
dictLoc += ".SetValue()"
|
dictLoc += ".SetValue()"
|
||||||
|
|
||||||
template += ('if (!%s.Init(cx, %s, "%s")) {\n'
|
template += ('if (!%s.Init(cx, %s, "%s", ${passedToJSImpl})) {\n'
|
||||||
"%s"
|
"%s"
|
||||||
"}\n" % (dictLoc, val, firstCap(sourceDescription),
|
"}\n" % (dictLoc, val, firstCap(sourceDescription),
|
||||||
exceptionCodeIndented.define()))
|
exceptionCodeIndented.define()))
|
||||||
@ -5167,7 +5200,8 @@ class CGArgumentConverter(CGThing):
|
|||||||
self.replacementVariables = {
|
self.replacementVariables = {
|
||||||
"declName": "arg%d" % index,
|
"declName": "arg%d" % index,
|
||||||
"holderName": ("arg%d" % index) + "_holder",
|
"holderName": ("arg%d" % index) + "_holder",
|
||||||
"obj": "obj"
|
"obj": "obj",
|
||||||
|
"passedToJSImpl": toStringBool(isJSImplementedDescriptor(descriptorProvider))
|
||||||
}
|
}
|
||||||
self.replacementVariables["val"] = string.Template(
|
self.replacementVariables["val"] = string.Template(
|
||||||
"args[${index}]").substitute(replacer)
|
"args[${index}]").substitute(replacer)
|
||||||
@ -5245,7 +5279,8 @@ class CGArgumentConverter(CGThing):
|
|||||||
# conversion even when forceOwningType ends up true.
|
# conversion even when forceOwningType ends up true.
|
||||||
"holderName": "tempHolder",
|
"holderName": "tempHolder",
|
||||||
# Use the same ${obj} as for the variadic arg itself
|
# Use the same ${obj} as for the variadic arg itself
|
||||||
"obj": replacer["obj"]
|
"obj": replacer["obj"],
|
||||||
|
"passedToJSImpl": toStringBool(isJSImplementedDescriptor(self.descriptorProvider))
|
||||||
}), 4)
|
}), 4)
|
||||||
|
|
||||||
variadicConversion += (" }\n"
|
variadicConversion += (" }\n"
|
||||||
@ -6741,7 +6776,8 @@ class CGMethodCall(CGThing):
|
|||||||
"holderName": ("arg%d" % distinguishingIndex) + "_holder",
|
"holderName": ("arg%d" % distinguishingIndex) + "_holder",
|
||||||
"val": distinguishingArg,
|
"val": distinguishingArg,
|
||||||
"obj": "obj",
|
"obj": "obj",
|
||||||
"haveValue": "args.hasDefined(%d)" % distinguishingIndex
|
"haveValue": "args.hasDefined(%d)" % distinguishingIndex,
|
||||||
|
"passedToJSImpl": toStringBool(isJSImplementedDescriptor(descriptor))
|
||||||
},
|
},
|
||||||
checkForValue=argIsOptional)
|
checkForValue=argIsOptional)
|
||||||
caseBody.append(CGIndenter(testCode, indent))
|
caseBody.append(CGIndenter(testCode, indent))
|
||||||
@ -8316,9 +8352,22 @@ def getUnionTypeTemplateVars(unionType, type, descriptorProvider,
|
|||||||
mUnion.mValue.mObject.SetValue(cx, obj);
|
mUnion.mValue.mObject.SetValue(cx, obj);
|
||||||
mUnion.mType = mUnion.eObject;
|
mUnion.mType = mUnion.eObject;
|
||||||
""")
|
""")
|
||||||
setter = ClassMethod("SetToObject", "void",
|
|
||||||
|
# It's a bit sketchy to do the security check after setting the value,
|
||||||
|
# but it keeps the code cleaner and lets us avoid rooting |obj| over the
|
||||||
|
# call to CallerSubsumes().
|
||||||
|
body = body + dedent("""
|
||||||
|
if (passedToJSImpl && !CallerSubsumes(obj)) {
|
||||||
|
ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "%s");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
""")
|
||||||
|
|
||||||
|
setter = ClassMethod("SetToObject", "bool",
|
||||||
[Argument("JSContext*", "cx"),
|
[Argument("JSContext*", "cx"),
|
||||||
Argument("JSObject*", "obj")],
|
Argument("JSObject*", "obj"),
|
||||||
|
Argument("bool", "passedToJSImpl", default="false")],
|
||||||
inline=True, bodyInHeader=True,
|
inline=True, bodyInHeader=True,
|
||||||
body=body)
|
body=body)
|
||||||
|
|
||||||
@ -8338,7 +8387,8 @@ def getUnionTypeTemplateVars(unionType, type, descriptorProvider,
|
|||||||
val="value",
|
val="value",
|
||||||
declName="memberSlot",
|
declName="memberSlot",
|
||||||
holderName=(holderName if ownsMembers else "%s.ref()" % holderName),
|
holderName=(holderName if ownsMembers else "%s.ref()" % holderName),
|
||||||
destroyHolder=destroyHolder)
|
destroyHolder=destroyHolder,
|
||||||
|
passedToJSImpl="passedToJSImpl")
|
||||||
|
|
||||||
jsConversion = fill(
|
jsConversion = fill(
|
||||||
"""
|
"""
|
||||||
@ -8357,7 +8407,8 @@ def getUnionTypeTemplateVars(unionType, type, descriptorProvider,
|
|||||||
setter = ClassMethod("TrySetTo" + name, "bool",
|
setter = ClassMethod("TrySetTo" + name, "bool",
|
||||||
[Argument("JSContext*", "cx"),
|
[Argument("JSContext*", "cx"),
|
||||||
Argument("JS::Handle<JS::Value>", "value"),
|
Argument("JS::Handle<JS::Value>", "value"),
|
||||||
Argument("bool&", "tryNext")],
|
Argument("bool&", "tryNext"),
|
||||||
|
Argument("bool", "passedToJSImpl", default="false")],
|
||||||
inline=not ownsMembers,
|
inline=not ownsMembers,
|
||||||
bodyInHeader=not ownsMembers,
|
bodyInHeader=not ownsMembers,
|
||||||
body=jsConversion)
|
body=jsConversion)
|
||||||
@ -9463,7 +9514,8 @@ class CGProxySpecialOperation(CGPerSignatureCall):
|
|||||||
"declName": argument.identifier.name,
|
"declName": argument.identifier.name,
|
||||||
"holderName": argument.identifier.name + "_holder",
|
"holderName": argument.identifier.name + "_holder",
|
||||||
"val": argumentMutableValue,
|
"val": argumentMutableValue,
|
||||||
"obj": "obj"
|
"obj": "obj",
|
||||||
|
"passedToJSImpl": "false"
|
||||||
}
|
}
|
||||||
self.cgRoot.prepend(instantiateJSToNativeConversion(info, templateValues))
|
self.cgRoot.prepend(instantiateJSToNativeConversion(info, templateValues))
|
||||||
elif operation.isGetter() or operation.isDeleter():
|
elif operation.isGetter() or operation.isDeleter():
|
||||||
@ -11087,7 +11139,8 @@ class CGDictionary(CGThing):
|
|||||||
return ClassMethod("Init", "bool", [
|
return ClassMethod("Init", "bool", [
|
||||||
Argument('JSContext*', 'cx'),
|
Argument('JSContext*', 'cx'),
|
||||||
Argument('JS::Handle<JS::Value>', 'val'),
|
Argument('JS::Handle<JS::Value>', 'val'),
|
||||||
Argument('const char*', 'sourceDescription', default='"Value"')
|
Argument('const char*', 'sourceDescription', default='"Value"'),
|
||||||
|
Argument('bool', 'passedToJSImpl', default='false')
|
||||||
], body=body)
|
], body=body)
|
||||||
|
|
||||||
def initFromJSONMethod(self):
|
def initFromJSONMethod(self):
|
||||||
@ -11322,7 +11375,8 @@ class CGDictionary(CGThing):
|
|||||||
# We need a holder name for external interfaces, but
|
# We need a holder name for external interfaces, but
|
||||||
# it's scoped down to the conversion so we can just use
|
# it's scoped down to the conversion so we can just use
|
||||||
# anything we want.
|
# anything we want.
|
||||||
"holderName": "holder"
|
"holderName": "holder",
|
||||||
|
"passedToJSImpl": "passedToJSImpl"
|
||||||
}
|
}
|
||||||
# We can't handle having a holderType here
|
# We can't handle having a holderType here
|
||||||
assert conversionInfo.holderType is None
|
assert conversionInfo.holderType is None
|
||||||
@ -11458,6 +11512,11 @@ class CGDictionary(CGThing):
|
|||||||
trace = CGGeneric('%s.TraceSelf(trc);\n' % memberData)
|
trace = CGGeneric('%s.TraceSelf(trc);\n' % memberData)
|
||||||
if type.nullable():
|
if type.nullable():
|
||||||
trace = CGIfWrapper(trace, "!%s.IsNull()" % memberNullable)
|
trace = CGIfWrapper(trace, "!%s.IsNull()" % memberNullable)
|
||||||
|
elif type.isMozMap():
|
||||||
|
# If you implement this, add a MozMap<object> to
|
||||||
|
# TestInterfaceJSDictionary and test it in test_bug1036214.html
|
||||||
|
# to make sure we end up with the correct security properties.
|
||||||
|
assert False
|
||||||
else:
|
else:
|
||||||
assert False # unknown type
|
assert False # unknown type
|
||||||
|
|
||||||
@ -13389,7 +13448,8 @@ class CallbackMember(CGNativeMember):
|
|||||||
# We actually want to pass in a null scope object here, because
|
# We actually want to pass in a null scope object here, because
|
||||||
# wrapping things into our current compartment (that of mCallback)
|
# wrapping things into our current compartment (that of mCallback)
|
||||||
# is what we want.
|
# is what we want.
|
||||||
"obj": "nullptr"
|
"obj": "nullptr",
|
||||||
|
"passedToJSImpl": "false"
|
||||||
}
|
}
|
||||||
|
|
||||||
if isJSImplementedDescriptor(self.descriptorProvider):
|
if isJSImplementedDescriptor(self.descriptorProvider):
|
||||||
|
@ -58,3 +58,4 @@ MSG_DEF(MSG_HEADERS_IMMUTABLE, 0, "Headers are immutable and cannot be modified.
|
|||||||
MSG_DEF(MSG_INVALID_HEADER_NAME, 1, "{0} is an invalid header name.")
|
MSG_DEF(MSG_INVALID_HEADER_NAME, 1, "{0} is an invalid header name.")
|
||||||
MSG_DEF(MSG_INVALID_HEADER_VALUE, 1, "{0} is an invalid header value.")
|
MSG_DEF(MSG_INVALID_HEADER_VALUE, 1, "{0} is an invalid header value.")
|
||||||
MSG_DEF(MSG_INVALID_HEADER_SEQUENCE, 0, "Headers require name/value tuples when being initialized by a sequence.")
|
MSG_DEF(MSG_INVALID_HEADER_SEQUENCE, 0, "Headers require name/value tuples when being initialized by a sequence.")
|
||||||
|
MSG_DEF(MSG_PERMISSION_DENIED_TO_PASS_ARG, 1, "Permission denied to pass cross-origin object as {0}.")
|
||||||
|
@ -9,17 +9,6 @@ const Ci = Components.interfaces;
|
|||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
Cu.import("resource://gre/modules/Services.jsm");
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
var gGlobal = this;
|
|
||||||
function checkGlobal(obj) {
|
|
||||||
if (Object(obj) === obj && Cu.getGlobalForObject(obj) != gGlobal) {
|
|
||||||
// This message may not make it to the caller in a useful form, so dump
|
|
||||||
// as well.
|
|
||||||
var msg = "TestInterfaceJS received an object from a different scope!";
|
|
||||||
dump(msg + "\n");
|
|
||||||
throw new Error(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function TestInterfaceJS(anyArg, objectArg) {}
|
function TestInterfaceJS(anyArg, objectArg) {}
|
||||||
|
|
||||||
TestInterfaceJS.prototype = {
|
TestInterfaceJS.prototype = {
|
||||||
@ -27,23 +16,32 @@ TestInterfaceJS.prototype = {
|
|||||||
contractID: "@mozilla.org/dom/test-interface-js;1",
|
contractID: "@mozilla.org/dom/test-interface-js;1",
|
||||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
|
||||||
|
|
||||||
__init: function (anyArg, objectArg) {
|
__init: function (anyArg, objectArg, dictionaryArg) {
|
||||||
this._anyAttr = undefined;
|
this._anyAttr = undefined;
|
||||||
this._objectAttr = null;
|
this._objectAttr = null;
|
||||||
this._anyArg = anyArg;
|
this._anyArg = anyArg;
|
||||||
this._objectArg = objectArg;
|
this._objectArg = objectArg;
|
||||||
checkGlobal(anyArg);
|
this._dictionaryArg = dictionaryArg;
|
||||||
checkGlobal(objectArg);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
get anyArg() { return this._anyArg; },
|
get anyArg() { return this._anyArg; },
|
||||||
get objectArg() { return this._objectArg; },
|
get objectArg() { return this._objectArg; },
|
||||||
|
get dictionaryArg() { return this._dictionaryArg; },
|
||||||
get anyAttr() { return this._anyAttr; },
|
get anyAttr() { return this._anyAttr; },
|
||||||
set anyAttr(val) { checkGlobal(val); this._anyAttr = val; },
|
set anyAttr(val) { this._anyAttr = val; },
|
||||||
get objectAttr() { return this._objectAttr; },
|
get objectAttr() { return this._objectAttr; },
|
||||||
set objectAttr(val) { checkGlobal(val); this._objectAttr = val; },
|
set objectAttr(val) { this._objectAttr = val; },
|
||||||
pingPongAny: function(any) { checkGlobal(any); return any; },
|
get dictionaryAttr() { return this._dictionaryAttr; },
|
||||||
pingPongObject: function(obj) { checkGlobal(obj); return obj; },
|
set dictionaryAttr(val) { this._dictionaryAttr = val; },
|
||||||
|
pingPongAny: function(any) { return any; },
|
||||||
|
pingPongObject: function(obj) { return obj; },
|
||||||
|
pingPongObjectOrString: function(objectOrString) { return objectOrString; },
|
||||||
|
pingPongDictionary: function(dict) { return dict; },
|
||||||
|
pingPongDictionaryOrLong: function(dictOrLong) { return dictOrLong.anyMember || dictOrLong; },
|
||||||
|
pingPongMap: function(map) { return JSON.stringify(map); },
|
||||||
|
objectSequenceLength: function(seq) { return seq.length; },
|
||||||
|
anySequenceLength: function(seq) { return seq.length; },
|
||||||
|
|
||||||
|
|
||||||
getCallerPrincipal: function() { return Cu.getWebIDLCallerPrincipal().origin; },
|
getCallerPrincipal: function() { return Cu.getWebIDLCallerPrincipal().origin; },
|
||||||
|
|
||||||
|
@ -17,10 +17,8 @@ support-files =
|
|||||||
[test_bug788369.html]
|
[test_bug788369.html]
|
||||||
[test_bug852846.html]
|
[test_bug852846.html]
|
||||||
[test_bug862092.html]
|
[test_bug862092.html]
|
||||||
# When bug 923904 lands, this test can be turned on, but only for debug builds
|
[test_bug1036214.html]
|
||||||
# where we have our test component. So this should become skip-if = debug == false.
|
skip-if = debug == false
|
||||||
[test_bug923904.html]
|
|
||||||
skip-if = true
|
|
||||||
[test_bug1041646.html]
|
[test_bug1041646.html]
|
||||||
[test_barewordGetsWindow.html]
|
[test_barewordGetsWindow.html]
|
||||||
[test_callback_default_thisval.html]
|
[test_callback_default_thisval.html]
|
||||||
|
123
dom/bindings/test/test_bug1036214.html
Normal file
123
dom/bindings/test/test_bug1036214.html
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<!--
|
||||||
|
https://bugzilla.mozilla.org/show_bug.cgi?id=1036214
|
||||||
|
-->
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Test for Bug 1036214</title>
|
||||||
|
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||||
|
<script type="application/javascript">
|
||||||
|
|
||||||
|
/** Test for subsumes-checking |any| and |object| for js-implemented WebIDL. **/
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
var xoObjects = [];
|
||||||
|
function setup() {
|
||||||
|
xoObjects.push(window[0]);
|
||||||
|
xoObjects.push(window[0].location);
|
||||||
|
xoObjects.push(SpecialPowers.unwrap(SpecialPowers.wrap(window[0]).document));
|
||||||
|
xoObjects.push(SpecialPowers);
|
||||||
|
xoObjects.push(SpecialPowers.wrap);
|
||||||
|
SpecialPowers.pushPrefEnv({set: [['dom.expose_test_interfaces', true]]}, go);
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkThrows(f, msg) {
|
||||||
|
try {
|
||||||
|
f();
|
||||||
|
ok(false, "Should have thrown: " + msg);
|
||||||
|
} catch (e) {
|
||||||
|
ok(true, "Threw correctly: " + msg);
|
||||||
|
ok(/denied|insecure/.test(e), "Threw security exception: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function go() {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Test the basics of the test interface.
|
||||||
|
//
|
||||||
|
|
||||||
|
var any = { a: 11 };
|
||||||
|
var obj = { b: 22, c: "str" };
|
||||||
|
var obj2 = { foo: "baz" };
|
||||||
|
var myDict = { anyMember: 42, objectMember: { answer: 42 }, objectOrStringMember: { answer: "anobject" },
|
||||||
|
anySequenceMember: [{}, 1, "thirdinsequence"],
|
||||||
|
innerDictionary: { innerObject: { answer: "rabbithole" } } };
|
||||||
|
var t = new TestInterfaceJS(any, obj, myDict);
|
||||||
|
is(Object.getPrototypeOf(t), TestInterfaceJS.prototype, "Prototype setup works correctly");
|
||||||
|
is(t.anyArg, any, "anyArg is correct");
|
||||||
|
is(t.objectArg, obj, "objectArg is correct");
|
||||||
|
is(t.dictionaryArg.anyMember, 42, "dictionaryArg looks correct");
|
||||||
|
is(t.dictionaryArg.objectMember.answer, 42, "dictionaryArg looks correct");
|
||||||
|
t.anyAttr = 2;
|
||||||
|
is(t.anyAttr, 2, "ping-pong any attribute works");
|
||||||
|
t.objAttr = obj2;
|
||||||
|
is(t.objAttr, obj2, "ping-pong object attribute works");
|
||||||
|
t.dictionaryAttr = myDict;
|
||||||
|
is(t.dictionaryAttr.anyMember, 42, "ping-pong dictionary attribute works");
|
||||||
|
is(t.dictionaryAttr.objectMember.answer, 42, "ping-pong dictionary attribute works");
|
||||||
|
|
||||||
|
is(any, t.pingPongAny(any), "ping-pong works with any");
|
||||||
|
is(obj, t.pingPongObject(obj), "ping-pong works with obj");
|
||||||
|
is(obj, t.pingPongObjectOrString(obj), "ping-pong works with obj or string");
|
||||||
|
is("foo", t.pingPongObjectOrString("foo"), "ping-pong works with obj or string");
|
||||||
|
is(t.pingPongDictionary(myDict).anyMember, 42, "ping pong works with dict");
|
||||||
|
is(t.pingPongDictionary(myDict).objectMember.answer, 42, "ping pong works with dict");
|
||||||
|
is(t.pingPongDictionary(myDict).objectOrStringMember.answer, "anobject", "ping pong works with dict");
|
||||||
|
is(t.pingPongDictionary(myDict).anySequenceMember[2], "thirdinsequence", "ping pong works with dict");
|
||||||
|
is(t.pingPongDictionary(myDict).innerDictionary.innerObject.answer, "rabbithole", "ping pong works with layered dicts");
|
||||||
|
is(t.pingPongDictionaryOrLong({anyMember: 42}), 42, "ping pong (dict or long) works with dict");
|
||||||
|
is(t.pingPongDictionaryOrLong(42), 42, "ping pong (dict or long) works with long");
|
||||||
|
ok(/canary/.test(t.pingPongMap({ someVal: 42, someOtherVal: "canary" })), "ping pong works with mozmap");
|
||||||
|
is(t.objectSequenceLength([{}, {}, {}]), 3, "ping pong works with object sequence");
|
||||||
|
is(t.anySequenceLength([42, 'string', {}, undefined]), 4, "ping pong works with any sequence");
|
||||||
|
|
||||||
|
//
|
||||||
|
// Test that we throw in the cross-origin cases.
|
||||||
|
//
|
||||||
|
|
||||||
|
xoObjects.forEach(function(xoObj) {
|
||||||
|
var blank = new TestInterfaceJS();
|
||||||
|
checkThrows(() => new TestInterfaceJS(xoObj, undefined), "any param for constructor");
|
||||||
|
checkThrows(() => new TestInterfaceJS(undefined, xoObj), "obj param for constructor");
|
||||||
|
checkThrows(() => new TestInterfaceJS(undefined, undefined, { anyMember: xoObj }), "any dict param for constructor");
|
||||||
|
checkThrows(() => new TestInterfaceJS(undefined, undefined, { objectMember: xoObj }), "object dict param for constructor");
|
||||||
|
checkThrows(() => new TestInterfaceJS(undefined, undefined, { objectOrStringMember: xoObj }), "union dict param for constructor");
|
||||||
|
checkThrows(() => new TestInterfaceJS(undefined, undefined, { anySequenceMember: [0, xoObj, 'hi' ] }), "sequence dict param for constructor");
|
||||||
|
checkThrows(() => new TestInterfaceJS(undefined, undefined, { innerDictionary: { innerObject: xoObj } }), "inner dict param for constructor");
|
||||||
|
checkThrows(() => t.anyAttr = xoObj, "anyAttr");
|
||||||
|
checkThrows(() => t.objectAttr = xoObj, "objAttr");
|
||||||
|
checkThrows(() => t.dictionaryAttr = { anyMember: xoObj }, "dictionaryAttr any");
|
||||||
|
checkThrows(() => t.dictionaryAttr = { objectMember: xoObj }, "dictionaryAttr object");
|
||||||
|
checkThrows(() => t.pingPongAny(xoObj), "pingpong any");
|
||||||
|
checkThrows(() => t.pingPongObject(xoObj), "pingpong obj");
|
||||||
|
checkThrows(() => t.pingPongObjectOrString(xoObj), "pingpong union");
|
||||||
|
checkThrows(() => t.pingPongDictionary({ anyMember: xoObj }), "dictionary pingpong any");
|
||||||
|
checkThrows(() => t.pingPongDictionary({ objectMember: xoObj }), "dictionary pingpong object");
|
||||||
|
checkThrows(() => t.pingPongDictionary({ anyMember: xoObj, objectMember: xoObj }), "dictionary pingpong both");
|
||||||
|
checkThrows(() => t.pingPongDictionary({ objectOrStringMember: xoObj }), "dictionary pingpong objectorstring");
|
||||||
|
checkThrows(() => t.pingPongDictionaryOrLong({ objectMember: xoObj }), "unionable dictionary");
|
||||||
|
checkThrows(() => t.pingPongDictionaryOrLong({ anyMember: xoObj }), "unionable dictionary");
|
||||||
|
checkThrows(() => t.pingPongMap({ someMember: 42, someOtherMember: {}, crossOriginMember: xoObj }), "mozmap");
|
||||||
|
checkThrows(() => t.objectSequenceLength([{}, {}, xoObj, {}]), "object sequence");
|
||||||
|
checkThrows(() => t.anySequenceLength([42, 'someString', xoObj, {}]), "any sequence");
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1036214">Mozilla Bug 1036214</a>
|
||||||
|
<p id="display"></p>
|
||||||
|
<div id="content" style="display: none">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<pre id="test">
|
||||||
|
</pre>
|
||||||
|
<iframe id="ifr" onload="setup();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,66 +0,0 @@
|
|||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<!--
|
|
||||||
https://bugzilla.mozilla.org/show_bug.cgi?id=923904
|
|
||||||
-->
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>Test for Bug 923904</title>
|
|
||||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
|
||||||
<script type="application/javascript">
|
|
||||||
|
|
||||||
/** Test for cloning of |any| and |object| for JS-Implemented WebIDL. **/
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
SpecialPowers.pushPrefEnv({set: [['dom.expose_test_interfaces', true]]}, go);
|
|
||||||
|
|
||||||
function go() {
|
|
||||||
var someAny = { a: 11 };
|
|
||||||
var someObj = { b: 22, c: "str" };
|
|
||||||
var t = new TestInterfaceJS(someAny, someObj);
|
|
||||||
is(Object.getPrototypeOf(t), TestInterfaceJS.prototype, "Prototype setup works correctly");
|
|
||||||
is(t.anyArg.toSource(), someAny.toSource(), "anyArg comes back looking like what we sent");
|
|
||||||
is(t.objectArg.toSource(), someObj.toSource(), "objectArg comes back looking like what we sent");
|
|
||||||
isnot(t.anyArg, t.anyArg, "get a new anyArg each time");
|
|
||||||
isnot(t.objectArg, t.objectArg, "get a new objectArg each time");
|
|
||||||
|
|
||||||
t.anyAttr = 2;
|
|
||||||
is(t.anyAttr, 2, "ping-pong works");
|
|
||||||
testObjectCloned(t, 'anyAttr');
|
|
||||||
testObjectCloned(t, 'objectAttr');
|
|
||||||
|
|
||||||
is(someAny.toSource(), t.pingPongAny(someAny).toSource(), "ping-pong works with any");
|
|
||||||
is(someObj.toSource(), t.pingPongObject(someObj).toSource(), "ping-pong works with obj");
|
|
||||||
isnot(someAny, t.pingPongAny(someAny), "Clone works for ping-pong any");
|
|
||||||
isnot(someObj, t.pingPongObject(someObj), "Clone works for ping-pong obj");
|
|
||||||
|
|
||||||
SimpleTest.finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
function testObjectCloned(iface, propname) {
|
|
||||||
var obj = { prop: 42 };
|
|
||||||
iface[propname] = obj;
|
|
||||||
is(iface[propname].prop, 42, "objects come back as well");
|
|
||||||
is(iface[propname].__proto__, Object.prototype, "vanilla object");
|
|
||||||
isnot(iface[propname], obj, "Should not be the original object");
|
|
||||||
isnot(iface[propname], iface[propname], "Should get cloned each time");
|
|
||||||
try {
|
|
||||||
iface[propname] = { stringProp: "hi", reflectorProp: document };
|
|
||||||
ok(false, "Should throw when trying to clone reflector");
|
|
||||||
} catch (e) {
|
|
||||||
ok(/cloned/.test(e), "Should throw clone error: " + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=923904">Mozilla Bug 923904</a>
|
|
||||||
<p id="display"></p>
|
|
||||||
<div id="content" style="display: none">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<pre id="test">
|
|
||||||
</pre>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1985,7 +1985,7 @@ CanvasRenderingContext2D::ArcTo(double x1, double y1, double x2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check for colinearity
|
// Check for colinearity
|
||||||
dir = (p2.x - p1.x) * (p0.y - p1.y) + (p2.y - p1.y) * (p1.x - p0.x);
|
dir = (p2.x - p1.x).value * (p0.y - p1.y).value + (p2.y - p1.y).value * (p1.x - p0.x).value;
|
||||||
if (dir == 0) {
|
if (dir == 0) {
|
||||||
LineTo(p1.x, p1.y);
|
LineTo(p1.x, p1.y);
|
||||||
return;
|
return;
|
||||||
@ -4500,7 +4500,7 @@ CanvasPath::ArcTo(double x1, double y1, double x2, double y2, double radius,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check for colinearity
|
// Check for colinearity
|
||||||
dir = (p2.x - p1.x) * (p0.y - p1.y) + (p2.y - p1.y) * (p1.x - p0.x);
|
dir = (p2.x - p1.x).value * (p0.y - p1.y).value + (p2.y - p1.y).value * (p1.x - p0.x).value;
|
||||||
if (dir == 0) {
|
if (dir == 0) {
|
||||||
LineTo(p1.x, p1.y);
|
LineTo(p1.x, p1.y);
|
||||||
return;
|
return;
|
||||||
|
@ -790,7 +790,7 @@ protected:
|
|||||||
// The spec says we should not draw shadows if the operator is OVER.
|
// The spec says we should not draw shadows if the operator is OVER.
|
||||||
// If it's over and the alpha value is zero, nothing needs to be drawn.
|
// If it's over and the alpha value is zero, nothing needs to be drawn.
|
||||||
return NS_GET_A(state.shadowColor) != 0 &&
|
return NS_GET_A(state.shadowColor) != 0 &&
|
||||||
(state.shadowBlur != 0 || state.shadowOffset.x != 0 || state.shadowOffset.y != 0);
|
(state.shadowBlur != 0.f || state.shadowOffset.x != 0.f || state.shadowOffset.y != 0.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
mozilla::gfx::CompositionOp UsedOperation()
|
mozilla::gfx::CompositionOp UsedOperation()
|
||||||
|
@ -1595,8 +1595,9 @@ EventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
|
|||||||
// fire drag gesture if mouse has moved enough
|
// fire drag gesture if mouse has moved enough
|
||||||
LayoutDeviceIntPoint pt = aEvent->refPoint +
|
LayoutDeviceIntPoint pt = aEvent->refPoint +
|
||||||
LayoutDeviceIntPoint::FromUntyped(aEvent->widget->WidgetToScreenOffset());
|
LayoutDeviceIntPoint::FromUntyped(aEvent->widget->WidgetToScreenOffset());
|
||||||
if (DeprecatedAbs(pt.x - mGestureDownPoint.x) > pixelThresholdX ||
|
LayoutDeviceIntPoint distance = pt - mGestureDownPoint;
|
||||||
DeprecatedAbs(pt.y - mGestureDownPoint.y) > pixelThresholdY) {
|
if (Abs(distance.x.value) > SafeCast<uint32_t>(pixelThresholdX) ||
|
||||||
|
Abs(distance.y.value) > SafeCast<uint32_t>(pixelThresholdY)) {
|
||||||
if (Prefs::ClickHoldContextMenu()) {
|
if (Prefs::ClickHoldContextMenu()) {
|
||||||
// stop the click-hold before we fire off the drag gesture, in case
|
// stop the click-hold before we fire off the drag gesture, in case
|
||||||
// it takes a long time
|
// it takes a long time
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
interface nsIDocument;
|
interface nsIDocument;
|
||||||
interface nsIURI;
|
interface nsIURI;
|
||||||
|
|
||||||
[uuid(cc539f1e-1ce6-4af5-bf94-195b30bde010)]
|
[uuid(9b5acea4-2601-4ac7-8836-4352ceb88178)]
|
||||||
interface nsIServiceWorkerManager : nsISupports
|
interface nsIServiceWorkerManager : nsISupports
|
||||||
{
|
{
|
||||||
// Returns a Promise
|
// Returns a Promise
|
||||||
@ -17,9 +17,9 @@ interface nsIServiceWorkerManager : nsISupports
|
|||||||
// Returns a Promise
|
// Returns a Promise
|
||||||
nsISupports unregister(in nsIDOMWindow aWindow, in DOMString aScope);
|
nsISupports unregister(in nsIDOMWindow aWindow, in DOMString aScope);
|
||||||
|
|
||||||
// aTarget MUST be a ServiceWorkerContainer.
|
// aTarget MUST be a ServiceWorkerRegistration.
|
||||||
[noscript] void AddContainerEventListener(in nsIURI aPageURI, in nsIDOMEventTarget aTarget);
|
[noscript] void AddRegistrationEventListener(in nsIURI aPageURI, in nsIDOMEventTarget aTarget);
|
||||||
[noscript] void RemoveContainerEventListener(in nsIURI aPageURI, in nsIDOMEventTarget aTarget);
|
[noscript] void RemoveRegistrationEventListener(in nsIURI aPageURI, in nsIDOMEventTarget aTarget);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call this to request that document `aDoc` be controlled by a ServiceWorker
|
* Call this to request that document `aDoc` be controlled by a ServiceWorker
|
||||||
|
@ -2102,12 +2102,12 @@ MediaManager::MediaCaptureWindowStateInternal(nsIDOMWindow* aWindow, bool* aVide
|
|||||||
// results.
|
// results.
|
||||||
nsCOMPtr<nsPIDOMWindow> piWin = do_QueryInterface(aWindow);
|
nsCOMPtr<nsPIDOMWindow> piWin = do_QueryInterface(aWindow);
|
||||||
if (piWin) {
|
if (piWin) {
|
||||||
if (piWin->GetCurrentInnerWindow() || piWin->IsInnerWindow()) {
|
if (piWin->IsInnerWindow() || piWin->GetCurrentInnerWindow()) {
|
||||||
uint64_t windowID;
|
uint64_t windowID;
|
||||||
if (piWin->GetCurrentInnerWindow()) {
|
if (piWin->IsInnerWindow()) {
|
||||||
windowID = piWin->GetCurrentInnerWindow()->WindowID();
|
|
||||||
} else {
|
|
||||||
windowID = piWin->WindowID();
|
windowID = piWin->WindowID();
|
||||||
|
} else {
|
||||||
|
windowID = piWin->GetCurrentInnerWindow()->WindowID();
|
||||||
}
|
}
|
||||||
StreamListeners* listeners = GetActiveWindows()->Get(windowID);
|
StreamListeners* listeners = GetActiveWindows()->Get(windowID);
|
||||||
if (listeners) {
|
if (listeners) {
|
||||||
|
@ -55,14 +55,14 @@ var SMILUtil =
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Smart wrapper for getComputedStyle, which will generate a "fake" computed
|
// Smart wrapper for getComputedStyle, which will generate a "fake" computed
|
||||||
// style for recognized shorthand properties (font, overflow, marker)
|
// style for recognized shorthand properties (font, font-variant, overflow, marker)
|
||||||
getComputedStyleWrapper : function(elem, propName)
|
getComputedStyleWrapper : function(elem, propName)
|
||||||
{
|
{
|
||||||
// Special cases for shorthand properties (which aren't directly queriable
|
// Special cases for shorthand properties (which aren't directly queriable
|
||||||
// via getComputedStyle)
|
// via getComputedStyle)
|
||||||
var computedStyle;
|
var computedStyle;
|
||||||
if (propName == "font") {
|
if (propName == "font") {
|
||||||
var subProps = ["font-style", "font-variant", "font-weight",
|
var subProps = ["font-style", "font-variant-caps", "font-weight",
|
||||||
"font-size", "line-height", "font-family"];
|
"font-size", "line-height", "font-family"];
|
||||||
for (var i in subProps) {
|
for (var i in subProps) {
|
||||||
var subPropStyle = SMILUtil.getComputedStyleSimple(elem, subProps[i]);
|
var subPropStyle = SMILUtil.getComputedStyleSimple(elem, subProps[i]);
|
||||||
@ -78,6 +78,10 @@ var SMILUtil =
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (propName == "font-variant") {
|
||||||
|
// xxx - this isn't completely correct but it's sufficient for what's
|
||||||
|
// being tested here
|
||||||
|
computedStyle = SMILUtil.getComputedStyleSimple(elem, "font-variant-caps");
|
||||||
} else if (propName == "marker") {
|
} else if (propName == "marker") {
|
||||||
var subProps = ["marker-end", "marker-mid", "marker-start"];
|
var subProps = ["marker-end", "marker-mid", "marker-start"];
|
||||||
for (var i in subProps) {
|
for (var i in subProps) {
|
||||||
|
@ -8,29 +8,27 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
[Pref="dom.serviceWorkers.enabled"]
|
[Pref="dom.serviceWorkers.enabled",
|
||||||
interface ServiceWorkerContainer {
|
Exposed=Window]
|
||||||
|
interface ServiceWorkerContainer : EventTarget {
|
||||||
// FIXME(nsm):
|
// FIXME(nsm):
|
||||||
// https://github.com/slightlyoff/ServiceWorker/issues/198
|
// https://github.com/slightlyoff/ServiceWorker/issues/198
|
||||||
// and discussion at https://etherpad.mozilla.org/serviceworker07apr
|
// and discussion at https://etherpad.mozilla.org/serviceworker07apr
|
||||||
[Unforgeable] readonly attribute ServiceWorker? installing;
|
|
||||||
[Unforgeable] readonly attribute ServiceWorker? waiting;
|
|
||||||
[Unforgeable] readonly attribute ServiceWorker? active;
|
|
||||||
[Unforgeable] readonly attribute ServiceWorker? controller;
|
[Unforgeable] readonly attribute ServiceWorker? controller;
|
||||||
|
|
||||||
[Throws]
|
[Throws]
|
||||||
readonly attribute Promise<any> ready;
|
readonly attribute Promise<ServiceWorkerRegistration> ready;
|
||||||
|
|
||||||
[Throws]
|
[Throws]
|
||||||
Promise<any> getAll();
|
Promise<ServiceWorkerRegistration> register(ScalarValueString scriptURL,
|
||||||
|
optional RegistrationOptionList options);
|
||||||
|
|
||||||
[Throws]
|
[Throws]
|
||||||
Promise<ServiceWorker> register(DOMString url, optional RegistrationOptionList options);
|
Promise<ServiceWorkerRegistration> getRegistration(optional ScalarValueString documentURL = "");
|
||||||
|
|
||||||
[Throws]
|
[Throws]
|
||||||
Promise<any> unregister(DOMString? scope);
|
Promise<sequence<ServiceWorkerRegistration>> getRegistrations();
|
||||||
|
|
||||||
attribute EventHandler onupdatefound;
|
|
||||||
attribute EventHandler oncontrollerchange;
|
attribute EventHandler oncontrollerchange;
|
||||||
attribute EventHandler onreloadpage;
|
attribute EventHandler onreloadpage;
|
||||||
attribute EventHandler onerror;
|
attribute EventHandler onerror;
|
||||||
@ -49,5 +47,5 @@ partial interface ServiceWorkerContainer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
dictionary RegistrationOptionList {
|
dictionary RegistrationOptionList {
|
||||||
DOMString scope = "/*";
|
ScalarValueString scope = "/*";
|
||||||
};
|
};
|
||||||
|
25
dom/webidl/ServiceWorkerRegistration.webidl
Normal file
25
dom/webidl/ServiceWorkerRegistration.webidl
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* The origin of this IDL file is
|
||||||
|
* http://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
[Pref="dom.serviceWorkers.enabled",
|
||||||
|
Exposed=Window]
|
||||||
|
interface ServiceWorkerRegistration : EventTarget {
|
||||||
|
[Unforgeable] readonly attribute ServiceWorker? installing;
|
||||||
|
[Unforgeable] readonly attribute ServiceWorker? waiting;
|
||||||
|
[Unforgeable] readonly attribute ServiceWorker? active;
|
||||||
|
|
||||||
|
readonly attribute ScalarValueString scope;
|
||||||
|
|
||||||
|
[Throws]
|
||||||
|
Promise<boolean> unregister();
|
||||||
|
|
||||||
|
// event
|
||||||
|
attribute EventHandler onupdatefound;
|
||||||
|
};
|
@ -4,16 +4,29 @@
|
|||||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
dictionary TestInterfaceJSUnionableDictionary {
|
||||||
|
object objectMember;
|
||||||
|
any anyMember;
|
||||||
|
};
|
||||||
|
|
||||||
[JSImplementation="@mozilla.org/dom/test-interface-js;1",
|
[JSImplementation="@mozilla.org/dom/test-interface-js;1",
|
||||||
Pref="dom.expose_test_interfaces",
|
Pref="dom.expose_test_interfaces",
|
||||||
Constructor(optional any anyArg, optional object objectArg)]
|
Constructor(optional any anyArg, optional object objectArg, optional TestInterfaceJSDictionary dictionaryArg)]
|
||||||
interface TestInterfaceJS {
|
interface TestInterfaceJS {
|
||||||
readonly attribute any anyArg;
|
readonly attribute any anyArg;
|
||||||
readonly attribute object objectArg;
|
readonly attribute object objectArg;
|
||||||
|
[Cached, Pure] readonly attribute TestInterfaceJSDictionary dictionaryArg;
|
||||||
attribute any anyAttr;
|
attribute any anyAttr;
|
||||||
attribute object objectAttr;
|
attribute object objectAttr;
|
||||||
|
[Cached, Pure] attribute TestInterfaceJSDictionary dictionaryAttr;
|
||||||
any pingPongAny(any arg);
|
any pingPongAny(any arg);
|
||||||
object pingPongObject(any obj);
|
object pingPongObject(object obj);
|
||||||
|
any pingPongObjectOrString((object or DOMString) objOrString);
|
||||||
|
TestInterfaceJSDictionary pingPongDictionary(optional TestInterfaceJSDictionary dict);
|
||||||
|
long pingPongDictionaryOrLong(optional (TestInterfaceJSUnionableDictionary or long) dictOrLong);
|
||||||
|
DOMString pingPongMap(MozMap<any> map);
|
||||||
|
long objectSequenceLength(sequence<object> seq);
|
||||||
|
long anySequenceLength(sequence<any> seq);
|
||||||
|
|
||||||
// For testing bug 968335.
|
// For testing bug 968335.
|
||||||
DOMString getCallerPrincipal();
|
DOMString getCallerPrincipal();
|
||||||
|
27
dom/webidl/TestInterfaceJSDictionaries.webidl
Normal file
27
dom/webidl/TestInterfaceJSDictionaries.webidl
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// These dictionaries are in a separate WebIDL file to avoid circular include
|
||||||
|
// problems. One of the dictionary includes a union as a member, so that
|
||||||
|
// dictionary's header needs to include UnionTypes.h. But the API in
|
||||||
|
// TestInterfaceJS also declares a union of dictionaries, so _that_
|
||||||
|
// dictionary's header needs to be included _by_ UnionTypes.h. The solution
|
||||||
|
// is to separate those two dictionaries into separate header files.
|
||||||
|
//
|
||||||
|
|
||||||
|
dictionary TestInterfaceJSDictionary2 {
|
||||||
|
object innerObject;
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary TestInterfaceJSDictionary {
|
||||||
|
TestInterfaceJSDictionary2 innerDictionary;
|
||||||
|
object objectMember;
|
||||||
|
any anyMember;
|
||||||
|
(object or DOMString) objectOrStringMember;
|
||||||
|
sequence<any> anySequenceMember;
|
||||||
|
};
|
||||||
|
|
@ -326,6 +326,7 @@ WEBIDL_FILES = [
|
|||||||
'ServiceWorker.webidl',
|
'ServiceWorker.webidl',
|
||||||
'ServiceWorkerContainer.webidl',
|
'ServiceWorkerContainer.webidl',
|
||||||
'ServiceWorkerGlobalScope.webidl',
|
'ServiceWorkerGlobalScope.webidl',
|
||||||
|
'ServiceWorkerRegistration.webidl',
|
||||||
'SettingsManager.webidl',
|
'SettingsManager.webidl',
|
||||||
'ShadowRoot.webidl',
|
'ShadowRoot.webidl',
|
||||||
'SharedWorker.webidl',
|
'SharedWorker.webidl',
|
||||||
@ -563,7 +564,7 @@ WEBIDL_FILES += [
|
|||||||
# We only expose our prefable test interfaces in debug builds, just to be on
|
# We only expose our prefable test interfaces in debug builds, just to be on
|
||||||
# the safe side.
|
# the safe side.
|
||||||
if CONFIG['MOZ_DEBUG']:
|
if CONFIG['MOZ_DEBUG']:
|
||||||
WEBIDL_FILES += ['TestInterfaceJS.webidl']
|
WEBIDL_FILES += ['TestInterfaceJS.webidl', 'TestInterfaceJSDictionaries.webidl']
|
||||||
|
|
||||||
if CONFIG['MOZ_B2G_BT']:
|
if CONFIG['MOZ_B2G_BT']:
|
||||||
if CONFIG['MOZ_B2G_BT_API_V2']:
|
if CONFIG['MOZ_B2G_BT_API_V2']:
|
||||||
|
25
dom/workers/ServiceWorkerCommon.h
Normal file
25
dom/workers/ServiceWorkerCommon.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef mozilla_dom_ServiceWorkerCommon_h
|
||||||
|
#define mozilla_dom_ServiceWorkerCommon_h
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
// Use multiples of 2 since they can be bitwise ORed when calling
|
||||||
|
// InvalidateServiceWorkerRegistrationWorker.
|
||||||
|
MOZ_BEGIN_ENUM_CLASS(WhichServiceWorker)
|
||||||
|
INSTALLING_WORKER = 1,
|
||||||
|
WAITING_WORKER = 2,
|
||||||
|
ACTIVE_WORKER = 4,
|
||||||
|
MOZ_END_ENUM_CLASS(WhichServiceWorker)
|
||||||
|
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(WhichServiceWorker)
|
||||||
|
|
||||||
|
} // dom namespace
|
||||||
|
} // mozilla namespace
|
||||||
|
|
||||||
|
#endif // mozilla_dom_ServiceWorkerCommon_h
|
@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
namespace workers {
|
|
||||||
|
|
||||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServiceWorkerContainer)
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServiceWorkerContainer)
|
||||||
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
||||||
@ -31,21 +30,16 @@ NS_IMPL_ADDREF_INHERITED(ServiceWorkerContainer, DOMEventTargetHelper)
|
|||||||
NS_IMPL_RELEASE_INHERITED(ServiceWorkerContainer, DOMEventTargetHelper)
|
NS_IMPL_RELEASE_INHERITED(ServiceWorkerContainer, DOMEventTargetHelper)
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorkerContainer, DOMEventTargetHelper,
|
NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorkerContainer, DOMEventTargetHelper,
|
||||||
mInstallingWorker,
|
|
||||||
mWaitingWorker,
|
|
||||||
mActiveWorker,
|
|
||||||
mControllerWorker)
|
mControllerWorker)
|
||||||
|
|
||||||
ServiceWorkerContainer::ServiceWorkerContainer(nsPIDOMWindow* aWindow)
|
ServiceWorkerContainer::ServiceWorkerContainer(nsPIDOMWindow* aWindow)
|
||||||
: mWindow(aWindow)
|
: mWindow(aWindow)
|
||||||
{
|
{
|
||||||
SetIsDOMBinding();
|
SetIsDOMBinding();
|
||||||
StartListeningForEvents();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceWorkerContainer::~ServiceWorkerContainer()
|
ServiceWorkerContainer::~ServiceWorkerContainer()
|
||||||
{
|
{
|
||||||
StopListeningForEvents();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JSObject*
|
JSObject*
|
||||||
@ -77,61 +71,6 @@ ServiceWorkerContainer::Register(const nsAString& aScriptURL,
|
|||||||
return ret.forget();
|
return ret.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<Promise>
|
|
||||||
ServiceWorkerContainer::Unregister(const nsAString& aScope,
|
|
||||||
ErrorResult& aRv)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsISupports> promise;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIServiceWorkerManager> swm = mozilla::services::GetServiceWorkerManager();
|
|
||||||
if (!swm) {
|
|
||||||
aRv.Throw(NS_ERROR_FAILURE);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
aRv = swm->Unregister(mWindow, aScope, getter_AddRefs(promise));
|
|
||||||
if (aRv.Failed()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<Promise> ret = static_cast<Promise*>(promise.get());
|
|
||||||
MOZ_ASSERT(ret);
|
|
||||||
return ret.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<workers::ServiceWorker>
|
|
||||||
ServiceWorkerContainer::GetInstalling()
|
|
||||||
{
|
|
||||||
if (!mInstallingWorker) {
|
|
||||||
mInstallingWorker = GetWorkerReference(WhichServiceWorker::INSTALLING_WORKER);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<ServiceWorker> ret = mInstallingWorker;
|
|
||||||
return ret.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<workers::ServiceWorker>
|
|
||||||
ServiceWorkerContainer::GetWaiting()
|
|
||||||
{
|
|
||||||
if (!mWaitingWorker) {
|
|
||||||
mWaitingWorker = GetWorkerReference(WhichServiceWorker::WAITING_WORKER);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<ServiceWorker> ret = mWaitingWorker;
|
|
||||||
return ret.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<workers::ServiceWorker>
|
|
||||||
ServiceWorkerContainer::GetActive()
|
|
||||||
{
|
|
||||||
if (!mActiveWorker) {
|
|
||||||
mActiveWorker = GetWorkerReference(WhichServiceWorker::ACTIVE_WORKER);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<ServiceWorker> ret = mActiveWorker;
|
|
||||||
return ret.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<workers::ServiceWorker>
|
already_AddRefed<workers::ServiceWorker>
|
||||||
ServiceWorkerContainer::GetController()
|
ServiceWorkerContainer::GetController()
|
||||||
{
|
{
|
||||||
@ -148,15 +87,25 @@ ServiceWorkerContainer::GetController()
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
mControllerWorker = static_cast<ServiceWorker*>(serviceWorker.get());
|
mControllerWorker =
|
||||||
|
static_cast<workers::ServiceWorker*>(serviceWorker.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<ServiceWorker> ref = mControllerWorker;
|
nsRefPtr<workers::ServiceWorker> ref = mControllerWorker;
|
||||||
return ref.forget();
|
return ref.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<Promise>
|
already_AddRefed<Promise>
|
||||||
ServiceWorkerContainer::GetAll(ErrorResult& aRv)
|
ServiceWorkerContainer::GetRegistrations(ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
// FIXME(nsm): Bug 1002571
|
||||||
|
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<Promise>
|
||||||
|
ServiceWorkerContainer::GetRegistration(const nsAString& aDocumentURL,
|
||||||
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
// FIXME(nsm): Bug 1002571
|
// FIXME(nsm): Bug 1002571
|
||||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||||
@ -171,74 +120,6 @@ ServiceWorkerContainer::GetReady(ErrorResult& aRv)
|
|||||||
return Promise::Create(global, aRv);
|
return Promise::Create(global, aRv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXXnsm, maybe this can be optimized to only add when a event handler is
|
|
||||||
// registered.
|
|
||||||
void
|
|
||||||
ServiceWorkerContainer::StartListeningForEvents()
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIServiceWorkerManager> swm = mozilla::services::GetServiceWorkerManager();
|
|
||||||
if (swm) {
|
|
||||||
swm->AddContainerEventListener(mWindow->GetDocumentURI(), this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ServiceWorkerContainer::StopListeningForEvents()
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIServiceWorkerManager> swm = mozilla::services::GetServiceWorkerManager();
|
|
||||||
if (swm) {
|
|
||||||
swm->RemoveContainerEventListener(mWindow->GetDocumentURI(), this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ServiceWorkerContainer::InvalidateWorkerReference(WhichServiceWorker aWhichOnes)
|
|
||||||
{
|
|
||||||
if (aWhichOnes & WhichServiceWorker::INSTALLING_WORKER) {
|
|
||||||
mInstallingWorker = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aWhichOnes & WhichServiceWorker::WAITING_WORKER) {
|
|
||||||
mWaitingWorker = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aWhichOnes & WhichServiceWorker::ACTIVE_WORKER) {
|
|
||||||
mActiveWorker = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<workers::ServiceWorker>
|
|
||||||
ServiceWorkerContainer::GetWorkerReference(WhichServiceWorker aWhichOne)
|
|
||||||
{
|
|
||||||
nsresult rv;
|
|
||||||
nsCOMPtr<nsIServiceWorkerManager> swm = mozilla::services::GetServiceWorkerManager();
|
|
||||||
if (!swm) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsISupports> serviceWorker;
|
|
||||||
switch(aWhichOne) {
|
|
||||||
case WhichServiceWorker::INSTALLING_WORKER:
|
|
||||||
rv = swm->GetInstalling(mWindow, getter_AddRefs(serviceWorker));
|
|
||||||
break;
|
|
||||||
case WhichServiceWorker::WAITING_WORKER:
|
|
||||||
rv = swm->GetWaiting(mWindow, getter_AddRefs(serviceWorker));
|
|
||||||
break;
|
|
||||||
case WhichServiceWorker::ACTIVE_WORKER:
|
|
||||||
rv = swm->GetActive(mWindow, getter_AddRefs(serviceWorker));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
MOZ_CRASH("Invalid enum value");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<ServiceWorker> ref = static_cast<ServiceWorker*>(serviceWorker.get());
|
|
||||||
return ref.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Testing only.
|
// Testing only.
|
||||||
already_AddRefed<Promise>
|
already_AddRefed<Promise>
|
||||||
ServiceWorkerContainer::ClearAllServiceWorkerData(ErrorResult& aRv)
|
ServiceWorkerContainer::ClearAllServiceWorkerData(ErrorResult& aRv)
|
||||||
@ -271,6 +152,5 @@ ServiceWorkerContainer::GetControllingWorkerScriptURLForPath(
|
|||||||
{
|
{
|
||||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||||
}
|
}
|
||||||
} // namespace workers
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
@ -4,13 +4,11 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#ifndef mozilla_dom_workers_serviceworkercontainer_h__
|
#ifndef mozilla_dom_serviceworkercontainer_h__
|
||||||
#define mozilla_dom_workers_serviceworkercontainer_h__
|
#define mozilla_dom_serviceworkercontainer_h__
|
||||||
|
|
||||||
#include "mozilla/DOMEventTargetHelper.h"
|
#include "mozilla/DOMEventTargetHelper.h"
|
||||||
|
|
||||||
#include "ServiceWorkerManager.h"
|
|
||||||
|
|
||||||
class nsPIDOMWindow;
|
class nsPIDOMWindow;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
@ -20,8 +18,8 @@ class Promise;
|
|||||||
struct RegistrationOptionList;
|
struct RegistrationOptionList;
|
||||||
|
|
||||||
namespace workers {
|
namespace workers {
|
||||||
|
|
||||||
class ServiceWorker;
|
class ServiceWorker;
|
||||||
|
}
|
||||||
|
|
||||||
// Lightweight serviceWorker APIs collection.
|
// Lightweight serviceWorker APIs collection.
|
||||||
class ServiceWorkerContainer MOZ_FINAL : public DOMEventTargetHelper
|
class ServiceWorkerContainer MOZ_FINAL : public DOMEventTargetHelper
|
||||||
@ -30,7 +28,6 @@ public:
|
|||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerContainer, DOMEventTargetHelper)
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerContainer, DOMEventTargetHelper)
|
||||||
|
|
||||||
IMPL_EVENT_HANDLER(updatefound)
|
|
||||||
IMPL_EVENT_HANDLER(controllerchange)
|
IMPL_EVENT_HANDLER(controllerchange)
|
||||||
IMPL_EVENT_HANDLER(reloadpage)
|
IMPL_EVENT_HANDLER(reloadpage)
|
||||||
IMPL_EVENT_HANDLER(error)
|
IMPL_EVENT_HANDLER(error)
|
||||||
@ -51,39 +48,19 @@ public:
|
|||||||
const RegistrationOptionList& aOptions,
|
const RegistrationOptionList& aOptions,
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
|
|
||||||
already_AddRefed<Promise>
|
already_AddRefed<workers::ServiceWorker>
|
||||||
Unregister(const nsAString& scope, ErrorResult& aRv);
|
|
||||||
|
|
||||||
already_AddRefed<ServiceWorker>
|
|
||||||
GetInstalling();
|
|
||||||
|
|
||||||
already_AddRefed<ServiceWorker>
|
|
||||||
GetWaiting();
|
|
||||||
|
|
||||||
already_AddRefed<ServiceWorker>
|
|
||||||
GetActive();
|
|
||||||
|
|
||||||
already_AddRefed<ServiceWorker>
|
|
||||||
GetController();
|
GetController();
|
||||||
|
|
||||||
already_AddRefed<Promise>
|
already_AddRefed<Promise>
|
||||||
GetAll(ErrorResult& aRv);
|
GetRegistration(const nsAString& aDocumentURL,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
already_AddRefed<Promise>
|
||||||
|
GetRegistrations(ErrorResult& aRv);
|
||||||
|
|
||||||
already_AddRefed<Promise>
|
already_AddRefed<Promise>
|
||||||
GetReady(ErrorResult& aRv);
|
GetReady(ErrorResult& aRv);
|
||||||
|
|
||||||
nsIURI*
|
|
||||||
GetDocumentURI() const
|
|
||||||
{
|
|
||||||
return mWindow->GetDocumentURI();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
InvalidateWorkerReference(WhichServiceWorker aWhichOnes);
|
|
||||||
|
|
||||||
already_AddRefed<workers::ServiceWorker>
|
|
||||||
GetWorkerReference(WhichServiceWorker aWhichOne);
|
|
||||||
|
|
||||||
// Testing only.
|
// Testing only.
|
||||||
already_AddRefed<Promise>
|
already_AddRefed<Promise>
|
||||||
ClearAllServiceWorkerData(ErrorResult& aRv);
|
ClearAllServiceWorkerData(ErrorResult& aRv);
|
||||||
@ -100,28 +77,14 @@ public:
|
|||||||
private:
|
private:
|
||||||
~ServiceWorkerContainer();
|
~ServiceWorkerContainer();
|
||||||
|
|
||||||
void
|
|
||||||
StartListeningForEvents();
|
|
||||||
|
|
||||||
void
|
|
||||||
StopListeningForEvents();
|
|
||||||
|
|
||||||
nsCOMPtr<nsPIDOMWindow> mWindow;
|
nsCOMPtr<nsPIDOMWindow> mWindow;
|
||||||
|
|
||||||
// The following properties are cached here to ensure JS equality is satisfied
|
|
||||||
// instead of acquiring a new worker instance from the ServiceWorkerManager
|
|
||||||
// for every access. A null value is considered a cache miss.
|
|
||||||
// These three may change to a new worker at any time.
|
|
||||||
nsRefPtr<ServiceWorker> mInstallingWorker;
|
|
||||||
nsRefPtr<ServiceWorker> mWaitingWorker;
|
|
||||||
nsRefPtr<ServiceWorker> mActiveWorker;
|
|
||||||
// This only changes when a worker hijacks everything in its scope by calling
|
// This only changes when a worker hijacks everything in its scope by calling
|
||||||
// replace().
|
// replace().
|
||||||
// FIXME(nsm): Bug 982711. Provide API to let SWM invalidate this.
|
// FIXME(nsm): Bug 982711. Provide API to let SWM invalidate this.
|
||||||
nsRefPtr<ServiceWorker> mControllerWorker;
|
nsRefPtr<workers::ServiceWorker> mControllerWorker;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace workers
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
#include "RuntimeService.h"
|
#include "RuntimeService.h"
|
||||||
#include "ServiceWorker.h"
|
#include "ServiceWorker.h"
|
||||||
#include "ServiceWorkerContainer.h"
|
#include "ServiceWorkerRegistration.h"
|
||||||
#include "ServiceWorkerEvents.h"
|
#include "ServiceWorkerEvents.h"
|
||||||
#include "WorkerInlines.h"
|
#include "WorkerInlines.h"
|
||||||
#include "WorkerPrivate.h"
|
#include "WorkerPrivate.h"
|
||||||
@ -36,7 +36,7 @@ using namespace mozilla::dom;
|
|||||||
|
|
||||||
BEGIN_WORKERS_NAMESPACE
|
BEGIN_WORKERS_NAMESPACE
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS0(ServiceWorkerRegistration)
|
NS_IMPL_ISUPPORTS0(ServiceWorkerRegistrationInfo)
|
||||||
|
|
||||||
UpdatePromise::UpdatePromise()
|
UpdatePromise::UpdatePromise()
|
||||||
: mState(Pending)
|
: mState(Pending)
|
||||||
@ -80,6 +80,7 @@ UpdatePromise::ResolveAllPromises(const nsACString& aScriptSpec, const nsACStrin
|
|||||||
|
|
||||||
GlobalObject domGlobal(cx, global);
|
GlobalObject domGlobal(cx, global);
|
||||||
|
|
||||||
|
// The service worker is created and kept alive as a SharedWorker.
|
||||||
nsRefPtr<ServiceWorker> serviceWorker;
|
nsRefPtr<ServiceWorker> serviceWorker;
|
||||||
nsresult rv = rs->CreateServiceWorker(domGlobal,
|
nsresult rv = rs->CreateServiceWorker(domGlobal,
|
||||||
NS_ConvertUTF8toUTF16(aScriptSpec),
|
NS_ConvertUTF8toUTF16(aScriptSpec),
|
||||||
@ -90,7 +91,14 @@ UpdatePromise::ResolveAllPromises(const nsACString& aScriptSpec, const nsACStrin
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
pendingPromise->MaybeResolve(serviceWorker);
|
// Since ServiceWorkerRegistration is only exposed to windows we can be
|
||||||
|
// certain about this cast.
|
||||||
|
nsCOMPtr<nsPIDOMWindow> window =
|
||||||
|
do_QueryInterface(pendingPromise->GetParentObject());
|
||||||
|
nsRefPtr<ServiceWorkerRegistration> swr =
|
||||||
|
new ServiceWorkerRegistration(window, NS_ConvertUTF8toUTF16(aScope));
|
||||||
|
|
||||||
|
pendingPromise->MaybeResolve(swr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -107,7 +115,7 @@ UpdatePromise::RejectAllPromises(nsresult aRv)
|
|||||||
for (uint32_t i = 0; i < array.Length(); ++i) {
|
for (uint32_t i = 0; i < array.Length(); ++i) {
|
||||||
WeakPtr<Promise>& pendingPromise = array.ElementAt(i);
|
WeakPtr<Promise>& pendingPromise = array.ElementAt(i);
|
||||||
if (pendingPromise) {
|
if (pendingPromise) {
|
||||||
// Since ServiceWorkerContainer is only exposed to windows we can be
|
// Since ServiceWorkerRegistration is only exposed to windows we can be
|
||||||
// certain about this cast.
|
// certain about this cast.
|
||||||
nsCOMPtr<nsPIDOMWindow> window =
|
nsCOMPtr<nsPIDOMWindow> window =
|
||||||
do_QueryInterface(pendingPromise->GetParentObject());
|
do_QueryInterface(pendingPromise->GetParentObject());
|
||||||
@ -129,7 +137,7 @@ UpdatePromise::RejectAllPromises(const ErrorEventInit& aErrorDesc)
|
|||||||
for (uint32_t i = 0; i < array.Length(); ++i) {
|
for (uint32_t i = 0; i < array.Length(); ++i) {
|
||||||
WeakPtr<Promise>& pendingPromise = array.ElementAt(i);
|
WeakPtr<Promise>& pendingPromise = array.ElementAt(i);
|
||||||
if (pendingPromise) {
|
if (pendingPromise) {
|
||||||
// Since ServiceWorkerContainer is only exposed to windows we can be
|
// Since ServiceWorkerRegistration is only exposed to windows we can be
|
||||||
// certain about this cast.
|
// certain about this cast.
|
||||||
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(pendingPromise->GetParentObject());
|
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(pendingPromise->GetParentObject());
|
||||||
MOZ_ASSERT(go);
|
MOZ_ASSERT(go);
|
||||||
@ -208,7 +216,7 @@ public:
|
|||||||
class ServiceWorkerUpdateInstance MOZ_FINAL : public nsISupports
|
class ServiceWorkerUpdateInstance MOZ_FINAL : public nsISupports
|
||||||
{
|
{
|
||||||
// Owner of this instance.
|
// Owner of this instance.
|
||||||
ServiceWorkerRegistration* mRegistration;
|
ServiceWorkerRegistrationInfo* mRegistration;
|
||||||
nsCString mScriptSpec;
|
nsCString mScriptSpec;
|
||||||
nsCOMPtr<nsPIDOMWindow> mWindow;
|
nsCOMPtr<nsPIDOMWindow> mWindow;
|
||||||
|
|
||||||
@ -219,7 +227,7 @@ class ServiceWorkerUpdateInstance MOZ_FINAL : public nsISupports
|
|||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
ServiceWorkerUpdateInstance(ServiceWorkerRegistration *aRegistration,
|
ServiceWorkerUpdateInstance(ServiceWorkerRegistrationInfo *aRegistration,
|
||||||
nsPIDOMWindow* aWindow)
|
nsPIDOMWindow* aWindow)
|
||||||
: mRegistration(aRegistration),
|
: mRegistration(aRegistration),
|
||||||
// Capture the current script spec in case register() gets called.
|
// Capture the current script spec in case register() gets called.
|
||||||
@ -297,13 +305,13 @@ FinishFetchOnMainThreadRunnable::Run()
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceWorkerRegistration::ServiceWorkerRegistration(const nsACString& aScope)
|
ServiceWorkerRegistrationInfo::ServiceWorkerRegistrationInfo(const nsACString& aScope)
|
||||||
: mControlledDocumentsCounter(0),
|
: mControlledDocumentsCounter(0),
|
||||||
mScope(aScope),
|
mScope(aScope),
|
||||||
mPendingUninstall(false)
|
mPendingUninstall(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
ServiceWorkerRegistration::~ServiceWorkerRegistration()
|
ServiceWorkerRegistrationInfo::~ServiceWorkerRegistrationInfo()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!IsControllingDocuments());
|
MOZ_ASSERT(!IsControllingDocuments());
|
||||||
}
|
}
|
||||||
@ -339,7 +347,7 @@ ServiceWorkerManager::CleanupServiceWorkerInformation(const nsACString& aDomain,
|
|||||||
ServiceWorkerDomainInfo* aDomainInfo,
|
ServiceWorkerDomainInfo* aDomainInfo,
|
||||||
void *aUnused)
|
void *aUnused)
|
||||||
{
|
{
|
||||||
aDomainInfo->mServiceWorkerRegistrations.Clear();
|
aDomainInfo->mServiceWorkerRegistrationInfos.Clear();
|
||||||
return PL_DHASH_NEXT;
|
return PL_DHASH_NEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,7 +384,7 @@ public:
|
|||||||
swm->mDomainMap.Put(domain, domainInfo);
|
swm->mDomainMap.Put(domain, domainInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<ServiceWorkerRegistration> registration =
|
nsRefPtr<ServiceWorkerRegistrationInfo> registration =
|
||||||
domainInfo->GetRegistration(mScope);
|
domainInfo->GetRegistration(mScope);
|
||||||
|
|
||||||
nsCString spec;
|
nsCString spec;
|
||||||
@ -412,7 +420,11 @@ public:
|
|||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
mPromise->MaybeResolve(serviceWorker);
|
nsRefPtr<ServiceWorkerRegistration> swr =
|
||||||
|
new ServiceWorkerRegistration(mWindow,
|
||||||
|
NS_ConvertUTF8toUTF16(registration->mScope));
|
||||||
|
|
||||||
|
mPromise->MaybeResolve(swr);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -528,7 +540,7 @@ ServiceWorkerManager::Register(nsIDOMWindow* aWindow, const nsAString& aScope,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ServiceWorkerManager::RejectUpdatePromiseObservers(ServiceWorkerRegistration* aRegistration,
|
ServiceWorkerManager::RejectUpdatePromiseObservers(ServiceWorkerRegistrationInfo* aRegistration,
|
||||||
nsresult aRv)
|
nsresult aRv)
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
@ -538,7 +550,7 @@ ServiceWorkerManager::RejectUpdatePromiseObservers(ServiceWorkerRegistration* aR
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ServiceWorkerManager::RejectUpdatePromiseObservers(ServiceWorkerRegistration* aRegistration,
|
ServiceWorkerManager::RejectUpdatePromiseObservers(ServiceWorkerRegistrationInfo* aRegistration,
|
||||||
const ErrorEventInit& aErrorDesc)
|
const ErrorEventInit& aErrorDesc)
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
@ -552,7 +564,7 @@ ServiceWorkerManager::RejectUpdatePromiseObservers(ServiceWorkerRegistration* aR
|
|||||||
* may access the registration's (new) Promise after calling this method.
|
* may access the registration's (new) Promise after calling this method.
|
||||||
*/
|
*/
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
ServiceWorkerManager::Update(ServiceWorkerRegistration* aRegistration,
|
ServiceWorkerManager::Update(ServiceWorkerRegistrationInfo* aRegistration,
|
||||||
nsPIDOMWindow* aWindow)
|
nsPIDOMWindow* aWindow)
|
||||||
{
|
{
|
||||||
if (aRegistration->HasUpdatePromise()) {
|
if (aRegistration->HasUpdatePromise()) {
|
||||||
@ -571,8 +583,8 @@ ServiceWorkerManager::Update(ServiceWorkerRegistration* aRegistration,
|
|||||||
// instance.
|
// instance.
|
||||||
// FIXME(nsm): Fire "statechange" on installing worker instance.
|
// FIXME(nsm): Fire "statechange" on installing worker instance.
|
||||||
aRegistration->mInstallingWorker = nullptr;
|
aRegistration->mInstallingWorker = nullptr;
|
||||||
InvalidateServiceWorkerContainerWorker(aRegistration,
|
InvalidateServiceWorkerRegistrationWorker(aRegistration,
|
||||||
WhichServiceWorker::INSTALLING_WORKER);
|
WhichServiceWorker::INSTALLING_WORKER);
|
||||||
}
|
}
|
||||||
|
|
||||||
aRegistration->mUpdatePromise = new UpdatePromise();
|
aRegistration->mUpdatePromise = new UpdatePromise();
|
||||||
@ -587,7 +599,7 @@ ServiceWorkerManager::Update(ServiceWorkerRegistration* aRegistration,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we return an error, ServiceWorkerContainer will reject the Promise.
|
// If we return an error, ServiceWorkerREgistration will reject the Promise.
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
ServiceWorkerManager::Unregister(nsIDOMWindow* aWindow, const nsAString& aScope,
|
ServiceWorkerManager::Unregister(nsIDOMWindow* aWindow, const nsAString& aScope,
|
||||||
nsISupports** aPromise)
|
nsISupports** aPromise)
|
||||||
@ -613,7 +625,7 @@ ServiceWorkerManager::GetInstance()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ServiceWorkerManager::ResolveRegisterPromises(ServiceWorkerRegistration* aRegistration,
|
ServiceWorkerManager::ResolveRegisterPromises(ServiceWorkerRegistrationInfo* aRegistration,
|
||||||
const nsACString& aWorkerScriptSpec)
|
const nsACString& aWorkerScriptSpec)
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
@ -630,7 +642,7 @@ ServiceWorkerManager::ResolveRegisterPromises(ServiceWorkerRegistration* aRegist
|
|||||||
|
|
||||||
// Must NS_Free() aString
|
// Must NS_Free() aString
|
||||||
void
|
void
|
||||||
ServiceWorkerManager::FinishFetch(ServiceWorkerRegistration* aRegistration,
|
ServiceWorkerManager::FinishFetch(ServiceWorkerRegistrationInfo* aRegistration,
|
||||||
nsPIDOMWindow* aWindow)
|
nsPIDOMWindow* aWindow)
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
@ -688,7 +700,7 @@ ServiceWorkerManager::HandleError(JSContext* aCx,
|
|||||||
|
|
||||||
nsCString scope;
|
nsCString scope;
|
||||||
scope.Assign(aScope);
|
scope.Assign(aScope);
|
||||||
nsRefPtr<ServiceWorkerRegistration> registration = domainInfo->GetRegistration(scope);
|
nsRefPtr<ServiceWorkerRegistrationInfo> registration = domainInfo->GetRegistration(scope);
|
||||||
MOZ_ASSERT(registration);
|
MOZ_ASSERT(registration);
|
||||||
|
|
||||||
RootedDictionary<ErrorEventInit> init(aCx);
|
RootedDictionary<ErrorEventInit> init(aCx);
|
||||||
@ -717,11 +729,11 @@ ServiceWorkerManager::HandleError(JSContext* aCx,
|
|||||||
|
|
||||||
class FinishInstallRunnable MOZ_FINAL : public nsRunnable
|
class FinishInstallRunnable MOZ_FINAL : public nsRunnable
|
||||||
{
|
{
|
||||||
nsMainThreadPtrHandle<ServiceWorkerRegistration> mRegistration;
|
nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> mRegistration;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit FinishInstallRunnable(
|
explicit FinishInstallRunnable(
|
||||||
const nsMainThreadPtrHandle<ServiceWorkerRegistration>& aRegistration)
|
const nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo>& aRegistration)
|
||||||
: mRegistration(aRegistration)
|
: mRegistration(aRegistration)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!NS_IsMainThread());
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
@ -740,10 +752,10 @@ public:
|
|||||||
|
|
||||||
class FinishActivationRunnable : public nsRunnable
|
class FinishActivationRunnable : public nsRunnable
|
||||||
{
|
{
|
||||||
nsMainThreadPtrHandle<ServiceWorkerRegistration> mRegistration;
|
nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> mRegistration;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FinishActivationRunnable(const nsMainThreadPtrHandle<ServiceWorkerRegistration>& aRegistration)
|
FinishActivationRunnable(const nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo>& aRegistration)
|
||||||
: mRegistration(aRegistration)
|
: mRegistration(aRegistration)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!NS_IsMainThread());
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
@ -763,11 +775,11 @@ public:
|
|||||||
|
|
||||||
class CancelServiceWorkerInstallationRunnable MOZ_FINAL : public nsRunnable
|
class CancelServiceWorkerInstallationRunnable MOZ_FINAL : public nsRunnable
|
||||||
{
|
{
|
||||||
nsMainThreadPtrHandle<ServiceWorkerRegistration> mRegistration;
|
nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> mRegistration;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CancelServiceWorkerInstallationRunnable(
|
explicit CancelServiceWorkerInstallationRunnable(
|
||||||
const nsMainThreadPtrHandle<ServiceWorkerRegistration>& aRegistration)
|
const nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo>& aRegistration)
|
||||||
: mRegistration(aRegistration)
|
: mRegistration(aRegistration)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -780,8 +792,8 @@ public:
|
|||||||
// FIXME(nsm): Fire statechange.
|
// FIXME(nsm): Fire statechange.
|
||||||
mRegistration->mInstallingWorker = nullptr;
|
mRegistration->mInstallingWorker = nullptr;
|
||||||
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||||
swm->InvalidateServiceWorkerContainerWorker(mRegistration,
|
swm->InvalidateServiceWorkerRegistrationWorker(mRegistration,
|
||||||
WhichServiceWorker::INSTALLING_WORKER);
|
WhichServiceWorker::INSTALLING_WORKER);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -791,7 +803,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
class FinishInstallHandler MOZ_FINAL : public PromiseNativeHandler
|
class FinishInstallHandler MOZ_FINAL : public PromiseNativeHandler
|
||||||
{
|
{
|
||||||
nsMainThreadPtrHandle<ServiceWorkerRegistration> mRegistration;
|
nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> mRegistration;
|
||||||
|
|
||||||
virtual
|
virtual
|
||||||
~FinishInstallHandler()
|
~FinishInstallHandler()
|
||||||
@ -799,7 +811,7 @@ class FinishInstallHandler MOZ_FINAL : public PromiseNativeHandler
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit FinishInstallHandler(
|
explicit FinishInstallHandler(
|
||||||
const nsMainThreadPtrHandle<ServiceWorkerRegistration>& aRegistration)
|
const nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo>& aRegistration)
|
||||||
: mRegistration(aRegistration)
|
: mRegistration(aRegistration)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!NS_IsMainThread());
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
@ -827,10 +839,10 @@ public:
|
|||||||
|
|
||||||
class FinishActivateHandler : public PromiseNativeHandler
|
class FinishActivateHandler : public PromiseNativeHandler
|
||||||
{
|
{
|
||||||
nsMainThreadPtrHandle<ServiceWorkerRegistration> mRegistration;
|
nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> mRegistration;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FinishActivateHandler(const nsMainThreadPtrHandle<ServiceWorkerRegistration>& aRegistration)
|
FinishActivateHandler(const nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo>& aRegistration)
|
||||||
: mRegistration(aRegistration)
|
: mRegistration(aRegistration)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!NS_IsMainThread());
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
@ -866,13 +878,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
class InstallEventRunnable MOZ_FINAL : public WorkerRunnable
|
class InstallEventRunnable MOZ_FINAL : public WorkerRunnable
|
||||||
{
|
{
|
||||||
nsMainThreadPtrHandle<ServiceWorkerRegistration> mRegistration;
|
nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> mRegistration;
|
||||||
nsCString mScope;
|
nsCString mScope;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InstallEventRunnable(
|
InstallEventRunnable(
|
||||||
WorkerPrivate* aWorkerPrivate,
|
WorkerPrivate* aWorkerPrivate,
|
||||||
const nsMainThreadPtrHandle<ServiceWorkerRegistration>& aRegistration)
|
const nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo>& aRegistration)
|
||||||
: WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount),
|
: WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount),
|
||||||
mRegistration(aRegistration),
|
mRegistration(aRegistration),
|
||||||
mScope(aRegistration.get()->mScope) // copied for access on worker thread.
|
mScope(aRegistration.get()->mScope) // copied for access on worker thread.
|
||||||
@ -935,11 +947,11 @@ private:
|
|||||||
|
|
||||||
class ActivateEventRunnable : public WorkerRunnable
|
class ActivateEventRunnable : public WorkerRunnable
|
||||||
{
|
{
|
||||||
nsMainThreadPtrHandle<ServiceWorkerRegistration> mRegistration;
|
nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> mRegistration;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ActivateEventRunnable(WorkerPrivate* aWorkerPrivate,
|
ActivateEventRunnable(WorkerPrivate* aWorkerPrivate,
|
||||||
const nsMainThreadPtrHandle<ServiceWorkerRegistration>& aRegistration)
|
const nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo>& aRegistration)
|
||||||
: WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount),
|
: WorkerRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount),
|
||||||
mRegistration(aRegistration)
|
mRegistration(aRegistration)
|
||||||
{
|
{
|
||||||
@ -998,17 +1010,17 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
ServiceWorkerManager::Install(ServiceWorkerRegistration* aRegistration,
|
ServiceWorkerManager::Install(ServiceWorkerRegistrationInfo* aRegistration,
|
||||||
ServiceWorkerInfo* aServiceWorkerInfo)
|
ServiceWorkerInfo* aServiceWorkerInfo)
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
aRegistration->mInstallingWorker = aServiceWorkerInfo;
|
aRegistration->mInstallingWorker = aServiceWorkerInfo;
|
||||||
MOZ_ASSERT(aRegistration->mInstallingWorker);
|
MOZ_ASSERT(aRegistration->mInstallingWorker);
|
||||||
InvalidateServiceWorkerContainerWorker(aRegistration,
|
InvalidateServiceWorkerRegistrationWorker(aRegistration,
|
||||||
WhichServiceWorker::INSTALLING_WORKER);
|
WhichServiceWorker::INSTALLING_WORKER);
|
||||||
|
|
||||||
nsMainThreadPtrHandle<ServiceWorkerRegistration> handle(
|
nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> handle(
|
||||||
new nsMainThreadPtrHolder<ServiceWorkerRegistration>(aRegistration));
|
new nsMainThreadPtrHolder<ServiceWorkerRegistrationInfo>(aRegistration));
|
||||||
|
|
||||||
nsRefPtr<ServiceWorker> serviceWorker;
|
nsRefPtr<ServiceWorker> serviceWorker;
|
||||||
nsresult rv =
|
nsresult rv =
|
||||||
@ -1042,15 +1054,15 @@ ServiceWorkerManager::Install(ServiceWorkerRegistration* aRegistration,
|
|||||||
// a wait is likely to be required only when performing networking or storage
|
// a wait is likely to be required only when performing networking or storage
|
||||||
// transactions in the first place.
|
// transactions in the first place.
|
||||||
|
|
||||||
FireEventOnServiceWorkerContainers(aRegistration,
|
FireEventOnServiceWorkerRegistrations(aRegistration,
|
||||||
NS_LITERAL_STRING("updatefound"));
|
NS_LITERAL_STRING("updatefound"));
|
||||||
}
|
}
|
||||||
|
|
||||||
class ActivationRunnable : public nsRunnable
|
class ActivationRunnable : public nsRunnable
|
||||||
{
|
{
|
||||||
nsRefPtr<ServiceWorkerRegistration> mRegistration;
|
nsRefPtr<ServiceWorkerRegistrationInfo> mRegistration;
|
||||||
public:
|
public:
|
||||||
explicit ActivationRunnable(ServiceWorkerRegistration* aRegistration)
|
explicit ActivationRunnable(ServiceWorkerRegistrationInfo* aRegistration)
|
||||||
: mRegistration(aRegistration)
|
: mRegistration(aRegistration)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -1065,13 +1077,13 @@ public:
|
|||||||
mRegistration->mCurrentWorker = mRegistration->mWaitingWorker.forget();
|
mRegistration->mCurrentWorker = mRegistration->mWaitingWorker.forget();
|
||||||
|
|
||||||
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||||
swm->InvalidateServiceWorkerContainerWorker(mRegistration,
|
swm->InvalidateServiceWorkerRegistrationWorker(mRegistration,
|
||||||
WhichServiceWorker::ACTIVE_WORKER | WhichServiceWorker::WAITING_WORKER);
|
WhichServiceWorker::ACTIVE_WORKER | WhichServiceWorker::WAITING_WORKER);
|
||||||
|
|
||||||
// FIXME(nsm): Steps 7 of the algorithm.
|
// FIXME(nsm): Steps 7 of the algorithm.
|
||||||
|
|
||||||
swm->FireEventOnServiceWorkerContainers(mRegistration,
|
swm->FireEventOnServiceWorkerRegistrations(mRegistration,
|
||||||
NS_LITERAL_STRING("controllerchange"));
|
NS_LITERAL_STRING("controllerchange"));
|
||||||
|
|
||||||
MOZ_ASSERT(mRegistration->mCurrentWorker);
|
MOZ_ASSERT(mRegistration->mCurrentWorker);
|
||||||
nsRefPtr<ServiceWorker> serviceWorker;
|
nsRefPtr<ServiceWorker> serviceWorker;
|
||||||
@ -1083,8 +1095,8 @@ public:
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsMainThreadPtrHandle<ServiceWorkerRegistration> handle(
|
nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> handle(
|
||||||
new nsMainThreadPtrHolder<ServiceWorkerRegistration>(mRegistration));
|
new nsMainThreadPtrHolder<ServiceWorkerRegistrationInfo>(mRegistration));
|
||||||
|
|
||||||
nsRefPtr<ActivateEventRunnable> r =
|
nsRefPtr<ActivateEventRunnable> r =
|
||||||
new ActivateEventRunnable(serviceWorker->GetWorkerPrivate(), handle);
|
new ActivateEventRunnable(serviceWorker->GetWorkerPrivate(), handle);
|
||||||
@ -1099,7 +1111,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
ServiceWorkerManager::FinishInstall(ServiceWorkerRegistration* aRegistration)
|
ServiceWorkerManager::FinishInstall(ServiceWorkerRegistrationInfo* aRegistration)
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
|
|
||||||
@ -1118,8 +1130,8 @@ ServiceWorkerManager::FinishInstall(ServiceWorkerRegistration* aRegistration)
|
|||||||
|
|
||||||
aRegistration->mWaitingWorker = aRegistration->mInstallingWorker.forget();
|
aRegistration->mWaitingWorker = aRegistration->mInstallingWorker.forget();
|
||||||
MOZ_ASSERT(aRegistration->mWaitingWorker);
|
MOZ_ASSERT(aRegistration->mWaitingWorker);
|
||||||
InvalidateServiceWorkerContainerWorker(aRegistration,
|
InvalidateServiceWorkerRegistrationWorker(aRegistration,
|
||||||
WhichServiceWorker::WAITING_WORKER | WhichServiceWorker::INSTALLING_WORKER);
|
WhichServiceWorker::WAITING_WORKER | WhichServiceWorker::INSTALLING_WORKER);
|
||||||
|
|
||||||
// FIXME(nsm): Actually update state of active ServiceWorker instances to
|
// FIXME(nsm): Actually update state of active ServiceWorker instances to
|
||||||
// installed.
|
// installed.
|
||||||
@ -1140,7 +1152,7 @@ ServiceWorkerManager::FinishInstall(ServiceWorkerRegistration* aRegistration)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ServiceWorkerManager::FinishActivate(ServiceWorkerRegistration* aRegistration)
|
ServiceWorkerManager::FinishActivate(ServiceWorkerRegistrationInfo* aRegistration)
|
||||||
{
|
{
|
||||||
// FIXME(nsm): Set aRegistration->mCurrentWorker state to activated.
|
// FIXME(nsm): Set aRegistration->mCurrentWorker state to activated.
|
||||||
// Fire statechange.
|
// Fire statechange.
|
||||||
@ -1178,22 +1190,22 @@ ServiceWorkerManager::CreateServiceWorkerForWindow(nsPIDOMWindow* aWindow,
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<ServiceWorkerRegistration>
|
already_AddRefed<ServiceWorkerRegistrationInfo>
|
||||||
ServiceWorkerManager::GetServiceWorkerRegistration(nsPIDOMWindow* aWindow)
|
ServiceWorkerManager::GetServiceWorkerRegistrationInfo(nsPIDOMWindow* aWindow)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIDocument> document = aWindow->GetExtantDoc();
|
nsCOMPtr<nsIDocument> document = aWindow->GetExtantDoc();
|
||||||
return GetServiceWorkerRegistration(document);
|
return GetServiceWorkerRegistrationInfo(document);
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<ServiceWorkerRegistration>
|
already_AddRefed<ServiceWorkerRegistrationInfo>
|
||||||
ServiceWorkerManager::GetServiceWorkerRegistration(nsIDocument* aDoc)
|
ServiceWorkerManager::GetServiceWorkerRegistrationInfo(nsIDocument* aDoc)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIURI> documentURI = aDoc->GetDocumentURI();
|
nsCOMPtr<nsIURI> documentURI = aDoc->GetDocumentURI();
|
||||||
return GetServiceWorkerRegistration(documentURI);
|
return GetServiceWorkerRegistrationInfo(documentURI);
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<ServiceWorkerRegistration>
|
already_AddRefed<ServiceWorkerRegistrationInfo>
|
||||||
ServiceWorkerManager::GetServiceWorkerRegistration(nsIURI* aURI)
|
ServiceWorkerManager::GetServiceWorkerRegistrationInfo(nsIURI* aURI)
|
||||||
{
|
{
|
||||||
nsRefPtr<ServiceWorkerDomainInfo> domainInfo = GetDomainInfo(aURI);
|
nsRefPtr<ServiceWorkerDomainInfo> domainInfo = GetDomainInfo(aURI);
|
||||||
if (!domainInfo) {
|
if (!domainInfo) {
|
||||||
@ -1211,8 +1223,8 @@ ServiceWorkerManager::GetServiceWorkerRegistration(nsIURI* aURI)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<ServiceWorkerRegistration> registration;
|
nsRefPtr<ServiceWorkerRegistrationInfo> registration;
|
||||||
domainInfo->mServiceWorkerRegistrations.Get(scope, getter_AddRefs(registration));
|
domainInfo->mServiceWorkerRegistrationInfos.Get(scope, getter_AddRefs(registration));
|
||||||
// ordered scopes and registrations better be in sync.
|
// ordered scopes and registrations better be in sync.
|
||||||
MOZ_ASSERT(registration);
|
MOZ_ASSERT(registration);
|
||||||
|
|
||||||
@ -1357,8 +1369,8 @@ ServiceWorkerManager::MaybeStartControlling(nsIDocument* aDoc)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<ServiceWorkerRegistration> registration =
|
nsRefPtr<ServiceWorkerRegistrationInfo> registration =
|
||||||
GetServiceWorkerRegistration(aDoc);
|
GetServiceWorkerRegistrationInfo(aDoc);
|
||||||
if (registration && registration->mCurrentWorker) {
|
if (registration && registration->mCurrentWorker) {
|
||||||
MOZ_ASSERT(!domainInfo->mControlledDocuments.Contains(aDoc));
|
MOZ_ASSERT(!domainInfo->mControlledDocuments.Contains(aDoc));
|
||||||
registration->StartControllingADocument();
|
registration->StartControllingADocument();
|
||||||
@ -1381,7 +1393,7 @@ ServiceWorkerManager::MaybeStopControlling(nsIDocument* aDoc)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<ServiceWorkerRegistration> registration;
|
nsRefPtr<ServiceWorkerRegistrationInfo> registration;
|
||||||
domainInfo->mControlledDocuments.Remove(aDoc, getter_AddRefs(registration));
|
domainInfo->mControlledDocuments.Remove(aDoc, getter_AddRefs(registration));
|
||||||
// A document which was uncontrolled does not maintain that state itself, so
|
// A document which was uncontrolled does not maintain that state itself, so
|
||||||
// it will always call MaybeStopControlling() even if there isn't an
|
// it will always call MaybeStopControlling() even if there isn't an
|
||||||
@ -1400,7 +1412,7 @@ ServiceWorkerManager::GetScopeForUrl(const nsAString& aUrl, nsAString& aScope)
|
|||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<ServiceWorkerRegistration> r = GetServiceWorkerRegistration(uri);
|
nsRefPtr<ServiceWorkerRegistrationInfo> r = GetServiceWorkerRegistrationInfo(uri);
|
||||||
if (!r) {
|
if (!r) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
@ -1410,7 +1422,7 @@ ServiceWorkerManager::GetScopeForUrl(const nsAString& aUrl, nsAString& aScope)
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
ServiceWorkerManager::AddContainerEventListener(nsIURI* aDocumentURI, nsIDOMEventTarget* aListener)
|
ServiceWorkerManager::AddRegistrationEventListener(nsIURI* aDocumentURI, nsIDOMEventTarget* aListener)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aDocumentURI);
|
MOZ_ASSERT(aDocumentURI);
|
||||||
nsRefPtr<ServiceWorkerDomainInfo> domainInfo = GetDomainInfo(aDocumentURI);
|
nsRefPtr<ServiceWorkerDomainInfo> domainInfo = GetDomainInfo(aDocumentURI);
|
||||||
@ -1427,13 +1439,14 @@ ServiceWorkerManager::AddContainerEventListener(nsIURI* aDocumentURI, nsIDOMEven
|
|||||||
|
|
||||||
MOZ_ASSERT(domainInfo);
|
MOZ_ASSERT(domainInfo);
|
||||||
|
|
||||||
ServiceWorkerContainer* container = static_cast<ServiceWorkerContainer*>(aListener);
|
// TODO: this is very very bad:
|
||||||
domainInfo->mServiceWorkerContainers.AppendElement(container);
|
ServiceWorkerRegistration* registration = static_cast<ServiceWorkerRegistration*>(aListener);
|
||||||
|
domainInfo->mServiceWorkerRegistrations.AppendElement(registration);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
ServiceWorkerManager::RemoveContainerEventListener(nsIURI* aDocumentURI, nsIDOMEventTarget* aListener)
|
ServiceWorkerManager::RemoveRegistrationEventListener(nsIURI* aDocumentURI, nsIDOMEventTarget* aListener)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aDocumentURI);
|
MOZ_ASSERT(aDocumentURI);
|
||||||
nsRefPtr<ServiceWorkerDomainInfo> domainInfo = GetDomainInfo(aDocumentURI);
|
nsRefPtr<ServiceWorkerDomainInfo> domainInfo = GetDomainInfo(aDocumentURI);
|
||||||
@ -1441,14 +1454,14 @@ ServiceWorkerManager::RemoveContainerEventListener(nsIURI* aDocumentURI, nsIDOME
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceWorkerContainer* container = static_cast<ServiceWorkerContainer*>(aListener);
|
ServiceWorkerRegistration* registration = static_cast<ServiceWorkerRegistration*>(aListener);
|
||||||
domainInfo->mServiceWorkerContainers.RemoveElement(container);
|
domainInfo->mServiceWorkerRegistrations.RemoveElement(registration);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ServiceWorkerManager::FireEventOnServiceWorkerContainers(
|
ServiceWorkerManager::FireEventOnServiceWorkerRegistrations(
|
||||||
ServiceWorkerRegistration* aRegistration,
|
ServiceWorkerRegistrationInfo* aRegistration,
|
||||||
const nsAString& aName)
|
const nsAString& aName)
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
@ -1456,9 +1469,9 @@ ServiceWorkerManager::FireEventOnServiceWorkerContainers(
|
|||||||
GetDomainInfo(aRegistration->mScriptSpec);
|
GetDomainInfo(aRegistration->mScriptSpec);
|
||||||
|
|
||||||
if (domainInfo) {
|
if (domainInfo) {
|
||||||
nsTObserverArray<ServiceWorkerContainer*>::ForwardIterator it(domainInfo->mServiceWorkerContainers);
|
nsTObserverArray<ServiceWorkerRegistration*>::ForwardIterator it(domainInfo->mServiceWorkerRegistrations);
|
||||||
while (it.HasMore()) {
|
while (it.HasMore()) {
|
||||||
nsRefPtr<ServiceWorkerContainer> target = it.GetNext();
|
nsRefPtr<ServiceWorkerRegistration> target = it.GetNext();
|
||||||
nsIURI* targetURI = target->GetDocumentURI();
|
nsIURI* targetURI = target->GetDocumentURI();
|
||||||
if (!targetURI) {
|
if (!targetURI) {
|
||||||
NS_WARNING("Controlled domain cannot have page with null URI!");
|
NS_WARNING("Controlled domain cannot have page with null URI!");
|
||||||
@ -1494,8 +1507,8 @@ ServiceWorkerManager::GetServiceWorkerForWindow(nsIDOMWindow* aWindow,
|
|||||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aWindow);
|
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aWindow);
|
||||||
MOZ_ASSERT(window);
|
MOZ_ASSERT(window);
|
||||||
|
|
||||||
nsRefPtr<ServiceWorkerRegistration> registration =
|
nsRefPtr<ServiceWorkerRegistrationInfo> registration =
|
||||||
GetServiceWorkerRegistration(window);
|
GetServiceWorkerRegistrationInfo(window);
|
||||||
|
|
||||||
if (!registration) {
|
if (!registration) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
@ -1549,7 +1562,7 @@ ServiceWorkerManager::GetDocumentController(nsIDOMWindow* aWindow, nsISupports**
|
|||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<ServiceWorkerRegistration> registration;
|
nsRefPtr<ServiceWorkerRegistrationInfo> registration;
|
||||||
if (!domainInfo->mControlledDocuments.Get(doc, getter_AddRefs(registration))) {
|
if (!domainInfo->mControlledDocuments.Get(doc, getter_AddRefs(registration))) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
@ -1615,7 +1628,7 @@ ServiceWorkerManager::CreateServiceWorker(const nsACString& aScriptSpec,
|
|||||||
|
|
||||||
// FIXME(nsm): Create correct principal based on app-ness.
|
// FIXME(nsm): Create correct principal based on app-ness.
|
||||||
// Would it make sense to store the nsIPrincipal of the first register() in
|
// Would it make sense to store the nsIPrincipal of the first register() in
|
||||||
// the ServiceWorkerRegistration and use that?
|
// the ServiceWorkerRegistrationInfo and use that?
|
||||||
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
|
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
|
||||||
rv = ssm->GetNoAppCodebasePrincipal(info.mBaseURI, getter_AddRefs(info.mPrincipal));
|
rv = ssm->GetNoAppCodebasePrincipal(info.mBaseURI, getter_AddRefs(info.mPrincipal));
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
@ -1642,17 +1655,17 @@ ServiceWorkerManager::CreateServiceWorker(const nsACString& aScriptSpec,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ServiceWorkerManager::InvalidateServiceWorkerContainerWorker(ServiceWorkerRegistration* aRegistration,
|
ServiceWorkerManager::InvalidateServiceWorkerRegistrationWorker(ServiceWorkerRegistrationInfo* aRegistration,
|
||||||
WhichServiceWorker aWhichOnes)
|
WhichServiceWorker aWhichOnes)
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
nsRefPtr<ServiceWorkerDomainInfo> domainInfo =
|
nsRefPtr<ServiceWorkerDomainInfo> domainInfo =
|
||||||
GetDomainInfo(aRegistration->mScriptSpec);
|
GetDomainInfo(aRegistration->mScriptSpec);
|
||||||
|
|
||||||
if (domainInfo) {
|
if (domainInfo) {
|
||||||
nsTObserverArray<ServiceWorkerContainer*>::ForwardIterator it(domainInfo->mServiceWorkerContainers);
|
nsTObserverArray<ServiceWorkerRegistration*>::ForwardIterator it(domainInfo->mServiceWorkerRegistrations);
|
||||||
while (it.HasMore()) {
|
while (it.HasMore()) {
|
||||||
nsRefPtr<ServiceWorkerContainer> target = it.GetNext();
|
nsRefPtr<ServiceWorkerRegistration> target = it.GetNext();
|
||||||
|
|
||||||
nsIURI* targetURI = target->GetDocumentURI();
|
nsIURI* targetURI = target->GetDocumentURI();
|
||||||
nsCString path;
|
nsCString path;
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "mozilla/WeakPtr.h"
|
#include "mozilla/WeakPtr.h"
|
||||||
#include "mozilla/dom/BindingUtils.h"
|
#include "mozilla/dom/BindingUtils.h"
|
||||||
#include "mozilla/dom/Promise.h"
|
#include "mozilla/dom/Promise.h"
|
||||||
|
#include "mozilla/dom/ServiceWorkerCommon.h"
|
||||||
#include "nsRefPtrHashtable.h"
|
#include "nsRefPtrHashtable.h"
|
||||||
#include "nsTArrayForwardDeclare.h"
|
#include "nsTArrayForwardDeclare.h"
|
||||||
#include "nsTObserverArray.h"
|
#include "nsTObserverArray.h"
|
||||||
@ -24,10 +25,12 @@ class nsIScriptError;
|
|||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
|
class ServiceWorkerRegistration;
|
||||||
|
|
||||||
namespace workers {
|
namespace workers {
|
||||||
|
|
||||||
class ServiceWorker;
|
class ServiceWorker;
|
||||||
class ServiceWorkerContainer;
|
|
||||||
class ServiceWorkerUpdateInstance;
|
class ServiceWorkerUpdateInstance;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -95,22 +98,13 @@ public:
|
|||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Use multiples of 2 since they can be bitwise ORed when calling
|
|
||||||
// InvalidateServiceWorkerContainerWorker.
|
|
||||||
MOZ_BEGIN_ENUM_CLASS(WhichServiceWorker)
|
|
||||||
INSTALLING_WORKER = 1,
|
|
||||||
WAITING_WORKER = 2,
|
|
||||||
ACTIVE_WORKER = 4,
|
|
||||||
MOZ_END_ENUM_CLASS(WhichServiceWorker)
|
|
||||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(WhichServiceWorker)
|
|
||||||
|
|
||||||
// Needs to inherit from nsISupports because NS_ProxyRelease() does not support
|
// Needs to inherit from nsISupports because NS_ProxyRelease() does not support
|
||||||
// non-ISupports classes.
|
// non-ISupports classes.
|
||||||
class ServiceWorkerRegistration MOZ_FINAL : public nsISupports
|
class ServiceWorkerRegistrationInfo MOZ_FINAL : public nsISupports
|
||||||
{
|
{
|
||||||
uint32_t mControlledDocumentsCounter;
|
uint32_t mControlledDocumentsCounter;
|
||||||
|
|
||||||
virtual ~ServiceWorkerRegistration();
|
virtual ~ServiceWorkerRegistrationInfo();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
@ -145,7 +139,7 @@ public:
|
|||||||
// pendingUninstall and when all controlling documents go away, removed.
|
// pendingUninstall and when all controlling documents go away, removed.
|
||||||
bool mPendingUninstall;
|
bool mPendingUninstall;
|
||||||
|
|
||||||
explicit ServiceWorkerRegistration(const nsACString& aScope);
|
explicit ServiceWorkerRegistrationInfo(const nsACString& aScope);
|
||||||
|
|
||||||
already_AddRefed<ServiceWorkerInfo>
|
already_AddRefed<ServiceWorkerInfo>
|
||||||
Newest()
|
Newest()
|
||||||
@ -236,35 +230,35 @@ public:
|
|||||||
nsTArray<nsCString> mOrderedScopes;
|
nsTArray<nsCString> mOrderedScopes;
|
||||||
|
|
||||||
// Scope to registration.
|
// Scope to registration.
|
||||||
nsRefPtrHashtable<nsCStringHashKey, ServiceWorkerRegistration> mServiceWorkerRegistrations;
|
nsRefPtrHashtable<nsCStringHashKey, ServiceWorkerRegistrationInfo> mServiceWorkerRegistrationInfos;
|
||||||
|
|
||||||
// This array can't be stored in ServiceWorkerRegistration because one may
|
// This array can't be stored in ServiceWorkerRegistration because one may
|
||||||
// not exist when a certain window is opened, but we still want that
|
// not exist when a certain window is opened, but we still want that
|
||||||
// window's container to be notified if it's in scope.
|
// window's container to be notified if it's in scope.
|
||||||
// The containers inform the SWM on creation and destruction.
|
// The containers inform the SWM on creation and destruction.
|
||||||
nsTObserverArray<ServiceWorkerContainer*> mServiceWorkerContainers;
|
nsTObserverArray<ServiceWorkerRegistration*> mServiceWorkerRegistrations;
|
||||||
|
|
||||||
nsRefPtrHashtable<nsISupportsHashKey, ServiceWorkerRegistration> mControlledDocuments;
|
nsRefPtrHashtable<nsISupportsHashKey, ServiceWorkerRegistrationInfo> mControlledDocuments;
|
||||||
|
|
||||||
ServiceWorkerDomainInfo()
|
ServiceWorkerDomainInfo()
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
already_AddRefed<ServiceWorkerRegistration>
|
already_AddRefed<ServiceWorkerRegistrationInfo>
|
||||||
GetRegistration(const nsCString& aScope) const
|
GetRegistration(const nsCString& aScope) const
|
||||||
{
|
{
|
||||||
nsRefPtr<ServiceWorkerRegistration> reg;
|
nsRefPtr<ServiceWorkerRegistrationInfo> reg;
|
||||||
mServiceWorkerRegistrations.Get(aScope, getter_AddRefs(reg));
|
mServiceWorkerRegistrationInfos.Get(aScope, getter_AddRefs(reg));
|
||||||
return reg.forget();
|
return reg.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceWorkerRegistration*
|
ServiceWorkerRegistrationInfo*
|
||||||
CreateNewRegistration(const nsCString& aScope)
|
CreateNewRegistration(const nsCString& aScope)
|
||||||
{
|
{
|
||||||
ServiceWorkerRegistration* registration =
|
ServiceWorkerRegistrationInfo* registration =
|
||||||
new ServiceWorkerRegistration(aScope);
|
new ServiceWorkerRegistrationInfo(aScope);
|
||||||
// From now on ownership of registration is with
|
// From now on ownership of registration is with
|
||||||
// mServiceWorkerRegistrations.
|
// mServiceWorkerRegistrationInfos.
|
||||||
mServiceWorkerRegistrations.Put(aScope, registration);
|
mServiceWorkerRegistrationInfos.Put(aScope, registration);
|
||||||
ServiceWorkerManager::AddScope(mOrderedScopes, aScope);
|
ServiceWorkerManager::AddScope(mOrderedScopes, aScope);
|
||||||
return registration;
|
return registration;
|
||||||
}
|
}
|
||||||
@ -279,26 +273,26 @@ public:
|
|||||||
nsRefPtrHashtable<nsCStringHashKey, ServiceWorkerDomainInfo> mDomainMap;
|
nsRefPtrHashtable<nsCStringHashKey, ServiceWorkerDomainInfo> mDomainMap;
|
||||||
|
|
||||||
void
|
void
|
||||||
ResolveRegisterPromises(ServiceWorkerRegistration* aRegistration,
|
ResolveRegisterPromises(ServiceWorkerRegistrationInfo* aRegistration,
|
||||||
const nsACString& aWorkerScriptSpec);
|
const nsACString& aWorkerScriptSpec);
|
||||||
|
|
||||||
void
|
void
|
||||||
RejectUpdatePromiseObservers(ServiceWorkerRegistration* aRegistration,
|
RejectUpdatePromiseObservers(ServiceWorkerRegistrationInfo* aRegistration,
|
||||||
nsresult aResult);
|
nsresult aResult);
|
||||||
|
|
||||||
void
|
void
|
||||||
RejectUpdatePromiseObservers(ServiceWorkerRegistration* aRegistration,
|
RejectUpdatePromiseObservers(ServiceWorkerRegistrationInfo* aRegistration,
|
||||||
const ErrorEventInit& aErrorDesc);
|
const ErrorEventInit& aErrorDesc);
|
||||||
|
|
||||||
void
|
void
|
||||||
FinishFetch(ServiceWorkerRegistration* aRegistration,
|
FinishFetch(ServiceWorkerRegistrationInfo* aRegistration,
|
||||||
nsPIDOMWindow* aWindow);
|
nsPIDOMWindow* aWindow);
|
||||||
|
|
||||||
void
|
void
|
||||||
FinishInstall(ServiceWorkerRegistration* aRegistration);
|
FinishInstall(ServiceWorkerRegistrationInfo* aRegistration);
|
||||||
|
|
||||||
void
|
void
|
||||||
FinishActivate(ServiceWorkerRegistration* aRegistration);
|
FinishActivate(ServiceWorkerRegistrationInfo* aRegistration);
|
||||||
|
|
||||||
void
|
void
|
||||||
HandleError(JSContext* aCx,
|
HandleError(JSContext* aCx,
|
||||||
@ -319,10 +313,10 @@ private:
|
|||||||
~ServiceWorkerManager();
|
~ServiceWorkerManager();
|
||||||
|
|
||||||
NS_IMETHOD
|
NS_IMETHOD
|
||||||
Update(ServiceWorkerRegistration* aRegistration, nsPIDOMWindow* aWindow);
|
Update(ServiceWorkerRegistrationInfo* aRegistration, nsPIDOMWindow* aWindow);
|
||||||
|
|
||||||
void
|
void
|
||||||
Install(ServiceWorkerRegistration* aRegistration,
|
Install(ServiceWorkerRegistrationInfo* aRegistration,
|
||||||
ServiceWorkerInfo* aServiceWorkerInfo);
|
ServiceWorkerInfo* aServiceWorkerInfo);
|
||||||
|
|
||||||
NS_IMETHOD
|
NS_IMETHOD
|
||||||
@ -356,17 +350,17 @@ private:
|
|||||||
nsISupports** aServiceWorker);
|
nsISupports** aServiceWorker);
|
||||||
|
|
||||||
void
|
void
|
||||||
InvalidateServiceWorkerContainerWorker(ServiceWorkerRegistration* aRegistration,
|
InvalidateServiceWorkerRegistrationWorker(ServiceWorkerRegistrationInfo* aRegistration,
|
||||||
WhichServiceWorker aWhichOnes);
|
WhichServiceWorker aWhichOnes);
|
||||||
|
|
||||||
already_AddRefed<ServiceWorkerRegistration>
|
already_AddRefed<ServiceWorkerRegistrationInfo>
|
||||||
GetServiceWorkerRegistration(nsPIDOMWindow* aWindow);
|
GetServiceWorkerRegistrationInfo(nsPIDOMWindow* aWindow);
|
||||||
|
|
||||||
already_AddRefed<ServiceWorkerRegistration>
|
already_AddRefed<ServiceWorkerRegistrationInfo>
|
||||||
GetServiceWorkerRegistration(nsIDocument* aDoc);
|
GetServiceWorkerRegistrationInfo(nsIDocument* aDoc);
|
||||||
|
|
||||||
already_AddRefed<ServiceWorkerRegistration>
|
already_AddRefed<ServiceWorkerRegistrationInfo>
|
||||||
GetServiceWorkerRegistration(nsIURI* aURI);
|
GetServiceWorkerRegistrationInfo(nsIURI* aURI);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
AddScope(nsTArray<nsCString>& aList, const nsACString& aScope);
|
AddScope(nsTArray<nsCString>& aList, const nsACString& aScope);
|
||||||
@ -378,8 +372,8 @@ private:
|
|||||||
RemoveScope(nsTArray<nsCString>& aList, const nsACString& aScope);
|
RemoveScope(nsTArray<nsCString>& aList, const nsACString& aScope);
|
||||||
|
|
||||||
void
|
void
|
||||||
FireEventOnServiceWorkerContainers(ServiceWorkerRegistration* aRegistration,
|
FireEventOnServiceWorkerRegistrations(ServiceWorkerRegistrationInfo* aRegistration,
|
||||||
const nsAString& aName);
|
const nsAString& aName);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
197
dom/workers/ServiceWorkerRegistration.cpp
Normal file
197
dom/workers/ServiceWorkerRegistration.cpp
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "ServiceWorkerRegistration.h"
|
||||||
|
|
||||||
|
#include "mozilla/dom/Promise.h"
|
||||||
|
#include "mozilla/dom/ServiceWorkerRegistrationBinding.h"
|
||||||
|
#include "nsCycleCollectionParticipant.h"
|
||||||
|
#include "nsServiceManagerUtils.h"
|
||||||
|
#include "ServiceWorker.h"
|
||||||
|
|
||||||
|
#include "nsIServiceWorkerManager.h"
|
||||||
|
#include "nsPIDOMWindow.h"
|
||||||
|
|
||||||
|
using namespace mozilla::dom::workers;
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServiceWorkerRegistration)
|
||||||
|
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
||||||
|
|
||||||
|
NS_IMPL_ADDREF_INHERITED(ServiceWorkerRegistration, DOMEventTargetHelper)
|
||||||
|
NS_IMPL_RELEASE_INHERITED(ServiceWorkerRegistration, DOMEventTargetHelper)
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorkerRegistration,
|
||||||
|
DOMEventTargetHelper,
|
||||||
|
mWindow,
|
||||||
|
mInstallingWorker,
|
||||||
|
mWaitingWorker,
|
||||||
|
mActiveWorker)
|
||||||
|
|
||||||
|
ServiceWorkerRegistration::ServiceWorkerRegistration(nsPIDOMWindow* aWindow,
|
||||||
|
const nsAString& aScope)
|
||||||
|
: mWindow(aWindow)
|
||||||
|
, mScope(aScope)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aWindow);
|
||||||
|
|
||||||
|
SetIsDOMBinding();
|
||||||
|
StartListeningForEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
ServiceWorkerRegistration::~ServiceWorkerRegistration()
|
||||||
|
{
|
||||||
|
StopListeningForEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
JSObject*
|
||||||
|
ServiceWorkerRegistration::WrapObject(JSContext* aCx)
|
||||||
|
{
|
||||||
|
return ServiceWorkerRegistrationBinding::Wrap(aCx, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<workers::ServiceWorker>
|
||||||
|
ServiceWorkerRegistration::GetInstalling()
|
||||||
|
{
|
||||||
|
if (!mInstallingWorker) {
|
||||||
|
mInstallingWorker = GetWorkerReference(WhichServiceWorker::INSTALLING_WORKER);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<ServiceWorker> ret = mInstallingWorker;
|
||||||
|
return ret.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<workers::ServiceWorker>
|
||||||
|
ServiceWorkerRegistration::GetWaiting()
|
||||||
|
{
|
||||||
|
if (!mWaitingWorker) {
|
||||||
|
mWaitingWorker = GetWorkerReference(WhichServiceWorker::WAITING_WORKER);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<ServiceWorker> ret = mWaitingWorker;
|
||||||
|
return ret.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<workers::ServiceWorker>
|
||||||
|
ServiceWorkerRegistration::GetActive()
|
||||||
|
{
|
||||||
|
if (!mActiveWorker) {
|
||||||
|
mActiveWorker = GetWorkerReference(WhichServiceWorker::ACTIVE_WORKER);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<ServiceWorker> ret = mActiveWorker;
|
||||||
|
return ret.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<Promise>
|
||||||
|
ServiceWorkerRegistration::Unregister(ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsISupports> promise;
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
nsCOMPtr<nsIServiceWorkerManager> swm =
|
||||||
|
do_GetService(SERVICEWORKERMANAGER_CONTRACTID, &rv);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
aRv.Throw(rv);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
aRv = swm->Unregister(mWindow, mScope, getter_AddRefs(promise));
|
||||||
|
if (aRv.Failed()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<Promise> ret = static_cast<Promise*>(promise.get());
|
||||||
|
MOZ_ASSERT(ret);
|
||||||
|
return ret.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<workers::ServiceWorker>
|
||||||
|
ServiceWorkerRegistration::GetWorkerReference(WhichServiceWorker aWhichOne)
|
||||||
|
{
|
||||||
|
nsresult rv;
|
||||||
|
nsCOMPtr<nsIServiceWorkerManager> swm =
|
||||||
|
do_GetService(SERVICEWORKERMANAGER_CONTRACTID, &rv);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsISupports> serviceWorker;
|
||||||
|
switch(aWhichOne) {
|
||||||
|
case WhichServiceWorker::INSTALLING_WORKER:
|
||||||
|
rv = swm->GetInstalling(mWindow, getter_AddRefs(serviceWorker));
|
||||||
|
break;
|
||||||
|
case WhichServiceWorker::WAITING_WORKER:
|
||||||
|
rv = swm->GetWaiting(mWindow, getter_AddRefs(serviceWorker));
|
||||||
|
break;
|
||||||
|
case WhichServiceWorker::ACTIVE_WORKER:
|
||||||
|
rv = swm->GetActive(mWindow, getter_AddRefs(serviceWorker));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
MOZ_CRASH("Invalid enum value");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<ServiceWorker> ref =
|
||||||
|
static_cast<ServiceWorker*>(serviceWorker.get());
|
||||||
|
return ref.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ServiceWorkerRegistration::InvalidateWorkerReference(WhichServiceWorker aWhichOnes)
|
||||||
|
{
|
||||||
|
if (aWhichOnes & WhichServiceWorker::INSTALLING_WORKER) {
|
||||||
|
mInstallingWorker = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aWhichOnes & WhichServiceWorker::WAITING_WORKER) {
|
||||||
|
mWaitingWorker = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aWhichOnes & WhichServiceWorker::ACTIVE_WORKER) {
|
||||||
|
mActiveWorker = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXXnsm, maybe this can be optimized to only add when a event handler is
|
||||||
|
// registered.
|
||||||
|
void
|
||||||
|
ServiceWorkerRegistration::StartListeningForEvents()
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIServiceWorkerManager> swm = do_GetService(SERVICEWORKERMANAGER_CONTRACTID);
|
||||||
|
MOZ_ASSERT(mWindow);
|
||||||
|
|
||||||
|
if (swm) {
|
||||||
|
swm->AddRegistrationEventListener(GetDocumentURI(), this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ServiceWorkerRegistration::StopListeningForEvents()
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIServiceWorkerManager> swm = do_GetService(SERVICEWORKERMANAGER_CONTRACTID);
|
||||||
|
|
||||||
|
// StopListeningForEvents is called in the dtor, and it can happen that
|
||||||
|
// SnowWhite had already set to null mWindow.
|
||||||
|
if (swm && mWindow) {
|
||||||
|
swm->RemoveRegistrationEventListener(GetDocumentURI(), this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIURI*
|
||||||
|
ServiceWorkerRegistration::GetDocumentURI() const
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mWindow);
|
||||||
|
return mWindow->GetDocumentURI();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // dom namespace
|
||||||
|
} // mozilla namespace
|
99
dom/workers/ServiceWorkerRegistration.h
Normal file
99
dom/workers/ServiceWorkerRegistration.h
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef mozilla_dom_ServiceWorkerRegistration_h
|
||||||
|
#define mozilla_dom_ServiceWorkerRegistration_h
|
||||||
|
|
||||||
|
#include "mozilla/DOMEventTargetHelper.h"
|
||||||
|
#include "mozilla/dom/ServiceWorkerCommon.h"
|
||||||
|
|
||||||
|
class nsPIDOMWindow;
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
class Promise;
|
||||||
|
|
||||||
|
namespace workers {
|
||||||
|
class ServiceWorker;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ServiceWorkerRegistration MOZ_FINAL : public DOMEventTargetHelper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerRegistration,
|
||||||
|
DOMEventTargetHelper)
|
||||||
|
|
||||||
|
IMPL_EVENT_HANDLER(updatefound)
|
||||||
|
|
||||||
|
ServiceWorkerRegistration(nsPIDOMWindow* aWindow,
|
||||||
|
const nsAString& aScope);
|
||||||
|
|
||||||
|
nsPIDOMWindow*
|
||||||
|
GetParentObject() const
|
||||||
|
{
|
||||||
|
return mWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSObject*
|
||||||
|
WrapObject(JSContext* aCx);
|
||||||
|
|
||||||
|
already_AddRefed<workers::ServiceWorker>
|
||||||
|
GetInstalling();
|
||||||
|
|
||||||
|
already_AddRefed<workers::ServiceWorker>
|
||||||
|
GetWaiting();
|
||||||
|
|
||||||
|
already_AddRefed<workers::ServiceWorker>
|
||||||
|
GetActive();
|
||||||
|
|
||||||
|
void
|
||||||
|
GetScope(nsAString& aScope) const
|
||||||
|
{
|
||||||
|
aScope = mScope;
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<Promise>
|
||||||
|
Unregister(ErrorResult& aRv);
|
||||||
|
|
||||||
|
// Useful methods for ServiceWorkerManager:
|
||||||
|
|
||||||
|
nsIURI*
|
||||||
|
GetDocumentURI() const;
|
||||||
|
|
||||||
|
void
|
||||||
|
InvalidateWorkerReference(WhichServiceWorker aWhichOnes);
|
||||||
|
|
||||||
|
private:
|
||||||
|
~ServiceWorkerRegistration();
|
||||||
|
|
||||||
|
already_AddRefed<workers::ServiceWorker>
|
||||||
|
GetWorkerReference(WhichServiceWorker aWhichOne);
|
||||||
|
|
||||||
|
void
|
||||||
|
StartListeningForEvents();
|
||||||
|
|
||||||
|
void
|
||||||
|
StopListeningForEvents();
|
||||||
|
|
||||||
|
nsCOMPtr<nsPIDOMWindow> mWindow;
|
||||||
|
|
||||||
|
// The following properties are cached here to ensure JS equality is satisfied
|
||||||
|
// instead of acquiring a new worker instance from the ServiceWorkerManager
|
||||||
|
// for every access. A null value is considered a cache miss.
|
||||||
|
// These three may change to a new worker at any time.
|
||||||
|
nsRefPtr<workers::ServiceWorker> mInstallingWorker;
|
||||||
|
nsRefPtr<workers::ServiceWorker> mWaitingWorker;
|
||||||
|
nsRefPtr<workers::ServiceWorker> mActiveWorker;
|
||||||
|
|
||||||
|
const nsString mScope;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif /* mozilla_dom_ServiceWorkerRegistration_h */
|
@ -6,7 +6,9 @@
|
|||||||
|
|
||||||
# Public stuff.
|
# Public stuff.
|
||||||
EXPORTS.mozilla.dom += [
|
EXPORTS.mozilla.dom += [
|
||||||
|
'ServiceWorkerCommon.h',
|
||||||
'ServiceWorkerContainer.h',
|
'ServiceWorkerContainer.h',
|
||||||
|
'ServiceWorkerRegistration.h',
|
||||||
'WorkerPrivate.h',
|
'WorkerPrivate.h',
|
||||||
'WorkerRunnable.h',
|
'WorkerRunnable.h',
|
||||||
'WorkerScope.h',
|
'WorkerScope.h',
|
||||||
@ -50,6 +52,7 @@ SOURCES += [
|
|||||||
'ServiceWorkerContainer.cpp',
|
'ServiceWorkerContainer.cpp',
|
||||||
'ServiceWorkerEvents.cpp',
|
'ServiceWorkerEvents.cpp',
|
||||||
'ServiceWorkerManager.cpp',
|
'ServiceWorkerManager.cpp',
|
||||||
|
'ServiceWorkerRegistration.cpp',
|
||||||
'SharedWorker.cpp',
|
'SharedWorker.cpp',
|
||||||
'URL.cpp',
|
'URL.cpp',
|
||||||
'WorkerPrivate.cpp',
|
'WorkerPrivate.cpp',
|
||||||
|
@ -32,9 +32,21 @@
|
|||||||
// We are controlled.
|
// We are controlled.
|
||||||
// Register a new worker for this sub-scope. After that, controller should still be for upper level, but active should change to be this scope's.
|
// Register a new worker for this sub-scope. After that, controller should still be for upper level, but active should change to be this scope's.
|
||||||
navigator.serviceWorker.register("../worker2.js", { scope: "./*" }).then(function(e) {
|
navigator.serviceWorker.register("../worker2.js", { scope: "./*" }).then(function(e) {
|
||||||
my_ok(navigator.serviceWorker.installing &&
|
my_ok("installing" in e, "ServiceWorkerRegistration.installing exists.");
|
||||||
navigator.serviceWorker.installing.scope.match(/controller\/\*$/),
|
my_ok(e.installing instanceof ServiceWorker, "ServiceWorkerRegistration.installing is a ServiceWorker.");
|
||||||
|
|
||||||
|
my_ok("waiting" in e, "ServiceWorkerRegistration.waiting exists.");
|
||||||
|
my_ok("active" in e, "ServiceWorkerRegistration.active exists.");
|
||||||
|
|
||||||
|
my_ok(e.installing &&
|
||||||
|
e.installing.scope.match(/controller\/\*$/),
|
||||||
"Installing is serviceworker/controller/*");
|
"Installing is serviceworker/controller/*");
|
||||||
|
|
||||||
|
my_ok("scope" in e, "ServiceWorkerRegistration.scope exists.");
|
||||||
|
my_ok(e.scope.match(/serviceworkers\/controller\/\*$/), "Scope is serviceworker/*: " + e.scope);
|
||||||
|
|
||||||
|
my_ok("unregister" in e, "ServiceWorkerRegistration.unregister exists.");
|
||||||
|
|
||||||
my_ok(navigator.serviceWorker.controller.scope.match(/serviceworkers\/control\*$/),
|
my_ok(navigator.serviceWorker.controller.scope.match(/serviceworkers\/control\*$/),
|
||||||
"Controller is still serviceworker/*");
|
"Controller is still serviceworker/*");
|
||||||
finish();
|
finish();
|
||||||
|
@ -20,11 +20,11 @@
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
function nextRegister() {
|
function nextRegister(reg) {
|
||||||
var p = navigator.serviceWorker.register("install_event_worker.js", { scope: "./*" });
|
var p = navigator.serviceWorker.register("install_event_worker.js", { scope: "./*" });
|
||||||
|
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
navigator.serviceWorker.onupdatefound = function(e) {
|
reg.onupdatefound = function(e) {
|
||||||
ok(true, "Received onupdatefound");
|
ok(true, "Received onupdatefound");
|
||||||
resolve();
|
resolve();
|
||||||
};
|
};
|
||||||
|
@ -57,11 +57,12 @@
|
|||||||
|
|
||||||
function realWorker() {
|
function realWorker() {
|
||||||
var p = navigator.serviceWorker.register("worker.js", { scope: "realworker*" });
|
var p = navigator.serviceWorker.register("worker.js", { scope: "realworker*" });
|
||||||
return p.then(function(w) {
|
return p.then(function(wr) {
|
||||||
ok(w instanceof ServiceWorker, "Register a ServiceWorker");
|
ok(wr instanceof ServiceWorkerRegistration, "Register a ServiceWorker");
|
||||||
info(w.scope);
|
|
||||||
ok(w.scope == (new URL("realworker*", document.baseURI)).href, "Scope should match");
|
info(wr.scope);
|
||||||
ok(w.url == (new URL("worker.js", document.baseURI)).href, "URL should be of the worker");
|
ok(wr.scope == (new URL("realworker*", document.baseURI)).href, "Scope should match");
|
||||||
|
|
||||||
}, function(e) {
|
}, function(e) {
|
||||||
info("Error: " + e.name);
|
info("Error: " + e.name);
|
||||||
ok(false, "realWorker Registration should have succeeded!");
|
ok(false, "realWorker Registration should have succeeded!");
|
||||||
@ -73,14 +74,14 @@
|
|||||||
var q = navigator.serviceWorker.register("worker3.js", { scope: "foo/*" });
|
var q = navigator.serviceWorker.register("worker3.js", { scope: "foo/*" });
|
||||||
|
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
p.then(function(w) {
|
p.then(function(wr) {
|
||||||
ok(false, "First registration should fail with AbortError");
|
ok(false, "First registration should fail with AbortError");
|
||||||
}, function(e) {
|
}, function(e) {
|
||||||
ok(e.name === "AbortError", "First registration should fail with AbortError");
|
ok(e.name === "AbortError", "First registration should fail with AbortError");
|
||||||
}),
|
}),
|
||||||
|
|
||||||
q.then(function(w) {
|
q.then(function(wr) {
|
||||||
ok(w instanceof ServiceWorker, "Second registration should succeed");
|
ok(wr instanceof ServiceWorkerRegistration, "Second registration should succeed");
|
||||||
}, function(e) {
|
}, function(e) {
|
||||||
ok(false, "Second registration should succeed");
|
ok(false, "Second registration should succeed");
|
||||||
})
|
})
|
||||||
@ -97,7 +98,7 @@
|
|||||||
|
|
||||||
function parseError() {
|
function parseError() {
|
||||||
var p = navigator.serviceWorker.register("parse_error_worker.js");
|
var p = navigator.serviceWorker.register("parse_error_worker.js");
|
||||||
return p.then(function(w) {
|
return p.then(function(wr) {
|
||||||
ok(false, "Registration should fail with parse error");
|
ok(false, "Registration should fail with parse error");
|
||||||
}, function(e) {
|
}, function(e) {
|
||||||
info("NSM " + e.name);
|
info("NSM " + e.name);
|
||||||
@ -107,6 +108,7 @@
|
|||||||
|
|
||||||
// FIXME(nsm): test for parse error when Update step doesn't happen (directly from register).
|
// FIXME(nsm): test for parse error when Update step doesn't happen (directly from register).
|
||||||
|
|
||||||
|
/* FIXME bug 1002571 - re-enable this test when GetRegistration is implemented.
|
||||||
function updatefound() {
|
function updatefound() {
|
||||||
var frame = document.createElement("iframe");
|
var frame = document.createElement("iframe");
|
||||||
frame.setAttribute("id", "simpleregister-frame");
|
frame.setAttribute("id", "simpleregister-frame");
|
||||||
@ -137,6 +139,7 @@
|
|||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
function runTest() {
|
function runTest() {
|
||||||
simpleRegister()
|
simpleRegister()
|
||||||
@ -147,7 +150,6 @@
|
|||||||
.then(abortPrevious)
|
.then(abortPrevious)
|
||||||
.then(networkError404)
|
.then(networkError404)
|
||||||
.then(parseError)
|
.then(parseError)
|
||||||
.then(updatefound)
|
|
||||||
// put more tests here.
|
// put more tests here.
|
||||||
.then(function() {
|
.then(function() {
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
|
@ -18,12 +18,9 @@
|
|||||||
function checkEnabled() {
|
function checkEnabled() {
|
||||||
ok(navigator.serviceWorker, "navigator.serviceWorker should exist when ServiceWorkers are enabled.");
|
ok(navigator.serviceWorker, "navigator.serviceWorker should exist when ServiceWorkers are enabled.");
|
||||||
ok(typeof navigator.serviceWorker.register === "function", "navigator.serviceWorker.register() should be a function.");
|
ok(typeof navigator.serviceWorker.register === "function", "navigator.serviceWorker.register() should be a function.");
|
||||||
ok(typeof navigator.serviceWorker.unregister === "function", "navigator.serviceWorker.unregister() should be a function.");
|
ok(typeof navigator.serviceWorker.getRegistration === "function", "navigator.serviceWorker.getAll() should be a function.");
|
||||||
ok(typeof navigator.serviceWorker.getAll === "function", "navigator.serviceWorker.getAll() should be a function.");
|
ok(typeof navigator.serviceWorker.getRegistrations === "function", "navigator.serviceWorker.getAll() should be a function.");
|
||||||
ok(navigator.serviceWorker.ready instanceof Promise, "navigator.serviceWorker.ready should be a Promise.");
|
ok(navigator.serviceWorker.ready instanceof Promise, "navigator.serviceWorker.ready should be a Promise.");
|
||||||
ok(navigator.serviceWorker.installing === null, "There should be no installing worker for an uncontrolled scope.");
|
|
||||||
ok(navigator.serviceWorker.waiting === null, "There should be no waiting worker for an uncontrolled scope.");
|
|
||||||
// ok(navigator.serviceWorker.active === null, "There should be no active worker for an uncontrolled scope.");
|
|
||||||
ok(navigator.serviceWorker.controller === null, "There should be no controller worker for an uncontrolled document.");
|
ok(navigator.serviceWorker.controller === null, "There should be no controller worker for an uncontrolled document.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,8 +302,7 @@ XMLDocument::Load(const nsAString& aUrl, ErrorResult& aRv)
|
|||||||
|
|
||||||
WarnOnceAbout(nsIDocument::eUseOfDOM3LoadMethod);
|
WarnOnceAbout(nsIDocument::eUseOfDOM3LoadMethod);
|
||||||
|
|
||||||
nsCOMPtr<nsIDocument> callingDoc = nsContentUtils::GetDocumentFromContext();
|
nsCOMPtr<nsIDocument> callingDoc = GetEntryDocument();
|
||||||
|
|
||||||
nsIURI *baseURI = mDocumentURI;
|
nsIURI *baseURI = mDocumentURI;
|
||||||
nsAutoCString charset;
|
nsAutoCString charset;
|
||||||
|
|
||||||
|
@ -65,6 +65,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
using namespace mozilla::dom;
|
||||||
|
|
||||||
/****************************************************************
|
/****************************************************************
|
||||||
******************** nsWatcherWindowEntry **********************
|
******************** nsWatcherWindowEntry **********************
|
||||||
@ -886,7 +887,7 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent,
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsPIDOMWindow> referrerWindow =
|
nsCOMPtr<nsPIDOMWindow> referrerWindow =
|
||||||
do_QueryInterface(dom::BrokenGetEntryGlobal());
|
do_QueryInterface(GetEntryGlobal());
|
||||||
if (!referrerWindow) {
|
if (!referrerWindow) {
|
||||||
referrerWindow = do_QueryInterface(aParent);
|
referrerWindow = do_QueryInterface(aParent);
|
||||||
}
|
}
|
||||||
@ -1345,18 +1346,8 @@ nsWindowWatcher::URIfromURL(const char *aURL,
|
|||||||
nsIDOMWindow *aParent,
|
nsIDOMWindow *aParent,
|
||||||
nsIURI **aURI)
|
nsIURI **aURI)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIDOMWindow> baseWindow;
|
// Build the URI relative to the entry global.
|
||||||
|
nsCOMPtr<nsIDOMWindow> baseWindow = do_QueryInterface(GetEntryGlobal());
|
||||||
/* build the URI relative to the calling JS Context, if any.
|
|
||||||
(note this is the same context used to make the security check
|
|
||||||
in nsGlobalWindow.cpp.) */
|
|
||||||
JSContext *cx = nsContentUtils::GetCurrentJSContext();
|
|
||||||
if (cx) {
|
|
||||||
nsIScriptContext *scriptcx = nsJSUtils::GetDynamicScriptContext(cx);
|
|
||||||
if (scriptcx) {
|
|
||||||
baseWindow = do_QueryInterface(scriptcx->GetGlobalObject());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// failing that, build it relative to the parent window, if possible
|
// failing that, build it relative to the parent window, if possible
|
||||||
if (!baseWindow)
|
if (!baseWindow)
|
||||||
@ -1726,16 +1717,8 @@ nsWindowWatcher::FindItemWithName(const char16_t* aName,
|
|||||||
already_AddRefed<nsIDocShellTreeItem>
|
already_AddRefed<nsIDocShellTreeItem>
|
||||||
nsWindowWatcher::GetCallerTreeItem(nsIDocShellTreeItem* aParentItem)
|
nsWindowWatcher::GetCallerTreeItem(nsIDocShellTreeItem* aParentItem)
|
||||||
{
|
{
|
||||||
JSContext *cx = nsContentUtils::GetCurrentJSContext();
|
nsCOMPtr<nsIWebNavigation> callerWebNav = do_GetInterface(GetEntryGlobal());
|
||||||
nsCOMPtr<nsIDocShellTreeItem> callerItem;
|
nsCOMPtr<nsIDocShellTreeItem> callerItem = do_QueryInterface(callerWebNav);
|
||||||
|
|
||||||
if (cx) {
|
|
||||||
nsCOMPtr<nsIWebNavigation> callerWebNav =
|
|
||||||
do_GetInterface(nsJSUtils::GetDynamicScriptGlobal(cx));
|
|
||||||
|
|
||||||
callerItem = do_QueryInterface(callerWebNav);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!callerItem) {
|
if (!callerItem) {
|
||||||
callerItem = aParentItem;
|
callerItem = aParentItem;
|
||||||
}
|
}
|
||||||
|
110
gfx/2d/BaseCoord.h
Normal file
110
gfx/2d/BaseCoord.h
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef MOZILLA_GFX_BASECOORD_H_
|
||||||
|
#define MOZILLA_GFX_BASECOORD_H_
|
||||||
|
|
||||||
|
#include "mozilla/Attributes.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace gfx {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do not use this class directly. Subclass it, pass that subclass as the
|
||||||
|
* Sub parameter, and only use that subclass. This allows methods to safely
|
||||||
|
* cast 'this' to 'Sub*'.
|
||||||
|
*/
|
||||||
|
template <class T, class Sub>
|
||||||
|
struct BaseCoord {
|
||||||
|
T value;
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
MOZ_CONSTEXPR BaseCoord() : value(0) {}
|
||||||
|
explicit MOZ_CONSTEXPR BaseCoord(T aValue) : value(aValue) {}
|
||||||
|
|
||||||
|
// Note that '=' isn't defined so we'll get the
|
||||||
|
// compiler generated default assignment operator
|
||||||
|
|
||||||
|
operator T() const { return value; }
|
||||||
|
|
||||||
|
friend bool operator==(Sub aA, Sub aB) {
|
||||||
|
return aA.value == aB.value;
|
||||||
|
}
|
||||||
|
friend bool operator!=(Sub aA, Sub aB) {
|
||||||
|
return aA.value != aB.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend Sub operator+(Sub aA, Sub aB) {
|
||||||
|
return Sub(aA.value + aB.value);
|
||||||
|
}
|
||||||
|
friend Sub operator-(Sub aA, Sub aB) {
|
||||||
|
return Sub(aA.value - aB.value);
|
||||||
|
}
|
||||||
|
friend Sub operator*(Sub aCoord, T aScale) {
|
||||||
|
return Sub(aCoord.value * aScale);
|
||||||
|
}
|
||||||
|
friend Sub operator*(T aScale, Sub aCoord) {
|
||||||
|
return Sub(aScale * aCoord.value);
|
||||||
|
}
|
||||||
|
friend Sub operator/(Sub aCoord, T aScale) {
|
||||||
|
return Sub(aCoord.value / aScale);
|
||||||
|
}
|
||||||
|
// 'scale / coord' is intentionally omitted because it doesn't make sense.
|
||||||
|
|
||||||
|
Sub& operator+=(Sub aCoord) {
|
||||||
|
value += aCoord.value;
|
||||||
|
return *static_cast<Sub*>(this);
|
||||||
|
}
|
||||||
|
Sub& operator-=(Sub aCoord) {
|
||||||
|
value -= aCoord.value;
|
||||||
|
return *static_cast<Sub*>(this);
|
||||||
|
}
|
||||||
|
Sub& operator*=(T aScale) {
|
||||||
|
value *= aScale;
|
||||||
|
return *static_cast<Sub*>(this);
|
||||||
|
}
|
||||||
|
Sub& operator/=(T aScale) {
|
||||||
|
value /= aScale;
|
||||||
|
return *static_cast<Sub*>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Since BaseCoord is implicitly convertible to its value type T, we need
|
||||||
|
// mixed-type operator overloads to avoid ambiguities at mixed-type call
|
||||||
|
// sites. As we transition more of our code to strongly-typed classes, we
|
||||||
|
// may be able to remove some or all of these overloads.
|
||||||
|
friend bool operator==(Sub aA, T aB) {
|
||||||
|
return aA.value == aB;
|
||||||
|
}
|
||||||
|
friend bool operator==(T aA, Sub aB) {
|
||||||
|
return aA == aB.value;
|
||||||
|
}
|
||||||
|
friend bool operator!=(Sub aA, T aB) {
|
||||||
|
return aA.value != aB;
|
||||||
|
}
|
||||||
|
friend bool operator!=(T aA, Sub aB) {
|
||||||
|
return aA != aB.value;
|
||||||
|
}
|
||||||
|
friend T operator+(Sub aA, T aB) {
|
||||||
|
return aA.value + aB;
|
||||||
|
}
|
||||||
|
friend T operator+(T aA, Sub aB) {
|
||||||
|
return aA + aB.value;
|
||||||
|
}
|
||||||
|
friend T operator-(Sub aA, T aB) {
|
||||||
|
return aA.value - aB;
|
||||||
|
}
|
||||||
|
friend T operator-(T aA, Sub aB) {
|
||||||
|
return aA - aB.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sub operator-() const {
|
||||||
|
return Sub(-value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* MOZILLA_GFX_BASECOORD_H_ */
|
@ -17,13 +17,13 @@ namespace gfx {
|
|||||||
* Sub parameter, and only use that subclass. This allows methods to safely
|
* Sub parameter, and only use that subclass. This allows methods to safely
|
||||||
* cast 'this' to 'Sub*'.
|
* cast 'this' to 'Sub*'.
|
||||||
*/
|
*/
|
||||||
template <class T, class Sub>
|
template <class T, class Sub, class Coord = T>
|
||||||
struct BasePoint {
|
struct BasePoint {
|
||||||
T x, y;
|
Coord x, y;
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
MOZ_CONSTEXPR BasePoint() : x(0), y(0) {}
|
MOZ_CONSTEXPR BasePoint() : x(0), y(0) {}
|
||||||
MOZ_CONSTEXPR BasePoint(T aX, T aY) : x(aX), y(aY) {}
|
MOZ_CONSTEXPR BasePoint(Coord aX, Coord aY) : x(aX), y(aY) {}
|
||||||
|
|
||||||
void MoveTo(T aX, T aY) { x = aX; y = aY; }
|
void MoveTo(T aX, T aY) { x = aX; y = aY; }
|
||||||
void MoveBy(T aDx, T aDy) { x += aDx; y += aDy; }
|
void MoveBy(T aDx, T aDy) { x += aDx; y += aDy; }
|
||||||
@ -67,15 +67,15 @@ struct BasePoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
T Length() const {
|
T Length() const {
|
||||||
return hypot(x, y);
|
return hypot(x.value, y.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Round() is *not* rounding to nearest integer if the values are negative.
|
// Round() is *not* rounding to nearest integer if the values are negative.
|
||||||
// They are always rounding as floor(n + 0.5).
|
// They are always rounding as floor(n + 0.5).
|
||||||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=410748#c14
|
// See https://bugzilla.mozilla.org/show_bug.cgi?id=410748#c14
|
||||||
Sub& Round() {
|
Sub& Round() {
|
||||||
x = static_cast<T>(floor(x + 0.5));
|
x = Coord(floor(T(x) + T(0.5)));
|
||||||
y = static_cast<T>(floor(y + 0.5));
|
y = Coord(floor(T(y) + T(0.5)));
|
||||||
return *static_cast<Sub*>(this);
|
return *static_cast<Sub*>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -734,8 +734,8 @@ static const Float GAUSSIAN_SCALE_FACTOR = Float((3 * sqrt(2 * M_PI) / 4) * 1.5)
|
|||||||
IntSize
|
IntSize
|
||||||
AlphaBoxBlur::CalculateBlurRadius(const Point& aStd)
|
AlphaBoxBlur::CalculateBlurRadius(const Point& aStd)
|
||||||
{
|
{
|
||||||
IntSize size(static_cast<int32_t>(floor(aStd.x * GAUSSIAN_SCALE_FACTOR + 0.5)),
|
IntSize size(static_cast<int32_t>(floor(aStd.x * GAUSSIAN_SCALE_FACTOR + 0.5f)),
|
||||||
static_cast<int32_t>(floor(aStd.y * GAUSSIAN_SCALE_FACTOR + 0.5)));
|
static_cast<int32_t>(floor(aStd.y * GAUSSIAN_SCALE_FACTOR + 0.5f)));
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
142
gfx/2d/Coord.h
Normal file
142
gfx/2d/Coord.h
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef MOZILLA_GFX_COORD_H_
|
||||||
|
#define MOZILLA_GFX_COORD_H_
|
||||||
|
|
||||||
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "Types.h"
|
||||||
|
#include "BaseCoord.h"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
template <typename> struct IsPixel;
|
||||||
|
|
||||||
|
namespace gfx {
|
||||||
|
|
||||||
|
template <class units> struct IntCoordTyped;
|
||||||
|
template <class units> struct CoordTyped;
|
||||||
|
|
||||||
|
// CommonType<coord, primitive> is a metafunction that returns the type of the
|
||||||
|
// result of an arithmetic operation on the underlying type of a strongly-typed
|
||||||
|
// coordinate type 'coord', and a primitive type 'primitive'. C++ rules for
|
||||||
|
// arithmetic conversions are designed to avoid losing information - for
|
||||||
|
// example, the result of adding an int and a float is a float - and we want
|
||||||
|
// the same behaviour when mixing our coordinate types with primitive types.
|
||||||
|
// We get C++ to compute the desired result type using 'decltype'.
|
||||||
|
|
||||||
|
template <class coord, class primitive>
|
||||||
|
struct CommonType;
|
||||||
|
|
||||||
|
template <class units, class primitive>
|
||||||
|
struct CommonType<IntCoordTyped<units>, primitive> {
|
||||||
|
typedef decltype(int32_t() + primitive()) type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class units, class primitive>
|
||||||
|
struct CommonType<CoordTyped<units>, primitive> {
|
||||||
|
typedef decltype(Float() + primitive()) type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is a base class that provides mixed-type operator overloads between
|
||||||
|
// a strongly-typed Coord and a primitive value. It is needed to avoid
|
||||||
|
// ambiguities at mixed-type call sites, because Coord classes are implicitly
|
||||||
|
// convertible to their underlying value type. As we transition more of our code
|
||||||
|
// to strongly-typed classes, we may be able to remove some or all of these
|
||||||
|
// overloads.
|
||||||
|
template <class coord, class primitive>
|
||||||
|
struct CoordOperatorsHelper {
|
||||||
|
friend bool operator==(coord aA, primitive aB) {
|
||||||
|
return aA.value == aB;
|
||||||
|
}
|
||||||
|
friend bool operator==(primitive aA, coord aB) {
|
||||||
|
return aA == aB.value;
|
||||||
|
}
|
||||||
|
friend bool operator!=(coord aA, primitive aB) {
|
||||||
|
return aA.value != aB;
|
||||||
|
}
|
||||||
|
friend bool operator!=(primitive aA, coord aB) {
|
||||||
|
return aA != aB.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef typename CommonType<coord, primitive>::type result_type;
|
||||||
|
|
||||||
|
friend result_type operator+(coord aA, primitive aB) {
|
||||||
|
return aA.value + aB;
|
||||||
|
}
|
||||||
|
friend result_type operator+(primitive aA, coord aB) {
|
||||||
|
return aA + aB.value;
|
||||||
|
}
|
||||||
|
friend result_type operator-(coord aA, primitive aB) {
|
||||||
|
return aA.value - aB;
|
||||||
|
}
|
||||||
|
friend result_type operator-(primitive aA, coord aB) {
|
||||||
|
return aA - aB.value;
|
||||||
|
}
|
||||||
|
friend result_type operator*(coord aCoord, primitive aScale) {
|
||||||
|
return aCoord.value * aScale;
|
||||||
|
}
|
||||||
|
friend result_type operator*(primitive aScale, coord aCoord) {
|
||||||
|
return aScale * aCoord.value;
|
||||||
|
}
|
||||||
|
friend result_type operator/(coord aCoord, primitive aScale) {
|
||||||
|
return aCoord.value / aScale;
|
||||||
|
}
|
||||||
|
// 'scale / coord' is intentionally omitted because it doesn't make sense.
|
||||||
|
};
|
||||||
|
|
||||||
|
// Note: 'IntCoordTyped<units>' and 'CoordTyped<units>' do not derive from
|
||||||
|
// 'units' to work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61959.
|
||||||
|
|
||||||
|
template<class units>
|
||||||
|
struct IntCoordTyped :
|
||||||
|
public BaseCoord< int32_t, IntCoordTyped<units> >,
|
||||||
|
public CoordOperatorsHelper< IntCoordTyped<units>, float >,
|
||||||
|
public CoordOperatorsHelper< IntCoordTyped<units>, double > {
|
||||||
|
static_assert(IsPixel<units>::value,
|
||||||
|
"'units' must be a coordinate system tag");
|
||||||
|
|
||||||
|
typedef BaseCoord< int32_t, IntCoordTyped<units> > Super;
|
||||||
|
|
||||||
|
MOZ_CONSTEXPR IntCoordTyped() : Super() {}
|
||||||
|
MOZ_CONSTEXPR IntCoordTyped(int32_t aValue) : Super(aValue) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class units>
|
||||||
|
struct CoordTyped :
|
||||||
|
public BaseCoord< Float, CoordTyped<units> >,
|
||||||
|
public CoordOperatorsHelper< CoordTyped<units>, int32_t >,
|
||||||
|
public CoordOperatorsHelper< CoordTyped<units>, uint32_t >,
|
||||||
|
public CoordOperatorsHelper< CoordTyped<units>, double > {
|
||||||
|
static_assert(IsPixel<units>::value,
|
||||||
|
"'units' must be a coordinate system tag");
|
||||||
|
|
||||||
|
typedef BaseCoord< Float, CoordTyped<units> > Super;
|
||||||
|
|
||||||
|
MOZ_CONSTEXPR CoordTyped() : Super() {}
|
||||||
|
MOZ_CONSTEXPR CoordTyped(Float aValue) : Super(aValue) {}
|
||||||
|
explicit MOZ_CONSTEXPR CoordTyped(const IntCoordTyped<units>& aCoord) : Super(float(aCoord.value)) {}
|
||||||
|
|
||||||
|
void Round() {
|
||||||
|
this->value = floor(this->value + 0.5);
|
||||||
|
}
|
||||||
|
void Truncate() {
|
||||||
|
this->value = int32_t(this->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
IntCoordTyped<units> Rounded() const {
|
||||||
|
return IntCoordTyped<units>(int32_t(floor(this->value + 0.5)));
|
||||||
|
}
|
||||||
|
IntCoordTyped<units> Truncated() const {
|
||||||
|
return IntCoordTyped<units>(int32_t(this->value));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* MOZILLA_GFX_COORD_H_ */
|
@ -2599,7 +2599,7 @@ DrawTargetD2D::SetupEffectForRadialGradient(const RadialGradientPattern *aPatter
|
|||||||
mPrivateData->mEffect->GetVariableByName("DeviceSpaceToUserSpace")->
|
mPrivateData->mEffect->GetVariableByName("DeviceSpaceToUserSpace")->
|
||||||
AsMatrix()->SetMatrix(matrix);
|
AsMatrix()->SetMatrix(matrix);
|
||||||
|
|
||||||
float A = dc.x * dc.x + dc.y * dc.y - dr * dr;
|
float A = dc.x.value * dc.x.value + dc.y.value * dc.y.value - dr * dr;
|
||||||
|
|
||||||
uint32_t offset = 0;
|
uint32_t offset = 0;
|
||||||
switch (stops->mStopCollection->GetExtendMode()) {
|
switch (stops->mStopCollection->GetExtendMode()) {
|
||||||
|
@ -35,8 +35,8 @@ DrawTargetTiled::Init(const TileSet& aTiles)
|
|||||||
mTiles[i].mTileOrigin.x + mTiles[i].mDrawTarget->GetSize().width);
|
mTiles[i].mTileOrigin.x + mTiles[i].mDrawTarget->GetSize().width);
|
||||||
uint32_t newYMost = max(mRect.YMost(),
|
uint32_t newYMost = max(mRect.YMost(),
|
||||||
mTiles[i].mTileOrigin.y + mTiles[i].mDrawTarget->GetSize().height);
|
mTiles[i].mTileOrigin.y + mTiles[i].mDrawTarget->GetSize().height);
|
||||||
mRect.x = min(mRect.x, mTiles[i].mTileOrigin.x);
|
mRect.x = min(mRect.x, mTiles[i].mTileOrigin.x.value);
|
||||||
mRect.y = min(mRect.y, mTiles[i].mTileOrigin.y);
|
mRect.y = min(mRect.y, mTiles[i].mTileOrigin.y.value);
|
||||||
mRect.width = newXMost - mRect.x;
|
mRect.width = newXMost - mRect.x;
|
||||||
mRect.height = newYMost - mRect.y;
|
mRect.height = newYMost - mRect.y;
|
||||||
}
|
}
|
||||||
|
@ -239,7 +239,7 @@ static inline bool IsPatternSupportedByD2D(const Pattern &aPattern)
|
|||||||
|
|
||||||
Point diff = pat->mCenter2 - pat->mCenter1;
|
Point diff = pat->mCenter2 - pat->mCenter1;
|
||||||
|
|
||||||
if (sqrt(diff.x * diff.x + diff.y * diff.y) >= pat->mRadius2) {
|
if (sqrt(diff.x.value * diff.x.value + diff.y.value * diff.y.value) >= pat->mRadius2) {
|
||||||
// Inner point lies outside the circle.
|
// Inner point lies outside the circle.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ FlattenedPath::QuadraticBezierTo(const Point &aCP1,
|
|||||||
const Point &aCP2)
|
const Point &aCP2)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!mCalculatedLength);
|
MOZ_ASSERT(!mCalculatedLength);
|
||||||
// We need to elevate the degree of this quadratic Bézier to cubic, so we're
|
// We need to elevate the degree of this quadratic B<EFBFBD>zier to cubic, so we're
|
||||||
// going to add an intermediate control point, and recompute control point 1.
|
// going to add an intermediate control point, and recompute control point 1.
|
||||||
// The first and last control points remain the same.
|
// The first and last control points remain the same.
|
||||||
// This formula can be found on http://fontforge.sourceforge.net/bezier.html
|
// This formula can be found on http://fontforge.sourceforge.net/bezier.html
|
||||||
@ -250,7 +250,7 @@ FlattenBezierCurveSegment(const BezierControlPoints &aControlPoints,
|
|||||||
Point cp21 = currentCP.mCP2 - currentCP.mCP3;
|
Point cp21 = currentCP.mCP2 - currentCP.mCP3;
|
||||||
Point cp31 = currentCP.mCP3 - currentCP.mCP1;
|
Point cp31 = currentCP.mCP3 - currentCP.mCP1;
|
||||||
|
|
||||||
Float s3 = (cp31.x * cp21.y - cp31.y * cp21.x) / hypotf(cp21.x, cp21.y);
|
Float s3 = (cp31.x.value * cp21.y.value - cp31.y.value * cp21.x.value) / hypotf(cp21.x, cp21.y);
|
||||||
|
|
||||||
t = 2 * Float(sqrt(aTolerance / (3. * abs(s3))));
|
t = 2 * Float(sqrt(aTolerance / (3. * abs(s3))));
|
||||||
|
|
||||||
@ -276,7 +276,7 @@ FindInflectionApproximationRange(BezierControlPoints aControlPoints,
|
|||||||
Point cp21 = aControlPoints.mCP2 - aControlPoints.mCP1;
|
Point cp21 = aControlPoints.mCP2 - aControlPoints.mCP1;
|
||||||
Point cp41 = aControlPoints.mCP4 - aControlPoints.mCP1;
|
Point cp41 = aControlPoints.mCP4 - aControlPoints.mCP1;
|
||||||
|
|
||||||
if (cp21.x == 0 && cp21.y == 0) {
|
if (cp21.x == 0.f && cp21.y == 0.f) {
|
||||||
// In this case s3 becomes lim[n->0] (cp41.x * n) / n - (cp41.y * n) / n = cp41.x - cp41.y.
|
// In this case s3 becomes lim[n->0] (cp41.x * n) / n - (cp41.y * n) / n = cp41.x - cp41.y.
|
||||||
|
|
||||||
// Use the absolute value so that Min and Max will correspond with the
|
// Use the absolute value so that Min and Max will correspond with the
|
||||||
@ -286,7 +286,7 @@ FindInflectionApproximationRange(BezierControlPoints aControlPoints,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Float s3 = (cp41.x * cp21.y - cp41.y * cp21.x) / hypotf(cp21.x, cp21.y);
|
Float s3 = (cp41.x.value * cp21.y.value - cp41.y.value * cp21.x.value) / hypotf(cp21.x, cp21.y);
|
||||||
|
|
||||||
if (s3 == 0) {
|
if (s3 == 0) {
|
||||||
// This means within the precision we have it can be approximated
|
// This means within the precision we have it can be approximated
|
||||||
|
@ -16,8 +16,8 @@ template <typename T>
|
|||||||
void ArcToBezier(T* aSink, const Point &aOrigin, const Size &aRadius,
|
void ArcToBezier(T* aSink, const Point &aOrigin, const Size &aRadius,
|
||||||
float aStartAngle, float aEndAngle, bool aAntiClockwise)
|
float aStartAngle, float aEndAngle, bool aAntiClockwise)
|
||||||
{
|
{
|
||||||
Point startPoint(aOrigin.x + cos(aStartAngle) * aRadius.width,
|
Point startPoint(aOrigin.x + cosf(aStartAngle) * aRadius.width,
|
||||||
aOrigin.y + sin(aStartAngle) * aRadius.height);
|
aOrigin.y + sinf(aStartAngle) * aRadius.height);
|
||||||
|
|
||||||
aSink->LineTo(startPoint);
|
aSink->LineTo(startPoint);
|
||||||
|
|
||||||
@ -56,10 +56,10 @@ void ArcToBezier(T* aSink, const Point &aOrigin, const Size &aRadius,
|
|||||||
currentEndAngle = currentStartAngle + arcSweepLeft * sweepDirection;
|
currentEndAngle = currentStartAngle + arcSweepLeft * sweepDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
Point currentStartPoint(aOrigin.x + cos(currentStartAngle) * aRadius.width,
|
Point currentStartPoint(aOrigin.x + cosf(currentStartAngle) * aRadius.width,
|
||||||
aOrigin.y + sin(currentStartAngle) * aRadius.height);
|
aOrigin.y + sinf(currentStartAngle) * aRadius.height);
|
||||||
Point currentEndPoint(aOrigin.x + cos(currentEndAngle) * aRadius.width,
|
Point currentEndPoint(aOrigin.x + cosf(currentEndAngle) * aRadius.width,
|
||||||
aOrigin.y + sin(currentEndAngle) * aRadius.height);
|
aOrigin.y + sinf(currentEndAngle) * aRadius.height);
|
||||||
|
|
||||||
// Calculate kappa constant for partial curve. The sign of angle in the
|
// Calculate kappa constant for partial curve. The sign of angle in the
|
||||||
// tangent will actually ensure this is negative for a counter clockwise
|
// tangent will actually ensure this is negative for a counter clockwise
|
||||||
|
@ -141,10 +141,10 @@ PathSkia::ContainsPoint(const Point &aPoint, const Matrix &aTransform) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
SkRegion pointRect;
|
SkRegion pointRect;
|
||||||
pointRect.setRect(int32_t(SkFloatToScalar(transformed.x - 1)),
|
pointRect.setRect(int32_t(SkFloatToScalar(transformed.x - 1.f)),
|
||||||
int32_t(SkFloatToScalar(transformed.y - 1)),
|
int32_t(SkFloatToScalar(transformed.y - 1.f)),
|
||||||
int32_t(SkFloatToScalar(transformed.x + 1)),
|
int32_t(SkFloatToScalar(transformed.x + 1.f)),
|
||||||
int32_t(SkFloatToScalar(transformed.y + 1)));
|
int32_t(SkFloatToScalar(transformed.y + 1.f)));
|
||||||
|
|
||||||
SkRegion pathRegion;
|
SkRegion pathRegion;
|
||||||
|
|
||||||
@ -174,10 +174,10 @@ PathSkia::StrokeContainsPoint(const StrokeOptions &aStrokeOptions,
|
|||||||
}
|
}
|
||||||
|
|
||||||
SkRegion pointRect;
|
SkRegion pointRect;
|
||||||
pointRect.setRect(int32_t(SkFloatToScalar(transformed.x - 1)),
|
pointRect.setRect(int32_t(SkFloatToScalar(transformed.x - 1.f)),
|
||||||
int32_t(SkFloatToScalar(transformed.y - 1)),
|
int32_t(SkFloatToScalar(transformed.y - 1.f)),
|
||||||
int32_t(SkFloatToScalar(transformed.x + 1)),
|
int32_t(SkFloatToScalar(transformed.x + 1.f)),
|
||||||
int32_t(SkFloatToScalar(transformed.y + 1)));
|
int32_t(SkFloatToScalar(transformed.y + 1.f)));
|
||||||
|
|
||||||
SkRegion pathRegion;
|
SkRegion pathRegion;
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
#include "Coord.h"
|
||||||
|
#include "BaseCoord.h"
|
||||||
#include "BasePoint.h"
|
#include "BasePoint.h"
|
||||||
#include "BasePoint3D.h"
|
#include "BasePoint3D.h"
|
||||||
#include "BasePoint4D.h"
|
#include "BasePoint4D.h"
|
||||||
@ -33,15 +35,21 @@ namespace gfx {
|
|||||||
|
|
||||||
template<class units>
|
template<class units>
|
||||||
struct IntPointTyped :
|
struct IntPointTyped :
|
||||||
public BasePoint< int32_t, IntPointTyped<units> >,
|
public BasePoint< int32_t, IntPointTyped<units>, IntCoordTyped<units> >,
|
||||||
public units {
|
public units {
|
||||||
static_assert(IsPixel<units>::value,
|
static_assert(IsPixel<units>::value,
|
||||||
"'units' must be a coordinate system tag");
|
"'units' must be a coordinate system tag");
|
||||||
|
|
||||||
typedef BasePoint< int32_t, IntPointTyped<units> > Super;
|
typedef IntCoordTyped<units> Coord;
|
||||||
|
typedef BasePoint< int32_t, IntPointTyped<units>, IntCoordTyped<units> > Super;
|
||||||
|
|
||||||
MOZ_CONSTEXPR IntPointTyped() : Super() {}
|
MOZ_CONSTEXPR IntPointTyped() : Super() {}
|
||||||
MOZ_CONSTEXPR IntPointTyped(int32_t aX, int32_t aY) : Super(aX, aY) {}
|
MOZ_CONSTEXPR IntPointTyped(int32_t aX, int32_t aY) : Super(Coord(aX), Coord(aY)) {}
|
||||||
|
// The mixed-type constructors (int, Coord) and (Coord, int) are needed to
|
||||||
|
// avoid ambiguities because Coord is implicitly convertible to int.
|
||||||
|
MOZ_CONSTEXPR IntPointTyped(int32_t aX, Coord aY) : Super(Coord(aX), aY) {}
|
||||||
|
MOZ_CONSTEXPR IntPointTyped(Coord aX, int32_t aY) : Super(aX, Coord(aY)) {}
|
||||||
|
MOZ_CONSTEXPR IntPointTyped(Coord aX, Coord aY) : Super(aX, aY) {}
|
||||||
|
|
||||||
// XXX When all of the code is ported, the following functions to convert to and from
|
// XXX When all of the code is ported, the following functions to convert to and from
|
||||||
// unknown types should be removed.
|
// unknown types should be removed.
|
||||||
@ -58,15 +66,21 @@ typedef IntPointTyped<UnknownUnits> IntPoint;
|
|||||||
|
|
||||||
template<class units>
|
template<class units>
|
||||||
struct PointTyped :
|
struct PointTyped :
|
||||||
public BasePoint< Float, PointTyped<units> >,
|
public BasePoint< Float, PointTyped<units>, CoordTyped<units> >,
|
||||||
public units {
|
public units {
|
||||||
static_assert(IsPixel<units>::value,
|
static_assert(IsPixel<units>::value,
|
||||||
"'units' must be a coordinate system tag");
|
"'units' must be a coordinate system tag");
|
||||||
|
|
||||||
typedef BasePoint< Float, PointTyped<units> > Super;
|
typedef CoordTyped<units> Coord;
|
||||||
|
typedef BasePoint< Float, PointTyped<units>, CoordTyped<units> > Super;
|
||||||
|
|
||||||
MOZ_CONSTEXPR PointTyped() : Super() {}
|
MOZ_CONSTEXPR PointTyped() : Super() {}
|
||||||
MOZ_CONSTEXPR PointTyped(Float aX, Float aY) : Super(aX, aY) {}
|
MOZ_CONSTEXPR PointTyped(Float aX, Float aY) : Super(Coord(aX), Coord(aY)) {}
|
||||||
|
// The mixed-type constructors (Float, Coord) and (Coord, Float) are needed to
|
||||||
|
// avoid ambiguities because Coord is implicitly convertible to Float.
|
||||||
|
MOZ_CONSTEXPR PointTyped(Float aX, Coord aY) : Super(Coord(aX), aY) {}
|
||||||
|
MOZ_CONSTEXPR PointTyped(Coord aX, Float aY) : Super(aX, Coord(aY)) {}
|
||||||
|
MOZ_CONSTEXPR PointTyped(Coord aX, Coord aY) : Super(aX.value, aY.value) {}
|
||||||
MOZ_CONSTEXPR MOZ_IMPLICIT PointTyped(const IntPointTyped<units>& point) : Super(float(point.x), float(point.y)) {}
|
MOZ_CONSTEXPR MOZ_IMPLICIT PointTyped(const IntPointTyped<units>& point) : Super(float(point.x), float(point.y)) {}
|
||||||
|
|
||||||
// XXX When all of the code is ported, the following functions to convert to and from
|
// XXX When all of the code is ported, the following functions to convert to and from
|
||||||
@ -84,8 +98,14 @@ typedef PointTyped<UnknownUnits> Point;
|
|||||||
|
|
||||||
template<class units>
|
template<class units>
|
||||||
IntPointTyped<units> RoundedToInt(const PointTyped<units>& aPoint) {
|
IntPointTyped<units> RoundedToInt(const PointTyped<units>& aPoint) {
|
||||||
return IntPointTyped<units>(int32_t(floorf(aPoint.x + 0.5f)),
|
return IntPointTyped<units>(aPoint.x.Rounded(),
|
||||||
int32_t(floorf(aPoint.y + 0.5f)));
|
aPoint.y.Rounded());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class units>
|
||||||
|
IntPointTyped<units> TruncatedToInt(const PointTyped<units>& aPoint) {
|
||||||
|
return IntPointTyped<units>(aPoint.x.Truncated(),
|
||||||
|
aPoint.y.Truncated());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class units>
|
template<class units>
|
||||||
|
@ -240,15 +240,15 @@ SVGTurbulenceRenderer<Type,Stitch,f32x4_t,i32x4_t,u8x16_t>::Noise2(Point aVec, c
|
|||||||
uint8_t i = mLatticeSelector[b0.x & sBM];
|
uint8_t i = mLatticeSelector[b0.x & sBM];
|
||||||
uint8_t j = mLatticeSelector[b1.x & sBM];
|
uint8_t j = mLatticeSelector[b1.x & sBM];
|
||||||
|
|
||||||
const f32x4_t* qua = mGradient[(i + b0.y) & sBM];
|
const f32x4_t* qua = mGradient[(i + b0.y.value) & sBM];
|
||||||
const f32x4_t* qub = mGradient[(i + b1.y) & sBM];
|
const f32x4_t* qub = mGradient[(i + b1.y.value) & sBM];
|
||||||
const f32x4_t* qva = mGradient[(j + b0.y) & sBM];
|
const f32x4_t* qva = mGradient[(j + b0.y.value) & sBM];
|
||||||
const f32x4_t* qvb = mGradient[(j + b1.y) & sBM];
|
const f32x4_t* qvb = mGradient[(j + b1.y.value) & sBM];
|
||||||
|
|
||||||
return BiMix(simd::WSumF32(qua[0], qua[1], r.x, r.y),
|
return BiMix(simd::WSumF32(qua[0], qua[1], r.x, r.y),
|
||||||
simd::WSumF32(qva[0], qva[1], r.x - 1, r.y),
|
simd::WSumF32(qva[0], qva[1], r.x - 1.f, r.y),
|
||||||
simd::WSumF32(qub[0], qub[1], r.x, r.y - 1),
|
simd::WSumF32(qub[0], qub[1], r.x, r.y - 1.f),
|
||||||
simd::WSumF32(qvb[0], qvb[1], r.x - 1, r.y - 1),
|
simd::WSumF32(qvb[0], qvb[1], r.x - 1.f, r.y - 1.f),
|
||||||
SCurve(r));
|
SCurve(r));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ EXPORTS.mozilla += [
|
|||||||
|
|
||||||
EXPORTS.mozilla.gfx += [
|
EXPORTS.mozilla.gfx += [
|
||||||
'2D.h',
|
'2D.h',
|
||||||
|
'BaseCoord.h',
|
||||||
'BaseMargin.h',
|
'BaseMargin.h',
|
||||||
'BasePoint.h',
|
'BasePoint.h',
|
||||||
'BasePoint3D.h',
|
'BasePoint3D.h',
|
||||||
@ -18,6 +19,7 @@ EXPORTS.mozilla.gfx += [
|
|||||||
'BaseSize.h',
|
'BaseSize.h',
|
||||||
'Blur.h',
|
'Blur.h',
|
||||||
'BorrowedContext.h',
|
'BorrowedContext.h',
|
||||||
|
'Coord.h',
|
||||||
'DataSurfaceHelpers.h',
|
'DataSurfaceHelpers.h',
|
||||||
'Filters.h',
|
'Filters.h',
|
||||||
'Helpers.h',
|
'Helpers.h',
|
||||||
|
@ -26,8 +26,8 @@ TestPoint::Addition()
|
|||||||
|
|
||||||
a += b;
|
a += b;
|
||||||
|
|
||||||
VERIFY(a.x == 7);
|
VERIFY(a.x == 7.f);
|
||||||
VERIFY(a.y == -3);
|
VERIFY(a.y == -3.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -41,6 +41,6 @@ TestPoint::Subtraction()
|
|||||||
|
|
||||||
a -= b;
|
a -= b;
|
||||||
|
|
||||||
VERIFY(a.x == -3);
|
VERIFY(a.x == -3.f);
|
||||||
VERIFY(a.y == 7);
|
VERIFY(a.y == 7.f);
|
||||||
}
|
}
|
||||||
|
@ -507,6 +507,38 @@ struct ParamTraits<nsIntSize>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct ParamTraits< mozilla::gfx::CoordTyped<T> >
|
||||||
|
{
|
||||||
|
typedef mozilla::gfx::CoordTyped<T> paramType;
|
||||||
|
|
||||||
|
static void Write(Message* msg, const paramType& param)
|
||||||
|
{
|
||||||
|
WriteParam(msg, param.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Read(const Message* msg, void** iter, paramType* result)
|
||||||
|
{
|
||||||
|
return (ReadParam(msg, iter, &result->value));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct ParamTraits< mozilla::gfx::IntCoordTyped<T> >
|
||||||
|
{
|
||||||
|
typedef mozilla::gfx::IntCoordTyped<T> paramType;
|
||||||
|
|
||||||
|
static void Write(Message* msg, const paramType& param)
|
||||||
|
{
|
||||||
|
WriteParam(msg, param.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Read(const Message* msg, void** iter, paramType* result)
|
||||||
|
{
|
||||||
|
return (ReadParam(msg, iter, &result->value));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<class T, class U>
|
template<class T, class U>
|
||||||
struct ParamTraits< mozilla::gfx::ScaleFactor<T, U> >
|
struct ParamTraits< mozilla::gfx::ScaleFactor<T, U> >
|
||||||
{
|
{
|
||||||
|
@ -197,7 +197,7 @@ protected:
|
|||||||
public:
|
public:
|
||||||
NS_INLINE_DECL_REFCOUNTING(Compositor)
|
NS_INLINE_DECL_REFCOUNTING(Compositor)
|
||||||
|
|
||||||
Compositor(PCompositorParent* aParent = nullptr)
|
explicit Compositor(PCompositorParent* aParent = nullptr)
|
||||||
: mCompositorID(0)
|
: mCompositorID(0)
|
||||||
, mDiagnosticTypes(DiagnosticTypes::NO_DIAGNOSTIC)
|
, mDiagnosticTypes(DiagnosticTypes::NO_DIAGNOSTIC)
|
||||||
, mParent(aParent)
|
, mParent(aParent)
|
||||||
|
@ -42,7 +42,7 @@ struct Effect
|
|||||||
{
|
{
|
||||||
NS_INLINE_DECL_REFCOUNTING(Effect)
|
NS_INLINE_DECL_REFCOUNTING(Effect)
|
||||||
|
|
||||||
Effect(EffectTypes aType) : mType(aType) {}
|
explicit Effect(EffectTypes aType) : mType(aType) {}
|
||||||
|
|
||||||
EffectTypes mType;
|
EffectTypes mType;
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ struct EffectMask : public Effect
|
|||||||
|
|
||||||
struct EffectBlendMode : public Effect
|
struct EffectBlendMode : public Effect
|
||||||
{
|
{
|
||||||
EffectBlendMode(gfx::CompositionOp aBlendMode)
|
explicit EffectBlendMode(gfx::CompositionOp aBlendMode)
|
||||||
: Effect(EffectTypes::BLEND_MODE)
|
: Effect(EffectTypes::BLEND_MODE)
|
||||||
, mBlendMode(aBlendMode)
|
, mBlendMode(aBlendMode)
|
||||||
{ }
|
{ }
|
||||||
@ -112,7 +112,7 @@ struct EffectBlendMode : public Effect
|
|||||||
// Render to a render target rather than the screen.
|
// Render to a render target rather than the screen.
|
||||||
struct EffectRenderTarget : public TexturedEffect
|
struct EffectRenderTarget : public TexturedEffect
|
||||||
{
|
{
|
||||||
EffectRenderTarget(CompositingRenderTarget *aRenderTarget)
|
explicit EffectRenderTarget(CompositingRenderTarget *aRenderTarget)
|
||||||
: TexturedEffect(EffectTypes::RENDER_TARGET, aRenderTarget, true, gfx::Filter::LINEAR)
|
: TexturedEffect(EffectTypes::RENDER_TARGET, aRenderTarget, true, gfx::Filter::LINEAR)
|
||||||
, mRenderTarget(aRenderTarget)
|
, mRenderTarget(aRenderTarget)
|
||||||
{}
|
{}
|
||||||
@ -183,7 +183,7 @@ struct EffectComponentAlpha : public TexturedEffect
|
|||||||
|
|
||||||
struct EffectSolidColor : public Effect
|
struct EffectSolidColor : public Effect
|
||||||
{
|
{
|
||||||
EffectSolidColor(const gfx::Color &aColor)
|
explicit EffectSolidColor(const gfx::Color &aColor)
|
||||||
: Effect(EffectTypes::SOLID_COLOR)
|
: Effect(EffectTypes::SOLID_COLOR)
|
||||||
, mColor(aColor)
|
, mColor(aColor)
|
||||||
{}
|
{}
|
||||||
|
@ -563,6 +563,22 @@ struct ScrollableLayerGuid {
|
|||||||
{
|
{
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator<(const ScrollableLayerGuid& other) const
|
||||||
|
{
|
||||||
|
if (mLayersId < other.mLayersId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (mLayersId == other.mLayersId) {
|
||||||
|
if (mPresShellId < other.mPresShellId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (mPresShellId == other.mPresShellId) {
|
||||||
|
return mScrollId < other.mScrollId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <int LogLevel>
|
template <int LogLevel>
|
||||||
|
@ -57,7 +57,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
class SurfaceReleaser : public nsRunnable {
|
class SurfaceReleaser : public nsRunnable {
|
||||||
public:
|
public:
|
||||||
SurfaceReleaser(RawRef aRef) : mRef(aRef) {}
|
explicit SurfaceReleaser(RawRef aRef) : mRef(aRef) {}
|
||||||
NS_IMETHOD Run() {
|
NS_IMETHOD Run() {
|
||||||
mRef->Release();
|
mRef->Release();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -350,7 +350,7 @@ public:
|
|||||||
|
|
||||||
enum { DISABLE_ASYNC = 0x0, ENABLE_ASYNC = 0x01 };
|
enum { DISABLE_ASYNC = 0x0, ENABLE_ASYNC = 0x01 };
|
||||||
|
|
||||||
ImageContainer(int flag = 0);
|
explicit ImageContainer(int flag = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an Image in one of the given formats.
|
* Create an Image in one of the given formats.
|
||||||
@ -666,7 +666,7 @@ private:
|
|||||||
class AutoLockImage
|
class AutoLockImage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AutoLockImage(ImageContainer *aContainer) : mContainer(aContainer) { mImage = mContainer->LockCurrentImage(); }
|
explicit AutoLockImage(ImageContainer *aContainer) : mContainer(aContainer) { mImage = mContainer->LockCurrentImage(); }
|
||||||
AutoLockImage(ImageContainer *aContainer, RefPtr<gfx::SourceSurface> *aSurface) : mContainer(aContainer) {
|
AutoLockImage(ImageContainer *aContainer, RefPtr<gfx::SourceSurface> *aSurface) : mContainer(aContainer) {
|
||||||
*aSurface = mContainer->LockCurrentAsSourceSurface(&mSize, getter_AddRefs(mImage));
|
*aSurface = mContainer->LockCurrentAsSourceSurface(&mSize, getter_AddRefs(mImage));
|
||||||
}
|
}
|
||||||
@ -821,7 +821,7 @@ public:
|
|||||||
|
|
||||||
virtual gfx::IntSize GetSize() { return mSize; }
|
virtual gfx::IntSize GetSize() { return mSize; }
|
||||||
|
|
||||||
PlanarYCbCrImage(BufferRecycleBin *aRecycleBin);
|
explicit PlanarYCbCrImage(BufferRecycleBin *aRecycleBin);
|
||||||
|
|
||||||
virtual SharedPlanarYCbCrImage *AsSharedPlanarYCbCrImage() { return nullptr; }
|
virtual SharedPlanarYCbCrImage *AsSharedPlanarYCbCrImage() { return nullptr; }
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user