merge m-c to inbound on a CLOSED TREE

This commit is contained in:
Wes Kocher 2014-06-20 14:02:54 -07:00
commit 94dec8fe7d
297 changed files with 4214 additions and 2059 deletions

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ccd70903544486bea04e85d8a4aacf63f1de2a72"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd5065ced020014df5fd45259fba1ac32d65673b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ccd70903544486bea04e85d8a4aacf63f1de2a72"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bd5065ced020014df5fd45259fba1ac32d65673b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8ba14125aba912707f44761f194339e6e59701b7"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="276ce45e78b09c4a4ee643646f691d22804754c1">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ccd70903544486bea04e85d8a4aacf63f1de2a72"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bd5065ced020014df5fd45259fba1ac32d65673b"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ccd70903544486bea04e85d8a4aacf63f1de2a72"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd5065ced020014df5fd45259fba1ac32d65673b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ccd70903544486bea04e85d8a4aacf63f1de2a72"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bd5065ced020014df5fd45259fba1ac32d65673b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8ba14125aba912707f44761f194339e6e59701b7"/>

View File

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "dcb55fbcaa9bd33e662a2c5e99cdb7e4c9d7ad51",
"revision": "387f4c0123a7e82eae4c83f88f73e81f907c00e2",
"repo_path": "/integration/gaia-central"
}

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ccd70903544486bea04e85d8a4aacf63f1de2a72"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd5065ced020014df5fd45259fba1ac32d65673b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ccd70903544486bea04e85d8a4aacf63f1de2a72"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd5065ced020014df5fd45259fba1ac32d65673b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ccd70903544486bea04e85d8a4aacf63f1de2a72"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bd5065ced020014df5fd45259fba1ac32d65673b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8ba14125aba912707f44761f194339e6e59701b7"/>

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ccd70903544486bea04e85d8a4aacf63f1de2a72"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd5065ced020014df5fd45259fba1ac32d65673b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -647,10 +647,6 @@ pref("accessibility.typeaheadfind.flashBar", 1);
// plugin finder service url
pref("pfs.datasource.url", "https://pfs.mozilla.org/plugins/PluginFinderService.php?mimetype=%PLUGIN_MIMETYPE%&appID=%APP_ID%&appVersion=%APP_VERSION%&clientOS=%CLIENT_OS%&chromeLocale=%CHROME_LOCALE%&appRelease=%APP_RELEASE%");
// by default we show an infobar message when pages require plugins that are blocked, or are outdated
pref("plugins.hide_infobar_for_blocked_plugin", false);
pref("plugins.hide_infobar_for_outdated_plugin", false);
pref("plugins.update.url", "https://www.mozilla.org/%LOCALE%/plugincheck/");
pref("plugins.update.notifyUser", false);
@ -1342,6 +1338,8 @@ pref("devtools.styleeditor.enabled", true);
pref("devtools.styleeditor.source-maps-enabled", false);
pref("devtools.styleeditor.autocompletion-enabled", true);
pref("devtools.styleeditor.showMediaSidebar", true);
pref("devtools.styleeditor.mediaSidebarWidth", 238);
pref("devtools.styleeditor.navSidebarWidth", 245);
// Enable the Shader Editor.
pref("devtools.shadereditor.enabled", false);

View File

@ -38,11 +38,11 @@ function checkPreferences(prefsWin) {
}
// Same as the other one, but for in-content preferences
function checkInContentPreferences(win) {
let sel = win.history.state;
let doc = win.document;
let sel = doc.getElementById("categories").selectedItems[0].id;
let tab = doc.getElementById("advancedPrefs").selectedTab.id;
is(gBrowser.currentURI.spec, "about:preferences", "about:preferences loaded");
is(sel, "paneAdvanced", "Advanced pane was selected");
is(gBrowser.currentURI.spec, "about:preferences#advanced", "about:preferences loaded");
is(sel, "category-advanced", "Advanced pane was selected");
is(tab, "networkTab", "Network tab is selected");
// all good, we are done.
win.close();
@ -75,7 +75,9 @@ function test() {
let newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab);
newTabBrowser.addEventListener("Initialized", function PrefInit() {
newTabBrowser.removeEventListener("Initialized", PrefInit, true);
checkInContentPreferences(newTabBrowser.contentWindow);
executeSoon(function() {
checkInContentPreferences(newTabBrowser.contentWindow);
})
}, true);
}
});

View File

