зеркало из https://github.com/mozilla/gecko-dev.git
merge fx-team to mozilla-central a=merge
This commit is contained in:
Коммит
f82b5b3d53
|
@ -646,8 +646,8 @@ FeedWriter.prototype = {
|
|||
_initMenuItemWithFile: function(aMenuItem, aFile) {
|
||||
var label = this._getFileDisplayName(aFile);
|
||||
var image = this._getFileIconURL(aFile);
|
||||
aMenuitem.setAttribute('label', label);
|
||||
aMenuitem.setAttribute('image', image);
|
||||
aMenuItem.setAttribute('label', label);
|
||||
aMenuItem.setAttribute('image', image);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,7 +8,6 @@ this.EXPORTED_SYMBOLS = ["ContentRestore"];
|
|||
|
||||
const Cu = Components.utils;
|
||||
const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
|
||||
|
||||
|
@ -183,19 +182,8 @@ ContentRestoreInternal.prototype = {
|
|||
let webNavigation = this.docShell.QueryInterface(Ci.nsIWebNavigation);
|
||||
let history = webNavigation.sessionHistory;
|
||||
|
||||
// Wait for the tab load to complete or fail
|
||||
this.restoreTabContentStarted((status) => {
|
||||
// If loadArgument is not null then we're attempting to load a new url
|
||||
// that required us to switch process. If that load is cancelled (for
|
||||
// example by a content handler) we want to restore the current history
|
||||
// entry.
|
||||
if (loadArguments && (status == Cr.NS_BINDING_ABORTED)) {
|
||||
this._tabData = tabData;
|
||||
this.restoreTabContent(null, finishCallback);
|
||||
} else {
|
||||
finishCallback();
|
||||
}
|
||||
});
|
||||
// Listen for the tab to finish loading.
|
||||
this.restoreTabContentStarted(finishCallback);
|
||||
|
||||
// Reset the current URI to about:blank. We changed it above for
|
||||
// switch-to-tab, but now it must go back to the correct value before the
|
||||
|
@ -260,26 +248,22 @@ ContentRestoreInternal.prototype = {
|
|||
*/
|
||||
restoreTabContentStarted(finishCallback) {
|
||||
// The reload listener is no longer needed.
|
||||
if (this._historyListener) {
|
||||
this._historyListener.uninstall();
|
||||
this._historyListener = null;
|
||||
}
|
||||
this._historyListener.uninstall();
|
||||
this._historyListener = null;
|
||||
|
||||
// Remove the old progress listener.
|
||||
if (this._progressListener) {
|
||||
this._progressListener.uninstall();
|
||||
}
|
||||
this._progressListener.uninstall();
|
||||
|
||||
// We're about to start a load. This listener will be called when the load
|
||||
// has finished getting everything from the network.
|
||||
this._progressListener = new ProgressListener(this.docShell, {
|
||||
onStopRequest: (status) => {
|
||||
onStopRequest: () => {
|
||||
// Call resetRestore() to reset the state back to normal. The data
|
||||
// needed for restoreDocument() (which hasn't happened yet) will
|
||||
// remain in _restoringDocument.
|
||||
this.resetRestore();
|
||||
|
||||
finishCallback(status);
|
||||
finishCallback();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
@ -431,7 +415,7 @@ ProgressListener.prototype = {
|
|||
}
|
||||
|
||||
if (stateFlags & STATE_STOP && this.callbacks.onStopRequest) {
|
||||
this.callbacks.onStopRequest(status);
|
||||
this.callbacks.onStopRequest();
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -45,53 +45,3 @@ add_task(function* () {
|
|||
// Cleanup.
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
|
||||
add_task(function* () {
|
||||
// Add a new non-remote tab.
|
||||
let tab = gBrowser.addTab("about:robots");
|
||||
let browser = tab.linkedBrowser;
|
||||
yield promiseBrowserLoaded(browser);
|
||||
ok(!browser.isRemoteBrowser, "browser is not remote");
|
||||
|
||||
// Wait for the tab to change to remote before adding the progress listener
|
||||
tab.addEventListener("TabRemotenessChange", function listener() {
|
||||
tab.removeEventListener("TabRemotenessChange", listener);
|
||||
|
||||
ContentTask.spawn(browser, URL, function*(url) {
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
let wp = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebProgress);
|
||||
|
||||
wp.addProgressListener({
|
||||
onStateChange: function(progress, request, stateFlags, status) {
|
||||
if (!(request instanceof Ci.nsIChannel))
|
||||
return;
|
||||
|
||||
if (request.URI.spec == url) {
|
||||
request.cancel(Cr.NS_BINDING_ABORTED);
|
||||
wp.removeProgressListener(this);
|
||||
}
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsIWebProgressListener,
|
||||
Ci.nsISupportsWeakReference
|
||||
])
|
||||
}, Ci.nsIWebProgress.NOTIFY_ALL);
|
||||
});
|
||||
});
|
||||
|
||||
// Load a new remote URI and when we see the load start cancel it
|
||||
browser.loadURI(URL);
|
||||
yield promiseTabRestored(tab);
|
||||
|
||||
let count = yield countHistoryEntries(browser);
|
||||
is(count, 1, "Should only be the one history entry.");
|
||||
|
||||
is(browser.currentURI.spec, "about:robots", "Should be back to the original URI");
|
||||
ok(!browser.isRemoteBrowser, "Should have gone back to a remote browser");
|
||||
|
||||
// Cleanup.
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
|
|
|
@ -197,7 +197,7 @@ toolbar[brighttext] #downloads-indicator-counter {
|
|||
#navigator-toolbox .searchbar-textbox {
|
||||
background-color: var(--url-and-searchbar-background-color) !important;
|
||||
background-image: none !important;
|
||||
color: inherit;
|
||||
color: inherit !important;
|
||||
border: 1px solid var(--chrome-nav-bar-controls-border-color) !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
|
|
@ -32,8 +32,6 @@ loader.lazyGetter(this, "clipboardHelper", () => {
|
|||
|
||||
loader.lazyImporter(this, "CommandUtils", "resource://devtools/client/shared/DeveloperToolbar.jsm");
|
||||
|
||||
const LAYOUT_CHANGE_TIMER = 250;
|
||||
|
||||
/**
|
||||
* Represents an open instance of the Inspector for a tab.
|
||||
* The inspector controls the breadcrumbs, the markup view, and the sidebar
|
||||
|
@ -49,8 +47,6 @@ const LAYOUT_CHANGE_TIMER = 250;
|
|||
* view has been reloaded)
|
||||
* - markuploaded
|
||||
* Fired when the markup-view frame has loaded
|
||||
* - layout-change
|
||||
* Fired when the layout of the inspector changes
|
||||
* - breadcrumbs-updated
|
||||
* Fired when the breadcrumb widget updates to a new node
|
||||
* - layoutview-updated
|
||||
|
@ -90,7 +86,6 @@ function InspectorPanel(iframeWindow, toolbox) {
|
|||
this.onBeforeNewSelection = this.onBeforeNewSelection.bind(this);
|
||||
this.onDetached = this.onDetached.bind(this);
|
||||
this.onToolboxHostChanged = this.onToolboxHostChanged.bind(this);
|
||||
this.scheduleLayoutChange = this.scheduleLayoutChange.bind(this);
|
||||
this.onPaneToggleButtonClicked = this.onPaneToggleButtonClicked.bind(this);
|
||||
this._onMarkupFrameLoad = this._onMarkupFrameLoad.bind(this);
|
||||
|
||||
|
@ -170,9 +165,6 @@ InspectorPanel.prototype = {
|
|||
this._toolbox.on("host-changed", this.onToolboxHostChanged);
|
||||
|
||||
if (this.target.isLocalTab) {
|
||||
this.browser = this.target.tab.linkedBrowser;
|
||||
this.browser.addEventListener("resize", this.scheduleLayoutChange, true);
|
||||
|
||||
// Show a warning when the debugger is paused.
|
||||
// We show the warning only when the inspector
|
||||
// is selected.
|
||||
|
@ -469,8 +461,6 @@ InspectorPanel.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
this.cancelLayoutChange();
|
||||
|
||||
// Wait for all the known tools to finish updating and then let the
|
||||
// client know.
|
||||
let selection = this.selection.nodeFront;
|
||||
|
@ -570,7 +560,6 @@ InspectorPanel.prototype = {
|
|||
* node was selected).
|
||||
*/
|
||||
onDetached: function(event, parentNode) {
|
||||
this.cancelLayoutChange();
|
||||
this.breadcrumbs.cutAfter(this.breadcrumbs.indexOf(parentNode));
|
||||
this.selection.setNodeFront(parentNode ? parentNode : this._defaultNode, "detached");
|
||||
},
|
||||
|
@ -589,12 +578,6 @@ InspectorPanel.prototype = {
|
|||
}
|
||||
|
||||
this.cancelUpdate();
|
||||
this.cancelLayoutChange();
|
||||
|
||||
if (this.browser) {
|
||||
this.browser.removeEventListener("resize", this.scheduleLayoutChange, true);
|
||||
this.browser = null;
|
||||
}
|
||||
|
||||
this.target.off("will-navigate", this._onBeforeNavigate);
|
||||
|
||||
|
@ -1392,41 +1375,5 @@ InspectorPanel.prototype = {
|
|||
this.inspector.resolveRelativeURL(link, this.selection.nodeFront).then(url => {
|
||||
clipboardHelper.copyString(url);
|
||||
}, console.error);
|
||||
},
|
||||
|
||||
/**
|
||||
* Trigger a high-priority layout change for things that need to be
|
||||
* updated immediately
|
||||
*/
|
||||
immediateLayoutChange: function() {
|
||||
this.emit("layout-change");
|
||||
},
|
||||
|
||||
/**
|
||||
* Schedule a low-priority change event for things like paint
|
||||
* and resize.
|
||||
*/
|
||||
scheduleLayoutChange: function(event) {
|
||||
// Filter out non browser window resize events (i.e. triggered by iframes)
|
||||
if (this.browser.contentWindow === event.target) {
|
||||
if (this._timer) {
|
||||
return null;
|
||||
}
|
||||
this._timer = this.panelWin.setTimeout(() => {
|
||||
this.emit("layout-change");
|
||||
this._timer = null;
|
||||
}, LAYOUT_CHANGE_TIMER);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Cancel a pending low-priority change event if any is
|
||||
* scheduled.
|
||||
*/
|
||||
cancelLayoutChange: function() {
|
||||
if (this._timer) {
|
||||
this.panelWin.clearTimeout(this._timer);
|
||||
delete this._timer;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -821,8 +821,6 @@ MarkupView.prototype = {
|
|||
* Mutation observer used for included nodes.
|
||||
*/
|
||||
_mutationObserver: function(aMutations) {
|
||||
let requiresLayoutChange = false;
|
||||
|
||||
for (let mutation of aMutations) {
|
||||
let type = mutation.type;
|
||||
let target = mutation.target;
|
||||
|
@ -845,11 +843,6 @@ MarkupView.prototype = {
|
|||
}
|
||||
if (type === "attributes" || type === "characterData") {
|
||||
container.update();
|
||||
|
||||
// Auto refresh style properties on selected node when they change.
|
||||
if (type === "attributes" && container.selected) {
|
||||
requiresLayoutChange = true;
|
||||
}
|
||||
} else if (type === "childList" || type === "nativeAnonymousChildList") {
|
||||
container.childrenDirty = true;
|
||||
// Update the children to take care of changes in the markup view DOM.
|
||||
|
@ -859,10 +852,7 @@ MarkupView.prototype = {
|
|||
}
|
||||
}
|
||||
|
||||
if (requiresLayoutChange) {
|
||||
this._inspector.immediateLayoutChange();
|
||||
}
|
||||
this._waitForChildren().then((nodes) => {
|
||||
this._waitForChildren().then(() => {
|
||||
if (this._destroyer) {
|
||||
console.warn("Could not fully update after markup mutations, " +
|
||||
"the markup-view was destroyed while waiting for children.");
|
||||
|
|
|
@ -7,9 +7,7 @@ support-files =
|
|||
|
||||
[browser_responsive_cmd.js]
|
||||
[browser_responsivecomputedview.js]
|
||||
skip-if = e10s # Bug ??????
|
||||
[browser_responsiveruleview.js]
|
||||
skip-if = e10s # Bug ??????
|
||||
[browser_responsiveui.js]
|
||||
skip-if = e10s && os == 'win'
|
||||
[browser_responsiveui_touch.js]
|
||||
|
|
|
@ -1,100 +1,66 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test() {
|
||||
let instance;
|
||||
"use strict";
|
||||
|
||||
let computedView;
|
||||
let inspector;
|
||||
// Check that when the viewport is resized, the computed-view refreshes.
|
||||
|
||||
waitForExplicitFinish();
|
||||
let mgr = ResponsiveUI.ResponsiveUIManager;
|
||||
const TEST_URI = "data:text/html;charset=utf-8,<html><style>" +
|
||||
"div {" +
|
||||
" width: 500px;" +
|
||||
" height: 10px;" +
|
||||
" background: purple;" +
|
||||
"} " +
|
||||
"@media screen and (max-width: 200px) {" +
|
||||
" div { " +
|
||||
" width: 100px;" +
|
||||
" }" +
|
||||
"};" +
|
||||
"</style><div></div></html>";
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
startTest();
|
||||
}, true);
|
||||
add_task(function*() {
|
||||
yield addTab(TEST_URI);
|
||||
|
||||
content.location = "data:text/html;charset=utf-8,<html><style>" +
|
||||
"div {" +
|
||||
" width: 500px;" +
|
||||
" height: 10px;" +
|
||||
" background: purple;" +
|
||||
"} " +
|
||||
"@media screen and (max-width: 200px) {" +
|
||||
" div { " +
|
||||
" width: 100px;" +
|
||||
" }" +
|
||||
"};" +
|
||||
"</style><div></div></html>"
|
||||
info("Open the responsive design mode and set its size to 500x500 to start");
|
||||
let {rdm} = yield openRDM();
|
||||
rdm.setSize(500, 500);
|
||||
|
||||
function computedWidth() {
|
||||
for (let prop of computedView.propertyViews) {
|
||||
if (prop.name === "width") {
|
||||
return prop.valueNode.textContent;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
info("Open the inspector, computed-view and select the test node");
|
||||
let {inspector, view} = yield openComputedView();
|
||||
yield selectNode("div", inspector);
|
||||
|
||||
function startTest() {
|
||||
document.getElementById("Tools:ResponsiveUI").doCommand();
|
||||
executeSoon(onUIOpen);
|
||||
}
|
||||
info("Try shrinking the viewport and checking the applied styles");
|
||||
yield testShrink(view, inspector, rdm);
|
||||
|
||||
function onUIOpen() {
|
||||
instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
|
||||
ok(instance, "instance of the module is attached to the tab.");
|
||||
info("Try growing the viewport and checking the applied styles");
|
||||
yield testGrow(view, inspector, rdm);
|
||||
|
||||
instance.stack.setAttribute("notransition", "true");
|
||||
registerCleanupFunction(function() {
|
||||
instance.stack.removeAttribute("notransition");
|
||||
});
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
instance.setSize(500, 500);
|
||||
function* testShrink(computedView, inspector, rdm) {
|
||||
is(computedWidth(computedView), "500px", "Should show 500px initially.");
|
||||
|
||||
openComputedView().then(onInspectorUIOpen);
|
||||
}
|
||||
let onRefresh = inspector.once("computed-view-refreshed");
|
||||
rdm.setSize(100, 100);
|
||||
yield onRefresh;
|
||||
|
||||
function onInspectorUIOpen(args) {
|
||||
inspector = args.inspector;
|
||||
computedView = args.view;
|
||||
ok(inspector, "Got inspector instance");
|
||||
|
||||
let div = content.document.getElementsByTagName("div")[0];
|
||||
|
||||
inspector.selection.setNode(div);
|
||||
inspector.once("inspector-updated", testShrink);
|
||||
}
|
||||
|
||||
function testShrink() {
|
||||
is(computedWidth(), "500px", "Should show 500px initially.");
|
||||
|
||||
inspector.once("computed-view-refreshed", function onShrink() {
|
||||
is(computedWidth(), "100px", "div should be 100px after shrinking.");
|
||||
testGrow();
|
||||
});
|
||||
|
||||
instance.setSize(100, 100);
|
||||
}
|
||||
|
||||
function testGrow() {
|
||||
inspector.once("computed-view-refreshed", function onGrow() {
|
||||
is(computedWidth(), "500px", "Should be 500px after growing.");
|
||||
finishUp();
|
||||
});
|
||||
|
||||
instance.setSize(500, 500);
|
||||
}
|
||||
|
||||
function finishUp() {
|
||||
document.getElementById("Tools:ResponsiveUI").doCommand();
|
||||
|
||||
// Menus are correctly updated?
|
||||
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), "false", "menu unchecked");
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
is(computedWidth(computedView), "100px", "Should be 100px after shrinking.");
|
||||
}
|
||||
|
||||
function* testGrow(computedView, inspector, rdm) {
|
||||
let onRefresh = inspector.once("computed-view-refreshed");
|
||||
rdm.setSize(500, 500);
|
||||
yield onRefresh;
|
||||
|
||||
is(computedWidth(computedView), "500px", "Should be 500px after growing.");
|
||||
}
|
||||
|
||||
function computedWidth(computedView) {
|
||||
for (let prop of computedView.propertyViews) {
|
||||
if (prop.name === "width") {
|
||||
return prop.valueNode.textContent;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -1,107 +1,99 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test() {
|
||||
let instance;
|
||||
"use strict";
|
||||
|
||||
let ruleView;
|
||||
let inspector;
|
||||
let mgr = ResponsiveUI.ResponsiveUIManager;
|
||||
// Check that when the viewport is resized, the rule-view refreshes.
|
||||
// Also test that ESC does open the split-console, and that the RDM menu item
|
||||
// gets updated correctly when needed.
|
||||
// TODO: split this test.
|
||||
|
||||
waitForExplicitFinish();
|
||||
const TEST_URI = "data:text/html;charset=utf-8,<html><style>" +
|
||||
"div {" +
|
||||
" width: 500px;" +
|
||||
" height: 10px;" +
|
||||
" background: purple;" +
|
||||
"} " +
|
||||
"@media screen and (max-width: 200px) {" +
|
||||
" div { " +
|
||||
" width: 100px;" +
|
||||
" }" +
|
||||
"};" +
|
||||
"</style><div></div></html>";
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", startTest, true);
|
||||
add_task(function*() {
|
||||
yield addTab(TEST_URI);
|
||||
|
||||
content.location = "data:text/html;charset=utf-8,<html><style>" +
|
||||
"div {" +
|
||||
" width: 500px;" +
|
||||
" height: 10px;" +
|
||||
" background: purple;" +
|
||||
"} " +
|
||||
"@media screen and (max-width: 200px) {" +
|
||||
" div { " +
|
||||
" width: 100px;" +
|
||||
" }" +
|
||||
"};" +
|
||||
"</style><div></div></html>"
|
||||
info("Open the responsive design mode and set its size to 500x500 to start");
|
||||
let {rdm, manager} = yield openRDM();
|
||||
rdm.setSize(500, 500);
|
||||
|
||||
function numberOfRules() {
|
||||
return ruleView.element.querySelectorAll(".ruleview-code").length;
|
||||
}
|
||||
info("Open the inspector, rule-view and select the test node");
|
||||
let {inspector, view} = yield openRuleView();
|
||||
yield selectNode("div", inspector);
|
||||
|
||||
function startTest() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", startTest, true);
|
||||
document.getElementById("Tools:ResponsiveUI").doCommand();
|
||||
executeSoon(onUIOpen);
|
||||
}
|
||||
info("Try shrinking the viewport and checking the applied styles");
|
||||
yield testShrink(view, rdm);
|
||||
|
||||
function onUIOpen() {
|
||||
instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
|
||||
ok(instance, "instance of the module is attached to the tab.");
|
||||
info("Try growing the viewport and checking the applied styles");
|
||||
yield testGrow(view, rdm);
|
||||
|
||||
instance.stack.setAttribute("notransition", "true");
|
||||
registerCleanupFunction(function() {
|
||||
instance.stack.removeAttribute("notransition");
|
||||
});
|
||||
info("Check that ESC still opens the split console");
|
||||
yield testEscapeOpensSplitConsole(inspector);
|
||||
|
||||
instance.setSize(500, 500);
|
||||
info("Test the state of the RDM menu item");
|
||||
yield testMenuItem(manager);
|
||||
|
||||
openRuleView().then(onInspectorUIOpen);
|
||||
}
|
||||
Services.prefs.clearUserPref("devtools.toolbox.splitconsoleEnabled");
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
function onInspectorUIOpen(args) {
|
||||
inspector = args.inspector;
|
||||
ruleView = args.view;
|
||||
ok(inspector, "Got inspector instance");
|
||||
function* testShrink(ruleView, rdm) {
|
||||
is(numberOfRules(ruleView), 2, "Should have two rules initially.");
|
||||
|
||||
let div = content.document.getElementsByTagName("div")[0];
|
||||
inspector.selection.setNode(div);
|
||||
inspector.once("inspector-updated", testShrink);
|
||||
}
|
||||
info("Resize to 100x100 and wait for the rule-view to update");
|
||||
let onRefresh = ruleView.once("ruleview-refreshed");
|
||||
rdm.setSize(100, 100);
|
||||
yield onRefresh;
|
||||
|
||||
function testShrink() {
|
||||
|
||||
is(numberOfRules(), 2, "Should have two rules initially.");
|
||||
|
||||
ruleView.on("ruleview-refreshed", function refresh() {
|
||||
ruleView.off("ruleview-refreshed", refresh, false);
|
||||
is(numberOfRules(), 3, "Should have three rules after shrinking.");
|
||||
testGrow();
|
||||
}, false);
|
||||
|
||||
instance.setSize(100, 100);
|
||||
}
|
||||
|
||||
function testGrow() {
|
||||
ruleView.on("ruleview-refreshed", function refresh() {
|
||||
ruleView.off("ruleview-refreshed", refresh, false);
|
||||
is(numberOfRules(), 2, "Should have two rules after growing.");
|
||||
testEscapeOpensSplitConsole();
|
||||
}, false);
|
||||
|
||||
instance.setSize(500, 500);
|
||||
}
|
||||
|
||||
function testEscapeOpensSplitConsole() {
|
||||
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), "true", "menu checked");
|
||||
ok(!inspector._toolbox._splitConsole, "Console is not split.");
|
||||
|
||||
inspector._toolbox.once("split-console", function() {
|
||||
mgr.once("off", function() {executeSoon(finishUp)});
|
||||
mgr.toggle(window, gBrowser.selectedTab);
|
||||
});
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {});
|
||||
}
|
||||
|
||||
function finishUp() {
|
||||
ok(inspector._toolbox._splitConsole, "Console is split after pressing escape.");
|
||||
|
||||
// Menus are correctly updated?
|
||||
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), "false", "menu unchecked");
|
||||
|
||||
Services.prefs.clearUserPref("devtools.toolbox.splitconsoleEnabled");
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
is(numberOfRules(ruleView), 3, "Should have three rules after shrinking.");
|
||||
}
|
||||
|
||||
function* testGrow(ruleView, rdm) {
|
||||
info("Resize to 500x500 and wait for the rule-view to update");
|
||||
let onRefresh = ruleView.once("ruleview-refreshed");
|
||||
rdm.setSize(500, 500);
|
||||
yield onRefresh;
|
||||
|
||||
is(numberOfRules(ruleView), 2, "Should have two rules after growing.");
|
||||
}
|
||||
|
||||
function* testEscapeOpensSplitConsole(inspector) {
|
||||
ok(!inspector._toolbox._splitConsole, "Console is not split.");
|
||||
|
||||
info("Press escape");
|
||||
let onSplit = inspector._toolbox.once("split-console");
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {});
|
||||
yield onSplit;
|
||||
|
||||
ok(inspector._toolbox._splitConsole, "Console is split after pressing ESC.");
|
||||
}
|
||||
|
||||
function* testMenuItem(manager) {
|
||||
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"),
|
||||
"true",
|
||||
"The menu item is checked");
|
||||
|
||||
info("Toggle off the RDM");
|
||||
let onManagerOff = manager.once("off");
|
||||
manager.toggle(window, gBrowser.selectedTab);
|
||||
yield onManagerOff;
|
||||
|
||||
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"),
|
||||
"false",
|
||||
"The menu item is unchecked");
|
||||
}
|
||||
|
||||
function numberOfRules(ruleView) {
|
||||
return ruleView.element.querySelectorAll(".ruleview-code").length;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,26 @@ registerCleanupFunction(() => {
|
|||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Open the Responsive Design Mode
|
||||
* @param {Tab} The browser tab to open it into (defaults to the selected tab).
|
||||
* @return {Promise} Resolves to the instance of the responsive design mode.
|
||||
*/
|
||||
function openRDM(tab = gBrowser.selectedTab) {
|
||||
return new Promise(resolve => {
|
||||
let manager = ResponsiveUI.ResponsiveUIManager;
|
||||
document.getElementById("Tools:ResponsiveUI").doCommand();
|
||||
executeSoon(() => {
|
||||
let rdm = manager.getResponsiveUIForTab(tab);
|
||||
rdm.stack.setAttribute("notransition", "true");
|
||||
registerCleanupFunction(function() {
|
||||
rdm.stack.removeAttribute("notransition");
|
||||
});
|
||||
resolve({rdm, manager});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the toolbox, with the inspector tool visible.
|
||||
* @return a promise that resolves when the inspector is ready
|
||||
|
@ -125,7 +145,6 @@ function openRuleView() {
|
|||
return openInspectorSideBar("ruleview");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a new test tab in the browser and load the given url.
|
||||
* @param {String} url The url to be loaded in the new tab
|
||||
|
@ -216,3 +235,36 @@ function waitForDocLoadComplete(aBrowser=gBrowser) {
|
|||
info("Waiting for browser load");
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the NodeFront for a node that matches a given css selector, via the
|
||||
* protocol.
|
||||
* @param {String|NodeFront} selector
|
||||
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
|
||||
* loaded in the toolbox
|
||||
* @return {Promise} Resolves to the NodeFront instance
|
||||
*/
|
||||
function getNodeFront(selector, {walker}) {
|
||||
if (selector._form) {
|
||||
return selector;
|
||||
}
|
||||
return walker.querySelector(walker.rootNode, selector);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the inspector's current selection to the first match of the given css
|
||||
* selector
|
||||
* @param {String|NodeFront} selector
|
||||
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
|
||||
* loaded in the toolbox
|
||||
* @param {String} reason Defaults to "test" which instructs the inspector not
|
||||
* to highlight the node upon selection
|
||||
* @return {Promise} Resolves when the inspector is updated with the new node
|
||||
*/
|
||||
var selectNode = Task.async(function*(selector, inspector, reason = "test") {
|
||||
info("Selecting the node for '" + selector + "'");
|
||||
let nodeFront = yield getNodeFront(selector, inspector);
|
||||
let updated = inspector.once("inspector-updated");
|
||||
inspector.selection.setNodeFront(nodeFront, reason);
|
||||
yield updated;
|
||||
});
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const {Cc, Cu, Ci} = require("chrome");
|
||||
const {Cu} = require("chrome");
|
||||
const promise = require("promise");
|
||||
const {Tools} = require("devtools/client/main");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
@ -37,6 +37,8 @@ function RuleViewTool(inspector, window) {
|
|||
this.onPropertyChanged = this.onPropertyChanged.bind(this);
|
||||
this.onViewRefreshed = this.onViewRefreshed.bind(this);
|
||||
this.onPanelSelected = this.onPanelSelected.bind(this);
|
||||
this.onMutations = this.onMutations.bind(this);
|
||||
this.onResized = this.onResized.bind(this);
|
||||
|
||||
this.view.on("ruleview-changed", this.onPropertyChanged);
|
||||
this.view.on("ruleview-refreshed", this.onViewRefreshed);
|
||||
|
@ -44,11 +46,12 @@ function RuleViewTool(inspector, window) {
|
|||
|
||||
this.inspector.selection.on("detached", this.onSelected);
|
||||
this.inspector.selection.on("new-node-front", this.onSelected);
|
||||
this.inspector.on("layout-change", this.refresh);
|
||||
this.inspector.selection.on("pseudoclass", this.refresh);
|
||||
this.inspector.target.on("navigate", this.clearUserProperties);
|
||||
this.inspector.sidebar.on("ruleview-selected", this.onPanelSelected);
|
||||
this.inspector.pageStyle.on("stylesheet-updated", this.refresh);
|
||||
this.inspector.walker.on("mutations", this.onMutations);
|
||||
this.inspector.walker.on("resize", this.onResized);
|
||||
|
||||
this.onSelected();
|
||||
}
|
||||
|
@ -147,8 +150,32 @@ RuleViewTool.prototype = {
|
|||
this.inspector.emit("rule-view-refreshed");
|
||||
},
|
||||
|
||||
/**
|
||||
* When markup mutations occur, if an attribute of the selected node changes,
|
||||
* we need to refresh the view as that might change the node's styles.
|
||||
*/
|
||||
onMutations: function(mutations) {
|
||||
for (let {type, target} of mutations) {
|
||||
if (target === this.inspector.selection.nodeFront &&
|
||||
type === "attributes") {
|
||||
this.refresh();
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* When the window gets resized, this may cause media-queries to match, and
|
||||
* therefore, different styles may apply.
|
||||
*/
|
||||
onResized: function() {
|
||||
this.refresh();
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this.inspector.off("layout-change", this.refresh);
|
||||
this.inspector.walker.off("mutations", this.onMutations);
|
||||
this.inspector.walker.off("resize", this.onResized);
|
||||
this.inspector.selection.off("detached", this.onSelected);
|
||||
this.inspector.selection.off("pseudoclass", this.refresh);
|
||||
this.inspector.selection.off("new-node-front", this.onSelected);
|
||||
this.inspector.target.off("navigate", this.clearUserProperties);
|
||||
|
@ -177,13 +204,16 @@ function ComputedViewTool(inspector, window) {
|
|||
this.onSelected = this.onSelected.bind(this);
|
||||
this.refresh = this.refresh.bind(this);
|
||||
this.onPanelSelected = this.onPanelSelected.bind(this);
|
||||
this.onMutations = this.onMutations.bind(this);
|
||||
this.onResized = this.onResized.bind(this);
|
||||
|
||||
this.inspector.selection.on("detached", this.onSelected);
|
||||
this.inspector.selection.on("new-node-front", this.onSelected);
|
||||
this.inspector.on("layout-change", this.refresh);
|
||||
this.inspector.selection.on("pseudoclass", this.refresh);
|
||||
this.inspector.sidebar.on("computedview-selected", this.onPanelSelected);
|
||||
this.inspector.pageStyle.on("stylesheet-updated", this.refresh);
|
||||
this.inspector.walker.on("mutations", this.onMutations);
|
||||
this.inspector.walker.on("resize", this.onResized);
|
||||
|
||||
this.view.selectElement(null);
|
||||
|
||||
|
@ -243,11 +273,35 @@ ComputedViewTool.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* When markup mutations occur, if an attribute of the selected node changes,
|
||||
* we need to refresh the view as that might change the node's styles.
|
||||
*/
|
||||
onMutations: function(mutations) {
|
||||
for (let {type, target} of mutations) {
|
||||
if (target === this.inspector.selection.nodeFront &&
|
||||
type === "attributes") {
|
||||
this.refresh();
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* When the window gets resized, this may cause media-queries to match, and
|
||||
* therefore, different styles may apply.
|
||||
*/
|
||||
onResized: function() {
|
||||
this.refresh();
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this.inspector.off("layout-change", this.refresh);
|
||||
this.inspector.walker.off("mutations", this.onMutations);
|
||||
this.inspector.walker.off("resize", this.onResized);
|
||||
this.inspector.sidebar.off("computedview-selected", this.refresh);
|
||||
this.inspector.selection.off("pseudoclass", this.refresh);
|
||||
this.inspector.selection.off("new-node-front", this.onSelected);
|
||||
this.inspector.selection.off("detached", this.onSelected);
|
||||
this.inspector.sidebar.off("computedview-selected", this.onPanelSelected);
|
||||
if (this.inspector.pageStyle) {
|
||||
this.inspector.pageStyle.off("stylesheet-updated", this.refresh);
|
||||
|
|
|
@ -1268,29 +1268,36 @@ var WalkerActor = protocol.ActorClass({
|
|||
typeName: "domwalker",
|
||||
|
||||
events: {
|
||||
"new-mutations" : {
|
||||
"new-mutations": {
|
||||
type: "newMutations"
|
||||
},
|
||||
"picker-node-picked" : {
|
||||
"picker-node-picked": {
|
||||
type: "pickerNodePicked",
|
||||
node: Arg(0, "disconnectedNode")
|
||||
},
|
||||
"picker-node-hovered" : {
|
||||
"picker-node-hovered": {
|
||||
type: "pickerNodeHovered",
|
||||
node: Arg(0, "disconnectedNode")
|
||||
},
|
||||
"picker-node-canceled" : {
|
||||
"picker-node-canceled": {
|
||||
type: "pickerNodeCanceled"
|
||||
},
|
||||
"highlighter-ready" : {
|
||||
"highlighter-ready": {
|
||||
type: "highlighter-ready"
|
||||
},
|
||||
"highlighter-hide" : {
|
||||
"highlighter-hide": {
|
||||
type: "highlighter-hide"
|
||||
},
|
||||
"display-change" : {
|
||||
"display-change": {
|
||||
type: "display-change",
|
||||
nodes: Arg(0, "array:domnode")
|
||||
},
|
||||
// The walker actor emits a useful "resize" event to its front to let
|
||||
// clients know when the browser window gets resized. This may be useful
|
||||
// for refreshing a DOM node's styles for example, since those may depend on
|
||||
// media-queries.
|
||||
"resize": {
|
||||
type: "resize"
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -1332,9 +1339,11 @@ var WalkerActor = protocol.ActorClass({
|
|||
// managed.
|
||||
this.rootNode = this.document();
|
||||
|
||||
this.reflowObserver = getLayoutChangesObserver(this.tabActor);
|
||||
this.layoutChangeObserver = getLayoutChangesObserver(this.tabActor);
|
||||
this._onReflows = this._onReflows.bind(this);
|
||||
this.reflowObserver.on("reflows", this._onReflows);
|
||||
this.layoutChangeObserver.on("reflows", this._onReflows);
|
||||
this._onResize = this._onResize.bind(this);
|
||||
this.layoutChangeObserver.on("resize", this._onResize);
|
||||
},
|
||||
|
||||
// Returns the JSON representation of this object over the wire.
|
||||
|
@ -1395,9 +1404,10 @@ var WalkerActor = protocol.ActorClass({
|
|||
this.onFrameUnload = null;
|
||||
|
||||
this.walkerSearch.destroy();
|
||||
this.reflowObserver.off("reflows", this._onReflows);
|
||||
this.reflowObserver = null;
|
||||
this._onReflows = null;
|
||||
|
||||
this.layoutChangeObserver.off("reflows", this._onReflows);
|
||||
this.layoutChangeObserver.off("resize", this._onResize);
|
||||
this.layoutChangeObserver = null;
|
||||
releaseLayoutChangesObserver(this.tabActor);
|
||||
|
||||
this.onMutations = null;
|
||||
|
@ -1467,6 +1477,13 @@ var WalkerActor = protocol.ActorClass({
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* When the browser window gets resized, relay the event to the front.
|
||||
*/
|
||||
_onResize: function() {
|
||||
events.emit(this, "resize");
|
||||
},
|
||||
|
||||
/**
|
||||
* This is kept for backward-compatibility reasons with older remote targets.
|
||||
* Targets prior to bug 916443.
|
||||
|
@ -3687,6 +3704,7 @@ var AttributeModificationList = Class({
|
|||
*/
|
||||
var InspectorActor = exports.InspectorActor = protocol.ActorClass({
|
||||
typeName: "inspector",
|
||||
|
||||
initialize: function(conn, tabActor) {
|
||||
protocol.Actor.prototype.initialize.call(this, conn);
|
||||
this.tabActor = tabActor;
|
||||
|
@ -3694,6 +3712,7 @@ var InspectorActor = exports.InspectorActor = protocol.ActorClass({
|
|||
|
||||
destroy: function () {
|
||||
protocol.Actor.prototype.destroy.call(this);
|
||||
|
||||
this._highlighterPromise = null;
|
||||
this._pageStylePromise = null;
|
||||
this._walkerPromise = null;
|
||||
|
|
|
@ -11,14 +11,14 @@
|
|||
* Mostly empty, just gets an instance of LayoutChangesObserver and forwards
|
||||
* its "reflows" events to clients.
|
||||
*
|
||||
* - Observable: A utility parent class, meant at being extended by classes that
|
||||
* need a start/stop behavior.
|
||||
*
|
||||
* - LayoutChangesObserver: extends Observable and uses the ReflowObserver, to
|
||||
* track reflows on the page.
|
||||
* Used by the LayoutActor, but is also exported on the module, so can be used
|
||||
* by any other actor that needs it.
|
||||
*
|
||||
* - Observable: A utility parent class, meant at being extended by classes that
|
||||
* need a to observe something on the tabActor's windows.
|
||||
*
|
||||
* - Dedicated observers: There's only one of them for now: ReflowObserver which
|
||||
* listens to reflow events via the docshell,
|
||||
* These dedicated classes are used by the LayoutChangesObserver.
|
||||
|
@ -27,7 +27,7 @@
|
|||
const {Ci, Cu} = require("chrome");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
const protocol = require("devtools/server/protocol");
|
||||
const {method, Arg, RetVal, types} = protocol;
|
||||
const {method, Arg} = protocol;
|
||||
const events = require("sdk/event/core");
|
||||
const Heritage = require("sdk/core/heritage");
|
||||
const {setTimeout, clearTimeout} = require("sdk/timers");
|
||||
|
@ -48,7 +48,7 @@ var ReflowActor = exports.ReflowActor = protocol.ActorClass({
|
|||
* - end {Number}
|
||||
* - isInterruptible {Boolean}
|
||||
*/
|
||||
"reflows" : {
|
||||
"reflows": {
|
||||
type: "reflows",
|
||||
reflows: Arg(0, "array:json")
|
||||
}
|
||||
|
@ -64,9 +64,9 @@ var ReflowActor = exports.ReflowActor = protocol.ActorClass({
|
|||
},
|
||||
|
||||
/**
|
||||
* The reflow actor is the first (and last) in its hierarchy to use protocol.js
|
||||
* so it doesn't have a parent protocol actor that takes care of its lifetime.
|
||||
* So it needs a disconnect method to cleanup.
|
||||
* The reflow actor is the first (and last) in its hierarchy to use
|
||||
* protocol.js so it doesn't have a parent protocol actor that takes care of
|
||||
* its lifetime. So it needs a disconnect method to cleanup.
|
||||
*/
|
||||
disconnect: function() {
|
||||
this.destroy();
|
||||
|
@ -132,63 +132,98 @@ exports.ReflowFront = protocol.FrontClass(ReflowActor, {
|
|||
});
|
||||
|
||||
/**
|
||||
* Base class for all sorts of observers we need to create for a given window.
|
||||
* Base class for all sorts of observers that need to listen to events on the
|
||||
* tabActor's windows.
|
||||
* @param {TabActor} tabActor
|
||||
* @param {Function} callback Executed everytime the observer observes something
|
||||
*/
|
||||
function Observable(tabActor, callback) {
|
||||
this.tabActor = tabActor;
|
||||
this.callback = callback;
|
||||
|
||||
this._onWindowReady = this._onWindowReady.bind(this);
|
||||
this._onWindowDestroyed = this._onWindowDestroyed.bind(this);
|
||||
|
||||
events.on(this.tabActor, "window-ready", this._onWindowReady);
|
||||
events.on(this.tabActor, "window-destroyed", this._onWindowDestroyed);
|
||||
}
|
||||
|
||||
Observable.prototype = {
|
||||
/**
|
||||
* Is the observer currently observing
|
||||
*/
|
||||
observing: false,
|
||||
isObserving: false,
|
||||
|
||||
/**
|
||||
* Stop observing and detroy this observer instance
|
||||
*/
|
||||
destroy: function() {
|
||||
if (this.isDestroyed) {
|
||||
return;
|
||||
}
|
||||
this.isDestroyed = true;
|
||||
|
||||
this.stop();
|
||||
|
||||
events.off(this.tabActor, "window-ready", this._onWindowReady);
|
||||
events.off(this.tabActor, "window-destroyed", this._onWindowDestroyed);
|
||||
|
||||
this.callback = null;
|
||||
this.tabActor = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Start observing whatever it is this observer is supposed to observe
|
||||
*/
|
||||
start: function() {
|
||||
if (!this.observing) {
|
||||
this._start();
|
||||
this.observing = true;
|
||||
if (this.isObserving) {
|
||||
return;
|
||||
}
|
||||
},
|
||||
this.isObserving = true;
|
||||
|
||||
_start: function() {
|
||||
/* To be implemented by sub-classes */
|
||||
this._startListeners(this.tabActor.windows);
|
||||
},
|
||||
|
||||
/**
|
||||
* Stop observing
|
||||
*/
|
||||
stop: function() {
|
||||
if (this.observing) {
|
||||
this._stop();
|
||||
this.observing = false;
|
||||
if (!this.isObserving) {
|
||||
return;
|
||||
}
|
||||
this.isObserving = false;
|
||||
|
||||
if (this.tabActor.attached && this.tabActor.docShell) {
|
||||
// It's only worth stopping if the tabActor is still attached
|
||||
this._stopListeners(this.tabActor.windows);
|
||||
}
|
||||
},
|
||||
|
||||
_stop: function() {
|
||||
/* To be implemented by sub-classes */
|
||||
_onWindowReady: function({window}) {
|
||||
if (this.isObserving) {
|
||||
this._startListeners([window]);
|
||||
}
|
||||
},
|
||||
|
||||
_onWindowDestroyed: function({window}) {
|
||||
if (this.isObserving) {
|
||||
this._stopListeners([window]);
|
||||
}
|
||||
},
|
||||
|
||||
_startListeners: function(windows) {
|
||||
// To be implemented by sub-classes.
|
||||
},
|
||||
|
||||
_stopListeners: function(windows) {
|
||||
// To be implemented by sub-classes.
|
||||
},
|
||||
|
||||
/**
|
||||
* To be called by sub-classes when something has been observed
|
||||
*/
|
||||
notifyCallback: function(...args) {
|
||||
this.observing && this.callback && this.callback.apply(null, args);
|
||||
},
|
||||
|
||||
/**
|
||||
* Stop observing and detroy this observer instance
|
||||
*/
|
||||
destroy: function() {
|
||||
this.stop();
|
||||
this.callback = null;
|
||||
this.tabActor = null;
|
||||
this.isObserving && this.callback && this.callback.apply(null, args);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -212,7 +247,7 @@ exports.setIgnoreLayoutChanges = function(ignore, syncReflowNode) {
|
|||
let forceSyncReflow = syncReflowNode.offsetWidth;
|
||||
}
|
||||
gIgnoreLayoutChanges = ignore;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The LayoutChangesObserver class is instantiated only once per given tab
|
||||
|
@ -230,28 +265,31 @@ exports.setIgnoreLayoutChanges = function(ignore, syncReflowNode) {
|
|||
* corresponding events:
|
||||
*
|
||||
* - "reflows", with an array of all the reflows that occured,
|
||||
* - "resizes", with an array of all the resizes that occured,
|
||||
*
|
||||
* @param {TabActor} tabActor
|
||||
*/
|
||||
function LayoutChangesObserver(tabActor) {
|
||||
Observable.call(this, tabActor);
|
||||
this.tabActor = tabActor;
|
||||
|
||||
this._startEventLoop = this._startEventLoop.bind(this);
|
||||
this._onReflow = this._onReflow.bind(this);
|
||||
this._onResize = this._onResize.bind(this);
|
||||
|
||||
// Creating the various observers we're going to need
|
||||
// For now, just the reflow observer, but later we can add markupMutation,
|
||||
// styleSheetChanges and styleRuleChanges
|
||||
this._onReflow = this._onReflow.bind(this);
|
||||
this.reflowObserver = new ReflowObserver(this.tabActor, this._onReflow);
|
||||
this.resizeObserver = new WindowResizeObserver(this.tabActor, this._onResize);
|
||||
|
||||
EventEmitter.decorate(this);
|
||||
}
|
||||
|
||||
exports.LayoutChangesObserver = LayoutChangesObserver;
|
||||
|
||||
LayoutChangesObserver.prototype = Heritage.extend(Observable.prototype, {
|
||||
LayoutChangesObserver.prototype = {
|
||||
/**
|
||||
* How long does this observer waits before emitting a batched reflows event.
|
||||
* How long does this observer waits before emitting batched events.
|
||||
* The lower the value, the more event packets will be sent to clients,
|
||||
* potentially impacting performance.
|
||||
* The higher the value, the more time we'll wait, this is better for
|
||||
|
@ -264,22 +302,45 @@ LayoutChangesObserver.prototype = Heritage.extend(Observable.prototype, {
|
|||
* events from being sent.
|
||||
*/
|
||||
destroy: function() {
|
||||
this.isObserving = false;
|
||||
|
||||
this.reflowObserver.destroy();
|
||||
this.reflows = null;
|
||||
|
||||
Observable.prototype.destroy.call(this);
|
||||
this.resizeObserver.destroy();
|
||||
this.hasResized = false;
|
||||
|
||||
this.tabActor = null;
|
||||
},
|
||||
|
||||
_start: function() {
|
||||
start: function() {
|
||||
if (this.isObserving) {
|
||||
return;
|
||||
}
|
||||
this.isObserving = true;
|
||||
|
||||
this.reflows = [];
|
||||
this.hasResized = false;
|
||||
|
||||
this._startEventLoop();
|
||||
|
||||
this.reflowObserver.start();
|
||||
this.resizeObserver.start();
|
||||
},
|
||||
|
||||
_stop: function() {
|
||||
stop: function() {
|
||||
if (!this.isObserving) {
|
||||
return;
|
||||
}
|
||||
this.isObserving = false;
|
||||
|
||||
this._stopEventLoop();
|
||||
|
||||
this.reflows = [];
|
||||
this.hasResized = false;
|
||||
|
||||
this.reflowObserver.stop();
|
||||
this.resizeObserver.stop();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -290,7 +351,7 @@ LayoutChangesObserver.prototype = Heritage.extend(Observable.prototype, {
|
|||
_startEventLoop: function() {
|
||||
// Avoid emitting events if the tabActor has been detached (may happen
|
||||
// during shutdown)
|
||||
if (!this.tabActor.attached) {
|
||||
if (!this.tabActor || !this.tabActor.attached) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -299,6 +360,13 @@ LayoutChangesObserver.prototype = Heritage.extend(Observable.prototype, {
|
|||
this.emit("reflows", this.reflows);
|
||||
this.reflows = [];
|
||||
}
|
||||
|
||||
// Send any resizes we have
|
||||
if (this.hasResized) {
|
||||
this.emit("resize");
|
||||
this.hasResized = false;
|
||||
}
|
||||
|
||||
this.eventLoopTimer = this._setTimeout(this._startEventLoop,
|
||||
this.EVENT_BATCHING_DELAY);
|
||||
},
|
||||
|
@ -335,8 +403,21 @@ LayoutChangesObserver.prototype = Heritage.extend(Observable.prototype, {
|
|||
end: end,
|
||||
isInterruptible: isInterruptible
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Executed whenever a resize is observed. Only store a flag saying that a
|
||||
* resize occured.
|
||||
* The EVENT_BATCHING_DELAY loop will take care of it later.
|
||||
*/
|
||||
_onResize: function() {
|
||||
if (gIgnoreLayoutChanges) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.hasResized = true;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a LayoutChangesObserver instance for a given window. This function makes
|
||||
|
@ -355,12 +436,13 @@ function getLayoutChangesObserver(tabActor) {
|
|||
let obs = new LayoutChangesObserver(tabActor);
|
||||
observedWindows.set(tabActor, {
|
||||
observer: obs,
|
||||
refCounting: 1 // counting references allows to stop the observer when no
|
||||
// tabActor owns an instance
|
||||
// counting references allows to stop the observer when no tabActor owns an
|
||||
// instance.
|
||||
refCounting: 1
|
||||
});
|
||||
obs.start();
|
||||
return obs;
|
||||
};
|
||||
}
|
||||
exports.getLayoutChangesObserver = getLayoutChangesObserver;
|
||||
|
||||
/**
|
||||
|
@ -380,52 +462,23 @@ function releaseLayoutChangesObserver(tabActor) {
|
|||
observerData.observer.destroy();
|
||||
observedWindows.delete(tabActor);
|
||||
}
|
||||
};
|
||||
}
|
||||
exports.releaseLayoutChangesObserver = releaseLayoutChangesObserver;
|
||||
|
||||
/**
|
||||
* Instantiate and start a reflow observer on a given window's document element.
|
||||
* Will report any reflow that occurs in this window's docshell.
|
||||
* Reports any reflow that occurs in the tabActor's docshells.
|
||||
* @extends Observable
|
||||
* @param {TabActor} tabActor
|
||||
* @param {Function} callback Executed everytime a reflow occurs
|
||||
*/
|
||||
function ReflowObserver(tabActor, callback) {
|
||||
Observable.call(this, tabActor, callback);
|
||||
|
||||
this._onWindowReady = this._onWindowReady.bind(this);
|
||||
events.on(this.tabActor, "window-ready", this._onWindowReady);
|
||||
this._onWindowDestroyed = this._onWindowDestroyed.bind(this);
|
||||
events.on(this.tabActor, "window-destroyed", this._onWindowDestroyed);
|
||||
}
|
||||
|
||||
ReflowObserver.prototype = Heritage.extend(Observable.prototype, {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIReflowObserver,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
|
||||
_onWindowReady: function({window}) {
|
||||
if (this.observing) {
|
||||
this._startListeners([window]);
|
||||
}
|
||||
},
|
||||
|
||||
_onWindowDestroyed: function({window}) {
|
||||
if (this.observing) {
|
||||
this._stopListeners([window]);
|
||||
}
|
||||
},
|
||||
|
||||
_start: function() {
|
||||
this._startListeners(this.tabActor.windows);
|
||||
},
|
||||
|
||||
_stop: function() {
|
||||
if (this.tabActor.attached && this.tabActor.docShell) {
|
||||
// It's only worth stopping if the tabActor is still attached
|
||||
this._stopListeners(this.tabActor.windows);
|
||||
}
|
||||
},
|
||||
|
||||
_startListeners: function(windows) {
|
||||
for (let window of windows) {
|
||||
let docshell = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
|
@ -437,14 +490,15 @@ ReflowObserver.prototype = Heritage.extend(Observable.prototype, {
|
|||
|
||||
_stopListeners: function(windows) {
|
||||
for (let window of windows) {
|
||||
// Corner cases where a global has already been freed may happen, in which
|
||||
// case, no need to remove the observer
|
||||
try {
|
||||
let docshell = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShell);
|
||||
docshell.removeWeakReflowObserver(this);
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
// Corner cases where a global has already been freed may happen, in
|
||||
// which case, no need to remove the observer.
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -454,16 +508,43 @@ ReflowObserver.prototype = Heritage.extend(Observable.prototype, {
|
|||
|
||||
reflowInterruptible: function(start, end) {
|
||||
this.notifyCallback(start, end, true);
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
if (this._isDestroyed) {
|
||||
return;
|
||||
}
|
||||
this._isDestroyed = true;
|
||||
|
||||
events.off(this.tabActor, "window-ready", this._onWindowReady);
|
||||
events.off(this.tabActor, "window-destroyed", this._onWindowDestroyed);
|
||||
Observable.prototype.destroy.call(this);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Reports window resize events on the tabActor's windows.
|
||||
* @extends Observable
|
||||
* @param {TabActor} tabActor
|
||||
* @param {Function} callback Executed everytime a resize occurs
|
||||
*/
|
||||
function WindowResizeObserver(tabActor, callback) {
|
||||
Observable.call(this, tabActor, callback);
|
||||
this.onResize = this.onResize.bind(this);
|
||||
}
|
||||
|
||||
WindowResizeObserver.prototype = Heritage.extend(Observable.prototype, {
|
||||
_startListeners: function() {
|
||||
this.listenerTarget.addEventListener("resize", this.onResize);
|
||||
},
|
||||
|
||||
_stopListeners: function() {
|
||||
this.listenerTarget.removeEventListener("resize", this.onResize);
|
||||
},
|
||||
|
||||
onResize: function() {
|
||||
this.notifyCallback();
|
||||
},
|
||||
|
||||
get listenerTarget() {
|
||||
// For the rootActor, return its window.
|
||||
if (this.tabActor.isRootActor) {
|
||||
return this.tabActor.window;
|
||||
}
|
||||
|
||||
// Otherwise, get the tabActor's chromeEventHandler.
|
||||
return this.tabActor.window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShell)
|
||||
.chromeEventHandler;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -76,6 +76,7 @@ skip-if = buildapp == 'mulet'
|
|||
[test_inspector-release.html]
|
||||
[test_inspector-reload.html]
|
||||
[test_inspector-remove.html]
|
||||
[test_inspector-resize.html]
|
||||
[test_inspector-resolve-url.html]
|
||||
[test_inspector-retain.html]
|
||||
[test_inspector-search.html]
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Test that the inspector actor emits "resize" events when the page is resized.
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1222409
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 1222409</title>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
|
||||
<script type="application/javascript;version=1.8" src="inspector-helpers.js"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = function() {
|
||||
const Cu = Components.utils;
|
||||
Cu.import("resource://gre/modules/devtools/Loader.jsm");
|
||||
const {Promise: promise} =
|
||||
Cu.import("resource://gre/modules/Promise.jsm", {});
|
||||
const {InspectorFront} =
|
||||
devtools.require("devtools/server/actors/inspector");
|
||||
const {console} =
|
||||
Cu.import("resource://gre/modules/devtools/shared/Console.jsm", {});
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
let win = null;
|
||||
let inspector = null;
|
||||
|
||||
addAsyncTest(function* setup() {
|
||||
info ("Setting up inspector and walker actors.");
|
||||
|
||||
let url = document.getElementById("inspectorContent").href;
|
||||
|
||||
yield new Promise(resolve => {
|
||||
attachURL(url, function(err, client, tab, doc) {
|
||||
win = doc.defaultView;
|
||||
inspector = InspectorFront(client, tab);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
runNextTest();
|
||||
});
|
||||
|
||||
addAsyncTest(function*() {
|
||||
let walker = yield inspector.getWalker();
|
||||
|
||||
// We can't receive events from the walker if we haven't first executed a
|
||||
// method on the actor to initialize it.
|
||||
yield walker.querySelector(walker.rootNode, "img");
|
||||
|
||||
let {outerWidth, outerHeight} = win;
|
||||
let onResize = new Promise(resolve => {
|
||||
walker.once("resize", () => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
win.resizeTo(800, 600);
|
||||
yield onResize;
|
||||
|
||||
ok(true, "The resize event was emitted");
|
||||
win.resizeTo(outerWidth, outerHeight);
|
||||
|
||||
runNextTest();
|
||||
});
|
||||
|
||||
runNextTest();
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a id="inspectorContent" target="_blank" href="inspector-search-data.html">Test Document</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -56,7 +56,26 @@ MockDocShell.prototype = {
|
|||
addWeakReflowObserver: function(observer) {
|
||||
this.observer = observer;
|
||||
},
|
||||
removeWeakReflowObserver: function(observer) {}
|
||||
removeWeakReflowObserver: function() {},
|
||||
get chromeEventHandler() {
|
||||
return {
|
||||
addEventListener: (type, cb) => {
|
||||
if (type === "resize") {
|
||||
this.resizeCb = cb;
|
||||
}
|
||||
},
|
||||
removeEventListener: (type, cb) => {
|
||||
if (type === "resize" && cb === this.resizeCb) {
|
||||
this.resizeCb = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
mockResize: function() {
|
||||
if (this.resizeCb) {
|
||||
this.resizeCb();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function run_test() {
|
||||
|
@ -110,6 +129,10 @@ function eventsAreBatched() {
|
|||
let onReflows = (event, reflows) => reflowsEvents.push(reflows);
|
||||
observer.on("reflows", onReflows);
|
||||
|
||||
let resizeEvents = [];
|
||||
let onResize = () => resizeEvents.push("resize");
|
||||
observer.on("resize", onResize);
|
||||
|
||||
do_print("Fake one reflow event");
|
||||
tabActor.window.docShell.observer.reflow();
|
||||
do_print("Checking that no batched reflow event has been emitted");
|
||||
|
@ -120,12 +143,21 @@ function eventsAreBatched() {
|
|||
do_print("Checking that still no batched reflow event has been emitted");
|
||||
do_check_eq(reflowsEvents.length, 0);
|
||||
|
||||
do_print("Faking timeout expiration and checking that reflow events are sent");
|
||||
do_print("Fake a few of resize events too");
|
||||
tabActor.window.docShell.mockResize();
|
||||
tabActor.window.docShell.mockResize();
|
||||
tabActor.window.docShell.mockResize();
|
||||
do_print("Checking that still no batched resize event has been emitted");
|
||||
do_check_eq(resizeEvents.length, 0);
|
||||
|
||||
do_print("Faking timeout expiration and checking that events are sent");
|
||||
observer.eventLoopTimer();
|
||||
do_check_eq(reflowsEvents.length, 1);
|
||||
do_check_eq(reflowsEvents[0].length, 2);
|
||||
do_check_eq(resizeEvents.length, 1);
|
||||
|
||||
observer.off("reflows", onReflows);
|
||||
observer.off("resize", onResize);
|
||||
releaseLayoutChangesObserver(tabActor);
|
||||
}
|
||||
|
||||
|
@ -153,13 +185,13 @@ function observerIsAlreadyStarted() {
|
|||
|
||||
let tabActor = new MockTabActor();
|
||||
let observer = getLayoutChangesObserver(tabActor);
|
||||
do_check_true(observer.observing);
|
||||
do_check_true(observer.isObserving);
|
||||
|
||||
observer.stop();
|
||||
do_check_false(observer.observing);
|
||||
do_check_false(observer.isObserving);
|
||||
|
||||
observer.start();
|
||||
do_check_true(observer.observing);
|
||||
do_check_true(observer.isObserving);
|
||||
|
||||
releaseLayoutChangesObserver(tabActor);
|
||||
}
|
||||
|
@ -169,10 +201,10 @@ function destroyStopsObserving() {
|
|||
|
||||
let tabActor = new MockTabActor();
|
||||
let observer = getLayoutChangesObserver(tabActor);
|
||||
do_check_true(observer.observing);
|
||||
do_check_true(observer.isObserving);
|
||||
|
||||
observer.destroy();
|
||||
do_check_false(observer.observing);
|
||||
do_check_false(observer.isObserving);
|
||||
|
||||
releaseLayoutChangesObserver(tabActor);
|
||||
}
|
||||
|
@ -184,18 +216,18 @@ function stoppingAndStartingSeveralTimesWorksCorrectly() {
|
|||
let tabActor = new MockTabActor();
|
||||
let observer = getLayoutChangesObserver(tabActor);
|
||||
|
||||
do_check_true(observer.observing);
|
||||
do_check_true(observer.isObserving);
|
||||
observer.start();
|
||||
observer.start();
|
||||
observer.start();
|
||||
do_check_true(observer.observing);
|
||||
do_check_true(observer.isObserving);
|
||||
|
||||
observer.stop();
|
||||
do_check_false(observer.observing);
|
||||
do_check_false(observer.isObserving);
|
||||
|
||||
observer.stop();
|
||||
observer.stop();
|
||||
do_check_false(observer.observing);
|
||||
do_check_false(observer.isObserving);
|
||||
|
||||
releaseLayoutChangesObserver(tabActor);
|
||||
}
|
||||
|
|
|
@ -174,6 +174,7 @@ const EXPERIMENTS_CHANGED_TOPIC = "experiments-changed";
|
|||
const SEARCH_ENGINE_MODIFIED_TOPIC = "browser-search-engine-modified";
|
||||
const SEARCH_SERVICE_TOPIC = "browser-search-service";
|
||||
const COMPOSITOR_CREATED_TOPIC = "compositor:created";
|
||||
const DISTRIBUTION_CUSTOMIZATION_COMPLETE_TOPIC = "distribution-customization-complete";
|
||||
|
||||
/**
|
||||
* Get the current browser.
|
||||
|
@ -683,6 +684,7 @@ function EnvironmentCache() {
|
|||
this._updateSettings();
|
||||
// Fill in the default search engine, if the search provider is already initialized.
|
||||
this._updateSearchEngine();
|
||||
this._addObservers();
|
||||
|
||||
// Build the remaining asynchronous parts of the environment. Don't register change listeners
|
||||
// until the initial environment has been built.
|
||||
|
@ -706,7 +708,6 @@ function EnvironmentCache() {
|
|||
this._initTask = null;
|
||||
this._startWatchingPrefs();
|
||||
this._addonBuilder.watchForChanges();
|
||||
this._addObservers();
|
||||
this._updateGraphicsFeatures();
|
||||
return this.currentEnvironment;
|
||||
};
|
||||
|
@ -847,6 +848,7 @@ EnvironmentCache.prototype = {
|
|||
Services.obs.addObserver(this, SEARCH_ENGINE_MODIFIED_TOPIC, false);
|
||||
Services.obs.addObserver(this, SEARCH_SERVICE_TOPIC, false);
|
||||
Services.obs.addObserver(this, COMPOSITOR_CREATED_TOPIC, false);
|
||||
Services.obs.addObserver(this, DISTRIBUTION_CUSTOMIZATION_COMPLETE_TOPIC, false);
|
||||
},
|
||||
|
||||
_removeObservers: function () {
|
||||
|
@ -854,6 +856,9 @@ EnvironmentCache.prototype = {
|
|||
Services.obs.removeObserver(this, SEARCH_ENGINE_MODIFIED_TOPIC);
|
||||
Services.obs.removeObserver(this, SEARCH_SERVICE_TOPIC);
|
||||
Services.obs.removeObserver(this, COMPOSITOR_CREATED_TOPIC);
|
||||
try {
|
||||
Services.obs.removeObserver(this, DISTRIBUTION_CUSTOMIZATION_COMPLETE_TOPIC);
|
||||
} catch(ex) {};
|
||||
},
|
||||
|
||||
observe: function (aSubject, aTopic, aData) {
|
||||
|
@ -879,6 +884,12 @@ EnvironmentCache.prototype = {
|
|||
// first compositor to be created and then query nsIGfxInfo again.
|
||||
this._updateGraphicsFeatures();
|
||||
break;
|
||||
case DISTRIBUTION_CUSTOMIZATION_COMPLETE_TOPIC:
|
||||
// Distribution customizations are applied after final-ui-startup. query
|
||||
// partner prefs again when they are ready.
|
||||
this._updatePartner();
|
||||
Services.obs.removeObserver(this, aTopic);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -958,6 +969,13 @@ EnvironmentCache.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the partner prefs.
|
||||
*/
|
||||
_updatePartner: function() {
|
||||
this._currentEnvironment.partner = this._getPartner();
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the build data in object form.
|
||||
* @return Object containing the build data.
|
||||
|
|
|
@ -63,7 +63,7 @@ Structure::
|
|||
creationDate: <integer>, // integer days since UNIX epoch, e.g. 16446
|
||||
resetDate: <integer>, // integer days since UNIX epoch, e.g. 16446 - optional
|
||||
},
|
||||
partner: {
|
||||
partner: { // This section may not be immediately available on startup
|
||||
distributionId: <string>, // pref "distribution.id", null on failure
|
||||
distributionVersion: <string>, // pref "distribution.version", null on failure
|
||||
partnerId: <string>, // pref mozilla.partner.id, null on failure
|
||||
|
@ -300,6 +300,11 @@ The following is a partial list of collected preferences.
|
|||
|
||||
- ``browser.urlbar.userMadeSearchSuggestionsChoice``: True if the user has clicked Yes or No in the urlbar's opt-in notification. Defaults to false.
|
||||
|
||||
partner
|
||||
~~~~~~~
|
||||
|
||||
If the user is using a partner repack, this contains information identifying the repack being used, otherwise "partnerNames" will be an empty array and other entries will be null. The information may be missing when the profile just becomes available. In Firefox for desktop, the information along with other customizations defined in distribution.ini are processed later in the startup phase, and will be fully applied when "distribution-customization-complete" notification is sent.
|
||||
|
||||
activeAddons
|
||||
~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ const DISTRIBUTOR_NAME = "Some Distributor";
|
|||
const DISTRIBUTOR_CHANNEL = "A Channel";
|
||||
const PARTNER_NAME = "test";
|
||||
const PARTNER_ID = "NicePartner-ID-3785";
|
||||
const DISTRIBUTION_CUSTOMIZATION_COMPLETE_TOPIC = "distribution-customization-complete";
|
||||
|
||||
const GFX_VENDOR_ID = "0xabcd";
|
||||
const GFX_DEVICE_ID = "0x1234";
|
||||
|
@ -303,7 +304,7 @@ function checkProfileSection(data) {
|
|||
Assert.equal(data.profile.resetDate, truncateToDays(PROFILE_RESET_DATE_MS));
|
||||
}
|
||||
|
||||
function checkPartnerSection(data) {
|
||||
function checkPartnerSection(data, isInitial) {
|
||||
const EXPECTED_FIELDS = {
|
||||
distributionId: DISTRIBUTION_ID,
|
||||
distributionVersion: DISTRIBUTION_VERSION,
|
||||
|
@ -315,12 +316,17 @@ function checkPartnerSection(data) {
|
|||
Assert.ok("partner" in data, "There must be a partner section in Environment.");
|
||||
|
||||
for (let f in EXPECTED_FIELDS) {
|
||||
Assert.equal(data.partner[f], EXPECTED_FIELDS[f], f + " must have the correct value.");
|
||||
let expected = isInitial ? null : EXPECTED_FIELDS[f];
|
||||
Assert.strictEqual(data.partner[f], expected, f + " must have the correct value.");
|
||||
}
|
||||
|
||||
// Check that "partnerNames" exists and contains the correct element.
|
||||
Assert.ok(Array.isArray(data.partner.partnerNames));
|
||||
Assert.ok(data.partner.partnerNames.indexOf(PARTNER_NAME) >= 0);
|
||||
if (isInitial) {
|
||||
Assert.equal(data.partner.partnerNames.length, 0);
|
||||
} else {
|
||||
Assert.ok(data.partner.partnerNames.indexOf(PARTNER_NAME) >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
function checkGfxAdapter(data) {
|
||||
|
@ -611,11 +617,11 @@ function checkAddonsSection(data) {
|
|||
Assert.ok(checkNullOrString(data.addons.persona));
|
||||
}
|
||||
|
||||
function checkEnvironmentData(data) {
|
||||
function checkEnvironmentData(data, isInitial = false) {
|
||||
checkBuildSection(data);
|
||||
checkSettingsSection(data);
|
||||
checkProfileSection(data);
|
||||
checkPartnerSection(data);
|
||||
checkPartnerSection(data, isInitial);
|
||||
checkSystemSection(data);
|
||||
checkAddonsSection(data);
|
||||
}
|
||||
|
@ -645,7 +651,6 @@ function run_test() {
|
|||
gHttpServer.registerDirectory("/data/", do_get_cwd());
|
||||
do_register_cleanup(() => gHttpServer.stop(() => {}));
|
||||
|
||||
spoofPartnerInfo();
|
||||
// Spoof the the hotfixVersion
|
||||
Preferences.set("extensions.hotfix.lastVersion", APP_HOTFIX_VERSION);
|
||||
|
||||
|
@ -664,6 +669,12 @@ add_task(function* asyncSetup() {
|
|||
|
||||
add_task(function* test_checkEnvironment() {
|
||||
let environmentData = yield TelemetryEnvironment.onInitialized();
|
||||
checkEnvironmentData(environmentData, true);
|
||||
|
||||
spoofPartnerInfo();
|
||||
Services.obs.notifyObservers(null, DISTRIBUTION_CUSTOMIZATION_COMPLETE_TOPIC, null);
|
||||
|
||||
environmentData = TelemetryEnvironment.currentEnvironment;
|
||||
checkEnvironmentData(environmentData);
|
||||
});
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче