Backed out changeset 01d03b6be047 (bug 1171200)

This commit is contained in:
mcaceres@mozilla.com 2015-07-17 11:45:59 +10:00
parent 67cc5004eb
commit 4a90596778
17 changed files with 247 additions and 467 deletions

View File

@ -11,82 +11,112 @@
*
* BUG: https://bugzilla.mozilla.org/show_bug.cgi?id=1083410
*/
/*globals Task, ManifestObtainer, ManifestFinder, content, sendAsyncMessage, addMessageListener, Components*/
/*globals content, sendAsyncMessage, addMessageListener, Components*/
'use strict';
const {
utils: Cu,
classes: Cc,
interfaces: Ci
} = Components;
Cu.import('resource://gre/modules/ManifestObtainer.jsm');
Cu.import('resource://gre/modules/ManifestFinder.jsm');
Cu.import('resource://gre/modules/Task.jsm');
const {
ManifestProcessor
} = Cu.import('resource://gre/modules/WebManifest.jsm', {});
const {
Task: {
spawn, async
}
} = Components.utils.import('resource://gre/modules/Task.jsm', {});
const finder = new ManifestFinder();
addMessageListener('DOM:ManifestObtainer:Obtain', async(function* (aMsg) {
const response = {
msgId: aMsg.data.msgId,
success: true,
result: undefined
};
try {
response.result = yield fetchManifest();
} catch (err) {
response.success = false;
response.result = cloneError(err);
}
sendAsyncMessage('DOM:ManifestObtainer:Obtain', response);
}));
const MessageHandler = {
registerListeners() {
addMessageListener(
'DOM:WebManifest:hasManifestLink',
this.hasManifestLink.bind(this)
);
addMessageListener(
'DOM:ManifestObtainer:Obtain',
this.obtainManifest.bind(this)
);
},
function cloneError(aError) {
const clone = {
'fileName': String(aError.fileName),
'lineNumber': String(aError.lineNumber),
'columnNumber': String(aError.columnNumber),
'stack': String(aError.stack),
'message': String(aError.message),
'name': String(aError.name)
};
return clone;
}
/**
* Check if the content document includes a link to a web manifest.
* @param {Object} aMsg The IPC message.
*/
hasManifestLink: Task.async(function* ({data: {id}}) {
const response = this.makeMsgResponse(id);
response.result = yield finder.hasManifestLink(content);
response.success = true;
sendAsyncMessage('DOM:WebManifest:hasManifestLink', response);
}),
/**
* Obtains a web manifest from content by using the ManifestObtainer
* and messages back the result.
* @param {Object} aMsg The IPC message.
*/
obtainManifest: Task.async(function* ({data: {id}}) {
const obtainer = new ManifestObtainer();
const response = this.makeMsgResponse(id);
try {
response.result = yield obtainer.obtainManifest(content);
response.success = true;
} catch (err) {
response.result = this.serializeError(err);
function fetchManifest() {
return spawn(function* () {
if (!content || content.top !== content) {
let msg = 'Content window must be a top-level browsing context.';
throw new Error(msg);
}
sendAsyncMessage('DOM:ManifestObtainer:Obtain', response);
}),
makeMsgResponse(aId) {
return {
id: aId,
success: false,
result: undefined
const elem = content.document.querySelector('link[rel~="manifest"]');
if (!elem || !elem.getAttribute('href')) {
let msg = 'No manifest to fetch.';
throw new Error(msg);
}
// Throws on malformed URLs
const manifestURL = new content.URL(elem.href, elem.baseURI);
if (!canLoadManifest(elem)) {
let msg = `Content Security Policy: The page's settings blocked the `;
msg += `loading of a resource at ${elem.href}`;
throw new Error(msg);
}
const reqInit = {
mode: 'cors'
};
},
if (elem.crossOrigin === 'use-credentials') {
reqInit.credentials = 'include';
}
const req = new content.Request(manifestURL, reqInit);
req.setContentPolicyType(Ci.nsIContentPolicy.TYPE_WEB_MANIFEST);
const response = yield content.fetch(req);
const manifest = yield processResponse(response, content);
return manifest;
});
}
/**
* Utility function to Serializes an JS Error, so it can be transferred over
* the message channel.
* FIX ME: https://bugzilla.mozilla.org/show_bug.cgi?id=1172586
* @param {Error} aError The error to serialize.
* @return {Object} The serialized object.
*/
serializeError(aError) {
const clone = {
'fileName': aError.fileName,
'lineNumber': aError.lineNumber,
'columnNumber': aError.columnNumber,
'stack': aError.stack,
'message': aError.message,
'name': aError.name
function canLoadManifest(aElem) {
const contentPolicy = Cc['@mozilla.org/layout/content-policy;1']
.getService(Ci.nsIContentPolicy);
const mimeType = aElem.type || 'application/manifest+json';
const elemURI = BrowserUtils.makeURI(
aElem.href, aElem.ownerDocument.characterSet
);
const shouldLoad = contentPolicy.shouldLoad(
Ci.nsIContentPolicy.TYPE_WEB_MANIFEST, elemURI,
aElem.ownerDocument.documentURIObject,
aElem, mimeType, null
);
return shouldLoad === Ci.nsIContentPolicy.ACCEPT;
}
function processResponse(aResp, aContentWindow) {
return spawn(function* () {
const badStatus = aResp.status < 200 || aResp.status >= 300;
if (aResp.type === 'error' || badStatus) {
let msg =
`Fetch error: ${aResp.status} - ${aResp.statusText} at ${aResp.url}`;
throw new Error(msg);
}
const text = yield aResp.text();
const args = {
jsonText: text,
manifestURL: aResp.url,
docURL: aContentWindow.location.href
};
return clone;
},
};
MessageHandler.registerListeners();
const processor = new ManifestProcessor();
const manifest = processor.process(args);
return Cu.cloneInto(manifest, content);
});
}

View File

@ -1,58 +0,0 @@
/* 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 https://mozilla.org/MPL/2.0/. */
/* globals Components, Task, PromiseMessage */
'use strict';
const {
utils: Cu
} = Components;
Cu.import('resource://gre/modules/PromiseMessage.jsm');
Cu.import('resource://gre/modules/Task.jsm');
/**
* @constructor
*/
function ManifestFinder() {}
/**
* checks if a browser window's document has a conforming
* manifest link relationship.
* @param aWindowOrBrowser the XUL browser or window to check.
* @return {Promise}
*/
ManifestFinder.prototype.hasManifestLink = Task.async(
function* (aWindowOrBrowser) {
const msgKey = 'DOM:WebManifest:hasManifestLink';
if (!(aWindowOrBrowser && (aWindowOrBrowser.namespaceURI || aWindowOrBrowser.location))) {
throw new TypeError('Invalid input.');
}
if (isXULBrowser(aWindowOrBrowser)) {
const mm = aWindowOrBrowser.messageManager;
const reply = yield PromiseMessage.send(mm, msgKey);
return reply.data.result;
}
return checkForManifest(aWindowOrBrowser);
}
);
function isXULBrowser(aBrowser) {
const XUL = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul';
return (aBrowser.namespaceURI && aBrowser.namespaceURI === XUL);
}
function checkForManifest(aWindow) {
// Only top-level browsing contexts are valid.
if (!aWindow || aWindow.top !== aWindow) {
return false;
}
const elem = aWindow.document.querySelector('link[rel~="manifest"]');
// Only if we have an element and a non-empty href attribute.
if (!elem || !elem.getAttribute('href')) {
return false;
}
return true;
}
this.EXPORTED_SYMBOLS = [ // jshint ignore:line
'ManifestFinder'
];

View File

@ -0,0 +1,92 @@
/* 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/.
*
* ManifestObtainer is an implementation of:
* http://w3c.github.io/manifest/#obtaining
*
* Exposes public method `.obtainManifest(browserWindow)`, which returns
* a promise. If successful, you get back a manifest (string).
*
* For e10s compat, this JSM relies on the following to do
* the nessesary IPC:
* dom/ipc/manifestMessages.js
*
* whose internal URL is:
* 'chrome://global/content/manifestMessages.js'
*
* Which is injected into every browser instance via browser.js.
*
* BUG: https://bugzilla.mozilla.org/show_bug.cgi?id=1083410
* exported ManifestObtainer
*/
'use strict';
const MSG_KEY = 'DOM:ManifestObtainer:Obtain';
let messageCounter = 0;
// FIXME: Ideally, we would store a reference to the
// message manager in a weakmap instead of needing a
// browserMap. However, trying to store a messageManager
// results in a TypeError because of:
// https://bugzilla.mozilla.org/show_bug.cgi?id=888600
const browsersMap = new WeakMap();
function ManifestObtainer() {}
ManifestObtainer.prototype = {
obtainManifest(aBrowserWindow) {
if (!aBrowserWindow) {
const err = new TypeError('Invalid input. Expected xul browser.');
return Promise.reject(err);
}
const mm = aBrowserWindow.messageManager;
const onMessage = function(aMsg) {
const msgId = aMsg.data.msgId;
const {
resolve, reject
} = browsersMap.get(aBrowserWindow).get(msgId);
browsersMap.get(aBrowserWindow).delete(msgId);
// If we we've processed all messages,
// stop listening.
if (!browsersMap.get(aBrowserWindow).size) {
browsersMap.delete(aBrowserWindow);
mm.removeMessageListener(MSG_KEY, onMessage);
}
if (aMsg.data.success) {
return resolve(aMsg.data.result);
}
reject(toError(aMsg.data.result));
};
// If we are not already listening for messages
// start listening.
if (!browsersMap.has(aBrowserWindow)) {
browsersMap.set(aBrowserWindow, new Map());
mm.addMessageListener(MSG_KEY, onMessage);
}
return new Promise((resolve, reject) => {
const msgId = messageCounter++;
browsersMap.get(aBrowserWindow).set(msgId, {
resolve: resolve,
reject: reject
});
mm.sendAsyncMessage(MSG_KEY, {
msgId: msgId
});
});
function toError(aErrorClone) {
let error;
switch (aErrorClone.name) {
case 'TypeError':
error = new TypeError();
break;
default:
error = new Error();
}
Object.getOwnPropertyNames(aErrorClone)
.forEach(name => error[name] = aErrorClone[name]);
return error;
}
}
};
this.ManifestObtainer = ManifestObtainer; // jshint ignore:line
this.EXPORTED_SYMBOLS = ['ManifestObtainer']; // jshint ignore:line

View File

@ -1,170 +0,0 @@
/* 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/.
*/
/*
* ManifestObtainer is an implementation of:
* http://w3c.github.io/manifest/#obtaining
*
* Exposes public method `.obtainManifest(Window)`, which returns
* a promise. If successful, you get back a manifest object.
*
* Import it with URL:
* 'chrome://global/content/manifestMessages.js'
*
* e10s IPC messaage from this components are handled by:
* dom/ipc/manifestMessages.js
*
* Which is injected into every browser instance via browser.js.
*
* exported ManifestObtainer
*/
/*globals Components, Task, PromiseMessage, XPCOMUtils, ManifestProcessor, BrowserUtils*/
'use strict';
const {
utils: Cu,
classes: Cc,
interfaces: Ci
} = Components;
Cu.import('resource://gre/modules/Task.jsm');
Cu.import('resource://gre/modules/PromiseMessage.jsm');
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.import('resource://gre/modules/ManifestProcessor.jsm');
XPCOMUtils.defineLazyModuleGetter(this, 'BrowserUtils', // jshint ignore:line
'resource://gre/modules/BrowserUtils.jsm');
const processor = new ManifestProcessor();
/**
* Asynchronously processes the result of response after having fetched
* a manifest.
* @param {Response} aResp Response from fetch().
* @param {Window} aContentWindow The content window.
* @return {Promise<Object>} The processed manifest.
*/
const processResponse = Task.async(function* (aResp, aContentWindow) {
const badStatus = aResp.status < 200 || aResp.status >= 300;
if (aResp.type === 'error' || badStatus) {
const msg =
`Fetch error: ${aResp.status} - ${aResp.statusText} at ${aResp.url}`;
throw new Error(msg);
}
const text = yield aResp.text();
const args = {
jsonText: text,
manifestURL: aResp.url,
docURL: aContentWindow.location.href
};
const manifest = processor.process(args);
return manifest;
});
/**
* Asynchronously fetches a web manifest.
* @param {Window} a The content Window from where to extract the manifest.
* @return {Promise<Object>}
*/
const fetchManifest = Task.async(function* (aWindow) {
if (!aWindow || aWindow.top !== aWindow) {
let msg = 'Window must be a top-level browsing context.';
throw new Error(msg);
}
const elem = aWindow.document.querySelector('link[rel~="manifest"]');
if (!elem || !elem.getAttribute('href')) {
let msg = `No manifest to fetch at ${aWindow.location}`;
throw new Error(msg);
}
// Throws on malformed URLs
const manifestURL = new aWindow.URL(elem.href, elem.baseURI);
if (!canLoadManifest(elem)) {
let msg = `Content Security Policy: The page's settings blocked the `;
msg += `loading of a resource at ${elem.href}`;
throw new Error(msg);
}
const reqInit = {
mode: 'cors'
};
if (elem.crossOrigin === 'use-credentials') {
reqInit.credentials = 'include';
}
const req = new aWindow.Request(manifestURL, reqInit);
req.setContentPolicyType(Ci.nsIContentPolicy.TYPE_WEB_MANIFEST);
const response = yield aWindow.fetch(req);
const manifest = yield processResponse(response, aWindow);
return manifest;
});
/**
* Checks against security manager if we can load the web manifest.
* @param {HTMLLinkElement} aElem The HTML element to security check.
* @return {Boolean} True if it can, false if it can't.
*/
function canLoadManifest(aElem) {
const contentPolicy = Cc['@mozilla.org/layout/content-policy;1']
.getService(Ci.nsIContentPolicy);
const mimeType = aElem.type || 'application/manifest+json';
const elemURI = BrowserUtils.makeURI(
aElem.href, aElem.ownerDocument.characterSet
);
const shouldLoad = contentPolicy.shouldLoad(
Ci.nsIContentPolicy.TYPE_WEB_MANIFEST, elemURI,
aElem.ownerDocument.documentURIObject,
aElem, mimeType, null
);
return shouldLoad === Ci.nsIContentPolicy.ACCEPT;
}
/**
* ManifestObtainer
* @constructor
*/
function ManifestObtainer() {
}
/**
* Public interface for obtaining a web manifest.
* @param {XULWindow or DOMWindow} aWindow The Window from which to fetch
* the manifest.
* @return {Promise<Object>} The processed manifest.
*/
ManifestObtainer.prototype.obtainManifest = Task.async(
function* (aWindowOrBrowser) {
const msgKey = 'DOM:ManifestObtainer:Obtain';
if (!(aWindowOrBrowser && (aWindowOrBrowser.namespaceURI || aWindowOrBrowser.location))) {
throw new TypeError('Invalid input.');
}
if (isXULBrowser(aWindowOrBrowser)) {
const mm = aWindowOrBrowser.messageManager;
const {data: {success, result}} = yield PromiseMessage.send(mm, msgKey);
if (!success) {
const error = toError(result);
throw error;
}
return result;
}
const manifest = yield fetchManifest(aWindowOrBrowser);
return manifest;
}
);
function toError(aErrorClone) {
let error;
switch (aErrorClone.name) {
case 'TypeError':
error = new TypeError();
break;
default:
error = new Error();
}
Object.getOwnPropertyNames(aErrorClone)
.forEach(name => error[name] = aErrorClone[name]);
return error;
}
function isXULBrowser(aBrowser) {
const XUL = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul';
return (aBrowser.namespaceURI && aBrowser.namespaceURI === XUL);
}
this.ManifestObtainer = ManifestObtainer; // jshint ignore:line
this.EXPORTED_SYMBOLS = ['ManifestObtainer']; // jshint ignore:line

View File

@ -19,10 +19,12 @@
* TODO: The constructor should accept the UA's supported display modes.
* TODO: hook up developer tools to console. (1086997).
*/
/*globals Components, ValueExtractor, ImageObjectProcessor, ConsoleAPI*/
/*globals Components*/
'use strict';
const {
utils: Cu
utils: Cu,
interfaces: Ci,
classes: Cc
} = Components;
Cu.importGlobalProperties(['URL']);
const displayModes = new Set(['fullscreen', 'standalone', 'minimal-ui',
@ -32,12 +34,18 @@ const orientationTypes = new Set(['any', 'natural', 'landscape', 'portrait',
'portrait-primary', 'portrait-secondary', 'landscape-primary',
'landscape-secondary'
]);
Cu.import('resource://gre/modules/devtools/Console.jsm');
const {
ConsoleAPI
} = Cu.import('resource://gre/modules/devtools/Console.jsm', {});
// ValueExtractor is used by the various processors to get values
// from the manifest and to report errors.
Cu.import('resource://gre/modules/ValueExtractor.jsm');
const {
ValueExtractor
} = Cu.import('resource://gre/modules/ValueExtractor.js', {});
// ImageObjectProcessor is used to process things like icons and images
Cu.import('resource://gre/modules/ImageObjectProcessor.jsm');
const {
ImageObjectProcessor
} = Cu.import('resource://gre/modules/ImageObjectProcessor.js', {});
function ManifestProcessor() {}

View File

@ -25,7 +25,9 @@ ValueExtractor.prototype = {
// objectName: string used to construct the developer warning.
// property: the name of the property being extracted.
// trim: boolean, if the value should be trimmed (used by string type).
extractValue({expectedType, object, objectName, property, trim}) {
extractValue({
expectedType, object, objectName, property, trim
}) {
const value = object[property];
const isArray = Array.isArray(value);
// We need to special-case "array", as it's not a JS primitive.

View File

@ -0,0 +1,19 @@
/* 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 https://mozilla.org/MPL/2.0/. */
/*exported EXPORTED_SYMBOLS, ManifestProcessor, ManifestObtainer*/
/*globals Components */
'use strict';
const {
utils: Cu
} = Components;
this.EXPORTED_SYMBOLS = [
'ManifestObtainer',
'ManifestProcessor'
];
// Export public interfaces
for (let symbl of EXPORTED_SYMBOLS) {
Cu.import(`resource://gre/modules/${symbl}.js`);
}

View File

@ -5,11 +5,11 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXTRA_JS_MODULES += [
'ImageObjectProcessor.jsm',
'ManifestFinder.jsm',
'ManifestObtainer.jsm',
'ManifestProcessor.jsm',
'ValueExtractor.jsm',
'ImageObjectProcessor.js',
'ManifestObtainer.js',
'ManifestProcessor.js',
'ValueExtractor.js',
'WebManifest.jsm'
]
MOCHITEST_MANIFESTS += ['test/mochitest.ini']

View File

@ -1,3 +1,2 @@
[DEFAULT]
[browser_hasManifestLink.js]
[browser_ManifestObtainer_obtain.js]
[browser_ManifestObtainer_obtain.js]

View File

@ -3,7 +3,7 @@
'use strict';
const {
ManifestObtainer
} = Cu.import('resource://gre/modules/ManifestObtainer.jsm', {});
} = Cu.import('resource://gre/modules/WebManifest.jsm', {});
requestLongerTimeout(4); // e10s tests take time.
const defaultURL =

View File

@ -1,109 +0,0 @@
//Used by JSHint:
/*global Cu, BrowserTestUtils, is, ok, add_task, gBrowser, ManifestFinder */
'use strict';
Cu.import('resource://gre/modules/ManifestFinder.jsm', this); // jshint ignore:line
const finder = new ManifestFinder();
const defaultURL =
'http://example.org/tests/dom/manifest/test/resource.sjs';
const tests = [{
expected: 'Document has a web manifest.',
get tabURL() {
let query = [
`body=<h1>${this.expected}</h1>`,
'Content-Type=text/html; charset=utf-8',
];
const URL = `${defaultURL}?${query.join('&')}`;
return URL;
},
run(result) {
is(result, true, this.expected);
},
testData: `
<link rel="manifesto" href='${defaultURL}?body={"name":"fail"}'>
<link rel="foo bar manifest bar test" href='${defaultURL}?body={"name":"value"}'>
<link rel="manifest" href='${defaultURL}?body={"name":"fail"}'>`
}, {
expected: 'Document does not have a web manifest.',
get tabURL() {
let query = [
`body=<h1>${this.expected}</h1>`,
'Content-Type=text/html; charset=utf-8',
];
const URL = `${defaultURL}?${query.join('&')}`;
return URL;
},
run(result) {
is(result, false, this.expected);
},
testData: `
<link rel="amanifista" href='${defaultURL}?body={"name":"fail"}'>
<link rel="foo bar manifesto bar test" href='${defaultURL}?body={"name":"pass-1"}'>
<link rel="manifesto" href='${defaultURL}?body={"name":"fail"}'>`
}, {
expected: 'Manifest link is has empty href.',
get tabURL() {
let query = [
`body=<h1>${this.expected}</h1>`,
'Content-Type=text/html; charset=utf-8',
];
const URL = `${defaultURL}?${query.join('&')}`;
return URL;
},
run(result) {
is(result, false, this.expected);
},
testData: `
<link rel="manifest" href="">
<link rel="manifest" href='${defaultURL}?body={"name":"fail"}'>`
}, {
expected: 'Manifest link is missing.',
get tabURL() {
let query = [
`body=<h1>${this.expected}</h1>`,
'Content-Type=text/html; charset=utf-8',
];
const URL = `${defaultURL}?${query.join('&')}`;
return URL;
},
run(result) {
is(result, false, this.expected);
},
testData: `
<link rel="manifest">
<link rel="manifest" href='${defaultURL}?body={"name":"fail"}'>`
}];
/**
* Test basic API error conditions
*/
add_task(function* () {
let expected = 'Invalid types should throw a TypeError.';
for (let invalidValue of [undefined, null, 1, {}, 'test']) {
try {
yield finder.hasManifestLink(invalidValue);
ok(false, expected);
} catch (e) {
is(e.name, 'TypeError', expected);
}
}
});
add_task(function* () {
for (let test of tests) {
let tabOptions = {
gBrowser: gBrowser,
url: test.tabURL,
};
yield BrowserTestUtils.withNewTab(
tabOptions,
browser => testHasManifest(browser, test)
);
}
function* testHasManifest(aBrowser, aTest) {
aBrowser.contentWindowAsCPOW.document.head.innerHTML = aTest.testData;
const result = yield finder.hasManifestLink(aBrowser);
aTest.run(result);
}
});

View File

@ -1,11 +1,11 @@
/**
* Common infrastructure for manifest tests.
**/
/*globals SpecialPowers, ManifestProcessor*/
'use strict';
const {
ManifestProcessor
} = SpecialPowers.Cu.import('resource://gre/modules/ManifestProcessor.jsm');
} = SpecialPowers.Cu.import('resource://gre/modules/WebManifest.jsm');
const processor = new ManifestProcessor();
const manifestURL = new URL(document.location.origin + '/manifest.json');
const docURL = document.location;

View File

@ -5,15 +5,21 @@
* In particular, the tests check that default-src and manifest-src directives are
* are respected by the ManifestObtainer.
*/
/*globals SpecialPowers, requestLongerTimeout, ok, Cu, is, add_task, gBrowser, BrowserTestUtils, ManifestObtainer*/
/*globals Components*/
'use strict';
requestLongerTimeout(10); // e10s tests take time.
Cu.import('resource://gre/modules/ManifestObtainer.jsm', this); // jshint ignore:line
const {
ManifestObtainer
} = Components.utils.import('resource://gre/modules/WebManifest.jsm', {});
const path = '/tests/dom/security/test/csp/';
const testFile = `file=${path}file_web_manifest.html`;
const remoteFile = `file=${path}file_web_manifest_remote.html`;
const httpsManifest = `file=${path}file_web_manifest_https.html`;
const mixedContent = `file=${path}file_web_manifest_mixed_content.html`;
const server = 'file_testserver.sjs';
const defaultURL = `http://example.org${path}${server}`;
const remoteURL = `http://mochi.test:8888`;
const secureURL = `https://example.com${path}${server}`;
const tests = [
// CSP block everything, so trying to load a manifest
// will result in a policy violation.
@ -242,7 +248,7 @@ function NetworkObserver(test) {
let success = false;
this.finished = new Promise((resolver) => {
finishedTest = resolver;
});
})
this.observe = function observer(subject, topic) {
SpecialPowers.removeObserver(this, 'csp-on-violate-policy');
test.run(topic);

View File

@ -3,12 +3,10 @@
* Check that mixed content blocker works prevents fetches of
* mixed content manifests.
*/
/*globals Cu, add_task, ok, gBrowser, BrowserTestUtils, ManifestObtainer*/
'use strict';
const {
ManifestObtainer
} = Cu.import('resource://gre/modules/ManifestObtainer.jsm', this); // jshint ignore:line
const obtainer = new ManifestObtainer();
} = Components.utils.import('resource://gre/modules/WebManifest.jsm', {});
const path = '/tests/dom/security/test/csp/';
const mixedContent = `file=${path}file_web_manifest_mixed_content.html`;
const server = 'file_testserver.sjs';
@ -33,7 +31,7 @@ const tests = [
];
//jscs:disable
add_task(function* () {
add_task(function*() {
//jscs:enable
for (let test of tests) {
let tabOptions = {
@ -47,11 +45,11 @@ add_task(function* () {
}
function* testObtainingManifest(aBrowser, aTest) {
let manifest;
const obtainer = new ManifestObtainer();
try {
yield obtainer.obtainManifest(aBrowser);
} catch (e) {
return aTest.run(e);
aTest.run(e)
}
}
});

View File

@ -1,36 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
this.EXPORTED_SYMBOLS = ['PromiseMessage'];
let msgId = 0;
let PromiseMessage = {
send(messageManager, name, data = {}) {
let id = msgId++;
// Make a copy of data so that the caller doesn't see us setting 'id'.
let dataCopy = {};
for (let prop in data) {
dataCopy[prop] = data[prop];
}
dataCopy.id = id;
// Send the message.
messageManager.sendAsyncMessage(name, dataCopy);
// Return a promise that resolves when we get a reply (a message of the same name).
return new Promise(resolve => {
messageManager.addMessageListener(name, function listener(reply) {
if (reply.data.id !== id) {
return;
}
messageManager.removeMessageListener(name, listener);
resolve(reply);
});
});
}
};

View File

@ -48,7 +48,6 @@ EXTRA_JS_MODULES += [
'ProfileAge.jsm',
'Promise-backend.js',
'Promise.jsm',
'PromiseMessage.jsm',
'PromiseUtils.jsm',
'PropertyListUtils.jsm',
'RemoteController.jsm',