@ -488,32 +488,36 @@ function openPreferences(paneID, extraArgs)
}
}
// This function is duplicated from preferences.js.
function internalPrefCategoryNameToFriendlyName(aName) {
return (aName || "").replace(/^pane./, function(toReplace) { return toReplace[4].toLowerCase(); });
}
if (getBoolPref("browser.preferences.inContent")) {
let win = Services.wm.getMostRecentWindow("navigator:browser");
if (!win) {
return;
}
let newLoad = !win.switchToTabHavingURI("about:preferences", true);
let friendlyCategoryName = internalPrefCategoryNameToFriendlyName(paneID);
let preferencesURL = "about:preferences" +
(friendlyCategoryName ? "#" + friendlyCategoryName : "");
let newLoad = !win.switchToTabHavingURI(preferencesURL, true, {ignoreFragment: true});
let browser = win.gBrowser.selectedBrowser;
function switchToPane() {
if (paneID) {
browser.contentWindow.selectCategory(paneID);
}
switchToAdvancedSubPane(browser.contentDocument);
}
if (newLoad) {
Services.obs.addObserver(function advancedPaneLoadedObs(prefWin, topic, data) {
if (prefWin != browser.contentWindow) {
return;
}
Services.obs.removeObserver(advancedPaneLoadedObs, "advanced-pane-loaded");
switchToPane();
switchToAdvancedSubPane(browser.contentDocument);
}, "advanced-pane-loaded", false);
} else {
switchToPane();
if (paneID) {
browser.contentWindow.gotoPref(paneID);
}
switchToAdvancedSubPane(browser.contentDocument);
}
} else {
var instantApply = getBoolPref("browser.preferences.instantApply", false);

View File

@ -138,6 +138,16 @@ function getExpectedDataForPlacesNode(aNode) {
return [wrappedNode];
}
function afterToolbarTransition(callback) {
function listener(event) {
if (event.propertyName == "max-height") {
toolbar.removeEventListener("transitionend", listener);
callback();
}
}
toolbar.addEventListener("transitionend", listener);
}
var gTests = [
//------------------------------------------------------------------------------
@ -234,9 +244,12 @@ function nextTest() {
}
else {
// Collapse the personal toolbar if needed.
if (wasCollapsed)
if (wasCollapsed) {
setToolbarVisibility(toolbar, false);
finish();
afterToolbarTransition(finish);
} else {
finish();
}
}
}
@ -247,9 +260,11 @@ function test() {
waitForExplicitFinish();
// Uncollapse the personal toolbar if needed.
if (wasCollapsed)
if (wasCollapsed) {
setToolbarVisibility(toolbar, true);
nextTest();
afterToolbarTransition(nextTest);
} else {
nextTest();
}
}

View File

@ -71,9 +71,6 @@ var gAdvancedPane = {
#endif
this.updateActualCacheSize();
this.updateActualAppCacheSize();
// Notify observers that the UI is now ready
Services.obs.notifyObservers(window, "advanced-pane-loaded", null);
},
/**

View File

@ -12,6 +12,8 @@ const Cr = Components.results;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
let gLastHash = "";
addEventListener("DOMContentLoaded", function onLoad() {
removeEventListener("DOMContentLoaded", onLoad);
init_all();
@ -42,21 +44,45 @@ function init_all() {
this.removeAttribute("keyboard-navigation");
});
if (document.getElementById("category-general").selected) {
gotoPref("paneGeneral");
}
window.addEventListener("hashchange", onHashChange);
gotoPref();
// Wait until initialization of all preferences are complete before
// notifying observers that the UI is now ready.
Services.obs.notifyObservers(window, "advanced-pane-loaded", null);
}
function selectCategory(name) {
function onHashChange() {
gotoPref();
}
function gotoPref(aCategory) {
let categories = document.getElementById("categories");
let item = categories.querySelector(".category[value=" + name + "]");
categories.selectedItem = item;
gotoPref(name);
}
const kDefaultCategoryInternalName = categories.firstElementChild.value;
let hash = document.location.hash;
let category = aCategory || hash.substr(1) || kDefaultCategoryInternalName;
category = friendlyPrefCategoryNameToInternalName(category);
function gotoPref(page) {
window.history.replaceState(page, document.title);
search(page, "data-category");
// Updating the hash (below) or changing the selected category
// will re-enter gotoPref.
if (gLastHash == category)
return;
let item = categories.querySelector(".category[value=" + category + "]");
if (!item) {
category = kDefaultCategoryInternalName;
item = categories.querySelector(".category[value=" + category + "]");
}
let newHash = internalPrefCategoryNameToFriendlyName(category);
if (gLastHash || category != kDefaultCategoryInternalName) {
document.location.hash = newHash;
}
// Need to set the gLastHash before setting categories.selectedItem since
// the categories 'select' event will re-enter the gotoPref codepath.
gLastHash = category;
categories.selectedItem = item;
window.history.replaceState(category, document.title);
search(category, "data-category");
}
function search(aQuery, aAttribute) {
@ -74,3 +100,14 @@ function helpButtonCommand() {
.getAttribute("helpTopic");
openHelpLink(helpTopic);
}
function friendlyPrefCategoryNameToInternalName(aName) {
if (aName.startsWith("pane"))
return aName;
return "pane" + aName.substring(0,1).toUpperCase() + aName.substr(1);
}
// This function is duplicated inside of utilityOverlay.js's openPreferences.
function internalPrefCategoryNameToFriendlyName(aName) {
return (aName || "").replace(/^pane./, function(toReplace) { return toReplace[4].toLowerCase(); });
}

View File

@ -1,25 +1,59 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
add_task(function test() {
waitForExplicitFinish();
add_task(function() {
let prefs = yield openPreferencesViaOpenPreferencesAPI("paneContent");
is(prefs.selectedPane, "paneContent", "Content pane was selected");
prefs = yield openPreferencesViaOpenPreferencesAPI("advanced", "updateTab");
is(prefs.selectedPane, "paneAdvanced", "Advanced pane was selected");
is(prefs.selectedAdvancedTab, "updateTab", "The update tab within the advanced prefs should be selected");
prefs = yield openPreferencesViaHash("privacy");
is(prefs.selectedPane, "panePrivacy", "Privacy pane is selected when hash is 'privacy'");
prefs = yield openPreferencesViaOpenPreferencesAPI("nonexistant-category");
is(prefs.selectedPane, "paneGeneral", "General pane is selected by default when a nonexistant-category is requested");
prefs = yield openPreferencesViaHash("nonexistant-category");
is(prefs.selectedPane, "paneGeneral", "General pane is selected when hash is a nonexistant-category");
prefs = yield openPreferencesViaHash();
is(prefs.selectedPane, "paneGeneral", "General pane is selected by default");
});
function openPreferencesViaOpenPreferencesAPI(aPane, aAdvancedTab) {
let deferred = Promise.defer();
gBrowser.selectedTab = gBrowser.addTab("about:blank");
openPreferences("paneContent");
let newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab);
openPreferences(aPane, aAdvancedTab ? {advancedTab: aAdvancedTab} : undefined);
let newTabBrowser = gBrowser.selectedBrowser;
newTabBrowser.addEventListener("Initialized", function PrefInit() {
newTabBrowser.removeEventListener("Initialized", PrefInit, true);
newTabBrowser.contentWindow.addEventListener("load", function prefLoad() {
newTabBrowser.contentWindow.removeEventListener("load", prefLoad);
let sel = gBrowser.contentWindow.history.state;
is(sel, "paneContent", "Content pane was selected");
deferred.resolve();
let win = gBrowser.contentWindow;
let selectedPane = win.history.state;
let doc = win.document;
let selectedAdvancedTab = aAdvancedTab && doc.getElementById("advancedPrefs").selectedTab.id;
gBrowser.removeCurrentTab();
deferred.resolve({selectedPane: selectedPane, selectedAdvancedTab: selectedAdvancedTab});
});
}, true);
yield deferred.promise;
return deferred.promise;
}
finish();
});
function openPreferencesViaHash(aPane) {
let deferred = Promise.defer();
gBrowser.selectedTab = gBrowser.addTab("about:preferences" + (aPane ? "#" + aPane : ""));
let newTabBrowser = gBrowser.selectedBrowser;
newTabBrowser.addEventListener("Initialized", function PrefInit() {
newTabBrowser.removeEventListener("Initialized", PrefInit, true);
newTabBrowser.contentWindow.addEventListener("load", function prefLoad() {
newTabBrowser.contentWindow.removeEventListener("load", prefLoad);
let win = gBrowser.contentWindow;
let selectedPane = win.history.state;
gBrowser.removeCurrentTab();
deferred.resolve({selectedPane: selectedPane});
});
}, true);
return deferred.promise;
}

View File

@ -37,7 +37,7 @@ function test() {
function runTest(win) {
win.gotoPref("applications");
var sel = win.history.state;
ok(sel == "applications", "Specified pane was opened");
is(sel, "paneApplications", "Specified pane was opened");
var rbox = win.document.getElementById("handlersView");
ok(rbox, "handlersView is present");

View File

@ -26,17 +26,6 @@ function runTest(win) {
}
}
//Test if tabs pane is opened correctly
win.gotoPref("paneTabs");
for (let element of elements) {
let attributeValue = element.getAttribute("data-category");
if (attributeValue == "paneTabs") {
is_element_visible(element, "Tab elements should be visible");
} else {
is_element_hidden(element, "Non-Tab elements should be hidden");
}
}
//Test if content pane is opened correctly
win.gotoPref("paneContent");
for (let element of elements) {

View File

@ -717,6 +717,9 @@ addEventListener("unload", () => {
SessionStorageListener.uninit();
SessionHistoryListener.uninit();
// Remove progress listeners.
gContentRestore.resetRestore();
// We don't need to take care of any gFrameTree observers as the gFrameTree
// will die with the content script. The same goes for the privacy transition
// observer that will die with the docShell when the tab is closed.

View File

@ -176,7 +176,7 @@ ContentRestoreInternal.prototype = {
// Call resetRestore to reset the state back to normal. The data needed
// for restoreDocument (which hasn't happened yet) will remain in
// _restoringDocument.
this.resetRestore(this.docShell);
this.resetRestore();
finishCallback();
});
@ -361,7 +361,10 @@ HistoryListener.prototype = {
]),
uninstall: function () {
this.webNavigation.sessionHistory.removeSHistoryListener(this);
let shistory = this.webNavigation.sessionHistory;
if (shistory) {
shistory.removeSHistoryListener(this);
}
},
OnHistoryNewEntry: function(newURI) {},

View File

@ -1,6 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test 911547</title>
</head>
<body>
@ -12,7 +13,7 @@
-->
<input type="text" id="test_id" value="ok">
<a id="test_data_link" href="data:text/html,<input type='text' id='test_id2' value='ok'/> <script>document.getElementById('test_id2').value = 'fail';</script>">Test Link</a>
<a id="test_data_link" href="data:text/html;charset=utf-8,<input type='text' id='test_id2' value='ok'/> <script>document.getElementById('test_id2').value = 'fail';</script>">Test Link</a>
</body>
</html>

View File

@ -29,7 +29,7 @@
<input required="required" class="devtools-textinput" id="port" type="number" pattern="\d+"></input>
</label>
<label>
<input class="devtools-toolbarbutton" id="submit" type="submit" value="&connect;"></input>
<input class="devtools-toolbarbutton" id="submit" standalone="true" type="submit" value="&connect;"></input>
</label>
</form>
<p class="error-message error-timeout">&errorTimeout;</p>

View File

@ -57,8 +57,6 @@ DevTools.prototype = {
// testing/profiles/prefs_general.js so lets set it to the same as it is
// in a default browser profile for the duration of the test.
Services.prefs.setBoolPref("dom.send_after_paint_to_content", false);
} else {
Services.prefs.setBoolPref("dom.send_after_paint_to_content", true);
}
},

View File

@ -8,6 +8,8 @@ support-files =
browser_inspector_cmd_inspect.html
browser_inspector_dead_node_exception.html
browser_inspector_destroyselection.html
browser_inspector_highlighter.html
browser_inspector_infobar.html
browser_inspector_menu.html
browser_inspector_select_last_selected.html
browser_inspector_select_last_selected2.html

View File

@ -6,9 +6,6 @@
// Test that hovering over nodes in the markup-view shows the highlighter over
// those nodes
waitForExplicitFinish();
let test = asyncTest(function*() {
info("Loading the test document and opening the inspector");
yield addTab("data:text/html;charset=utf-8,<h1>foo</h1><span>bar</span>");

View File

@ -3,7 +3,6 @@
function test()
{
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
let nodes = [

View File

@ -3,8 +3,6 @@
function test()
{
waitForExplicitFinish();
let inspector, searchBox, state;
let keypressStates = [3,4,8,18,19,20,21,22];

View File

@ -2,7 +2,6 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
let doc;

View File

@ -7,8 +7,6 @@
function test()
{
waitForExplicitFinish();
let doc;
let node;
let inspector;

View File

@ -3,8 +3,6 @@
function test()
{
waitForExplicitFinish();
let doc;
let iframeNode, iframeBodyNode;
let inspector;

View File

@ -65,8 +65,6 @@ function test() {
});
}
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onBrowserLoad() {
gBrowser.selectedBrowser.removeEventListener("load", onBrowserLoad, true);

View File

@ -3,7 +3,6 @@
function test()
{
waitForExplicitFinish();
//ignoreAllUncaughtExceptions();
let node, iframe, inspector;

View File

@ -3,8 +3,6 @@
function test()
{
waitForExplicitFinish();
let inspector, searchBox, state, popup;
// The various states of the inspector: [key, suggestions array]

View File

@ -3,8 +3,6 @@
function test()
{
waitForExplicitFinish();
let inspector, searchBox, state, popup;
// The various states of the inspector: [key, suggestions array]

View File

@ -3,7 +3,6 @@
function test()
{
waitForExplicitFinish();
requestLongerTimeout(2);
let inspector, searchBox, state, panel;

View File

@ -6,8 +6,6 @@ let Toolbox = devtools.Toolbox;
let TargetFactory = devtools.TargetFactory;
function test() {
waitForExplicitFinish();
const URL_1 = "data:text/plain;charset=UTF-8,abcde";
const URL_2 = "data:text/plain;charset=UTF-8,12345";

View File

@ -13,8 +13,6 @@ const TEST_PAGE = "http://mochi.test:8888/browser/browser/devtools/inspector/tes
function test() {
let inspector, toolbox;
waitForExplicitFinish();
// Create a tab, load test HTML, wait for load and start the tests
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onload() {

View File

@ -5,8 +5,6 @@ let Toolbox = devtools.Toolbox;
let TargetFactory = devtools.TargetFactory;
function test() {
waitForExplicitFinish();
const URL_1 = "data:text/html;charset=UTF-8,<div id='one' style='color:red;'>ONE</div>";
const URL_2 = "data:text/html;charset=UTF-8,<div id='two' style='color:green;'>TWO</div>";

View File

@ -8,8 +8,6 @@ let doc;
let toolbox;
function test() {
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onload(evt) {
gBrowser.selectedBrowser.removeEventListener("load", onload, true);

View File

@ -15,7 +15,6 @@ const TEST_PAGE = "http://mochi.test:8888/browser/browser/devtools/inspector/tes
let inspector, markupView, doc;
function test() {
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onload() {
gBrowser.selectedBrowser.removeEventListener("load", onload, true);

View File

@ -8,8 +8,6 @@
function test() {
let {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onload() {
gBrowser.selectedBrowser.removeEventListener("load", onload, true);

View File

@ -8,8 +8,6 @@
function test() {
let {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onload() {
gBrowser.selectedBrowser.removeEventListener("load", onload, true);

View File

@ -4,8 +4,6 @@ http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
let contentTab, contentDoc, inspector;
waitForExplicitFinish();
// Create a tab
contentTab = gBrowser.selectedTab = gBrowser.addTab();

View File

@ -3,8 +3,6 @@
function test()
{
waitForExplicitFinish();
let node, iframe, inspector;
gBrowser.selectedTab = gBrowser.addTab();

View File

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>
<head>
<style>
div {
position:absolute;
}
#simple-div {
padding: 5px;
border: 7px solid red;
margin: 9px;
top: 30px;
left: 150px;
}
#rotated-div {
padding: 5px;
border: 7px solid red;
margin: 9px;
transform: rotate(45deg);
top: 30px;
left: 80px;
}
#widthHeightZero-div {
top: 30px;
left: 10px;
width: 0;
height: 0;
}
</style>
</head>
<body>
<div id="simple-div">Gort! Klaatu barada nikto!</div>
<div id="rotated-div"></div>
<div id="widthHeightZero-div">Width &amp; height = 0</div>
</body>
</html>

View File

@ -8,18 +8,18 @@
// Test that the highlighter is correctly displayed over a variety of elements
waitForExplicitFinish();
let test = asyncTest(function*() {
info("Adding the test tab and creating the document");
yield addTab("data:text/html;charset=utf-8,browser_inspector_highlighter.js");
createDocument(content.document);
const TEST_URI = "http://example.com/browser/browser/devtools/inspector/" +
"test/browser_inspector_highlighter.html";
info("Opening the document");
yield addTab(TEST_URI);
info("Opening the inspector");
let {toolbox, inspector} = yield openInspector();
info("Selecting the simple, non-transformed DIV");
let div = getNode(".simple-div");
let div = getNode("#simple-div");
yield selectNode(div, inspector, "highlight");
testSimpleDivHighlighted(div);
@ -28,36 +28,24 @@ let test = asyncTest(function*() {
yield zoomTo(1);
info("Selecting the rotated DIV");
let rotated = getNode(".rotated-div");
let rotated = getNode("#rotated-div");
let onBoxModelUpdate = waitForBoxModelUpdate();
yield selectNode(rotated, inspector, "highlight");
yield onBoxModelUpdate;
testMouseOverRotatedHighlights(rotated);
info("Selecting the zero width height DIV");
let zeroWidthHeight = getNode("#widthHeightZero-div");
let onBoxModelUpdate = waitForBoxModelUpdate();
yield selectNode(zeroWidthHeight, inspector, "highlight");
yield onBoxModelUpdate;
testMouseOverWidthHeightZeroDiv(zeroWidthHeight);
gBrowser.removeCurrentTab();
});
function createDocument(doc) {
info("Creating the test document");
let div = doc.createElement("div");
div.className = "simple-div";
div.setAttribute("style",
"padding:5px; border:7px solid red; margin: 9px; " +
"position:absolute; top:30px; left:150px;");
div.appendChild(doc.createTextNode("Gort! Klaatu barada nikto!"));
doc.body.appendChild(div);
let rotatedDiv = doc.createElement("div");
rotatedDiv.className = "rotated-div";
rotatedDiv.setAttribute("style",
"padding:5px; border:7px solid red; margin: 9px; " +
"transform:rotate(45deg); " +
"position:absolute; top:30px; left:80px;");
doc.body.appendChild(rotatedDiv);
}
function testSimpleDivHighlighted(div) {
ok(isHighlighting(), "The highlighter is shown");
is(getHighlitNode(), div, "The highlighter's outline corresponds to the simple div");
@ -89,3 +77,10 @@ function testMouseOverRotatedHighlights(rotated) {
info("Checking that the rotated div is correctly highlighted");
isNodeCorrectlyHighlighted(rotated, "rotated");
}
function testMouseOverWidthHeightZeroDiv(zeroHeightWidthDiv) {
ok(isHighlighting(), "The highlighter is shown");
info("Checking that the zero width height div is correctly highlighted");
isNodeCorrectlyHighlighted(zeroHeightWidthDiv, "zero width height");
}

View File

@ -99,8 +99,6 @@ function finishUp() {
}
function test() {
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function() {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);

View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style>
body {
width: 100%;
height: 100%;
}
div {
position: absolute;
height: 100px;
width: 500px;
}
#bottom {
bottom: 0px;
}
#vertical {
height: 100%;
}
#farbottom {
top: 2000px;
background: red;
}
#abovetop {
top: -123px;
}";
</style>
</head>
<body>
<div id="abovetop"></div>
<div id="vertical"></div>
<div id="top" class="class1 class2"></div>
<div id="bottom"></div>
<div id="farbottom"></div>
</body>
</html>

View File

@ -1,141 +1,150 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.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/. */
function test() {
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
"use strict";
let doc;
let nodes;
let cursor;
let inspector;
const TEST_URI = "http://example.com/browser/browser/devtools/inspector/" +
"test/browser_inspector_infobar.html";
const DOORHANGER_ARROW_HEIGHT = 5;
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onload() {
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
doc = content.document;
waitForFocus(setupInfobarTest, content);
}, true);
// Test that hovering over nodes in the markup-view shows the highlighter over
// those nodes
let test = asyncTest(function*() {
info("Loading the test document and opening the inspector");
let style = "body{width:100%;height: 100%} div {position: absolute;" +
"height: 100px;width: 500px}#bottom {bottom: 0px}#vertical {"+
"height: 100%}#farbottom{bottom: -200px}";
let html = "<style>" + style + "</style><div id=vertical></div>" +
"<div id=top class='class1 class2'></div><div id=bottom></div>" +
"<div id=farbottom></div>"
yield addTab(TEST_URI);
content.location = "data:text/html;charset=utf-8," + encodeURIComponent(html);
let {inspector} = yield openInspector();
function setupInfobarTest() {
nodes = [
{
node: doc.querySelector("#top"),
position: "bottom",
tag: "DIV",
id: "#top",
classes: ".class1.class2",
dims: "500 x 100"
},
{
node: doc.querySelector("#vertical"),
position: "overlap",
tag: "DIV",
id: "#vertical",
classes: ""
// No dims as they will vary between computers
},
{
node: doc.querySelector("#bottom"),
position: "top",
tag: "DIV",
id: "#bottom",
classes: "",
dims: "500 x 100"
},
{
node: doc.querySelector("body"),
position: "overlap",
tag: "BODY",
id: "",
classes: ""
// No dims as they will vary between computers
},
{
node: doc.querySelector("#farbottom"),
position: "top",
tag: "DIV",
id: "#farbottom",
classes: "",
dims: "500 x 100"
},
];
let doc = content.document;
let testData = [
{
node: doc.querySelector("#top"),
position: "bottom",
tag: "DIV",
id: "#top",
classes: ".class1.class2",
dims: "500 x 100"
},
{
node: doc.querySelector("#vertical"),
position: "overlap",
tag: "DIV",
id: "#vertical",
classes: ""
// No dims as they will vary between computers
},
{
node: doc.querySelector("#bottom"),
position: "top",
tag: "DIV",
id: "#bottom",
classes: "",
dims: "500 x 100"
},
{
node: doc.querySelector("body"),
position: "bottom",
tag: "BODY",
id: "",
classes: ""
// No dims as they will vary between computers
},
{
node: doc.querySelector("#farbottom"),
position: "top",
tag: "DIV",
id: "#farbottom",
classes: "",
dims: "500 x 100"
},
];
for (let i = 0; i < nodes.length; i++) {
ok(nodes[i].node, "node " + i + " found");
}
openInspector(runTests);
for (let currTest of testData) {
yield testPosition(currTest, inspector);
}
function mouseOverContainerToShowHighlighter(node, cb) {
let container = getContainerForRawNode(inspector.markup, node);
EventUtils.synthesizeMouse(container.tagLine, 2, 2, {type: "mousemove"},
inspector.markup.doc.defaultView);
executeSoon(cb);
}
yield checkInfoBarAboveTop(inspector);
yield checkInfoBarBelowFindbar(inspector);
function runTests(aInspector) {
inspector = aInspector;
inspector.selection.setNode(content.document.querySelector("body"));
inspector.once("inspector-updated", () => {
cursor = 0;
executeSoon(function() {
mouseOverContainerToShowHighlighter(nodes[0].node, nodeSelected);
});
});
}
gBrowser.removeCurrentTab();
});
function nodeSelected() {
executeSoon(function() {
performTest();
cursor++;
if (cursor >= nodes.length) {
finishUp();
} else {
let node = nodes[cursor].node;
mouseOverContainerToShowHighlighter(node, nodeSelected);
}
});
}
function* testPosition(currTest, inspector) {
let browser = gBrowser.selectedBrowser;
let stack = browser.parentNode;
function performTest() {
let browser = gBrowser.selectedBrowser;
let stack = browser.parentNode;
info("Testing " + currTest.id);
let container = stack.querySelector(".highlighter-nodeinfobar-positioner");
is(container.getAttribute("position"),
nodes[cursor].position, "node " + cursor + ": position matches.");
yield selectNode(currTest.node, inspector, "highlight");
let tagNameLabel = stack.querySelector(".highlighter-nodeinfobar-tagname");
is(tagNameLabel.textContent, nodes[cursor].tag,
"node " + cursor + ": tagName matches.");
let container = stack.querySelector(".highlighter-nodeinfobar-positioner");
is(container.getAttribute("position"),
currTest.position, "node " + currTest.id + ": position matches.");
let tagNameLabel = stack.querySelector(".highlighter-nodeinfobar-tagname");
is(tagNameLabel.textContent, currTest.tag,
"node " + currTest.id + ": tagName matches.");
if (currTest.id) {
let idLabel = stack.querySelector(".highlighter-nodeinfobar-id");
is(idLabel.textContent, nodes[cursor].id, "node " + cursor + ": id matches.");
let classesBox = stack.querySelector(".highlighter-nodeinfobar-classes");
is(classesBox.textContent, nodes[cursor].classes,
"node " + cursor + ": classes match.");
if (nodes[cursor].dims) {
let dimBox = stack.querySelector(".highlighter-nodeinfobar-dimensions");
is(dimBox.textContent, nodes[cursor].dims, "node " + cursor + ": dims match.");
}
is(idLabel.textContent, currTest.id, "node " + currTest.id + ": id matches.");
}
function finishUp() {
doc = nodes = null;
gBrowser.removeCurrentTab();
finish();
let classesBox = stack.querySelector(".highlighter-nodeinfobar-classes");
is(classesBox.textContent, currTest.classes,
"node " + currTest.id + ": classes match.");
if (currTest.dims) {
let dimBox = stack.querySelector(".highlighter-nodeinfobar-dimensions");
is(dimBox.textContent, currTest.dims, "node " + currTest.id + ": dims match.");
}
}
function* checkInfoBarAboveTop(inspector) {
yield selectNode("#abovetop", inspector);
let positioner = getPositioner();
let insideContent = parseInt(positioner.style.top, 10) >= -DOORHANGER_ARROW_HEIGHT;
ok(insideContent, "Infobar is inside the content window (top = " +
parseInt(positioner.style.top, 10) + ", content = '" +
positioner.textContent +"')");
}
function* checkInfoBarBelowFindbar(inspector) {
gFindBar.open();
let body = content.document.body;
let farBottom = body.querySelector("#farbottom");
farBottom.scrollIntoView();
// Wait for scrollIntoView
yield waitForTick();
body.scrollTop -= 130;
yield selectNode(farBottom, inspector);
let positioner = getPositioner();
let insideContent = parseInt(positioner.style.top, 10) >= -DOORHANGER_ARROW_HEIGHT;
ok(insideContent, "Infobar does not overlap the findbar (top = " +
parseInt(positioner.style.top, 10) + ", content = '" +
positioner.textContent +"')");
gFindBar.close();
}
function getPositioner() {
let browser = gBrowser.selectedBrowser;
let stack = browser.parentNode;
return stack.querySelector(".highlighter-nodeinfobar-positioner");
}
function waitForTick() {
let deferred = promise.defer();
executeSoon(deferred.resolve);
return deferred.promise;
}

View File

@ -129,7 +129,6 @@ function finishInspectorTests(subject, topic, aWinIdString)
function test()
{
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function() {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);

View File

@ -43,7 +43,6 @@ function test() {
});
}
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function() {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);

View File

@ -5,9 +5,6 @@ http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
let clipboard = require("sdk/clipboard");
waitForExplicitFinish();
let doc;
let inspector;

View File

@ -8,8 +8,6 @@
function test() {
let inspector, toolbox;
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onload() {
gBrowser.selectedBrowser.removeEventListener("load", onload, true);

View File

@ -12,7 +12,6 @@ function test() {
let menu;
let inspector;
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function() {

View File

@ -16,8 +16,6 @@ const TEST_URL = 'data:text/html,' +
' </div>' +
'</body>';
waitForExplicitFinish();
function test() {
ignoreAllUncaughtExceptions();
gBrowser.selectedTab = gBrowser.addTab();

View File

@ -8,8 +8,6 @@
function test() {
let inspector, toolbox;
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onload() {
gBrowser.selectedBrowser.removeEventListener("load", onload, true);

View File

@ -65,7 +65,6 @@ function finishUp()
function test()
{
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function() {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);

View File

@ -9,8 +9,6 @@ function test() {
let page1 = "http://mochi.test:8888/browser/browser/devtools/inspector/test/browser_inspector_select_last_selected.html";
let page2 = "http://mochi.test:8888/browser/browser/devtools/inspector/test/browser_inspector_select_last_selected2.html";
waitForExplicitFinish();
// Create a tab, load test HTML, wait for load and start the tests
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onload() {

View File

@ -60,7 +60,6 @@ function finishTest()
function test()
{
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function() {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);

View File

@ -98,7 +98,6 @@ function finishInspectorTests()
function test()
{
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function() {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);

View File

@ -16,6 +16,9 @@ const Cc = Components.classes;
const { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
const require = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools.require;
// All test are asynchronous
waitForExplicitFinish();
let tempScope = {};
Cu.import("resource://gre/modules/devtools/LayoutHelpers.jsm", tempScope);
let LayoutHelpers = tempScope.LayoutHelpers;
@ -91,7 +94,8 @@ function getNode(nodeOrSelector) {
* loaded in the toolbox
* @param {String} reason Defaults to "test" which instructs the inspector not
* to highlight the node upon selection
* @param {String} reason Defaults to "test" which instructs the inspector not to highlight the node upon selection
* @param {String} reason Defaults to "test" which instructs the inspector not
* to highlight the node upon selection
* @return a promise that resolves when the inspector is updated with the new
* node
*/
@ -507,3 +511,32 @@ SimpleTest.registerCleanupFunction(function () {
let target = TargetFactory.forTab(gBrowser.selectedTab);
gDevTools.closeToolbox(target);
});
/**
* Define an async test based on a generator function
*/
function asyncTest(generator) {
return () => Task.spawn(generator).then(null, ok.bind(null, false)).then(finish);
}
/**
* Add a new test tab in the browser and load the given url.
* @param {String} url The url to be loaded in the new tab
* @return a promise that resolves to the tab object when the url is loaded
*/
function addTab(url) {
info("Adding a new tab with URL: '" + url + "'");
let def = promise.defer();
let tab = gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onload() {
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
info("URL '" + url + "' loading complete");
waitForFocus(() => {
def.resolve(tab);
}, content);
}, true);
content.location = url;
return def.promise;
}

View File

@ -26,6 +26,7 @@ box,
min-height: 3em;
max-height: 14em;
max-width: 400px;
min-width: 180px;
}
.splitview-nav {

View File

@ -26,6 +26,7 @@ support-files =
[browser_graphs-11.js]
[browser_graphs-12.js]
[browser_graphs-13.js]
[browser_graphs-14.js]
[browser_layoutHelpers.js]
[browser_layoutHelpers-getBoxQuads.js]
[browser_observableobject.js]

View File

@ -19,16 +19,18 @@ let test = Task.async(function*() {
function* performTest() {
let [host, win, doc] = yield createHost();
let graph = new LineGraphWidget(doc.body, "fps");
yield graph.once("ready");
testGraph(graph);
yield testGraph(graph);
graph.destroy();
host.destroy();
}
function testGraph(graph) {
graph.setData(TEST_DATA);
function* testGraph(graph) {
info("Should be able to set the grpah data before waiting for the ready event.");
yield graph.setDataWhenReady(TEST_DATA);
ok(graph.hasData(), "Data was set successfully.");
is(graph._maxTooltip.querySelector("[text=info]").textContent, "max",
"The maximum tooltip displays the correct info.");

View File

@ -0,0 +1,92 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Tests that graph widgets correctly emit mouse input events.
const TEST_DATA = [{ delta: 112, value: 48 }, { delta: 213, value: 59 }, { delta: 313, value: 60 }, { delta: 413, value: 59 }, { delta: 530, value: 59 }, { delta: 646, value: 58 }, { delta: 747, value: 60 }, { delta: 863, value: 48 }, { delta: 980, value: 37 }, { delta: 1097, value: 30 }, { delta: 1213, value: 29 }, { delta: 1330, value: 23 }, { delta: 1430, value: 10 }, { delta: 1534, value: 17 }, { delta: 1645, value: 20 }, { delta: 1746, value: 22 }, { delta: 1846, value: 39 }, { delta: 1963, value: 26 }, { delta: 2080, value: 27 }, { delta: 2197, value: 35 }, { delta: 2312, value: 47 }, { delta: 2412, value: 53 }, { delta: 2514, value: 60 }, { delta: 2630, value: 37 }, { delta: 2730, value: 36 }, { delta: 2830, value: 37 }, { delta: 2946, value: 36 }, { delta: 3046, value: 40 }, { delta: 3163, value: 47 }, { delta: 3280, value: 41 }, { delta: 3380, value: 35 }, { delta: 3480, value: 27 }, { delta: 3580, value: 39 }, { delta: 3680, value: 42 }, { delta: 3780, value: 49 }, { delta: 3880, value: 55 }, { delta: 3980, value: 60 }, { delta: 4080, value: 60 }, { delta: 4180, value: 60 }];
let {LineGraphWidget} = Cu.import("resource:///modules/devtools/Graphs.jsm", {});
let {DOMHelpers} = Cu.import("resource:///modules/devtools/DOMHelpers.jsm", {});
let {Promise} = devtools.require("resource://gre/modules/Promise.jsm");
let {Hosts} = devtools.require("devtools/framework/toolbox-hosts");
let test = Task.async(function*() {
yield promiseTab("about:blank");
yield performTest();
gBrowser.removeCurrentTab();
finish();
});
function* performTest() {
let [host, win, doc] = yield createHost();
let graph = new LineGraphWidget(doc.body, "fps");
yield testGraph(graph);
graph.destroy();
host.destroy();
}
function* testGraph(graph) {
let mouseDownEvents = 0;
let mouseUpEvents = 0;
let scrollEvents = 0;
graph.on("mousedown", () => mouseDownEvents++);
graph.on("mouseup", () => mouseUpEvents++);
graph.on("scroll", () => scrollEvents++);
yield graph.setDataWhenReady(TEST_DATA);
info("Making a selection.");
dragStart(graph, 300);
dragStop(graph, 500);
is(graph.getSelection().start, 300,
"The current selection start value is correct (1).");
is(graph.getSelection().end, 500,
"The current selection end value is correct (1).");
is(mouseDownEvents, 1,
"One mousedown event should have been fired.");
is(mouseUpEvents, 1,
"One mouseup event should have been fired.");
is(scrollEvents, 0,
"No scroll event should have been fired.");
info("Zooming in by scrolling inside the selection.");
scroll(graph, -1000, 400);
is(graph.getSelection().start, 375,
"The current selection start value is correct (2).");
is(graph.getSelection().end, 425,
"The current selection end value is correct (2).");
is(mouseDownEvents, 1,
"No more mousedown events should have been fired.");
is(mouseUpEvents, 1,
"No more mouseup events should have been fired.");
is(scrollEvents, 1,
"One scroll event should have been fired.");
}
// EventUtils just doesn't work!
function dragStart(graph, x, y = 1) {
x /= window.devicePixelRatio;
y /= window.devicePixelRatio;
graph._onMouseMove({ clientX: x, clientY: y });
graph._onMouseDown({ clientX: x, clientY: y });
}
function dragStop(graph, x, y = 1) {
x /= window.devicePixelRatio;
y /= window.devicePixelRatio;
graph._onMouseMove({ clientX: x, clientY: y });
graph._onMouseUp({ clientX: x, clientY: y });
}
function scroll(graph, wheel, x, y = 1) {
x /= window.devicePixelRatio;
y /= window.devicePixelRatio;
graph._onMouseMove({ clientX: x, clientY: y });
graph._onMouseWheel({ clientX: x, clientY: y, detail: wheel });
}

View File

@ -282,6 +282,19 @@ AbstractCanvasGraph.prototype = {
this._shouldRedraw = true;
},
/**
* Same as `setData`, but waits for this graph to finish initializing first.
*
* @param object data
* The data source. The actual format is specified by subclasses.
* @return promise
* A promise resolved once the data is set.
*/
setDataWhenReady: Task.async(function*(data) {
yield this.ready();
this.setData(data);
}),
/**
* Adds regions to this graph.
*
@ -293,7 +306,7 @@ AbstractCanvasGraph.prototype = {
*/
setRegions: function(regions) {
if (!this._cachedGraphImage) {
throw "Can't highlighted regions on a graph with no data displayed.";
throw "Can't highlight regions on a graph with no data displayed.";
}
if (this._regions) {
throw "Regions were already highlighted on the graph.";
@ -829,6 +842,7 @@ AbstractCanvasGraph.prototype = {
}
this._shouldRedraw = true;
this.emit("mousedown");
},
/**
@ -870,6 +884,7 @@ AbstractCanvasGraph.prototype = {
}
this._shouldRedraw = true;
this.emit("mouseup");
},
/**
@ -938,6 +953,7 @@ AbstractCanvasGraph.prototype = {
this._shouldRedraw = true;
this.emit("selecting");
this.emit("scroll");
},
/**
@ -1547,6 +1563,9 @@ this.CanvasGraphUtils = {
* Merges the animation loop of two graphs.
*/
linkAnimation: Task.async(function*(graph1, graph2) {
if (!graph1 || !graph2) {
return;
}
yield graph1.ready();
yield graph2.ready();
@ -1567,6 +1586,9 @@ this.CanvasGraphUtils = {
* Makes sure selections in one graph are reflected in another.
*/
linkSelection: function(graph1, graph2) {
if (!graph1 || !graph2) {
return;
}
graph1.on("selecting", () => {
graph2.setSelection(graph1.getSelection());
});

View File

@ -34,6 +34,8 @@ const console = require("resource://gre/modules/devtools/Console.jsm").console;
const LOAD_ERROR = "error-load";
const STYLE_EDITOR_TEMPLATE = "stylesheet";
const PREF_MEDIA_SIDEBAR = "devtools.styleeditor.showMediaSidebar";
const PREF_SIDEBAR_WIDTH = "devtools.styleeditor.mediaSidebarWidth";
const PREF_NAV_WIDTH = "devtools.styleeditor.navSidebarWidth";
/**
* StyleEditorUI is controls and builds the UI of the Style Editor, including
@ -64,7 +66,8 @@ function StyleEditorUI(debuggee, target, panelDoc) {
this.selectedEditor = null;
this.savedLocations = {};
this._updateOptionsMenu = this._updateOptionsMenu.bind(this);
this._onOptionsPopupShowing = this._onOptionsPopupShowing.bind(this);
this._onOptionsPopupHiding = this._onOptionsPopupHiding.bind(this);
this._onStyleSheetCreated = this._onStyleSheetCreated.bind(this);
this._onNewDocument = this._onNewDocument.bind(this);
this._onMediaPrefChanged = this._onMediaPrefChanged.bind(this);
@ -142,9 +145,12 @@ StyleEditorUI.prototype = {
this._importFromFile(this._mockImportFile || null, this._window);
});
this._optionsButton = this._panelDoc.getElementById("style-editor-options");
this._optionsMenu = this._panelDoc.getElementById("style-editor-options-popup");
this._optionsMenu.addEventListener("popupshowing",
this._updateOptionsMenu);
this._onOptionsPopupShowing);
this._optionsMenu.addEventListener("popuphiding",
this._onOptionsPopupHiding);
this._sourcesItem = this._panelDoc.getElementById("options-origsources");
this._sourcesItem.addEventListener("command",
@ -152,18 +158,30 @@ StyleEditorUI.prototype = {
this._mediaItem = this._panelDoc.getElementById("options-show-media");
this._mediaItem.addEventListener("command",
this._toggleMediaSidebar);
let nav = this._panelDoc.querySelector(".splitview-controller");
nav.setAttribute("width", Services.prefs.getIntPref(PREF_NAV_WIDTH));
},
/**
* Listener handling the 'gear menu' popup showing event.
* Update options menu items to reflect current preference settings.
*/
_updateOptionsMenu: function() {
_onOptionsPopupShowing: function() {
this._optionsButton.setAttribute("open", "true");
this._sourcesItem.setAttribute("checked",
Services.prefs.getBoolPref(PREF_ORIG_SOURCES));
this._mediaItem.setAttribute("checked",
Services.prefs.getBoolPref(PREF_MEDIA_SIDEBAR));
},
/**
* Listener handling the 'gear menu' popup hiding event.
*/
_onOptionsPopupHiding: function() {
this._optionsButton.removeAttribute("open");
},
/**
* Refresh editors to reflect the stylesheets in the document.
*
@ -454,6 +472,22 @@ StyleEditorUI.prototype = {
}
}, false);
let sidebar = details.querySelector(".stylesheet-sidebar");
sidebar.setAttribute("width",
Services.prefs.getIntPref(PREF_SIDEBAR_WIDTH));
let splitter = details.querySelector(".devtools-side-splitter");
splitter.addEventListener("mousemove", () => {
let sidebarWidth = sidebar.getAttribute("width");
Services.prefs.setIntPref(PREF_SIDEBAR_WIDTH, sidebarWidth);
// update all @media sidebars for consistency
let sidebars = [...this._panelDoc.querySelectorAll(".stylesheet-sidebar")];
for (let mediaSidebar of sidebars) {
mediaSidebar.setAttribute("width", sidebarWidth);
}
});
// autofocus if it's a new user-created stylesheet
if (editor.isNew) {
this._selectEditor(editor);
@ -788,8 +822,14 @@ StyleEditorUI.prototype = {
destroy: function() {
this._clearStyleSheetEditors();
let sidebar = this._panelDoc.querySelector(".splitview-controller");
let sidebarWidth = sidebar.getAttribute("width");
Services.prefs.setIntPref(PREF_NAV_WIDTH, sidebarWidth);
this._optionsMenu.removeEventListener("popupshowing",
this._updateOptionsMenu);
this._onOptionsPopupShowing);
this._optionsMenu.removeEventListener("popuphiding",
this._onOptionsPopupHiding);
this._prefObserver.off(PREF_ORIG_SOURCES, this._onNewDocument);
this._prefObserver.off(PREF_MEDIA_SIDEBAR, this._onMediaPrefChanged);

View File

@ -102,7 +102,7 @@
</xul:hbox>
<xul:spacer/>
<xul:toolbarbutton id="style-editor-options"
class="devtools-option-toolbarbutton"
class="devtools-toolbarbutton devtools-option-toolbarbutton"
tooltiptext="&optionsButton.tooltip;"
popup="style-editor-options-popup"/>
</xul:toolbar>
@ -148,6 +148,7 @@
<xul:hbox class="stylesheet-details-container">
<xul:box class="stylesheet-editor-input textbox"
data-placeholder="&editorTextbox.placeholder;"/>
<xul:splitter class="devtools-side-splitter"/>
<xul:vbox class="stylesheet-sidebar theme-sidebar" hidden="true">
<xul:toolbar class="devtools-toolbar">
&mediaRules.label;

View File

@ -6,6 +6,7 @@ support-files =
doc_complex-context.html
doc_simple-node-creation.html
doc_buffer-and-array.html
doc_media-node-creation.html
440hz_sine.ogg
head.js
@ -32,6 +33,7 @@ support-files =
[browser_wa_inspector-toggle.js]
[browser_wa_properties-view.js]
[browser_wa_properties-view-media-nodes.js]
# [browser_wa_properties-view-edit.js]
# Disabled for too many intermittents bug 1010423
[browser_wa_properties-view-params.js]

View File

@ -0,0 +1,45 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that params view correctly displays all properties for nodes
* correctly, with default values and correct types.
*/
let MEDIA_PERMISSION = "media.navigator.permission.disabled";
function spawnTest() {
let [target, debuggee, panel] = yield initWebAudioEditor(MEDIA_NODES_URL);
let { panelWin } = panel;
let { gFront, $, $$, EVENTS, WebAudioInspectorView } = panelWin;
let gVars = WebAudioInspectorView._propsView;
// Auto enable getUserMedia
let mediaPermissionPref = Services.prefs.getBoolPref(MEDIA_PERMISSION);
Services.prefs.setBoolPref(MEDIA_PERMISSION, true);
reload(target);
let [actors] = yield Promise.all([
getN(gFront, "create-node", 4),
waitForGraphRendered(panelWin, 4, 0)
]);
let nodeIds = actors.map(actor => actor.actorID);
let types = [
"AudioDestinationNode", "MediaElementAudioSourceNode",
"MediaStreamAudioSourceNode", "MediaStreamAudioDestinationNode"
];
for (let i = 0; i < types.length; i++) {
click(panelWin, findGraphNode(panelWin, nodeIds[i]));
yield once(panelWin, EVENTS.UI_INSPECTOR_NODE_SET);
checkVariableView(gVars, 0, NODE_DEFAULT_VALUES[types[i]], types[i]);
}
// Reset permissions on getUserMedia
Services.prefs.setBoolPref(MEDIA_PERMISSION, mediaPermissionPref);
yield teardown(panel);
finish();
}

View File

@ -0,0 +1,29 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>Web Audio Editor test page</title>
</head>
<body>
<script type="text/javascript;version=1.8">
"use strict";
let ctx = new AudioContext();
let audio = new Audio();
let meNode, msNode, mdNode;
navigator.getUserMedia = navigator.getUserMedia || navigator.mozGetUserMedia;
navigator.getUserMedia({ audio: true }, stream => {
meNode = ctx.createMediaElementSource(audio);
msNode = ctx.createMediaStreamSource(stream);
mdNode = ctx.createMediaStreamDestination();
}, () => {});
</script>
</body>
</html>

View File

@ -24,6 +24,7 @@ const EXAMPLE_URL = "http://example.com/browser/browser/devtools/webaudioeditor/
const SIMPLE_CONTEXT_URL = EXAMPLE_URL + "doc_simple-context.html";
const COMPLEX_CONTEXT_URL = EXAMPLE_URL + "doc_complex-context.html";
const SIMPLE_NODES_URL = EXAMPLE_URL + "doc_simple-node-creation.html";
const MEDIA_NODES_URL = EXAMPLE_URL + "doc_media-node-creation.html";
const BUFFER_AND_ARRAY_URL = EXAMPLE_URL + "doc_buffer-and-array.html";
// All tests are asynchronous.
@ -216,6 +217,16 @@ function checkVariableView (view, index, hash, description = "") {
info("Checking Variable View");
let scope = view.getScopeAtIndex(index);
let variables = Object.keys(hash);
// If node shouldn't display any properties, ensure that the 'empty' message is
// visible
if (!variables.length) {
ok(isVisible(scope.window.$("#properties-tabpanel-content-empty")),
description + " should show the empty properties tab.");
return;
}
// Otherwise, iterate over expected properties
variables.forEach(variable => {
let aVar = scope.get(variable);
is(aVar.target.querySelector(".name").getAttribute("value"), variable,
@ -367,6 +378,11 @@ function countGraphObjects (win) {
const NODE_DEFAULT_VALUES = {
"AudioDestinationNode": {},
"MediaElementAudioSourceNode": {},
"MediaStreamAudioSourceNode": {},
"MediaStreamAudioDestinationNode": {
"stream": "MediaStream"
},
"AudioBufferSourceNode": {
"playbackRate": 1,
"loop": false,

View File

@ -229,7 +229,13 @@ this.ContentSearch = {
xhr.onloadend = () => {
deferred.resolve(xhr.response);
};
xhr.send();
try {
// This throws if the URI is erroneously encoded.
xhr.send();
}
catch (err) {
return Promise.resolve(null);
}
return deferred.promise;
},

View File

@ -1,12 +1,14 @@
[DEFAULT]
support-files =
head.js
contentSearch.js
image.png
uitour.*
[browser_BrowserUITelemetry_buckets.js]
[browser_ContentSearch.js]
support-files =
contentSearch.js
contentSearchBadImage.xml
[browser_NetworkPrioritizer.js]
skip-if = e10s # Bug 666804 - Support NetworkPrioritizer in e10s
[browser_SignInToWebsite.js]

View File

@ -146,6 +146,31 @@ add_task(function* search() {
yield deferred.promise;
});
add_task(function* badImage() {
yield addTab();
// If the bad image URI caused an exception to be thrown within ContentSearch,
// then we'll hang waiting for the CurrentState responses triggered by the new
// engine. That's what we're testing, and obviously it shouldn't happen.
let vals = yield waitForNewEngine("contentSearchBadImage.xml", 1);
let engine = vals[0];
let finalCurrentStateMsg = vals[vals.length - 1];
let expectedCurrentState = yield currentStateObj();
let expectedEngine =
expectedCurrentState.engines.find(e => e.name == engine.name);
ok(!!expectedEngine, "Sanity check: engine should be in expected state");
ok(expectedEngine.iconBuffer === null,
"Sanity check: icon array buffer of engine in expected state " +
"should be null: " + expectedEngine.iconBuffer);
checkMsg(finalCurrentStateMsg, {
type: "CurrentState",
data: expectedCurrentState,
});
// Removing the engine triggers a final CurrentState message. Wait for it so
// it doesn't trip up subsequent tests.
Services.search.removeEngine(engine);
yield waitForTestMsg("CurrentState");
});
function checkMsg(actualMsg, expectedMsgData) {
SimpleTest.isDeeply(actualMsg.data, expectedMsgData, "Checking message");
}
@ -167,6 +192,35 @@ function waitForTestMsg(type) {
return waitForMsg(TEST_MSG, type);
}
function waitForNewEngine(basename, numImages) {
info("Waiting for engine to be added: " + basename);
// Wait for the search events triggered by adding the new engine.
// engine-added engine-loaded
let expectedSearchEvents = ["CurrentState", "CurrentState"];
// engine-changed for each of the images
for (let i = 0; i < numImages; i++) {
expectedSearchEvents.push("CurrentState");
}
let eventPromises = expectedSearchEvents.map(e => waitForTestMsg(e));
// Wait for addEngine().
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 Promise.all([addDeferred.promise].concat(eventPromises));
}
function addTab() {
let deferred = Promise.defer();
let tab = gBrowser.addTab();
@ -230,6 +284,11 @@ function arrayBufferFromDataURI(uri) {
xhr.onloadend = () => {
deferred.resolve(xhr.response);
};
xhr.send();
try {
xhr.send();
}
catch (err) {
return Promise.resolve(null);
}
return deferred.promise;
}

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
<ShortName>browser_ContentSearch contentSearchBadImage.xml</ShortName>
<Url type="text/html" method="GET" template="http://browser-ContentSearch.com/contentSearchBadImage" rel="searchform"/>
<Image width="16" height="16">data:image/x-icon;base64,notbase64</Image>
</SearchPlugin>

View File

@ -51,6 +51,18 @@
padding-bottom: 1px;
}
#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar):not(#nav-bar):not(#addon-bar) {
overflow: -moz-hidden-unscrollable;
max-height: 4em;
transition: min-height 170ms ease-out, max-height 170ms ease-out;
}
#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar):not(#nav-bar):not(#addon-bar)[collapsed=true] {
min-height: 0.1px;
max-height: 0;
transition: min-height 170ms ease-out, max-height 170ms ease-out, visibility 170ms linear;
}
#TabsToolbar:not([collapsed="true"]) + #nav-bar {
border-top: 1px solid hsla(0,0%,0%,.3) !important;
background-clip: padding-box;

View File

@ -109,6 +109,18 @@ toolbarseparator {
background: url(chrome://browser/skin/Toolbar-background-noise.png) hsl(0,0%,83%);
}
#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar):not(#nav-bar):not(#addon-bar) {
overflow: -moz-hidden-unscrollable;
max-height: 4em;
transition: min-height 170ms ease-out, max-height 170ms ease-out;
}
#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar):not(#nav-bar):not(#addon-bar)[collapsed=true] {
min-height: 0.1px;
max-height: 0;
transition: min-height 170ms ease-out, max-height 170ms ease-out, visibility 170ms linear;
}
#nav-bar {
-moz-appearance: none;
background: url(chrome://browser/skin/Toolbar-background-noise.png),
@ -149,7 +161,7 @@ toolbarseparator {
padding: 4px;
}
#PersonalToolbar {
#PersonalToolbar:not([collapsed=true]) {
padding: 0 4px 4px;
/* 4px padding ^ plus 19px personal-bookmarks (see below) */
min-height: 23px;

View File

@ -65,8 +65,8 @@
}
.stylesheet-sidebar {
width: 237px;
-moz-border-start: 1px solid;
max-width: 400px;
min-width: 100px;
}
.theme-light .stylesheet-sidebar {
@ -125,11 +125,6 @@
background-position: -24px 8px;
}
#style-editor-options {
width: 20px;
overflow: hidden;
}
/* Invert all toggle icons but the one in the active row for light theme */
.theme-light .splitview-nav > li:not(.splitview-active) .stylesheet-enabled {
filter: url(filters.svg#invert);

View File

@ -25,6 +25,19 @@
padding: 0 3px;
}
.devtools-toolbar checkbox {
margin: 0 2px;
padding: 0;
}
.devtools-toolbar checkbox .checkbox-check {
margin: 0;
padding: 0;
}
.devtools-toolbar checkbox .checkbox-label-box .checkbox-label {
margin: 0 6px !important; /* overrides .checkbox-label from checkbox.css */
padding: 0;
}
/* Toolbar buttons */
.devtools-menulist,
.devtools-toolbarbutton {
@ -38,6 +51,7 @@
border: none;
border-radius: 0;
margin: 2px 3px;
color: inherit;
}
.devtools-menulist:-moz-focusring,
@ -72,15 +86,12 @@
margin: 0;
}
.devtools-toolbarbutton > .toolbarbutton-menubutton-button {
-moz-box-orient: horizontal;
padding: 0;
}
.devtools-toolbarbutton[type=menu-button] > .toolbarbutton-menubutton-button {
-moz-appearance: none;
color: inherit;
border-width: 0;
-moz-box-orient: horizontal;
padding: 0;
}
.devtools-toolbarbutton[type=menu-button] {
@ -88,6 +99,10 @@
-moz-box-align: stretch;
}
.devtools-toolbarbutton > .toolbarbutton-menubutton-button > .toolbarbutton-icon {
-moz-margin-end: 4px;
}
.devtools-menulist > .menulist-dropmarker {
-moz-appearance: none;
display: -moz-box;

View File

@ -203,6 +203,12 @@
color: hsl(210,30%,85%);
}
.breadcrumbs-widget-item > .button-box {
border: none;
padding-top: 0;
padding-bottom: 0;
}
.breadcrumbs-widget-item:not([checked]) {
background: -moz-element(#breadcrumb-separator-normal) no-repeat center left;
}

View File

@ -78,6 +78,18 @@
background-color: -moz-Dialog;
}
#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar):not(#nav-bar):not(#addon-bar) {
overflow: -moz-hidden-unscrollable;
max-height: 4em;
transition: min-height 170ms ease-out, max-height 170ms ease-out;
}
#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar):not(#nav-bar):not(#addon-bar)[collapsed=true] {
min-height: 0.1px;
max-height: 0;
transition: min-height 170ms ease-out, max-height 170ms ease-out, visibility 170ms linear;
}
%ifdef WINDOWS_AERO
@media not all and (-moz-windows-compositor),
not all and (-moz-windows-default-theme) {

View File

@ -83,9 +83,11 @@ DOMRequestIpcHelper.prototype = {
aMessages.forEach((aMsg) => {
let name = aMsg.name || aMsg;
// If the listener is already set and it is of the same type we just
// bail out. If it is not of the same type, we throw an exception.
// increase the count and bail out. If it is not of the same type,
// we throw an exception.
if (this._listeners[name] != undefined) {
if (!!aMsg.weakRef == this._listeners[name]) {
if (!!aMsg.weakRef == this._listeners[name].weakRef) {
this._listeners[name].count++;
return;
} else {
throw Cr.NS_ERROR_FAILURE;
@ -94,7 +96,10 @@ DOMRequestIpcHelper.prototype = {
aMsg.weakRef ? cpmm.addWeakMessageListener(name, this)
: cpmm.addMessageListener(name, this);
this._listeners[name] = !!aMsg.weakRef;
this._listeners[name] = {
weakRef: !!aMsg.weakRef,
count: 1
};
});
},
@ -116,9 +121,14 @@ DOMRequestIpcHelper.prototype = {
return;
}
this._listeners[aName] ? cpmm.removeWeakMessageListener(aName, this)
: cpmm.removeMessageListener(aName, this);
delete this._listeners[aName];
// Only remove the listener really when we don't have anybody that could
// be waiting on a message.
if (!--this._listeners[aName].count) {
this._listeners[aName].weakRef ?
cpmm.removeWeakMessageListener(aName, this)
: cpmm.removeMessageListener(aName, this);
delete this._listeners[aName];
}
});
},

View File

@ -66,20 +66,22 @@
* Message listeners.
*/
function checkMessageListeners(aExpectedListeners, aCount) {
ok(true, "Checking message listeners\n" + "Expected listeners " +
JSON.stringify(aExpectedListeners) + " \nExpected count " + aCount);
info("Checking message listeners\n" + "Expected listeners " +
JSON.stringify(aExpectedListeners) + " \nExpected count " + aCount);
let count = 0;
Object.keys(dummy._listeners).forEach(function(name) {
count++;
is(aExpectedListeners[name], dummy._listeners[name],
"Message found " + name + " - Same listeners");
is(aExpectedListeners[name].weakRef, dummy._listeners[name].weakRef,
"Message found " + name + " - Same weakRef");
is(aExpectedListeners[name].count, dummy._listeners[name].count,
"Message found " + name + " - Same count");
});
is(aCount, count, "Correct number of listeners");
}
function addMessageListenersTest(aMessages, aExpectedListeners, aCount) {
dummy.addMessageListeners(aMessages);
ok(true, JSON.stringify(dummy._listeners));
info(JSON.stringify(dummy._listeners));
checkMessageListeners(aExpectedListeners, aCount);
}
@ -165,39 +167,40 @@
*/
var tests = [
function() {
ok(true, "== InitDOMRequestHelper no messages");
info("== InitDOMRequestHelper no messages");
initDOMRequestHelperTest(null);
next();
},
function() {
ok(true, "== DestroyDOMRequestHelper");
info("== DestroyDOMRequestHelper");
destroyDOMRequestHelperTest();
next();
},
function() {
ok(true, "== InitDOMRequestHelper empty array");
info("== InitDOMRequestHelper empty array");
initDOMRequestHelperTest([]);
checkMessageListeners({}, 0);
next();
},
function() {
ok(true, "== DestroyDOMRequestHelper");
info("== DestroyDOMRequestHelper");
destroyDOMRequestHelperTest();
next();
},
function() {
ok(true, "== InitDOMRequestHelper with strings array");
info("== InitDOMRequestHelper with strings array");
initDOMRequestHelperTest(["name1", "nameN"]);
checkMessageListeners({"name1": false, "nameN": false}, 2);
checkMessageListeners({"name1": {weakRef: false, count: 1},
"nameN": {weakRef: false, count: 1}}, 2);
next();
},
function() {
ok(true, "== DestroyDOMRequestHelper");
info("== DestroyDOMRequestHelper");
destroyDOMRequestHelperTest();
next();
},
function() {
ok(true, "== InitDOMRequestHelper with objects array");
info("== InitDOMRequestHelper with objects array");
initDOMRequestHelperTest([{
name: "name1",
weakRef: false
@ -205,41 +208,50 @@
name: "nameN",
weakRef: true
}]);
checkMessageListeners({"name1": false, "nameN": true}, 2);
checkMessageListeners({
"name1": {weakRef: false, count: 1},
"nameN": {weakRef: true, count: 1}
}, 2);
next();
},
function() {
ok(true, "== AddMessageListeners empty array");
addMessageListenersTest([], {"name1": false, "nameN": true}, 2);
info("== AddMessageListeners empty array");
addMessageListenersTest([], {
"name1": {weakRef: false, count: 1},
"nameN": {weakRef: true, count: 1}
}, 2);
next();
},
function() {
ok(true, "== AddMessageListeners null");
addMessageListenersTest(null, {"name1": false, "nameN": true}, 2);
info("== AddMessageListeners null");
addMessageListenersTest(null, {
"name1": {weakRef: false, count: 1},
"nameN": {weakRef: true, count: 1}
}, 2);
next();
},
function() {
ok(true, "== AddMessageListeners new listener, string only");
info("== AddMessageListeners new listener, string only");
addMessageListenersTest("name2", {
"name1": false,
"name2": false,
"nameN": true
"name1": {weakRef: false, count: 1},
"name2": {weakRef: false, count: 1},
"nameN": {weakRef: true, count: 1}
}, 3);
next();
},
function() {
ok(true, "== AddMessageListeners new listeners, strings array");
info("== AddMessageListeners new listeners, strings array");
addMessageListenersTest(["name3", "name4"], {
"name1": false,
"name2": false,
"name3": false,
"name4": false,
"nameN": true
"name1": {weakRef: false, count: 1},
"name2": {weakRef: false, count: 1},
"name3": {weakRef: false, count: 1},
"name4": {weakRef: false, count: 1},
"nameN": {weakRef: true, count: 1}
}, 5);
next();
},
function() {
ok(true, "== AddMessageListeners new listeners, objects array");
info("== AddMessageListeners new listeners, objects array");
addMessageListenersTest([{
name: "name5",
weakRef: true
@ -247,69 +259,69 @@
name: "name6",
weakRef: false
}], {
"name1": false,
"name2": false,
"name3": false,
"name4": false,
"name5": true,
"name6": false,
"nameN": true
"name1": {weakRef: false, count: 1},
"name2": {weakRef: false, count: 1},
"name3": {weakRef: false, count: 1},
"name4": {weakRef: false, count: 1},
"name5": {weakRef: true, count: 1},
"name6": {weakRef: false, count: 1},
"nameN": {weakRef: true, count: 1}
}, 7);
next();
},
function() {
ok(true, "== RemoveMessageListeners, null");
info("== RemoveMessageListeners, null");
removeMessageListenersTest(null, {
"name1": false,
"name2": false,
"name3": false,
"name4": false,
"name5": true,
"name6": false,
"nameN": true
"name1": {weakRef: false, count: 1},
"name2": {weakRef: false, count: 1},
"name3": {weakRef: false, count: 1},
"name4": {weakRef: false, count: 1},
"name5": {weakRef: true, count: 1},
"name6": {weakRef: false, count: 1},
"nameN": {weakRef: true, count: 1}
}, 7);
next();
},
function() {
ok(true, "== RemoveMessageListeners, one message");
info("== RemoveMessageListeners, one message");
removeMessageListenersTest("name1", {
"name2": false,
"name3": false,
"name4": false,
"name5": true,
"name6": false,
"nameN": true
"name2": {weakRef: false, count: 1},
"name3": {weakRef: false, count: 1},
"name4": {weakRef: false, count: 1},
"name5": {weakRef: true, count: 1},
"name6": {weakRef: false, count: 1},
"nameN": {weakRef: true, count: 1}
}, 6);
next();
},
function() {
ok(true, "== RemoveMessageListeners, array of messages");
info("== RemoveMessageListeners, array of messages");
removeMessageListenersTest(["name2", "name3"], {
"name4": false,
"name5": true,
"name6": false,
"nameN": true
"name4": {weakRef: false, count: 1},
"name5": {weakRef: true, count: 1},
"name6": {weakRef: false, count: 1},
"nameN": {weakRef: true, count: 1}
}, 4);
next();
},
function() {
ok(true, "== RemoveMessageListeners, unknown message");
info("== RemoveMessageListeners, unknown message");
removeMessageListenersTest("unknown", {
"name4": false,
"name5": true,
"name6": false,
"nameN": true
"name4": {weakRef: false, count: 1},
"name5": {weakRef: true, count: 1},
"name6": {weakRef: false, count: 1},
"nameN": {weakRef: true, count: 1}
}, 4);
next();
},
function() {
try {
ok(true, "== AddMessageListeners, same message, same kind");
info("== AddMessageListeners, same message, same kind");
addMessageListenersTest("name4", {
"name4": false,
"name5": true,
"name6": false,
"nameN": true
"name4": {weakRef: false, count: 2},
"name5": {weakRef: true, count: 1},
"name6": {weakRef: false, count: 1},
"nameN": {weakRef: true, count: 1}
}, 4);
next();
} catch (ex) {
@ -317,13 +329,13 @@
}
},
function() {
ok(true, "== AddMessageListeners, same message, different kind");
info("== AddMessageListeners, same message, different kind");
try {
addMessageListenersTest({name: "name4", weakRef: true}, {
"name4": true,
"name5": true,
"name6": false,
"nameN": true
"name4": {weakRef: false, count: 2},
"name5": {weakRef: true, count: 1},
"name6": {weakRef: false, count: 1},
"nameN": {weakRef: true, count: 1}
}, 4);
ok(false, "Should have thrown an exception");
} catch (ex) {
@ -332,14 +344,27 @@
}
},
function() {
ok(true, "== Test createRequest()");
info("== RemoveMessageListeners, message with two listeners");
try {
removeMessageListenersTest(["name4", "name5"], {
"name4": {weakRef: false, count: 1},
"name6": {weakRef: false, count: 1},
"nameN": {weakRef: true, count: 1}
}, 3);
next();
} catch (ex) {
ok(false, "Unexpected exception " + ex);
}
},
function() {
info("== Test createRequest()");
ok(DOMRequest, "DOMRequest object exists");
var req = dummy.createRequest();
ok(req instanceof DOMRequest, "Returned a DOMRequest");
next();
},
function() {
ok(true, "== Test getRequestId(), removeRequest() and getRequest()");
info("== Test getRequestId(), removeRequest() and getRequest()");
var req = dummy.createRequest();
var id = dummy.getRequestId(req);
is(typeof id, "string", "id is a string");
@ -351,7 +376,7 @@
next();
},
function() {
ok(true, "== Test createPromise()");
info("== Test createPromise()");
ok(Promise, "Promise object exists");
var promise = dummy.createPromise(function(resolve, reject) {
resolve(true);
@ -360,7 +385,7 @@
promise.then(next);
},
function() {
ok(true, "== Test getResolver()");
info("== Test getResolver()");
var id;
var resolver;
var promise = dummy.createPromise(function(resolve, reject) {
@ -376,7 +401,7 @@
});
},
function() {
ok(true, "== Test removeResolver");
info("== Test removeResolver");
var id;
var promise = dummy.createPromise(function(resolve, reject) {
var r = { resolve: resolve, reject: reject };
@ -384,7 +409,7 @@
ok(typeof id === "string", "id is a string");
var resolver = dummy.getPromiseResolver(id);
ok(true, "Got resolver " + JSON.stringify(resolver));
info("Got resolver " + JSON.stringify(resolver));
ok(resolver === r, "Resolver get succeeded");
r.resolve(true);
@ -396,7 +421,7 @@
});
},
function() {
ok(true, "== Test takeResolver");
info("== Test takeResolver");
var id;
var resolver;
var promise = dummy.createPromise(function(resolve, reject) {
@ -419,21 +444,21 @@
});
},
function() {
ok(true, "== Test window destroyed without messages and without GC");
info("== Test window destroyed without messages and without GC");
checkWindowDestruction({ gc: false }, function(uninitCalled) {
ok(uninitCalled, "uninit() should have been called");
next();
});
},
function() {
ok(true, "== Test window destroyed without messages and with GC");
info("== Test window destroyed without messages and with GC");
checkWindowDestruction({ gc: true }, function(uninitCalled) {
ok(!uninitCalled, "uninit() should NOT have been called");
next();
});
},
function() {
ok(true, "== Test window destroyed with weak messages and without GC");
info("== Test window destroyed with weak messages and without GC");
checkWindowDestruction({ messages: [{ name: "foo", weakRef: true }],
gc: false }, function(uninitCalled) {
ok(uninitCalled, "uninit() should have been called");
@ -441,7 +466,7 @@
});
},
function() {
ok(true, "== Test window destroyed with weak messages and with GC");
info("== Test window destroyed with weak messages and with GC");
checkWindowDestruction({ messages: [{ name: "foo", weakRef: true }],
gc: true }, function(uninitCalled) {
ok(!uninitCalled, "uninit() should NOT have been called");
@ -449,7 +474,7 @@
});
},
function() {
ok(true, "== Test window destroyed with strong messages and without GC");
info("== Test window destroyed with strong messages and without GC");
checkWindowDestruction({ messages: [{ name: "foo", weakRef: false }],
gc: false }, function(uninitCalled) {
ok(uninitCalled, "uninit() should have been called");
@ -457,7 +482,7 @@
});
},
function() {
ok(true, "== Test window destroyed with strong messages and with GC");
info("== Test window destroyed with strong messages and with GC");
checkWindowDestruction({ messages: [{ name: "foo", weakRef: false }],
gc: true }, function(uninitCalled) {
ok(uninitCalled, "uninit() should have been called");

View File

@ -181,6 +181,9 @@ TelephonyListener::CallStateChanged(uint32_t aServiceId,
uint32_t aCallIndex,
uint16_t aCallState,
const nsAString& aNumber,
uint16_t aNumberPresentation,
const nsAString& aName,
uint16_t aNamePresentation,
bool aIsOutgoing,
bool aIsEmergency,
bool aIsConference,
@ -200,6 +203,9 @@ TelephonyListener::EnumerateCallState(uint32_t aServiceId,
uint32_t aCallIndex,
uint16_t aCallState,
const nsAString_internal& aNumber,
uint16_t aNumberPresentation,
const nsAString& aName,
uint16_t aNamePresentation,
bool aIsOutgoing,
bool aIsEmergency,
bool aIsConference,
@ -270,7 +276,10 @@ TelephonyListener::NotifyConferenceError(const nsAString& aName,
NS_IMETHODIMP
TelephonyListener::NotifyCdmaCallWaiting(uint32_t aServiceId,
const nsAString& aNumber)
const nsAString& aNumber,
uint16_t aNumberPresentation,
const nsAString& aName,
uint16_t aNamePresentation)
{
BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
NS_ENSURE_TRUE(hfp, NS_ERROR_FAILURE);

View File

@ -50,12 +50,12 @@ USING_BLUETOOTH_NAMESPACE
static nsString sAdapterBdAddress;
static nsString sAdapterBdName;
static InfallibleTArray<nsString> sAdapterBondedAddressArray;
static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sChangeAdapterStateRunnableArray;
// Static variables below should only be used on *main thread*
static const bt_interface_t* sBtInterface;
static nsTArray<nsRefPtr<BluetoothProfileController> > sControllerArray;
static nsTArray<int> sRequestedDeviceCountArray;
static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sChangeAdapterStateRunnableArray;
static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sChangeDiscoveryRunnableArray;
static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sSetPropertyRunnableArray;
static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sGetDeviceRunnableArray;
@ -295,6 +295,27 @@ PlayStatusStringToControlPlayStatus(const nsAString& aPlayStatus)
return playStatus;
}
class AdapterStateChangedCallbackTask MOZ_FINAL : public nsRunnable
{
public:
NS_IMETHOD
Run()
{
MOZ_ASSERT(NS_IsMainThread());
// Resolve promise if existed
if (!sChangeAdapterStateRunnableArray.IsEmpty()) {
BluetoothValue values(true);
DispatchBluetoothReply(sChangeAdapterStateRunnableArray[0],
values, EmptyString());
sChangeAdapterStateRunnableArray.RemoveElementAt(0);
}
return NS_OK;
}
};
/**
* Bluedroid HAL callback functions
*
@ -327,13 +348,8 @@ AdapterStateChangeCallback(bt_state_t aStatus)
return;
}
// Resolve promise if existed
if(!sChangeAdapterStateRunnableArray.IsEmpty()) {
DispatchBluetoothReply(sChangeAdapterStateRunnableArray[0],
BluetoothValue(true),
EmptyString());
sChangeAdapterStateRunnableArray.RemoveElementAt(0);
}
// Redirect to main thread to avoid racing problem
NS_DispatchToMainThread(new AdapterStateChangedCallbackTask());
}
class AdapterPropertiesCallbackTask MOZ_FINAL : public nsRunnable

View File

@ -640,12 +640,12 @@ BrowserElementParent.prototype = {
if (aStatusCode == Cr.NS_OK) {
// Everything looks great.
debug('DownloadListener - Download Successful.');
this.services.DOMRequest.fireSuccess(this.req, aStatusCode);
Services.DOMRequest.fireSuccess(req, aStatusCode);
}
else {
// In case of failure, we'll simply return the failure status code.
debug('DownloadListener - Download Failed!');
this.services.DOMRequest.fireError(this.req, aStatusCode);
Services.DOMRequest.fireError(req, aStatusCode);
}
if (this.extListener) {

View File

@ -59,30 +59,18 @@ function handleTechnologyDiscoveredRE0ForP2PRegFailure(msg) {
}
}
function activateRE(re) {
let deferred = Promise.defer();
let cmd = "nfc nci rf_intf_activated_ntf " + re;
emulator.run(cmd, function(result) {
is(result.pop(), "OK", "check activation of RE" + re);
deferred.resolve();
});
return deferred.promise;
}
function testPeerReady() {
window.navigator.mozSetMessageHandler(
"nfc-manager-tech-discovered", handleTechnologyDiscoveredRE0);
toggleNFC(true).then(() => activateRE(0));
toggleNFC(true).then(() => emulator.activateRE(0));
}
function testCheckP2PRegFailure() {
window.navigator.mozSetMessageHandler(
"nfc-manager-tech-discovered", handleTechnologyDiscoveredRE0ForP2PRegFailure);
toggleNFC(true).then(() => activateRE(0));
toggleNFC(true).then(() => emulator.activateRE(0));
}
function testCheckNfcPeerObjForInvalidToken() {

View File

@ -35,8 +35,8 @@ function testUrlTagDiscover(re) {
});
toggleNFC(true)
.then(() => setTagData(re, flag, tnf, btoa(type), btoa(payload)))
.then(() => activateRE(re));
.then(() => emulator.setTagData(re, flag, tnf, btoa(type), btoa(payload)))
.then(() => emulator.activateRE(re));
}
function testUrlT1TDiscover() {

View File

@ -2075,7 +2075,7 @@ RadioInterface.prototype = {
gTelephonyService.notifyConferenceCallStateChanged(message.state);
break;
case "cdmaCallWaiting":
gTelephonyService.notifyCdmaCallWaiting(this.clientId, message.number);
gTelephonyService.notifyCdmaCallWaiting(this.clientId, message.waitingCall);
break;
case "suppSvcNotification":
gTelephonyService.notifySupplementaryService(this.clientId,

View File

@ -364,10 +364,24 @@ this.GECKO_CARD_TYPE = [
"isim"
];
this.NETWORK_STATE_UNKNOWN = "unknown";
this.NETWORK_STATE_AVAILABLE = "available";
this.NETWORK_STATE_CONNECTED = "connected";
this.NETWORK_STATE_FORBIDDEN = "forbidden";
// Used for QUERY_AVAILABLE_NETWORKS status.
this.QAN_STATE_UNKNOWN = "unknown";
this.QAN_STATE_AVAILABLE = "available";
this.QAN_STATE_CURRENT = "current";
this.QAN_STATE_FORBIDDEN = "forbidden";
// Must be in sync with MobileNetworkState of MozMobileNetworkInfo.webidl
this.GECKO_QAN_STATE_UNKNOWN = null;
this.GECKO_QAN_STATE_AVAILABLE = "available";
this.GECKO_QAN_STATE_CONNECTED = "connected";
this.GECKO_QAN_STATE_FORBIDDEN = "forbidden";
this.RIL_QAN_STATE_TO_GECKO_STATE = {};
this.RIL_QAN_STATE_TO_GECKO_STATE[this.QAN_STATE_UNKNOWN] = this.GECKO_QAN_STATE_UNKNOWN;
this.RIL_QAN_STATE_TO_GECKO_STATE[this.QAN_STATE_AVAILABLE] = this.GECKO_QAN_STATE_AVAILABLE;
this.RIL_QAN_STATE_TO_GECKO_STATE[this.QAN_STATE_CURRENT] = this.GECKO_QAN_STATE_CONNECTED;
this.RIL_QAN_STATE_TO_GECKO_STATE[this.QAN_STATE_FORBIDDEN] = this.GECKO_QAN_STATE_FORBIDDEN;
this.NETWORK_SELECTION_MODE_AUTOMATIC = 0;
this.NETWORK_SELECTION_MODE_MANUAL = 1;
@ -2395,9 +2409,6 @@ this.GECKO_NETWORK_STATE_CONNECTED = 1;
this.GECKO_NETWORK_STATE_DISCONNECTING = 2;
this.GECKO_NETWORK_STATE_DISCONNECTED = 3;
// Used for QUERY_AVAILABLE_NETWORKS status of "unknown"
this.GECKO_QAN_STATE_UNKNOWN = null;
this.CALL_FAIL_UNOBTAINABLE_NUMBER = 1;
this.CALL_FAIL_NORMAL = 16;
this.CALL_FAIL_BUSY = 17;

View File

@ -4461,13 +4461,8 @@ RilObject.prototype = {
}
let state = strings[i + 3];
if (state === NETWORK_STATE_UNKNOWN) {
// TODO: looks like this might conflict in style with
// GECKO_NETWORK_STYLE_UNKNOWN / nsINetworkManager
state = GECKO_QAN_STATE_UNKNOWN;
}
network.state = RIL_QAN_STATE_TO_GECKO_STATE[state];
network.state = state;
networks.push(network);
}
return networks;
@ -5529,7 +5524,7 @@ RilObject.prototype[REQUEST_GET_CURRENT_CALLS] = function REQUEST_GET_CURRENT_CA
if (RILQUIRKS_CALLSTATE_EXTRA_UINT32) {
Buf.readInt32();
}
call.number = Buf.readString(); //TODO munge with TOA
call.number = Buf.readString();
call.numberPresentation = Buf.readInt32(); // CALL_PRESENTATION_*
call.name = Buf.readString();
call.namePresentation = Buf.readInt32();
@ -6860,7 +6855,7 @@ RilObject.prototype[UNSOLICITED_CDMA_CALL_WAITING] = function UNSOLICITED_CDMA_C
call.alertPitch = Buf.readInt32();
call.signal = Buf.readInt32();
this.sendChromeMessage({rilMessageType: "cdmaCallWaiting",
number: call.number});
waitingCall: call});
};
RilObject.prototype[UNSOLICITED_CDMA_OTA_PROVISION_STATUS] = function UNSOLICITED_CDMA_OTA_PROVISION_STATUS() {
let status = this.context.Buf.readInt32List()[0];

View File

@ -25,6 +25,7 @@
#include "CallsList.h"
#include "TelephonyCall.h"
#include "TelephonyCallGroup.h"
#include "TelephonyCallId.h"
using namespace mozilla::dom;
using mozilla::ErrorResult;
@ -276,6 +277,9 @@ Telephony::CreateNewDialingCall(uint32_t aServiceId, const nsAString& aNumber,
{
nsRefPtr<TelephonyCall> call =
TelephonyCall::Create(this, aServiceId, aNumber,
nsITelephonyService::CALL_PRESENTATION_ALLOWED,
EmptyString(),
nsITelephonyService::CALL_PRESENTATION_ALLOWED,
nsITelephonyService::CALL_STATE_DIALING, aCallIndex);
NS_ASSERTION(call, "This should never fail!");
@ -474,8 +478,10 @@ Telephony::EventListenerAdded(nsIAtom* aType)
NS_IMETHODIMP
Telephony::CallStateChanged(uint32_t aServiceId, uint32_t aCallIndex,
uint16_t aCallState, const nsAString& aNumber,
bool aIsOutgoing, bool aIsEmergency,
bool aIsConference, bool aIsSwitchable, bool aIsMergeable)
uint16_t aNumberPresentation, const nsAString& aName,
uint16_t aNamePresentation, bool aIsOutgoing,
bool aIsEmergency, bool aIsConference,
bool aIsSwitchable, bool aIsMergeable)
{
nsRefPtr<TelephonyCall> modifiedCall
= GetCallFromEverywhere(aServiceId, aCallIndex);
@ -520,9 +526,10 @@ Telephony::CallStateChanged(uint32_t aServiceId, uint32_t aCallIndex,
// Didn't find this call in mCalls or mGroup. Create a new call.
nsRefPtr<TelephonyCall> call =
TelephonyCall::Create(this, aServiceId, aNumber, aCallState, aCallIndex,
aIsEmergency, aIsConference, aIsSwitchable,
aIsMergeable);
TelephonyCall::Create(this, aServiceId, aNumber, aNumberPresentation,
aName, aNamePresentation, aCallState, aCallIndex,
aIsEmergency, aIsConference, aIsSwitchable,
aIsMergeable);
NS_ASSERTION(call, "This should never fail!");
NS_ASSERTION(aIsConference ? mGroup->CallsArray().Contains(call) :
@ -564,8 +571,10 @@ Telephony::EnumerateCallStateComplete()
NS_IMETHODIMP
Telephony::EnumerateCallState(uint32_t aServiceId, uint32_t aCallIndex,
uint16_t aCallState, const nsAString& aNumber,
bool aIsOutgoing, bool aIsEmergency,
bool aIsConference, bool aIsSwitchable, bool aIsMergeable)
uint16_t aNumberPresentation, const nsAString& aName,
uint16_t aNamePresentation, bool aIsOutgoing,
bool aIsEmergency, bool aIsConference,
bool aIsSwitchable, bool aIsMergeable)
{
nsRefPtr<TelephonyCall> call;
@ -580,7 +589,8 @@ Telephony::EnumerateCallState(uint32_t aServiceId, uint32_t aCallIndex,
}
// Didn't know anything about this call before now.
call = TelephonyCall::Create(this, aServiceId, aNumber, aCallState,
call = TelephonyCall::Create(this, aServiceId, aNumber, aNumberPresentation,
aName, aNamePresentation, aCallState,
aCallIndex, aIsEmergency, aIsConference,
aIsSwitchable, aIsMergeable);
NS_ASSERTION(call, "This should never fail!");
@ -642,14 +652,20 @@ Telephony::NotifyError(uint32_t aServiceId,
}
NS_IMETHODIMP
Telephony::NotifyCdmaCallWaiting(uint32_t aServiceId, const nsAString& aNumber)
Telephony::NotifyCdmaCallWaiting(uint32_t aServiceId, const nsAString& aNumber,
uint16_t aNumberPresentation,
const nsAString& aName,
uint16_t aNamePresentation)
{
MOZ_ASSERT(mCalls.Length() == 1);
nsRefPtr<TelephonyCall> callToNotify = mCalls[0];
MOZ_ASSERT(callToNotify && callToNotify->ServiceId() == aServiceId);
callToNotify->UpdateSecondNumber(aNumber);
nsRefPtr<TelephonyCallId> id =
new TelephonyCallId(GetOwner(), aNumber, aNumberPresentation, aName,
aNamePresentation);
callToNotify->UpdateSecondId(id);
DispatchCallEvent(NS_LITERAL_STRING("callschanged"), callToNotify);
return NS_OK;
}

View File

@ -19,25 +19,29 @@ using mozilla::ErrorResult;
// static
already_AddRefed<TelephonyCall>
TelephonyCall::Create(Telephony* aTelephony, uint32_t aServiceId,
const nsAString& aNumber, uint16_t aCallState,
uint32_t aCallIndex, bool aEmergency, bool aIsConference,
bool aSwitchable, bool aMergeable)
const nsAString& aNumber, uint16_t aNumberPresentation,
const nsAString& aName, uint16_t aNamePresentation,
uint16_t aCallState, uint32_t aCallIndex, bool aEmergency,
bool aIsConference, bool aSwitchable, bool aMergeable)
{
NS_ASSERTION(aTelephony, "Null pointer!");
NS_ASSERTION(!aNumber.IsEmpty(), "Empty number!");
NS_ASSERTION(aCallIndex >= 1, "Invalid call index!");
nsRefPtr<TelephonyCall> call = new TelephonyCall(aTelephony->GetOwner());
nsRefPtr<TelephonyCallId> id = new TelephonyCallId(aTelephony->GetOwner(),
aNumber, aNumberPresentation,
aName, aNamePresentation);
call->mTelephony = aTelephony;
call->mServiceId = aServiceId;
call->mNumber = aNumber;
call->mCallIndex = aCallIndex;
call->mError = nullptr;
call->mEmergency = aEmergency;
call->mGroup = aIsConference ? aTelephony->ConferenceGroup() : nullptr;
call->mSwitchable = aSwitchable;
call->mMergeable = aMergeable;
call->mId = id;
call->ChangeStateInternal(aCallState, false);
@ -187,7 +191,9 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(TelephonyCall,
DOMEventTargetHelper,
mTelephony,
mError,
mGroup);
mGroup,
mId,
mSecondId);
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TelephonyCall)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
@ -197,6 +203,20 @@ NS_IMPL_RELEASE_INHERITED(TelephonyCall, DOMEventTargetHelper)
// TelephonyCall WebIDL
already_AddRefed<TelephonyCallId>
TelephonyCall::Id() const
{
nsRefPtr<TelephonyCallId> id = mId;
return id.forget();
}
already_AddRefed<TelephonyCallId>
TelephonyCall::GetSecondId() const
{
nsRefPtr<TelephonyCallId> id = mSecondId;
return id.forget();
}
already_AddRefed<DOMError>
TelephonyCall::GetError() const
{
@ -272,7 +292,7 @@ TelephonyCall::Hold(ErrorResult& aRv)
return;
}
if (!mSecondNumber.IsEmpty()) {
if (mSecondId) {
// No state transition when we switch two numbers within one TelephonyCall
// object. Otherwise, the state here will be inconsistent with the backend
// RIL and will never be right.

View File

@ -11,6 +11,8 @@
#include "mozilla/dom/DOMError.h"
#include "TelephonyCallId.h"
class nsPIDOMWindow;
namespace mozilla {
@ -21,9 +23,10 @@ class TelephonyCall MOZ_FINAL : public DOMEventTargetHelper
nsRefPtr<Telephony> mTelephony;
nsRefPtr<TelephonyCallGroup> mGroup;
nsRefPtr<TelephonyCallId> mId;
nsRefPtr<TelephonyCallId> mSecondId;
uint32_t mServiceId;
nsString mNumber;
nsString mSecondNumber;
nsString mState;
bool mEmergency;
nsRefPtr<DOMError> mError;
@ -39,7 +42,6 @@ public:
NS_REALLY_FORWARD_NSIDOMEVENTTARGET(DOMEventTargetHelper)
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TelephonyCall,
DOMEventTargetHelper)
friend class Telephony;
nsPIDOMWindow*
@ -53,17 +55,11 @@ public:
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
// WebIDL
void
GetNumber(nsString& aNumber) const
{
aNumber.Assign(mNumber);
}
already_AddRefed<TelephonyCallId>
Id() const;
void
GetSecondNumber(nsString& aSecondNumber) const
{
aSecondNumber.Assign(mSecondNumber);
}
already_AddRefed<TelephonyCallId>
GetSecondId() const;
void
GetState(nsString& aState) const
@ -122,7 +118,9 @@ public:
static already_AddRefed<TelephonyCall>
Create(Telephony* aTelephony, uint32_t aServiceId,
const nsAString& aNumber, uint16_t aCallState, uint32_t aCallIndex,
const nsAString& aNumber, uint16_t aNumberPresentation,
const nsAString& aName, uint16_t aNamePresentation,
uint16_t aCallState, uint32_t aCallIndex,
bool aEmergency = false, bool aIsConference = false,
bool aSwitchable = true, bool aMergeable = true);
@ -156,12 +154,6 @@ public:
mEmergency = aEmergency;
}
void
UpdateSecondNumber(const nsAString& aNumber)
{
mSecondNumber = aNumber;
}
void
UpdateSwitchable(bool aSwitchable) {
mSwitchable = aSwitchable;
@ -172,6 +164,11 @@ public:
mMergeable = aMergeable;
}
void
UpdateSecondId(TelephonyCallId* aId) {
mSecondId = aId;
}
void
NotifyError(const nsAString& aError);

View File

@ -0,0 +1,77 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "TelephonyCallId.h"
#include "nsITelephonyService.h"
namespace mozilla {
namespace dom {
TelephonyCallId::TelephonyCallId(nsPIDOMWindow* aWindow,
const nsAString& aNumber,
uint16_t aNumberPresentation,
const nsAString& aName,
uint16_t aNamePresentation)
: mWindow(aWindow), mNumber(aNumber), mNumberPresentation(aNumberPresentation),
mName(aName), mNamePresentation(aNamePresentation)
{
SetIsDOMBinding();
}
TelephonyCallId::~TelephonyCallId()
{
}
JSObject*
TelephonyCallId::WrapObject(JSContext* aCx)
{
return TelephonyCallIdBinding::Wrap(aCx, this);
}
CallIdPresentation
TelephonyCallId::GetPresentationStr(uint16_t aPresentation) const
{
switch (aPresentation) {
case nsITelephonyService::CALL_PRESENTATION_ALLOWED:
return CallIdPresentation::Allowed;
case nsITelephonyService::CALL_PRESENTATION_RESTRICTED:
return CallIdPresentation::Restricted;
case nsITelephonyService::CALL_PRESENTATION_UNKNOWN:
return CallIdPresentation::Unknown;
case nsITelephonyService::CALL_PRESENTATION_PAYPHONE:
return CallIdPresentation::Payphone;
default:
MOZ_ASSUME_UNREACHABLE("Bad presentation!");
}
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TelephonyCallId, mWindow)
NS_IMPL_CYCLE_COLLECTING_ADDREF(TelephonyCallId)
NS_IMPL_CYCLE_COLLECTING_RELEASE(TelephonyCallId)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TelephonyCallId)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
// WebIDL
CallIdPresentation
TelephonyCallId::NumberPresentation() const
{
return GetPresentationStr(mNumberPresentation);
}
CallIdPresentation
TelephonyCallId::NamePresentation() const
{
return GetPresentationStr(mNamePresentation);
}
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,76 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_TelephonyCallId_h
#define mozilla_dom_TelephonyCallId_h
#include "mozilla/dom/TelephonyCallIdBinding.h"
#include "mozilla/dom/telephony/TelephonyCommon.h"
#include "nsWrapperCache.h"
class nsPIDOMWindow;
namespace mozilla {
namespace dom {
class TelephonyCallId MOZ_FINAL : public nsISupports,
public nsWrapperCache
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TelephonyCallId)
TelephonyCallId(nsPIDOMWindow* aWindow, const nsAString& aNumber,
uint16_t aNumberPresentation, const nsAString& aName,
uint16_t aNamePresentation);
nsPIDOMWindow*
GetParentObject() const
{
return mWindow;
}
virtual JSObject*
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
// WebIDL
void
GetNumber(nsString& aNumber) const
{
aNumber.Assign(mNumber);
}
CallIdPresentation
NumberPresentation() const;
void
GetName(nsString& aName) const
{
aName.Assign(mName);
}
CallIdPresentation
NamePresentation() const;
private:
~TelephonyCallId();
nsCOMPtr<nsPIDOMWindow> mWindow;
nsString mNumber;
uint16_t mNumberPresentation;
nsString mName;
uint16_t mNamePresentation;
CallIdPresentation
GetPresentationStr(uint16_t aPresentation) const;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_TelephonyCallId_h

View File

@ -361,7 +361,9 @@ TelephonyService.prototype = {
for (let i = 0, indexes = Object.keys(calls); i < indexes.length; ++i) {
let call = calls[indexes[i]];
aListener.enumerateCallState(call.clientId, call.callIndex,
call.state, call.number, call.isOutgoing,
call.state, call.number,
call.numberPresentation, call.name,
call.namePresentation, call.isOutgoing,
call.isEmergency, call.isConference,
call.isSwitchable, call.isMergeable);
}
@ -729,6 +731,9 @@ TelephonyService.prototype = {
aCall.callIndex,
aCall.state,
aCall.number,
aCall.numberPresentation,
aCall.name,
aCall.namePresentation,
aCall.isOutgoing,
aCall.isEmergency,
aCall.isConference,
@ -793,6 +798,13 @@ TelephonyService.prototype = {
call.isMergeable = aCall.isMergeable != null ?
aCall.isMergeable : true;
call.numberPresentation = aCall.numberPresentation != null ?
aCall.numberPresentation : nsITelephonyService.CALL_PRESENTATION_ALLOWED;
call.name = aCall.name != null ?
aCall.name : "";
call.namePresentation = aCall.namePresentation != null ?
aCall.namePresentation : nsITelephonyService.CALL_PRESENTATION_ALLOWED;
this._currentCalls[aClientId][aCall.callIndex] = call;
}
@ -800,6 +812,9 @@ TelephonyService.prototype = {
call.callIndex,
call.state,
call.number,
call.numberPresentation,
call.name,
call.namePresentation,
call.isOutgoing,
call.isEmergency,
call.isConference,
@ -807,7 +822,7 @@ TelephonyService.prototype = {
call.isMergeable]);
},
notifyCdmaCallWaiting: function(aClientId, aNumber) {
notifyCdmaCallWaiting: function(aClientId, aCall) {
// We need to acquire a CPU wake lock to avoid the system falling into
// the sleep mode when the RIL handles the incoming call.
this._acquireCallRingWakeLock();
@ -818,7 +833,11 @@ TelephonyService.prototype = {
// call comes after a 3way call.
this.notifyCallDisconnected(aClientId, call);
}
this._notifyAllListeners("notifyCdmaCallWaiting", [aClientId, aNumber]);
this._notifyAllListeners("notifyCdmaCallWaiting", [aClientId,
aCall.number,
aCall.numberPresentation,
aCall.name,
aCall.namePresentation]);
},
notifySupplementaryService: function(aClientId, aCallIndex, aNotification) {

View File

@ -39,7 +39,7 @@ child:
NotifyCallStateChanged(uint32_t aClientId, IPCCallStateData aData);
NotifyCdmaCallWaiting(uint32_t aClientId, nsString aNumber);
NotifyCdmaCallWaiting(uint32_t aClientId, IPCCdmaWaitingCallData aData);
NotifyConferenceCallStateChanged(uint16_t aCallState);

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