Merge m-c to b2ginbound, a=merge CLOSED TREE

This commit is contained in:
Wes Kocher 2015-09-23 13:25:06 -07:00
commit 268dd97805
351 changed files with 3017 additions and 1632 deletions

View File

@ -18,3 +18,6 @@ LOCAL_INCLUDES += [
]
FINAL_LIBRARY = 'xul'
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -275,7 +275,7 @@ var gTests = [
Services.obs.removeObserver(searchObserver, "browser-search-engine-modified");
});
Services.search.addEngine("http://test:80/browser/browser/base/content/test/general/POSTSearchEngine.xml",
Ci.nsISearchEngine.DATA_XML, null, false);
null, null, false);
return deferred.promise;
}
},
@ -659,7 +659,7 @@ function promiseNewEngine(basename) {
info("Waiting for engine to be added: " + basename);
let addDeferred = Promise.defer();
let url = getRootDirectory(gTestPath) + basename;
Services.search.addEngine(url, Ci.nsISearchEngine.TYPE_MOZSEARCH, "", false, {
Services.search.addEngine(url, null, "", false, {
onSuccess: function (engine) {
info("Search engine added: " + basename);
registerCleanupFunction(() => {

View File

@ -194,32 +194,32 @@ add_task(function* cycleSuggestions() {
shiftKey: true,
accelKey: true,
};
let state = yield msg("key", { key: "VK_DOWN", modifiers: modifiers });
checkState(state, "xfoo", ["xfoo", "xbar"], 0, aSelectedButtonIndex);
state = yield msg("key", { key: "VK_DOWN", modifiers: modifiers });
checkState(state, "xbar", ["xfoo", "xbar"], 1, aSelectedButtonIndex);
state = yield msg("key", { key: "VK_DOWN", modifiers: modifiers });
checkState(state, "x", ["xfoo", "xbar"], -1, aSelectedButtonIndex);
state = yield msg("key", { key: "VK_DOWN", modifiers: modifiers });
checkState(state, "xfoo", ["xfoo", "xbar"], 0, aSelectedButtonIndex);
state = yield msg("key", { key: "VK_UP", modifiers: modifiers });
checkState(state, "x", ["xfoo", "xbar"], -1, aSelectedButtonIndex);
state = yield msg("key", { key: "VK_UP", modifiers: modifiers });
checkState(state, "xbar", ["xfoo", "xbar"], 1, aSelectedButtonIndex);
state = yield msg("key", { key: "VK_UP", modifiers: modifiers });
checkState(state, "xfoo", ["xfoo", "xbar"], 0, aSelectedButtonIndex);
state = yield msg("key", { key: "VK_UP", modifiers: modifiers });
checkState(state, "x", ["xfoo", "xbar"], -1, aSelectedButtonIndex);
});
yield cycle();
// Repeat with a one-off selected.
@ -689,7 +689,7 @@ function checkState(actualState, expectedInputVal, expectedSuggestions,
if (expectedSelectedIdx == -1 && expectedSelectedButtonIdx != undefined) {
expectedSelectedIdx = expectedSuggestions.length + expectedSelectedButtonIdx;
}
let expectedState = {
selectedIndex: expectedSelectedIdx,
numSuggestions: expectedSuggestions.length,
@ -759,34 +759,15 @@ function setUpEngines() {
let currentEngineName = Services.search.currentEngine.name;
let currentEngines = Services.search.getVisibleEngines();
info("Adding test search engines");
let engine1 = yield promiseNewEngine(TEST_ENGINE_BASENAME);
let engine2 = yield promiseNewEngine(TEST_ENGINE_2_BASENAME);
let engine1 = yield promiseNewSearchEngine(TEST_ENGINE_BASENAME);
let engine2 = yield promiseNewSearchEngine(TEST_ENGINE_2_BASENAME);
Services.search.currentEngine = engine1;
for (let engine of currentEngines) {
Services.search.removeEngine(engine);
}
registerCleanupFunction(() => {
Services.search.restoreDefaultEngines();
Services.search.removeEngine(engine1);
Services.search.removeEngine(engine2);
Services.search.currentEngine = Services.search.getEngineByName(currentEngineName);
});
});
}
function promiseNewEngine(basename) {
info("Waiting for engine to be added: " + basename);
let addDeferred = Promise.defer();
let url = getRootDirectory(gTestPath) + basename;
Services.search.addEngine(url, Ci.nsISearchEngine.TYPE_MOZSEARCH, "", false, {
onSuccess: function (engine) {
info("Search engine added: " + basename);
addDeferred.resolve(engine);
},
onError: function (errCode) {
ok(false, "addEngine failed with error code " + errCode);
addDeferred.reject();
},
});
return addDeferred.promise;
}

View File

@ -50,7 +50,7 @@ function test() {
});
Services.search.addEngine("http://test:80/browser/browser/base/content/test/general/POSTSearchEngine.xml",
Ci.nsISearchEngine.DATA_XML, null, false);
null, null, false);
}
var gCurrTest;

View File

@ -65,6 +65,76 @@ function once(target, name) {
});
}
function fetchFile(uri) {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();
xhr.open("GET", uri, true);
xhr.onreadystatechange = function() {
if (this.readyState != this.DONE) {
return;
}
try {
resolve(this.responseText);
} catch (ex) {
ok(false, `Script error reading ${uri}: ${ex}`);
resolve("");
}
};
xhr.onerror = error => {
ok(false, `XHR error reading ${uri}: ${error}`);
resolve("");
};
xhr.send(null);
});
}
var gChromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"]
.getService(Ci.nsIChromeRegistry);
var gChromeMap = new Map();
function getBaseUriForChromeUri(chromeUri) {
let chromeFile = chromeUri + "gobbledygooknonexistentfile.reallynothere";
let uri = Services.io.newURI(chromeFile, null, null);
let fileUri = gChromeReg.convertChromeURL(uri);
return fileUri.resolve(".");
}
function parseManifest(manifestUri) {
return fetchFile(manifestUri.spec).then(data => {
for (let line of data.split('\n')) {
let [type, ...argv] = line.split(/\s+/);
let component;
if (type == "content" || type == "skin") {
[component] = argv;
} else {
// skip unrelated lines
continue;
}
let chromeUri = `chrome://${component}/${type}/`;
gChromeMap.set(getBaseUriForChromeUri(chromeUri), chromeUri);
}
});
}
function convertToChromeUri(fileUri) {
let baseUri = fileUri.spec;
let path = "";
while (true) {
let slashPos = baseUri.lastIndexOf("/", baseUri.length - 2);
if (slashPos < 0) {
info(`File not accessible from chrome protocol: ${fileUri.path}`);
return fileUri;
}
path = baseUri.slice(slashPos + 1) + path;
baseUri = baseUri.slice(0, slashPos + 1);
if (gChromeMap.has(baseUri)) {
let chromeBaseUri = gChromeMap.get(baseUri);
let chromeUri = `${chromeBaseUri}${path}`;
return Services.io.newURI(chromeUri, null, null);
}
}
}
function messageIsCSSError(msg, innerWindowID, outerWindowID) {
// Only care about CSS errors generated by our iframe:
if ((msg instanceof Ci.nsIScriptError) &&
@ -85,15 +155,11 @@ add_task(function checkAllTheCSS() {
// This asynchronously produces a list of URLs (sadly, mostly sync on our
// test infrastructure because it runs against jarfiles there, and
// our zipreader APIs are all sync)
let uris = yield generateURIsFromDirTree(appDir, ".css");
let uris = yield generateURIsFromDirTree(appDir, [".css", ".manifest"]);
// Create a clean iframe to load all the files into. This needs to live at a
// file or jar URI (depending on whether we're using a packaged build or not)
// so that it's allowed to load other same-scheme URIs (i.e. the browser css).
let resHandler = Services.io.getProtocolHandler("resource")
.QueryInterface(Ci.nsISubstitutingProtocolHandler);
let resURI = Services.io.newURI('resource://testing-common/resource_test_file.html', null, null);
let testFile = resHandler.resolveURI(resURI);
// chrome URI so that it's allowed to load and parse any styles.
let testFile = getRootDirectory(gTestPath) + "dummy_page.html";
let windowless = Services.appShell.createWindowlessBrowser();
let iframe = windowless.document.createElementNS("http://www.w3.org/1999/xhtml", "html:iframe");
windowless.document.documentElement.appendChild(iframe);
@ -106,6 +172,20 @@ add_task(function checkAllTheCSS() {
let innerWindowID = windowUtils.currentInnerWindowID;
let outerWindowID = windowUtils.outerWindowID;
// Parse and remove all manifests from the list.
// NOTE that this must be done before filtering out devtools paths
// so that all chrome paths can be recorded.
let manifestPromises = [];
uris = uris.filter(uri => {
if (uri.path.endsWith(".manifest")) {
manifestPromises.push(parseManifest(uri));
return false;
}
return true;
});
// Wait for all manifest to be parsed
yield Promise.all(manifestPromises);
// We build a list of promises that get resolved when their respective
// files have loaded and produced no errors.
let allPromises = [];
@ -133,7 +213,8 @@ add_task(function checkAllTheCSS() {
linkEl.addEventListener("load", onLoad);
linkEl.addEventListener("error", onError);
linkEl.setAttribute("type", "text/css");
linkEl.setAttribute("href", uri.spec);
let chromeUri = convertToChromeUri(uri);
linkEl.setAttribute("href", chromeUri.spec);
allPromises.push(promiseForThisSpec.promise);
doc.head.appendChild(linkEl);
}

View File

@ -1033,8 +1033,7 @@ function promiseNewSearchEngine(basename) {
return new Promise((resolve, reject) => {
info("Waiting for engine to be added: " + basename);
let url = getRootDirectory(gTestPath) + basename;
Services.search.addEngine(url, Ci.nsISearchEngine.TYPE_MOZSEARCH, "",
false, {
Services.search.addEngine(url, null, "", false, {
onSuccess: function (engine) {
info("Search engine added: " + basename);
registerCleanupFunction(() => Services.search.removeEngine(engine));

View File

@ -237,7 +237,7 @@ function promiseNewSearchEngine({name: basename, numLogos}) {
// Wait for addEngine().
let addDeferred = Promise.defer();
let url = getRootDirectory(gTestPath) + basename;
Services.search.addEngine(url, Ci.nsISearchEngine.TYPE_MOZSEARCH, "", false, {
Services.search.addEngine(url, null, "", false, {
onSuccess: function (engine) {
info("Search engine added: " + basename);
gNewEngines.push(engine);

View File

@ -17,3 +17,6 @@ FINAL_LIBRARY = 'browsercomps'
LOCAL_INCLUDES += [
'../build',
]
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -38,3 +38,6 @@ if CONFIG['OS_ARCH'] == 'WINNT':
# GTK2: Need to link with glib for GNOME shell service
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('cocoa', 'gtk2', 'gtk3'):
OS_LIBS += CONFIG['TK_LIBS']
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -21,3 +21,6 @@ FINAL_LIBRARY = 'browsercomps'
LOCAL_INCLUDES += [
'../build'
]
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -42,3 +42,6 @@ LOCAL_INCLUDES += [
with Files('**'):
BUG_COMPONENT = ('Firefox', 'RSS Discovery and Preview')
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -930,6 +930,10 @@ loop.OTSdkDriver = (function() {
this.dispatcher.dispatch(new sharedActions.ConnectionFailure({
reason: FAILURE_DETAILS.UNABLE_TO_PUBLISH_MEDIA
}));
} else if (event.code === OT.ExceptionCodes.UNABLE_TO_PUBLISH) {
// We need to log the message so that we can understand where the exception
// is coming from. Potentially a temporary addition.
this._notifyMetricsEvent("sdk.exception." + event.code + "." + event.message);
} else {
this._notifyMetricsEvent("sdk.exception." + event.code);
}

View File

@ -1537,6 +1537,26 @@ describe("loop.OTSdkDriver", function () {
}));
});
describe("Unable to publish (not GetUserMedia)", function() {
it("should notify metrics", function() {
sdk.trigger("exception", {
code: OT.ExceptionCodes.UNABLE_TO_PUBLISH,
message: "Fake",
title: "Connect Failed"
});
sinon.assert.calledOnce(dispatcher.dispatch);
sinon.assert.calledWithExactly(dispatcher.dispatch,
new sharedActions.ConnectionStatus({
event: "sdk.exception." + OT.ExceptionCodes.UNABLE_TO_PUBLISH + ".Fake",
state: "starting",
connections: 0,
sendStreams: 0,
recvStreams: 0
}));
});
});
describe("Unable to publish (GetUserMedia)", function() {
it("should destroy the publisher", function() {
sdk.trigger("exception", {

View File

@ -446,13 +446,11 @@
if (target.engine) {
this.currentEngine = target.engine;
} else if (target.classList.contains("addengine-item")) {
// We only detect OpenSearch files
var type = Ci.nsISearchEngine.DATA_XML;
// Select the installed engine if the installation succeeds
var installCallback = {
onSuccess: engine => this.currentEngine = engine
}
Services.search.addEngine(target.getAttribute("uri"), type,
Services.search.addEngine(target.getAttribute("uri"), null,
target.getAttribute("src"), false,
installCallback);
}
@ -1432,8 +1430,7 @@
Components.utils.reportError("Error adding search engine: " + errorCode);
}
}
Services.search.addEngine(target.getAttribute("uri"),
Ci.nsISearchEngine.DATA_XML,
Services.search.addEngine(target.getAttribute("uri"), null,
target.getAttribute("image"), false,
installCallback);
}

View File

@ -7,7 +7,6 @@ support-files =
head.js
opensearch.html
test.html
testEngine.src
testEngine.xml
testEngine_diacritics.xml
testEngine_dupe.xml

View File

@ -99,8 +99,7 @@ function* promiseSetEngine() {
Services.obs.addObserver(observer, "browser-search-engine-modified", false);
ss.addEngine("http://mochi.test:8888/browser/browser/components/search/test/426329.xml",
Ci.nsISearchEngine.DATA_XML, "data:image/x-icon,%00",
false);
null, "data:image/x-icon,%00", false);
return deferred.promise;
}

View File

@ -24,8 +24,7 @@ function test() {
Services.obs.addObserver(observer, "browser-search-engine-modified", false);
gSS.addEngine("http://mochi.test:8888/browser/browser/components/search/test/483086-1.xml",
Ci.nsISearchEngine.DATA_XML, "data:image/x-icon;%00",
false);
null, "data:image/x-icon;%00", false);
}
function test2() {
@ -37,7 +36,7 @@ function test2() {
is(engine.searchForm, "http://example.com", "SearchForm is correct");
gSS.removeEngine(engine);
break;
case "engine-removed":
case "engine-removed":
Services.obs.removeObserver(observer, "browser-search-engine-modified");
finish();
break;
@ -46,6 +45,5 @@ function test2() {
Services.obs.addObserver(observer, "browser-search-engine-modified", false);
gSS.addEngine("http://mochi.test:8888/browser/browser/components/search/test/483086-2.xml",
Ci.nsISearchEngine.DATA_XML, "data:image/x-icon;%00",
false);
null, "data:image/x-icon;%00", false);
}

View File

@ -44,12 +44,11 @@ var gTests = [
name: "Foo",
alias: null,
description: "Foo Search",
searchForm: "http://mochi.test:8888/browser/browser/components/search/test/",
type: Ci.nsISearchEngine.TYPE_OPENSEARCH
searchForm: "http://mochi.test:8888/browser/browser/components/search/test/"
},
run: function () {
gSS.addEngine("http://mochi.test:8888/browser/browser/components/search/test/testEngine.xml",
Ci.nsISearchEngine.DATA_XML, "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC",
null, "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC",
false);
},
added: function (engine) {
@ -77,37 +76,6 @@ var gTests = [
ok(currentEngine, "An engine is present.");
isnot(currentEngine.name, this.engine.name, "Current engine reset after removal");
nextTest();
}
},
{
name: "sherlock install",
engine: {
name: "Test Sherlock",
alias: null,
description: "Test Description",
searchForm: "http://example.com/searchform",
type: Ci.nsISearchEngine.TYPE_SHERLOCK
},
run: function () {
gSS.addEngine("http://mochi.test:8888/browser/browser/components/search/test/testEngine.src",
Ci.nsISearchEngine.DATA_TEXT, "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC",
false);
},
added: function (engine) {
ok(engine, "engine was added.");
checkEngine(this.engine, engine);
let engineFromSS = gSS.getEngineByName(this.engine.name);
is(engineFromSS, engine, "engine is obtainable via getEngineByName");
gSS.removeEngine(engine);
},
removed: function (engine) {
let currentEngine = gSS.currentEngine;
ok(currentEngine, "An engine is present.");
isnot(currentEngine.name, this.engine.name, "Current engine reset after removal");
nextTest();
}
}

View File

@ -30,7 +30,6 @@ function test() {
alias: null,
description: "Amazon.com Search",
searchForm: "https://www.amazon.com/exec/obidos/external-search/?field-keywords=&mode=blended&tag=mozilla-20&sourceid=Mozilla-search",
type: Ci.nsISearchEngine.TYPE_MOZSEARCH,
hidden: false,
wrappedJSObject: {
queryCharset: "UTF-8",

View File

@ -40,7 +40,6 @@ function test() {
alias: null,
description: "Bing. Search by Microsoft.",
searchForm: "https://www.bing.com/search?q=&pc=MOZI",
type: Ci.nsISearchEngine.TYPE_MOZSEARCH,
hidden: false,
wrappedJSObject: {
queryCharset: "UTF-8",

View File

@ -31,8 +31,7 @@ function test() {
Services.obs.addObserver(observer, "browser-search-engine-modified", false);
ss.addEngine("http://mochi.test:8888/browser/browser/components/search/test/testEngine_mozsearch.xml",
Ci.nsISearchEngine.DATA_XML, "data:image/x-icon,%00",
false);
null, "data:image/x-icon,%00", false);
function startTest() {
contextMenu = document.getElementById("contentAreaContextMenu");

View File

@ -30,7 +30,6 @@ function test() {
alias: null,
description: "eBay - Online auctions",
searchForm: "http://search.ebay.com/",
type: Ci.nsISearchEngine.TYPE_MOZSEARCH,
hidden: false,
wrappedJSObject: {
queryCharset: "ISO-8859-1",

View File

@ -46,7 +46,6 @@ function test() {
alias: null,
description: "Google Search",
searchForm: "https://www.google.com/search?q=&ie=utf-8&oe=utf-8",
type: Ci.nsISearchEngine.TYPE_MOZSEARCH,
hidden: false,
wrappedJSObject: {
queryCharset: "UTF-8",

View File

@ -96,9 +96,7 @@ function test() {
Services.obs.addObserver(observer, "browser-search-engine-modified", false);
Services.search.addEngine("http://mochi.test:8888/browser/browser/components/search/test/testEngine.xml",
Ci.nsISearchEngine.DATA_XML,
"data:image/x-icon,%00",
false);
null, "data:image/x-icon,%00", false);
}

View File

@ -9,7 +9,7 @@ function promiseNewEngine(basename) {
Services.search.init({
onInitComplete: function() {
let url = getRootDirectory(gTestPath) + basename;
Services.search.addEngine(url, Ci.nsISearchEngine.TYPE_MOZSEARCH, "", false, {
Services.search.addEngine(url, null, "", false, {
onSuccess: function (engine) {
info("Search engine added: " + basename);
resolve(engine);

View File

@ -51,8 +51,7 @@ function test() {
ok(false, "failed to install engine: " + errorCode);
}
};
Services.search.addEngine(engineURL + "426329.xml",
Ci.nsISearchEngine.DATA_XML,
Services.search.addEngine(engineURL + "426329.xml", null,
"data:image/x-icon,%00", false, installCallback);
}

View File

@ -8,11 +8,7 @@ function getString(key, ...params) {
}
function AddSearchProvider(...args) {
return gBrowser.addTab(ROOT + "webapi.html?AddSearchProvider:" + encodeURIComponent(JSON.stringify(args)));
}
function addSearchEngine(...args) {
return gBrowser.addTab(ROOT + "webapi.html?addSearchEngine:" + encodeURIComponent(JSON.stringify(args)));
return gBrowser.addTab(ROOT + "webapi.html?" + encodeURIComponent(JSON.stringify(args)));
}
function promiseDialogOpened() {
@ -34,7 +30,7 @@ function promiseDialogOpened() {
});
}
add_task(function* test_working_AddSearchProvider() {
add_task(function* test_working() {
gBrowser.selectedTab = AddSearchProvider(ROOT + "testEngine.xml");
let dialog = yield promiseDialogOpened();
@ -46,7 +42,7 @@ add_task(function* test_working_AddSearchProvider() {
gBrowser.removeCurrentTab();
});
add_task(function* test_HTTP_AddSearchProvider() {
add_task(function* test_HTTP() {
gBrowser.selectedTab = AddSearchProvider(ROOT.replace("http:", "HTTP:") + "testEngine.xml");
let dialog = yield promiseDialogOpened();
@ -58,7 +54,7 @@ add_task(function* test_HTTP_AddSearchProvider() {
gBrowser.removeCurrentTab();
});
add_task(function* test_relative_AddSearchProvider() {
add_task(function* test_relative() {
gBrowser.selectedTab = AddSearchProvider("testEngine.xml");
let dialog = yield promiseDialogOpened();
@ -70,7 +66,7 @@ add_task(function* test_relative_AddSearchProvider() {
gBrowser.removeCurrentTab();
});
add_task(function* test_invalid_AddSearchProvider() {
add_task(function* test_invalid() {
gBrowser.selectedTab = AddSearchProvider("z://foobar");
let dialog = yield promiseDialogOpened();
@ -82,7 +78,7 @@ add_task(function* test_invalid_AddSearchProvider() {
gBrowser.removeCurrentTab();
});
add_task(function* test_missing_AddSearchProvider() {
add_task(function* test_missing() {
let url = ROOT + "foobar.xml";
gBrowser.selectedTab = AddSearchProvider(url);
@ -94,88 +90,3 @@ add_task(function* test_missing_AddSearchProvider() {
gBrowser.removeCurrentTab();
});
add_task(function* test_working_addSearchEngine_xml() {
gBrowser.selectedTab = addSearchEngine(ROOT + "testEngine.xml", "", "", "");
let dialog = yield promiseDialogOpened();
is(dialog.args.promptType, "confirmEx", "Should see the confirmation dialog.");
is(dialog.args.text, getString("addEngineConfirmation", "Foo", "example.com"),
"Should have seen the right install message");
dialog.document.documentElement.cancelDialog();
gBrowser.removeCurrentTab();
});
add_task(function* test_working_addSearchEngine_src() {
gBrowser.selectedTab = addSearchEngine(ROOT + "testEngine.src", "", "", "");
let dialog = yield promiseDialogOpened();
is(dialog.args.promptType, "confirmEx", "Should see the confirmation dialog.");
is(dialog.args.text, getString("addEngineConfirmation", "Test Sherlock", "example.com"),
"Should have seen the right install message");
dialog.document.documentElement.cancelDialog();
gBrowser.removeCurrentTab();
});
add_task(function* test_relative_addSearchEngine_xml() {
gBrowser.selectedTab = addSearchEngine("testEngine.xml", "", "", "");
let dialog = yield promiseDialogOpened();
is(dialog.args.promptType, "confirmEx", "Should see the confirmation dialog.");
is(dialog.args.text, getString("addEngineConfirmation", "Foo", "example.com"),
"Should have seen the right install message");
dialog.document.documentElement.cancelDialog();
gBrowser.removeCurrentTab();
});
add_task(function* test_relative_addSearchEngine_src() {
gBrowser.selectedTab = addSearchEngine("testEngine.src", "", "", "");
let dialog = yield promiseDialogOpened();
is(dialog.args.promptType, "confirmEx", "Should see the confirmation dialog.");
is(dialog.args.text, getString("addEngineConfirmation", "Test Sherlock", "example.com"),
"Should have seen the right install message");
dialog.document.documentElement.cancelDialog();
gBrowser.removeCurrentTab();
});
add_task(function* test_invalid_addSearchEngine() {
gBrowser.selectedTab = addSearchEngine("z://foobar", "", "", "");
let dialog = yield promiseDialogOpened();
is(dialog.args.promptType, "alert", "Should see the alert dialog.");
is(dialog.args.text, getString("error_invalid_engine_msg", brandName),
"Should have seen the right error message")
dialog.document.documentElement.acceptDialog();
gBrowser.removeCurrentTab();
});
add_task(function* test_invalid_icon_addSearchEngine() {
gBrowser.selectedTab = addSearchEngine(ROOT + "testEngine.src", "z://foobar", "", "");
let dialog = yield promiseDialogOpened();
is(dialog.args.promptType, "alert", "Should see the alert dialog.");
is(dialog.args.text, getString("error_invalid_engine_msg", brandName),
"Should have seen the right error message")
dialog.document.documentElement.acceptDialog();
gBrowser.removeCurrentTab();
});
add_task(function* test_missing_addSearchEngine() {
let url = ROOT + "foobar.xml";
gBrowser.selectedTab = addSearchEngine(url, "", "", "");
let dialog = yield promiseDialogOpened();
is(dialog.args.promptType, "alert", "Should see the alert dialog.");
is(dialog.args.text, getString("error_loading_engine_msg2", brandName, url),
"Should have seen the right error message")
dialog.document.documentElement.acceptDialog();
gBrowser.removeCurrentTab();
});

View File

@ -30,7 +30,6 @@ function test() {
alias: null,
description: "Yahoo Search",
searchForm: "https://search.yahoo.com/yhs/search?p=&ei=UTF-8&hspart=mozilla",
type: Ci.nsISearchEngine.TYPE_MOZSEARCH,
hidden: false,
wrappedJSObject: {
queryCharset: "UTF-8",

View File

@ -146,7 +146,7 @@ function promiseNewEngine(basename, options = {}) {
onInitComplete: function() {
let url = getRootDirectory(gTestPath) + basename;
let current = Services.search.currentEngine;
Services.search.addEngine(url, Ci.nsISearchEngine.TYPE_MOZSEARCH, "", false, {
Services.search.addEngine(url, null, "", false, {
onSuccess: function (engine) {
info("Search engine added: " + basename);
if (setAsCurrent) {

View File

@ -1,11 +0,0 @@
<search
name="Test Sherlock"
description="Test Description"
method="GET"
searchform="http://example.com/searchform"
action="http://example.com/action"
queryCharset="UTF-8"
>
<input name="userParam" user>
<input name="param" value="value">
</search>

View File

@ -4,14 +4,10 @@
<head>
<script>
function installEngine() {
var query = window.location.search.substring(1).split(":");
var func = query[0];
var args = JSON.parse(decodeURIComponent(query[1]));
var query = window.location.search.substring(1);
var args = JSON.parse(decodeURIComponent(query));
if (func == "AddSearchProvider")
window.external.AddSearchProvider(...args);
else if (func == "addSearchEngine")
window.sidebar.addSearchEngine(...args);
window.external.AddSearchProvider(...args);
}
</script>
</head>

View File

@ -52,3 +52,6 @@ CXXFLAGS += CONFIG['TK_CFLAGS']
with Files('**'):
BUG_COMPONENT = ('Firefox', 'Shell Integration')
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -317,7 +317,7 @@ function waitForNewEngine(basename, numImages) {
// Wait for addEngine().
let addDeferred = Promise.defer();
let url = getRootDirectory(gTestPath) + basename;
Services.search.addEngine(url, Ci.nsISearchEngine.TYPE_MOZSEARCH, "", false, {
Services.search.addEngine(url, null, "", false, {
onSuccess: function (engine) {
info("Search engine added: " + basename);
addDeferred.resolve(engine);

View File

@ -3,7 +3,7 @@
* 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/. */
@import url("chrome://devtools/skin/themes/floating-scrollbars.css");
@import url("floating-scrollbars.css");
scrollbar thumb {
background-color: rgba(170,170,170,0.2) !important;

View File

@ -35,3 +35,6 @@ DevToolsModules(
'protocol.js',
'worker.js'
)
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -35,3 +35,6 @@ FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [
'/docshell/base'
]
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -32,3 +32,6 @@ LOCAL_INCLUDES += [
]
FINAL_LIBRARY = 'xul'
if CONFIG['CLANG_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -38,3 +38,6 @@ LOCAL_INCLUDES += [
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -498,6 +498,11 @@ this.PermissionsTable = { geolocation: {
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"system-app-only-audio-channels-in-app": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"killswitch": {
app: DENY_ACTION,
trusted: DENY_ACTION,

View File

@ -46,3 +46,7 @@ property FillOpacity
// Push API
method PushManager.subscribe
method PushSubscription.unsubscribe
// window.sidebar.addSearchEngine
attribute Window.sidebar
method External.addSearchEngine

View File

@ -15,3 +15,6 @@ LOCAL_INCLUDES += [
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul-gtest'
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -18,3 +18,6 @@ include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
MOCHITEST_MANIFESTS += ['test/mochitest.ini']
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -29,3 +29,6 @@ MOCHITEST_CHROME_MANIFESTS += ['tests/chrome.ini']
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -45,6 +45,24 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(BrowserElementAudioChannel,
mTabParent,
mBrowserElementAPI)
/* static */ already_AddRefed<BrowserElementAudioChannel>
BrowserElementAudioChannel::Create(nsPIDOMWindow* aWindow,
nsIFrameLoader* aFrameLoader,
nsIBrowserElementAPI* aAPI,
AudioChannel aAudioChannel,
ErrorResult& aRv)
{
nsRefPtr<BrowserElementAudioChannel> ac =
new BrowserElementAudioChannel(aWindow, aFrameLoader, aAPI, aAudioChannel);
aRv = ac->Initialize();
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
return ac.forget();
}
BrowserElementAudioChannel::BrowserElementAudioChannel(
nsPIDOMWindow* aWindow,
nsIFrameLoader* aFrameLoader,
@ -58,7 +76,6 @@ BrowserElementAudioChannel::BrowserElementAudioChannel(
{
MOZ_ASSERT(NS_IsMainThread());
AssertIsInMainProcess();
MOZ_ASSERT(mFrameLoader);
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
@ -94,6 +111,20 @@ BrowserElementAudioChannel::~BrowserElementAudioChannel()
nsresult
BrowserElementAudioChannel::Initialize()
{
if (!mFrameLoader) {
nsCOMPtr<nsPIDOMWindow> window = GetOwner();
if (!window) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDOMWindow> topWindow;
window->GetScriptableTop(getter_AddRefs(topWindow));
mFrameWindow = do_QueryInterface(topWindow);
mFrameWindow = mFrameWindow->GetOuterWindow();
return NS_OK;
}
nsCOMPtr<nsIDocShell> docShell;
nsresult rv = mFrameLoader->GetDocShell(getter_AddRefs(docShell));
if (NS_WARN_IF(NS_FAILED(rv))) {

View File

@ -35,12 +35,12 @@ public:
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BrowserElementAudioChannel,
DOMEventTargetHelper)
BrowserElementAudioChannel(nsPIDOMWindow* aWindow,
nsIFrameLoader* aFrameLoader,
nsIBrowserElementAPI* aAPI,
AudioChannel aAudioChannel);
nsresult Initialize();
static already_AddRefed<BrowserElementAudioChannel>
Create(nsPIDOMWindow* aWindow,
nsIFrameLoader* aFrameLoader,
nsIBrowserElementAPI* aAPI,
AudioChannel aAudioChannel,
ErrorResult& aRv);
// WebIDL methods
@ -60,8 +60,15 @@ public:
IMPL_EVENT_HANDLER(activestatechanged);
private:
BrowserElementAudioChannel(nsPIDOMWindow* aWindow,
nsIFrameLoader* aFrameLoader,
nsIBrowserElementAPI* aAPI,
AudioChannel aAudioChannel);
~BrowserElementAudioChannel();
nsresult Initialize();
void ProcessStateChanged(const char16_t* aData);
nsCOMPtr<nsIFrameLoader> mFrameLoader;

View File

@ -12,6 +12,8 @@ var { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/BrowserElementPromptService.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/Microformats.js");
XPCOMUtils.defineLazyServiceGetter(this, "acs",
"@mozilla.org/audiochannel/service;1",
@ -251,7 +253,8 @@ BrowserElementChild.prototype = {
"set-audio-channel-volume": this._recvSetAudioChannelVolume,
"get-audio-channel-muted": this._recvGetAudioChannelMuted,
"set-audio-channel-muted": this._recvSetAudioChannelMuted,
"get-is-audio-channel-active": this._recvIsAudioChannelActive
"get-is-audio-channel-active": this._recvIsAudioChannelActive,
"get-structured-data": this._recvGetStructuredData
}
addMessageListener("browser-element-api:call", function(aMessage) {
@ -1558,6 +1561,300 @@ BrowserElementChild.prototype = {
sendAsyncMsg('got-set-input-method-active', msgData);
},
_processMicroformatValue(field, value) {
if (['node', 'resolvedNode', 'semanticType'].includes(field)) {
return null;
} else if (Array.isArray(value)) {
var result = value.map(i => this._processMicroformatValue(field, i))
.filter(i => i !== null);
return result.length ? result : null;
} else if (typeof value == 'string') {
return value;
} else if (typeof value == 'object' && value !== null) {
return this._processMicroformatItem(value);
}
return null;
},
// This function takes legacy Microformat data (hCard and hCalendar)
// and produces the same result that the equivalent Microdata data
// would produce.
_processMicroformatItem(microformatData) {
var result = {};
if (microformatData.semanticType == 'geo') {
return microformatData.latitude + ';' + microformatData.longitude;
}
if (microformatData.semanticType == 'hCard') {
result.type = ["http://microformats.org/profile/hcard"];
} else if (microformatData.semanticType == 'hCalendar') {
result.type = ["http://microformats.org/profile/hcalendar#vevent"];
}
for (let field of Object.getOwnPropertyNames(microformatData)) {
var processed = this._processMicroformatValue(field, microformatData[field]);
if (processed === null) {
continue;
}
if (!result.properties) {
result.properties = {};
}
if (Array.isArray(processed)) {
result.properties[field] = processed;
} else {
result.properties[field] = [processed];
}
}
return result;
},
_findItemProperties: function(node, properties, alreadyProcessed) {
if (node.itemProp) {
var value;
if (node.itemScope) {
value = this._processItem(node, alreadyProcessed);
} else {
value = node.itemValue;
}
for (let i = 0; i < node.itemProp.length; ++i) {
var property = node.itemProp[i];
if (!properties[property]) {
properties[property] = [];
}
properties[property].push(value);
}
}
if (!node.itemScope) {
var childNodes = node.childNodes;
for (var childNode of childNodes) {
this._findItemProperties(childNode, properties, alreadyProcessed);
}
}
},
_processItem: function(node, alreadyProcessed = []) {
if (alreadyProcessed.includes(node)) {
return "ERROR";
}
alreadyProcessed.push(node);
var result = {};
if (node.itemId) {
result.id = node.itemId;
}
if (node.itemType) {
result.type = [];
for (let i = 0; i < node.itemType.length; ++i) {
result.type.push(node.itemType[i]);
}
}
var properties = {};
var childNodes = node.childNodes;
for (var childNode of childNodes) {
this._findItemProperties(childNode, properties, alreadyProcessed);
}
if (node.itemRef) {
for (let i = 0; i < node.itemRef.length; ++i) {
var refNode = content.document.getElementById(node.itemRef[i]);
this._findItemProperties(refNode, properties, alreadyProcessed);
}
}
result.properties = properties;
return result;
},
_recvGetStructuredData: function(data) {
var result = {
items: []
};
var microdataItems = content.document.getItems();
for (let microdataItem of microdataItems) {
result.items.push(this._processItem(microdataItem));
}
var hCardItems = Microformats.get("hCard", content.document);
for (let hCardItem of hCardItems) {
if (!hCardItem.node.itemScope) { // If it's also marked with Microdata, ignore the Microformat
result.items.push(this._processMicroformatItem(hCardItem));
}
}
var hCalendarItems = Microformats.get("hCalendar", content.document);
for (let hCalendarItem of hCalendarItems) {
if (!hCalendarItem.node.itemScope) { // If it's also marked with Microdata, ignore the Microformat
result.items.push(this._processMicroformatItem(hCalendarItem));
}
}
var resultString = JSON.stringify(result);
sendAsyncMsg('got-structured-data', {
id: data.json.id,
successRv: resultString
});
},
_processMicroformatValue(field, value) {
if (['node', 'resolvedNode', 'semanticType'].includes(field)) {
return null;
} else if (Array.isArray(value)) {
var result = value.map(i => this._processMicroformatValue(field, i))
.filter(i => i !== null);
return result.length ? result : null;
} else if (typeof value == 'string') {
return value;
} else if (typeof value == 'object' && value !== null) {
return this._processMicroformatItem(value);
}
return null;
},
// This function takes legacy Microformat data (hCard and hCalendar)
// and produces the same result that the equivalent Microdata data
// would produce.
_processMicroformatItem(microformatData) {
var result = {};
if (microformatData.semanticType == 'geo') {
return microformatData.latitude + ';' + microformatData.longitude;
}
if (microformatData.semanticType == 'hCard') {
result.type = ["http://microformats.org/profile/hcard"];
} else if (microformatData.semanticType == 'hCalendar') {
result.type = ["http://microformats.org/profile/hcalendar#vevent"];
}
for (let field of Object.getOwnPropertyNames(microformatData)) {
var processed = this._processMicroformatValue(field, microformatData[field]);
if (processed === null) {
continue;
}
if (!result.properties) {
result.properties = {};
}
if (Array.isArray(processed)) {
result.properties[field] = processed;
} else {
result.properties[field] = [processed];
}
}
return result;
},
_findItemProperties: function(node, properties, alreadyProcessed) {
if (node.itemProp) {
var value;
if (node.itemScope) {
value = this._processItem(node, alreadyProcessed);
} else {
value = node.itemValue;
}
for (let i = 0; i < node.itemProp.length; ++i) {
var property = node.itemProp[i];
if (!properties[property]) {
properties[property] = [];
}
properties[property].push(value);
}
}
if (!node.itemScope) {
var childNodes = node.childNodes;
for (var childNode of childNodes) {
this._findItemProperties(childNode, properties, alreadyProcessed);
}
}
},
_processItem: function(node, alreadyProcessed = []) {
if (alreadyProcessed.includes(node)) {
return "ERROR";
}
alreadyProcessed.push(node);
var result = {};
if (node.itemId) {
result.id = node.itemId;
}
if (node.itemType) {
result.type = [];
for (let i = 0; i < node.itemType.length; ++i) {
result.type.push(node.itemType[i]);
}
}
var properties = {};
var childNodes = node.childNodes;
for (var childNode of childNodes) {
this._findItemProperties(childNode, properties, alreadyProcessed);
}
if (node.itemRef) {
for (let i = 0; i < node.itemRef.length; ++i) {
var refNode = content.document.getElementById(node.itemRef[i]);
this._findItemProperties(refNode, properties, alreadyProcessed);
}
}
result.properties = properties;
return result;
},
_recvGetStructuredData: function(data) {
var result = {
items: []
};
var microdataItems = content.document.getItems();
for (let microdataItem of microdataItems) {
result.items.push(this._processItem(microdataItem));
}
var hCardItems = Microformats.get("hCard", content.document);
for (let hCardItem of hCardItems) {
if (!hCardItem.node.itemScope) { // If it's also marked with Microdata, ignore the Microformat
result.items.push(this._processMicroformatItem(hCardItem));
}
}
var hCalendarItems = Microformats.get("hCalendar", content.document);
for (let hCalendarItem of hCalendarItems) {
if (!hCalendarItem.node.itemScope) { // If it's also marked with Microdata, ignore the Microformat
result.items.push(this._processMicroformatItem(hCalendarItem));
}
}
var resultString = JSON.stringify(result);
sendAsyncMsg('got-structured-data', {
id: data.json.id,
successRv: resultString
});
},
// The docShell keeps a weak reference to the progress listener, so we need
// to keep a strong ref to it ourselves.
_progressListener: {

View File

@ -208,7 +208,8 @@ BrowserElementParent.prototype = {
"got-set-audio-channel-volume": this._gotDOMRequestResult,
"got-audio-channel-muted": this._gotDOMRequestResult,
"got-set-audio-channel-muted": this._gotDOMRequestResult,
"got-is-audio-channel-active": this._gotDOMRequestResult
"got-is-audio-channel-active": this._gotDOMRequestResult,
"got-structured-data": this._gotDOMRequestResult
};
let mmSecuritySensitiveCalls = {
@ -1033,6 +1034,8 @@ BrowserElementParent.prototype = {
{audioChannel: aAudioChannel});
},
getStructuredData: defineDOMRequestMethod('get-structured-data'),
/**
* Called when the visibility of the window which owns this iframe changes.
*/

View File

@ -0,0 +1,78 @@
/* 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/. */
/*
* This is an approximate implementation of ES7's async-await pattern.
* see: https://github.com/tc39/ecmascript-asyncawait
*
* It allows for simple creation of async function and "tasks".
*
* For example:
*
* var myThinger = {
* doAsynThing: async(function*(url){
* var result = yield fetch(url);
* return process(result);
* });
* }
*
* And Task-like things can be created as follows:
*
* var myTask = async(function*{
* var result = yield fetch(url);
* return result;
* });
* //returns a promise
*
* myTask().then(doSomethingElse);
*
*/
(function(exports) {
"use strict";
function async(func, self) {
return function asyncFunction() {
const functionArgs = Array.from(arguments);
return new Promise(function(resolve, reject) {
var gen;
if (typeof func !== "function") {
reject(new TypeError("Expected a Function."));
}
//not a generator, wrap it.
if (func.constructor.name !== "GeneratorFunction") {
gen = (function*() {
return func.apply(self, functionArgs);
}());
} else {
gen = func.apply(self, functionArgs);
}
try {
step(gen.next(undefined));
} catch (err) {
reject(err);
}
function step({value, done}) {
if (done) {
return resolve(value);
}
if (value instanceof Promise) {
return value.then(
result => step(gen.next(result)),
error => {
try {
step(gen.throw(error));
} catch (err) {
throw err;
}
}
).catch(err => reject(err));
}
step(gen.next(value));
}
});
};
}
exports.async = async;
}(this || self));

View File

@ -0,0 +1,111 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/*globals async, is, SimpleTest, browserElementTestHelpers*/
// Bug 119580 - getStructuredData tests
'use strict';
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
const EMPTY_URL = 'file_empty.html';
const MICRODATA_URL = 'file_microdata.html';
const MICRODATA_ITEMREF_URL = 'file_microdata_itemref.html';
const MICRODATA_BAD_ITEMREF_URL = 'file_microdata_bad_itemref.html';
const MICROFORMATS_URL = 'file_microformats.html';
var test1 = async(function* () {
var structuredData = yield requestStructuredData(EMPTY_URL);
is(structuredData.items && structuredData.items.length, 0,
'There should be 0 items.');
});
var test2 = async(function* () {
var structuredData = yield requestStructuredData(MICRODATA_URL);
is(structuredData.items && structuredData.items.length, 2,
'There should be two items.');
is(structuredData.items[0].type[0], 'http://schema.org/Recipe',
'Can get item type.');
is(structuredData.items[0].properties['datePublished'][0], '2009-05-08',
'Can get item property.');
is(structuredData.items[1]
.properties["aggregateRating"][0]
.properties["ratingValue"][0],
'4', 'Can get nested item property.');
});
var test3 = async(function* () {
var structuredData = yield requestStructuredData(MICROFORMATS_URL);
is(structuredData.items && structuredData.items.length, 2,
'There should be two items.');
is(structuredData.items[0].type[0], 'http://microformats.org/profile/hcard',
'Got hCard object.');
is(structuredData.items[0]
.properties["adr"][0]
.properties["country-name"][0],
'France', 'Can read hCard properties.');
is(structuredData.items[0]
.properties["adr"][0]
.properties["type"]
.includes('home') &&
structuredData.items[0]
.properties["adr"][0]
.properties["type"]
.includes('postal'),
true, 'Property can contain multiple values.');
is(structuredData.items[0]
.properties["geo"][0],
'48.816667;2.366667', 'Geo value is formatted as per WHATWG spec.');
is(structuredData.items[1].type[0],
'http://microformats.org/profile/hcalendar#vevent',
'Got hCalendar object.');
is(structuredData.items[1]
.properties["dtstart"][0],
'2005-10-05', 'Can read hCalendar properties');
});
var test4 = async(function* () {
var structuredData = yield requestStructuredData(MICRODATA_ITEMREF_URL);
is(structuredData.items[0].properties["license"][0],
'http://www.opensource.org/licenses/mit-license.php', 'itemref works.');
is(structuredData.items[1].properties["license"][0],
'http://www.opensource.org/licenses/mit-license.php',
'Two items can successfully share an itemref.');
});
var test5 = async(function* () {
var structuredData = yield requestStructuredData(MICRODATA_BAD_ITEMREF_URL);
is(structuredData.items[0]
.properties["band"][0]
.properties["cycle"][0]
.properties["band"][0],
'ERROR', 'Cyclic reference should be detected as an error.');
});
Promise
.all([test1(), test2(), test3(), test4(), test5()])
.then(SimpleTest.finish);
function requestStructuredData(url) {
var iframe = document.createElement('iframe');
iframe.setAttribute('mozbrowser', 'true');
iframe.src = url;
document.body.appendChild(iframe);
return new Promise((resolve, reject) => {
iframe.addEventListener('mozbrowserloadend', function loadend() {
iframe.removeEventListener('mozbrowserloadend', loadend);
SimpleTest.executeSoon(() => {
var req = iframe.getStructuredData();
req.onsuccess = (ev) => {
document.body.removeChild(iframe);
resolve(JSON.parse(req.result));
};
req.onerror = (ev) => {
document.body.removeChild(iframe);
reject(new Error(req.error));
};
});
});
});
}

View File

@ -0,0 +1,70 @@
<html>
<head>
</head>
<body>
<h1>This example is taken from <a href="https://schema.org/Recipe">https://schema.org/Recipe</a></h1>
<div itemscope itemtype="http://schema.org/Recipe">
<span itemprop="name">Mom's World Famous Banana Bread</span> By <span itemprop="author">John Smith</span>,
<meta itemprop="datePublished" content="2009-05-08">May 8, 2009
<img itemprop="image" src="bananabread.jpg" alt="Banana bread on a plate" />
<span itemprop="description">This classic banana bread recipe comes
from my mom -- the walnuts add a nice texture and flavor to the banana
bread.</span> Prep Time:
<meta itemprop="prepTime" content="PT15M">15 minutes Cook time:
<meta itemprop="cookTime" content="PT1H">1 hour Yield: <span itemprop="recipeYield">1 loaf</span>
<div itemprop="nutrition" itemscope itemtype="http://schema.org/NutritionInformation">
Nutrition facts:
<span itemprop="calories">240 calories</span>,
<span itemprop="fatContent">9 grams fat</span>
</div>
Ingredients: - <span itemprop="recipeIngredient">3 or 4 ripe bananas, smashed</span> - <span itemprop="recipeIngredient">1 egg</span> - <span itemprop="recipeIngredient">3/4 cup of sugar</span> ... Instructions:
<span itemprop="recipeInstructions">
Preheat the oven to 350 degrees. Mix in the ingredients in a bowl. Add
the flour last. Pour the mixture into a loaf pan and bake for one hour.
</span> 140 comments:
<div itemprop="interactionStatistic" itemscope itemtype="http://schema.org/InteractionCounter">
<meta itemprop="interactionType" content="http://schema.org/CommentAction" />
<meta itemprop="userInteractionCount" content="140" />
</div>
From Janel, May 5 -- thank you, great recipe! ...
</div>
<h1>This example is taken from <a href="https://schema.org/Book">https://schema.org/Book</a></h1>
<div itemscope itemtype="http://schema.org/Book">
<img itemprop="image" src="catcher-in-the-rye-book-cover.jpg" alt="cover art: red horse, city in background" />
<span itemprop="name">The Catcher in the Rye</span> -
<link itemprop="bookFormat" href="http://schema.org/Paperback">Mass Market Paperback by <a itemprop="author" href="/author/jd_salinger.html">J.D. Salinger</a>
<div itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">
<span itemprop="ratingValue">4</span> stars -
<span itemprop="reviewCount">3077</span> reviews
</div>
<div itemprop="offers" itemscope itemtype="http://schema.org/Offer">
Price: <span itemprop="price" content="6.99">$6.99</span>
<meta itemprop="priceCurrency" content="USD" />
<link itemprop="availability" href="http://schema.org/InStock">In Stock
</div>
Product details
<span itemprop="numberOfPages">224</span> pages Publisher: <span itemprop="publisher">Little, Brown, and Company</span> -
<meta itemprop="datePublished" content="1991-05-01">May 1, 1991 Language: <span itemprop="inLanguage">English</span> ISBN-10:
<span itemprop="isbn">0316769487</span> Reviews:
<div itemprop="review" itemscope itemtype="http://schema.org/Review">
<span itemprop="reviewRating">5</span> stars -
<b>"<span itemprop="name">A masterpiece of literature</span>"</b> by
<span itemprop="author">John Doe</span>, Written on
<meta itemprop="datePublished" content="2006-05-04">May 4, 2006
<span itemprop="reviewBody">I really enjoyed this book. It captures the essential
challenge people face as they try make sense of their lives and grow to adulthood.</span>
</div>
<div itemprop="review" itemscope itemtype="http://schema.org/Review">
<span itemprop="reviewRating">4</span> stars -
<b>"<span itemprop="name">A good read.</span>" </b> by <span itemprop="author">Bob Smith</span>, Written on
<meta itemprop="datePublished" content="2006-06-15">June 15, 2006
<span itemprop="reviewBody">Catcher in the Rye is a fun book. It's a good book to read.</span>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,18 @@
<html>
<head>
</head>
<body>
<h1>This example is taken from <a href="https://html.spec.whatwg.org/multipage/microdata.html">https://html.spec.whatwg.org/multipage/microdata.html</a>, and modified.</h1>
<div itemscope id="amanda" itemref="a b"></div>
<p id="a">Name: <span itemprop="name">Amanda</span></p>
<div id="b" itemprop="band" itemscope itemref="c"></div>
<div id="c">
<p>Band: <span itemprop="name">Jazz Band</span></p>
<p>Size: <span itemprop="size">12</span> players</p>
<span itemprop="cycle" itemscope itemref="b">This is an error.</span>
</div>
</body>
</html>

View File

@ -0,0 +1,23 @@
<html>
<head>
</head>
<body>
<h1>This example is taken from <a href="https://html.spec.whatwg.org/multipage/microdata.html">https://html.spec.whatwg.org/multipage/microdata.html</a></h1>
<figure itemscope itemtype="http://n.whatwg.org/work" itemref="licenses">
<img itemprop="work" src="images/house.jpeg" alt="A white house, boarded up, sits in a forest.">
<figcaption itemprop="title">The house I found.</figcaption>
</figure>
<figure itemscope itemtype="http://n.whatwg.org/work" itemref="licenses">
<img itemprop="work" src="images/mailbox.jpeg" alt="Outside the house is a mailbox. It has a leaflet inside.">
<figcaption itemprop="title">The mailbox.</figcaption>
</figure>
<footer>
<p id="licenses">All images licensed under the <a itemprop="license"
href="http://www.opensource.org/licenses/mit-license.php">MIT
license</a>.</p>
</footer>
</body>
</html>

View File

@ -0,0 +1,50 @@
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<h1>This example is taken from <a href="http://microformats.org/wiki/hcard-examples">http://microformats.org/wiki/hcard-examples</a></h1>
<div class="vcard">
<span class="fn n">
<a class="url" href="http://t37.net">
<span class="given-name">Fréderic</span>
<span class="family-name">de Villamil</span>
</a>
</span>
<span class="nickname">neuro</span>
<a class="email" href="mailto:neuroNOSPAM@t37.net">
<span class="type">pref</span><span>erred email</span>
</a>
<span class="org">Omatis</span>
<span class="adr">
<abbr class="type" title="dom">France</abbr>
<span class="type">home</span> address
<abbr class="type" title="postal">mail</abbr> and
<abbr class="type" title="parcel">shipments</abbr>:
<span class="street-address">12 rue Danton</span>
<span class="locality">Le Kremlin-Bicetre</span>
<span class="postal-code">94270</span>
<span class="country-name">France</span>
</span>
<span class="geo">
<abbr class="latitude" title="48.816667">N 48° 81.6667</abbr>
<abbr class="longitude" title="2.366667">E 2° 36.6667</abbr>
</span>
</div>
<h1>This example is taken from <a href="http://microformats.org/wiki/hCalendar">http://microformats.org/wiki/hCalendar</a></h1>
<div class="vevent">
<a class="url" href="http://conferences.oreillynet.com/pub/w/40/program.html">
http://conferences.oreillynet.com/pub/w/40/program.html
</a>
<span class="summary">Web 2.0 Conference</span>:
<abbr class="dtstart" title="2005-10-05">October 5</abbr>-
<abbr class="dtend" title="2005-10-07">7</abbr>,
at the <span class="location">Argent Hotel, San Francisco, CA</span>
</div>
</body>
</html>

View File

@ -12,6 +12,7 @@ support-files =
browserElement_Find.js
browserElement_OpenTab.js
[test_browserElement_oop_getStructuredData.html]
[test_browserElement_oop_Viewmode.html]
[test_browserElement_oop_ThemeColor.html]
[test_browserElement_inproc_ErrorSecurity.html]

View File

@ -3,6 +3,7 @@ skip-if = buildapp == 'mulet' || (buildapp == 'b2g' && (toolkit != 'gonk' || deb
support-files =
../../../browser/base/content/test/general/audio.ogg
../../../dom/media/test/short-video.ogv
async.js
browserElementTestHelpers.js
browserElement_Alert.js
browserElement_AlertInFrame.js
@ -37,6 +38,7 @@ support-files =
browserElement_FrameWrongURI.js
browserElement_GetScreenshot.js
browserElement_GetScreenshotDppx.js
browserElement_getStructuredData.js
browserElement_Iconchange.js
browserElement_LoadEvents.js
browserElement_Manifestchange.js
@ -124,6 +126,11 @@ support-files =
file_http_401_response.sjs
file_http_407_response.sjs
file_inputmethod.html
file_microdata.html
file_microdata_bad_itemref.html
file_microdata_itemref.html
file_microformats.html
file_inputmethod.html
file_post_request.html
file_wyciwyg.html
file_audio.html
@ -232,3 +239,4 @@ disabled = bug 774100
[test_browserElement_inproc_GetContentDimensions.html]
[test_browserElement_inproc_AudioChannel.html]
[test_browserElement_inproc_SetNFCFocus.html]
[test_browserElement_inproc_getStructuredData.html]

View File

@ -0,0 +1,14 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for Bug 1195801</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript;version=1.8" src="async.js"></script>
<script type="application/javascript;version=1.8" src="browserElement_getStructuredData.js"></script>
</script>
</body>
</html>

View File

@ -0,0 +1,14 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for Bug 1195801</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript;version=1.8" src="async.js"></script>
<script type="application/javascript;version=1.8" src="browserElement_getStructuredData.js"></script>
</script>
</body>
</html>

View File

@ -52,3 +52,6 @@ MOCHITEST_MANIFESTS += [
'mochitest/mochitest.ini',
'mochitest/priority/mochitest.ini',
]
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -26,7 +26,7 @@ interface nsIBrowserElementNextPaintListener : nsISupports
* Interface to the BrowserElementParent implementation. All methods
* but setFrameLoader throw when the remote process is dead.
*/
[scriptable, uuid(56bd3e12-4a8b-422a-89fc-6dc25aa30aa2)]
[scriptable, uuid(9946695c-1ed3-4abb-bc60-6f8947fd5641)]
interface nsIBrowserElementAPI : nsISupports
{
const long FIND_CASE_SENSITIVE = 0;
@ -100,4 +100,16 @@ interface nsIBrowserElementAPI : nsISupports
void setNFCFocus(in boolean isFocus);
nsIDOMDOMRequest executeScript(in DOMString script, in jsval options);
/**
* Returns a JSON string representing Microdata objects on the page.
* Format is described at:
* https://html.spec.whatwg.org/multipage/microdata.html#json
*
* Also contains hCard and hCalendar objects after converting them
* to equivalent Microdata objects described at:
* https://html.spec.whatwg.org/multipage/microdata.html#vcard
* https://html.spec.whatwg.org/multipage/microdata.html#vevent
*/
nsIDOMDOMRequest getStructuredData();
};

View File

@ -36,3 +36,6 @@ IPDL_SOURCES += [
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -45,3 +45,6 @@ MOCHITEST_MANIFESTS += [
'test/mochitest.ini',
]
MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -45,3 +45,6 @@ MOCHITEST_MANIFESTS += [
]
MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -430,6 +430,13 @@ const kEventConstructors = {
return e;
},
},
ServiceWorkerMessageEvent: { create: function (aName, aProps) {
var e = new ServiceWorkerMessageEvent("serviceworkermessageevent", { bubbles: aProps.bubbles,
cancelable: aProps.cancelable, data: aProps.data, origin: aProps.origin,
lastEventId: aProps.lastEventId, source: aProps.source });
return e;
},
},
SimpleGestureEvent: { create: function (aName, aProps) {
var e = document.createEvent("simplegestureevent");
e.initSimpleGestureEvent(aName, aProps.bubbles, aProps.cancelable,

View File

@ -41,3 +41,6 @@ include('/ipc/chromium/chromium-config.mozbuild')
LOCAL_INCLUDES += [
'/dom/base',
]
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -30,3 +30,5 @@ LOCAL_INCLUDES += [
'/dom/fmradio',
]
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -32,3 +32,6 @@ LOCAL_INCLUDES += [
'../system/gonk',
]
include('/ipc/chromium/chromium-config.mozbuild')
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -54,3 +54,6 @@ CFLAGS += CONFIG['GLIB_CFLAGS']
CFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS']
CXXFLAGS += CONFIG['GLIB_CFLAGS']
CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS']
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -51,3 +51,6 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
LOCAL_INCLUDES += [
'/dom/system/windows',
]
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -2527,6 +2527,9 @@ HTMLInputElement::UpdateFileList()
}
}
// Make sure we (lazily) create a new Promise for GetFilesAndDirectories:
mFilesAndDirectoriesPromise = nullptr;
return NS_OK;
}
@ -4884,6 +4887,15 @@ MakeOrReuseFileSystem(const nsAString& aNewLocalRootPath,
already_AddRefed<Promise>
HTMLInputElement::GetFilesAndDirectories(ErrorResult& aRv)
{
if (mType != NS_FORM_INPUT_FILE) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
if (mFilesAndDirectoriesPromise) {
return nsRefPtr<Promise>(mFilesAndDirectoriesPromise).forget();
}
nsCOMPtr<nsIGlobalObject> global = OwnerDoc()->GetScopeObject();
MOZ_ASSERT(global);
if (!global) {
@ -4932,6 +4944,11 @@ HTMLInputElement::GetFilesAndDirectories(ErrorResult& aRv)
p->MaybeResolve(filesAndDirsSeq);
// Cache the Promise so that repeat getFilesAndDirectories() calls return
// the same Promise and array of File and Directory objects until the user
// picks different files/directories:
mFilesAndDirectoriesPromise = p;
return p.forget();
}

View File

@ -1285,6 +1285,7 @@ protected:
#endif
nsRefPtr<FileList> mFileList;
nsRefPtr<Promise> mFilesAndDirectoriesPromise;
nsString mStaticDocFileList;

View File

@ -563,69 +563,84 @@ nsBrowserElement::GetAllowedAudioChannels(
return;
}
nsCOMPtr<nsIAppsService> appsService =
do_GetService("@mozilla.org/AppsService;1");
if (NS_WARN_IF(!appsService)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsCOMPtr<mozIApplication> app;
aRv = appsService->GetAppByManifestURL(manifestURL, getter_AddRefs(app));
GenerateAllowedAudioChannels(window, frameLoader, mBrowserElementAPI,
manifestURL, mBrowserElementAudioChannels,
aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
}
// Normal is always allowed.
nsTArray<nsRefPtr<BrowserElementAudioChannel>> channels;
aAudioChannels.AppendElements(mBrowserElementAudioChannels);
}
nsRefPtr<BrowserElementAudioChannel> ac =
new BrowserElementAudioChannel(window, frameLoader, mBrowserElementAPI,
AudioChannel::Normal);
/* static */ void
nsBrowserElement::GenerateAllowedAudioChannels(
nsPIDOMWindow* aWindow,
nsIFrameLoader* aFrameLoader,
nsIBrowserElementAPI* aAPI,
const nsAString& aManifestURL,
nsTArray<nsRefPtr<BrowserElementAudioChannel>>& aAudioChannels,
ErrorResult& aRv)
{
MOZ_ASSERT(aAudioChannels.IsEmpty());
aRv = ac->Initialize();
if (NS_WARN_IF(aRv.Failed())) {
return;
}
nsCOMPtr<nsIAppsService> appsService =
do_GetService("@mozilla.org/AppsService;1");
if (NS_WARN_IF(!appsService)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
channels.AppendElement(ac);
nsCOMPtr<mozIApplication> app;
aRv = appsService->GetAppByManifestURL(aManifestURL, getter_AddRefs(app));
if (NS_WARN_IF(aRv.Failed())) {
return;
}
if (app) {
const nsAttrValue::EnumTable* audioChannelTable =
AudioChannelService::GetAudioChannelTable();
// Normal is always allowed.
nsTArray<nsRefPtr<BrowserElementAudioChannel>> channels;
bool allowed;
nsAutoCString permissionName;
nsRefPtr<BrowserElementAudioChannel> ac =
BrowserElementAudioChannel::Create(aWindow, aFrameLoader, aAPI,
AudioChannel::Normal, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
for (uint32_t i = 0; audioChannelTable && audioChannelTable[i].tag; ++i) {
permissionName.AssignASCII("audio-channel-");
permissionName.AppendASCII(audioChannelTable[i].tag);
channels.AppendElement(ac);
aRv = app->HasPermission(permissionName.get(), &allowed);
if (app) {
const nsAttrValue::EnumTable* audioChannelTable =
AudioChannelService::GetAudioChannelTable();
bool allowed;
nsAutoCString permissionName;
for (uint32_t i = 0; audioChannelTable && audioChannelTable[i].tag; ++i) {
permissionName.AssignASCII("audio-channel-");
permissionName.AppendASCII(audioChannelTable[i].tag);
aRv = app->HasPermission(permissionName.get(), &allowed);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
if (allowed) {
nsRefPtr<BrowserElementAudioChannel> ac =
BrowserElementAudioChannel::Create(aWindow, aFrameLoader, aAPI,
(AudioChannel)audioChannelTable[i].value,
aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
if (allowed) {
nsRefPtr<BrowserElementAudioChannel> ac =
new BrowserElementAudioChannel(window, frameLoader,
mBrowserElementAPI,
(AudioChannel)audioChannelTable[i].value);
aRv = ac->Initialize();
if (NS_WARN_IF(aRv.Failed())) {
return;
}
channels.AppendElement(ac);
}
channels.AppendElement(ac);
}
}
mBrowserElementAudioChannels.AppendElements(channels);
}
aAudioChannels.AppendElements(mBrowserElementAudioChannels);
aAudioChannels.SwapElements(channels);
}
already_AddRefed<DOMRequest>
@ -747,4 +762,20 @@ nsBrowserElement::ExecuteScript(const nsAString& aScript,
return req.forget().downcast<DOMRequest>();
}
already_AddRefed<DOMRequest>
nsBrowserElement::GetStructuredData(ErrorResult& aRv)
{
NS_ENSURE_TRUE(IsBrowserElementOrThrow(aRv), nullptr);
nsCOMPtr<nsIDOMDOMRequest> req;
nsresult rv = mBrowserElementAPI->GetStructuredData(getter_AddRefs(req));
if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
return req.forget().downcast<DOMRequest>();
}
} // namespace mozilla

View File

@ -112,9 +112,20 @@ public:
const dom::BrowserElementExecuteScriptOptions& aOptions,
ErrorResult& aRv);
already_AddRefed<dom::DOMRequest> GetStructuredData(ErrorResult& aRv);
void SetNFCFocus(bool isFocus,
ErrorResult& aRv);
// Helper
static void GenerateAllowedAudioChannels(
nsPIDOMWindow* aWindow,
nsIFrameLoader* aFrameLoader,
nsIBrowserElementAPI* aAPI,
const nsAString& aManifestURL,
nsTArray<nsRefPtr<dom::BrowserElementAudioChannel>>& aAudioChannels,
ErrorResult& aRv);
protected:
NS_IMETHOD_(already_AddRefed<nsFrameLoader>) GetFrameLoader() = 0;
void InitBrowserElementAPI();

View File

@ -55,3 +55,6 @@ FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [
'/dom/system/gonk',
]
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -44,3 +44,6 @@ XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell/xpcshell.ini']
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -20,3 +20,6 @@ FINAL_LIBRARY = 'xul'
XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
MOCHITEST_MANIFESTS += ['test/mochitest.ini']
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -22,3 +22,6 @@ FINAL_LIBRARY = 'xul'
include('/ipc/chromium/chromium-config.mozbuild')
MOCHITEST_MANIFESTS += ['test/mochitest.ini']
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -16,3 +16,5 @@ LOCAL_INCLUDES += [
'/dom/base',
]
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -25,3 +25,6 @@ LOCAL_INCLUDES += [
]
FINAL_LIBRARY = 'xul'
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -22,3 +22,6 @@ USE_STATIC_LIBS = True
NO_VISIBILITY_FLAGS = True
# Don't use STL wrappers; this isn't Gecko code
DISABLE_STL_WRAPPING = True
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -24,3 +24,6 @@ USE_STATIC_LIBS = True
NO_VISIBILITY_FLAGS = True
# Don't use STL wrappers; this isn't Gecko code
DISABLE_STL_WRAPPING = True
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -14,3 +14,6 @@ UNIFIED_SOURCES += [
]
FINAL_LIBRARY = 'xul'
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

View File

@ -242,12 +242,20 @@ PlatformDecoderModule::CreateDecoder(const TrackInfo& aConfig,
}
if (H264Converter::IsH264(aConfig)) {
m = new H264Converter(this,
nsRefPtr<H264Converter> h
= new H264Converter(this,
*aConfig.GetAsVideoInfo(),
aLayersBackend,
aImageContainer,
aTaskQueue,
callback);
const nsresult rv = h->GetLastError();
if (NS_SUCCEEDED(rv) || rv == NS_ERROR_NOT_INITIALIZED) {
// The H264Converter either successfully created the wrapped decoder,
// or there wasn't enough AVCC data to do so. Otherwise, there was some
// problem, for example WMF DLLs were missing.
m = h.forget();
}
} else if (!hasPlatformDecoder && VPXDecoder::IsVPX(aConfig.mMimeType)) {
m = new VPXDecoder(*aConfig.GetAsVideoInfo(),
aImageContainer,

View File

@ -38,6 +38,7 @@ public:
// Return true if mimetype is H.264.
static bool IsH264(const TrackInfo& aConfig);
nsresult GetLastError() const { return mLastError; }
private:
// Will create the required MediaDataDecoder if need AVCC and we have a SPS NAL.

View File

@ -59,6 +59,7 @@ public:
}
virtual void ProcessBlock(AudioNodeStream* aStream,
GraphTime aFrom,
const AudioBlock& aInput,
AudioBlock* aOutput,
bool* aFinished) override

View File

@ -235,8 +235,7 @@ public:
// The number of frames consumed/produced depends on the amount of space
// remaining in both the input and output buffer, and the playback rate (that
// is, the ratio between the output samplerate and the input samplerate).
void CopyFromInputBufferWithResampling(AudioNodeStream* aStream,
AudioBlock* aOutput,
void CopyFromInputBufferWithResampling(AudioBlock* aOutput,
uint32_t aChannels,
uint32_t* aOffsetWithinBlock,
uint32_t aAvailableInOutput,
@ -368,8 +367,7 @@ public:
* This function knows when it needs to allocate the output buffer, and also
* optimizes the case where it can avoid memory allocations.
*/
void CopyFromBuffer(AudioNodeStream* aStream,
AudioBlock* aOutput,
void CopyFromBuffer(AudioBlock* aOutput,
uint32_t aChannels,
uint32_t* aOffsetWithinBlock,
StreamTime* aCurrentPosition,
@ -380,7 +378,7 @@ public:
std::min<StreamTime>(WEBAUDIO_BLOCK_SIZE - *aOffsetWithinBlock,
mStop - *aCurrentPosition);
if (mResampler) {
CopyFromInputBufferWithResampling(aStream, aOutput, aChannels,
CopyFromInputBufferWithResampling(aOutput, aChannels,
aOffsetWithinBlock, availableInOutput,
aCurrentPosition, aBufferMax);
return;
@ -434,7 +432,7 @@ public:
return rate ? rate : mBufferSampleRate;
}
void UpdateSampleRateIfNeeded(uint32_t aChannels)
void UpdateSampleRateIfNeeded(uint32_t aChannels, StreamTime aStreamPosition)
{
float playbackRate;
float detune;
@ -442,12 +440,12 @@ public:
if (mPlaybackRateTimeline.HasSimpleValue()) {
playbackRate = mPlaybackRateTimeline.GetValue();
} else {
playbackRate = mPlaybackRateTimeline.GetValueAtTime(mSource->GetCurrentPosition());
playbackRate = mPlaybackRateTimeline.GetValueAtTime(aStreamPosition);
}
if (mDetuneTimeline.HasSimpleValue()) {
detune = mDetuneTimeline.GetValue();
} else {
detune = mDetuneTimeline.GetValueAtTime(mSource->GetCurrentPosition());
detune = mDetuneTimeline.GetValueAtTime(aStreamPosition);
}
if (playbackRate <= 0 || mozilla::IsNaN(playbackRate)) {
playbackRate = 1.0f;
@ -460,6 +458,7 @@ public:
}
virtual void ProcessBlock(AudioNodeStream* aStream,
GraphTime aFrom,
const AudioBlock& aInput,
AudioBlock* aOutput,
bool* aFinished) override
@ -470,7 +469,7 @@ public:
return;
}
StreamTime streamPosition = aStream->GetCurrentPosition();
StreamTime streamPosition = aStream->GraphTimeToStreamTime(aFrom);
// We've finished if we've gone past mStop, or if we're past mDuration when
// looping is disabled.
if (streamPosition >= mStop ||
@ -482,7 +481,7 @@ public:
uint32_t channels = mBuffer ? mBuffer->GetChannels() : 0;
UpdateSampleRateIfNeeded(channels);
UpdateSampleRateIfNeeded(channels, streamPosition);
uint32_t written = 0;
while (written < WEBAUDIO_BLOCK_SIZE) {
@ -503,10 +502,10 @@ public:
if (mBufferPosition >= mLoopEnd) {
mBufferPosition = mLoopStart;
}
CopyFromBuffer(aStream, aOutput, channels, &written, &streamPosition, mLoopEnd);
CopyFromBuffer(aOutput, channels, &written, &streamPosition, mLoopEnd);
} else {
if (mBufferPosition < mBufferEnd || mRemainingResamplerTail) {
CopyFromBuffer(aStream, aOutput, channels, &written, &streamPosition, mBufferEnd);
CopyFromBuffer(aOutput, channels, &written, &streamPosition, mBufferEnd);
} else {
FillWithZeroes(aOutput, channels, &written, &streamPosition, STREAM_TIME_MAX);
}

View File

@ -46,6 +46,7 @@ public:
}
virtual void ProcessBlock(AudioNodeStream* aStream,
GraphTime aFrom,
const AudioBlock& aInput,
AudioBlock* aOutput,
bool* aFinished) override
@ -241,6 +242,7 @@ public:
}
virtual void ProcessBlock(AudioNodeStream* aStream,
GraphTime aFrom,
const AudioBlock& aInput,
AudioBlock* aOutput,
bool* aFinished) override

View File

@ -273,6 +273,7 @@ AudioBufferSumOfSquares(const float* aInput, uint32_t aLength)
void
AudioNodeEngine::ProcessBlock(AudioNodeStream* aStream,
GraphTime aFrom,
const AudioBlock& aInput,
AudioBlock* aOutput,
bool* aFinished)

View File

@ -315,6 +315,7 @@ public:
* call this again.
*/
virtual void ProcessBlock(AudioNodeStream* aStream,
GraphTime aFrom,
const AudioBlock& aInput,
AudioBlock* aOutput,
bool* aFinished);
@ -323,7 +324,8 @@ public:
* ProcessBlock() will be called later, and it then should not change
* aOutput. This is used only for DelayNodeEngine in a feedback loop.
*/
virtual void ProduceBlockBeforeInput(AudioBlock* aOutput)
virtual void ProduceBlockBeforeInput(GraphTime aFrom,
AudioBlock* aOutput)
{
NS_NOTREACHED("ProduceBlockBeforeInput called on wrong engine\n");
}

View File

@ -131,7 +131,6 @@ AudioNodeExternalInputStream::ProcessInput(GraphTime aFrom, GraphTime aTo,
// Handle that.
if (!IsEnabled() || mInputs.IsEmpty() || mPassThrough) {
mLastChunks[0].SetNull(WEBAUDIO_BLOCK_SIZE);
AdvanceOutputSegment();
return;
}
@ -205,9 +204,6 @@ AudioNodeExternalInputStream::ProcessInput(GraphTime aFrom, GraphTime aTo,
if (accumulateIndex == 0) {
mLastChunks[0].SetNull(WEBAUDIO_BLOCK_SIZE);
}
// Using AudioNodeStream's AdvanceOutputSegment to push the media stream graph along with null data.
AdvanceOutputSegment();
}
bool

View File

@ -513,12 +513,6 @@ AudioNodeStream::UpMixDownMixChunk(const AudioBlock* aChunk,
void
AudioNodeStream::ProcessInput(GraphTime aFrom, GraphTime aTo, uint32_t aFlags)
{
if (!mFinished) {
EnsureTrack(AUDIO_TRACK);
}
// No more tracks will be coming
mBuffer.AdvanceKnownTracksTime(STREAM_TIME_MAX);
uint16_t outputCount = mLastChunks.Length();
MOZ_ASSERT(outputCount == std::max(uint16_t(1), mEngine->OutputCount()));
@ -547,7 +541,8 @@ AudioNodeStream::ProcessInput(GraphTime aFrom, GraphTime aTo, uint32_t aFlags)
mLastChunks[0] = mInputChunks[0];
} else {
if (maxInputs <= 1 && outputCount <= 1) {
mEngine->ProcessBlock(this, mInputChunks[0], &mLastChunks[0], &finished);
mEngine->ProcessBlock(this, aFrom,
mInputChunks[0], &mLastChunks[0], &finished);
} else {
mEngine->ProcessBlocksOnPorts(this, mInputChunks, mLastChunks, &finished);
}
@ -570,12 +565,17 @@ AudioNodeStream::ProcessInput(GraphTime aFrom, GraphTime aTo, uint32_t aFlags)
if (!mFinished) {
// Don't output anything while finished
AdvanceOutputSegment();
if (mFlags & EXTERNAL_OUTPUT) {
AdvanceOutputSegment();
}
if (mMarkAsFinishedAfterThisBlock && (aFlags & ALLOW_FINISH)) {
// This stream was finished the last time that we looked at it, and all
// of the depending streams have finished their output as well, so now
// it's time to mark this stream as finished.
FinishOutput();
if (mFlags & EXTERNAL_OUTPUT) {
FinishOutput();
}
FinishOnGraphThread();
}
}
}
@ -592,7 +592,7 @@ AudioNodeStream::ProduceOutputBeforeInput(GraphTime aFrom)
if (!mIsActive) {
mLastChunks[0].SetNull(WEBAUDIO_BLOCK_SIZE);
} else {
mEngine->ProduceBlockBeforeInput(&mLastChunks[0]);
mEngine->ProduceBlockBeforeInput(aFrom, &mLastChunks[0]);
NS_ASSERTION(mLastChunks[0].GetDuration() == WEBAUDIO_BLOCK_SIZE,
"Invalid WebAudio chunk size");
if (mDisabledTrackIDs.Contains(static_cast<TrackID>(AUDIO_TRACK))) {
@ -605,9 +605,12 @@ void
AudioNodeStream::AdvanceOutputSegment()
{
StreamBuffer::Track* track = EnsureTrack(AUDIO_TRACK);
// No more tracks will be coming
mBuffer.AdvanceKnownTracksTime(STREAM_TIME_MAX);
AudioSegment* segment = track->Get<AudioSegment>();
if (mFlags & EXTERNAL_OUTPUT) {
if (!mLastChunks[0].IsNull()) {
segment->AppendAndConsumeChunk(mLastChunks[0].AsMutableChunk());
} else {
segment->AppendNullData(mLastChunks[0].GetDuration());
@ -623,23 +626,11 @@ AudioNodeStream::AdvanceOutputSegment()
}
}
StreamTime
AudioNodeStream::GetCurrentPosition()
{
NS_ASSERTION(!mFinished, "Don't create another track after finishing");
return EnsureTrack(AUDIO_TRACK)->Get<AudioSegment>()->GetDuration();
}
void
AudioNodeStream::FinishOutput()
{
if (IsFinishedOnGraphThread()) {
return;
}
StreamBuffer::Track* track = EnsureTrack(AUDIO_TRACK);
track->SetEnded();
FinishOnGraphThread();
for (uint32_t j = 0; j < mListeners.Length(); ++j) {
MediaStreamListener* l = mListeners[j];

View File

@ -122,7 +122,6 @@ public:
* the output. This is used only for DelayNodeEngine in a feedback loop.
*/
void ProduceOutputBeforeInput(GraphTime aFrom);
StreamTime GetCurrentPosition();
bool IsAudioParamStream() const
{
return mAudioParamStream;

View File

@ -138,6 +138,7 @@ public:
}
virtual void ProcessBlock(AudioNodeStream* aStream,
GraphTime aFrom,
const AudioBlock& aInput,
AudioBlock* aOutput,
bool* aFinished) override
@ -186,7 +187,7 @@ public:
uint32_t numberOfChannels = mBiquads.Length();
aOutput->AllocateChannels(numberOfChannels);
StreamTime pos = aStream->GetCurrentPosition();
StreamTime pos = aStream->GraphTimeToStreamTime(aFrom);
double freq = mFrequency.GetValueAtTime(pos);
double q = mQ.GetValueAtTime(pos);

View File

@ -102,6 +102,7 @@ public:
}
virtual void ProcessBlock(AudioNodeStream* aStream,
GraphTime aFrom,
const AudioBlock& aInput,
AudioBlock* aOutput,
bool* aFinished) override

View File

@ -76,6 +76,7 @@ public:
}
virtual void ProcessBlock(AudioNodeStream* aStream,
GraphTime aFrom,
const AudioBlock& aInput,
AudioBlock* aOutput,
bool* aFinished) override
@ -115,13 +116,13 @@ public:
// Skip output update if mLastChunks has already been set by
// ProduceBlockBeforeInput() when in a cycle.
if (!mHaveProducedBeforeInput) {
UpdateOutputBlock(aOutput, 0.0);
UpdateOutputBlock(aFrom, aOutput, 0.0);
}
mHaveProducedBeforeInput = false;
mBuffer.NextBlock();
}
void UpdateOutputBlock(AudioBlock* aOutput, double minDelay)
void UpdateOutputBlock(GraphTime aFrom, AudioBlock* aOutput, double minDelay)
{
double maxDelay = mMaxDelay;
double sampleRate = mSource->SampleRate();
@ -138,7 +139,7 @@ public:
// Compute the delay values for the duration of the input AudioChunk
// If this DelayNode is in a cycle, make sure the delay value is at least
// one block.
StreamTime tick = mSource->GetCurrentPosition();
StreamTime tick = mSource->GraphTimeToStreamTime(aFrom);
float values[WEBAUDIO_BLOCK_SIZE];
mDelay.GetValuesAtTime(tick, values,WEBAUDIO_BLOCK_SIZE);
@ -153,12 +154,13 @@ public:
}
}
virtual void ProduceBlockBeforeInput(AudioBlock* aOutput) override
virtual void ProduceBlockBeforeInput(GraphTime aFrom,
AudioBlock* aOutput) override
{
if (mLeftOverData <= 0) {
aOutput->SetNull(WEBAUDIO_BLOCK_SIZE);
} else {
UpdateOutputBlock(aOutput, WEBAUDIO_BLOCK_SIZE);
UpdateOutputBlock(aFrom, aOutput, WEBAUDIO_BLOCK_SIZE);
}
mHaveProducedBeforeInput = true;
}

View File

@ -93,6 +93,7 @@ public:
}
virtual void ProcessBlock(AudioNodeStream* aStream,
GraphTime aFrom,
const AudioBlock& aInput,
AudioBlock* aOutput,
bool* aFinished) override
@ -110,7 +111,7 @@ public:
aInput.ChannelCount());
}
StreamTime pos = aStream->GetCurrentPosition();
StreamTime pos = aStream->GraphTimeToStreamTime(aFrom);
mCompressor->setParameterValue(DynamicsCompressor::ParamThreshold,
mThreshold.GetValueAtTime(pos));
mCompressor->setParameterValue(DynamicsCompressor::ParamKnee,

View File

@ -59,6 +59,7 @@ public:
}
virtual void ProcessBlock(AudioNodeStream* aStream,
GraphTime aFrom,
const AudioBlock& aInput,
AudioBlock* aOutput,
bool* aFinished) override
@ -84,7 +85,7 @@ public:
aOutput->AllocateChannels(aInput.ChannelCount());
// Compute the gain values for the duration of the input AudioChunk
StreamTime tick = aStream->GetCurrentPosition();
StreamTime tick = aStream->GraphTimeToStreamTime(aFrom);
float computedGain[WEBAUDIO_BLOCK_SIZE];
mGain.GetValuesAtTime(tick, computedGain, WEBAUDIO_BLOCK_SIZE);

View File

@ -286,13 +286,14 @@ public:
}
virtual void ProcessBlock(AudioNodeStream* aStream,
GraphTime aFrom,
const AudioBlock& aInput,
AudioBlock* aOutput,
bool* aFinished) override
{
MOZ_ASSERT(mSource == aStream, "Invalid source stream");
StreamTime ticks = aStream->GetCurrentPosition();
StreamTime ticks = aStream->GraphTimeToStreamTime(aFrom);
if (mStart == -1) {
ComputeSilence(aOutput);
return;

View File

@ -135,6 +135,7 @@ public:
}
virtual void ProcessBlock(AudioNodeStream* aStream,
GraphTime aFrom,
const AudioBlock& aInput,
AudioBlock* aOutput,
bool *aFinished) override

View File

@ -280,6 +280,7 @@ public:
}
virtual void ProcessBlock(AudioNodeStream* aStream,
GraphTime aFrom,
const AudioBlock& aInput,
AudioBlock* aOutput,
bool* aFinished) override
@ -328,7 +329,7 @@ public:
*aOutput = mSharedBuffers->GetOutputBuffer();
if (mInputWriteIndex >= mBufferSize) {
SendBuffersToMainThread(aStream);
SendBuffersToMainThread(aStream, aFrom);
mInputWriteIndex -= mBufferSize;
}
}
@ -359,12 +360,12 @@ public:
}
private:
void SendBuffersToMainThread(AudioNodeStream* aStream)
void SendBuffersToMainThread(AudioNodeStream* aStream, GraphTime aFrom)
{
MOZ_ASSERT(!NS_IsMainThread());
// we now have a full input buffer ready to be sent to the main thread.
StreamTime playbackTick = mSource->GetCurrentPosition();
StreamTime playbackTick = mSource->GraphTimeToStreamTime(aFrom);
// Add the duration of the current sample
playbackTick += WEBAUDIO_BLOCK_SIZE;
// Add the delay caused by the main thread

View File

@ -109,6 +109,7 @@ public:
}
virtual void ProcessBlock(AudioNodeStream* aStream,
GraphTime aFrom,
const AudioBlock& aInput,
AudioBlock* aOutput,
bool *aFinished) override
@ -146,7 +147,7 @@ public:
bool onLeft[WEBAUDIO_BLOCK_SIZE];
float values[WEBAUDIO_BLOCK_SIZE];
StreamTime tick = aStream->GetCurrentPosition();
StreamTime tick = aStream->GraphTimeToStreamTime(aFrom);
mPan.GetValuesAtTime(tick, values, WEBAUDIO_BLOCK_SIZE);
for (size_t counter = 0; counter < WEBAUDIO_BLOCK_SIZE; ++counter) {

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