зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to inbound.
This commit is contained in:
Коммит
6b6ad4faae
|
@ -18,6 +18,19 @@ input[type=button] {
|
|||
overflow: auto;
|
||||
}
|
||||
|
||||
/* UNDO */
|
||||
#newtab-undo-container {
|
||||
transition: opacity 100ms ease-out;
|
||||
display: -moz-box;
|
||||
-moz-box-align: center;
|
||||
-moz-box-pack: center;
|
||||
}
|
||||
|
||||
#newtab-undo-container[undo-disabled] {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* TOGGLE */
|
||||
#newtab-toggle {
|
||||
position: absolute;
|
||||
|
@ -41,7 +54,10 @@ input[type=button] {
|
|||
#newtab-margin-top {
|
||||
min-height: 50px;
|
||||
max-height: 80px;
|
||||
display: -moz-box;
|
||||
-moz-box-flex: 1;
|
||||
-moz-box-align: center;
|
||||
-moz-box-pack: center;
|
||||
}
|
||||
|
||||
#newtab-margin-bottom {
|
||||
|
|
|
@ -51,6 +51,7 @@ const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
|
|||
#include dropTargetShim.js
|
||||
#include dropPreview.js
|
||||
#include updater.js
|
||||
#include undo.js
|
||||
|
||||
// Everything is loaded. Initialize the New Tab Page.
|
||||
gPage.init();
|
||||
|
|
|
@ -20,7 +20,20 @@
|
|||
<div id="newtab-scrollbox">
|
||||
|
||||
<div id="newtab-vertical-margin">
|
||||
<div id="newtab-margin-top"/>
|
||||
<div id="newtab-margin-top">
|
||||
<div id="newtab-undo-container" undo-disabled="true">
|
||||
<xul:label id="newtab-undo-label"
|
||||
value="&newtab.undo.removedLabel;" />
|
||||
<xul:button id="newtab-undo-button" tabindex="-1"
|
||||
label="&newtab.undo.undoButton;"
|
||||
class="newtab-undo-button" />
|
||||
<xul:button id="newtab-undo-restore-button" tabindex="-1"
|
||||
label="&newtab.undo.restoreButton;"
|
||||
class="newtab-undo-button" />
|
||||
<xul:toolbarbutton id="newtab-undo-close-button" tabindex="-1"
|
||||
title="&newtab.undo.closeTooltip;" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="newtab-horizontal-margin">
|
||||
<div class="newtab-side-margin"/>
|
||||
|
|
|
@ -39,8 +39,11 @@ let gPage = {
|
|||
this._updateAttributes(enabled);
|
||||
|
||||
// Initialize the whole page if we haven't done that, yet.
|
||||
if (enabled)
|
||||
if (enabled) {
|
||||
this._init();
|
||||
} else {
|
||||
gUndoDialog.hide();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -84,6 +84,7 @@ Site.prototype = {
|
|||
*/
|
||||
block: function Site_block() {
|
||||
if (!gBlockedLinks.isBlocked(this._link)) {
|
||||
gUndoDialog.show(this);
|
||||
gBlockedLinks.block(this._link);
|
||||
gUpdater.updateGrid();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
#ifdef 0
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Dialog allowing to undo the removal of single site or to completely restore
|
||||
* the grid's original state.
|
||||
*/
|
||||
let gUndoDialog = {
|
||||
/**
|
||||
* The undo dialog's timeout in miliseconds.
|
||||
*/
|
||||
HIDE_TIMEOUT_MS: 15000,
|
||||
|
||||
/**
|
||||
* Contains undo information.
|
||||
*/
|
||||
_undoData: null,
|
||||
|
||||
/**
|
||||
* Initializes the undo dialog.
|
||||
*/
|
||||
init: function UndoDialog_init() {
|
||||
this._undoContainer = document.getElementById("newtab-undo-container");
|
||||
this._undoContainer.addEventListener("click", this, false);
|
||||
this._undoButton = document.getElementById("newtab-undo-button");
|
||||
this._undoCloseButton = document.getElementById("newtab-undo-close-button");
|
||||
this._undoRestoreButton = document.getElementById("newtab-undo-restore-button");
|
||||
},
|
||||
|
||||
/**
|
||||
* Shows the undo dialog.
|
||||
* @param aSite The site that just got removed.
|
||||
*/
|
||||
show: function UndoDialog_show(aSite) {
|
||||
if (this._undoData)
|
||||
clearTimeout(this._undoData.timeout);
|
||||
|
||||
this._undoData = {
|
||||
index: aSite.cell.index,
|
||||
wasPinned: aSite.isPinned(),
|
||||
blockedLink: aSite.link,
|
||||
timeout: setTimeout(this.hide.bind(this), this.HIDE_TIMEOUT_MS)
|
||||
};
|
||||
|
||||
this._undoContainer.removeAttribute("undo-disabled");
|
||||
this._undoButton.removeAttribute("tabindex");
|
||||
this._undoCloseButton.removeAttribute("tabindex");
|
||||
this._undoRestoreButton.removeAttribute("tabindex");
|
||||
},
|
||||
|
||||
/**
|
||||
* Hides the undo dialog.
|
||||
*/
|
||||
hide: function UndoDialog_hide() {
|
||||
if (!this._undoData)
|
||||
return;
|
||||
|
||||
clearTimeout(this._undoData.timeout);
|
||||
this._undoData = null;
|
||||
this._undoContainer.setAttribute("undo-disabled", "true");
|
||||
this._undoButton.setAttribute("tabindex", "-1");
|
||||
this._undoCloseButton.setAttribute("tabindex", "-1");
|
||||
this._undoRestoreButton.setAttribute("tabindex", "-1");
|
||||
},
|
||||
|
||||
/**
|
||||
* The undo dialog event handler.
|
||||
* @param aEvent The event to handle.
|
||||
*/
|
||||
handleEvent: function UndoDialog_handleEvent(aEvent) {
|
||||
switch (aEvent.target.id) {
|
||||
case "newtab-undo-button":
|
||||
this._undo();
|
||||
break;
|
||||
case "newtab-undo-restore-button":
|
||||
this._undoAll();
|
||||
break;
|
||||
case "newtab-undo-close-button":
|
||||
this.hide();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Undo the last blocked site.
|
||||
*/
|
||||
_undo: function UndoDialog_undo() {
|
||||
if (!this._undoData)
|
||||
return;
|
||||
|
||||
let {index, wasPinned, blockedLink} = this._undoData;
|
||||
gBlockedLinks.unblock(blockedLink);
|
||||
|
||||
if (wasPinned) {
|
||||
gPinnedLinks.pin(blockedLink, index);
|
||||
}
|
||||
|
||||
gUpdater.updateGrid();
|
||||
this.hide();
|
||||
},
|
||||
|
||||
/**
|
||||
* Undo all blocked sites.
|
||||
*/
|
||||
_undoAll: function UndoDialog_undoAll() {
|
||||
NewTabUtils.undoAll(function() {
|
||||
gUpdater.updateGrid();
|
||||
this.hide();
|
||||
}.bind(this));
|
||||
}
|
||||
};
|
||||
|
||||
gUndoDialog.init();
|
|
@ -19,6 +19,7 @@ _BROWSER_FILES = \
|
|||
browser_newtab_focus.js \
|
||||
browser_newtab_reset.js \
|
||||
browser_newtab_tabsync.js \
|
||||
browser_newtab_undo.js \
|
||||
browser_newtab_unpin.js \
|
||||
browser_newtab_bug721442.js \
|
||||
browser_newtab_bug722273.js \
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/*
|
||||
* These tests make sure that the undo dialog works as expected.
|
||||
*/
|
||||
function runTests() {
|
||||
// remove unpinned sites and undo it
|
||||
yield setLinks("0,1,2,3,4,5,6,7,8");
|
||||
setPinnedLinks("5");
|
||||
|
||||
yield addNewTabPageTab();
|
||||
checkGrid("5p,0,1,2,3,4,6,7,8");
|
||||
|
||||
yield blockCell(4);
|
||||
yield blockCell(4);
|
||||
checkGrid("5p,0,1,2,6,7,8");
|
||||
|
||||
yield undo();
|
||||
checkGrid("5p,0,1,2,4,6,7,8");
|
||||
|
||||
// now remove a pinned site and undo it
|
||||
yield blockCell(0);
|
||||
checkGrid("0,1,2,4,6,7,8");
|
||||
|
||||
yield undo();
|
||||
checkGrid("5p,0,1,2,4,6,7,8");
|
||||
|
||||
// remove a site and restore all
|
||||
yield blockCell(1);
|
||||
checkGrid("5p,1,2,4,6,7,8");
|
||||
|
||||
yield undoAll();
|
||||
checkGrid("5p,0,1,2,3,4,6,7,8");
|
||||
}
|
||||
|
||||
function undo() {
|
||||
let cw = getContentWindow();
|
||||
let target = cw.document.getElementById("newtab-undo-button");
|
||||
EventUtils.synthesizeMouseAtCenter(target, {}, cw);
|
||||
whenPagesUpdated();
|
||||
}
|
||||
|
||||
function undoAll() {
|
||||
let cw = getContentWindow();
|
||||
let target = cw.document.getElementById("newtab-undo-restore-button");
|
||||
EventUtils.synthesizeMouseAtCenter(target, {}, cw);
|
||||
whenPagesUpdated();
|
||||
}
|
|
@ -12,9 +12,11 @@ relativesrcdir = @relativesrcdir@
|
|||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MOCHITEST_BROWSER_FILES = \
|
||||
browser_cmd_addon.js \
|
||||
browser_cmd_calllog.js \
|
||||
browser_cmd_calllog_chrome.js \
|
||||
browser_dbg_cmd_break.html \
|
||||
browser_dbg_cmd_break.js \
|
||||
browser_cmd_addon.js \
|
||||
browser_cmd_commands.js \
|
||||
browser_cmd_cookie.js \
|
||||
browser_cmd_integrate.js \
|
||||
|
@ -67,13 +69,9 @@ ifneq ($(OS_ARCH),WINNT)
|
|||
MOCHITEST_BROWSER_FILES += \
|
||||
browser_dbg_cmd.html \
|
||||
browser_dbg_cmd.js \
|
||||
browser_cmd_calllog.js \
|
||||
browser_cmd_calllog_chrome.js \
|
||||
$(NULL)
|
||||
else
|
||||
$(filter disabled-temporarily--bug-820221, browser_dbg_cmd.js)
|
||||
$(filter disabled-temporarily--bug-817304, browser_cmd_calllog.js)
|
||||
$(filter disabled-temporarily--bug-819017, browser_cmd_calllog_chrome.js)
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -70,6 +70,32 @@ function testVariablesView()
|
|||
testThirdLevelContents();
|
||||
testIntegrity(arr, obj);
|
||||
|
||||
let fooScope = gVariablesView.addScope("foo");
|
||||
let anonymousVar = fooScope.addVar();
|
||||
|
||||
let anonymousScope = gVariablesView.addScope();
|
||||
let barVar = anonymousScope.addVar("bar");
|
||||
|
||||
is(fooScope.header, true,
|
||||
"A named scope should have a header visible.");
|
||||
is(fooScope.target.hasAttribute("non-header"), false,
|
||||
"The non-header attribute should not be applied to scopes with headers.");
|
||||
|
||||
is(anonymousScope.header, false,
|
||||
"An anonymous scope should have a header visible.");
|
||||
is(anonymousScope.target.hasAttribute("non-header"), true,
|
||||
"The non-header attribute should not be applied to scopes without headers.");
|
||||
|
||||
is(barVar.header, true,
|
||||
"A named variable should have a header visible.");
|
||||
is(barVar.target.hasAttribute("non-header"), false,
|
||||
"The non-header attribute should not be applied to variables with headers.");
|
||||
|
||||
is(anonymousVar.header, false,
|
||||
"An anonymous variable should have a header visible.");
|
||||
is(anonymousVar.target.hasAttribute("non-header"), true,
|
||||
"The non-header attribute should not be applied to variables without headers.");
|
||||
|
||||
gVariablesView.clearHierarchy();
|
||||
is (gVariablesView._prevHierarchy.size, 0,
|
||||
"The previous hierarchy should have been cleared.");
|
||||
|
@ -103,18 +129,18 @@ function testHeader() {
|
|||
gScope.showHeader();
|
||||
gVariable.showHeader();
|
||||
|
||||
is(gScope.header, true,
|
||||
"The scope title header should now be visible");
|
||||
is(gVariable.header, true,
|
||||
"The variable title header should now be visible");
|
||||
is(gScope.header, false,
|
||||
"The scope title header should still not be visible");
|
||||
is(gVariable.header, false,
|
||||
"The variable title header should still not be visible");
|
||||
|
||||
gScope.hideHeader();
|
||||
gVariable.hideHeader();
|
||||
|
||||
is(gScope.header, false,
|
||||
"The scope title header should now be hidden");
|
||||
"The scope title header should now still be hidden");
|
||||
is(gVariable.header, false,
|
||||
"The variable title header should now be hidden");
|
||||
"The variable title header should now still be hidden");
|
||||
}
|
||||
|
||||
function testFirstLevelContents() {
|
||||
|
|
|
@ -341,6 +341,28 @@ let gDevToolsBrowser = {
|
|||
gDevToolsBrowser._updateMenuCheckbox, false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a <key> to <keyset id="devtoolsKeyset">.
|
||||
* Appending a <key> element is not always enough. The <keyset> needs
|
||||
* to be detached and reattached to make sure the <key> is taken into
|
||||
* account (see bug 832984).
|
||||
*
|
||||
* @param {XULDocument} doc
|
||||
* The document to which keys are to be added
|
||||
* @param {XULElement} or {DocumentFragment} keys
|
||||
* Keys to add
|
||||
*/
|
||||
attachKeybindingsToBrowser: function DT_attachKeybindingsToBrowser(doc, keys) {
|
||||
let devtoolsKeyset = doc.getElementById("devtoolsKeyset");
|
||||
if (!devtoolsKeyset) {
|
||||
devtoolsKeyset = doc.createElement("keyset");
|
||||
devtoolsKeyset.setAttribute("id", "devtoolsKeyset");
|
||||
}
|
||||
devtoolsKeyset.appendChild(keys);
|
||||
let mainKeyset = doc.getElementById("mainKeyset");
|
||||
mainKeyset.parentNode.insertBefore(devtoolsKeyset, mainKeyset);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add the menuitem for a tool to all open browser windows.
|
||||
*
|
||||
|
@ -366,7 +388,7 @@ let gDevToolsBrowser = {
|
|||
doc.getElementById("mainCommandSet").appendChild(elements.cmd);
|
||||
|
||||
if (elements.key) {
|
||||
doc.getElementById("mainKeyset").appendChild(elements.key);
|
||||
this.attachKeybindingsToBrowser(doc, elements.keys);
|
||||
}
|
||||
|
||||
doc.getElementById("mainBroadcasterSet").appendChild(elements.bc);
|
||||
|
@ -420,8 +442,7 @@ let gDevToolsBrowser = {
|
|||
let mcs = doc.getElementById("mainCommandSet");
|
||||
mcs.appendChild(fragCommands);
|
||||
|
||||
let mks = doc.getElementById("mainKeyset");
|
||||
mks.appendChild(fragKeys);
|
||||
this.attachKeybindingsToBrowser(doc, fragKeys);
|
||||
|
||||
let mbs = doc.getElementById("mainBroadcasterSet");
|
||||
mbs.appendChild(fragBroadcasters);
|
||||
|
|
|
@ -122,10 +122,10 @@ LayoutView.prototype = {
|
|||
this.inspector.selection.reason != "highlighter") {
|
||||
this.cssLogic.highlight(this.inspector.selection.node);
|
||||
this.undim();
|
||||
this.update();
|
||||
} else {
|
||||
this.dim();
|
||||
}
|
||||
this.update();
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -784,6 +784,9 @@ function MarkupContainer(aMarkupView, aNode)
|
|||
}.bind(this), false);
|
||||
|
||||
if (this.editor.closeElt) {
|
||||
this.editor.closeElt.addEventListener("mousedown", function(evt) {
|
||||
this.markup.navigate(this);
|
||||
}.bind(this), false);
|
||||
this.codeBox.appendChild(this.editor.closeElt);
|
||||
}
|
||||
|
||||
|
|
|
@ -699,8 +699,9 @@ var Scratchpad = {
|
|||
// Check to see if the first line is a mode-line comment.
|
||||
let line = content.split("\n")[0];
|
||||
let modeline = self._scanModeLine(line);
|
||||
let chrome = Services.prefs.getBoolPref(DEVTOOLS_CHROME_ENABLED);
|
||||
|
||||
if (modeline["-sp-context"] === "browser") {
|
||||
if (chrome && modeline["-sp-context"] === "browser") {
|
||||
self.setBrowserContext();
|
||||
}
|
||||
|
||||
|
|
|
@ -8,18 +8,14 @@ Cu.import("resource://gre/modules/FileUtils.jsm", tempScope);
|
|||
let NetUtil = tempScope.NetUtil;
|
||||
let FileUtils = tempScope.FileUtils;
|
||||
|
||||
// Reference to the Scratchpad object.
|
||||
let gScratchpad;
|
||||
|
||||
// Reference to the temporary nsIFile we will work with.
|
||||
let gFile;
|
||||
let gScratchpad; // Reference to the Scratchpad object.
|
||||
let gFile; // Reference to the temporary nsIFile we will work with.
|
||||
let DEVTOOLS_CHROME_ENABLED = "devtools.chrome.enabled";
|
||||
|
||||
// The temporary file content.
|
||||
let gFileContent = "function main() { return 0; }";
|
||||
|
||||
const SCRATCHPAD_CONTEXT_CONTENT = 1;
|
||||
const SCRATCHPAD_CONTEXT_BROWSER = 2;
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
|
@ -72,11 +68,25 @@ function runTests() {
|
|||
|
||||
function fileImported(status, content) {
|
||||
ok(Components.isSuccessCode(status), "File was imported successfully");
|
||||
is(gScratchpad.executionContext, SCRATCHPAD_CONTEXT_BROWSER);
|
||||
|
||||
gFile.remove(false);
|
||||
gFile = null;
|
||||
gScratchpad = null;
|
||||
finish();
|
||||
// Since devtools.chrome.enabled is off, Scratchpad should still be in
|
||||
// the content context.
|
||||
is(gScratchpad.executionContext, gScratchpadWindow.SCRATCHPAD_CONTEXT_CONTENT);
|
||||
|
||||
// Set the pref and try again.
|
||||
Services.prefs.setBoolPref(DEVTOOLS_CHROME_ENABLED, true);
|
||||
|
||||
gScratchpad.importFromFile(gFile.QueryInterface(Ci.nsILocalFile), true, function(status, content) {
|
||||
ok(Components.isSuccessCode(status), "File was imported successfully");
|
||||
is(gScratchpad.executionContext, gScratchpadWindow.SCRATCHPAD_CONTEXT_BROWSER);
|
||||
|
||||
gFile.remove(false);
|
||||
gFile = null;
|
||||
gScratchpad = null;
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.clearUserPref(DEVTOOLS_CHROME_ENABLED);
|
||||
});
|
|
@ -34,6 +34,10 @@ XPCOMUtils.defineLazyGetter(this, "prefBranch", function() {
|
|||
.QueryInterface(Components.interfaces.nsIPrefBranch2);
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "toolboxStrings", function () {
|
||||
return Services.strings.createBundle("chrome://browser/locale/devtools/toolbox.properties");
|
||||
});
|
||||
|
||||
/**
|
||||
* A collection of utilities to help working with commands
|
||||
*/
|
||||
|
@ -163,9 +167,12 @@ this.DeveloperToolbar = function DeveloperToolbar(aChromeWindow, aToolbarElement
|
|||
this._pendingShowCallback = undefined;
|
||||
this._pendingHide = false;
|
||||
this._errorsCount = {};
|
||||
this._warningsCount = {};
|
||||
this._errorListeners = {};
|
||||
this._errorCounterButton = this._doc
|
||||
.getElementById("developer-toolbar-toolbox-button");
|
||||
this._errorCounterButton._defaultTooltipText =
|
||||
this._errorCounterButton.getAttribute("tooltiptext");
|
||||
|
||||
try {
|
||||
CmdCommands.refreshAutoCommands(aChromeWindow);
|
||||
|
@ -397,6 +404,7 @@ DeveloperToolbar.prototype._initErrorsCount = function DT__initErrorsCount(aTab)
|
|||
|
||||
this._errorListeners[tabId] = listener;
|
||||
this._errorsCount[tabId] = 0;
|
||||
this._warningsCount[tabId] = 0;
|
||||
|
||||
let messages = listener.getCachedMessages();
|
||||
messages.forEach(this._onPageError.bind(this, tabId));
|
||||
|
@ -415,7 +423,7 @@ DeveloperToolbar.prototype._initErrorsCount = function DT__initErrorsCount(aTab)
|
|||
DeveloperToolbar.prototype._stopErrorsCount = function DT__stopErrorsCount(aTab)
|
||||
{
|
||||
let tabId = aTab.linkedPanel;
|
||||
if (!(tabId in this._errorsCount)) {
|
||||
if (!(tabId in this._errorsCount) || !(tabId in this._warningsCount)) {
|
||||
this._updateErrorsCount();
|
||||
return;
|
||||
}
|
||||
|
@ -423,6 +431,7 @@ DeveloperToolbar.prototype._stopErrorsCount = function DT__stopErrorsCount(aTab)
|
|||
this._errorListeners[tabId].destroy();
|
||||
delete this._errorListeners[tabId];
|
||||
delete this._errorsCount[tabId];
|
||||
delete this._warningsCount[tabId];
|
||||
|
||||
this._updateErrorsCount();
|
||||
};
|
||||
|
@ -550,13 +559,15 @@ DeveloperToolbar.prototype._onPageError =
|
|||
function DT__onPageError(aTabId, aPageError)
|
||||
{
|
||||
if (aPageError.category == "CSS Parser" ||
|
||||
aPageError.category == "CSS Loader" ||
|
||||
(aPageError.flags & aPageError.warningFlag) ||
|
||||
(aPageError.flags & aPageError.strictFlag)) {
|
||||
return; // just a CSS or JS warning
|
||||
aPageError.category == "CSS Loader") {
|
||||
return;
|
||||
}
|
||||
if ((aPageError.flags & aPageError.warningFlag) ||
|
||||
(aPageError.flags & aPageError.strictFlag)) {
|
||||
this._warningsCount[aTabId]++;
|
||||
} else {
|
||||
this._errorsCount[aTabId]++;
|
||||
}
|
||||
|
||||
this._errorsCount[aTabId]++;
|
||||
this._updateErrorsCount(aTabId);
|
||||
};
|
||||
|
||||
|
@ -579,8 +590,9 @@ function DT__onPageBeforeUnload(aEvent)
|
|||
Array.prototype.some.call(tabs, function(aTab) {
|
||||
if (aTab.linkedBrowser.contentWindow === window) {
|
||||
let tabId = aTab.linkedPanel;
|
||||
if (tabId in this._errorsCount) {
|
||||
if (tabId in this._errorsCount || tabId in this._warningsCount) {
|
||||
this._errorsCount[tabId] = 0;
|
||||
this._warningsCount[tabId] = 0;
|
||||
this._updateErrorsCount(tabId);
|
||||
}
|
||||
return true;
|
||||
|
@ -607,11 +619,15 @@ function DT__updateErrorsCount(aChangedTabId)
|
|||
}
|
||||
|
||||
let errors = this._errorsCount[tabId];
|
||||
|
||||
let warnings = this._warningsCount[tabId];
|
||||
let btn = this._errorCounterButton;
|
||||
if (errors) {
|
||||
this._errorCounterButton.setAttribute("error-count", errors);
|
||||
let tooltiptext = toolboxStrings.formatStringFromName("toolboxDockButtons.errorsCount.tooltip", [errors, warnings], 2);
|
||||
btn.setAttribute("error-count", errors);
|
||||
btn.setAttribute("tooltiptext", tooltiptext);
|
||||
} else {
|
||||
this._errorCounterButton.removeAttribute("error-count");
|
||||
btn.removeAttribute("error-count");
|
||||
btn.setAttribute("tooltiptext", btn._defaultTooltipText);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -625,8 +641,9 @@ DeveloperToolbar.prototype.resetErrorsCount =
|
|||
function DT_resetErrorsCount(aTab)
|
||||
{
|
||||
let tabId = aTab.linkedPanel;
|
||||
if (tabId in this._errorsCount) {
|
||||
if (tabId in this._errorsCount || tabId in this._warningsCount) {
|
||||
this._errorsCount[tabId] = 0;
|
||||
this._warningsCount[tabId] = 0;
|
||||
this._updateErrorsCount(tabId);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -698,7 +698,7 @@ Scope.prototype = {
|
|||
* Shows the scope's title header.
|
||||
*/
|
||||
showHeader: function S_showHeader() {
|
||||
if (this._isHeaderVisible) {
|
||||
if (this._isHeaderVisible || !this._nameString) {
|
||||
return;
|
||||
}
|
||||
this._target.removeAttribute("non-header");
|
||||
|
@ -788,6 +788,18 @@ Scope.prototype = {
|
|||
*/
|
||||
set twisty(aFlag) aFlag ? this.showArrow() : this.hideArrow(),
|
||||
|
||||
/**
|
||||
* Gets the expand lock state.
|
||||
* @return boolean
|
||||
*/
|
||||
get locked() this._locked,
|
||||
|
||||
/**
|
||||
* Sets the expand lock state.
|
||||
* @param boolean aFlag
|
||||
*/
|
||||
set locked(aFlag) this._locked = aFlag,
|
||||
|
||||
/**
|
||||
* Adds an event listener for a certain event on this scope's title.
|
||||
* @param string aName
|
||||
|
@ -1386,7 +1398,9 @@ create({ constructor: Variable, proto: Scope.prototype }, {
|
|||
get setter() this._initialDescriptor.set,
|
||||
|
||||
/**
|
||||
* Sets the specific grip for this variable.
|
||||
* Sets the specific grip for this variable (applies the text content and
|
||||
* class name to the value label).
|
||||
*
|
||||
* The grip should contain the value or the type & class, as defined in the
|
||||
* remote debugger protocol. For convenience, undefined and null are
|
||||
* both considered types.
|
||||
|
@ -1401,23 +1415,18 @@ create({ constructor: Variable, proto: Scope.prototype }, {
|
|||
* - { type: "object", class: "Object" }
|
||||
*/
|
||||
_setGrip: function V__setGrip(aGrip) {
|
||||
// Don't allow displaying grip information if there's no name available.
|
||||
if (!this._nameString) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aGrip === undefined) {
|
||||
aGrip = { type: "undefined" };
|
||||
}
|
||||
if (aGrip === null) {
|
||||
aGrip = { type: "null" };
|
||||
}
|
||||
this._applyGrip(aGrip);
|
||||
},
|
||||
|
||||
/**
|
||||
* Applies the necessary text content and class name to a value node based
|
||||
* on a grip.
|
||||
*
|
||||
* @param any aGrip
|
||||
* @see Variable._setGrip
|
||||
*/
|
||||
_applyGrip: function V__applyGrip(aGrip) {
|
||||
let prevGrip = this._valueGrip;
|
||||
if (prevGrip) {
|
||||
this._valueLabel.classList.remove(VariablesView.getClass(prevGrip));
|
||||
|
@ -1441,11 +1450,16 @@ create({ constructor: Variable, proto: Scope.prototype }, {
|
|||
_init: function V__init(aName, aDescriptor) {
|
||||
this._idString = generateId(this._nameString = aName);
|
||||
this._displayScope(aName, "variable");
|
||||
this._displayVariable();
|
||||
this._customizeVariable();
|
||||
this._prepareTooltip();
|
||||
this._setAttributes();
|
||||
this._addEventListeners();
|
||||
|
||||
// Don't allow displaying variable information there's no name available.
|
||||
if (this._nameString) {
|
||||
this._displayVariable();
|
||||
this._customizeVariable();
|
||||
this._prepareTooltip();
|
||||
this._setAttributes();
|
||||
this._addEventListeners();
|
||||
}
|
||||
|
||||
this._onInit(this.ownerView._store.size < LAZY_APPEND_BATCH);
|
||||
},
|
||||
|
||||
|
@ -1530,18 +1544,16 @@ create({ constructor: Variable, proto: Scope.prototype }, {
|
|||
let document = this.document;
|
||||
|
||||
let tooltip = document.createElement("tooltip");
|
||||
tooltip.id = "tooltip-" + this.id;
|
||||
tooltip.id = "tooltip-" + this._idString;
|
||||
|
||||
let configurableLabel = document.createElement("label");
|
||||
configurableLabel.setAttribute("value", "configurable");
|
||||
|
||||
let enumerableLabel = document.createElement("label");
|
||||
enumerableLabel.setAttribute("value", "enumerable");
|
||||
|
||||
let writableLabel = document.createElement("label");
|
||||
configurableLabel.setAttribute("value", "configurable");
|
||||
enumerableLabel.setAttribute("value", "enumerable");
|
||||
writableLabel.setAttribute("value", "writable");
|
||||
|
||||
tooltip.setAttribute("orient", "horizontal")
|
||||
tooltip.setAttribute("orient", "horizontal");
|
||||
tooltip.appendChild(configurableLabel);
|
||||
tooltip.appendChild(enumerableLabel);
|
||||
tooltip.appendChild(writableLabel);
|
||||
|
@ -1847,11 +1859,16 @@ create({ constructor: Property, proto: Variable.prototype }, {
|
|||
_init: function P__init(aName, aDescriptor) {
|
||||
this._idString = generateId(this._nameString = aName);
|
||||
this._displayScope(aName, "property");
|
||||
this._displayVariable();
|
||||
this._customizeVariable();
|
||||
this._prepareTooltip();
|
||||
this._setAttributes();
|
||||
this._addEventListeners();
|
||||
|
||||
// Don't allow displaying property information there's no name available.
|
||||
if (this._nameString) {
|
||||
this._displayVariable();
|
||||
this._customizeVariable();
|
||||
this._prepareTooltip();
|
||||
this._setAttributes();
|
||||
this._addEventListeners();
|
||||
}
|
||||
|
||||
this._onInit(this.ownerView._store.size < LAZY_APPEND_BATCH);
|
||||
},
|
||||
|
||||
|
@ -1990,9 +2007,9 @@ VariablesView.isPrimitive = function VV_isPrimitive(aDescriptor) {
|
|||
return true;
|
||||
}
|
||||
|
||||
// For convenience, undefined and null are both considered types.
|
||||
// For convenience, undefined, null and long strings are considered primitives.
|
||||
let type = grip.type;
|
||||
if (type == "undefined" || type == "null") {
|
||||
if (type == "undefined" || type == "null" || type == "longString") {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2087,6 +2104,8 @@ VariablesView.getString = function VV_getString(aGrip, aConciseFlag) {
|
|||
return "undefined";
|
||||
case "null":
|
||||
return "null";
|
||||
case "longString":
|
||||
return "\"" + aGrip.initial + "\"";
|
||||
default:
|
||||
if (!aConciseFlag) {
|
||||
return "[" + aGrip.type + " " + aGrip.class + "]";
|
||||
|
|
|
@ -20,8 +20,11 @@
|
|||
<p>Hello world! Test for errors count in the Web Console button (developer
|
||||
toolbar).</p>
|
||||
<p style="color: foobarBug762996css"><button>click me</button></p>
|
||||
<script type="text/javascript">
|
||||
<script type="text/javascript;version=1.8">
|
||||
"use strict";
|
||||
let testObj = {};
|
||||
document.querySelector("button").onclick = function() {
|
||||
let test = testObj.fooBug788445 + "warning";
|
||||
window.foobarBug762996click();
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -21,6 +21,8 @@ function test() {
|
|||
let toolbar = document.getElementById("Tools:DevToolbar");
|
||||
let tab1, tab2;
|
||||
|
||||
Services.prefs.setBoolPref("javascript.options.strict", true);
|
||||
|
||||
function openToolbar(browser, tab) {
|
||||
tab1 = tab;
|
||||
ignoreAllUncaughtExceptions(false);
|
||||
|
@ -40,13 +42,46 @@ function test() {
|
|||
return count ? count : "0";
|
||||
}
|
||||
|
||||
function getTooltipValues() {
|
||||
let matches = webconsole.getAttribute("tooltiptext")
|
||||
.match(/(\d+) errors, (\d+) warnings/);
|
||||
return matches ? [matches[1], matches[2]] : [0, 0];
|
||||
}
|
||||
|
||||
function waitForButtonUpdate(aOptions)
|
||||
{
|
||||
aOptions.validator = function() {
|
||||
let errors = getErrorsCount();
|
||||
let tooltip = getTooltipValues();
|
||||
let result = errors == aOptions.errors &&
|
||||
tooltip[1] == aOptions.warnings;
|
||||
if (result) {
|
||||
is(errors, tooltip[0], "button error-count is the same as in the tooltip");
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
let originalFailure = aOptions.failure;
|
||||
aOptions.failure = function() {
|
||||
let tooltip = getTooltipValues();
|
||||
|
||||
info("expected " + aOptions.errors + " errors, " +
|
||||
aOptions.warnings + " warnings");
|
||||
info("got " + tooltip[0] + " errors, " + tooltip[1] + " warnings");
|
||||
|
||||
originalFailure();
|
||||
};
|
||||
|
||||
waitForValue(aOptions);
|
||||
}
|
||||
|
||||
function onOpenToolbar() {
|
||||
ok(DeveloperToolbar.visible, "DeveloperToolbar is visible");
|
||||
|
||||
waitForValue({
|
||||
waitForButtonUpdate({
|
||||
name: "web console button shows page errors",
|
||||
validator: getErrorsCount,
|
||||
value: 3,
|
||||
errors: 3,
|
||||
warnings: 0,
|
||||
success: addErrors,
|
||||
failure: finish,
|
||||
});
|
||||
|
@ -57,13 +92,15 @@ function test() {
|
|||
|
||||
waitForFocus(function() {
|
||||
let button = content.document.querySelector("button");
|
||||
EventUtils.synthesizeMouse(button, 2, 2, {}, content);
|
||||
executeSoon(function() {
|
||||
EventUtils.synthesizeMouse(button, 3, 2, {}, content);
|
||||
});
|
||||
}, content);
|
||||
|
||||
waitForValue({
|
||||
waitForButtonUpdate({
|
||||
name: "button shows one more error after click in page",
|
||||
validator: getErrorsCount,
|
||||
value: 4,
|
||||
errors: 4,
|
||||
warnings: 1,
|
||||
success: function() {
|
||||
ignoreAllUncaughtExceptions();
|
||||
addTab(TEST_URI, onOpenSecondTab);
|
||||
|
@ -78,10 +115,10 @@ function test() {
|
|||
ignoreAllUncaughtExceptions(false);
|
||||
expectUncaughtException();
|
||||
|
||||
waitForValue({
|
||||
waitForButtonUpdate({
|
||||
name: "button shows correct number of errors after new tab is open",
|
||||
validator: getErrorsCount,
|
||||
value: 3,
|
||||
errors: 3,
|
||||
warnings: 0,
|
||||
success: switchToTab1,
|
||||
failure: finish,
|
||||
});
|
||||
|
@ -89,10 +126,10 @@ function test() {
|
|||
|
||||
function switchToTab1() {
|
||||
gBrowser.selectedTab = tab1;
|
||||
waitForValue({
|
||||
waitForButtonUpdate({
|
||||
name: "button shows the page errors from tab 1",
|
||||
validator: getErrorsCount,
|
||||
value: 4,
|
||||
errors: 4,
|
||||
warnings: 1,
|
||||
success: function() {
|
||||
openWebConsole(tab1, onWebConsoleOpen);
|
||||
},
|
||||
|
@ -128,12 +165,12 @@ function test() {
|
|||
}
|
||||
|
||||
function checkConsoleOutput(hud) {
|
||||
let errors = ["foobarBug762996a", "foobarBug762996b", "foobarBug762996load",
|
||||
"foobarBug762996click", "foobarBug762996consoleLog",
|
||||
"foobarBug762996css"];
|
||||
errors.forEach(function(error) {
|
||||
isnot(hud.outputNode.textContent.indexOf(error), -1,
|
||||
error + " found in the Web Console output");
|
||||
let msgs = ["foobarBug762996a", "foobarBug762996b", "foobarBug762996load",
|
||||
"foobarBug762996click", "foobarBug762996consoleLog",
|
||||
"foobarBug762996css", "fooBug788445"];
|
||||
msgs.forEach(function(msg) {
|
||||
isnot(hud.outputNode.textContent.indexOf(msg), -1,
|
||||
msg + " found in the Web Console output");
|
||||
});
|
||||
|
||||
hud.jsterm.clearOutput();
|
||||
|
@ -145,10 +182,10 @@ function test() {
|
|||
let button = content.document.querySelector("button");
|
||||
EventUtils.synthesizeMouse(button, 2, 2, {}, content);
|
||||
|
||||
waitForValue({
|
||||
waitForButtonUpdate({
|
||||
name: "button shows one more error after another click in page",
|
||||
validator: getErrorsCount,
|
||||
value: 5,
|
||||
errors: 5,
|
||||
warnings: 1, // warnings are not repeated by the js engine
|
||||
success: function() {
|
||||
waitForValue(waitForNewError);
|
||||
},
|
||||
|
@ -173,6 +210,8 @@ function test() {
|
|||
is(hud.outputNode.textContent.indexOf("foobarBug762996click"), -1,
|
||||
"clear console button worked");
|
||||
is(getErrorsCount(), 0, "page errors counter has been reset");
|
||||
let tooltip = getTooltipValues();
|
||||
is(tooltip[1], 0, "page warnings counter has been reset");
|
||||
|
||||
doPageReload(hud);
|
||||
}
|
||||
|
@ -187,10 +226,10 @@ function test() {
|
|||
ignoreAllUncaughtExceptions();
|
||||
content.location.reload();
|
||||
|
||||
waitForValue({
|
||||
waitForButtonUpdate({
|
||||
name: "the Web Console button count has been reset after page reload",
|
||||
validator: getErrorsCount,
|
||||
value: 3,
|
||||
errors: 3,
|
||||
warnings: 0,
|
||||
success: function() {
|
||||
waitForValue(waitForConsoleOutputAfterReload);
|
||||
},
|
||||
|
@ -218,6 +257,7 @@ function test() {
|
|||
gDevTools.closeToolbox(target1);
|
||||
gBrowser.removeTab(tab1);
|
||||
gBrowser.removeTab(tab2);
|
||||
Services.prefs.clearUserPref("javascript.options.strict");
|
||||
finish();
|
||||
}
|
||||
|
||||
|
|
|
@ -194,7 +194,9 @@ TiltVisualizer.prototype = {
|
|||
this._browserTab = null;
|
||||
|
||||
if (this.inspector) {
|
||||
this.inspector.selection.off("new-node", this.onNewNodeFromInspector);
|
||||
if (this.inspector.selection) {
|
||||
this.inspector.selection.off("new-node", this.onNewNodeFromInspector);
|
||||
}
|
||||
this.inspector = null;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
toolboxDockButtons.bottom.tooltip=Dock to bottom of browser window
|
||||
toolboxDockButtons.side.tooltip=Dock to side of browser window
|
||||
toolboxDockButtons.window.tooltip=Show in separate window
|
||||
toolboxDockButtons.bottom.tooltip=Dock to bottom of browser window
|
||||
toolboxDockButtons.side.tooltip=Dock to side of browser window
|
||||
toolboxDockButtons.window.tooltip=Show in separate window
|
||||
toolboxDockButtons.errorsCount.tooltip=%S errors, %S warnings.\nClick to toggle developer tools.
|
|
@ -4,3 +4,7 @@
|
|||
|
||||
<!-- These strings are used in the about:newtab page -->
|
||||
<!ENTITY newtab.pageTitle "New Tab">
|
||||
<!ENTITY newtab.undo.removedLabel "Thumbnail removed.">
|
||||
<!ENTITY newtab.undo.undoButton "Undo.">
|
||||
<!ENTITY newtab.undo.restoreButton "Restore All.">
|
||||
<!ENTITY newtab.undo.closeTooltip "Hide">
|
||||
|
|
|
@ -196,12 +196,20 @@ LinksStorage.prototype = {
|
|||
string);
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes the storage value for a given key.
|
||||
* @param aKey The storage key (a string).
|
||||
*/
|
||||
remove: function Storage_remove(aKey) {
|
||||
Services.prefs.clearUserPref(this._prefs[aKey]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Clears the storage and removes all values.
|
||||
*/
|
||||
clear: function Storage_clear() {
|
||||
for each (let pref in this._prefs) {
|
||||
Services.prefs.clearUserPref(pref);
|
||||
for (let key in this._prefs) {
|
||||
this.remove(key);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -813,6 +821,18 @@ this.NewTabUtils = {
|
|||
}, true);
|
||||
},
|
||||
|
||||
/**
|
||||
* Undoes all sites that have been removed from the grid and keep the pinned
|
||||
* tabs.
|
||||
* @param aCallback the callback method.
|
||||
*/
|
||||
undoAll: function NewTabUtils_undoAll(aCallback) {
|
||||
Storage.remove("blockedLinks");
|
||||
Links.resetCache();
|
||||
BlockedLinks.resetCache();
|
||||
Links.populateCache(aCallback, true);
|
||||
},
|
||||
|
||||
links: Links,
|
||||
allPages: AllPages,
|
||||
linkChecker: LinkChecker,
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
:root {
|
||||
-moz-appearance: none;
|
||||
font-size: 75%;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
|
@ -15,6 +16,59 @@
|
|||
background-attachment: fixed;
|
||||
}
|
||||
|
||||
/* UNDO */
|
||||
#newtab-undo-container {
|
||||
padding: 4px 3px;
|
||||
border: 1px solid;
|
||||
border-color: rgba(8,22,37,.12) rgba(8,22,37,.14) rgba(8,22,37,.16);
|
||||
background-color: rgba(255,255,255,.4);
|
||||
color: #525e69;
|
||||
}
|
||||
|
||||
#newtab-undo-label {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.newtab-undo-button {
|
||||
-moz-appearance: none;
|
||||
color: rgb(221,72,20);
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
margin: 0 4px;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
text-decoration: none;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.newtab-undo-button:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.newtab-undo-button:-moz-focusring {
|
||||
outline: 1px dotted;
|
||||
}
|
||||
|
||||
#newtab-undo-close-button {
|
||||
padding: 0;
|
||||
border: none;
|
||||
list-style-image: url("moz-icon://stock/gtk-close?size=menu");
|
||||
-moz-user-focus: normal;
|
||||
}
|
||||
|
||||
#newtab-undo-close-button > .toolbarbutton-icon {
|
||||
margin: -4px;
|
||||
}
|
||||
|
||||
#newtab-undo-close-button > .toolbarbutton-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#newtab-undo-close-button:-moz-focusring {
|
||||
outline: 1px dotted;
|
||||
}
|
||||
|
||||
/* TOGGLE */
|
||||
#newtab-toggle {
|
||||
width: 16px;
|
||||
|
@ -89,7 +143,6 @@
|
|||
padding: 0 8px;
|
||||
background-color: rgba(248,249,251,.95);
|
||||
color: #1f364c;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
:root {
|
||||
-moz-appearance: none;
|
||||
font-size: 75%;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
|
@ -15,6 +16,64 @@
|
|||
background-attachment: fixed;
|
||||
}
|
||||
|
||||
/* UNDO */
|
||||
#newtab-undo-container {
|
||||
padding: 4px 3px;
|
||||
border: 1px solid;
|
||||
border-color: rgba(8,22,37,.12) rgba(8,22,37,.14) rgba(8,22,37,.16);
|
||||
background-color: rgba(255,255,255,.4);
|
||||
color: #525e69;
|
||||
}
|
||||
|
||||
#newtab-undo-label {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.newtab-undo-button {
|
||||
-moz-appearance: none;
|
||||
color: rgb(20,79,174);
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
margin: 0 4px;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
text-decoration: none;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.newtab-undo-button:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.newtab-undo-button:-moz-focusring {
|
||||
outline: 1px dotted;
|
||||
}
|
||||
|
||||
#newtab-undo-close-button {
|
||||
padding: 0;
|
||||
border: none;
|
||||
list-style-image: url("chrome://global/skin/icons/close.png");
|
||||
-moz-image-region: rect(0, 16px, 16px, 0);
|
||||
-moz-user-focus: normal;
|
||||
}
|
||||
|
||||
#newtab-undo-close-button:hover {
|
||||
-moz-image-region: rect(0, 32px, 16px, 16px);
|
||||
}
|
||||
|
||||
#newtab-undo-close-button:hover:active {
|
||||
-moz-image-region: rect(0, 48px, 16px, 32px);
|
||||
}
|
||||
|
||||
#newtab-undo-close-button > .toolbarbutton-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#newtab-undo-close-button:-moz-focusring {
|
||||
outline: 1px dotted;
|
||||
}
|
||||
|
||||
/* TOGGLE */
|
||||
#newtab-toggle {
|
||||
width: 16px;
|
||||
|
@ -96,7 +155,6 @@
|
|||
padding: 0 8px;
|
||||
background-color: rgba(248,249,251,.95);
|
||||
color: #1f364c;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
:root {
|
||||
-moz-appearance: none;
|
||||
font-size: 75%;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
|
@ -15,6 +16,70 @@
|
|||
background-attachment: fixed;
|
||||
}
|
||||
|
||||
/* UNDO */
|
||||
#newtab-undo-container {
|
||||
padding: 4px 3px;
|
||||
border: 1px solid;
|
||||
border-color: rgba(8,22,37,.12) rgba(8,22,37,.14) rgba(8,22,37,.16);
|
||||
background-color: rgba(255,255,255,.4);
|
||||
color: #525e69;
|
||||
}
|
||||
|
||||
#newtab-undo-label {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.newtab-undo-button {
|
||||
-moz-appearance: none;
|
||||
color: -moz-nativehyperlinktext;
|
||||
color: rgb(0,102,204);
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
margin: 0 4px;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
text-decoration: none;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.newtab-undo-button:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.newtab-undo-button:-moz-focusring {
|
||||
outline: 1px dotted;
|
||||
}
|
||||
|
||||
.newtab-undo-button > .button-box {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#newtab-undo-close-button {
|
||||
-moz-appearance: none;
|
||||
padding: 0;
|
||||
border: none;
|
||||
list-style-image: url("chrome://global/skin/icons/close.png");
|
||||
-moz-image-region: rect(0, 16px, 16px, 0);
|
||||
-moz-user-focus: normal;
|
||||
}
|
||||
|
||||
#newtab-undo-close-button:hover {
|
||||
-moz-image-region: rect(0, 32px, 16px, 16px);
|
||||
}
|
||||
|
||||
#newtab-undo-close-button:hover:active {
|
||||
-moz-image-region: rect(0, 48px, 16px, 32px);
|
||||
}
|
||||
|
||||
#newtab-undo-close-button > .toolbarbutton-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#newtab-undo-close-button:-moz-focusring {
|
||||
outline: 1px dotted;
|
||||
}
|
||||
|
||||
/* TOGGLE */
|
||||
#newtab-toggle {
|
||||
width: 16px;
|
||||
|
@ -89,7 +154,6 @@
|
|||
padding: 0 8px;
|
||||
background-color: rgba(248,249,251,.95);
|
||||
color: #1f364c;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
|
|
|
@ -1512,8 +1512,27 @@ NS_INTERFACE_MAP_END
|
|||
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDocument)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_DESTROY(nsDocument,
|
||||
nsNodeUtils::LastRelease(this))
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
nsDocument::Release()
|
||||
{
|
||||
NS_PRECONDITION(0 != mRefCnt, "dup release");
|
||||
NS_ASSERT_OWNINGTHREAD_AND_NOT_CCTHREAD(nsDocument);
|
||||
nsISupports* base = NS_CYCLE_COLLECTION_CLASSNAME(nsDocument)::Upcast(this);
|
||||
nsrefcnt count = mRefCnt.decr(base);
|
||||
NS_LOG_RELEASE(this, count, "nsDocument");
|
||||
if (count == 0) {
|
||||
if (mStackRefCnt && !mNeedsReleaseAfterStackRefCntRelease) {
|
||||
mNeedsReleaseAfterStackRefCntRelease = true;
|
||||
NS_ADDREF_THIS();
|
||||
return mRefCnt.get();
|
||||
}
|
||||
NS_ASSERT_OWNINGTHREAD(nsDocument);
|
||||
mRefCnt.stabilizeForDeletion();
|
||||
nsNodeUtils::LastRelease(this);
|
||||
return 0;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsDocument)
|
||||
if (Element::CanSkip(tmp, aRemovingAllowed)) {
|
||||
|
@ -6707,6 +6726,8 @@ nsIDocument::CreateEvent(const nsAString& aEventType, ErrorResult& rv) const
|
|||
void
|
||||
nsDocument::FlushPendingNotifications(mozFlushType aType)
|
||||
{
|
||||
nsDocumentOnStack dos(this);
|
||||
|
||||
// We need to flush the sink for non-HTML documents (because the XML
|
||||
// parser still does insertion with deferred notifications). We
|
||||
// also need to flush the sink if this is a layout-related flush, to
|
||||
|
|
|
@ -93,6 +93,7 @@ class nsHTMLCSSStyleSheet;
|
|||
class nsDOMNavigationTiming;
|
||||
class nsWindowSizes;
|
||||
class nsHtml5TreeOpExecutor;
|
||||
class nsDocumentOnStack;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -1020,6 +1021,20 @@ public:
|
|||
|
||||
protected:
|
||||
friend class nsNodeUtils;
|
||||
friend class nsDocumentOnStack;
|
||||
|
||||
void IncreaseStackRefCnt()
|
||||
{
|
||||
++mStackRefCnt;
|
||||
}
|
||||
|
||||
void DecreaseStackRefCnt()
|
||||
{
|
||||
if (--mStackRefCnt == 0 && mNeedsReleaseAfterStackRefCntRelease) {
|
||||
mNeedsReleaseAfterStackRefCntRelease = false;
|
||||
NS_RELEASE_THIS();
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if a request for DOM full-screen is currently enabled in
|
||||
// this document. This returns true if there are no windowed plugins in this
|
||||
|
@ -1379,12 +1394,30 @@ private:
|
|||
bool mAutoSize, mAllowZoom, mValidScaleFloat, mValidMaxScale, mScaleStrEmpty, mWidthStrEmpty;
|
||||
uint32_t mViewportWidth, mViewportHeight;
|
||||
|
||||
nsrefcnt mStackRefCnt;
|
||||
bool mNeedsReleaseAfterStackRefCntRelease;
|
||||
|
||||
#ifdef DEBUG
|
||||
protected:
|
||||
bool mWillReparent;
|
||||
#endif
|
||||
};
|
||||
|
||||
class nsDocumentOnStack
|
||||
{
|
||||
public:
|
||||
nsDocumentOnStack(nsDocument* aDoc) : mDoc(aDoc)
|
||||
{
|
||||
mDoc->IncreaseStackRefCnt();
|
||||
}
|
||||
~nsDocumentOnStack()
|
||||
{
|
||||
mDoc->DecreaseStackRefCnt();
|
||||
}
|
||||
private:
|
||||
nsDocument* mDoc;
|
||||
};
|
||||
|
||||
#define NS_DOCUMENT_INTERFACE_TABLE_BEGIN(_class) \
|
||||
NS_NODE_OFFSET_AND_INTERFACE_TABLE_BEGIN(_class) \
|
||||
NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsIDOMDocument, nsDocument) \
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
var EXPORTED_SYMBOLS = [ "SourceMapConsumer", "SourceMapGenerator", "SourceNode" ];
|
||||
this.EXPORTED_SYMBOLS = [ "SourceMapConsumer", "SourceMapGenerator", "SourceNode" ];
|
||||
|
||||
Components.utils.import('resource://gre/modules/devtools/Require.jsm');
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
|
|
Загрузка…
Ссылка в новой задаче