mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-21 17:59:34 +00:00
merge m-c to fx-team
This commit is contained in:
commit
b19af7fcad
@ -1026,7 +1026,7 @@ pref("devtools.layoutview.enabled", false);
|
||||
pref("devtools.layoutview.open", false);
|
||||
|
||||
// Enable the Debugger
|
||||
pref("devtools.debugger.enabled", false);
|
||||
pref("devtools.debugger.enabled", true);
|
||||
pref("devtools.debugger.remote-enabled", false);
|
||||
pref("devtools.debugger.remote-host", "localhost");
|
||||
pref("devtools.debugger.remote-port", 6000);
|
||||
|
@ -73,16 +73,16 @@ let DocumentUtils = {
|
||||
// <select>s without the multiple attribute are hard to determine the
|
||||
// default value, so assume we don't have the default.
|
||||
hasDefaultValue = false;
|
||||
value = node.selectedIndex;
|
||||
value = { selectedIndex: node.selectedIndex, value: node.value };
|
||||
} else {
|
||||
// <select>s with the multiple attribute are easier to determine the
|
||||
// default value since each <option> has a defaultSelected
|
||||
let options = Array.map(node.options, function(aOpt, aIx) {
|
||||
let oSelected = aOpt.selected;
|
||||
hasDefaultValue = hasDefaultValue && (oSelected == aOpt.defaultSelected);
|
||||
return oSelected ? aIx : -1;
|
||||
return oSelected ? aOpt.value : -1;
|
||||
});
|
||||
value = options.filter(function(aIx) aIx >= 0);
|
||||
value = options.filter(function(aIx) aIx !== -1);
|
||||
}
|
||||
|
||||
// In order to reduce XPath generation (which is slow), we only save data
|
||||
@ -177,23 +177,41 @@ let DocumentUtils = {
|
||||
aNode.checked = aValue;
|
||||
eventType = "change";
|
||||
} else if (typeof aValue == "number") {
|
||||
// handle select backwards compatibility, example { "#id" : index }
|
||||
// We saved the value blindly since selects take more work to determine
|
||||
// default values. So now we should check to avoid unnecessary events.
|
||||
if (aNode.selectedIndex == aValue) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (aValue < aNode.options.length) {
|
||||
aNode.selectedIndex = aValue;
|
||||
eventType = "change";
|
||||
} catch (ex) { /* throws for invalid indices */ }
|
||||
}
|
||||
} else if (aValue && aValue.selectedIndex >= 0 && aValue.value) {
|
||||
// handle select new format
|
||||
|
||||
// Don't dispatch a change event for no change
|
||||
if (aNode.options[aNode.selectedIndex].value == aValue.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
// find first option with matching aValue if possible
|
||||
for (let i = 0; i < aNode.options.length; i++) {
|
||||
if (aNode.options[i].value == aValue.value) {
|
||||
aNode.selectedIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
eventType = "change";
|
||||
} else if (aValue && aValue.fileList && aValue.type == "file" &&
|
||||
aNode.type == "file") {
|
||||
aNode.mozSetFileNameArray(aValue.fileList, aValue.fileList.length);
|
||||
eventType = "input";
|
||||
} else if (aValue && typeof aValue.indexOf == "function" && aNode.options) {
|
||||
Array.forEach(aNode.options, function(opt, index) {
|
||||
opt.selected = aValue.indexOf(index) > -1;
|
||||
// don't worry about malformed options with same values
|
||||
opt.selected = aValue.indexOf(opt.value) > -1;
|
||||
|
||||
// Only fire the event here if this wasn't selected by default
|
||||
if (!opt.defaultSelected) {
|
||||
|
@ -121,6 +121,8 @@ _BROWSER_TEST_FILES = \
|
||||
browser_644409-scratchpads.js \
|
||||
browser_645428.js \
|
||||
browser_659591.js \
|
||||
browser_662743.js \
|
||||
browser_662743_sample.html \
|
||||
browser_662812.js \
|
||||
browser_665702-state_session.js \
|
||||
browser_682507.js \
|
||||
|
128
browser/components/sessionstore/test/browser_662743.js
Normal file
128
browser/components/sessionstore/test/browser_662743.js
Normal file
@ -0,0 +1,128 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// This tests that session restore component does restore the right <select> option.
|
||||
// Session store should not rely only on previous user's selectedIndex, it should
|
||||
// check its value as well.
|
||||
|
||||
function test() {
|
||||
/** Tests selected options **/
|
||||
waitForExplicitFinish();
|
||||
|
||||
let testTabCount = 0;
|
||||
let formData = [
|
||||
// default case
|
||||
{ },
|
||||
// old format
|
||||
{ "#select_id" : 0 },
|
||||
{ "#select_id" : 2 },
|
||||
// invalid index
|
||||
{ "#select_id" : 8 },
|
||||
{ "/xhtml:html/xhtml:body/xhtml:select" : 5},
|
||||
{ "/xhtml:html/xhtml:body/xhtml:select[@name='select_name']" : 6},
|
||||
|
||||
// new format
|
||||
// index doesn't match value (testing an option in between (two))
|
||||
{ id:{ "select_id": {"selectedIndex":0,"value":"val2"} } },
|
||||
// index doesn't match value (testing an invalid value)
|
||||
{ id:{ "select_id": {"selectedIndex":4,"value":"val8"} } },
|
||||
// index doesn't match value (testing an invalid index)
|
||||
{ id:{ "select_id": {"selectedIndex":8,"value":"val5"} } },
|
||||
// index and value match position zero
|
||||
{ id:{ "select_id": {"selectedIndex":0,"value":"val0"} }, xpath: {} },
|
||||
// index doesn't match value (testing the last option (seven))
|
||||
{ id:{},"xpath":{ "/xhtml:html/xhtml:body/xhtml:select[@name='select_name']": {"selectedIndex":1,"value":"val7"} } },
|
||||
// index and value match the default option "selectedIndex":3,"value":"val3"
|
||||
{ xpath: { "/xhtml:html/xhtml:body/xhtml:select[@name='select_name']" : {"selectedIndex":3,"value":"val3"} } },
|
||||
// index matches default option however it doesn't match value
|
||||
{ id:{ "select_id": {"selectedIndex":3,"value":"val4"} } },
|
||||
|
||||
// combinations
|
||||
{ "#select_id" : 3, id:{ "select_id": {"selectedIndex":1,"value":"val1"} } },
|
||||
{ "#select_id" : 5, xpath: { "/xhtml:html/xhtml:body/xhtml:select[@name='select_name']" : {"selectedIndex":4,"value":"val4"} } },
|
||||
{ "/xhtml:html/xhtml:body/xhtml:select" : 5, id:{ "select_id": {"selectedIndex":1,"value":"val1"} }},
|
||||
{ "/xhtml:html/xhtml:body/xhtml:select[@name='select_name']" : 2, xpath: { "/xhtml:html/xhtml:body/xhtml:select[@name='select_name']" : {"selectedIndex":7,"value":"val7"} } }
|
||||
];
|
||||
|
||||
let expectedValues = [
|
||||
[ "val3"], // default value
|
||||
[ "val0"],
|
||||
[ "val2"],
|
||||
[ "val3"], // default value (invalid index)
|
||||
[ "val5"],
|
||||
[ "val6"],
|
||||
[ "val2"],
|
||||
[ "val3"], // default value (invalid value)
|
||||
[ "val5"], // value is still valid (even it has an invalid index)
|
||||
[ "val0"],
|
||||
[ "val7"],
|
||||
[ "val3"],
|
||||
[ "val4"],
|
||||
[ "val1"],
|
||||
[ "val4"],
|
||||
[ "val1"],
|
||||
[ "val7"]
|
||||
];
|
||||
let callback = function() {
|
||||
testTabCount--;
|
||||
if (testTabCount == 0) {
|
||||
finish();
|
||||
}
|
||||
};
|
||||
|
||||
for (let i = 0; i < formData.length; i++) {
|
||||
testTabCount++;
|
||||
testTabRestoreData(formData[i], expectedValues[i], callback);
|
||||
}
|
||||
}
|
||||
|
||||
function testTabRestoreData(aFormData, aExpectedValues, aCallback) {
|
||||
let testURL =
|
||||
getRootDirectory(gTestPath) + "browser_662743_sample.html";
|
||||
let tab = gBrowser.addTab(testURL);
|
||||
let tabState = { entries: [{ url: testURL, formdata: aFormData}] };
|
||||
|
||||
tab.linkedBrowser.addEventListener("load", function(aEvent) {
|
||||
tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
ss.setTabState(tab, JSON.stringify(tabState));
|
||||
|
||||
tab.addEventListener("SSTabRestored", function(aEvent) {
|
||||
tab.removeEventListener("SSTabRestored", arguments.callee);
|
||||
let doc = tab.linkedBrowser.contentDocument;
|
||||
let select = doc.getElementById("select_id");
|
||||
let value = select.options[select.selectedIndex].value;
|
||||
|
||||
// test select options values
|
||||
is(value, aExpectedValues[0],
|
||||
"Select Option by selectedIndex &/or value has been restored correctly");
|
||||
|
||||
// clean up
|
||||
gBrowser.removeTab(tab);
|
||||
aCallback();
|
||||
});
|
||||
|
||||
tab.addEventListener("TabClose", function(aEvent) {
|
||||
tab.removeEventListener("TabClose", arguments.callee);
|
||||
let restoredTabState = JSON.parse(ss.getTabState(tab));
|
||||
let restoredFormData = restoredTabState.entries[0].formdata;
|
||||
let selectIdFormData = restoredFormData.id.select_id;
|
||||
let value = restoredFormData.id.select_id.value;
|
||||
|
||||
// test format
|
||||
ok("id" in restoredFormData && "xpath" in restoredFormData,
|
||||
"FormData format is valid");
|
||||
// validate that there are no old keys
|
||||
is(Object.keys(restoredFormData).length, 2,
|
||||
"FormData key length is valid");
|
||||
// test format
|
||||
ok("selectedIndex" in selectIdFormData && "value" in selectIdFormData,
|
||||
"select format is valid");
|
||||
// validate that there are no old keys
|
||||
is(Object.keys(selectIdFormData).length, 2,
|
||||
"select_id length is valid");
|
||||
// test set collection values
|
||||
is(value, aExpectedValues[0],
|
||||
"Collection has been saved correctly");
|
||||
});
|
||||
}, true);
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<title>Test 662743</title>
|
||||
|
||||
<!-- Select events -->
|
||||
<h3>Select options</h3>
|
||||
<select id="select_id" name="select_name">
|
||||
<option value="val0">Zero</option>
|
||||
<option value="val1">One</option>
|
||||
<option value="val2">Two</option>
|
||||
<option value="val3" selected="selected">Three</option>
|
||||
<option value="val4">Four</option>
|
||||
<option value="val5">Five</option>
|
||||
<option value="val6">Six</option>
|
||||
<option value="val7">Seven</option>
|
||||
</select>
|
@ -6201,7 +6201,7 @@ var eagerHelperSettingSpec = {
|
||||
{ name: 'always', value: Eagerness.ALWAYS },
|
||||
]
|
||||
},
|
||||
defaultValue: 1,
|
||||
defaultValue: Eagerness.SOMETIMES,
|
||||
description: l10n.lookup('eagerHelperDesc'),
|
||||
ignoreTypeDifference: true
|
||||
};
|
||||
@ -6346,7 +6346,8 @@ FocusManager.prototype.removeMonitoredElement = function(element, where) {
|
||||
FocusManager.prototype.updatePosition = function(dimensions) {
|
||||
var ev = {
|
||||
tooltipVisible: this.isTooltipVisible,
|
||||
outputVisible: this.isOutputVisible
|
||||
outputVisible: this.isOutputVisible,
|
||||
dimensions: dimensions
|
||||
};
|
||||
this.onVisibilityChange(ev);
|
||||
};
|
||||
|
58
browser/devtools/commandline/gclioutput.xhtml
Normal file
58
browser/devtools/commandline/gclioutput.xhtml
Normal file
@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
||||
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"
|
||||
[
|
||||
<!ENTITY % webConsoleDTD SYSTEM "chrome://browser/locale/devtools/webConsole.dtd">
|
||||
%webConsoleDTD;
|
||||
]
|
||||
>
|
||||
|
||||
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License Version
|
||||
- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
- the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is GCLI.
|
||||
-
|
||||
- The Initial Developer of the Original Code is
|
||||
- Mozilla Foundation.
|
||||
- Portions created by the Initial Developer are Copyright (C) 2012
|
||||
- the Initial Developer. All Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Joe Walker <jwalker@mozilla.com>
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the terms of
|
||||
- either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
- in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
- of those above. If you wish to allow use of your version of this file only
|
||||
- under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
- use your version of this file under the terms of the MPL, indicate your
|
||||
- decision by deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the LGPL or the GPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this file under
|
||||
- the terms of any one of the MPL, the GPL or the LGPL.
|
||||
-
|
||||
- ***** END LICENSE BLOCK ***** -->
|
||||
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<link rel="stylesheet" href="chrome://global/skin/global.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="chrome://browser/content/devtools/gcli.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="chrome://browser/skin/devtools/gcli.css" type="text/css"/>
|
||||
</head>
|
||||
<body class="gcli-body">
|
||||
<div id="gcli-output-root"></div>
|
||||
</body>
|
||||
</html>
|
@ -19,8 +19,8 @@
|
||||
<link rel="stylesheet" href="chrome://browser/content/devtools/gcli.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="chrome://browser/skin/devtools/gcli.css" type="text/css"/>
|
||||
</head>
|
||||
<body id="gclichrome-body">
|
||||
<div>
|
||||
</div>
|
||||
<body class="gcli-body">
|
||||
<div id="gcli-tooltip-root"></div>
|
||||
<div id="gcli-tooltip-connector"></div>
|
||||
</body>
|
||||
</html>
|
@ -533,32 +533,10 @@ StackFrames.prototype = {
|
||||
paramVar.setGrip(paramVal);
|
||||
this._addExpander(paramVar, paramVal);
|
||||
}
|
||||
|
||||
// If we already found 'arguments', we are done here.
|
||||
if ("arguments" in frame.environment.bindings.variables) {
|
||||
// Signal that variables have been fetched.
|
||||
DebuggerController.dispatchEvent("Debugger:FetchedVariables");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Sometimes in call frames with arguments we don't get 'arguments' in the
|
||||
// environment (bug 746601) and we have to construct it manually. Note, that
|
||||
// in this case arguments.callee will be absent, even in the cases where it
|
||||
// shouldn't be.
|
||||
if (frame.arguments && frame.arguments.length > 0) {
|
||||
// Add "arguments".
|
||||
let argsVar = localScope.addVar("arguments");
|
||||
argsVar.setGrip({
|
||||
type: "object",
|
||||
class: "Arguments"
|
||||
});
|
||||
this._addExpander(argsVar, frame.arguments);
|
||||
|
||||
// Signal that variables have been fetched.
|
||||
DebuggerController.dispatchEvent("Debugger:FetchedVariables");
|
||||
}
|
||||
|
||||
// Signal that variables have been fetched.
|
||||
DebuggerController.dispatchEvent("Debugger:FetchedVariables");
|
||||
},
|
||||
|
||||
/**
|
||||
@ -566,10 +544,9 @@ StackFrames.prototype = {
|
||||
* new properties.
|
||||
*/
|
||||
_addExpander: function SF__addExpander(aVar, aObject) {
|
||||
// No need for expansion for null and undefined values, but we do need them
|
||||
// for frame.arguments which is a regular array.
|
||||
// No need for expansion for null and undefined values.
|
||||
if (!aVar || !aObject || typeof aObject !== "object" ||
|
||||
(aObject.type !== "object" && !Array.isArray(aObject))) {
|
||||
aObject.type !== "object") {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -588,23 +565,6 @@ StackFrames.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
// For arrays we have to construct a grip-like object.
|
||||
if (Array.isArray(aObject)) {
|
||||
let properties = { length: { value: aObject.length } };
|
||||
for (let i = 0, l = aObject.length; i < l; i++) {
|
||||
properties[i] = { value: aObject[i] };
|
||||
}
|
||||
aVar.addProperties(properties);
|
||||
|
||||
// Expansion handlers must be set after the properties are added.
|
||||
for (let i = 0, l = aObject.length; i < l; i++) {
|
||||
this._addExpander(aVar[i], aObject[i]);
|
||||
}
|
||||
|
||||
aVar.fetched = true;
|
||||
return;
|
||||
}
|
||||
|
||||
let objClient = this.activeThread.pauseGrip(aObject);
|
||||
objClient.getPrototypeAndProperties(function SF_onProtoAndProps(aResponse) {
|
||||
// Add __proto__.
|
||||
|
@ -76,18 +76,17 @@ function testFrameParameters()
|
||||
is(localNodes[6].querySelector(".info").textContent, "undefined",
|
||||
"Should have the right property value for 'fArg'.");
|
||||
|
||||
// FIXME bug TODO: reenable
|
||||
//is(localNodes[7].querySelector(".info").textContent, "1",
|
||||
// "Should have the right property value for 'a'.");
|
||||
is(localNodes[7].querySelector(".info").textContent, "1",
|
||||
"Should have the right property value for 'a'.");
|
||||
|
||||
//is(localNodes[8].querySelector(".info").textContent, "[object Object]",
|
||||
// "Should have the right property value for 'b'.");
|
||||
is(localNodes[8].querySelector(".info").textContent, "[object Object]",
|
||||
"Should have the right property value for 'b'.");
|
||||
|
||||
//is(localNodes[9].querySelector(".info").textContent, "[object Object]",
|
||||
// "Should have the right property value for 'c'.");
|
||||
is(localNodes[9].querySelector(".info").textContent, "[object Object]",
|
||||
"Should have the right property value for 'c'.");
|
||||
|
||||
//is(localNodes[10].querySelector(".info").textContent, "[object Arguments]",
|
||||
// "Should have the right property value for 'arguments'.");
|
||||
is(localNodes[10].querySelector(".info").textContent, "[object Arguments]",
|
||||
"Should have the right property value for 'arguments'.");
|
||||
|
||||
resumeAndFinish();
|
||||
}}, 0);
|
||||
|
@ -56,7 +56,7 @@ function testFrameParameters()
|
||||
is(localNodes[0].querySelector(".info").textContent, "[object Proxy]",
|
||||
"Should have the right property value for 'this'.");
|
||||
|
||||
// Expand the '__proto__', 'arguments' and 'a' tree nodes. This causes
|
||||
// Expand the 'this', 'arguments' and 'c' tree nodes. This causes
|
||||
// their properties to be retrieved and displayed.
|
||||
localNodes[0].expand();
|
||||
localNodes[9].expand();
|
||||
@ -67,6 +67,7 @@ function testFrameParameters()
|
||||
// content window timers are disabled while the debuggee is paused.
|
||||
let count = 0;
|
||||
let intervalID = window.setInterval(function(){
|
||||
dump("count: "+count+" ");
|
||||
if (++count > 50) {
|
||||
ok(false, "Timed out while polling for the properties.");
|
||||
resumeAndFinish();
|
||||
@ -96,17 +97,17 @@ function testFrameParameters()
|
||||
.textContent, 1,
|
||||
"Should have the right value for 'c.a'.");
|
||||
|
||||
//is(localNodes[10].querySelector(".info").textContent,
|
||||
// "[object Arguments]",
|
||||
// "Should have the right property value for 'arguments'.");
|
||||
is(localNodes[10].querySelector(".info").textContent,
|
||||
"[object Arguments]",
|
||||
"Should have the right property value for 'arguments'.");
|
||||
|
||||
//is(localNodes[10].querySelector(".property > .title > .key")
|
||||
// .textContent, "length",
|
||||
// "Should have the right property name for 'length'.");
|
||||
is(localNodes[10].querySelectorAll(".property > .title > .key")[7]
|
||||
.textContent, "length",
|
||||
"Should have the right property name for 'length'.");
|
||||
|
||||
//is(localNodes[10].querySelector(".property > .title > .value")
|
||||
// .textContent, 5,
|
||||
// "Should have the right argument length.");
|
||||
is(localNodes[10].querySelectorAll(".property > .title > .value")[7]
|
||||
.textContent, 5,
|
||||
"Should have the right argument length.");
|
||||
|
||||
resumeAndFinish();
|
||||
}, 100);
|
||||
|
@ -23,4 +23,5 @@ browser.jar:
|
||||
content/browser/debugger-controller.js (debugger/debugger-controller.js)
|
||||
content/browser/debugger-view.js (debugger/debugger-view.js)
|
||||
content/browser/devtools/gcli.css (commandline/gcli.css)
|
||||
content/browser/devtools/gcliblank.xhtml (commandline/gcliblank.xhtml)
|
||||
content/browser/devtools/gclioutput.xhtml (commandline/gclioutput.xhtml)
|
||||
content/browser/devtools/gclitooltip.xhtml (commandline/gclitooltip.xhtml)
|
||||
|
@ -7,7 +7,6 @@
|
||||
const EXPORTED_SYMBOLS = [ "DeveloperToolbar" ];
|
||||
|
||||
const NS_XHTML = "http://www.w3.org/1999/xhtml";
|
||||
const URI_GCLIBLANK = "chrome://browser/content/devtools/gcliblank.xhtml";
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
@ -79,7 +78,6 @@ DeveloperToolbar.prototype.toggle = function DT_toggle()
|
||||
this.hide();
|
||||
} else {
|
||||
this.show();
|
||||
this._input.focus();
|
||||
}
|
||||
};
|
||||
|
||||
@ -154,9 +152,11 @@ DeveloperToolbar.prototype._onload = function DT_onload()
|
||||
this.display.onOutput.add(this.outputPanel._outputChanged, this.outputPanel);
|
||||
|
||||
this._chromeWindow.getBrowser().tabContainer.addEventListener("TabSelect", this, false);
|
||||
this._chromeWindow.getBrowser().addEventListener("load", this, true);
|
||||
this._chromeWindow.getBrowser().addEventListener("load", this, true);
|
||||
this._chromeWindow.addEventListener("resize", this, false);
|
||||
|
||||
this._element.hidden = false;
|
||||
this._input.focus();
|
||||
|
||||
this._notify(NOTIFICATIONS.SHOW);
|
||||
if (this._pendingShowCallback) {
|
||||
@ -263,65 +263,10 @@ DeveloperToolbar.prototype.handleEvent = function DT_handleEvent(aEvent)
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Add class="gcli-panel-inner-arrowcontent" to a panel's
|
||||
* |<xul:box class="panel-inner-arrowcontent">| so we can alter the styling
|
||||
* without complex CSS expressions.
|
||||
* @param aPanel The panel to affect
|
||||
*/
|
||||
function getContentBox(aPanel)
|
||||
{
|
||||
let container = aPanel.ownerDocument.getAnonymousElementByAttribute(
|
||||
aPanel, "anonid", "container");
|
||||
return container.querySelector(".panel-inner-arrowcontent");
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to calculate the sum of the vertical padding and margins
|
||||
* between a nested node |aNode| and an ancestor |aRoot|. Iff all of the
|
||||
* children of aRoot are 'only-childs' until you get to aNode then to avoid
|
||||
* scroll-bars, the 'correct' height of aRoot is verticalSpacing + aNode.height.
|
||||
* @param aNode The child node whose height is known.
|
||||
* @param aRoot The parent height whose height we can affect.
|
||||
* @return The sum of the vertical padding/margins in between aNode and aRoot.
|
||||
*/
|
||||
function getVerticalSpacing(aNode, aRoot)
|
||||
{
|
||||
let win = aNode.ownerDocument.defaultView;
|
||||
|
||||
function pxToNum(styles, property) {
|
||||
return parseInt(styles.getPropertyValue(property).replace(/px$/, ''), 10);
|
||||
else if (aEvent.type == "resize") {
|
||||
this.outputPanel._resize();
|
||||
}
|
||||
|
||||
let vertSpacing = 0;
|
||||
do {
|
||||
let styles = win.getComputedStyle(aNode);
|
||||
vertSpacing += pxToNum(styles, "padding-top");
|
||||
vertSpacing += pxToNum(styles, "padding-bottom");
|
||||
vertSpacing += pxToNum(styles, "margin-top");
|
||||
vertSpacing += pxToNum(styles, "margin-bottom");
|
||||
vertSpacing += pxToNum(styles, "border-top-width");
|
||||
vertSpacing += pxToNum(styles, "border-bottom-width");
|
||||
|
||||
let prev = aNode.previousSibling;
|
||||
while (prev != null) {
|
||||
vertSpacing += prev.clientHeight;
|
||||
prev = prev.previousSibling;
|
||||
}
|
||||
|
||||
let next = aNode.nextSibling;
|
||||
while (next != null) {
|
||||
vertSpacing += next.clientHeight;
|
||||
next = next.nextSibling;
|
||||
}
|
||||
|
||||
aNode = aNode.parentNode;
|
||||
} while (aNode !== aRoot);
|
||||
|
||||
return vertSpacing + 9;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Panel to handle command line output.
|
||||
@ -332,32 +277,31 @@ function getVerticalSpacing(aNode, aRoot)
|
||||
function OutputPanel(aChromeDoc, aInput, aLoadCallback)
|
||||
{
|
||||
this._input = aInput;
|
||||
this._anchor = aChromeDoc.getElementById("developer-toolbar");
|
||||
this._toolbar = aChromeDoc.getElementById("developer-toolbar");
|
||||
|
||||
this._loadCallback = aLoadCallback;
|
||||
|
||||
/*
|
||||
<panel id="gcli-output"
|
||||
type="arrow"
|
||||
noautofocus="true"
|
||||
noautohide="true"
|
||||
class="gcli-panel">
|
||||
<iframe id="gcli-output-frame"
|
||||
src=URI_GCLIBLANK
|
||||
flex="1"/>
|
||||
<html:iframe xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
id="gcli-output-frame"
|
||||
src="chrome://browser/content/devtools/gclioutput.xhtml"
|
||||
flex="1"/>
|
||||
</panel>
|
||||
*/
|
||||
this._panel = aChromeDoc.createElement("panel");
|
||||
this._panel.id = "gcli-output";
|
||||
this._panel.classList.add("gcli-panel");
|
||||
this._panel.setAttribute("type", "arrow");
|
||||
this._panel.setAttribute("noautofocus", "true");
|
||||
this._panel.setAttribute("noautohide", "true");
|
||||
this._anchor.parentElement.insertBefore(this._panel, this._anchor);
|
||||
this._toolbar.parentElement.insertBefore(this._panel, this._toolbar);
|
||||
|
||||
this._frame = aChromeDoc.createElement("iframe");
|
||||
this._frame = aChromeDoc.createElementNS(NS_XHTML, "iframe");
|
||||
this._frame.id = "gcli-output-frame";
|
||||
this._frame.setAttribute("src", URI_GCLIBLANK);
|
||||
this._frame.setAttribute("src", "chrome://browser/content/devtools/gclioutput.xhtml");
|
||||
this._frame.setAttribute("flex", "1");
|
||||
this._panel.appendChild(this._frame);
|
||||
|
||||
@ -377,13 +321,9 @@ OutputPanel.prototype._onload = function OP_onload()
|
||||
this._frame.removeEventListener("load", this._onload, true);
|
||||
delete this._onload;
|
||||
|
||||
this._content = getContentBox(this._panel);
|
||||
this._content.classList.add("gcli-panel-inner-arrowcontent");
|
||||
|
||||
this.document = this._frame.contentDocument;
|
||||
this.document.body.classList.add("gclichrome-output");
|
||||
|
||||
this._div = this.document.querySelector("div");
|
||||
this._div = this.document.getElementById("gcli-output-root");
|
||||
this._div.classList.add('gcli-row-out');
|
||||
this._div.setAttribute('aria-live', 'assertive');
|
||||
|
||||
@ -399,12 +339,15 @@ OutputPanel.prototype._onload = function OP_onload()
|
||||
*/
|
||||
OutputPanel.prototype.show = function OP_show()
|
||||
{
|
||||
// This is nasty, but displaying the panel causes it to re-flow, which can
|
||||
// change the size it should be, so we need to resize the iframe after the
|
||||
// panel has displayed
|
||||
this._panel.ownerDocument.defaultView.setTimeout(function() {
|
||||
this._resize();
|
||||
}.bind(this), 0);
|
||||
|
||||
this._panel.openPopup(this._input, "before_start", 0, 0, false, false, null);
|
||||
this._resize();
|
||||
this._panel.openPopup(this._anchor, "before_end", -300, 0, false, false, null);
|
||||
|
||||
this._input.focus();
|
||||
};
|
||||
@ -415,9 +358,12 @@ OutputPanel.prototype.show = function OP_show()
|
||||
*/
|
||||
OutputPanel.prototype._resize = function CLP_resize()
|
||||
{
|
||||
let vertSpacing = getVerticalSpacing(this._content, this._panel);
|
||||
let idealHeight = this.document.body.scrollHeight + vertSpacing;
|
||||
this._panel.sizeTo(400, Math.min(idealHeight, 500));
|
||||
if (this._panel == null || this.document == null || !this._panel.state == "closed") {
|
||||
return
|
||||
}
|
||||
|
||||
this._frame.height = this.document.body.scrollHeight;
|
||||
this._frame.width = this._input.clientWidth + 2;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -476,10 +422,10 @@ OutputPanel.prototype.destroy = function OP_destroy()
|
||||
this.remove();
|
||||
|
||||
this._panel.removeChild(this._frame);
|
||||
this._anchor.parentElement.removeChild(this._panel);
|
||||
this._toolbar.parentElement.removeChild(this._panel);
|
||||
|
||||
delete this._input;
|
||||
delete this._anchor;
|
||||
delete this._toolbar;
|
||||
delete this._panel;
|
||||
delete this._frame;
|
||||
delete this._content;
|
||||
@ -510,7 +456,8 @@ OutputPanel.prototype._visibilityChanged = function OP_visibilityChanged(aEvent)
|
||||
function TooltipPanel(aChromeDoc, aInput, aLoadCallback)
|
||||
{
|
||||
this._input = aInput;
|
||||
this._anchor = aChromeDoc.getElementById("developer-toolbar");
|
||||
this._toolbar = aChromeDoc.getElementById("developer-toolbar");
|
||||
this._dimensions = { start: 0, end: 0 };
|
||||
|
||||
this._onload = this._onload.bind(this);
|
||||
this._loadCallback = aLoadCallback;
|
||||
@ -520,22 +467,22 @@ function TooltipPanel(aChromeDoc, aInput, aLoadCallback)
|
||||
noautofocus="true"
|
||||
noautohide="true"
|
||||
class="gcli-panel">
|
||||
<iframe id="gcli-tooltip-frame"
|
||||
src=URI_GCLIBLANK
|
||||
flex="1"/>
|
||||
<html:iframe xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
id="gcli-tooltip-frame"
|
||||
src="chrome://browser/content/devtools/gclitooltip.xhtml"
|
||||
flex="1"/>
|
||||
</panel>
|
||||
*/
|
||||
this._panel = aChromeDoc.createElement("panel");
|
||||
this._panel.id = "gcli-tooltip";
|
||||
this._panel.classList.add("gcli-panel");
|
||||
this._panel.setAttribute("type", "arrow");
|
||||
this._panel.setAttribute("noautofocus", "true");
|
||||
this._panel.setAttribute("noautohide", "true");
|
||||
this._anchor.parentElement.insertBefore(this._panel, this._anchor);
|
||||
this._toolbar.parentElement.insertBefore(this._panel, this._toolbar);
|
||||
|
||||
this._frame = aChromeDoc.createElement("iframe");
|
||||
this._frame = aChromeDoc.createElementNS(NS_XHTML, "iframe");
|
||||
this._frame.id = "gcli-tooltip-frame";
|
||||
this._frame.setAttribute("src", URI_GCLIBLANK);
|
||||
this._frame.setAttribute("src", "chrome://browser/content/devtools/gclitooltip.xhtml");
|
||||
this._frame.setAttribute("flex", "1");
|
||||
this._panel.appendChild(this._frame);
|
||||
|
||||
@ -550,13 +497,9 @@ TooltipPanel.prototype._onload = function TP_onload()
|
||||
{
|
||||
this._frame.removeEventListener("load", this._onload, true);
|
||||
|
||||
this._content = getContentBox(this._panel);
|
||||
this._content.classList.add("gcli-panel-inner-arrowcontent");
|
||||
|
||||
this.document = this._frame.contentDocument;
|
||||
this.document.body.classList.add("gclichrome-tooltip");
|
||||
|
||||
this.hintElement = this.document.querySelector("div");
|
||||
this.hintElement = this.document.getElementById("gcli-tooltip-root");
|
||||
this._connector = this.document.getElementById("gcli-tooltip-connector");
|
||||
|
||||
this.loaded = true;
|
||||
|
||||
@ -569,16 +512,58 @@ TooltipPanel.prototype._onload = function TP_onload()
|
||||
/**
|
||||
* Display the TooltipPanel.
|
||||
*/
|
||||
TooltipPanel.prototype.show = function TP_show()
|
||||
TooltipPanel.prototype.show = function TP_show(aDimensions)
|
||||
{
|
||||
let vertSpacing = getVerticalSpacing(this._content, this._panel);
|
||||
let idealHeight = this.document.body.scrollHeight + vertSpacing;
|
||||
this._panel.sizeTo(350, Math.min(idealHeight, 500));
|
||||
this._panel.openPopup(this._anchor, "before_start", 0, 0, false, false, null);
|
||||
if (!aDimensions) {
|
||||
aDimensions = { start: 0, end: 0 };
|
||||
}
|
||||
this._dimensions = aDimensions;
|
||||
|
||||
// This is nasty, but displaying the panel causes it to re-flow, which can
|
||||
// change the size it should be, so we need to resize the iframe after the
|
||||
// panel has displayed
|
||||
this._panel.ownerDocument.defaultView.setTimeout(function() {
|
||||
this._resize();
|
||||
}.bind(this), 0);
|
||||
|
||||
this._resize();
|
||||
this._panel.openPopup(this._input, "before_start", aDimensions.start * 10, 0, false, false, null);
|
||||
this._input.focus();
|
||||
};
|
||||
|
||||
/**
|
||||
* One option is to spend lots of time taking an average width of characters
|
||||
* in the current font, dynamically, and weighting for the frequency of use of
|
||||
* various characters, or even to render the given string off screen, and then
|
||||
* measure the width.
|
||||
* Or we could do this...
|
||||
*/
|
||||
const AVE_CHAR_WIDTH = 4.5;
|
||||
|
||||
/**
|
||||
* Display the TooltipPanel.
|
||||
*/
|
||||
TooltipPanel.prototype._resize = function TP_resize()
|
||||
{
|
||||
if (this._panel == null || this.document == null || !this._panel.state == "closed") {
|
||||
return
|
||||
}
|
||||
|
||||
let offset = 10 + Math.floor(this._dimensions.start * AVE_CHAR_WIDTH);
|
||||
this._frame.style.marginLeft = offset + "px";
|
||||
|
||||
/*
|
||||
// Bug 744906: UX review - Not sure if we want this code to fatten connector
|
||||
// with param width
|
||||
let width = Math.floor(this._dimensions.end * AVE_CHAR_WIDTH);
|
||||
width = Math.min(width, 100);
|
||||
width = Math.max(width, 10);
|
||||
this._connector.style.width = width + "px";
|
||||
*/
|
||||
|
||||
this._frame.height = this.document.body.scrollHeight;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the TooltipPanel.
|
||||
*/
|
||||
@ -595,13 +580,15 @@ TooltipPanel.prototype.destroy = function TP_destroy()
|
||||
this.remove();
|
||||
|
||||
this._panel.removeChild(this._frame);
|
||||
this._anchor.parentElement.removeChild(this._panel);
|
||||
this._toolbar.parentElement.removeChild(this._panel);
|
||||
|
||||
delete this._connector;
|
||||
delete this._dimensions;
|
||||
delete this._input;
|
||||
delete this._onload;
|
||||
delete this._panel;
|
||||
delete this._frame;
|
||||
delete this._anchor;
|
||||
delete this._toolbar;
|
||||
delete this._content;
|
||||
delete this.document;
|
||||
delete this.hintElement;
|
||||
@ -614,7 +601,7 @@ TooltipPanel.prototype.destroy = function TP_destroy()
|
||||
TooltipPanel.prototype._visibilityChanged = function TP_visibilityChanged(aEvent)
|
||||
{
|
||||
if (aEvent.tooltipVisible === true) {
|
||||
this.show();
|
||||
this.show(aEvent.dimensions);
|
||||
} else {
|
||||
this._panel.hidePopup();
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ _BROWSER_TEST_FILES = \
|
||||
browser_require_basic.js \
|
||||
browser_templater_basic.js \
|
||||
browser_toolbar_basic.js \
|
||||
browser_toolbar_tooltip.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
|
@ -9,10 +9,10 @@ registerCleanupFunction(function() {
|
||||
imported = {};
|
||||
});
|
||||
|
||||
const URL = "http://example.com/browser/browser/devtools/shared/test/browser_toolbar_basic.html";
|
||||
const TEST_URI = "http://example.com/browser/browser/devtools/shared/test/browser_toolbar_basic.html";
|
||||
|
||||
function test() {
|
||||
addTab(URL, function(browser, tab) {
|
||||
addTab(TEST_URI, function(browser, tab) {
|
||||
info("Starting browser_toolbar_basic.js");
|
||||
runTest();
|
||||
});
|
||||
|
45
browser/devtools/shared/test/browser_toolbar_tooltip.js
Executable file
45
browser/devtools/shared/test/browser_toolbar_tooltip.js
Executable file
@ -0,0 +1,45 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that the developer toolbar works properly
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf-8,<p>Tooltip Tests</p>";
|
||||
|
||||
function test() {
|
||||
DeveloperToolbarTest.test(TEST_URI, function(browser, tab) {
|
||||
runTest();
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
let tooltipPanel = DeveloperToolbar.tooltipPanel;
|
||||
|
||||
DeveloperToolbar.display.focusManager.helpRequest();
|
||||
DeveloperToolbar.display.inputter.setInput('help help');
|
||||
|
||||
DeveloperToolbar.display.inputter.setCursor({ start: 'help help'.length });
|
||||
is(tooltipPanel._dimensions.start, 'help '.length,
|
||||
'search param start, when cursor at end');
|
||||
ok(getLeftMargin() > 30, 'tooltip offset, when cursor at end')
|
||||
|
||||
DeveloperToolbar.display.inputter.setCursor({ start: 'help'.length });
|
||||
is(tooltipPanel._dimensions.start, 0,
|
||||
'search param start, when cursor at end of command');
|
||||
ok(getLeftMargin() > 9, 'tooltip offset, when cursor at end of command')
|
||||
|
||||
DeveloperToolbar.display.inputter.setCursor({ start: 'help help'.length - 1 });
|
||||
is(tooltipPanel._dimensions.start, 'help '.length,
|
||||
'search param start, when cursor at penultimate position');
|
||||
ok(getLeftMargin() > 30, 'tooltip offset, when cursor at penultimate position')
|
||||
|
||||
DeveloperToolbar.display.inputter.setCursor({ start: 0 });
|
||||
is(tooltipPanel._dimensions.start, 0,
|
||||
'search param start, when cursor at start');
|
||||
ok(getLeftMargin() > 9, 'tooltip offset, when cursor at start')
|
||||
}
|
||||
|
||||
function getLeftMargin() {
|
||||
let style = DeveloperToolbar.tooltipPanel._frame.style.marginLeft;
|
||||
return parseInt(style.slice(0, -2), 10);
|
||||
}
|
@ -67,7 +67,55 @@ let DeveloperToolbarTest = {
|
||||
DeveloperToolbar.display.inputter.setInput("");
|
||||
DeveloperToolbar.hide();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Quick wrapper around the things you need to do to run DeveloperToolbar
|
||||
* command tests:
|
||||
* - Set the pref 'devtools.toolbar.enabled' to true
|
||||
* - Add a tab pointing at |uri|
|
||||
* - Open the DeveloperToolbar
|
||||
* - Register a cleanup function to undo the above
|
||||
* - Run the tests
|
||||
*
|
||||
* @param uri The uri of a page to load. Can be 'about:blank' or 'data:...'
|
||||
* @param testFunc A function containing the tests to run. This should
|
||||
* arrange for 'finish()' to be called on completion.
|
||||
*/
|
||||
test: function DTT_test(uri, testFunc) {
|
||||
let menuItem = document.getElementById("menu_devToolbar");
|
||||
let command = document.getElementById("Tools:DevToolbar");
|
||||
let appMenuItem = document.getElementById("appmenu_devToolbar");
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
DeveloperToolbarTest.hide();
|
||||
|
||||
// a.k.a Services.prefs.clearUserPref("devtools.toolbar.enabled");
|
||||
if (menuItem) menuItem.hidden = true;
|
||||
if (command) command.setAttribute("disabled", "true");
|
||||
if (appMenuItem) appMenuItem.hidden = true;
|
||||
});
|
||||
|
||||
// a.k.a: Services.prefs.setBoolPref("devtools.toolbar.enabled", true);
|
||||
if (menuItem) menuItem.hidden = false;
|
||||
if (command) command.removeAttribute("disabled");
|
||||
if (appMenuItem) appMenuItem.hidden = false;
|
||||
|
||||
addTab(uri, function(browser, tab) {
|
||||
DeveloperToolbarTest.show(function() {
|
||||
|
||||
try {
|
||||
testFunc(browser, tab);
|
||||
}
|
||||
catch (ex) {
|
||||
ok(false, "" + ex);
|
||||
console.error(ex);
|
||||
finish();
|
||||
throw ex;
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
function catchFail(func) {
|
||||
|
@ -1758,6 +1758,7 @@ HUD_SERVICE.prototype =
|
||||
// Remove the HUDBox and the consolePanel if the Web Console is inside a
|
||||
// floating panel.
|
||||
if (hud.consolePanel && hud.consolePanel.parentNode) {
|
||||
hud.consolePanel.hidePopup();
|
||||
hud.consolePanel.parentNode.removeChild(hud.consolePanel);
|
||||
hud.consolePanel.removeAttribute("hudId");
|
||||
hud.consolePanel = null;
|
||||
|
@ -1092,14 +1092,14 @@ Function .onInit
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 1" Left "0"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 1" Right "-1"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 1" Top "5"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 1" Bottom "15"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 1" Bottom "25"
|
||||
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" Type "checkbox"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" Text "$(MAINTENANCE_SERVICE_CHECKBOX_DESC)"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" Left "0"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" Right "-1"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" Top "20"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" Bottom "30"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" Top "27"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" Bottom "37"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" State "1"
|
||||
WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" Flags "GROUP"
|
||||
|
||||
|
@ -229,9 +229,9 @@ These should match what Safari and other Apple applications use on OS X Lion. --
|
||||
<!ENTITY inspectCloseButton.tooltiptext "Close Inspector">
|
||||
|
||||
<!ENTITY devToolbarCloseButton.tooltiptext "Close Developer Toolbar">
|
||||
<!ENTITY devToolbarMenu.label "Developer Toolbar">
|
||||
<!ENTITY devToolbarMenu.accesskey "v">
|
||||
<!ENTITY devToolbar.commandkey "v">
|
||||
<!ENTITY devToolbarMenu.label "Developer Toolbar">
|
||||
<!ENTITY devToolbarMenu.accesskey "v">
|
||||
<!ENTITY devToolbar.commandkey "v">
|
||||
|
||||
<!ENTITY webConsoleButton.label "Web Console">
|
||||
<!ENTITY inspectorButton.label "Inspector">
|
||||
|
@ -173,6 +173,7 @@ TelemetryPing.prototype = {
|
||||
_startupHistogramRegex: /SQLITE|HTTP|SPDY|CACHE|DNS/,
|
||||
_slowSQLStartup: {},
|
||||
_prevSession: null,
|
||||
_hasWindowRestoredObserver : false,
|
||||
// Bug 756152
|
||||
_disablePersistentTelemetrySending: true,
|
||||
|
||||
@ -628,6 +629,7 @@ TelemetryPing.prototype = {
|
||||
Services.obs.addObserver(this, "profile-before-change", false);
|
||||
Services.obs.addObserver(this, "sessionstore-windows-restored", false);
|
||||
Services.obs.addObserver(this, "quit-application-granted", false);
|
||||
this._hasWindowRestoredObserver = true;
|
||||
|
||||
// Delay full telemetry initialization to give the browser time to
|
||||
// run various late initializers. Otherwise our gathered memory
|
||||
@ -661,10 +663,9 @@ TelemetryPing.prototype = {
|
||||
*/
|
||||
uninstall: function uninstall() {
|
||||
this.detachObservers()
|
||||
try {
|
||||
if (this._hasWindowRestoredObserver) {
|
||||
Services.obs.removeObserver(this, "sessionstore-windows-restored");
|
||||
} catch (e) {
|
||||
// Already observed this event.
|
||||
this._hasWindowRestoredObserver = false;
|
||||
}
|
||||
Services.obs.removeObserver(this, "profile-before-change");
|
||||
Services.obs.removeObserver(this, "private-browsing");
|
||||
@ -706,6 +707,7 @@ TelemetryPing.prototype = {
|
||||
break;
|
||||
case "sessionstore-windows-restored":
|
||||
Services.obs.removeObserver(this, "sessionstore-windows-restored");
|
||||
this._hasWindowRestoredObserver = false;
|
||||
// fall through
|
||||
case "test-gather-startup":
|
||||
this.gatherStartupInformation();
|
||||
|
Loading…
x
Reference in New Issue
Block a user