Merge m-c to b2g-inbound. a=merge

This commit is contained in:
Ryan VanderMeulen 2014-09-03 16:41:25 -04:00
commit 12be16d588
795 changed files with 10803 additions and 12804 deletions

View File

@ -177,5 +177,5 @@ def js
end
def ft
call nsFrame::DumpFrameTree($arg0)
call $arg0->DumpFrameTree()
end

View File

@ -21,7 +21,10 @@ class TableAccessible;
class xpcAccessibleTable
{
public:
explicit xpcAccessibleTable(mozilla::a11y::TableAccessible* aTable) : mTable(aTable) { }
explicit xpcAccessibleTable(TableAccessible* aTable) :
mTable(aTable)
{
}
nsresult GetCaption(nsIAccessible** aCaption);
nsresult GetSummary(nsAString& aSummary);

View File

@ -25,8 +25,10 @@ class TableCellAccessible;
class xpcAccessibleTableCell
{
public:
explicit xpcAccessibleTableCell(mozilla::a11y::TableCellAccessible* aTableCell) :
mTableCell(aTableCell) { }
explicit xpcAccessibleTableCell(TableCellAccessible* aTableCell) :
mTableCell(aTableCell)
{
}
nsresult GetTable(nsIAccessibleTable** aTable);
nsresult GetColumnIndex(int32_t* aColIdx);

View File

@ -7,22 +7,27 @@ module.metadata = {
};
const { Cc, Ci, Cu } = require('chrome');
const { isNative } = require('@loader/options');
const { rootURI, metadata, isNative } = require('@loader/options');
const { id, loadReason } = require('../self');
const { descriptor, Sandbox, evaluate, main, resolveURI } = require('toolkit/loader');
const { once } = require('../system/events');
const { exit, env, staticArgs } = require('../system');
const { when: unload } = require('../system/unload');
const { loadReason } = require('../self');
const { rootURI, metadata } = require("@loader/options");
const globals = require('../system/globals');
const xulApp = require('../system/xul-app');
const { id } = require('sdk/self');
const { get } = require('../preferences/service');
const appShellService = Cc['@mozilla.org/appshell/appShellService;1'].
getService(Ci.nsIAppShellService);
const { preferences } = metadata;
const Startup = Cu.import("resource://gre/modules/sdk/system/Startup.js", {}).exports;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyGetter(this, "BrowserToolboxProcess", function () {
return Cu.import("resource:///modules/devtools/ToolboxProcess.jsm", {}).
BrowserToolboxProcess;
});
// Initializes default preferences
function setDefaultPrefs(prefsURI) {
const prefs = Cc['@mozilla.org/preferences-service;1'].
@ -102,7 +107,9 @@ function run(options) {
// native-options does stuff directly with preferences key from package.json
if (preferences && preferences.length > 0) {
try {
require('../preferences/native-options').enable({ preferences: preferences, id: id });
require('../preferences/native-options').
enable({ preferences: preferences, id: id }).
catch(console.exception);
}
catch (error) {
console.exception(error);
@ -141,7 +148,6 @@ function run(options) {
unload(program.onUnload);
if (typeof(program.main) === 'function') {
program.main({
loadReason: loadReason,
staticArgs: staticArgs
@ -150,6 +156,10 @@ function run(options) {
quit: exit
});
}
if (get("extensions." + id + ".sdk.debug.show", false)) {
BrowserToolboxProcess.init({ addonID: id });
}
} catch (error) {
console.exception(error);
throw error;

View File

@ -55,6 +55,10 @@ DEFAULT_NO_CONNECTIONS_PREFS = {
# Disable app update
'app.update.enabled' : False,
# Disable about:newtab content fetch and ping
'browser.newtabpage.directory.source': 'data:application/json,{"jetpack":1}',
'browser.newtabpage.directory.ping': '',
# Point update checks to a nonexistent local URL for fast failures.
'extensions.update.url' : 'http://localhost/extensions-dummy/updateURL',
'extensions.blocklist.url' : 'http://localhost/extensions-dummy/blocklistURL',

View File

@ -0,0 +1,17 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
const { Cu } = require('chrome');
const self = require('sdk/self');
const { AddonManager } = Cu.import('resource://gre/modules/AddonManager.jsm', {});
exports.testContributors = function(assert, done) {
AddonManager.getAddonByID(self.id, (addon) => {
assert.equal(addon.creator.name, 'test <test@mozilla.com>', '< and > characters work');
done();
});
}
require('sdk/test/runner').runTestsFromModule(module);

View File

@ -0,0 +1,4 @@
{
"id": "test-addon-author-email@jetpack",
"author": "test <test@mozilla.com>"
}

View File

@ -76,7 +76,7 @@ exports['test `load` events'] = function(assert, done) {
});
};
exports['test removeing listeners'] = function(assert, done) {
exports['test removing listeners'] = function(assert, done) {
Loader({
onLoad: function(window) {
assert.equal(window, this._window, 'windows should match');

View File

@ -7,7 +7,6 @@ support-files =
invalid.json
[browser_sdk_loader_sdk_modules.js]
[browser_sdk_loader_sdk_gui_modules.js]
skip-if = e10s # Bug ?????? - test times out.
[browser_sdk_loader_jsm_modules.js]
[browser_sdk_loader_js_modules.js]
[browser_sdk_loader_json.js]

View File

@ -293,6 +293,7 @@
@BINPATH@/components/spellchecker.xpt
@BINPATH@/components/storage.xpt
@BINPATH@/components/telemetry.xpt
@BINPATH@/components/toolkit_filewatcher.xpt
@BINPATH@/components/toolkit_finalizationwitness.xpt
@BINPATH@/components/toolkit_formautofill.xpt
@BINPATH@/components/toolkit_osfile.xpt

View File

@ -10,18 +10,6 @@
* Tab previews utility, produces thumbnails
*/
var tabPreviews = {
aspectRatio: 0.5625, // 16:9
get width() {
delete this.width;
return this.width = Math.ceil(screen.availWidth / 5.75);
},
get height() {
delete this.height;
return this.height = Math.round(this.width * this.aspectRatio);
},
init: function tabPreviews_init() {
if (this._selectedTab)
return;
@ -29,6 +17,12 @@ var tabPreviews = {
gBrowser.tabContainer.addEventListener("TabSelect", this, false);
gBrowser.tabContainer.addEventListener("SSTabRestored", this, false);
let screenManager = Cc["@mozilla.org/gfx/screenmanager;1"]
.getService(Ci.nsIScreenManager);
let left = {}, top = {}, width = {}, height = {};
screenManager.primaryScreen.GetRectDisplayPix(left, top, width, height);
this.aspectRatio = height.value / width.value;
},
get: function tabPreviews_get(aTab) {
@ -52,31 +46,35 @@ var tabPreviews = {
return this.capture(aTab, !aTab.hasAttribute("busy"));
},
capture: function tabPreviews_capture(aTab, aStore) {
var thumbnail = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
thumbnail.mozOpaque = true;
thumbnail.height = this.height;
thumbnail.width = this.width;
capture: function tabPreviews_capture(aTab, aShouldCache) {
let browser = aTab.linkedBrowser;
let uri = browser.currentURI.spec;
// drawWindow doesn't yet work with e10s (bug 698371)
if (gMultiProcessBrowser)
return thumbnail;
// FIXME: The gBrowserThumbnails._shouldCapture determines whether
// thumbnails should be written to disk. This should somehow be part
// of the PageThumbs API. (bug 1062414)
if (aShouldCache &&
gBrowserThumbnails._shouldCapture(browser)) {
let img = new Image;
var ctx = thumbnail.getContext("2d");
var win = aTab.linkedBrowser.contentWindow;
var snippetWidth = win.innerWidth * .6;
var scale = this.width / snippetWidth;
ctx.scale(scale, scale);
ctx.drawWindow(win, win.scrollX, win.scrollY,
snippetWidth, snippetWidth * this.aspectRatio, "rgb(255,255,255)");
PageThumbs.captureAndStore(browser, function () {
img.src = PageThumbs.getThumbnailURL(uri);
});
if (aStore &&
aTab.linkedBrowser /* bug 795608: the tab may got removed while drawing the thumbnail */) {
aTab.__thumbnail = thumbnail;
aTab.__thumbnail_lastURI = aTab.linkedBrowser.currentURI.spec;
aTab.__thumbnail = img;
aTab.__thumbnail_lastURI = uri;
return img;
}
return thumbnail;
let canvas = PageThumbs.createCanvas(window);
if (aShouldCache) {
aTab.__thumbnail = canvas;
aTab.__thumbnail_lastURI = uri;
}
PageThumbs.captureToCanvas(aTab.linkedBrowser.contentWindow, canvas);
return canvas;
},
handleEvent: function tabPreviews_handleEvent(event) {
@ -182,8 +180,7 @@ var ctrlTab = {
get isOpen () this.panel.state == "open" || this.panel.state == "showing" || this._timer,
get tabCount () this.tabList.length,
get tabPreviewCount () Math.min(this.previews.length - 1, this.tabCount),
get canvasWidth () Math.min(tabPreviews.width,
Math.ceil(screen.availWidth * .85 / this.tabPreviewCount)),
get canvasWidth () Math.ceil(screen.availWidth * .85 / this.tabPreviewCount),
get canvasHeight () Math.round(this.canvasWidth * tabPreviews.aspectRatio),
get tabList () {
@ -505,6 +502,15 @@ var ctrlTab = {
}
},
filterForThumbnailExpiration: function (aCallback) {
let urls = [];
let previewCount = this.tabPreviewCount;
for (let i = 0; i < previewCount; i++)
urls.push(this.tabList[i].linkedBrowser.currentURI.spec);
aCallback(urls);
},
_initRecentlyUsedTabs: function () {
this._recentlyUsedTabs =
Array.filter(gBrowser.tabs, tab => !tab.closing)
@ -525,6 +531,11 @@ var ctrlTab = {
document[toggleEventListener]("keypress", this, false);
gBrowser.mTabBox.handleCtrlTab = !enable;
if (enable)
PageThumbs.addExpirationFilter(this);
else
PageThumbs.removeExpirationFilter(this);
// If we're not running, hide the "Show All Tabs" menu item,
// as Shift+Ctrl+Tab will be handled by the tab bar.
document.getElementById("menu_showAllTabs").hidden = !enable;

View File

@ -103,7 +103,9 @@ let gBrowserThumbnails = {
},
_capture: function Thumbnails_capture(aBrowser) {
if (this._shouldCapture(aBrowser))
// Only capture about:newtab top sites.
if (this._topSiteURLs.indexOf(aBrowser.currentURI.spec) >= 0 &&
this._shouldCapture(aBrowser))
PageThumbs.captureAndStoreIfStale(aBrowser);
},
@ -121,15 +123,12 @@ let gBrowserThumbnails = {
this._timeouts.set(aBrowser, timeout);
},
// FIXME: This should be part of the PageThumbs API. (bug 1062414)
_shouldCapture: function Thumbnails_shouldCapture(aBrowser) {
// Capture only if it's the currently selected tab.
if (aBrowser != gBrowser.selectedBrowser)
return false;
// Only capture about:newtab top sites.
if (this._topSiteURLs.indexOf(aBrowser.currentURI.spec) < 0)
return false;
// Don't capture in per-window private browsing mode.
if (PrivateBrowsingUtils.isWindowPrivate(window))
return false;

View File

@ -672,33 +672,17 @@ var gPopupBlockerObserver = {
}
};
function gKeywordURIFixup(fixupInfo, topic, data) {
fixupInfo.QueryInterface(Ci.nsIURIFixupInfo);
function gKeywordURIFixup({ target: browser, data: fixupInfo }) {
let deserializeURI = (spec) => spec ? makeURI(spec) : null;
// We get called irrespective of whether we did a keyword search, or
// whether the original input would be vaguely interpretable as a URL,
// so figure that out first.
let alternativeURI = fixupInfo.fixedURI;
let alternativeURI = deserializeURI(fixupInfo.fixedURI);
if (!fixupInfo.fixupUsedKeyword || !alternativeURI) {
return;
}
// We should have a document loader...
let docshellRef = fixupInfo.consumer;
try {
docshellRef.QueryInterface(Ci.nsIDocumentLoader);
} catch (ex) {
return;
}
if (!docshellRef.document)
return;
// ... from which we can deduce the browser
let browser = gBrowser.getBrowserForDocument(docshellRef.document);
if (!browser)
return;
// At this point we're still only just about to load this URI.
// When the async DNS lookup comes back, we may be in any of these states:
// 1) still on the previous URI, waiting for the preferredURI (keyword
@ -708,6 +692,7 @@ function gKeywordURIFixup(fixupInfo, topic, data) {
// We keep track of the currentURI to detect case (1) in the DNS lookup
// callback.
let previousURI = browser.currentURI;
let preferredURI = deserializeURI(fixupInfo.preferredURI);
// now swap for a weak ref so we don't hang on to browser needlessly
// even if the DNS query takes forever
@ -738,7 +723,7 @@ function gKeywordURIFixup(fixupInfo, topic, data) {
let currentURI = browser.currentURI;
// If we're in case (3) (see above), don't show an info bar.
if (!currentURI.equals(previousURI) &&
!currentURI.equals(fixupInfo.preferredURI)) {
!currentURI.equals(preferredURI)) {
return;
}
@ -1025,15 +1010,12 @@ var gBrowserInit = {
// This pageshow listener needs to be registered before we may call
// swapBrowsersAndCloseOther() to receive pageshow events fired by that.
if (!gMultiProcessBrowser) {
// pageshow handlers are being migrated to
// content.js. Eventually this code should be removed.
gBrowser.addEventListener("pageshow", function(event) {
// Filter out events that are not about the document load we are interested in
if (content && event.target == content.document)
setTimeout(pageShowEventHandlers, 0, event.persisted);
}, true);
}
let mm = window.messageManager;
mm.addMessageListener("PageVisibility:Show", function(message) {
if (message.target == gBrowser.selectedBrowser) {
setTimeout(pageShowEventHandlers, 0, message.data.persisted);
}
});
if (uriToLoad && uriToLoad != "about:blank") {
if (uriToLoad instanceof Ci.nsISupportsArray) {
@ -1087,7 +1069,7 @@ var gBrowserInit = {
Services.obs.addObserver(gXPInstallObserver, "addon-install-blocked", false);
Services.obs.addObserver(gXPInstallObserver, "addon-install-failed", false);
Services.obs.addObserver(gXPInstallObserver, "addon-install-complete", false);
Services.obs.addObserver(gKeywordURIFixup, "keyword-uri-fixup", false);
window.messageManager.addMessageListener("Browser:URIFixup", gKeywordURIFixup);
BrowserOffline.init();
OfflineApps.init();
@ -1393,7 +1375,7 @@ var gBrowserInit = {
Services.obs.removeObserver(gXPInstallObserver, "addon-install-blocked");
Services.obs.removeObserver(gXPInstallObserver, "addon-install-failed");
Services.obs.removeObserver(gXPInstallObserver, "addon-install-complete");
Services.obs.removeObserver(gKeywordURIFixup, "keyword-uri-fixup");
window.messageManager.removeMessageListener("Browser:URIFixup", gKeywordURIFixup);
try {
gPrefService.removeObserver(gHomeButton.prefDomain, gHomeButton);
@ -3561,42 +3543,11 @@ var XULBrowserWindow = {
// Called before links are navigated to to allow us to retarget them if needed.
onBeforeLinkTraversal: function(originalTarget, linkURI, linkNode, isAppTab) {
let target = this._onBeforeLinkTraversal(originalTarget, linkURI, linkNode, isAppTab);
let target = BrowserUtils.onBeforeLinkTraversal(originalTarget, linkURI, linkNode, isAppTab);
SocialUI.closeSocialPanelForLinkTraversal(target, linkNode);
return target;
},
_onBeforeLinkTraversal: function(originalTarget, linkURI, linkNode, isAppTab) {
// Don't modify non-default targets or targets that aren't in top-level app
// tab docshells (isAppTab will be false for app tab subframes).
if (originalTarget != "" || !isAppTab)
return originalTarget;
// External links from within app tabs should always open in new tabs
// instead of replacing the app tab's page (Bug 575561)
let linkHost;
let docHost;
try {
linkHost = linkURI.host;
docHost = linkNode.ownerDocument.documentURIObject.host;
} catch(e) {
// nsIURI.host can throw for non-nsStandardURL nsIURIs.
// If we fail to get either host, just return originalTarget.
return originalTarget;
}
if (docHost == linkHost)
return originalTarget;
// Special case: ignore "www" prefix if it is part of host string
let [longHost, shortHost] =
linkHost.length > docHost.length ? [linkHost, docHost] : [docHost, linkHost];
if (longHost == "www." + shortHost)
return originalTarget;
return "_blank";
},
onProgressChange: function (aWebProgress, aRequest,
aCurSelfProgress, aMaxSelfProgress,
aCurTotalProgress, aMaxTotalProgress) {
@ -7367,9 +7318,17 @@ let ToolbarIconColor = {
toolbarSelector += ":not([type=menubar])";
#endif
// The getComputedStyle calls and setting the brighttext are separated in
// two loops to avoid flushing layout and making it dirty repeatedly.
let luminances = new Map;
for (let toolbar of document.querySelectorAll(toolbarSelector)) {
let [r, g, b] = parseRGB(getComputedStyle(toolbar).color);
let luminance = 0.2125 * r + 0.7154 * g + 0.0721 * b;
luminances.set(toolbar, luminance);
}
for (let [toolbar, luminance] of luminances) {
if (luminance <= 110)
toolbar.removeAttribute("brighttext");
else

View File

@ -633,3 +633,54 @@ let DOMFullscreenHandler = {
}
};
DOMFullscreenHandler.init();
function gKeywordURIFixup(fixupInfo) {
fixupInfo.QueryInterface(Ci.nsIURIFixupInfo);
// Ignore info from other docshells
let parent = fixupInfo.consumer.QueryInterface(Ci.nsIDocShellTreeItem).sameTypeRootTreeItem;
if (parent != docShell)
return;
let data = {};
for (let f of Object.keys(fixupInfo)) {
if (f == "consumer" || typeof fixupInfo[f] == "function")
continue;
if (fixupInfo[f] && fixupInfo[f] instanceof Ci.nsIURI) {
data[f] = fixupInfo[f].spec;
} else {
data[f] = fixupInfo[f];
}
}
sendAsyncMessage("Browser:URIFixup", data);
}
Services.obs.addObserver(gKeywordURIFixup, "keyword-uri-fixup", false);
addEventListener("unload", () => {
Services.obs.removeObserver(gKeywordURIFixup, "keyword-uri-fixup");
}, false);
addMessageListener("Browser:AppTab", function(message) {
docShell.isAppTab = message.data.isAppTab;
});
let WebBrowserChrome = {
onBeforeLinkTraversal: function(originalTarget, linkURI, linkNode, isAppTab) {
return BrowserUtils.onBeforeLinkTraversal(originalTarget, linkURI, linkNode, isAppTab);
},
};
if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
let tabchild = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsITabChild);
tabchild.webBrowserChrome = WebBrowserChrome;
}
addEventListener("pageshow", function(event) {
if (event.target == content.document) {
sendAsyncMessage("PageVisibility:Show", {
persisted: event.persisted,
});
}
});

View File

@ -289,9 +289,7 @@
this.tabContainer._positionPinnedTabs();
this.tabContainer.adjustTabstrip();
// Bug 961867 - [e10s] Implement the logic for app tabs
if (!gMultiProcessBrowser)
this.getBrowserForTab(aTab).docShell.isAppTab = true;
this.getBrowserForTab(aTab).messageManager.sendAsyncMessage("Browser:AppTab", { isAppTab: true })
if (aTab.selected)
this._setCloseKeyState(false);
@ -315,9 +313,7 @@
this.tabContainer._positionPinnedTabs();
this.tabContainer.adjustTabstrip();
// Bug 961867 - [e10s] Implement the logic for app tabs
if (!gMultiProcessBrowser)
this.getBrowserForTab(aTab).docShell.isAppTab = false;
this.getBrowserForTab(aTab).messageManager.sendAsyncMessage("Browser:AppTab", { isAppTab: false })
if (aTab.selected)
this._setCloseKeyState(true);
@ -5330,7 +5326,8 @@
let switchPromise = gBrowser._prepareForTabSwitch(toTab, fromTab);
var panel = this._selectedPanel;
this._selectedPanel = this.childNodes[val];
var newPanel = this.childNodes[val];
this._selectedPanel = newPanel;
if (this._selectedPanel != panel) {
var event = document.createEvent("Events");
event.initEvent("select", true, true);
@ -5340,8 +5337,16 @@
this._selectedIndex = val;
switchPromise.then(() => {
this.setAttribute("selectedIndex", val);
gBrowser._finalizeTabSwitch(toTab, fromTab);
// If we cannot find the tabpanel that we were trying to switch to, then
// it must have been removed before our Promise could be resolved. In
// that case, we just cancel the tab switch.
var updatedTabIndex = Array.indexOf(this.childNodes, newPanel);
if (updatedTabIndex == -1) {
gBrowser._cancelTabSwitch(toTab);
} else {
this.setAttribute("selectedIndex", updatedTabIndex);
gBrowser._finalizeTabSwitch(toTab, fromTab);
}
}, () => {
// If the promise rejected, that means we don't want to actually
// flip the deck, so we cancel the tab switch.

View File

@ -1,5 +1,5 @@
[DEFAULT]
skip-if = buildapp == 'mulet'
skip-if = buildapp == 'mulet' || e10s
support-files =
head.js
chat.html

View File

@ -102,6 +102,7 @@ skip-if = os == "linux" # Bug 924307
skip-if = e10s # Bug ?????? - no about:home support yet
[browser_aboutSyncProgress.js]
[browser_addKeywordSearch.js]
skip-if = e10s
[browser_alltabslistener.js]
skip-if = os == "linux" || e10s # Linux: Intermittent failures, bug 951680; e10s: Bug ?????? - notifications don't work correctly.
[browser_backButtonFitts.js]
@ -110,10 +111,13 @@ skip-if = os != "win" || e10s # The Fitts Law back button is only supported on W
[browser_bookmark_titles.js]
skip-if = buildapp == 'mulet' || toolkit == "windows" || e10s # Disabled on Windows due to frequent failures (bugs 825739, 841341) / e10s - Bug ?????? test checks event.target on load event, which our e10s utils don't support
[browser_bug304198.js]
skip-if = e10s
[browser_bug321000.js]
skip-if = true # browser_bug321000.js is disabled because newline handling is shaky (bug 592528)
[browser_bug329212.js]
skip-if = e10s
[browser_bug331772_xul_tooltiptext_in_html.js]
skip-if = e10s
[browser_bug356571.js]
[browser_bug380960.js]
[browser_bug386835.js]
@ -121,8 +125,8 @@ skip-if = e10s # Bug 691614 - no e10s zoom support yet
[browser_bug405137.js]
[browser_bug406216.js]
[browser_bug409481.js]
skip-if = e10s # Bug 921952 - Content:Click event issues (test simulated middle-click on a link and checks the value pastes - it doesn't)
[browser_bug409624.js]
skip-if = e10s
[browser_bug413915.js]
[browser_bug416661.js]
skip-if = e10s # Bug 691614 - no e10s zoom support yet
@ -146,6 +150,7 @@ skip-if = buildapp == 'mulet' || e10s # Bug ?????? - test directly manipulates c
[browser_bug441778.js]
skip-if = buildapp == 'mulet' || e10s # Bug 691614 - no e10s zoom support yet
[browser_bug455852.js]
skip-if = e10s
[browser_bug460146.js]
skip-if = e10s # Bug 866413 - PageInfo doesn't work in e10s
[browser_bug462289.js]
@ -159,6 +164,7 @@ skip-if = buildapp == 'mulet' || e10s # Bug 918663 - DOMLinkAdded events don't m
[browser_bug481560.js]
skip-if = e10s # Bug ????? - This bug attached an event listener directly to the content
[browser_bug484315.js]
skip-if = e10s
[browser_bug491431.js]
skip-if = buildapp == 'mulet' || e10s # Bug 918634 - swapFrameLoaders (and thus replaceTabWithWindow) not implemented for e10s
[browser_bug495058.js]
@ -188,27 +194,26 @@ skip-if = e10s # Bug 932651 - getClipboardData in specialpowersAPI.js not e10s f
[browser_bug559991.js]
skip-if = e10s # Bug 691614 - no e10s zoom support yet
[browser_bug561623.js]
skip-if = e10s
[browser_bug561636.js]
skip-if = e10s # Bug 691601 - no form submit observers
[browser_bug562649.js]
skip-if = e10s # Bug 940195 - XULBrowserWindow.isBusy is false as a remote tab starts loading
[browser_bug563588.js]
[browser_bug565575.js]
skip-if = e10s
[browser_bug565667.js]
run-if = toolkit == "cocoa"
[browser_bug567306.js]
skip-if = e10s
[browser_bug575561.js]
skip-if = e10s # Bug 921905 - pinTab/unpinTab fail in e10s
[browser_bug575830.js]
skip-if = e10s # Bug 691614 - no e10s zoom support yet
[browser_bug577121.js]
skip-if = e10s # Bug 921905 - pinTab/unpinTab fail in e10s
[browser_bug578534.js]
skip-if = e10s # Bug ?????? - test directly manipulates content
[browser_bug579872.js]
skip-if = e10s # Bug 921905 - pinTab/unpinTab fail in e10s
[browser_bug580638.js]
skip-if = e10s # Bug 921905 - pinTab/unpinTab fail in e10s
[browser_bug580956.js]
skip-if = e10s # Bug 516755 - SessionStore disabled for e10s
[browser_bug581242.js]
@ -216,20 +221,18 @@ skip-if = e10s # Bug 930863 - pageshow issues ("TypeError: charset is undefined"
[browser_bug581253.js]
skip-if = e10s # Bug 930863 - pageshow issues ("TypeError: charset is undefined" in pageshow listener, as document is null)
[browser_bug581947.js]
skip-if = e10s
[browser_bug585558.js]
skip-if = e10s # Bug 921905 - pinTab/unpinTab fail in e10s
[browser_bug585785.js]
[browser_bug585830.js]
[browser_bug590206.js]
[browser_bug592338.js]
skip-if = e10s # Bug 653065 - Make the lightweight theme web installer ready for e10s
[browser_bug594131.js]
skip-if = e10s # Bug 921905 - pinTab/unpinTab fail in e10s
[browser_bug595507.js]
skip-if = e10s # Bug 691601 - no form submit observers
[browser_bug596687.js]
[browser_bug597218.js]
skip-if = e10s # Bug 921905 - pinTab/unpinTab fail in e10s
[browser_bug609700.js]
skip-if = e10s # Bug 516755 - SessionStore disabled for e10s (calls duplicateTabIn, which uses SessionStore)
[browser_bug623155.js]
@ -242,6 +245,7 @@ skip-if = e10s # Bug ?????? - test directly manipulates content (eg, var expertD
[browser_bug647886.js]
skip-if = buildapp == 'mulet' || e10s # Bug 916974 - Session history doesn't work in e10s
[browser_bug655584.js]
skip-if = e10s
[browser_bug664672.js]
[browser_bug676619.js]
skip-if = buildapp == 'mulet' || os == "mac" || e10s # mac: Intermittent failures, bug 925225; e10s: Bug ?????? - test directly manipulates content (event.target.location)
@ -258,6 +262,7 @@ skip-if = e10s # Bug ?????? - test directly manipulates content
[browser_bug749738.js]
skip-if = e10s # Bug 921935 - focusmanager issues with e10s
[browser_bug763468_perwindowpb.js]
skip-if = e10s
[browser_bug767836_perwindowpb.js]
skip-if = e10s # Bug ?????? - test reports a leaked nsGlobalWindow with e10s enabled.
[browser_bug771331.js]
@ -273,6 +278,7 @@ skip-if = e10s # Bug 916974 - Session history doesn't work in e10s
[browser_bug880101.js]
[browser_bug882977.js]
[browser_bug902156.js]
skip-if = e10s
[browser_bug906190.js]
skip-if = buildapp == "mulet" || e10s # Bug ?????? - test directly manipulates content (strange - gets an element from a child which it tries to treat as a string, but that fails)
[browser_bug970746.js]
@ -282,11 +288,13 @@ skip-if = os == 'win' || e10s # Bug 1056146 - FullZoomHelper uses promiseTabLoad
[browser_canonizeURL.js]
skip-if = e10s # Bug ?????? - [JavaScript Error: "Error in AboutHome.sendAboutHomeData TypeError: target.messageManager is undefined" {file: "resource:///modules/AboutHome.jsm" line: 208}]
[browser_contentAreaClick.js]
skip-if = e10s
[browser_contextSearchTabPosition.js]
skip-if = os == "mac" # bug 967013, bug 926729
skip-if = os == "mac" || e10s # bug 967013, bug 926729
[browser_ctrlTab.js]
skip-if = e10s # Bug ????? - thumbnail captures need e10s love (tabPreviews_capture fails with Argument 1 of CanvasRenderingContext2D.drawWindow does not implement interface Window.)
[browser_customize_popupNotification.js]
skip-if = e10s
[browser_datareporting_notification.js]
run-if = datareporting
[browser_devices_get_user_media.js]
@ -299,11 +307,13 @@ skip-if = e10s # Bug 918663 - DOMLinkAdded events don't make their way to chrome
[browser_drag.js]
skip-if = true # browser_drag.js is disabled, as it needs to be updated for the new behavior from bug 320638.
[browser_favicon_change.js]
skip-if = e10s
[browser_findbarClose.js]
skip-if = e10s # Bug ?????? - test directly manipulates content (tries to grab an iframe directly from content)
[browser_fullscreen-window-open.js]
skip-if = buildapp == 'mulet' || e10s || os == "linux" # Bug 933103 - mochitest's EventUtils.synthesizeMouse functions not e10s friendly. Linux: Intermittent failures - bug 941575.
[browser_fxa_oauth.js]
skip-if = e10s
[browser_gestureSupport.js]
skip-if = e10s # Bug 863514 - no gesture support.
[browser_getshortcutoruri.js]
@ -323,6 +333,7 @@ skip-if = toolkit == "windows" # Disabled on Windows due to frequent failures (b
[browser_locationBarCommand.js]
skip-if = os == "linux" || e10s # Linux: Intermittent failures, bug 917535; e10s: Bug ?????? - Focus issues (There should be no focused element - Got [object XULElement], expected null)
[browser_locationBarExternalLoad.js]
skip-if = e10s
[browser_menuButtonFitts.js]
skip-if = os != "win" || e10s # The Fitts Law menu button is only supported on Windows (bug 969376); # Bug ?????? - URL bar issues ("There should be no focused element - Got [object XULElement], expected null")
[browser_middleMouse_noJSPaste.js]
@ -336,18 +347,17 @@ skip-if = buildapp == 'mulet' || e10s # Bug ?????? - uncaught exception - Error:
[browser_offlineQuotaNotification.js]
skip-if = buildapp == 'mulet' || e10s # Bug ?????? - test directly manipulates content (gBrowser.selectedBrowser.contentWindow.applicationCache.oncached = function() {...})
[browser_overflowScroll.js]
skip-if = e10s # Bug 921905 - pinTab/unpinTab fail in e10s
[browser_pageInfo.js]
skip-if = buildapp == 'mulet' || e10s # Bug 866413 - PageInfo doesn't work in e10s
[browser_page_style_menu.js]
skip-if = e10s # Bug ?????? - test directly manipulates content
[browser_parsable_css.js]
skip-if = e10s
[browser_parsable_script.js]
skip-if = debug || asan # Times out on debug/asan, and we are less picky about our JS there
[browser_pinnedTabs.js]
skip-if = e10s # Bug 921905 - pinTab/unpinTab fail in e10s
[browser_plainTextLinks.js]
skip-if = e10s # Bug ?????? - test directly manipulates content (creates and fetches elements directly from content document)
[browser_popupUI.js]
@ -360,8 +370,8 @@ skip-if = buildapp == 'mulet'
skip-if = buildapp == 'mulet'
[browser_relatedTabs.js]
[browser_removeTabsToTheEnd.js]
skip-if = e10s # Bug 921905 - pinTab/unpinTab fail in e10s
[browser_removeUnsafeProtocolsFromURLBarPaste.js]
skip-if = e10s
[browser_sanitize-download-history.js]
skip-if = true # bug 432425
[browser_sanitize-passwordDisabledHosts.js]
@ -382,6 +392,7 @@ skip-if = buildapp == 'mulet' || e10s # e10s: Bug 933103 - mochitest's EventUtil
skip-if = buildapp == 'mulet' || e10s # Bug ?????? - test directly manipulates content (event.target)
[browser_scope.js]
[browser_searchSuggestionUI.js]
skip-if = e10s
support-files =
searchSuggestionUI.html
searchSuggestionUI.js
@ -391,7 +402,7 @@ skip-if = e10s # Bug ?????? - no idea! "Accel+9 selects expected tab - Got 0, ex
skip-if = e10s # Bug ?????? - timeout after logging "Error: Channel closing: too late to send/recv, messages will be lost"
[browser_subframe_favicons_not_used.js]
[browser_tabDrop.js]
skip-if = buildapp == 'mulet'
skip-if = buildapp == 'mulet' || e10s
[browser_tabMatchesInAwesomebar_perwindowpb.js]
skip-if = e10s # Bug 918634 - swapFrameLoaders not implemented for e10s (test uses gBrowser.swapBrowsersAndCloseOther)
[browser_tab_drag_drop_perwindow.js]
@ -399,19 +410,21 @@ skip-if = buildapp == 'mulet'
[browser_tab_dragdrop.js]
skip-if = buildapp == 'mulet' || e10s # Bug 918634 - swapFrameLoaders not implemented for e10s (test uses gBrowser.swapBrowsersAndCloseOther)
[browser_tab_dragdrop2.js]
skip-if = buildapp == 'mulet'
skip-if = buildapp == 'mulet' || e10s
[browser_tabbar_big_widgets.js]
skip-if = os == "linux" || os == "mac" # No tabs in titlebar on linux
# Disabled on OS X because of bug 967917
[browser_tabfocus.js]
skip-if = e10s # Bug 921935 - focusmanager issues with e10s (test calls getFocusedElementForWindow with a content window)
[browser_tabkeynavigation.js]
skip-if = e10s
[browser_tabopen_reflows.js]
skip-if = e10s # Bug ?????? - test needs to be updated for e10s (captures a stack that isn't correct in e10s)
[browser_tabs_isActive.js]
skip-if = e10s # Bug ?????? - test directly manipulates content (tries to get/set attributes directly on content docshell)
[browser_tabs_owner.js]
[browser_trackingUI.js]
skip-if = e10s
support-files =
trackingPage.html
benignPage.html
@ -420,7 +433,9 @@ skip-if = buildapp == 'mulet' || e10s # Bug 921935 - focusmanager issues with e1
[browser_unloaddialogs.js]
skip-if = e10s # Bug ?????? - test uses chrome windowMediator to try and see alert() from content
[browser_urlHighlight.js]
skip-if = e10s
[browser_urlbarAutoFillTrimURLs.js]
skip-if = e10s
[browser_urlbarCopying.js]
skip-if = e10s # Bug 932651 - getClipboardData in specialpowersAPI.js not e10s friendly
[browser_urlbarEnter.js]
@ -428,9 +443,11 @@ skip-if = e10s # Bug ?????? - obscure non-windows child process crashes on try
[browser_urlbarRevert.js]
skip-if = e10s # Bug ?????? - ESC reverted the location bar value - Got foobar, expected example.com
[browser_urlbarSearchSingleWordNotification.js]
skip-if = e10s
[browser_urlbarStop.js]
skip-if = e10s # Bug ????? - test calls gBrowser.contentWindow.stop
[browser_urlbarTrimURLs.js]
skip-if = e10s
[browser_urlbar_search_healthreport.js]
skip-if = e10s # Bug ?????? - FHR tests failing (either with "no data for today" or "2 records for today")
[browser_utilityOverlay.js]
@ -438,13 +455,10 @@ skip-if = e10s # Bug ?????? - FHR tests failing (either with "no data for today"
skip-if = e10s # Bug ?????? - test directly manipulates content
[browser_visibleLabel.js]
[browser_visibleTabs.js]
skip-if = e10s # Bug 921905 - pinTab/unpinTab fail in e10s
[browser_visibleTabs_bookmarkAllPages.js]
skip-if = true # Bug 1005420 - fails intermittently. also with e10s enabled: bizarre problem with hidden tab having _mouseenter called, via _setPositionalAttributes, and tab not being found resulting in 'candidate is undefined'
[browser_visibleTabs_bookmarkAllTabs.js]
skip-if = e10s # Bug 921905 - pinTab/unpinTab fail in e10s
[browser_visibleTabs_contextMenu.js]
skip-if = e10s # Bug 921905 - pinTab/unpinTab fail in e10s
[browser_visibleTabs_tabPreview.js]
skip-if = (os == "win" && !debug) || e10s # Bug 1007418 / Bug 698371 - thumbnail captures need e10s love (tabPreviews_capture fails with Argument 1 of CanvasRenderingContext2D.drawWindow does not implement interface Window.)
[browser_web_channel.js]
@ -459,8 +473,11 @@ skip-if = e10s # Bug 940206 - nsIWebContentHandlerRegistrar::registerProtocolHan
[browser_no_mcb_on_http_site.js]
skip-if = e10s # Bug 516755 - SessionStore disabled for e10s
[browser_bug1003461-switchtab-override.js]
skip-if = e10s
[browser_bug1024133-switchtab-override-keynav.js]
skip-if = e10s
[browser_bug1025195_switchToTabHavingURI_ignoreFragment.js]
[browser_addCertException.js]
skip-if = e10s # Bug ?????? - test directly manipulates content (content.document.getElementById)
[browser_bug1045809.js]
skip-if = e10s

View File

@ -43,16 +43,8 @@ function testLink(aLinkIndex, pinTab, expectNewTab, nextTest, testSubFrame) {
if (pinTab)
gBrowser.pinTab(appTab);
gBrowser.selectedTab = appTab;
appTab.linkedBrowser.addEventListener("load", onLoad, true);
let loadCount = 0;
function onLoad() {
loadCount++;
if (loadCount < 2)
return;
appTab.linkedBrowser.removeEventListener("load", onLoad, true);
waitForDocLoadComplete(appTab.linkedBrowser).then(function() {
let browser = gBrowser.getBrowserForTab(appTab);
if (testSubFrame)
browser = browser.contentDocument.getElementsByTagName("iframe")[0];
@ -62,7 +54,7 @@ function testLink(aLinkIndex, pinTab, expectNewTab, nextTest, testSubFrame) {
if (expectNewTab)
gBrowser.tabContainer.addEventListener("TabOpen", onTabOpen, true);
else
browser.addEventListener("load", onPageLoad, true);
waitForDocLoadComplete(appTab.linkedBrowser).then(onPageLoad);
info("Clicking " + links[aLinkIndex].textContent);
EventUtils.sendMouseEvent({type:"click"}, links[aLinkIndex], browser.contentWindow);
@ -80,11 +72,13 @@ function testLink(aLinkIndex, pinTab, expectNewTab, nextTest, testSubFrame) {
function onTabOpen(event) {
gBrowser.tabContainer.removeEventListener("TabOpen", onTabOpen, true);
ok(true, "Link should open a new tab");
executeSoon(function(){
gBrowser.removeTab(appTab);
gBrowser.removeCurrentTab();
nextTest();
waitForDocLoadComplete(event.target.linkedBrowser).then(function() {
executeSoon(function(){
gBrowser.removeTab(appTab);
gBrowser.removeCurrentTab();
nextTest();
});
});
}
}
});
}

View File

@ -49,14 +49,6 @@ const EXPECTED_REFLOWS = [
"ssi_updateWindowFeatures/<@resource:///modules/sessionstore/SessionStore.jsm|" +
"ssi_updateWindowFeatures@resource:///modules/sessionstore/SessionStore.jsm|" +
"ssi_collectWindowData@resource:///modules/sessionstore/SessionStore.jsm|",
// tabPreviews.capture()
"tabPreviews_capture@chrome://browser/content/browser.js|" +
"tabPreviews_handleEvent/<@chrome://browser/content/browser.js|",
// tabPreviews.capture()
"tabPreviews_capture@chrome://browser/content/browser.js|" +
"@chrome://browser/content/browser.js|"
];
const PREF_PRELOAD = "browser.newtab.preload";

View File

@ -15,8 +15,10 @@ function promiseNotificationForTab(aBrowser, value, expected, tab=aBrowser.selec
let deferred = Promise.defer();
let notificationBox = aBrowser.getNotificationBox(tab.linkedBrowser);
if (expected) {
info("Waiting for " + value + " notification");
let checkForNotification = function() {
if (notificationBox.getNotificationWithValue(value)) {
info("Saw the notification");
notificationObserver.disconnect();
notificationObserver = null;
deferred.resolve();
@ -48,12 +50,13 @@ function* runURLBarSearchTest(valueToOpen, expectSearch, expectNotification, aWi
expectedURI = Services.search.defaultEngine.getSubmission(valueToOpen, null, "keyword").uri.spec;
}
aWindow.gURLBar.focus();
let docLoadPromise = waitForDocLoadAndStopIt(expectedURI, aWindow.gBrowser);
let docLoadPromise = waitForDocLoadAndStopIt(expectedURI, aWindow.gBrowser.selectedBrowser);
EventUtils.synthesizeKey("VK_RETURN", {}, aWindow);
yield docLoadPromise;
yield promiseNotificationForTab(aWindow.gBrowser, "keyword-uri-fixup", expectNotification);
yield Promise.all([
docLoadPromise,
promiseNotificationForTab(aWindow.gBrowser, "keyword-uri-fixup", expectNotification)
]);
}
add_task(function* test_navigate_full_domain() {
@ -88,7 +91,7 @@ function get_test_function_for_localhost_with_hostname(hostName, isPrivate) {
let notificationBox = browser.getNotificationBox(tab.linkedBrowser);
let notification = notificationBox.getNotificationWithValue("keyword-uri-fixup");
let docLoadPromise = waitForDocLoadAndStopIt("http://" + hostName + "/", browser);
let docLoadPromise = waitForDocLoadAndStopIt("http://" + hostName + "/", tab.linkedBrowser);
notification.querySelector(".notification-button-default").click();
// check pref value

View File

@ -394,26 +394,66 @@ function promiseClearHistory() {
* The URL of the document that is expected to load.
* @return promise
*/
function waitForDocLoadAndStopIt(aExpectedURL, aBrowser=gBrowser) {
function waitForDocLoadAndStopIt(aExpectedURL, aBrowser=gBrowser.selectedBrowser) {
function content_script() {
let { interfaces: Ci, utils: Cu } = Components;
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
let wp = docShell.QueryInterface(Ci.nsIWebProgress);
let progressListener = {
onStateChange: function (webProgress, req, flags, status) {
dump("waitForDocLoadAndStopIt: onStateChange " + flags.toString(16) + ": " + req.name + "\n");
let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT |
Ci.nsIWebProgressListener.STATE_START;
if (((flags & docStart) == docStart) && webProgress.isTopLevel) {
dump("waitForDocLoadAndStopIt: Document start: " +
req.QueryInterface(Ci.nsIChannel).URI.spec + "\n");
req.cancel(Components.results.NS_ERROR_FAILURE);
wp.removeProgressListener(progressListener);
sendAsyncMessage("Test:WaitForDocLoadAndStopIt", { uri: req.originalURI.spec });
}
},
QueryInterface: XPCOMUtils.generateQI(["nsISupportsWeakReference"])
};
wp.addProgressListener(progressListener, wp.NOTIFY_ALL);
}
return new Promise((resolve, reject) => {
function complete({ data }) {
is(data.uri, aExpectedURL, "waitForDocLoadAndStopIt: The expected URL was loaded");
mm.removeMessageListener("Test:WaitForDocLoadAndStopIt", complete);
resolve();
}
let mm = aBrowser.messageManager;
mm.loadFrameScript("data:,(" + content_script.toString() + ")();", true);
mm.addMessageListener("Test:WaitForDocLoadAndStopIt", complete);
info("waitForDocLoadAndStopIt: Waiting for URL: " + aExpectedURL);
});
}
/**
* Waits for the next load to complete in the current browser.
*
* @return promise
*/
function waitForDocLoadComplete(aBrowser=gBrowser) {
let deferred = Promise.defer();
let progressListener = {
onStateChange: function (webProgress, req, flags, status) {
info("waitForDocLoadAndStopIt: onStateChange: " + req.name);
let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT |
Ci.nsIWebProgressListener.STATE_START;
if ((flags & docStart) && webProgress.isTopLevel) {
info("waitForDocLoadAndStopIt: Document start: " +
req.QueryInterface(Ci.nsIChannel).URI.spec);
is(req.originalURI.spec, aExpectedURL,
"waitForDocLoadAndStopIt: The expected URL was loaded");
req.cancel(Components.results.NS_ERROR_FAILURE);
let docStart = Ci.nsIWebProgressListener.STATE_IS_NETWORK |
Ci.nsIWebProgressListener.STATE_STOP;
if ((flags & docStart) == docStart) {
aBrowser.removeProgressListener(progressListener);
info("Browser loaded");
deferred.resolve();
}
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
Ci.nsISupportsWeakReference])
};
aBrowser.addProgressListener(progressListener);
info("waitForDocLoadAndStopIt: Waiting for URL: " + aExpectedURL);
info("Waiting for browser load");
return deferred.promise;
}

View File

@ -1,5 +1,5 @@
[DEFAULT]
skip-if = buildapp == "mulet"
skip-if = buildapp == "mulet" || e10s
support-files =
head.js
support/test_967000_charEncoding_page.html

View File

@ -2,7 +2,7 @@
support-files = head.js
[browser_basic_functionality.js]
skip-if = buildapp == "mulet"
skip-if = buildapp == "mulet" || e10s
[browser_first_download_panel.js]
skip-if = os == "linux" # Bug 949434
[browser_overflow_anchor.js]

View File

@ -21,7 +21,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "console",
*/
let MozLoopPushHandler = {
// This is the uri of the push server.
pushServerUri: Services.prefs.getCharPref("services.push.serverURL"),
pushServerUri: undefined,
// This is the channel id we're using for notifications
channelID: "8b1081ce-9b35-42b5-b8f5-3ff8cb813a50",
// This is the UserAgent UUID assigned by the PushServer
@ -211,8 +211,51 @@ let MozLoopPushHandler = {
}
this._websocket.protocol = "push-notification";
let uri = Services.io.newURI(this.pushServerUri, null, null);
this._websocket.asyncOpen(uri, this.pushServerUri, this, null);
let performOpen = () => {
let uri = Services.io.newURI(this.pushServerUri, null, null);
this._websocket.asyncOpen(uri, this.pushServerUri, this, null);
}
let pushServerURLFetchError = () => {
console.warn("MozLoopPushHandler - Could not retrieve push server URL from Loop server; using default");
this.pushServerUri = Services.prefs.getCharPref("services.push.serverURL");
performOpen();
}
if (!this.pushServerUri) {
// Get push server to use from the Loop server
let pushUrlEndpoint = Services.prefs.getCharPref("loop.server") + "/push-server-config";
let req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
createInstance(Ci.nsIXMLHttpRequest);
req.open("GET", pushUrlEndpoint);
req.onload = () => {
if (req.status >= 200 && req.status < 300) {
let pushServerConfig;
try {
pushServerConfig = JSON.parse(req.responseText);
} catch (e) {
console.warn("MozLoopPushHandler - Error parsing JSON response for push server URL");
pushServerURLFetchError();
}
if (pushServerConfig.pushServerURI) {
this.pushServerUri = pushServerConfig.pushServerURI;
performOpen();
} else {
console.warn("MozLoopPushHandler - push server URL config lacks pushServerURI parameter");
pushServerURLFetchError();
}
} else {
console.warn("MozLoopPushHandler - push server URL retrieve error: " + req.status);
pushServerURLFetchError();
}
};
req.onerror = pushServerURLFetchError;
req.send();
} else {
// this.pushServerUri already set -- just open the channel
performOpen();
}
},
/**

View File

@ -6,7 +6,7 @@ support-files =
[browser_CardDavImporter.js]
[browser_fxa_login.js]
skip-if = !debug
skip-if = !debug || e10s
[browser_loop_fxa_server.js]
[browser_LoopContacts.js]
[browser_mozLoop_appVersionInfo.js]

View File

@ -57,9 +57,17 @@ function loadLoopPanel() {
Services.prefs.setCharPref("services.push.serverURL", "ws://localhost/");
Services.prefs.setCharPref("loop.server", "http://localhost/");
// Turn off the network for loop tests, so that we don't
// try to access the remote servers. If we want to turn this
// back on in future, be careful to check for intermittent
// failures.
let wasOffline = Services.io.offline;
Services.io.offline = true;
registerCleanupFunction(function() {
Services.prefs.clearUserPref("services.push.serverURL");
Services.prefs.clearUserPref("loop.server");
Services.io.offline = wasOffline;
});
// Turn off animations to make tests quicker.

View File

@ -54,6 +54,8 @@
});
function run_test() {
setupFakeLoopServer();
Services.prefs.setCharPref("services.push.serverURL", kServerPushUrl);
Services.prefs.setIntPref("loop.retry_delay.start", 10); // 10 ms
Services.prefs.setIntPref("loop.retry_delay.limit", 20); // 20 ms

View File

@ -7,6 +7,8 @@ function expiryTimePref() {
function run_test()
{
setupFakeLoopServer();
Services.prefs.setIntPref("loop.urlsExpiryTimeSeconds", 0);
MozLoopService.noteCallUrlExpiry(1000);

View File

@ -50,6 +50,8 @@ add_task(function test_initialize_starts_timer() {
function run_test()
{
setupFakeLoopServer();
// Override MozLoopService's initializeTimer, so that we can verify the timeout is called
// correctly.
MozLoopService.initializeTimerFunc = function() {

View File

@ -22,6 +22,8 @@ function test_getStrings() {
function run_test()
{
setupFakeLoopServer();
test_locale();
test_getStrings();
}

View File

@ -89,6 +89,8 @@ function test_getLoopBoolPref_not_found()
function run_test()
{
setupFakeLoopServer();
test_getLoopCharPref();
test_getLoopCharPref_not_found();
test_getLoopCharPref_non_coercible_type();

View File

@ -15,6 +15,7 @@ support-files =
[browser_library_left_pane_fixnames.js]
[browser_425884.js]
[browser_475045.js]
skip-if = e10s
[browser_423515.js]
[browser_410196_paste_into_tags.js]
skip-if = e10s # Bug ?????? - clipboard operations don't seem to work in this test?
@ -24,6 +25,7 @@ skip-if = e10s # Bug ?????? - clipboard operations don't seem to work in this te
[browser_library_search.js]
[browser_history_sidebar_search.js]
[browser_bookmarksProperties.js]
skip-if = e10s
[browser_forgetthissite_single.js]
# disabled for very frequent oranges - bug 551540
@ -46,10 +48,13 @@ skip-if = e10s # Bug 933103 - mochitest's EventUtils.synthesizeMouse functions n
[browser_toolbar_migration.js]
[browser_library_batch_delete.js]
[browser_555547.js]
skip-if = e10s
[browser_416459_cut.js]
skip-if = e10s # Bug ?????? - clipboard operations don't seem to work in this test?
[browser_library_downloads.js]
[browser_library_left_pane_select_hierarchy.js]
[browser_435851_copy_query.js]
skip-if = e10s
[browser_toolbarbutton_menu_context.js]
skip-if = e10s
[browser_library_openFlatContainer.js]

View File

@ -62,8 +62,8 @@ var gAdvancedPane = {
gAdvancedPane.clearOfflineAppCache);
setEventListener("offlineNotifyExceptions", "command",
gAdvancedPane.showOfflineExceptions);
setEventListener("offlineNotifyExceptions", "command", function (event) {
gAdvancedPane.offlineAppSelected(event); })
setEventListener("offlineAppsList", "select",
gAdvancedPane.offlineAppSelected);
let bundlePrefs = document.getElementById("bundlePreferences");
document.getElementById("offlineAppsList")
.style.height = bundlePrefs.getString("offlineAppsList.height");
@ -72,9 +72,9 @@ var gAdvancedPane = {
#ifdef MOZ_UPDATER
setEventListener("updateRadioGroup", "command",
gAdvancedPane.updateWritePrefs);
#endif
setEventListener("showUpdateHistory", "command",
gAdvancedPane.showUpdates);
#endif
setEventListener("viewCertificatesButton", "command",
gAdvancedPane.showCertificates);
setEventListener("viewSecurityDevicesButton", "command",

View File

@ -1,5 +1,5 @@
[DEFAULT]
skip-if = buildapp == "mulet"
skip-if = buildapp == "mulet" || e10s
support-files =
head.js
privacypane_tests_perwindow.js
@ -17,5 +17,7 @@ skip-if = !healthreport || (os == 'linux' && debug)
[browser_privacypane_1.js]
[browser_privacypane_3.js]
[browser_privacypane_4.js]
skip-if = e10s # leaks windows
[browser_privacypane_5.js]
skip-if = e10s # leaks windows
[browser_privacypane_8.js]

View File

@ -1,5 +1,5 @@
[DEFAULT]
skip-if = buildapp == "mulet"
skip-if = buildapp == "mulet" || e10s
support-files =
browser_privatebrowsing_concurrent_page.html
browser_privatebrowsing_cookieacceptdialog.html
@ -17,19 +17,14 @@ support-files =
[browser_privatebrowsing_DownloadLastDirWithCPS.js]
[browser_privatebrowsing_aboutHomeButtonAfterWindowClose.js]
skip-if = e10s # Bug ?????? - test directly manipulates content (win.getComputedStyle(win.gBrowser.contentDocument.getElementById("restorePreviousSession")))
[browser_privatebrowsing_aboutSessionRestore.js]
skip-if = e10s # Bug ?????? - "leaked until shutdown [nsGlobalWindow...]"
[browser_privatebrowsing_cache.js]
[browser_privatebrowsing_certexceptionsui.js]
[browser_privatebrowsing_concurrent.js]
skip-if = e10s # Bug ?????? - test directly manipulates content (private_tab.docShell.QueryInterface...)
[browser_privatebrowsing_cookieacceptdialog.js]
[browser_privatebrowsing_crh.js]
[browser_privatebrowsing_downloadLastDir.js]
skip-if = e10s # Bug ?????? MockFilePicker cleanup failing ( nsresult: "0x80040154 (NS_ERROR_FACTORY_NOT_REGISTERED)" location: "JS frame :: resource://specialpowers/MockFilePicker.jsm :: this.MockFilePicker.cleanup :: line 84")
[browser_privatebrowsing_downloadLastDir_c.js]
skip-if = e10s # Bug ?????? MockFilePicker cleanup failing ( nsresult: "0x80040154 (NS_ERROR_FACTORY_NOT_REGISTERED)" location: "JS frame :: resource://specialpowers/MockFilePicker.jsm :: this.MockFilePicker.cleanup :: line 84")
[browser_privatebrowsing_downloadLastDir_toggle.js]
[browser_privatebrowsing_geoprompt.js]
[browser_privatebrowsing_lastpbcontextexited.js]
@ -47,8 +42,5 @@ skip-if = e10s # Bug ?????? MockFilePicker cleanup failing ( nsresult: "0x800401
[browser_privatebrowsing_ui.js]
[browser_privatebrowsing_urlbarfocus.js]
[browser_privatebrowsing_windowtitle.js]
skip-if = e10s # Bug 918634 - swapFrameLoaders
[browser_privatebrowsing_zoom.js]
skip-if = e10s # Bug 691614 - e10s support for content zooming
[browser_privatebrowsing_zoomrestore.js]
skip-if = e10s # Bug 691614 - e10s support for content zooming

View File

@ -2,6 +2,7 @@
support-files = head.js
[browser_bug400731.js]
skip-if = e10s
[browser_bug415846.js]
skip-if = true
# Disabled because it seems to now touch network resources

View File

@ -6,5 +6,6 @@ support-files =
[browser_translation_bing.js]
[browser_translation_fhr.js]
skip-if = e10s
[browser_translation_infobar.js]
[browser_translation_exceptions.js]

View File

@ -1,3 +1,4 @@
. "$topsrcdir/build/mozconfig.win-common"
. "$topsrcdir/browser/config/mozconfigs/win64/common-win64"
. "$topsrcdir/browser/config/mozconfigs/win64/common-opt"

View File

@ -1,5 +1,6 @@
# This make file should be identical to the beta mozconfig, apart from the
# safeguard below
. "$topsrcdir/build/mozconfig.win-common"
. "$topsrcdir/browser/config/mozconfigs/win64/common-win64"
. "$topsrcdir/browser/config/mozconfigs/win64/common-opt"

View File

@ -76,6 +76,9 @@ const TEST_DATA = [
" var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
" };\n" +
" var handler10 = function divDragOut() {\n" +
" alert(10);\n" +
" };\n" +
"\n" +
" if ($(\"#livediv\").live) {\n" +
" $(\"#livediv\").live(\"dblclick\", handler1);\n" +
@ -90,6 +93,7 @@ const TEST_DATA = [
" if ($(\"#livediv\").on) {\n" +
" $(document).on(\"drop\", \"#livediv\", handler5);\n" +
" $(document).on(\"dragover\", \"#livediv\", handler6);\n" +
" $(document).on(\"dragout\", \"#livediv:xxxxx\", handler10);\n" +
" }\n" +
"\n" +
" var div = $(\"div\")[0];\n" +

View File

@ -80,6 +80,9 @@ const TEST_DATA = [
" var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
" };\n" +
" var handler10 = function divDragOut() {\n" +
" alert(10);\n" +
" };\n" +
"\n" +
" if ($(\"#livediv\").live) {\n" +
" $(\"#livediv\").live(\"dblclick\", handler1);\n" +
@ -94,6 +97,7 @@ const TEST_DATA = [
" if ($(\"#livediv\").on) {\n" +
" $(document).on(\"drop\", \"#livediv\", handler5);\n" +
" $(document).on(\"dragover\", \"#livediv\", handler6);\n" +
" $(document).on(\"dragout\", \"#livediv:xxxxx\", handler10);\n" +
" }\n" +
"\n" +
" var div = $(\"div\")[0];\n" +

View File

@ -51,6 +51,9 @@ const TEST_DATA = [
" var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
" };\n" +
" var handler10 = function divDragOut() {\n" +
" alert(10);\n" +
" };\n" +
"\n" +
" if ($(\"#livediv\").live) {\n" +
" $(\"#livediv\").live(\"dblclick\", handler1);\n" +
@ -65,6 +68,7 @@ const TEST_DATA = [
" if ($(\"#livediv\").on) {\n" +
" $(document).on(\"drop\", \"#livediv\", handler5);\n" +
" $(document).on(\"dragover\", \"#livediv\", handler6);\n" +
" $(document).on(\"dragout\", \"#livediv:xxxxx\", handler10);\n" +
" }\n" +
"\n" +
" var div = $(\"div\")[0];\n" +

View File

@ -51,6 +51,9 @@ const TEST_DATA = [
" var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
" };\n" +
" var handler10 = function divDragOut() {\n" +
" alert(10);\n" +
" };\n" +
"\n" +
" if ($(\"#livediv\").live) {\n" +
" $(\"#livediv\").live(\"dblclick\", handler1);\n" +
@ -65,6 +68,7 @@ const TEST_DATA = [
" if ($(\"#livediv\").on) {\n" +
" $(document).on(\"drop\", \"#livediv\", handler5);\n" +
" $(document).on(\"dragover\", \"#livediv\", handler6);\n" +
" $(document).on(\"dragout\", \"#livediv:xxxxx\", handler10);\n" +
" }\n" +
"\n" +
" var div = $(\"div\")[0];\n" +

View File

@ -81,6 +81,9 @@ const TEST_DATA = [
" var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
" };\n" +
" var handler10 = function divDragOut() {\n" +
" alert(10);\n" +
" };\n" +
"\n" +
" if ($(\"#livediv\").live) {\n" +
" $(\"#livediv\").live(\"dblclick\", handler1);\n" +
@ -95,6 +98,7 @@ const TEST_DATA = [
" if ($(\"#livediv\").on) {\n" +
" $(document).on(\"drop\", \"#livediv\", handler5);\n" +
" $(document).on(\"dragover\", \"#livediv\", handler6);\n" +
" $(document).on(\"dragout\", \"#livediv:xxxxx\", handler10);\n" +
" }\n" +
"\n" +
" var div = $(\"div\")[0];\n" +

View File

@ -51,6 +51,9 @@ const TEST_DATA = [
" var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
" };\n" +
" var handler10 = function divDragOut() {\n" +
" alert(10);\n" +
" };\n" +
"\n" +
" if ($(\"#livediv\").live) {\n" +
" $(\"#livediv\").live(\"dblclick\", handler1);\n" +
@ -65,6 +68,7 @@ const TEST_DATA = [
" if ($(\"#livediv\").on) {\n" +
" $(document).on(\"drop\", \"#livediv\", handler5);\n" +
" $(document).on(\"dragover\", \"#livediv\", handler6);\n" +
" $(document).on(\"dragout\", \"#livediv:xxxxx\", handler10);\n" +
" }\n" +
"\n" +
" var div = $(\"div\")[0];\n" +

View File

@ -51,6 +51,9 @@ const TEST_DATA = [
" var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
" };\n" +
" var handler10 = function divDragOut() {\n" +
" alert(10);\n" +
" };\n" +
"\n" +
" if ($(\"#livediv\").live) {\n" +
" $(\"#livediv\").live(\"dblclick\", handler1);\n" +
@ -65,6 +68,7 @@ const TEST_DATA = [
" if ($(\"#livediv\").on) {\n" +
" $(document).on(\"drop\", \"#livediv\", handler5);\n" +
" $(document).on(\"dragover\", \"#livediv\", handler6);\n" +
" $(document).on(\"dragout\", \"#livediv:xxxxx\", handler10);\n" +
" }\n" +
"\n" +
" var div = $(\"div\")[0];\n" +

View File

@ -51,6 +51,9 @@ const TEST_DATA = [
" var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
" };\n" +
" var handler10 = function divDragOut() {\n" +
" alert(10);\n" +
" };\n" +
"\n" +
" if ($(\"#livediv\").live) {\n" +
" $(\"#livediv\").live(\"dblclick\", handler1);\n" +
@ -65,6 +68,7 @@ const TEST_DATA = [
" if ($(\"#livediv\").on) {\n" +
" $(document).on(\"drop\", \"#livediv\", handler5);\n" +
" $(document).on(\"dragover\", \"#livediv\", handler6);\n" +
" $(document).on(\"dragout\", \"#livediv:xxxxx\", handler10);\n" +
" }\n" +
"\n" +
" var div = $(\"div\")[0];\n" +

View File

@ -51,6 +51,9 @@ const TEST_DATA = [
" var handler9 = function divKeyDown() {\n" +
" alert(9);\n" +
" };\n" +
" var handler10 = function divDragOut() {\n" +
" alert(10);\n" +
" };\n" +
"\n" +
" if ($(\"#livediv\").live) {\n" +
" $(\"#livediv\").live(\"dblclick\", handler1);\n" +
@ -65,6 +68,7 @@ const TEST_DATA = [
" if ($(\"#livediv\").on) {\n" +
" $(document).on(\"drop\", \"#livediv\", handler5);\n" +
" $(document).on(\"dragover\", \"#livediv\", handler6);\n" +
" $(document).on(\"dragout\", \"#livediv:xxxxx\", handler10);\n" +
" }\n" +
"\n" +
" var div = $(\"div\")[0];\n" +

View File

@ -34,6 +34,7 @@
var handler7 = function divClick1() { alert(7); };
var handler8 = function divClick2() { alert(8); };
var handler9 = function divKeyDown() { alert(9); };
var handler10 = function divDragOut() { alert(10); };
if ($("#livediv").live) {
$("#livediv").live( "dblclick", handler1);
@ -48,6 +49,7 @@
if ($("#livediv").on) {
$(document).on( "drop", "#livediv", handler5);
$(document).on( "dragover", "#livediv", handler6);
$(document).on( "dragout", "#livediv:xxxxx", handler10);
}
var div = $("div")[0];

View File

@ -324,38 +324,83 @@ CssHtmlTree.prototype = {
* returns null of the node isn't anything we care about
*/
getNodeInfo: function(node) {
let type, value;
if (!node) {
return null;
}
let classes = node.classList;
if (classes.contains("property-name") ||
classes.contains("property-value") ||
(classes.contains("theme-link") && !classes.contains("link"))) {
// Go up to the common parent to find the property and value
let parent = node.parentNode;
while (!parent.classList.contains("property-view")) {
parent = parent.parentNode;
// Check if the node isn't a selector first since this doesn't require
// walking the DOM
if (classes.contains("matched") ||
classes.contains("bestmatch") ||
classes.contains("parentmatch")) {
let selectorText = "";
for (let child of node.childNodes) {
if (child.nodeType === node.TEXT_NODE) {
selectorText += child.textContent;
}
}
return {
type: overlays.VIEW_NODE_SELECTOR_TYPE,
value: selectorText.trim()
}
}
// Walk up the nodes to find out where node is
let propertyView;
let propertyContent;
let parent = node;
while (parent.parentNode) {
if (parent.classList.contains("property-view")) {
propertyView = parent;
break;
}
if (parent.classList.contains("property-content")) {
propertyContent = parent;
break;
}
parent = parent.parentNode;
}
if (!propertyView && !propertyContent) {
return null;
}
let value, type;
// Get the property and value for a node that's a property name or value
let isHref = classes.contains("theme-link") && !classes.contains("link");
if (propertyView && (classes.contains("property-name") ||
classes.contains("property-value") ||
isHref)) {
value = {
property: parent.querySelector(".property-name").textContent,
value: parent.querySelector(".property-value").textContent
};
}
if (propertyContent && (classes.contains("other-property-value") ||
isHref)) {
let view = propertyContent.previousSibling;
value = {
property: view.querySelector(".property-name").textContent,
value: node.textContent
};
}
// Get the type
if (classes.contains("property-name")) {
type = overlays.VIEW_NODE_PROPERTY_TYPE;
} else if (classes.contains("property-value")) {
} else if (classes.contains("property-value") ||
classes.contains("other-property-value")) {
type = overlays.VIEW_NODE_VALUE_TYPE;
} else if (classes.contains("theme-link")) {
} else if (isHref) {
type = overlays.VIEW_NODE_IMAGE_URL_TYPE;
value.url = node.href;
} else {
return null;
}
return {
type: type,
value: value
};
return {type, value};
},
_createPropertyViews: function()

View File

@ -1248,6 +1248,10 @@ CssRuleView.prototype = {
* returns null of the node isn't anything we care about
*/
getNodeInfo: function(node) {
if (!node) {
return null;
}
let type, value;
let classes = node.classList;
let prop = getParentTextProperty(node);

View File

@ -25,6 +25,7 @@ support-files =
head.js
[browser_computedview_browser-styles.js]
[browser_computedview_getNodeInfo.js]
[browser_computedview_keybindings_01.js]
[browser_computedview_keybindings_02.js]
[browser_computedview_matched-selectors-toggle.js]

View File

@ -0,0 +1,177 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test various output of the computed-view's getNodeInfo method.
// This method is used by the style-inspector-overlay on mouseover to decide
// which tooltip or highlighter to show when hovering over a value/name/selector
// if any.
// For instance, browser_ruleview_selector-highlighter_01.js and
// browser_ruleview_selector-highlighter_02.js test that the selector
// highlighter appear when hovering over a selector in the rule-view.
// Since the code to make this work for the computed-view is 90% the same, there
// is no need for testing it again here.
// This test however serves as a unit test for getNodeInfo.
const {
VIEW_NODE_SELECTOR_TYPE,
VIEW_NODE_PROPERTY_TYPE,
VIEW_NODE_VALUE_TYPE,
VIEW_NODE_IMAGE_URL_TYPE
} = devtools.require("devtools/styleinspector/style-inspector-overlays");
const PAGE_CONTENT = [
'<style type="text/css">',
' body {',
' background: red;',
' color: white;',
' }',
' div {',
' background: green;',
' }',
' div div {',
' background-color: yellow;',
' background-image: url(chrome://global/skin/icons/warning-64.png);',
' color: red;',
' }',
'</style>',
'<div><div id="testElement">Test element</div></div>'
].join("\n");
// Each item in this array must have the following properties:
// - desc {String} will be logged for information
// - getHoveredNode {Generator Function} received the computed-view instance as
// argument and must return the node to be tested
// - assertNodeInfo {Function} should check the validity of the nodeInfo
// argument it receives
const TEST_DATA = [
{
desc: "Testing a null node",
getHoveredNode: function*() {
return null;
},
assertNodeInfo: function(nodeInfo) {
is(nodeInfo, null);
}
},
{
desc: "Testing a useless node",
getHoveredNode: function*(view) {
return view.element;
},
assertNodeInfo: function(nodeInfo) {
is(nodeInfo, null);
}
},
{
desc: "Testing a property name",
getHoveredNode: function*(view) {
return getComputedViewProperty(view, "color").nameSpan;
},
assertNodeInfo: function(nodeInfo) {
is(nodeInfo.type, VIEW_NODE_PROPERTY_TYPE);
ok("property" in nodeInfo.value);
ok("value" in nodeInfo.value);
is(nodeInfo.value.property, "color");
is(nodeInfo.value.value, "#F00");
}
},
{
desc: "Testing a property value",
getHoveredNode: function*(view) {
return getComputedViewProperty(view, "color").valueSpan;
},
assertNodeInfo: function(nodeInfo) {
is(nodeInfo.type, VIEW_NODE_VALUE_TYPE);
ok("property" in nodeInfo.value);
ok("value" in nodeInfo.value);
is(nodeInfo.value.property, "color");
is(nodeInfo.value.value, "#F00");
}
},
{
desc: "Testing an image url",
getHoveredNode: function*(view) {
let {valueSpan} = getComputedViewProperty(view, "background-image");
return valueSpan.querySelector(".theme-link");
},
assertNodeInfo: function(nodeInfo) {
is(nodeInfo.type, VIEW_NODE_IMAGE_URL_TYPE);
ok("property" in nodeInfo.value);
ok("value" in nodeInfo.value);
is(nodeInfo.value.property, "background-image");
is(nodeInfo.value.value, "url(\"chrome://global/skin/icons/warning-64.png\")");
is(nodeInfo.value.url, "chrome://global/skin/icons/warning-64.png");
}
},
{
desc: "Testing a matched rule selector (bestmatch)",
getHoveredNode: function*(view) {
let content = yield getComputedViewMatchedRules(view, "background-color");
return content.querySelector(".bestmatch");
},
assertNodeInfo: function(nodeInfo) {
is(nodeInfo.type, VIEW_NODE_SELECTOR_TYPE);
is(nodeInfo.value, "div div");
}
},
{
desc: "Testing a matched rule selector (matched)",
getHoveredNode: function*(view) {
let content = yield getComputedViewMatchedRules(view, "background-color");
return content.querySelector(".matched");
},
assertNodeInfo: function(nodeInfo) {
is(nodeInfo.type, VIEW_NODE_SELECTOR_TYPE);
is(nodeInfo.value, "div");
}
},
{
desc: "Testing a matched rule selector (parentmatch)",
getHoveredNode: function*(view) {
let content = yield getComputedViewMatchedRules(view, "color");
return content.querySelector(".parentmatch");
},
assertNodeInfo: function(nodeInfo) {
is(nodeInfo.type, VIEW_NODE_SELECTOR_TYPE);
is(nodeInfo.value, "body");
}
},
{
desc: "Testing a matched rule value",
getHoveredNode: function*(view) {
let content = yield getComputedViewMatchedRules(view, "color");
return content.querySelector(".other-property-value");
},
assertNodeInfo: function(nodeInfo) {
is(nodeInfo.type, VIEW_NODE_VALUE_TYPE);
is(nodeInfo.value.property, "color");
is(nodeInfo.value.value, "#F00");
}
},
{
desc: "Testing a matched rule stylesheet link",
getHoveredNode: function*(view) {
let content = yield getComputedViewMatchedRules(view, "color");
return content.querySelector(".rule-link .theme-link");
},
assertNodeInfo: function(nodeInfo) {
is(nodeInfo, null);
}
}
];
let test = asyncTest(function*() {
yield addTab("data:text/html;charset=utf-8," + PAGE_CONTENT);
let {inspector, view} = yield openComputedView();
yield selectNode("#testElement", inspector);
for (let {desc, getHoveredNode, assertNodeInfo} of TEST_DATA) {
info(desc);
let nodeInfo = view.getNodeInfo(yield getHoveredNode(view));
assertNodeInfo(nodeInfo);
}
});

View File

@ -23,7 +23,7 @@ let test = asyncTest(function*() {
yield selectNode("div", inspector);
info("Expanding the first property");
yield expandComputedViewPropertyByIndex(view, inspector, 0);
yield expandComputedViewPropertyByIndex(view, 0);
info("Verifying the link text");
yield verifyLinkText(view, SCSS_LOC);

View File

@ -61,7 +61,7 @@ let test = asyncTest(function*() {
function* testInlineStyle(view, inspector) {
info("Testing inline style");
yield expandComputedViewPropertyByIndex(view, inspector, 0);
yield expandComputedViewPropertyByIndex(view, 0);
let onWindow = waitForWindow();
info("Clicking on the first rule-link in the computed-view");

View File

@ -35,6 +35,8 @@ let test = asyncTest(function*() {
let {toolbox, inspector, view} = yield openComputedView();
yield testComputedView(view, inspector.selection.nodeFront);
yield testExpandedComputedViewProperty(view, inspector.selection.nodeFront);
});
function* testRuleView(ruleView, nodeFront) {
@ -77,3 +79,39 @@ function* testComputedView(computedView, nodeFront) {
let dataURL = yield getFontFamilyDataURL(valueSpan.textContent, nodeFront);
is(images[0].getAttribute("src"), dataURL, "Tooltip contains the correct data-uri image");
}
function* testExpandedComputedViewProperty(computedView, nodeFront) {
info("Testing font-family tooltips in expanded properties of the computed view");
info("Expanding the font-family property to reveal matched selectors");
let propertyView = getPropertyView(computedView, "font-family");
propertyView.matchedExpanded = true;
yield propertyView.refreshMatchedSelectors();
let valueSpan = propertyView.matchedSelectorsContainer
.querySelector(".bestmatch .other-property-value");
let tooltip = computedView.tooltips.previewTooltip;
let panel = tooltip.panel;
yield assertHoverTooltipOn(tooltip, valueSpan);
let images = panel.getElementsByTagName("image");
is(images.length, 1, "Tooltip contains an image");
ok(images[0].getAttribute("src").startsWith("data:"), "Tooltip contains a data-uri image as expected");
let dataURL = yield getFontFamilyDataURL(valueSpan.textContent, nodeFront);
is(images[0].getAttribute("src"), dataURL, "Tooltip contains the correct data-uri image");
}
function getPropertyView(computedView, name) {
let propertyView = null;
computedView.propertyViews.some(function(view) {
if (view.name == name) {
propertyView = view;
return true;
}
return false;
});
return propertyView;
}

View File

@ -28,11 +28,6 @@ let test = asyncTest(function*() {
yield selectNode("#testElement", inspector);
yield testRuleView(view, inspector.selection.nodeFront);
info("Opening the computed view");
let {toolbox, inspector, view} = yield openComputedView();
yield testComputedView(view, inspector.selection.nodeFront);
});
function* testRuleView(ruleView, nodeFront) {
@ -63,21 +58,3 @@ function* testRuleView(ruleView, nodeFront) {
let dataURL = yield getFontFamilyDataURL(valueSpan.textContent, nodeFront);
is(images[0].getAttribute("src"), dataURL, "Tooltip contains the correct data-uri image");
}
function* testComputedView(computedView, nodeFront) {
info("Testing font-family tooltips in the computed view");
let tooltip = computedView.tooltips.previewTooltip;
let panel = tooltip.panel;
let {valueSpan} = getComputedViewProperty(computedView, "font-family");
yield assertHoverTooltipOn(tooltip, valueSpan);
let images = panel.getElementsByTagName("image");
is(images.length, 1, "Tooltip contains an image");
ok(images[0].getAttribute("src").startsWith("data:"), "Tooltip contains a data-uri image as expected");
let dataURL = yield getFontFamilyDataURL(valueSpan.textContent, nodeFront);
is(images[0].getAttribute("src"), dataURL, "Tooltip contains the correct data-uri image");
}

View File

@ -752,32 +752,6 @@ let createNewRuleViewProperty = Task.async(function*(ruleEditor, inputValue) {
yield onFocus;
});
// TO BE UNCOMMENTED WHEN THE EYEDROPPER FINALLY LANDS
// /**
// * Given a color swatch in the ruleview, click on it to open the color picker
// * and then click on the eyedropper button to start the eyedropper tool
// * @param {CssRuleView} view The instance of the rule-view panel
// * @param {DOMNode} swatch The color swatch to be clicked on
// * @return A promise that resolves when the dropper is opened
// */
// let openRuleViewEyeDropper = Task.async(function*(view, swatch) {
// info("Opening the colorpicker tooltip on a colorswatch");
// let tooltip = view.colorPicker.tooltip;
// let onTooltipShown = tooltip.once("shown");
// swatch.click();
// yield onTooltipShown;
// info("Finding the eyedropper icon in the colorpicker document");
// let tooltipDoc = tooltip.content.contentDocument;
// let dropperButton = tooltipDoc.querySelector("#eyedropper-button");
// ok(dropperButton, "Found the eyedropper icon");
// info("Opening the eyedropper");
// let onOpen = tooltip.once("eyedropper-opened");
// dropperButton.click();
// return yield onOpen;
// });
/* *********************************************
* COMPUTED-VIEW
* *********************************************
@ -806,6 +780,40 @@ function getComputedViewProperty(view, name) {
return prop;
}
/**
* Get a reference to the property-content element for a given property name in
* the computed-view.
* A property-content element always follows (nextSibling) the property itself
* and is only shown when the twisty icon is expanded on the property.
* A property-content element contains matched rules, with selectors, properties,
* values and stylesheet links
* @param {CssHtmlTree} view The instance of the computed view panel
* @param {String} name The name of the property to retrieve
* @return {Promise} A promise that resolves to the property matched rules
* container
*/
let getComputedViewMatchedRules = Task.async(function*(view, name) {
let expander;
let propertyContent;
for (let property of view.styleDocument.querySelectorAll(".property-view")) {
let nameSpan = property.querySelector(".property-name");
if (nameSpan.textContent === name) {
expander = property.querySelector(".expandable");
propertyContent = property.nextSibling;
break;
}
}
if (!expander.hasAttribute("open")) {
// Need to expand the property
let onExpand = view.inspector.once("computed-view-property-expanded");
expander.click();
yield onExpand;
}
return propertyContent;
});
/**
* Get the text value of the property corresponding to a given name in the
* computed-view
@ -813,8 +821,8 @@ function getComputedViewProperty(view, name) {
* @param {String} name The name of the property to retrieve
* @return {String} The property value
*/
function getComputedViewPropertyValue(view, selectorText, propertyName) {
return getComputedViewProperty(view, selectorText, propertyName)
function getComputedViewPropertyValue(view, name, propertyName) {
return getComputedViewProperty(view, name, propertyName)
.valueSpan.textContent;
}
@ -822,19 +830,18 @@ function getComputedViewPropertyValue(view, selectorText, propertyName) {
* Expand a given property, given its index in the current property list of
* the computed view
* @param {CssHtmlTree} view The instance of the computed view panel
* @param {InspectorPanel} inspector The instance of the inspector panel
* @param {Number} index The index of the property to be expanded
* @return a promise that resolves when the property has been expanded, or
* rejects if the property was not found
*/
function expandComputedViewPropertyByIndex(view, inspector, index) {
function expandComputedViewPropertyByIndex(view, index) {
info("Expanding property " + index + " in the computed view");
let expandos = view.styleDocument.querySelectorAll(".expandable");
if (!expandos.length || !expandos[index]) {
return promise.reject();
}
let onExpand = inspector.once("computed-view-property-expanded");
let onExpand = view.inspector.once("computed-view-property-expanded");
expandos[index].click();
return onExpand;
}

View File

@ -147,13 +147,18 @@ const HISTORY_FORWARD = 1;
const GROUP_INDENT = 12;
// The number of messages to display in a single display update. If we display
// too many messages at once we slow the Firefox UI too much.
// too many messages at once we slow down the Firefox UI too much.
const MESSAGES_IN_INTERVAL = DEFAULT_LOG_LIMIT;
// The delay between display updates - tells how often we should *try* to push
// new messages to screen. This value is optimistic, updates won't always
// happen. Keep this low so the Web Console output feels live.
const OUTPUT_INTERVAL = 50; // milliseconds
const OUTPUT_INTERVAL = 20; // milliseconds
// The maximum amount of time that can be spent doing cleanup inside of the
// flush output callback. If things don't get cleaned up in this time,
// then it will start again the next time it is called.
const MAX_CLEANUP_TIME = 10; // milliseconds
// When the output queue has more than MESSAGES_IN_INTERVAL items we throttle
// output updates to this number of milliseconds. So during a lot of output we
@ -190,6 +195,7 @@ function WebConsoleFrame(aWebConsoleOwner)
this._repeatNodes = {};
this._outputQueue = [];
this._itemDestroyQueue = [];
this._pruneCategoriesQueue = {};
this._networkRequests = {};
this.filterPrefs = {};
@ -2048,9 +2054,7 @@ WebConsoleFrame.prototype = {
this._outputQueue.push([aCategory, aMethodOrNode, aArguments]);
if (!this._outputTimerInitialized) {
this._initOutputTimer();
}
this._initOutputTimer();
},
/**
@ -2062,21 +2066,31 @@ WebConsoleFrame.prototype = {
*/
_flushMessageQueue: function WCF__flushMessageQueue()
{
this._outputTimerInitialized = false;
if (!this._outputTimer) {
return;
}
let timeSinceFlush = Date.now() - this._lastOutputFlush;
if (this._outputQueue.length > MESSAGES_IN_INTERVAL &&
timeSinceFlush < THROTTLE_UPDATES) {
this._initOutputTimer();
return;
}
let startTime = Date.now();
let timeSinceFlush = startTime - this._lastOutputFlush;
let shouldThrottle = this._outputQueue.length > MESSAGES_IN_INTERVAL &&
timeSinceFlush < THROTTLE_UPDATES;
// Determine how many messages we can display now.
let toDisplay = Math.min(this._outputQueue.length, MESSAGES_IN_INTERVAL);
if (toDisplay < 1) {
this._outputTimerInitialized = false;
// If there aren't any messages to display (because of throttling or an
// empty queue), then take care of some cleanup. Destroy items that were
// pruned from the outputQueue before being displayed.
if (shouldThrottle || toDisplay < 1) {
while (this._itemDestroyQueue.length) {
if ((Date.now() - startTime) > MAX_CLEANUP_TIME) {
break;
}
this._destroyItem(this._itemDestroyQueue.pop());
}
this._initOutputTimer();
return;
}
@ -2088,21 +2102,22 @@ WebConsoleFrame.prototype = {
}
let batch = this._outputQueue.splice(0, toDisplay);
if (!batch.length) {
this._outputTimerInitialized = false;
return;
}
let outputNode = this.outputNode;
let lastVisibleNode = null;
let scrollNode = outputNode.parentNode;
let scrolledToBottom = Utils.isOutputScrolledToBottom(outputNode);
let hudIdSupportsString = WebConsoleUtils.supportsString(this.hudId);
// We won't bother to try to restore scroll position if this is showing
// a lot of messages at once (and there are still items in the queue).
// It is going to purge whatever you were looking at anyway.
let scrolledToBottom = shouldPrune ||
Utils.isOutputScrolledToBottom(outputNode);
// Output the current batch of messages.
let newMessages = new Set();
let updatedMessages = new Set();
for (let item of batch) {
for (let i = 0; i < batch.length; i++) {
let item = batch[i];
let result = this._outputMessageFromQueue(hudIdSupportsString, item);
if (result) {
if (result.isRepeated) {
@ -2118,12 +2133,15 @@ WebConsoleFrame.prototype = {
}
let oldScrollHeight = 0;
// Prune messages if needed. We do not do this for every flush call to
// improve performance.
let removedNodes = 0;
// Prune messages from the DOM, but only if needed.
if (shouldPrune || !this._outputQueue.length) {
oldScrollHeight = scrollNode.scrollHeight;
// Only bother measuring the scrollHeight if not scrolled to bottom,
// since the oldScrollHeight will not be used if it is.
if (!scrolledToBottom) {
oldScrollHeight = scrollNode.scrollHeight;
}
let categories = Object.keys(this._pruneCategoriesQueue);
categories.forEach(function _pruneOutput(aCategory) {
@ -2156,17 +2174,15 @@ WebConsoleFrame.prototype = {
this.emit("messages-updated", updatedMessages);
}
// If the queue is not empty, schedule another flush.
if (this._outputQueue.length > 0) {
this._initOutputTimer();
}
else {
this._outputTimerInitialized = false;
if (this._flushCallback && this._flushCallback() === false) {
// If the output queue is empty, then run _flushCallback.
if (this._outputQueue.length === 0 && this._flushCallback) {
if (this._flushCallback() === false) {
this._flushCallback = null;
}
}
this._initOutputTimer();
this._lastOutputFlush = Date.now();
},
@ -2176,7 +2192,13 @@ WebConsoleFrame.prototype = {
*/
_initOutputTimer: function WCF__initOutputTimer()
{
if (!this._outputTimer) {
let panelIsDestroyed = !this._outputTimer;
let alreadyScheduled = this._outputTimerInitialized;
let nothingToDo = !this._itemDestroyQueue.length &&
!this._outputQueue.length;
// Don't schedule a callback in the following cases:
if (panelIsDestroyed || alreadyScheduled || nothingToDo) {
return;
}
@ -2274,7 +2296,7 @@ WebConsoleFrame.prototype = {
let n = Math.max(0, indexes.length - limit);
pruned += n;
for (let i = n - 1; i >= 0; i--) {
this._pruneItemFromQueue(this._outputQueue[indexes[i]]);
this._itemDestroyQueue.push(this._outputQueue[indexes[i]]);
this._outputQueue.splice(indexes[i], 1);
}
}
@ -2284,17 +2306,18 @@ WebConsoleFrame.prototype = {
},
/**
* Prune an item from the output queue.
* Destroy an item that was once in the outputQueue but isn't needed
* after all.
*
* @private
* @param array aItem
* The item you want to remove from the output queue.
* The item you want to destroy. Does not remove it from the output
* queue.
*/
_pruneItemFromQueue: function WCF__pruneItemFromQueue(aItem)
_destroyItem: function WCF__destroyItem(aItem)
{
// TODO: handle object releasing in a more elegant way once all console
// messages use the new API - bug 778766.
let [category, methodOrNode, args] = aItem;
if (typeof methodOrNode != "function" && methodOrNode._objectActors) {
for (let actor of methodOrNode._objectActors) {
@ -2370,9 +2393,7 @@ WebConsoleFrame.prototype = {
let messageNodes = this.outputNode.querySelectorAll(".message[category=" +
CATEGORY_CLASS_FRAGMENTS[aCategory] + "]");
let n = Math.max(0, messageNodes.length - logLimit);
let toRemove = Array.prototype.slice.call(messageNodes, 0, n);
toRemove.forEach(this.removeOutputMessage, this);
[...messageNodes].slice(0, n).forEach(this.removeOutputMessage, this);
return n;
},
@ -2415,9 +2436,7 @@ WebConsoleFrame.prototype = {
aNode._variablesView = null;
}
if (aNode.parentNode) {
aNode.parentNode.removeChild(aNode);
}
aNode.remove();
},
/**
@ -2897,7 +2916,10 @@ WebConsoleFrame.prototype = {
gDevTools.off("pref-changed", this._onToolboxPrefChanged);
this._repeatNodes = {};
this._outputQueue.forEach(this._destroyItem, this);
this._outputQueue = [];
this._itemDestroyQueue.forEach(this._destroyItem, this);
this._itemDestroyQueue = [];
this._pruneCategoriesQueue = {};
this._networkRequests = {};
@ -2906,7 +2928,6 @@ WebConsoleFrame.prototype = {
this._outputTimer.cancel();
}
this._outputTimer = null;
if (this.jsterm) {
this.jsterm.destroy();
this.jsterm = null;
@ -3787,7 +3808,7 @@ JSTerm.prototype = {
}
hud.groupDepth = 0;
hud._outputQueue.forEach(hud._pruneItemFromQueue, hud);
hud._outputQueue.forEach(hud._destroyItem, hud);
hud._outputQueue = [];
hud._networkRequests = {};
hud._repeatNodes = {};

View File

@ -89,6 +89,7 @@ SimulatorRuntime.prototype = {
return promise.reject("Can't find simulator: " + this.getName());
}
return simulator.launch({port: port}).then(() => {
connection.host = "localhost";
connection.port = port;
connection.keepConnecting = true;
connection.once(Connection.Events.DISCONNECTED, simulator.close);
@ -109,8 +110,8 @@ let gLocalRuntime = {
DebuggerServer.init();
DebuggerServer.addBrowserActors();
}
connection.port = null;
connection.host = null; // Force Pipe transport
connection.port = null;
connection.connect();
return promise.resolve();
},

View File

@ -300,6 +300,7 @@
@BINPATH@/components/shistory.xpt
@BINPATH@/components/spellchecker.xpt
@BINPATH@/components/storage.xpt
@BINPATH@/components/toolkit_filewatcher.xpt
@BINPATH@/components/toolkit_finalizationwitness.xpt
@BINPATH@/components/toolkit_formautofill.xpt
@BINPATH@/components/toolkit_osfile.xpt

View File

@ -6,6 +6,7 @@ support-files =
[browser_BrowserUITelemetry_buckets.js]
[browser_ContentSearch.js]
skip-if = e10s
support-files =
contentSearch.js
contentSearchBadImage.xml

Binary file not shown.

Before

Width:  |  Height:  |  Size: 883 B

After

Width:  |  Height:  |  Size: 874 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 811 B

After

Width:  |  Height:  |  Size: 742 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

@ -4,7 +4,7 @@ export LIB=/d/msvs10/vc/lib:/d/msvs10/vc/atlmfc/lib:/d/sdks/v7.0/lib:/d/msvs8/VC
export PATH="/d/msvs10/VSTSDB/Deploy:/d/msvs10/Common7/IDE/:/d/msvs10/VC/BIN:/d/msvs10/Common7/Tools:/d/msvs10/VC/VCPackages:${PATH}"
export WIN32_REDIST_DIR=/d/msvs10/VC/redist/x86/Microsoft.VC100.CRT
. $topsrcdir/build/mozconfig.vs2010-common
. $topsrcdir/build/mozconfig.vs-common
mk_export_correct_style LIB
mk_export_correct_style LIBPATH

View File

@ -25,7 +25,7 @@ export PATH="/c/Program Files (x86)/Windows Kits/8.0/bin/x86:${_VSPATH}/Common7/
## WindowsSDKDir ##
export WINDOWSSDKDIR="/c/Program Files (x86)/Windows Kits/8.0/"
. $topsrcdir/build/mozconfig.vs2010-common
. $topsrcdir/build/mozconfig.vs-common
mk_export_correct_style LIB
mk_export_correct_style LIBPATH

View File

@ -0,0 +1,28 @@
_VSPATH="/c/tools/vs2013"
export WIN32_REDIST_DIR=${_VSPATH}/VC/redist/x86/Microsoft.VC120.CRT
## moz tools location for 64-bit builders ##
export MOZ_TOOLS=C:/mozilla-build/moztools
## includes: win8 sdk includes, winrt headers for metro, msvc std library, directx sdk for d3d9 ##
export INCLUDE=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/shared:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/um:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt/wrl:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt/wrl/wrappers:${_VSPATH}/vc/include:${_VSPATH}/vc/atlmfc/include:/c/tools/sdks/dx10/include
## libs: win8 sdk x86 (32-bit) libs, msvc (32-bit) std library, msvc atl libs, directx sdk (32-bit) for d3d9 ##
export LIBPATH=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/Lib/win8/um/x86:${_VSPATH}/vc/lib:${_VSPATH}/vc/atlmfc/lib:/c/tools/sdks/dx10/lib
export LIB=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/Lib/win8/um/x86:${_VSPATH}/vc/lib:${_VSPATH}/vc/atlmfc/lib:/c/tools/sdks/dx10/lib
## paths: win8 sdk x86 (32-bit) tools, msvc (64-bit compiling 32-bit) build toolchain, moz tools ##
export PATH="/c/Program Files (x86)/Windows Kits/8.0/bin/x86:${_VSPATH}/Common7/IDE:${_VSPATH}/VC/BIN/amd64_x86:${_VSPATH}/VC/BIN/amd64:${_VSPATH}/Common7/Tools:${_VSPATH}/VC/VCPackages:/c/mozilla-build/moztools:${PATH}"
## WindowsSDKDir ##
export WINDOWSSDKDIR="/c/Program Files (x86)/Windows Kits/8.0/"
. $topsrcdir/build/mozconfig.vs-common
mk_export_correct_style LIB
mk_export_correct_style LIBPATH
mk_export_correct_style PATH
mk_export_correct_style INCLUDE
mk_export_correct_style WIN32_REDIST_DIR
mk_add_options "export MOZ_TOOLS=$MOZ_TOOLS"

View File

@ -31,7 +31,7 @@ else
export LD=c:/tools/msvs10/VC/BIN/x86_amd64/link.exe
fi
. $topsrcdir/build/mozconfig.vs2010-common
. $topsrcdir/build/mozconfig.vs-common
mk_export_correct_style LIB
mk_export_correct_style LIBPATH

View File

@ -0,0 +1,23 @@
_VSPATH="/c/tools/vs2013"
export WIN32_REDIST_DIR=${_VSPATH}/VC/redist/x64/Microsoft.VC120.CRT
## includes: win8 sdk includes, winrt headers for metro, msvc 10 std library, directx sdk for d3d9 ##
export INCLUDE=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/shared:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/um:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt/wrl:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt/wrl/wrappers:${_VSPATH}/vc/include:${_VSPATH}/vc/atlmfc/include:/c/tools/sdks/dx10/include
## libs: win8 sdk x64 (64-bit) libs, msvc 10 (64-bit) std library, msvc 10 atl libs, directx sdk (64-bit) for d3d9 ##
export LIBPATH=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/Lib/win8/um/x64:${_VSPATH}/vc/lib/amd64:${_VSPATH}/vc/atlmfc/lib/amd64:/c/tools/sdks/dx10/lib/x64
export LIB=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/Lib/win8/um/x64:${_VSPATH}/vc/lib/amd64:${_VSPATH}/vc/atlmfc/lib/amd64:/c/tools/sdks/dx10/lib/x64
## paths: win8 sdk x64 (64-bit) tools, msvc 10 (64-bit) build toolchain, moz tools ##
export PATH="/c/Program Files (x86)/Windows Kits/8.0/bin/x64:${_VSPATH}/Common7/IDE:${_VSPATH}/VC/BIN/amd64:${_VSPATH}/VC/BIN/x86_amd64:${_VSPATH}/VC/BIN:${_VSPATH}/Common7/Tools:${_VSPATH}/VC/VCPackages:${PATH}"
## WindowsSDKDir ##
export WINDOWSSDKDIR="/c/Program Files (x86)/Windows Kits/8.0/"
. $topsrcdir/build/mozconfig.vs-common
mk_export_correct_style LIB
mk_export_correct_style LIBPATH
mk_export_correct_style PATH
mk_export_correct_style INCLUDE
mk_export_correct_style WIN32_REDIST_DIR

View File

@ -34,7 +34,7 @@ public:
virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
nsNullPrincipalURI(const nsCString &aSpec);
explicit nsNullPrincipalURI(const nsCString &aSpec);
private:
~nsNullPrincipalURI() {}

View File

@ -123,7 +123,7 @@ protected:
class nsExpandedPrincipal : public nsIExpandedPrincipal, public nsBasePrincipal
{
public:
nsExpandedPrincipal(nsTArray< nsCOMPtr<nsIPrincipal> > &aWhiteList);
explicit nsExpandedPrincipal(nsTArray< nsCOMPtr<nsIPrincipal> > &aWhiteList);
protected:
virtual ~nsExpandedPrincipal();

View File

@ -127,7 +127,7 @@ class nsChromeRegistryChrome : public nsChromeRegistry
typedef nsURIHashKey::KeyType KeyType;
typedef nsURIHashKey::KeyTypePointer KeyTypePointer;
OverlayListEntry(KeyTypePointer aKey) : nsURIHashKey(aKey) { }
explicit OverlayListEntry(KeyTypePointer aKey) : nsURIHashKey(aKey) { }
OverlayListEntry(OverlayListEntry&& toMove) : nsURIHashKey(mozilla::Move(toMove)),
mArray(mozilla::Move(toMove.mArray)) { }
~OverlayListEntry() { }

View File

@ -359,19 +359,25 @@ JAVA_GEN_DIR = _javagen
JAVA_DIST_DIR = $(DEPTH)/$(JAVA_GEN_DIR)
JAVA_IFACES_PKG_NAME = org/mozilla/interfaces
OS_INCLUDES += $(MOZ_JPEG_CFLAGS) $(MOZ_PNG_CFLAGS) $(MOZ_ZLIB_CFLAGS) $(MOZ_PIXMAN_CFLAGS)
# NSPR_CFLAGS and NSS_CFLAGS must appear ahead of OS_INCLUDES to avoid Linux
# builds wrongly picking up system NSPR/NSS header files.
INCLUDES = \
-I$(srcdir) \
-I. \
$(LOCAL_INCLUDES) \
-I$(DIST)/include \
$(NULL)
ifndef IS_GYP_DIR
# NSPR_CFLAGS and NSS_CFLAGS must appear ahead of the other flags to avoid Linux
# builds wrongly picking up system NSPR/NSS header files.
OS_INCLUDES := \
$(if $(LIBXUL_SDK),-I$(LIBXUL_SDK)/include) \
$(NSPR_CFLAGS) $(NSS_CFLAGS) \
$(OS_INCLUDES) \
$(MOZ_JPEG_CFLAGS) \
$(MOZ_PNG_CFLAGS) \
$(MOZ_ZLIB_CFLAGS) \
$(MOZ_PIXMAN_CFLAGS) \
$(NULL)
endif
include $(topsrcdir)/config/static-checking-config.mk
@ -483,8 +489,8 @@ OS_COMPILE_CMMFLAGS += -fobjc-abi-version=2 -fobjc-legacy-dispatch
endif
endif
COMPILE_CFLAGS = $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CFLAGS) $(CFLAGS) $(MOZBUILD_CFLAGS) $(EXTRA_COMPILE_FLAGS)
COMPILE_CXXFLAGS = $(if $(DISABLE_STL_WRAPPING),,$(STL_FLAGS)) $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CXXFLAGS) $(CXXFLAGS) $(MOZBUILD_CXXFLAGS) $(EXTRA_COMPILE_FLAGS)
COMPILE_CFLAGS = $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(OS_INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CFLAGS) $(CFLAGS) $(MOZBUILD_CFLAGS) $(EXTRA_COMPILE_FLAGS)
COMPILE_CXXFLAGS = $(if $(DISABLE_STL_WRAPPING),,$(STL_FLAGS)) $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(OS_INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CXXFLAGS) $(CXXFLAGS) $(MOZBUILD_CXXFLAGS) $(EXTRA_COMPILE_FLAGS)
COMPILE_CMFLAGS = $(OS_COMPILE_CMFLAGS) $(MOZBUILD_CMFLAGS) $(EXTRA_COMPILE_FLAGS)
COMPILE_CMMFLAGS = $(OS_COMPILE_CMMFLAGS) $(MOZBUILD_CMMFLAGS) $(EXTRA_COMPILE_FLAGS)
ASFLAGS += $(EXTRA_ASSEMBLER_FLAGS)
@ -750,22 +756,5 @@ export NONASCII
DEFINES += -DNO_NSPR_10_SUPPORT
ifdef IS_GYP_DIR
LOCAL_INCLUDES += \
-I$(topsrcdir)/ipc/chromium/src \
-I$(topsrcdir)/ipc/glue \
-I$(DEPTH)/ipc/ipdl/_ipdlheaders \
$(NULL)
ifeq (WINNT,$(OS_TARGET))
# These get set via VC project file settings for normal GYP builds.
DEFINES += -DUNICODE -D_UNICODE
endif
DISABLE_STL_WRAPPING := 1
# Skip most Mozilla-specific include locations.
INCLUDES = -I. $(LOCAL_INCLUDES) -I$(DEPTH)/dist/include
endif
# Freeze the values specified by moz.build to catch them if they fail.
$(foreach var,$(_MOZBUILD_EXTERNAL_VARIABLES) $(_DEPRECATED_VARIABLES),$(eval $(var)_FROZEN := '$($(var))'))

View File

@ -142,6 +142,9 @@ public:
protected:
double mX, mY, mWidth, mHeight;
private:
~DOMRect() {};
};
class DOMRectList MOZ_FINAL : public nsIDOMClientRectList,
@ -210,12 +213,6 @@ protected:
}
template<>
struct HasDangerousPublicDestructor<dom::DOMRect>
{
static const bool value = true;
};
}
#endif /*MOZILLA_DOMRECT_H_*/

View File

@ -1601,6 +1601,12 @@ nsDocument::~nsDocument()
NS_ASSERTION(!mIsShowing, "Destroying a currently-showing document");
// Note: This assert is only non-fatal because mochitest-bc triggers
// it... as well as the preceding assert about !mIsShowing.
NS_ASSERTION(!mObservingAppThemeChanged,
"Document leaked to shutdown, then the observer service dropped "
"its ref to us so we were able to go away.");
if (IsTopLevelContentDocument()) {
//don't report for about: pages
nsCOMPtr<nsIPrincipal> principal = GetPrincipal();
@ -8873,7 +8879,10 @@ nsDocument::OnPageShow(bool aPersisted,
"chrome-page-shown" :
"content-page-shown",
nullptr);
os->AddObserver(this, "app-theme-changed", /* ownsWeak */ false);
if (!mObservingAppThemeChanged) {
os->AddObserver(this, "app-theme-changed", /* ownsWeak */ false);
mObservingAppThemeChanged = true;
}
DispatchPageTransition(target, NS_LITERAL_STRING("pageshow"), aPersisted);
}
@ -8949,6 +8958,7 @@ nsDocument::OnPageHide(bool aPersisted,
nullptr);
os->RemoveObserver(this, "app-theme-changed");
mObservingAppThemeChanged = false;
}
DispatchPageTransition(target, NS_LITERAL_STRING("pagehide"), aPersisted);

View File

@ -1598,6 +1598,12 @@ public:
bool mAsyncFullscreenPending:1;
// Whether we're observing the "app-theme-changed" observer service
// notification. We need to keep track of this because we might get multiple
// OnPageShow notifications in a row without an OnPageHide in between, if
// we're getting document.open()/close() called on us.
bool mObservingAppThemeChanged:1;
// Keeps track of whether we have a pending
// 'style-sheet-applicable-state-changed' notification.
bool mSSApplicableStateNotificationPending:1;

View File

@ -26,10 +26,10 @@ class GlobalObject;
} // namespace dom
} // namespace mozilla
class nsFormData : public nsIDOMFormData,
public nsIXHRSendable,
public nsFormSubmission,
public nsWrapperCache
class nsFormData MOZ_FINAL : public nsIDOMFormData,
public nsIXHRSendable,
public nsFormSubmission,
public nsWrapperCache
{
~nsFormData() {}

View File

@ -1051,6 +1051,9 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
nsCOMPtr<EventTarget> otherChromeEventHandler =
do_QueryInterface(otherWindow->GetChromeEventHandler());
nsCOMPtr<EventTarget> ourEventTarget = ourWindow->GetParentTarget();
nsCOMPtr<EventTarget> otherEventTarget = otherWindow->GetParentTarget();
NS_ASSERTION(SameCOMIdentity(ourFrameElement, ourContent) &&
SameCOMIdentity(otherFrameElement, otherContent) &&
SameCOMIdentity(ourChromeEventHandler, ourContent) &&
@ -1100,25 +1103,25 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
// Fire pageshow events on still-loading pages, and then fire pagehide
// events. Note that we do NOT fire these in the normal way, but just fire
// them on the chrome event handlers.
FirePageShowEvent(ourDocshell, ourChromeEventHandler, false);
FirePageShowEvent(otherDocshell, otherChromeEventHandler, false);
FirePageHideEvent(ourDocshell, ourChromeEventHandler);
FirePageHideEvent(otherDocshell, otherChromeEventHandler);
FirePageShowEvent(ourDocshell, ourEventTarget, false);
FirePageShowEvent(otherDocshell, otherEventTarget, false);
FirePageHideEvent(ourDocshell, ourEventTarget);
FirePageHideEvent(otherDocshell, otherEventTarget);
nsIFrame* ourFrame = ourContent->GetPrimaryFrame();
nsIFrame* otherFrame = otherContent->GetPrimaryFrame();
if (!ourFrame || !otherFrame) {
mInSwap = aOther->mInSwap = false;
FirePageShowEvent(ourDocshell, ourChromeEventHandler, true);
FirePageShowEvent(otherDocshell, otherChromeEventHandler, true);
FirePageShowEvent(ourDocshell, ourEventTarget, true);
FirePageShowEvent(otherDocshell, otherEventTarget, true);
return NS_ERROR_NOT_IMPLEMENTED;
}
nsSubDocumentFrame* ourFrameFrame = do_QueryFrame(ourFrame);
if (!ourFrameFrame) {
mInSwap = aOther->mInSwap = false;
FirePageShowEvent(ourDocshell, ourChromeEventHandler, true);
FirePageShowEvent(otherDocshell, otherChromeEventHandler, true);
FirePageShowEvent(ourDocshell, ourEventTarget, true);
FirePageShowEvent(otherDocshell, otherEventTarget, true);
return NS_ERROR_NOT_IMPLEMENTED;
}
@ -1126,8 +1129,8 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
rv = ourFrameFrame->BeginSwapDocShells(otherFrame);
if (NS_FAILED(rv)) {
mInSwap = aOther->mInSwap = false;
FirePageShowEvent(ourDocshell, ourChromeEventHandler, true);
FirePageShowEvent(otherDocshell, otherChromeEventHandler, true);
FirePageShowEvent(ourDocshell, ourEventTarget, true);
FirePageShowEvent(otherDocshell, otherEventTarget, true);
return rv;
}
@ -1230,8 +1233,8 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
ourParentDocument->FlushPendingNotifications(Flush_Layout);
otherParentDocument->FlushPendingNotifications(Flush_Layout);
FirePageShowEvent(ourDocshell, otherChromeEventHandler, true);
FirePageShowEvent(otherDocshell, ourChromeEventHandler, true);
FirePageShowEvent(ourDocshell, ourEventTarget, true);
FirePageShowEvent(otherDocshell, otherEventTarget, true);
mInSwap = aOther->mInSwap = false;
return NS_OK;

View File

@ -1035,6 +1035,16 @@ nsObjectLoadingContent::BuildParametersArray()
}
nsAdoptingCString wmodeOverride = Preferences::GetCString("plugins.force.wmode");
#if defined(XP_WIN) || defined(XP_LINUX)
// Bug 923745 (/Bug 1061995) - Until we support windowed mode plugins in
// content processes, force flash to use a windowless rendering mode. This
// hack should go away when bug 923746 lands. (OS X plugins always use some
// native widgets, so unfortunately this does not help there)
if (wmodeOverride.IsEmpty() &&
XRE_GetProcessType() == GeckoProcessType_Content) {
wmodeOverride.AssignLiteral("transparent");
}
#endif
for (uint32_t i = 0; i < mCachedAttributes.Length(); i++) {
if (!wmodeOverride.IsEmpty() && mCachedAttributes[i].mName.EqualsIgnoreCase("wmode")) {

View File

@ -35,7 +35,7 @@ class AutoJSAPI;
// Script loader implementation
//////////////////////////////////////////////////////////////
class nsScriptLoader : public nsIStreamLoaderObserver
class nsScriptLoader MOZ_FINAL : public nsIStreamLoaderObserver
{
class MOZ_STACK_CLASS AutoCurrentScriptUpdater
{

View File

@ -7,3 +7,5 @@ skip-if = e10s # Bug ?????? - test e10s utils don't support load events from ifr
[browser_state_notifications.js]
# skip-if = e10s # Bug ?????? - content-document-* notifications come while document's URI is still about:blank, but test expects real URL.
skip-if = true # Intermittent failures - bug 987493. Restore the skip-if above once fixed
[browser_bug1058164.js]
skip-if = e10s # We need bug 918634 to land before this can be tested with e10s.

View File

@ -0,0 +1,106 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const kTimeout = 5000; // ms
/**
* Frame script injected in the test browser that sends
* messages when it sees the pagehide and pageshow events
* with the persisted property set to true.
*/
function frame_script() {
addEventListener("pageshow", (event) => {
if (event.persisted) {
sendAsyncMessage("test:pageshow");
}
});
addEventListener("pagehide", (event) => {
if (event.persisted) {
sendAsyncMessage("test:pagehide");
}
});
}
/**
* Return a Promise that resolves when the browser's frame
* script sees an event of type eventType. eventType can be
* either "pagehide" or "pageshow". Times out after kTimeout
* milliseconds if the event is never seen.
*/
function prepareForPageEvent(browser, eventType) {
return new Promise((resolve, reject) => {
let mm = browser.messageManager;
let timeoutId = setTimeout(() => {
ok(false, "Timed out waiting for " + eventType)
reject();
}, kTimeout);
mm.addMessageListener("test:" + eventType, function onSawEvent(message) {
mm.removeMessageListener("test:" + eventType, onSawEvent);
ok(true, "Saw " + eventType + " event in frame script.");
clearTimeout(timeoutId);
resolve();
});
});
}
/**
* Returns a Promise that resolves when both the pagehide
* and pageshow events have been seen from the frame script.
*/
function prepareForPageHideAndShow(browser) {
return Promise.all([prepareForPageEvent(browser, "pagehide"),
prepareForPageEvent(browser, "pageshow")]);
}
/**
* Returns a Promise that resolves when the load event for
* aWindow fires during the capture phase.
*/
function waitForLoad(aWindow) {
return new Promise((resolve, reject) => {
aWindow.addEventListener("load", function onLoad(aEvent) {
aWindow.removeEventListener("load", onLoad, true);
resolve();
}, true);
});
}
/**
* Tests that frame scripts get pageshow / pagehide events when
* swapping browser frameloaders (which occurs when moving a tab
* into a different window).
*/
add_task(function* test_swap_frameloader_pagevisibility_events() {
// Inject our frame script into a new browser.
let tab = gBrowser.addTab();
gBrowser.selectedTab = tab;
let mm = window.getGroupMessageManager("browsers");
mm.loadFrameScript("data:,(" + frame_script.toString() + ")();", true);
let browser = gBrowser.selectedBrowser;
// Swap the browser out to a new window
let newWindow = gBrowser.replaceTabWithWindow(tab);
// We have to wait for the window to load so we can get the selected browser
// to listen to.
yield waitForLoad(newWindow);
let pageHideAndShowPromise = prepareForPageHideAndShow(newWindow.gBrowser.selectedBrowser);
// Yield waiting for the pagehide and pageshow events.
yield pageHideAndShowPromise;
// Send the browser back to its original window
let newTab = gBrowser.addTab();
gBrowser.selectedTab = newTab;
browser = newWindow.gBrowser.selectedBrowser;
pageHideAndShowPromise = prepareForPageHideAndShow(gBrowser.selectedBrowser);
gBrowser.swapBrowsersAndCloseOther(newTab, newWindow.gBrowser.selectedTab);
// Yield waiting for the pagehide and pageshow events.
yield pageHideAndShowPromise;
gBrowser.removeTab(gBrowser.selectedTab);
});

View File

@ -48,9 +48,9 @@ protected:
nsRefPtr<HTMLPropertiesCollection> mCollection;
};
class HTMLPropertiesCollection : public nsIHTMLCollection,
public nsStubMutationObserver,
public nsWrapperCache
class HTMLPropertiesCollection MOZ_FINAL : public nsIHTMLCollection,
public nsStubMutationObserver,
public nsWrapperCache
{
friend class PropertyNodeList;
friend class PropertyStringList;

View File

@ -65,11 +65,6 @@ public:
// Can be called on any thread.
virtual void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded) = 0;
// Returns the end time of the last sample in the media. Note that a media
// can have a non-zero start time, so the end time may not necessarily be
// the same as the duration (i.e. duration is (end_time - start_time)).
virtual int64_t GetEndMediaTime() const = 0;
// Return the duration of the media in microseconds.
virtual int64_t GetMediaDuration() = 0;

View File

@ -17,6 +17,20 @@ extern PRLogModuleInfo* gMediaStreamGraphLog;
#define STREAM_LOG(type, msg)
#endif
// We don't use NSPR log here because we want this interleaved with adb logcat
// on Android/B2G
// #define ENABLE_LIFECYCLE_LOG
#ifdef ENABLE_LIFECYCLE_LOG
#ifdef ANDROID
#include "android/log.h"
#define LIFECYCLE_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gecko - MSG" , ## __VA_ARGS__); printf(__VA_ARGS__);printf("\n");
#else
#define LIFECYCLE_LOG(...) printf(__VA_ARGS__);printf("\n");
#endif
#else
#define LIFECYCLE_LOG(...)
#endif
namespace mozilla {
struct AutoProfilerUnregisterThread
@ -68,10 +82,12 @@ void GraphDriver::SetGraphTime(GraphDriver* aPreviousDriver,
void GraphDriver::SwitchAtNextIteration(GraphDriver* aNextDriver)
{
STREAM_LOG(PR_LOG_DEBUG, ("Switching to new driver: %p (%s)", aNextDriver, aNextDriver->AsAudioCallbackDriver() ? "AudioCallbackDriver" : "SystemClockDriver"));
LIFECYCLE_LOG("Switching to new driver: %p (%s)",
aNextDriver, aNextDriver->AsAudioCallbackDriver() ?
"AudioCallbackDriver" : "SystemClockDriver");
// Sometimes we switch twice to a new driver per iteration, this is probably a
// bug.
MOZ_ASSERT(!mNextDriver || !mNextDriver->AsAudioCallbackDriver());
MOZ_ASSERT(!mNextDriver || mNextDriver->AsAudioCallbackDriver());
mNextDriver = aNextDriver;
}
@ -115,6 +131,47 @@ void GraphDriver::EnsureNextIterationLocked()
mNeedAnotherIteration = true;
}
class MediaStreamGraphShutdownThreadRunnable : public nsRunnable {
public:
explicit MediaStreamGraphShutdownThreadRunnable(GraphDriver* aDriver)
: mDriver(aDriver)
{
}
NS_IMETHOD Run()
{
MOZ_ASSERT(NS_IsMainThread());
LIFECYCLE_LOG("MediaStreamGraphShutdownThreadRunnable for graph %p",
mDriver->GraphImpl());
// We can't release an audio driver on the main thread, because it can be
// blocking.
if (mDriver->AsAudioCallbackDriver()) {
LIFECYCLE_LOG("Releasing audio driver off main thread.");
nsRefPtr<AsyncCubebTask> releaseEvent =
new AsyncCubebTask(mDriver->AsAudioCallbackDriver(),
AsyncCubebTask::SHUTDOWN);
mDriver = nullptr;
releaseEvent->Dispatch();
} else {
LIFECYCLE_LOG("Dropping driver reference for SystemClockDriver.");
mDriver = nullptr;
}
return NS_OK;
}
private:
nsRefPtr<GraphDriver> mDriver;
};
void GraphDriver::Shutdown()
{
if (AsAudioCallbackDriver()) {
LIFECYCLE_LOG("Releasing audio driver off main thread (GraphDriver::Shutdown).\n");
nsRefPtr<AsyncCubebTask> releaseEvent =
new AsyncCubebTask(AsAudioCallbackDriver(), AsyncCubebTask::SHUTDOWN);
releaseEvent->Dispatch();
}
}
ThreadedDriver::ThreadedDriver(MediaStreamGraphImpl* aGraphImpl)
: GraphDriver(aGraphImpl)
{ }
@ -125,33 +182,6 @@ ThreadedDriver::~ThreadedDriver()
mThread->Shutdown();
}
}
class MediaStreamGraphShutdownThreadRunnable : public nsRunnable {
public:
explicit MediaStreamGraphShutdownThreadRunnable(GraphDriver* aDriver)
: mDriver(aDriver)
{
}
NS_IMETHOD Run()
{
MOZ_ASSERT(NS_IsMainThread());
// We can't release an audio driver on the main thread, because it can be
// blocking.
if (mDriver->AsAudioCallbackDriver()) {
STREAM_LOG(PR_LOG_DEBUG, ("Releasing audio driver off main thread.\n"));
nsRefPtr<AsyncCubebTask> releaseEvent =
new AsyncCubebTask(mDriver->AsAudioCallbackDriver(), AsyncCubebTask::SHUTDOWN);
mDriver = nullptr;
releaseEvent->Dispatch();
} else {
mDriver = nullptr;
}
return NS_OK;
}
private:
nsRefPtr<GraphDriver> mDriver;
};
class MediaStreamGraphInitThreadRunnable : public nsRunnable {
public:
explicit MediaStreamGraphInitThreadRunnable(ThreadedDriver* aDriver)
@ -163,7 +193,13 @@ public:
char aLocal;
STREAM_LOG(PR_LOG_DEBUG, ("Starting system thread"));
profiler_register_thread("MediaStreamGraph", &aLocal);
LIFECYCLE_LOG("Starting a new system driver for graph %p\n",
mDriver->mGraphImpl);
if (mDriver->mPreviousDriver) {
LIFECYCLE_LOG("%p releasing an AudioCallbackDriver(%p), for graph %p\n",
mDriver,
mDriver->mPreviousDriver.get(),
mDriver->GraphImpl());
MOZ_ASSERT(!mDriver->AsAudioCallbackDriver());
// Stop and release the previous driver off-main-thread.
nsRefPtr<AsyncCubebTask> releaseEvent =
@ -185,6 +221,7 @@ private:
void
ThreadedDriver::Start()
{
LIFECYCLE_LOG("Starting thread for a SystemClockDriver %p\n", mGraphImpl);
nsCOMPtr<nsIRunnable> event = new MediaStreamGraphInitThreadRunnable(this);
NS_NewNamedThread("MediaStreamGrph", getter_AddRefs(mThread), event);
}
@ -413,6 +450,17 @@ OfflineClockDriver::WakeUp()
MOZ_ASSERT(false, "An offline graph should not have to wake up.");
}
AsyncCubebTask::AsyncCubebTask(AudioCallbackDriver* aDriver, AsyncCubebOperation aOperation)
: mDriver(aDriver),
mOperation(aOperation),
mShutdownGrip(aDriver->GraphImpl())
{
MOZ_ASSERT(mDriver->mAudioStream || aOperation == INIT, "No audio stream !");
}
AsyncCubebTask::~AsyncCubebTask()
{
}
NS_IMETHODIMP
AsyncCubebTask::Run()
@ -432,14 +480,18 @@ AsyncCubebTask::Run()
switch(mOperation) {
case AsyncCubebOperation::INIT:
LIFECYCLE_LOG("AsyncCubebOperation::INIT\n");
mDriver->Init();
break;
case AsyncCubebOperation::SHUTDOWN:
LIFECYCLE_LOG("AsyncCubebOperation::SHUTDOWN\n");
mDriver->Stop();
mDriver = nullptr;
mShutdownGrip = nullptr;
break;
case AsyncCubebOperation::SLEEP: {
{
LIFECYCLE_LOG("AsyncCubebOperation::SLEEP\n");
MonitorAutoLock mon(mDriver->mGraphImpl->GetMonitor());
// We might just have been awoken
if (mDriver->mNeedAnotherIteration) {
@ -797,7 +849,7 @@ AudioCallbackDriver::DataCallback(AudioDataValue* aBuffer, long aFrames)
}
if (!stillProcessing) {
STREAM_LOG(PR_LOG_DEBUG, ("Stopping audio thread for MediaStreamGraph %p", this));
LIFECYCLE_LOG("Stopping audio thread for MediaStreamGraph %p", this);
return aFrames - 1;
}
return aFrames;

View File

@ -96,6 +96,7 @@ public:
virtual void Resume() = 0;
/* Revive this driver, as more messages just arrived. */
virtual void Revive() = 0;
void Shutdown();
/* Rate at which the GraphDriver runs, in ms. This can either be user
* controlled (because we are using a {System,Offline}ClockDriver, and decide
* how often we want to wakeup/how much we want to process per iteration), or
@ -187,6 +188,10 @@ public:
*/
void EnsureNextIterationLocked();
MediaStreamGraphImpl* GraphImpl() {
return mGraphImpl;
}
protected:
// Time of the start of this graph iteration.
GraphTime mIterationStart;
@ -460,12 +465,7 @@ public:
};
AsyncCubebTask(AudioCallbackDriver* aDriver, AsyncCubebOperation aOperation)
: mDriver(aDriver),
mOperation(aOperation)
{
MOZ_ASSERT(mDriver->mAudioStream || aOperation == INIT, "No audio stream !");
}
AsyncCubebTask(AudioCallbackDriver* aDriver, AsyncCubebOperation aOperation);
nsresult Dispatch()
{
@ -479,13 +479,14 @@ public:
}
protected:
virtual ~AsyncCubebTask() {};
virtual ~AsyncCubebTask();
private:
NS_IMETHOD Run() MOZ_OVERRIDE MOZ_FINAL;
nsCOMPtr<nsIThread> mThread;
nsRefPtr<AudioCallbackDriver> mDriver;
AsyncCubebOperation mOperation;
nsRefPtr<MediaStreamGraphImpl> mShutdownGrip;
};
}

View File

@ -130,12 +130,10 @@ void MediaDecoder::SetDormantIfNecessary(bool aDormant)
MOZ_ASSERT(NS_IsMainThread());
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
if (!mDecoderStateMachine || !mDecoderStateMachine->IsDormantNeeded() || (mPlayState == PLAY_STATE_SHUTDOWN)) {
return;
}
if (mIsDormant == aDormant) {
// no change to dormant state
if (!mDecoderStateMachine ||
!mDecoderStateMachine->IsDormantNeeded() ||
mPlayState == PLAY_STATE_SHUTDOWN ||
mIsDormant == aDormant) {
return;
}
@ -149,16 +147,11 @@ void MediaDecoder::SetDormantIfNecessary(bool aDormant)
SecondsToUsecs(mCurrentTime, timeUsecs);
mRequestedSeekTarget = SeekTarget(timeUsecs, SeekTarget::Accurate);
if (mPlayState == PLAY_STATE_PLAYING){
mNextState = PLAY_STATE_PLAYING;
} else {
mNextState = PLAY_STATE_PAUSED;
}
mNextState = mPlayState;
mIsDormant = true;
mIsExitingDormant = false;
ChangeState(PLAY_STATE_LOADING);
} else if ((aDormant != true) && (mPlayState == PLAY_STATE_LOADING)) {
} else if (!aDormant && mPlayState == PLAY_STATE_LOADING) {
// exit dormant state
// trigger to state machine.
mDecoderStateMachine->SetDormant(false);
@ -170,7 +163,9 @@ void MediaDecoder::Pause()
{
MOZ_ASSERT(NS_IsMainThread());
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
if ((mPlayState == PLAY_STATE_LOADING && mIsDormant) || mPlayState == PLAY_STATE_SEEKING || mPlayState == PLAY_STATE_ENDED) {
if ((mPlayState == PLAY_STATE_LOADING && mIsDormant) ||
mPlayState == PLAY_STATE_SEEKING ||
mPlayState == PLAY_STATE_ENDED) {
mNextState = PLAY_STATE_PAUSED;
return;
}
@ -869,8 +864,11 @@ void MediaDecoder::PlaybackEnded()
{
MOZ_ASSERT(NS_IsMainThread());
if (mShuttingDown || mPlayState == MediaDecoder::PLAY_STATE_SEEKING)
if (mShuttingDown ||
mPlayState == PLAY_STATE_SEEKING ||
(mPlayState == PLAY_STATE_LOADING && mIsDormant)) {
return;
}
{
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
@ -1554,11 +1552,6 @@ bool MediaDecoder::IsShutdown() const {
return GetStateMachine()->IsShutdown();
}
int64_t MediaDecoder::GetEndMediaTime() const {
NS_ENSURE_TRUE(GetStateMachine(), -1);
return GetStateMachine()->GetEndMediaTime();
}
// Drop reference to state machine. Only called during shutdown dance.
void MediaDecoder::BreakCycles() {
mDecoderStateMachine = nullptr;

View File

@ -581,8 +581,6 @@ public:
// by the MediaResource read functions.
void NotifyBytesConsumed(int64_t aBytes, int64_t aOffset) MOZ_FINAL MOZ_OVERRIDE;
int64_t GetEndMediaTime() const MOZ_FINAL MOZ_OVERRIDE;
// Return true if we are currently seeking in the media resource.
// Call on the main thread only.
virtual bool IsSeeking() const;

View File

@ -1450,6 +1450,7 @@ void MediaDecoderStateMachine::Play()
void MediaDecoderStateMachine::ResetPlayback()
{
AssertCurrentThreadInMonitor();
MOZ_ASSERT(mState == DECODER_STATE_SEEKING ||
mState == DECODER_STATE_SHUTDOWN ||
mState == DECODER_STATE_DORMANT);
@ -2485,7 +2486,7 @@ MediaDecoderStateMachine::FlushDecoding()
{
NS_ASSERTION(OnStateMachineThread() || OnDecodeThread(),
"Should be on state machine or decode thread.");
mDecoder->GetReentrantMonitor().AssertNotCurrentThreadIn();
AssertCurrentThreadInMonitor();
{
// Put a task in the decode queue to abort any decoding operations.

View File

@ -275,11 +275,6 @@ public:
void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset);
int64_t GetEndMediaTime() const {
AssertCurrentThreadInMonitor();
return mEndTime;
}
// Returns the shared state machine thread.
nsIEventTarget* GetStateMachineThread() const;

View File

@ -936,6 +936,7 @@ ChannelMediaResource::RecreateChannel()
loadGroup,
nullptr,
loadFlags);
NS_ENSURE_SUCCESS(rv, rv);
// We have cached the Content-Type, which should not change. Give a hint to
// the channel to avoid a sniffing failure, which would be expected because we
@ -1034,8 +1035,7 @@ ChannelMediaResource::CacheClientSeek(int64_t aOffset, bool aResume)
}
nsresult rv = RecreateChannel();
if (NS_FAILED(rv))
return rv;
NS_ENSURE_SUCCESS(rv, rv);
return OpenChannel(nullptr);
}

View File

@ -45,6 +45,21 @@ PRLogModuleInfo* gMediaStreamGraphLog;
#define STREAM_LOG(type, msg)
#endif
// #define ENABLE_LIFECYCLE_LOG
// We don't use NSPR log here because we want this interleaved with adb logcat
// on Android/B2G
#ifdef ENABLE_LIFECYCLE_LOG
# ifdef ANDROID
# include "android/log.h"
# define LIFECYCLE_LOG(...) __android_log_print(ANDROID_LOG_INFO, "Gecko - MSG", ## __VA_ARGS__); printf(__VA_ARGS__);printf("\n");
# else
# define LIFECYCLE_LOG(...) printf(__VA_ARGS__);printf("\n");
# endif
#else
# define LIFECYCLE_LOG(...)
#endif
/**
* The singleton graph instance.
*/
@ -55,6 +70,7 @@ MediaStreamGraphImpl::~MediaStreamGraphImpl()
NS_ASSERTION(IsEmpty(),
"All streams should have been destroyed by messages from the main thread");
STREAM_LOG(PR_LOG_DEBUG, ("MediaStreamGraph %p destroyed", this));
LIFECYCLE_LOG("MediaStreamGraphImpl::~MediaStreamGraphImpl\n");
}
@ -526,8 +542,11 @@ MediaStreamGraphImpl::UpdateStreamOrder()
started = CurrentDriver()->AsAudioCallbackDriver()->IsStarted();
}
if (started) {
SystemClockDriver* driver = new SystemClockDriver(this);
CurrentDriver()->SwitchAtNextIteration(driver);
MonitorAutoLock mon(mMonitor);
if (mLifecycleState == LIFECYCLE_RUNNING) {
SystemClockDriver* driver = new SystemClockDriver(this);
CurrentDriver()->SwitchAtNextIteration(driver);
}
}
}
@ -905,9 +924,12 @@ MediaStreamGraphImpl::CreateOrDestroyAudioStreams(GraphTime aAudioOutputStartTim
if (!CurrentDriver()->AsAudioCallbackDriver() &&
!CurrentDriver()->Switching()) {
AudioCallbackDriver* driver = new AudioCallbackDriver(this);
mMixer.AddCallback(driver);
CurrentDriver()->SwitchAtNextIteration(driver);
MonitorAutoLock mon(mMonitor);
if (mLifecycleState == LIFECYCLE_RUNNING) {
AudioCallbackDriver* driver = new AudioCallbackDriver(this);
mMixer.AddCallback(driver);
CurrentDriver()->SwitchAtNextIteration(driver);
}
}
}
}
@ -1456,13 +1478,13 @@ public:
NS_ASSERTION(mGraph->mDetectedNotRunning,
"We should know the graph thread control loop isn't running!");
STREAM_LOG(PR_LOG_DEBUG, ("Shutting down graph %p", mGraph.get()));
LIFECYCLE_LOG("Shutting down graph %p", mGraph.get());
if (mGraph->CurrentDriver()->AsAudioCallbackDriver()) {
MOZ_ASSERT(!mGraph->CurrentDriver()->AsAudioCallbackDriver()->InCallback());
}
mGraph->CurrentDriver()->Stop();
mGraph->CurrentDriver()->Shutdown();
// mGraph's thread is not running so it's OK to do whatever here
if (mGraph->IsEmpty()) {
@ -1559,6 +1581,23 @@ MediaStreamGraphImpl::RunInStableState(bool aSourceIsMSG)
mPostedRunInStableStateEvent = false;
}
#ifdef ENABLE_LIFECYCLE_LOG
// This should be kept in sync with the LifecycleState enum in
// MediaStreamGraphImpl.h
const char * LifecycleState_str[] = {
"LIFECYCLE_THREAD_NOT_STARTED",
"LIFECYCLE_RUNNING",
"LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP",
"LIFECYCLE_WAITING_FOR_THREAD_SHUTDOWN",
"LIFECYCLE_WAITING_FOR_STREAM_DESTRUCTION"
};
if (mLifecycleState != LIFECYCLE_RUNNING) {
LIFECYCLE_LOG("Running %p in stable state. Current state: %s\n",
this, LifecycleState_str[mLifecycleState]);
}
#endif
runnables.SwapElements(mUpdateRunnables);
for (uint32_t i = 0; i < mStreamUpdates.Length(); ++i) {
StreamUpdate* update = &mStreamUpdates[i];
@ -1572,17 +1611,19 @@ MediaStreamGraphImpl::RunInStableState(bool aSourceIsMSG)
if (mLifecycleState == LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP && IsEmpty()) {
// Complete shutdown. First, ensure that this graph is no longer used.
// A new graph graph will be created if one is needed.
STREAM_LOG(PR_LOG_DEBUG, ("Disconnecting MediaStreamGraph %p", this));
if (this == gGraph) {
// null out gGraph if that's the graph being shut down
gGraph = nullptr;
}
// Asynchronously clean up old graph. We don't want to do this
// synchronously because it spins the event loop waiting for threads
// to shut down, and we don't want to do that in a stable state handler.
mLifecycleState = LIFECYCLE_WAITING_FOR_THREAD_SHUTDOWN;
LIFECYCLE_LOG("Sending MediaStreamGraphShutDownRunnable %p", this);
nsCOMPtr<nsIRunnable> event = new MediaStreamGraphShutDownRunnable(this );
NS_DispatchToMainThread(event);
LIFECYCLE_LOG("Disconnecting MediaStreamGraph %p", this);
if (this == gGraph) {
// null out gGraph if that's the graph being shut down
gGraph = nullptr;
}
}
} else {
if (mLifecycleState <= LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP) {
@ -1605,6 +1646,9 @@ MediaStreamGraphImpl::RunInStableState(bool aSourceIsMSG)
// or it might exit immediately.
{
MonitorAutoUnlock unlock(mMonitor);
LIFECYCLE_LOG("Reviving a graph (%p) ! %s\n",
this, CurrentDriver()->AsAudioCallbackDriver() ? "AudioDriver" :
"SystemDriver");
CurrentDriver()->Revive();
}
}
@ -1622,7 +1666,10 @@ MediaStreamGraphImpl::RunInStableState(bool aSourceIsMSG)
// We should exit the monitor for now, because starting a stream might
// take locks, and we don't want to deadlock.
MonitorAutoUnlock unlock(mMonitor);
STREAM_LOG(PR_LOG_DEBUG, ("Starting a graph ! %s\n", CurrentDriver()->AsAudioCallbackDriver() ? "AudioDriver" : "SystemDriver"));
LIFECYCLE_LOG("Starting a graph (%p) ! %s\n",
this,
CurrentDriver()->AsAudioCallbackDriver() ? "AudioDriver" :
"SystemDriver");
CurrentDriver()->Start();
}
}

View File

@ -688,7 +688,8 @@ public:
mMutex("mozilla::media::SourceMediaStream"),
mUpdateKnownTracksTime(0),
mPullEnabled(false),
mUpdateFinished(false)
mUpdateFinished(false),
mNeedsMixing(false)
{}
virtual SourceMediaStream* AsSourceStream() { return this; }

View File

@ -520,6 +520,9 @@ public:
* is not deleted. New messages for the graph are processed synchronously on
* the main thread if necessary. When the last stream is destroyed, the
* graph object is deleted.
*
* This should be kept in sync with the LifecycleState_str array in
* MediaStreamGraph.cpp
*/
enum LifecycleState {
// The graph thread hasn't started yet.

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