merge
1
.hgtags
|
@ -69,3 +69,4 @@ a95d426422816513477e5863add1b00ac7041dcb AURORA_BASE_20110412
|
|||
5eb553dd2ceae5f88d80f27afc5ef3935c5d43b0 AURORA_BASE_20110705
|
||||
41b84b87c816403e1b74963d8094cff0406c989e AURORA_BASE_20110816
|
||||
c0983049bcaa9551e5f276d5a77ce154c151e0b0 AURORA_BASE_20110927
|
||||
462c726144bc1fb45b61e774f64ac5d61b4e047c UPDATE_PACKAGING_R15
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "nsAccUtils.h"
|
||||
#include "nsRootAccessible.h"
|
||||
|
||||
#include "nsEventStateManager.h"
|
||||
#include "nsFocusManager.h"
|
||||
|
||||
namespace dom = mozilla::dom;
|
||||
|
@ -352,18 +353,22 @@ FocusManager::ProcessFocusEvent(AccEvent* aEvent)
|
|||
}
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
FocusManager::FocusedDOMElm() const
|
||||
nsINode*
|
||||
FocusManager::FocusedDOMNode() const
|
||||
{
|
||||
nsFocusManager* DOMFocusManager = nsFocusManager::GetFocusManager();
|
||||
return DOMFocusManager->GetFocusedContent();
|
||||
}
|
||||
nsIContent* focusedElm = DOMFocusManager->GetFocusedContent();
|
||||
|
||||
nsIDocument*
|
||||
FocusManager::FocusedDOMDocument() const
|
||||
{
|
||||
nsFocusManager* DOMFocusManager = nsFocusManager::GetFocusManager();
|
||||
// No focus on remote target elements like xul:browser having DOM focus and
|
||||
// residing in chrome process because it means an element in content process
|
||||
// keeps the focus.
|
||||
if (focusedElm) {
|
||||
if (nsEventStateManager::IsRemoteTarget(focusedElm))
|
||||
return nsnull;
|
||||
return focusedElm;
|
||||
}
|
||||
|
||||
// Otherwise the focus can be on DOM document.
|
||||
nsCOMPtr<nsIDOMWindow> focusedWnd;
|
||||
DOMFocusManager->GetFocusedWindow(getter_AddRefs(focusedWnd));
|
||||
if (focusedWnd) {
|
||||
|
@ -374,3 +379,10 @@ FocusManager::FocusedDOMDocument() const
|
|||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsIDocument*
|
||||
FocusManager::FocusedDOMDocument() const
|
||||
{
|
||||
nsINode* focusedNode = FocusedDOMNode();
|
||||
return focusedNode ? focusedNode->OwnerDoc() : nsnull;
|
||||
}
|
||||
|
|
|
@ -146,18 +146,7 @@ private:
|
|||
/**
|
||||
* Return DOM node having DOM focus.
|
||||
*/
|
||||
inline nsINode* FocusedDOMNode() const
|
||||
{
|
||||
nsINode* focusedNode = FocusedDOMElm();
|
||||
if (focusedNode)
|
||||
return focusedNode;
|
||||
return FocusedDOMDocument();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return DOM element having DOM focus.
|
||||
*/
|
||||
nsIContent* FocusedDOMElm() const;
|
||||
nsINode* FocusedDOMNode() const;
|
||||
|
||||
/**
|
||||
* Return DOM document having DOM focus.
|
||||
|
|
|
@ -654,7 +654,7 @@ nsAccessible::IsVisible(bool* aIsOffscreen)
|
|||
}
|
||||
|
||||
// The frame intersects the viewport, but we need to check the parent view chain :(
|
||||
bool isVisible = nsCoreUtils::CheckVisibilityInParentChain(frame);
|
||||
bool isVisible = frame->IsVisibleConsideringAncestors(nsIFrame::VISIBILITY_CROSS_CHROME_CONTENT_BOUNDARY);
|
||||
if (isVisible && rectVisibility == nsRectVisibility_kVisible) {
|
||||
*aIsOffscreen = false;
|
||||
}
|
||||
|
|
|
@ -758,31 +758,6 @@ nsCoreUtils::IsColumnHidden(nsITreeColumn *aColumn)
|
|||
nsGkAtoms::_true, eCaseMatters);
|
||||
}
|
||||
|
||||
bool
|
||||
nsCoreUtils::CheckVisibilityInParentChain(nsIFrame* aFrame)
|
||||
{
|
||||
nsIView* view = aFrame->GetClosestView();
|
||||
if (view && !view->IsEffectivelyVisible())
|
||||
return false;
|
||||
|
||||
nsIPresShell* presShell = aFrame->PresContext()->GetPresShell();
|
||||
while (presShell) {
|
||||
if (!presShell->IsActive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsIFrame* rootFrame = presShell->GetRootFrame();
|
||||
presShell = nsnull;
|
||||
if (rootFrame) {
|
||||
nsIFrame* frame = nsLayoutUtils::GetCrossDocParentFrame(rootFrame);
|
||||
if (frame) {
|
||||
presShell = frame->PresContext()->GetPresShell();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessibleDOMStringList
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -370,11 +370,6 @@ public:
|
|||
aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the visibility across both parent content and chrome.
|
||||
*/
|
||||
static bool CheckVisibilityInParentChain(nsIFrame* aFrame);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -311,7 +311,8 @@ nsDocAccessible::NativeState()
|
|||
state |= states::BUSY;
|
||||
|
||||
nsIFrame* frame = GetFrame();
|
||||
if (!frame || !nsCoreUtils::CheckVisibilityInParentChain(frame)) {
|
||||
if (!frame ||
|
||||
!frame->IsVisibleConsideringAncestors(nsIFrame::VISIBILITY_CROSS_CHROME_CONTENT_BOUNDARY)) {
|
||||
state |= states::INVISIBLE | states::OFFSCREEN;
|
||||
}
|
||||
|
||||
|
|
|
@ -234,6 +234,10 @@ body[dir=rtl] #searchSubmit:active {
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
#snippets:empty {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
@media all and (max-width: 470px) {
|
||||
#snippets { width: 65% }
|
||||
}
|
||||
|
|
|
@ -131,7 +131,16 @@ let RemoteTabViewer = {
|
|||
let item = this._tabsList.selectedItems[0];
|
||||
let uri = Weave.Utils.makeURI(item.getAttribute("url"));
|
||||
let title = item.getAttribute("title");
|
||||
PlacesUIUtils.showMinimalAddBookmarkUI(uri, title);
|
||||
PlacesUIUtils.showBookmarkDialog({ action: "add"
|
||||
, type: "bookmark"
|
||||
, uri: uri
|
||||
, title: title
|
||||
, hiddenRows: [ "description"
|
||||
, "location"
|
||||
, "folderPicker"
|
||||
, "loadInSidebar"
|
||||
, "keyword" ]
|
||||
});
|
||||
},
|
||||
|
||||
bookmarkSelectedTabs: function() {
|
||||
|
@ -146,8 +155,13 @@ let RemoteTabViewer = {
|
|||
URIs.push(uri);
|
||||
}
|
||||
}
|
||||
if (URIs.length)
|
||||
PlacesUIUtils.showMinimalAddMultiBookmarkUI(URIs);
|
||||
if (URIs.length) {
|
||||
PlacesUIUtils.showBookmarkDialog({ action: "add"
|
||||
, type: "folder"
|
||||
, URIList: URIs
|
||||
, hiddenRows: [ "description" ]
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_generateTabList: function() {
|
||||
|
|
|
@ -378,11 +378,23 @@ var PlacesCommandHook = {
|
|||
bookmarkLink: function PCH_bookmarkLink(aParent, aURL, aTitle) {
|
||||
var linkURI = makeURI(aURL);
|
||||
var itemId = PlacesUtils.getMostRecentBookmarkForURI(linkURI);
|
||||
if (itemId == -1)
|
||||
PlacesUIUtils.showMinimalAddBookmarkUI(linkURI, aTitle);
|
||||
if (itemId == -1) {
|
||||
PlacesUIUtils.showBookmarkDialog({ action: "add"
|
||||
, type: "bookmark"
|
||||
, uri: linkURI
|
||||
, title: aTitle
|
||||
, hiddenRows: [ "description"
|
||||
, "location"
|
||||
, "loadInSidebar"
|
||||
, "folderPicker"
|
||||
, "keyword" ]
|
||||
});
|
||||
}
|
||||
else {
|
||||
PlacesUIUtils.showItemProperties(itemId,
|
||||
PlacesUtils.bookmarks.TYPE_BOOKMARK);
|
||||
PlacesUIUtils.showBookmarkDialog({ action: "edit"
|
||||
, type: "bookmark"
|
||||
, itemId: itemId
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -411,7 +423,11 @@ var PlacesCommandHook = {
|
|||
bookmarkCurrentPages: function PCH_bookmarkCurrentPages() {
|
||||
let pages = this.uniqueCurrentPages;
|
||||
if (pages.length > 1) {
|
||||
PlacesUIUtils.showMinimalAddMultiBookmarkUI(pages);
|
||||
PlacesUIUtils.showBookmarkDialog({ action: "add"
|
||||
, type: "folder"
|
||||
, URIList: pages
|
||||
, hiddenRows: [ "description" ]
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -451,10 +467,18 @@ var PlacesCommandHook = {
|
|||
else
|
||||
description = PlacesUIUtils.getDescriptionFromDocument(doc);
|
||||
|
||||
var toolbarIP =
|
||||
new InsertionPoint(PlacesUtils.bookmarks.toolbarFolder, -1);
|
||||
PlacesUIUtils.showMinimalAddLivemarkUI(feedURI, gBrowser.currentURI,
|
||||
title, description, toolbarIP, true);
|
||||
var toolbarIP = new InsertionPoint(PlacesUtils.toolbarFolderId, -1);
|
||||
PlacesUIUtils.showBookmarkDialog({ action: "add"
|
||||
, type: "livemark"
|
||||
, feedURI: feedURI
|
||||
, siteURI: gBrowser.currentURI
|
||||
, title: title
|
||||
, description: description
|
||||
, defaultInsertionPoint: toolbarIP
|
||||
, hiddenRows: [ "feedLocation"
|
||||
, "siteLocation"
|
||||
, "description" ]
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -855,18 +879,13 @@ var PlacesMenuDNDHandler = {
|
|||
if (!this._isStaticContainer(event.target))
|
||||
return;
|
||||
|
||||
let ip = new InsertionPoint(PlacesUtils.bookmarksMenuFolderId,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
Ci.nsITreeView.DROP_ON);
|
||||
if (ip && PlacesControllerDragHelper.canDrop(ip, event.dataTransfer)) {
|
||||
this._loadTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
this._loadTimer.initWithCallback(function() {
|
||||
PlacesMenuDNDHandler._loadTimer = null;
|
||||
event.target.lastChild.setAttribute("autoopened", "true");
|
||||
event.target.lastChild.showPopup(event.target.lastChild);
|
||||
}, this._springLoadDelay, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
event.preventDefault();
|
||||
}
|
||||
this._loadTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
this._loadTimer.initWithCallback(function() {
|
||||
PlacesMenuDNDHandler._loadTimer = null;
|
||||
event.target.lastChild.setAttribute("autoopened", "true");
|
||||
event.target.lastChild.showPopup(event.target.lastChild);
|
||||
}, this._springLoadDelay, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
},
|
||||
|
||||
|
@ -952,7 +971,7 @@ var PlacesStarButton = {
|
|||
uninit: function PSB_uninit()
|
||||
{
|
||||
if (this._hasBookmarksObserver) {
|
||||
PlacesUtils.bookmarks.removeObserver(this);
|
||||
PlacesUtils.removeLazyBookmarkObserver(this);
|
||||
}
|
||||
if (this._pendingStmt) {
|
||||
this._pendingStmt.cancel();
|
||||
|
@ -1016,7 +1035,7 @@ var PlacesStarButton = {
|
|||
// Start observing bookmarks if needed.
|
||||
if (!this._hasBookmarksObserver) {
|
||||
try {
|
||||
PlacesUtils.bookmarks.addObserver(this, false);
|
||||
PlacesUtils.addLazyBookmarkObserver(this);
|
||||
this._hasBookmarksObserver = true;
|
||||
} catch(ex) {
|
||||
Components.utils.reportError("PlacesStarButton failed adding a bookmarks observer: " + ex);
|
||||
|
|
|
@ -13,7 +13,6 @@ tabbrowser {
|
|||
-moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tabs");
|
||||
}
|
||||
|
||||
#tabbrowser-tabs[drag=detach][closebuttons=hidden] > .tabbrowser-arrowscrollbox > .tabs-newtab-button,
|
||||
#tabbrowser-tabs:not([overflow="true"]) + #new-tab-button,
|
||||
#tabbrowser-tabs[overflow="true"] > .tabbrowser-arrowscrollbox > .tabs-newtab-button,
|
||||
#TabsToolbar[currentset]:not([currentset*="tabbrowser-tabs,new-tab-button"]) > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .tabs-newtab-button,
|
||||
|
@ -63,35 +62,6 @@ tabbrowser {
|
|||
display: block; /* position:fixed already does this (bug 579776), but let's be explicit */
|
||||
}
|
||||
|
||||
.tabbrowser-tabs[drag] > .tabbrowser-tab[selected] {
|
||||
z-index: 2; /* ensure selected tab stays on top despite -moz-transform */
|
||||
}
|
||||
|
||||
.tabbrowser-tabs[drag] > .tabbrowser-tab[dragged] {
|
||||
-moz-transition: 0s; /* suppress opening animation when reattaching tab */
|
||||
}
|
||||
|
||||
/* visibility: collapse might collapse the tab bar, so we use this instead */
|
||||
.tabbrowser-tabs[drag=detach] > .tabbrowser-tab[dragged]:not(:only-child) {
|
||||
min-width: 0 !important;
|
||||
max-width: 0 !important;
|
||||
border: 0 !important;
|
||||
opacity: 0;
|
||||
overflow: hidden;
|
||||
-moz-transition: max-width 150ms ease-out;
|
||||
}
|
||||
.tabbrowser-tabs[drag=detach] > .tabbrowser-tab[dragged]:only-child {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.tabbrowser-tabs[drag=move] > .tabbrowser-tab[fadein]:not([dragged]) {
|
||||
-moz-transition: -moz-transform 200ms ease-out;
|
||||
}
|
||||
|
||||
.tabbrowser-tabs[drag=finish] > .tabbrowser-tab[dragged][fadein] {
|
||||
-moz-transition: -moz-transform 100ms ease-out;
|
||||
}
|
||||
|
||||
#alltabs-popup {
|
||||
-moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-alltabs-popup");
|
||||
}
|
||||
|
@ -387,6 +357,25 @@ window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(.chromeclass-m
|
|||
background: black;
|
||||
}
|
||||
|
||||
#full-screen-warning-container {
|
||||
pointer-events: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
min-width: 100%;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
#full-screen-warning-container[fade-warning-out] {
|
||||
-moz-transition-property: opacity !important;
|
||||
-moz-transition-duration: 500ms !important;
|
||||
opacity: 0.0;
|
||||
}
|
||||
|
||||
#full-screen-warning-message {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
#nav-bar[mode="text"] > #window-controls > toolbarbutton > .toolbarbutton-icon {
|
||||
display: -moz-box;
|
||||
}
|
||||
|
|
|
@ -1346,7 +1346,6 @@ function BrowserStartup() {
|
|||
gURLBar.setAttribute("readonly", "true");
|
||||
gURLBar.setAttribute("enablehistory", "false");
|
||||
}
|
||||
goSetCommandEnabled("Browser:OpenLocation", false);
|
||||
goSetCommandEnabled("cmd_newNavigatorTab", false);
|
||||
}
|
||||
|
||||
|
@ -1670,8 +1669,19 @@ function delayedStartup(isLoadingBlank, mustLoadSidebar) {
|
|||
// called when we go into full screen, even if it is
|
||||
// initiated by a web page script
|
||||
window.addEventListener("fullscreen", onFullScreen, true);
|
||||
|
||||
// Called when we enter DOM full-screen mode. Note we can already be in browser
|
||||
// full-screen mode when we enter DOM full-screen mode.
|
||||
window.addEventListener("mozfullscreenchange", onMozFullScreenChange, true);
|
||||
|
||||
// When a restricted key is pressed in DOM full-screen mode, we should display
|
||||
// the "Press ESC to exit" warning message.
|
||||
window.addEventListener("MozShowFullScreenWarning", onShowFullScreenWarning, true);
|
||||
|
||||
if (window.fullScreen)
|
||||
onFullScreen();
|
||||
if (document.mozFullScreen)
|
||||
onMozFullScreenChange();
|
||||
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
// initialize the sync UI
|
||||
|
@ -2125,7 +2135,7 @@ function loadOneOrMoreURIs(aURIString)
|
|||
}
|
||||
|
||||
function focusAndSelectUrlBar() {
|
||||
if (gURLBar && !gURLBar.readOnly) {
|
||||
if (gURLBar) {
|
||||
if (window.fullScreen)
|
||||
FullScreen.mouseoverToggle(true);
|
||||
if (isElementVisible(gURLBar)) {
|
||||
|
@ -2839,6 +2849,14 @@ function onFullScreen(event) {
|
|||
FullScreen.toggle(event);
|
||||
}
|
||||
|
||||
function onMozFullScreenChange(event) {
|
||||
FullScreen.enterDomFullScreen(event);
|
||||
}
|
||||
|
||||
function onShowFullScreenWarning(event) {
|
||||
FullScreen.showWarning(false);
|
||||
}
|
||||
|
||||
function getWebNavigation()
|
||||
{
|
||||
try {
|
||||
|
@ -3122,7 +3140,16 @@ var bookmarksButtonObserver = {
|
|||
let name = { };
|
||||
let url = browserDragAndDrop.drop(aEvent, name);
|
||||
try {
|
||||
PlacesUIUtils.showMinimalAddBookmarkUI(makeURI(url), name);
|
||||
PlacesUIUtils.showBookmarkDialog({ action: "add"
|
||||
, type: "bookmark"
|
||||
, uri: makeURI(url)
|
||||
, title: name
|
||||
, hiddenRows: [ "description"
|
||||
, "location"
|
||||
, "loadInSidebar"
|
||||
, "folderPicker"
|
||||
, "keyword" ]
|
||||
});
|
||||
} catch(ex) { }
|
||||
},
|
||||
|
||||
|
@ -3821,17 +3848,19 @@ var FullScreen = {
|
|||
if (enterFS) {
|
||||
// Add a tiny toolbar to receive mouseover and dragenter events, and provide affordance.
|
||||
// This will help simulate the "collapse" metaphor while also requiring less code and
|
||||
// events than raw listening of mouse coords.
|
||||
let fullScrToggler = document.getElementById("fullscr-toggler");
|
||||
if (!fullScrToggler) {
|
||||
fullScrToggler = document.createElement("hbox");
|
||||
fullScrToggler.id = "fullscr-toggler";
|
||||
fullScrToggler.collapsed = true;
|
||||
gNavToolbox.parentNode.insertBefore(fullScrToggler, gNavToolbox.nextSibling);
|
||||
// events than raw listening of mouse coords. We don't add the toolbar in DOM full-screen
|
||||
// mode, only browser full-screen mode.
|
||||
if (!document.mozFullScreen) {
|
||||
let fullScrToggler = document.getElementById("fullscr-toggler");
|
||||
if (!fullScrToggler) {
|
||||
fullScrToggler = document.createElement("hbox");
|
||||
fullScrToggler.id = "fullscr-toggler";
|
||||
fullScrToggler.collapsed = true;
|
||||
gNavToolbox.parentNode.insertBefore(fullScrToggler, gNavToolbox.nextSibling);
|
||||
}
|
||||
fullScrToggler.addEventListener("mouseover", this._expandCallback, false);
|
||||
fullScrToggler.addEventListener("dragenter", this._expandCallback, false);
|
||||
}
|
||||
fullScrToggler.addEventListener("mouseover", this._expandCallback, false);
|
||||
fullScrToggler.addEventListener("dragenter", this._expandCallback, false);
|
||||
|
||||
if (gPrefService.getBoolPref("browser.fullscreen.autohide"))
|
||||
gBrowser.mPanelContainer.addEventListener("mousemove",
|
||||
this._collapseCallback, false);
|
||||
|
@ -3839,7 +3868,10 @@ var FullScreen = {
|
|||
document.addEventListener("keypress", this._keyToggleCallback, false);
|
||||
document.addEventListener("popupshown", this._setPopupOpen, false);
|
||||
document.addEventListener("popuphidden", this._setPopupOpen, false);
|
||||
this._shouldAnimate = true;
|
||||
// We don't animate the toolbar collapse if in DOM full-screen mode,
|
||||
// as the size of the content area would still be changing after the
|
||||
// mozfullscreenchange event fired, which could confuse content script.
|
||||
this._shouldAnimate = !document.mozFullScreen;
|
||||
this.mouseoverToggle(false);
|
||||
|
||||
// Autohide prefs
|
||||
|
@ -3860,6 +3892,29 @@ var FullScreen = {
|
|||
}
|
||||
},
|
||||
|
||||
enterDomFullScreen : function(event) {
|
||||
if (!document.mozFullScreen) {
|
||||
return;
|
||||
}
|
||||
this.showWarning(true);
|
||||
|
||||
// Cancel any "hide the toolbar" animation which is in progress, and make
|
||||
// the toolbar hide immediately.
|
||||
clearInterval(this._animationInterval);
|
||||
clearTimeout(this._animationTimeout);
|
||||
this._isAnimating = false;
|
||||
this._shouldAnimate = false;
|
||||
this.mouseoverToggle(false);
|
||||
|
||||
// If there's a full-screen toggler, remove its listeners, so that mouseover
|
||||
// the top of the screen will not cause the toolbar to re-appear.
|
||||
let fullScrToggler = document.getElementById("fullscr-toggler");
|
||||
if (fullScrToggler) {
|
||||
fullScrToggler.removeEventListener("mouseover", this._expandCallback, false);
|
||||
fullScrToggler.removeEventListener("dragenter", this._expandCallback, false);
|
||||
}
|
||||
},
|
||||
|
||||
cleanup: function () {
|
||||
if (window.fullScreen) {
|
||||
gBrowser.mPanelContainer.removeEventListener("mousemove",
|
||||
|
@ -3874,6 +3929,7 @@ var FullScreen = {
|
|||
fullScrToggler.removeEventListener("mouseover", this._expandCallback, false);
|
||||
fullScrToggler.removeEventListener("dragenter", this._expandCallback, false);
|
||||
}
|
||||
this.cancelWarning();
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -3994,6 +4050,84 @@ var FullScreen = {
|
|||
FullScreen._animationInterval = setInterval(animateUpFrame, 70);
|
||||
},
|
||||
|
||||
cancelWarning: function(event) {
|
||||
if (!this.warningBox) {
|
||||
return;
|
||||
}
|
||||
if (this.onWarningHidden) {
|
||||
this.warningBox.removeEventListener("transitionend", this.onWarningHidden, false);
|
||||
this.onWarningHidden = null;
|
||||
}
|
||||
if (this.warningFadeOutTimeout) {
|
||||
clearTimeout(this.warningFadeOutTimeout);
|
||||
this.warningFadeOutTimeout = null;
|
||||
}
|
||||
if (this.revealBrowserTimeout) {
|
||||
clearTimeout(this.revealBrowserTimeout);
|
||||
this.revealBrowserTimeout = null;
|
||||
}
|
||||
this.warningBox.removeAttribute("fade-warning-out");
|
||||
this.warningBox.removeAttribute("stop-obscuring-browser");
|
||||
this.warningBox.removeAttribute("obscure-browser");
|
||||
this.warningBox.setAttribute("hidden", true);
|
||||
this.warningBox = null;
|
||||
},
|
||||
|
||||
warningBox: null,
|
||||
warningFadeOutTimeout: null,
|
||||
revealBrowserTimeout: null,
|
||||
onWarningHidden: null,
|
||||
|
||||
// Fade in a warning that document has entered full-screen, and then fade it
|
||||
// out after a few seconds.
|
||||
showWarning: function(obscureBackground) {
|
||||
if (!document.mozFullScreen || !gPrefService.getBoolPref("full-screen-api.warning.enabled")) {
|
||||
return;
|
||||
}
|
||||
if (this.warningBox) {
|
||||
// Warning is already showing. Reset the timer which fades out the warning message,
|
||||
// and we'll restart the timer down below.
|
||||
if (this.warningFadeOutTimeout) {
|
||||
clearTimeout(this.warningFadeOutTimeout);
|
||||
this.warningFadeOutTimeout = null;
|
||||
}
|
||||
} else {
|
||||
this.warningBox = document.getElementById("full-screen-warning-container");
|
||||
// Add a listener to clean up state after the warning is hidden.
|
||||
this.onWarningHidden =
|
||||
function(event) {
|
||||
if (event.propertyName != "opacity")
|
||||
return;
|
||||
this.cancelWarning();
|
||||
}.bind(this);
|
||||
this.warningBox.addEventListener("transitionend", this.onWarningHidden, false);
|
||||
this.warningBox.removeAttribute("hidden");
|
||||
}
|
||||
|
||||
if (obscureBackground) {
|
||||
// Partially obscure the <browser> element underneath the warning panel...
|
||||
this.warningBox.setAttribute("obscure-browser", "true");
|
||||
// ...But set a timeout to stop obscuring the browser after a few moments.
|
||||
this.warningBox.removeAttribute("stop-obscuring-browser");
|
||||
this.revealBrowserTimeout =
|
||||
setTimeout(
|
||||
function() {
|
||||
if (this.warningBox)
|
||||
this.warningBox.setAttribute("stop-obscuring-browser", "true");
|
||||
}.bind(this),
|
||||
1250);
|
||||
}
|
||||
|
||||
// Set a timeout to fade the warning out after a few moments.
|
||||
this.warningFadeOutTimeout =
|
||||
setTimeout(
|
||||
function() {
|
||||
if (this.warningBox)
|
||||
this.warningBox.setAttribute("fade-warning-out", "true");
|
||||
}.bind(this),
|
||||
3000);
|
||||
},
|
||||
|
||||
mouseoverToggle: function(aShow, forceHide)
|
||||
{
|
||||
// Don't do anything if:
|
||||
|
@ -4033,7 +4167,10 @@ var FullScreen = {
|
|||
gNavToolbox.style.marginTop =
|
||||
aShow ? "" : -gNavToolbox.getBoundingClientRect().height + "px";
|
||||
|
||||
document.getElementById("fullscr-toggler").collapsed = aShow;
|
||||
let toggler = document.getElementById("fullscr-toggler");
|
||||
if (toggler) {
|
||||
toggler.collapsed = aShow;
|
||||
}
|
||||
this._isChromeCollapsed = !aShow;
|
||||
if (gPrefService.getIntPref("browser.fullscreen.animateUp") == 2)
|
||||
this._shouldAnimate = true;
|
||||
|
@ -4159,7 +4296,7 @@ var XULBrowserWindow = {
|
|||
startTime: 0,
|
||||
statusText: "",
|
||||
isBusy: false,
|
||||
inContentWhitelist: ["about:addons", "about:permissions"],
|
||||
inContentWhitelist: ["about:addons", "about:permissions", "about:sync-progress"],
|
||||
|
||||
QueryInterface: function (aIID) {
|
||||
if (aIID.equals(Ci.nsIWebProgressListener) ||
|
||||
|
@ -5588,9 +5725,16 @@ function contentAreaClick(event, isPanelClick)
|
|||
// This is the Opera convention for a special link that, when clicked,
|
||||
// allows to add a sidebar panel. The link's title attribute contains
|
||||
// the title that should be used for the sidebar panel.
|
||||
PlacesUIUtils.showMinimalAddBookmarkUI(makeURI(href),
|
||||
linkNode.getAttribute("title"),
|
||||
null, null, true, true);
|
||||
PlacesUIUtils.showBookmarkDialog({ action: "add"
|
||||
, type: "bookmark"
|
||||
, uri: makeURI(href)
|
||||
, title: linkNode.getAttribute("title")
|
||||
, loadBookmarkInSidebar: true
|
||||
, hiddenRows: [ "description"
|
||||
, "location"
|
||||
, "folderPicker"
|
||||
, "keyword" ]
|
||||
});
|
||||
event.preventDefault();
|
||||
return true;
|
||||
}
|
||||
|
@ -6626,8 +6770,18 @@ function AddKeywordForSearchField() {
|
|||
else
|
||||
spec += "?" + formData.join("&");
|
||||
|
||||
PlacesUIUtils.showMinimalAddBookmarkUI(makeURI(spec), title, description, null,
|
||||
null, null, "", postData, charset);
|
||||
PlacesUIUtils.showBookmarkDialog({ action: "add"
|
||||
, type: "bookmark"
|
||||
, uri: makeURI(spec)
|
||||
, title: title
|
||||
, description: description
|
||||
, keyword: ""
|
||||
, postData: postData
|
||||
, charSet: charset
|
||||
, hiddenRows: [ "location"
|
||||
, "loadInSidebar"
|
||||
, "folderPicker" ]
|
||||
});
|
||||
}
|
||||
|
||||
function SwitchDocumentDirection(aWindow) {
|
||||
|
@ -6679,14 +6833,6 @@ var gPluginHandler = {
|
|||
return this.CrashSubmit;
|
||||
},
|
||||
|
||||
get crashReportHelpURL() {
|
||||
delete this.crashReportHelpURL;
|
||||
let url = formatURL("app.support.baseURL", true);
|
||||
url += "plugin-crashed";
|
||||
this.crashReportHelpURL = url;
|
||||
return this.crashReportHelpURL;
|
||||
},
|
||||
|
||||
// Map the plugin's name to a filtered version more suitable for user UI.
|
||||
makeNicePluginName : function (aName, aFilename) {
|
||||
if (aName == "Shockwave Flash")
|
||||
|
@ -6825,10 +6971,25 @@ var gPluginHandler = {
|
|||
BrowserOpenAddonsMgr("addons://list/plugin");
|
||||
},
|
||||
|
||||
// Callback for user clicking "submit a report" link
|
||||
submitReport : function(pluginDumpID, browserDumpID) {
|
||||
// The crash reporter wants a DOM element it can append an IFRAME to,
|
||||
// which it uses to submit a form. Let's just give it gBrowser.
|
||||
// When user clicks try, checks if we should also send crash report in bg
|
||||
retryPluginPage: function (browser, plugin, pluginDumpID, browserDumpID) {
|
||||
let doc = plugin.ownerDocument;
|
||||
|
||||
let statusDiv =
|
||||
doc.getAnonymousElementByAttribute(plugin, "class", "submitStatus");
|
||||
let status = statusDiv.getAttribute("status");
|
||||
|
||||
let submitChk =
|
||||
doc.getAnonymousElementByAttribute(plugin, "class", "pleaseSubmitCheckbox");
|
||||
|
||||
// Check status to make sure we haven't submitted already
|
||||
if (status == "please" && submitChk.checked) {
|
||||
this.submitReport(pluginDumpID, browserDumpID);
|
||||
}
|
||||
this.reloadPage(browser);
|
||||
},
|
||||
|
||||
submitReport: function (pluginDumpID, browserDumpID) {
|
||||
this.CrashSubmit.submit(pluginDumpID);
|
||||
if (browserDumpID)
|
||||
this.CrashSubmit.submit(browserDumpID);
|
||||
|
@ -7046,8 +7207,7 @@ var gPluginHandler = {
|
|||
return;
|
||||
|
||||
let submittedReport = aEvent.getData("submittedCrashReport");
|
||||
let doPrompt = true; // XXX followup for .getData("doPrompt");
|
||||
let submitReports = true; // XXX followup for .getData("submitReports");
|
||||
let doPrompt = true; // XXX followup to get via gCrashReporter
|
||||
let pluginName = aEvent.getData("pluginName");
|
||||
let pluginFilename = aEvent.getData("pluginFilename");
|
||||
let pluginDumpID = aEvent.getData("pluginDumpID");
|
||||
|
@ -7065,6 +7225,7 @@ var gPluginHandler = {
|
|||
let overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
|
||||
let statusDiv = doc.getAnonymousElementByAttribute(plugin, "class", "submitStatus");
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
let submitReports = gCrashReporter.submitReports;
|
||||
let status;
|
||||
|
||||
// Determine which message to show regarding crash reports.
|
||||
|
@ -7075,18 +7236,21 @@ var gPluginHandler = {
|
|||
status = "noSubmit";
|
||||
}
|
||||
else { // doPrompt
|
||||
// link submit checkbox to gCrashReporter submitReports preference
|
||||
let submitChk = doc.getAnonymousElementByAttribute(
|
||||
plugin, "class", "pleaseSubmitCheckbox");
|
||||
submitChk.checked = submitReports;
|
||||
submitChk.addEventListener("click", function() {
|
||||
gCrashReporter.submitReports = this.checked;
|
||||
}, false);
|
||||
|
||||
status = "please";
|
||||
// XXX can we make the link target actually be blank?
|
||||
let pleaseLink = doc.getAnonymousElementByAttribute(
|
||||
plugin, "class", "pleaseSubmitLink");
|
||||
this.addLinkClickCallback(pleaseLink, "submitReport",
|
||||
pluginDumpID, browserDumpID);
|
||||
}
|
||||
|
||||
// If we don't have a minidumpID, we can't (or didn't) submit anything.
|
||||
// This can happen if the plugin is killed from the task manager.
|
||||
if (!pluginDumpID) {
|
||||
status = "noReport";
|
||||
status = "noReport";
|
||||
}
|
||||
|
||||
statusDiv.setAttribute("status", status);
|
||||
|
@ -7096,10 +7260,23 @@ var gPluginHandler = {
|
|||
let helpIcon = doc.getAnonymousElementByAttribute(plugin, "class", "helpIcon");
|
||||
this.addLinkClickCallback(helpIcon, "openHelpPage");
|
||||
|
||||
// If we're showing the link to manually trigger report submission, we'll
|
||||
// want to be able to update all the instances of the UI for this crash to
|
||||
// show an updated message when a report is submitted.
|
||||
// If we're showing the checkbox to trigger report submission, we'll want
|
||||
// to be able to update all the instances of the UI for this crash when
|
||||
// one instance of the checkbox is modified or the status is updated.
|
||||
if (doPrompt) {
|
||||
let submitReportsPrefObserver = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
observe : function(subject, topic, data) {
|
||||
let submitChk = doc.getAnonymousElementByAttribute(
|
||||
plugin, "class", "pleaseSubmitCheckbox");
|
||||
submitChk.checked = gCrashReporter.submitReports;
|
||||
},
|
||||
handleEvent : function(event) {
|
||||
// Not expected to be called, just here for the closure.
|
||||
}
|
||||
};
|
||||
|
||||
let observer = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
|
@ -7116,16 +7293,21 @@ var gPluginHandler = {
|
|||
handleEvent : function(event) {
|
||||
// Not expected to be called, just here for the closure.
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Use a weak reference, so we don't have to remove it...
|
||||
Services.obs.addObserver(observer, "crash-report-status", true);
|
||||
Services.obs.addObserver(
|
||||
submitReportsPrefObserver, "submit-reports-pref-changed", true);
|
||||
|
||||
// ...alas, now we need something to hold a strong reference to prevent
|
||||
// it from being GC. But I don't want to manually manage the reference's
|
||||
// lifetime (which should be no greater than the page).
|
||||
// Clever solution? Use a closue with an event listener on the document.
|
||||
// Clever solution? Use a closure with an event listener on the document.
|
||||
// When the doc goes away, so do the listener references and the closure.
|
||||
doc.addEventListener("mozCleverClosureHack", observer, false);
|
||||
doc.addEventListener(
|
||||
"mozCleverClosureHack", submitReportsPrefObserver, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -7135,7 +7317,12 @@ var gPluginHandler = {
|
|||
let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
|
||||
|
||||
let link = doc.getAnonymousElementByAttribute(plugin, "class", "reloadLink");
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
this.addLinkClickCallback(
|
||||
link, "retryPluginPage", browser, plugin, pluginDumpID, browserDumpID);
|
||||
#else
|
||||
this.addLinkClickCallback(link, "reloadPage", browser);
|
||||
#endif
|
||||
|
||||
let notificationBox = gBrowser.getNotificationBox(browser);
|
||||
|
||||
|
@ -7201,7 +7388,10 @@ var gPluginHandler = {
|
|||
let link = notification.ownerDocument.createElementNS(XULNS, "label");
|
||||
link.className = "text-link";
|
||||
link.setAttribute("value", gNavigatorBundle.getString("crashedpluginsMessage.learnMore"));
|
||||
link.href = gPluginHandler.crashReportHelpURL;
|
||||
let crashurl = formatURL("app.support.baseURL", true);
|
||||
crashurl += "plugin-crashed-notificationbar";
|
||||
link.href = crashurl;
|
||||
|
||||
let description = notification.ownerDocument.getAnonymousElementByAttribute(notification, "anonid", "messageText");
|
||||
description.appendChild(link);
|
||||
|
||||
|
|
|
@ -969,18 +969,40 @@
|
|||
<vbox id="browser-border-end" hidden="true" layer="true"/>
|
||||
</hbox>
|
||||
|
||||
<hbox id="full-screen-warning-container" hidden="true" fadeout="true">
|
||||
<hbox style="min-width: 100%;" pack="center"> <!-- Inner hbox needed due to bug 579776. -->
|
||||
<hbox id="full-screen-warning-message">
|
||||
<description id="full-screen-warning-text" value="&domFullScreenWarning.label;"></description>
|
||||
</hbox>
|
||||
</hbox>
|
||||
</hbox>
|
||||
|
||||
<vbox id="browser-bottombox" layer="true">
|
||||
<toolbar id="inspector-toolbar"
|
||||
nowindowdrag="true"
|
||||
hidden="true">
|
||||
<toolbarbutton id="inspector-inspect-toolbutton"
|
||||
label="&inspectButton.label;"
|
||||
accesskey="&inspectButton.accesskey;"
|
||||
command="Inspector:Inspect"/>
|
||||
<toolbarseparator />
|
||||
<hbox id="inspector-tools">
|
||||
<!-- registered tools go here -->
|
||||
</hbox>
|
||||
<vbox flex="1">
|
||||
<resizer id="inspector-top-resizer" flex="1"
|
||||
class="inspector-resizer"
|
||||
dir="top" disabled="true"
|
||||
element="inspector-tree-box"/>
|
||||
<hbox>
|
||||
<toolbarbutton id="inspector-inspect-toolbutton"
|
||||
label="&inspectButton.label;"
|
||||
accesskey="&inspectButton.accesskey;"
|
||||
command="Inspector:Inspect"/>
|
||||
<arrowscrollbox id="inspector-breadcrumbs"
|
||||
flex="1" orient="horizontal"
|
||||
clicktoscroll="true"/>
|
||||
<hbox id="inspector-tools">
|
||||
<!-- registered tools go here -->
|
||||
</hbox>
|
||||
<resizer id="inspector-end-resizer"
|
||||
class="inspector-resizer"
|
||||
dir="top" disabled="true"
|
||||
element="inspector-tree-box"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</toolbar>
|
||||
<toolbar id="addon-bar"
|
||||
toolbarname="&addonBarCmd.label;" accesskey="&addonBarCmd.accesskey;"
|
||||
|
|
|
@ -36,6 +36,10 @@
|
|||
z-index: 1;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button {
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Node Infobar
|
||||
*/
|
||||
|
|
|
@ -1397,11 +1397,24 @@ nsContextMenu.prototype = {
|
|||
if (itemId == -1) {
|
||||
var title = doc.title;
|
||||
var description = PlacesUIUtils.getDescriptionFromDocument(doc);
|
||||
PlacesUIUtils.showMinimalAddBookmarkUI(uri, title, description);
|
||||
PlacesUIUtils.showBookmarkDialog({ action: "add"
|
||||
, type: "bookmark"
|
||||
, uri: uri
|
||||
, title: title
|
||||
, description: description
|
||||
, hiddenRows: [ "description"
|
||||
, "location"
|
||||
, "loadInSidebar"
|
||||
, "folderPicker"
|
||||
, "keyword" ]
|
||||
});
|
||||
}
|
||||
else {
|
||||
PlacesUIUtils.showBookmarkDialog({ action: "edit"
|
||||
, type: "bookmark"
|
||||
, itemId: itemId
|
||||
});
|
||||
}
|
||||
else
|
||||
PlacesUIUtils.showItemProperties(itemId,
|
||||
PlacesUtils.bookmarks.TYPE_BOOKMARK);
|
||||
},
|
||||
|
||||
savePageAs: function CM_savePageAs() {
|
||||
|
@ -1443,13 +1456,13 @@ nsContextMenu.prototype = {
|
|||
media.setAttribute("controls", "true");
|
||||
break;
|
||||
case "showstats":
|
||||
var event = document.createEvent("CustomEvent");
|
||||
event.initCustomEvent("media-showStatistics", false, true, true);
|
||||
var event = document.createEvent("CustomEvent");
|
||||
event.initCustomEvent("media-showStatistics", false, true, true);
|
||||
media.dispatchEvent(event);
|
||||
break;
|
||||
case "hidestats":
|
||||
var event = document.createEvent("CustomEvent");
|
||||
event.initCustomEvent("media-showStatistics", false, true, false);
|
||||
var event = document.createEvent("CustomEvent");
|
||||
event.initCustomEvent("media-showStatistics", false, true, false);
|
||||
media.dispatchEvent(event);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/* ***** 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 Firefox Sync.
|
||||
*
|
||||
* The Initial Developer of the Original Code is the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Allison Naaktgeboren <ally@mozilla.com> (original author)
|
||||
*
|
||||
* 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 GPL or the LGPL. 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 ***** */
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://services-sync/main.js");
|
||||
|
||||
let gProgressBar;
|
||||
let gCounter = 0;
|
||||
|
||||
function onLoad(event) {
|
||||
Services.obs.addObserver(increaseProgressBar, "weave:engine:sync:finish", false);
|
||||
Services.obs.addObserver(increaseProgressBar, "weave:engine:sync:error", false);
|
||||
gProgressBar = document.getElementById('uploadProgressBar');
|
||||
|
||||
if (Services.prefs.getPrefType("services.sync.firstSync") != Ci.nsIPrefBranch.PREF_INVALID) {
|
||||
gProgressBar.max = Weave.Engines.getEnabled().length;
|
||||
gProgressBar.style.display = "inline";
|
||||
}
|
||||
else {
|
||||
gProgressBar.style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
function onUnload(event) {
|
||||
Services.obs.removeObserver(increaseProgressBar, "weave:engine:sync:finish");
|
||||
Services.obs.removeObserver(increaseProgressBar, "weave:engine:sync:error");
|
||||
}
|
||||
|
||||
function increaseProgressBar(){
|
||||
gCounter += 1;
|
||||
gProgressBar.setAttribute("value", gCounter);
|
||||
}
|
||||
|
||||
function closeTab() {
|
||||
window.close();
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
# ***** 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 Firefox Sync.
|
||||
#
|
||||
# The Initial Developer of the Original Code is the Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2011
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Allison Naaktgeboren <ally@mozilla.com> (original author)
|
||||
#
|
||||
# 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 GPL or the LGPL. 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 *****
|
||||
|
||||
<!DOCTYPE html [
|
||||
<!ENTITY % htmlDTD
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"DTD/xhtml1-strict.dtd">
|
||||
%htmlDTD;
|
||||
<!ENTITY % syncProgressDTD
|
||||
SYSTEM "chrome://browser/locale/syncProgress.dtd">
|
||||
%syncProgressDTD;
|
||||
<!ENTITY % syncSetupDTD
|
||||
SYSTEM "chrome://browser/locale/syncSetup.dtd">
|
||||
%syncSetupDTD;
|
||||
]>
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>&syncProgress.pageTitle;</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" media="all"
|
||||
href="chrome://browser/skin/syncProgress.css"/>
|
||||
|
||||
<link rel="icon" type="image/png" id="favicon"
|
||||
href="chrome://browser/skin/sync-16.png"/>
|
||||
|
||||
<script type="text/javascript;version=1.8"
|
||||
src="chrome://browser/content/syncProgress.js"/>
|
||||
</head>
|
||||
<body onload="onLoad(event)" onunload="onUnload(event)">
|
||||
<title>&setup.successPage.title;</title>
|
||||
<div id="floatingBox" class="main-content">
|
||||
<div id="title">
|
||||
<h1>&setup.successPage.title;</h1>
|
||||
</div>
|
||||
<div id="successLogo">
|
||||
<img id="brandSyncLogo" src="chrome://browser/skin/sync-128.png" alt="&syncProgress.logoAltText;" />
|
||||
</div>
|
||||
<div id="loadingText">
|
||||
<p id="blurb">&syncProgress.textBlurb; </p>
|
||||
</div>
|
||||
<div id="progressBar">
|
||||
<progress id="uploadProgressBar" value="0"/>
|
||||
</div>
|
||||
<div id="bottomRow">
|
||||
<button id="closeButton" onclick="closeTab()">&syncProgress.closeButton; </button>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -24,6 +24,7 @@
|
|||
* Philipp von Weitershausen <philipp@weitershausen.de>
|
||||
* Paul O’Shannessy <paul@oshannessy.com>
|
||||
* Richard Newman <rnewman@mozilla.com>
|
||||
* Allison Naaktgeboren <ally@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
|
||||
|
@ -53,7 +54,6 @@ const EXISTING_ACCOUNT_CONNECT_PAGE = 3;
|
|||
const EXISTING_ACCOUNT_LOGIN_PAGE = 4;
|
||||
const OPTIONS_PAGE = 5;
|
||||
const OPTIONS_CONFIRM_PAGE = 6;
|
||||
const SETUP_SUCCESS_PAGE = 7;
|
||||
|
||||
// Broader than we'd like, but after this changed from api-secure.recaptcha.net
|
||||
// we had no choice. At least we only do this for the duration of setup.
|
||||
|
@ -411,6 +411,7 @@ var gSyncSetup = {
|
|||
this.checkFields();
|
||||
break;
|
||||
case EXISTING_ACCOUNT_CONNECT_PAGE:
|
||||
Weave.Svc.Prefs.set("firstSync", "existingAccount");
|
||||
this.wizard.getButton("next").hidden = false;
|
||||
this.wizard.getButton("back").hidden = false;
|
||||
this.wizard.getButton("extra1").hidden = false;
|
||||
|
@ -425,18 +426,6 @@ var gSyncSetup = {
|
|||
this.wizard.canRewind = true;
|
||||
this.checkFields();
|
||||
break;
|
||||
case SETUP_SUCCESS_PAGE:
|
||||
this.wizard.canRewind = false;
|
||||
this.wizard.canAdvance = true;
|
||||
this.wizard.getButton("back").hidden = true;
|
||||
this.wizard.getButton("next").hidden = true;
|
||||
this.wizard.getButton("cancel").hidden = true;
|
||||
this.wizard.getButton("finish").hidden = false;
|
||||
this._handleSuccess();
|
||||
if (this.wizardType == "pair") {
|
||||
this.completePairing();
|
||||
}
|
||||
break;
|
||||
case OPTIONS_PAGE:
|
||||
this.wizard.canRewind = false;
|
||||
this.wizard.canAdvance = true;
|
||||
|
@ -473,7 +462,7 @@ var gSyncSetup = {
|
|||
!Weave.Utils.ensureMPUnlocked()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
switch (this.wizard.pageIndex) {
|
||||
case PAIR_PAGE:
|
||||
this.startPairing();
|
||||
|
@ -519,7 +508,8 @@ var gSyncSetup = {
|
|||
Weave.Service.password = password;
|
||||
Weave.Service.passphrase = Weave.Utils.generatePassphrase();
|
||||
this._handleNoScript(false);
|
||||
this.wizard.pageIndex = SETUP_SUCCESS_PAGE;
|
||||
Weave.Svc.Prefs.set("firstSync", "newAccount");
|
||||
this.wizardFinish();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -532,8 +522,9 @@ var gSyncSetup = {
|
|||
Weave.Service.password = document.getElementById("existingPassword").value;
|
||||
let pp = document.getElementById("existingPassphrase").value;
|
||||
Weave.Service.passphrase = Weave.Utils.normalizePassphrase(pp);
|
||||
if (Weave.Service.login())
|
||||
this.wizard.pageIndex = SETUP_SUCCESS_PAGE;
|
||||
if (Weave.Service.login()) {
|
||||
this.wizardFinish();
|
||||
}
|
||||
return false;
|
||||
case OPTIONS_PAGE:
|
||||
let desc = document.getElementById("mergeChoiceRadio").selectedIndex;
|
||||
|
@ -544,8 +535,7 @@ var gSyncSetup = {
|
|||
return this._handleChoice();
|
||||
case OPTIONS_CONFIRM_PAGE:
|
||||
if (this._resettingSync) {
|
||||
this.onWizardFinish();
|
||||
window.close();
|
||||
this.wizardFinish();
|
||||
return false;
|
||||
}
|
||||
return this.returnFromOptions();
|
||||
|
@ -580,9 +570,13 @@ var gSyncSetup = {
|
|||
return true;
|
||||
},
|
||||
|
||||
onWizardFinish: function () {
|
||||
wizardFinish: function () {
|
||||
this.setupInitialSync();
|
||||
|
||||
if (this.wizardType == "pair") {
|
||||
this.completePairing();
|
||||
}
|
||||
|
||||
if (!this._resettingSync) {
|
||||
function isChecked(element) {
|
||||
return document.getElementById(element).hasAttribute("checked");
|
||||
|
@ -598,22 +592,17 @@ var gSyncSetup = {
|
|||
|
||||
Weave.Service.persistLogin();
|
||||
Weave.Svc.Obs.notify("weave:service:setup-complete");
|
||||
if (this._settingUpNew)
|
||||
gSyncUtils.openFirstClientFirstrun();
|
||||
else
|
||||
gSyncUtils.openAddedClientFirstrun();
|
||||
|
||||
gSyncUtils.openFirstSyncProgressPage();
|
||||
}
|
||||
Weave.Utils.nextTick(Weave.Service.sync, Weave.Service);
|
||||
window.close();
|
||||
},
|
||||
|
||||
onWizardCancel: function () {
|
||||
if (this._resettingSync)
|
||||
return;
|
||||
|
||||
if (this.wizard.pageIndex == SETUP_SUCCESS_PAGE) {
|
||||
this.onWizardFinish();
|
||||
return;
|
||||
}
|
||||
this.abortEasySetup();
|
||||
this._handleNoScript(false);
|
||||
Weave.Service.startOver();
|
||||
|
@ -714,7 +703,7 @@ var gSyncSetup = {
|
|||
Weave.Service.password = credentials.password;
|
||||
Weave.Service.passphrase = credentials.synckey;
|
||||
Weave.Service.serverURL = credentials.serverURL;
|
||||
self.wizard.pageIndex = SETUP_SUCCESS_PAGE;
|
||||
gSyncSetup.wizardFinish();
|
||||
},
|
||||
|
||||
onAbort: function onAbort(error) {
|
||||
|
@ -906,25 +895,6 @@ var gSyncSetup = {
|
|||
return valid;
|
||||
},
|
||||
|
||||
_handleSuccess: function() {
|
||||
let self = this;
|
||||
function fill(id, string)
|
||||
document.getElementById(id).firstChild.nodeValue =
|
||||
string ? self._stringBundle.GetStringFromName(string) : "";
|
||||
|
||||
fill("firstSyncAction", "");
|
||||
fill("firstSyncActionWarning", "");
|
||||
if (this._settingUpNew) {
|
||||
fill("firstSyncAction", "newAccount.action.label");
|
||||
fill("firstSyncActionChange", "newAccount.change.label");
|
||||
return;
|
||||
}
|
||||
fill("firstSyncActionChange", "existingAccount.change.label");
|
||||
let action = document.getElementById("mergeChoiceRadio").selectedItem.id;
|
||||
let id = action == "resetClient" ? "firstSyncAction" : "firstSyncActionWarning";
|
||||
fill(id, action + ".change.label");
|
||||
},
|
||||
|
||||
_handleChoice: function () {
|
||||
let desc = document.getElementById("mergeChoiceRadio").selectedIndex;
|
||||
document.getElementById("chosenActionDeck").selectedIndex = desc;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
# Mike Connor <mconnor@mozilla.com>
|
||||
# Paul O’Shannessy <paul@oshannessy.com>
|
||||
# Philipp von Weitershausen <philipp@weitershausen.de>
|
||||
# Allison Naaktgeboren <ally@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
|
||||
|
@ -60,7 +61,6 @@
|
|||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
onwizardnext="return gSyncSetup.onWizardAdvance()"
|
||||
onwizardback="return gSyncSetup.onWizardBack()"
|
||||
onwizardfinish="gSyncSetup.onWizardFinish()"
|
||||
onwizardcancel="gSyncSetup.onWizardCancel()"
|
||||
onload="gSyncSetup.init()">
|
||||
|
||||
|
@ -511,24 +511,11 @@
|
|||
</vbox>
|
||||
</deck>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage label="&setup.successPage.title;"
|
||||
id="successfulSetup"
|
||||
onextra1="gSyncSetup.onSyncOptions()"
|
||||
onpageshow="gSyncSetup.onPageShow()">
|
||||
<vbox align="center">
|
||||
<image id="successPageIcon"/>
|
||||
</vbox>
|
||||
<separator/>
|
||||
<description class="normal">
|
||||
<html:span id="firstSyncAction">replace me</html:span>
|
||||
<html:strong id="firstSyncActionWarning">replace me</html:strong>
|
||||
<html:span id="firstSyncActionChange">replace me</html:span>
|
||||
</description>
|
||||
<description>
|
||||
&continueUsing.label;
|
||||
</description>
|
||||
<separator flex="1"/>
|
||||
# In terms of the wizard flow shown to the user, the 'syncOptionsConfirm'
|
||||
# page above is not the last wizard page. To prevent the wizard binding from
|
||||
# assuming that it is, we're inserting this dummy page here. This also means
|
||||
# that the wizard needs to always be closed manually via wizardFinish().
|
||||
<wizardpage>
|
||||
</wizardpage>
|
||||
</wizard>
|
||||
|
||||
|
|
|
@ -109,17 +109,8 @@ let gSyncUtils = {
|
|||
this._openLink(Weave.Svc.Prefs.get("privacyURL"));
|
||||
},
|
||||
|
||||
// xxxmpc - fix domain before 1.3 final (bug 583652)
|
||||
_baseURL: "http://www.mozilla.com/firefox/sync/",
|
||||
|
||||
openFirstClientFirstrun: function () {
|
||||
let url = this._baseURL + "firstrun.html";
|
||||
this._openLink(url);
|
||||
},
|
||||
|
||||
openAddedClientFirstrun: function () {
|
||||
let url = this._baseURL + "secondrun.html";
|
||||
this._openLink(url);
|
||||
openFirstSyncProgressPage: function () {
|
||||
this._openLink("about:sync-progress");
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -32,16 +32,6 @@ tabpanels {
|
|||
background-color: transparent;
|
||||
}
|
||||
|
||||
.tab-drag-preview {
|
||||
background: -moz-element(#content) left top;
|
||||
background-clip: content-box;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.tab-drag-panel[target] > .tab-drag-preview {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tab-drop-indicator {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
|
|
@ -245,6 +245,7 @@ _BROWSER_FILES = \
|
|||
test_wyciwyg_copying.html \
|
||||
authenticate.sjs \
|
||||
browser_minimize.js \
|
||||
browser_aboutSyncProgress.js \
|
||||
browser_middleMouse_inherit.js \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://services-sync/main.js");
|
||||
|
||||
let gTests = [ {
|
||||
desc: "Makes sure the progress bar appears if firstSync pref is set",
|
||||
setup: function () {
|
||||
Services.prefs.setCharPref("services.sync.firstSync", "newAccount");
|
||||
},
|
||||
run: function () {
|
||||
let doc = gBrowser.selectedTab.linkedBrowser.contentDocument;
|
||||
let progressBar = doc.getElementById("uploadProgressBar");
|
||||
|
||||
isnot(progressBar.style.display, "none", "progress bar should be visible");
|
||||
executeSoon(runNextTest);
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
desc: "Makes sure the progress bar is hidden if firstSync pref is not set",
|
||||
setup: function () {
|
||||
Services.prefs.clearUserPref("services.sync.firstSync");
|
||||
is(Services.prefs.getPrefType("services.sync.firstSync"),
|
||||
Ci.nsIPrefBranch.PREF_INVALID, "pref DNE" );
|
||||
},
|
||||
run: function () {
|
||||
let doc = gBrowser.selectedTab.linkedBrowser.contentDocument;
|
||||
let progressBar = doc.getElementById("uploadProgressBar");
|
||||
|
||||
is(progressBar.style.display, "none",
|
||||
"progress bar should not be visible");
|
||||
executeSoon(runNextTest);
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: "Makes sure the observer updates are reflected in the progress bar",
|
||||
setup: function () {
|
||||
},
|
||||
run: function () {
|
||||
let doc = gBrowser.selectedTab.linkedBrowser.contentDocument;
|
||||
let progressBar = doc.getElementById("uploadProgressBar");
|
||||
|
||||
Services.obs.notifyObservers(null, "weave:engine:sync:finish", null);
|
||||
Services.obs.notifyObservers(null, "weave:engine:sync:error", null);
|
||||
|
||||
let received = progressBar.getAttribute("value");
|
||||
|
||||
is(received, 2, "progress bar received correct notifications");
|
||||
executeSoon(runNextTest);
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: "Close button should close tab",
|
||||
setup: function (){
|
||||
},
|
||||
run: function () {
|
||||
function onTabClosed() {
|
||||
ok(true, "received TabClose notification");
|
||||
gBrowser.tabContainer.removeEventListener("TabClose", onTabClosed, false);
|
||||
executeSoon(runNextTest);
|
||||
}
|
||||
let doc = gBrowser.selectedTab.linkedBrowser.contentDocument;
|
||||
let button = doc.getElementById('closeButton');
|
||||
let window = doc.defaultView;
|
||||
gBrowser.tabContainer.addEventListener("TabClose", onTabClosed, false);
|
||||
EventUtils.sendMouseEvent({type: "click"}, button, window);
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
function test () {
|
||||
waitForExplicitFinish();
|
||||
executeSoon(runNextTest);
|
||||
}
|
||||
|
||||
function runNextTest()
|
||||
{
|
||||
while (gBrowser.tabs.length > 1) {
|
||||
gBrowser.removeCurrentTab();
|
||||
}
|
||||
|
||||
if (gTests.length) {
|
||||
let test = gTests.shift();
|
||||
info(test.desc);
|
||||
test.setup();
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab("about:sync-progress");
|
||||
tab.linkedBrowser.addEventListener("load", function (event) {
|
||||
tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
// Some part of the page is populated on load, so enqueue on it.
|
||||
executeSoon(test.run);
|
||||
}, true);
|
||||
}
|
||||
else {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
|
@ -36,8 +36,8 @@ function testPopupUI(win) {
|
|||
ok(win.gURLBar, "location bar exists in the popup");
|
||||
isnot(win.gURLBar.clientWidth, 0, "location bar is visible in the popup");
|
||||
ok(win.gURLBar.readOnly, "location bar is read-only in the popup");
|
||||
is(doc.getElementById("Browser:OpenLocation").getAttribute("disabled"), "true",
|
||||
"'open location' command is disabled in the popup");
|
||||
isnot(doc.getElementById("Browser:OpenLocation").getAttribute("disabled"), "true",
|
||||
"'open location' command is not disabled in the popup");
|
||||
|
||||
let historyButton = doc.getAnonymousElementByAttribute(win.gURLBar, "anonid",
|
||||
"historydropmarker");
|
||||
|
|
|
@ -247,6 +247,12 @@ function runTest(testNum) {
|
|||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
ok(true, "Starting test #" + testNum);
|
||||
|
||||
var inspectItems = [];
|
||||
if (SpecialPowers.getBoolPref("devtools.inspector.enabled")) {
|
||||
inspectItems = ["---", null,
|
||||
"context-inspect", true];
|
||||
}
|
||||
|
||||
switch (testNum) {
|
||||
case 1:
|
||||
// Invoke context menu for next test.
|
||||
|
@ -268,9 +274,8 @@ function runTest(testNum) {
|
|||
"context-selectall", true,
|
||||
"---", null,
|
||||
"context-viewsource", true,
|
||||
"context-viewinfo", true,
|
||||
"---", null,
|
||||
"context-inspect", true]);
|
||||
"context-viewinfo", true
|
||||
].concat(inspectItems));
|
||||
closeContextMenu();
|
||||
openContextMenuFor(link); // Invoke context menu for next test.
|
||||
break;
|
||||
|
@ -283,18 +288,15 @@ function runTest(testNum) {
|
|||
"context-bookmarklink", true,
|
||||
"context-savelink", true,
|
||||
"context-sendlink", true,
|
||||
"context-copylink", true,
|
||||
"---", null,
|
||||
"context-inspect", true]);
|
||||
"context-copylink", true
|
||||
].concat(inspectItems));
|
||||
closeContextMenu();
|
||||
openContextMenuFor(mailto); // Invoke context menu for next test.
|
||||
break;
|
||||
|
||||
case 4:
|
||||
// Context menu for text mailto-link
|
||||
checkContextMenu(["context-copyemail", true,
|
||||
"---", null,
|
||||
"context-inspect", true]);
|
||||
checkContextMenu(["context-copyemail", true].concat(inspectItems));
|
||||
closeContextMenu();
|
||||
openContextMenuFor(input); // Invoke context menu for next test.
|
||||
break;
|
||||
|
@ -310,9 +312,8 @@ function runTest(testNum) {
|
|||
"---", null,
|
||||
"context-selectall", false,
|
||||
"---", null,
|
||||
"spell-check-enabled", true,
|
||||
"---", null,
|
||||
"context-inspect", true]);
|
||||
"spell-check-enabled", true
|
||||
].concat(inspectItems));
|
||||
closeContextMenu();
|
||||
openContextMenuFor(img); // Invoke context menu for next test.
|
||||
break;
|
||||
|
@ -326,9 +327,8 @@ function runTest(testNum) {
|
|||
"context-saveimage", true,
|
||||
"context-sendimage", true,
|
||||
"context-setDesktopBackground", true,
|
||||
"context-viewimageinfo", true,
|
||||
"---", null,
|
||||
"context-inspect", true]);
|
||||
"context-viewimageinfo", true
|
||||
].concat(inspectItems));
|
||||
closeContextMenu();
|
||||
openContextMenuFor(canvas); // Invoke context menu for next test.
|
||||
break;
|
||||
|
@ -338,9 +338,8 @@ function runTest(testNum) {
|
|||
checkContextMenu(["context-viewimage", true,
|
||||
"context-saveimage", true,
|
||||
"context-bookmarkpage", true,
|
||||
"context-selectall", true,
|
||||
"---", null,
|
||||
"context-inspect", true]);
|
||||
"context-selectall", true
|
||||
].concat(inspectItems));
|
||||
closeContextMenu();
|
||||
openContextMenuFor(video_ok); // Invoke context menu for next test.
|
||||
break;
|
||||
|
@ -358,9 +357,8 @@ function runTest(testNum) {
|
|||
"---", null,
|
||||
"context-savevideo", true,
|
||||
"context-video-saveimage", true,
|
||||
"context-sendvideo", true,
|
||||
"---", null,
|
||||
"context-inspect", true]);
|
||||
"context-sendvideo", true
|
||||
].concat(inspectItems));
|
||||
closeContextMenu();
|
||||
openContextMenuFor(video_bad); // Invoke context menu for next test.
|
||||
break;
|
||||
|
@ -378,9 +376,8 @@ function runTest(testNum) {
|
|||
"---", null,
|
||||
"context-savevideo", true,
|
||||
"context-video-saveimage", false,
|
||||
"context-sendvideo", true,
|
||||
"---", null,
|
||||
"context-inspect", true]);
|
||||
"context-sendvideo", true
|
||||
].concat(inspectItems));
|
||||
closeContextMenu();
|
||||
openContextMenuFor(video_bad2); // Invoke context menu for next test.
|
||||
break;
|
||||
|
@ -398,9 +395,8 @@ function runTest(testNum) {
|
|||
"---", null,
|
||||
"context-savevideo", false,
|
||||
"context-video-saveimage", false,
|
||||
"context-sendvideo", false,
|
||||
"---", null,
|
||||
"context-inspect", true]);
|
||||
"context-sendvideo", false
|
||||
].concat(inspectItems));
|
||||
closeContextMenu();
|
||||
openContextMenuFor(iframe); // Invoke context menu for next test.
|
||||
break;
|
||||
|
@ -434,9 +430,8 @@ function runTest(testNum) {
|
|||
"context-viewframeinfo", true], null,
|
||||
"---", null,
|
||||
"context-viewsource", true,
|
||||
"context-viewinfo", true,
|
||||
"---", null,
|
||||
"context-inspect", true]);
|
||||
"context-viewinfo", true
|
||||
].concat(inspectItems));
|
||||
closeContextMenu();
|
||||
openContextMenuFor(textarea, false, true); // Invoke context menu for next test, but wait for the spellcheck.
|
||||
break;
|
||||
|
@ -460,8 +455,7 @@ function runTest(testNum) {
|
|||
["spell-check-dictionary-en-US", true,
|
||||
"---", null,
|
||||
"spell-add-dictionaries", true], null,
|
||||
"---", null,
|
||||
"context-inspect", true]);
|
||||
].concat(inspectItems));
|
||||
|
||||
closeContextMenu();
|
||||
openContextMenuFor(contenteditable); // Invoke context menu for next test.
|
||||
|
@ -485,9 +479,8 @@ function runTest(testNum) {
|
|||
"spell-dictionaries", true,
|
||||
["spell-check-dictionary-en-US", true,
|
||||
"---", null,
|
||||
"spell-add-dictionaries", true], null,
|
||||
"---", null,
|
||||
"context-inspect", true]);
|
||||
"spell-add-dictionaries", true], null
|
||||
].concat(inspectItems));
|
||||
|
||||
closeContextMenu();
|
||||
openContextMenuFor(inputspell); // Invoke context menu for next test.
|
||||
|
@ -511,9 +504,8 @@ function runTest(testNum) {
|
|||
"spell-dictionaries", true,
|
||||
["spell-check-dictionary-en-US", true,
|
||||
"---", null,
|
||||
"spell-add-dictionaries", true], null,
|
||||
"---", null,
|
||||
"context-inspect", true]);
|
||||
"spell-add-dictionaries", true], null
|
||||
].concat(inspectItems));
|
||||
|
||||
closeContextMenu();
|
||||
openContextMenuFor(link); // Invoke context menu for next test.
|
||||
|
@ -560,9 +552,8 @@ function runTest(testNum) {
|
|||
"context-selectall", true,
|
||||
"---", null,
|
||||
"context-viewsource", true,
|
||||
"context-viewinfo", true,
|
||||
"---", null,
|
||||
"context-inspect", true]);
|
||||
"context-viewinfo", true
|
||||
].concat(inspectItems));
|
||||
|
||||
invokeItemAction("0");
|
||||
closeContextMenu();
|
||||
|
@ -585,9 +576,8 @@ function runTest(testNum) {
|
|||
"context-selectall", true,
|
||||
"---", null,
|
||||
"context-viewsource", true,
|
||||
"context-viewinfo", true,
|
||||
"---", null,
|
||||
"context-inspect", true]);
|
||||
"context-viewinfo", true
|
||||
].concat(inspectItems));
|
||||
|
||||
subwindow.close();
|
||||
SimpleTest.finish();
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
// Services = object with smart getters for common XPCOM services
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
var TAB_DROP_TYPE = "application/x-moz-tabbrowser-tab";
|
||||
|
||||
var gBidiUI = false;
|
||||
|
||||
function getBrowserURL()
|
||||
|
|
|
@ -71,6 +71,8 @@ browser.jar:
|
|||
* content/browser/syncQuota.xul (content/syncQuota.xul)
|
||||
content/browser/syncQuota.js (content/syncQuota.js)
|
||||
content/browser/syncUtils.js (content/syncUtils.js)
|
||||
content/browser/syncProgress.js (content/syncProgress.js)
|
||||
* content/browser/syncProgress.xhtml (content/syncProgress.xhtml)
|
||||
#endif
|
||||
# XXX: We should exclude this one as well (bug 71895)
|
||||
* content/browser/hiddenWindow.xul (content/hiddenWindow.xul)
|
||||
|
|
|
@ -97,6 +97,8 @@ static RedirEntry kRedirMap[] = {
|
|||
{ "sessionrestore", "chrome://browser/content/aboutSessionRestore.xhtml",
|
||||
nsIAboutModule::ALLOW_SCRIPT },
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
{ "sync-progress", "chrome://browser/content/syncProgress.xhtml",
|
||||
nsIAboutModule::ALLOW_SCRIPT },
|
||||
{ "sync-tabs", "chrome://browser/content/aboutSyncTabs.xul",
|
||||
nsIAboutModule::ALLOW_SCRIPT },
|
||||
#endif
|
||||
|
|
|
@ -156,6 +156,7 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = {
|
|||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "sessionrestore", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "sync-tabs", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "sync-progress", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||
#endif
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "home", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "permissions", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||
|
|
|
@ -586,9 +586,6 @@ PlacesViewBase.prototype = {
|
|||
nodeKeywordChanged: function() { },
|
||||
sortingChanged: function() { },
|
||||
batching: function() { },
|
||||
// Replaced by containerStateChanged.
|
||||
containerOpened: function() { },
|
||||
containerClosed: function() { },
|
||||
|
||||
nodeInserted:
|
||||
function PVB_nodeInserted(aParentPlacesNode, aPlacesNode, aIndex) {
|
||||
|
|
|
@ -137,7 +137,6 @@ PlacesController.prototype = {
|
|||
},
|
||||
|
||||
supportsCommand: function PC_supportsCommand(aCommand) {
|
||||
//LOG("supportsCommand: " + command);
|
||||
// Non-Places specific commands that we also support
|
||||
switch (aCommand) {
|
||||
case "cmd_undo":
|
||||
|
@ -778,17 +777,6 @@ PlacesController.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Create a new Bookmark folder somewhere. Prompts the user for the name
|
||||
* of the folder.
|
||||
*/
|
||||
newFolder: function PC_newFolder() {
|
||||
Cu.reportError("PlacesController.newFolder is deprecated and will be \
|
||||
removed in a future release. Use newItem instead.");
|
||||
this.newItem("folder");
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a new Bookmark separator somewhere.
|
||||
*/
|
||||
|
@ -1403,13 +1391,17 @@ let PlacesControllerDragHelper = {
|
|||
|
||||
// Urls can be dropped on any insertionpoint.
|
||||
// XXXmano: remember that this method is called for each dragover event!
|
||||
// Thus we shouldn't use unwrapNodes here at all if possible. I think it
|
||||
// would be OK to accept bogus data here (this is not in our control and
|
||||
// will just case the actual drop to be a no-op) and only rule out valid
|
||||
// Thus we shouldn't use unwrapNodes here at all if possible.
|
||||
// I think it would be OK to accept bogus data here (e.g. text which was
|
||||
// somehow wrapped as TAB_DROP_TYPE, this is not in our control, and
|
||||
// will just case the actual drop to be a no-op), and only rule out valid
|
||||
// expected cases, which are either unsupported flavors, or items which
|
||||
// cannot be dropped in the current insertionpoint. The last case will
|
||||
// likely force us to use unwrapNodes for the private data types of
|
||||
// places.
|
||||
if (flavor == TAB_DROP_TYPE)
|
||||
continue;
|
||||
|
||||
let data = dt.mozGetDataAt(flavor, i);
|
||||
let dragged;
|
||||
try {
|
||||
|
@ -1523,8 +1515,21 @@ let PlacesControllerDragHelper = {
|
|||
|
||||
let data = dt.mozGetDataAt(flavor, i);
|
||||
let unwrapped;
|
||||
// There's only ever one in the D&D case.
|
||||
unwrapped = PlacesUtils.unwrapNodes(data, flavor)[0];
|
||||
if (flavor != TAB_DROP_TYPE) {
|
||||
// There's only ever one in the D&D case.
|
||||
unwrapped = PlacesUtils.unwrapNodes(data, flavor)[0];
|
||||
}
|
||||
else if (data instanceof XULElement && data.localName == "tab" &&
|
||||
data.ownerDocument.defaultView instanceof ChromeWindow) {
|
||||
let uri = data.linkedBrowser.currentURI;
|
||||
let spec = uri ? uri.spec : "about:blank";
|
||||
let title = data.label;
|
||||
unwrapped = { uri: spec,
|
||||
title: data.label,
|
||||
type: PlacesUtils.TYPE_X_MOZ_URL};
|
||||
}
|
||||
else
|
||||
throw("bogus data was passed as a tab")
|
||||
|
||||
let index = insertionPoint.index;
|
||||
|
||||
|
@ -1578,6 +1583,7 @@ let PlacesControllerDragHelper = {
|
|||
PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR,
|
||||
PlacesUtils.TYPE_X_MOZ_PLACE,
|
||||
PlacesUtils.TYPE_X_MOZ_URL,
|
||||
TAB_DROP_TYPE,
|
||||
PlacesUtils.TYPE_UNICODE],
|
||||
};
|
||||
|
||||
|
|
|
@ -90,7 +90,8 @@ PlacesTreeView.prototype = {
|
|||
selection.selectEventsSuppressed = true;
|
||||
|
||||
if (!this._rootNode.containerOpen) {
|
||||
// This triggers containerOpened which then builds the visible section.
|
||||
// This triggers containerStateChanged which then builds the visible
|
||||
// section.
|
||||
this._rootNode.containerOpen = true;
|
||||
}
|
||||
else
|
||||
|
@ -858,16 +859,10 @@ PlacesTreeView.prototype = {
|
|||
this._invalidateCellValue(aNode, this.COLUMN_TYPE_LASTMODIFIED);
|
||||
},
|
||||
|
||||
containerOpened: function PTV_containerOpened(aNode) {
|
||||
this.invalidateContainer(aNode);
|
||||
},
|
||||
|
||||
containerClosed: function PTV_containerClosed(aNode) {
|
||||
this.invalidateContainer(aNode);
|
||||
},
|
||||
|
||||
containerStateChanged:
|
||||
function PTV_containerStateChanged(aNode, aOldState, aNewState) {},
|
||||
function PTV_containerStateChanged(aNode, aOldState, aNewState) {
|
||||
this.invalidateContainer(aNode);
|
||||
},
|
||||
|
||||
invalidateContainer: function PTV_invalidateContainer(aContainer) {
|
||||
NS_ASSERT(this._result, "Need to have a result to update");
|
||||
|
|
|
@ -332,238 +332,6 @@ var PlacesUIUtils = {
|
|||
return null;
|
||||
},
|
||||
|
||||
_reportDeprecatedAddBookmarkMethod:
|
||||
function PUIU__reportDeprecatedAddBookmarkMethod() {
|
||||
// Removes "PUIU_".
|
||||
let oldFuncName = arguments.callee.caller.name.slice(5);
|
||||
Cu.reportError(oldFuncName + " is deprecated and will be removed in a " +
|
||||
"future release. Use showBookmarkDialog instead.");
|
||||
},
|
||||
|
||||
/**
|
||||
* This is here for compatibility reasons, use ShowBookmarkDialog instead.
|
||||
*/
|
||||
showAddBookmarkUI: function PUIU_showAddBookmarkUI(
|
||||
aURI, aTitle, aDescription, aDefaultInsertionPoint, aShowPicker,
|
||||
aLoadInSidebar, aKeyword, aPostData, aCharSet) {
|
||||
this._reportDeprecatedAddBookmarkMethod();
|
||||
|
||||
var info = {
|
||||
action: "add",
|
||||
type: "bookmark"
|
||||
};
|
||||
|
||||
if (aURI)
|
||||
info.uri = aURI;
|
||||
|
||||
// allow default empty title
|
||||
if (typeof(aTitle) == "string")
|
||||
info.title = aTitle;
|
||||
|
||||
if (aDescription)
|
||||
info.description = aDescription;
|
||||
|
||||
if (aDefaultInsertionPoint) {
|
||||
info.defaultInsertionPoint = aDefaultInsertionPoint;
|
||||
if (!aShowPicker)
|
||||
info.hiddenRows = ["folderPicker"];
|
||||
}
|
||||
|
||||
if (aLoadInSidebar)
|
||||
info.loadBookmarkInSidebar = true;
|
||||
|
||||
if (typeof(aKeyword) == "string") {
|
||||
info.keyword = aKeyword;
|
||||
if (typeof(aPostData) == "string")
|
||||
info.postData = aPostData;
|
||||
if (typeof(aCharSet) == "string")
|
||||
info.charSet = aCharSet;
|
||||
}
|
||||
|
||||
return this.showBookmarkDialog(info);
|
||||
},
|
||||
|
||||
/**
|
||||
* This is here for compatibility reasons, use ShowBookmarkDialog instead.
|
||||
*/
|
||||
showMinimalAddBookmarkUI:
|
||||
function PUIU_showMinimalAddBookmarkUI(
|
||||
aURI, aTitle, aDescription, aDefaultInsertionPoint, aShowPicker,
|
||||
aLoadInSidebar, aKeyword, aPostData, aCharSet) {
|
||||
this._reportDeprecatedAddBookmarkMethod();
|
||||
|
||||
var info = {
|
||||
action: "add",
|
||||
type: "bookmark",
|
||||
hiddenRows: ["description"]
|
||||
};
|
||||
if (aURI)
|
||||
info.uri = aURI;
|
||||
|
||||
// allow default empty title
|
||||
if (typeof(aTitle) == "string")
|
||||
info.title = aTitle;
|
||||
|
||||
if (aDescription)
|
||||
info.description = aDescription;
|
||||
|
||||
if (aDefaultInsertionPoint) {
|
||||
info.defaultInsertionPoint = aDefaultInsertionPoint;
|
||||
if (!aShowPicker)
|
||||
info.hiddenRows.push("folderPicker");
|
||||
}
|
||||
|
||||
if (aLoadInSidebar)
|
||||
info.loadBookmarkInSidebar = true;
|
||||
else
|
||||
info.hiddenRows = info.hiddenRows.concat(["location", "loadInSidebar"]);
|
||||
|
||||
if (typeof(aKeyword) == "string") {
|
||||
info.keyword = aKeyword;
|
||||
// Hide the Tags field if we are adding a keyword.
|
||||
info.hiddenRows.push("tags");
|
||||
// Keyword related params.
|
||||
if (typeof(aPostData) == "string")
|
||||
info.postData = aPostData;
|
||||
if (typeof(aCharSet) == "string")
|
||||
info.charSet = aCharSet;
|
||||
}
|
||||
else
|
||||
info.hiddenRows.push("keyword");
|
||||
|
||||
return this.showBookmarkDialog(info, undefined, true);
|
||||
},
|
||||
|
||||
/**
|
||||
* This is here for compatibility reasons, use ShowBookmarkDialog instead.
|
||||
*/
|
||||
showAddLivemarkUI: function PUIU_showAddLivemarkURI(aFeedURI,
|
||||
aSiteURI,
|
||||
aTitle,
|
||||
aDescription,
|
||||
aDefaultInsertionPoint,
|
||||
aShowPicker) {
|
||||
this._reportDeprecatedAddBookmarkMethod();
|
||||
|
||||
var info = {
|
||||
action: "add",
|
||||
type: "livemark"
|
||||
};
|
||||
|
||||
if (aFeedURI)
|
||||
info.feedURI = aFeedURI;
|
||||
if (aSiteURI)
|
||||
info.siteURI = aSiteURI;
|
||||
|
||||
// allow default empty title
|
||||
if (typeof(aTitle) == "string")
|
||||
info.title = aTitle;
|
||||
|
||||
if (aDescription)
|
||||
info.description = aDescription;
|
||||
|
||||
if (aDefaultInsertionPoint) {
|
||||
info.defaultInsertionPoint = aDefaultInsertionPoint;
|
||||
if (!aShowPicker)
|
||||
info.hiddenRows = ["folderPicker"];
|
||||
}
|
||||
return this.showBookmarkDialog(info);
|
||||
},
|
||||
|
||||
/**
|
||||
* This is here for compatibility reasons, use ShowBookmarkDialog instead.
|
||||
*/
|
||||
showMinimalAddLivemarkUI:
|
||||
function PUIU_showMinimalAddLivemarkURI(
|
||||
aFeedURI, aSiteURI, aTitle, aDescription, aDefaultInsertionPoint,
|
||||
aShowPicker) {
|
||||
|
||||
this._reportDeprecatedAddBookmarkMethod();
|
||||
|
||||
var info = {
|
||||
action: "add",
|
||||
type: "livemark",
|
||||
hiddenRows: ["feedLocation", "siteLocation", "description"]
|
||||
};
|
||||
|
||||
if (aFeedURI)
|
||||
info.feedURI = aFeedURI;
|
||||
if (aSiteURI)
|
||||
info.siteURI = aSiteURI;
|
||||
|
||||
// allow default empty title
|
||||
if (typeof(aTitle) == "string")
|
||||
info.title = aTitle;
|
||||
|
||||
if (aDescription)
|
||||
info.description = aDescription;
|
||||
|
||||
if (aDefaultInsertionPoint) {
|
||||
info.defaultInsertionPoint = aDefaultInsertionPoint;
|
||||
if (!aShowPicker)
|
||||
info.hiddenRows.push("folderPicker");
|
||||
}
|
||||
return this.showBookmarkDialog(info, undefined, true);
|
||||
},
|
||||
|
||||
/**
|
||||
* This is here for compatibility reasons, use ShowBookmarkDialog instead.
|
||||
*/
|
||||
showMinimalAddMultiBookmarkUI: function PUIU_showAddMultiBookmarkUI(aURIList) {
|
||||
this._reportDeprecatedAddBookmarkMethod();
|
||||
|
||||
if (aURIList.length == 0)
|
||||
throw("showAddMultiBookmarkUI expects a list of nsIURI objects");
|
||||
var info = {
|
||||
action: "add",
|
||||
type: "folder",
|
||||
hiddenRows: ["description"],
|
||||
URIList: aURIList
|
||||
};
|
||||
return this.showBookmarkDialog(info, undefined, true);
|
||||
},
|
||||
|
||||
/**
|
||||
* This is here for compatibility reasons, use ShowBookmarkDialog instead.
|
||||
*/
|
||||
showItemProperties: function PUIU_showItemProperties(aItemId, aType, aReadOnly) {
|
||||
this._reportDeprecatedAddBookmarkMethod();
|
||||
|
||||
var info = {
|
||||
action: "edit",
|
||||
type: aType,
|
||||
itemId: aItemId,
|
||||
readOnly: aReadOnly
|
||||
};
|
||||
return this.showBookmarkDialog(info);
|
||||
},
|
||||
|
||||
/**
|
||||
* This is here for compatibility reasons, use ShowBookmarkDialog instead.
|
||||
*/
|
||||
showAddFolderUI:
|
||||
function PUIU_showAddFolderUI(aTitle, aDefaultInsertionPoint, aShowPicker) {
|
||||
this._reportDeprecatedAddBookmarkMethod();
|
||||
|
||||
var info = {
|
||||
action: "add",
|
||||
type: "folder",
|
||||
hiddenRows: []
|
||||
};
|
||||
|
||||
// allow default empty title
|
||||
if (typeof(aTitle) == "string")
|
||||
info.title = aTitle;
|
||||
|
||||
if (aDefaultInsertionPoint) {
|
||||
info.defaultInsertionPoint = aDefaultInsertionPoint;
|
||||
if (!aShowPicker)
|
||||
info.hiddenRows.push("folderPicker");
|
||||
}
|
||||
return this.showBookmarkDialog(info);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Shows the bookmark dialog corresponding to the specified info.
|
||||
*
|
||||
|
|
|
@ -177,6 +177,9 @@ SessionStartup.prototype = {
|
|||
Services.obs.addObserver(this, "domwindowopened", true);
|
||||
|
||||
Services.obs.addObserver(this, "sessionstore-windows-restored", true);
|
||||
|
||||
if (this._sessionType != Ci.nsISessionStartup.NO_SESSION)
|
||||
Services.obs.addObserver(this, "browser:purge-session-history", true);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -197,6 +200,8 @@ SessionStartup.prototype = {
|
|||
// no reason for initializing at this point (cf. bug 409115)
|
||||
Services.obs.removeObserver(this, "final-ui-startup");
|
||||
Services.obs.removeObserver(this, "quit-application");
|
||||
if (this._sessionType != Ci.nsISessionStartup.NO_SESSION)
|
||||
Services.obs.removeObserver(this, "browser:purge-session-history");
|
||||
break;
|
||||
case "domwindowopened":
|
||||
var window = aSubject;
|
||||
|
@ -210,6 +215,10 @@ SessionStartup.prototype = {
|
|||
Services.obs.removeObserver(this, "sessionstore-windows-restored");
|
||||
// free _initialState after nsSessionStore is done with it
|
||||
this._initialState = null;
|
||||
break;
|
||||
case "browser:purge-session-history":
|
||||
Services.obs.removeObserver(this, "browser:purge-session-history");
|
||||
// reset all state on sanitization
|
||||
this._sessionType = Ci.nsISessionStartup.NO_SESSION;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -143,7 +143,7 @@ XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
|
|||
XPCOMUtils.defineLazyServiceGetter(this, "CookieSvc",
|
||||
"@mozilla.org/cookiemanager;1", "nsICookieManager2");
|
||||
|
||||
#ifdef MOZ_CRASH_REPORTER
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "CrashReporter",
|
||||
"@mozilla.org/xre/app-info;1", "nsICrashReporter");
|
||||
#endif
|
||||
|
@ -2481,7 +2481,19 @@ SessionStoreService.prototype = {
|
|||
if (ix != -1 && total[ix] && total[ix].sizemode == "minimized")
|
||||
ix = -1;
|
||||
|
||||
return { windows: total, selectedWindow: ix + 1, _closedWindows: lastClosedWindowsCopy };
|
||||
let session = {
|
||||
state: this._loadState == STATE_RUNNING ? STATE_RUNNING_STR : STATE_STOPPED_STR,
|
||||
lastUpdate: Date.now(),
|
||||
startTime: this._sessionStartTime,
|
||||
recentCrashes: this._recentCrashes
|
||||
};
|
||||
|
||||
return {
|
||||
windows: total,
|
||||
selectedWindow: ix + 1,
|
||||
_closedWindows: lastClosedWindowsCopy,
|
||||
session: session
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -2565,7 +2577,7 @@ SessionStoreService.prototype = {
|
|||
this._closedWindows = root._closedWindows;
|
||||
|
||||
var winData;
|
||||
if (!root.selectedWindow) {
|
||||
if (!root.selectedWindow || root.selectedWindow > root.windows.length) {
|
||||
root.selectedWindow = 0;
|
||||
} else {
|
||||
// put the selected window at the beginning of the array to ensure that
|
||||
|
@ -3263,31 +3275,48 @@ SessionStoreService.prototype = {
|
|||
if (!node)
|
||||
continue;
|
||||
|
||||
let eventType;
|
||||
let value = aData[key];
|
||||
if (typeof value == "string" && node.type != "file") {
|
||||
if (node.value == value)
|
||||
continue; // don't dispatch an input event for no change
|
||||
|
||||
node.value = value;
|
||||
|
||||
let event = aDocument.createEvent("UIEvents");
|
||||
event.initUIEvent("input", true, true, aDocument.defaultView, 0);
|
||||
node.dispatchEvent(event);
|
||||
eventType = "input";
|
||||
}
|
||||
else if (typeof value == "boolean")
|
||||
else if (typeof value == "boolean") {
|
||||
if (node.checked == value)
|
||||
continue; // don't dispatch a change event for no change
|
||||
|
||||
node.checked = value;
|
||||
else if (typeof value == "number")
|
||||
eventType = "change";
|
||||
}
|
||||
else if (typeof value == "number") {
|
||||
try {
|
||||
node.selectedIndex = value;
|
||||
eventType = "change";
|
||||
} catch (ex) { /* throws for invalid indices */ }
|
||||
else if (value && value.fileList && value.type == "file" && node.type == "file")
|
||||
}
|
||||
else if (value && value.fileList && value.type == "file" && node.type == "file") {
|
||||
node.mozSetFileNameArray(value.fileList, value.fileList.length);
|
||||
eventType = "input";
|
||||
}
|
||||
else if (value && typeof value.indexOf == "function" && node.options) {
|
||||
Array.forEach(node.options, function(aOpt, aIx) {
|
||||
aOpt.selected = value.indexOf(aIx) > -1;
|
||||
|
||||
// Only fire the event here if this wasn't selected by default
|
||||
if (!aOpt.defaultSelected)
|
||||
eventType = "change";
|
||||
});
|
||||
}
|
||||
// NB: dispatching "change" events might have unintended side-effects
|
||||
|
||||
// Fire events for this node if applicable
|
||||
if (eventType) {
|
||||
let event = aDocument.createEvent("UIEvents");
|
||||
event.initUIEvent(eventType, true, true, aDocument.defaultView, 0);
|
||||
node.dispatchEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3521,14 +3550,6 @@ SessionStoreService.prototype = {
|
|||
}
|
||||
}
|
||||
|
||||
oState.session = {
|
||||
state: this._loadState == STATE_RUNNING ? STATE_RUNNING_STR : STATE_STOPPED_STR,
|
||||
lastUpdate: Date.now(),
|
||||
startTime: this._sessionStartTime
|
||||
};
|
||||
if (this._recentCrashes)
|
||||
oState.session.recentCrashes = this._recentCrashes;
|
||||
|
||||
// Persist the last session if we deferred restoring it
|
||||
if (this._lastSessionState)
|
||||
oState.lastSessionState = this._lastSessionState;
|
||||
|
@ -3796,7 +3817,7 @@ SessionStoreService.prototype = {
|
|||
* Annotate a breakpad crash report with the currently selected tab's URL.
|
||||
*/
|
||||
_updateCrashReportURL: function sss_updateCrashReportURL(aWindow) {
|
||||
#ifdef MOZ_CRASH_REPORTER
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
try {
|
||||
var currentURI = aWindow.gBrowser.currentURI.clone();
|
||||
// if the current URI contains a username/password, remove it
|
||||
|
|
|
@ -50,6 +50,8 @@ include $(topsrcdir)/config/rules.mk
|
|||
|
||||
_BROWSER_TEST_FILES = \
|
||||
head.js \
|
||||
browser_form_restore_events.js \
|
||||
browser_form_restore_events_sample.html \
|
||||
browser_248970_a.js \
|
||||
browser_248970_b.js \
|
||||
browser_248970_b_sample.html \
|
||||
|
@ -98,8 +100,6 @@ _BROWSER_TEST_FILES = \
|
|||
browser_465223.js \
|
||||
browser_466937.js \
|
||||
browser_466937_sample.html \
|
||||
browser_476161.js \
|
||||
browser_476161_sample.html \
|
||||
browser_477657.js \
|
||||
browser_480148.js \
|
||||
browser_480893.js \
|
||||
|
@ -152,7 +152,9 @@ _BROWSER_TEST_FILES = \
|
|||
browser_645428.js \
|
||||
browser_659591.js \
|
||||
browser_662812.js \
|
||||
browser_665702-state_session.js \
|
||||
browser_682507.js \
|
||||
browser_694378.js \
|
||||
$(NULL)
|
||||
|
||||
ifneq ($(OS_ARCH),Darwin)
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Test for bug 476161</title>
|
||||
|
||||
<script>
|
||||
|
||||
document.addEventListener("input", function(aEvent) {
|
||||
var inputEl = aEvent.originalTarget;
|
||||
var changedEl = document.getElementById("changed");
|
||||
|
||||
changedEl.textContent += " " + inputEl.id;
|
||||
}, false);
|
||||
|
||||
</script>
|
||||
|
||||
<h3>Text fields with changed text</h3>
|
||||
<input type="text" id="modify1">
|
||||
<input type="text" id="modify2" value="preset value">
|
||||
|
||||
<h3>Text fields with unchanged text</h3>
|
||||
<input type="text" id="unchanged1">
|
||||
<input type="text" id="unchanged2" value="preset value">
|
||||
|
||||
<h3>Changed field IDs</h3>
|
||||
<div id="changed"></div>
|
|
@ -0,0 +1,24 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function compareArray(a, b) {
|
||||
if (a.length !== b.length) {
|
||||
return false;
|
||||
}
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
if (a[i] !== b[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function test() {
|
||||
let currentState = JSON.parse(ss.getBrowserState());
|
||||
ok(currentState.session, "session data returned by getBrowserState");
|
||||
|
||||
let keys = Object.keys(currentState.session);
|
||||
let expectedKeys = ["state", "lastUpdate", "startTime", "recentCrashes"];
|
||||
ok(compareArray(keys.sort(), expectedKeys.sort()),
|
||||
"session object from getBrowserState has correct keys");
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test Summary:
|
||||
// 1. call ss.setWindowState with a broken state
|
||||
// 1a. ensure that it doesn't throw.
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
let brokenState = {
|
||||
windows: [
|
||||
{ tabs: [{ entries: [{ url: "about:mozilla" }] }] }
|
||||
//{ tabs: [{ entries: [{ url: "about:robots" }] }] },
|
||||
],
|
||||
selectedWindow: 2
|
||||
};
|
||||
let brokenStateString = JSON.stringify(brokenState);
|
||||
|
||||
let gotError = false;
|
||||
try {
|
||||
ss.setWindowState(window, brokenStateString, true);
|
||||
}
|
||||
catch (ex) {
|
||||
gotError = true;
|
||||
info(ex);
|
||||
}
|
||||
|
||||
ok(!gotError, "ss.setWindowState did not throw an error");
|
||||
|
||||
// Make sure that we reset the state. Use a full state just in case things get crazy.
|
||||
let blankState = { windows: [{ tabs: [{ entries: [{ url: "about:blank" }] }]}]};
|
||||
waitForBrowserState(blankState, finish);
|
||||
}
|
||||
|
|
@ -35,33 +35,64 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 476161 **/
|
||||
|
||||
/** Originally a test for Bug 476161, but then expanded to include all input types in bug 640136 **/
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
|
||||
let file = Components.classes["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Components.interfaces.nsIProperties)
|
||||
.get("TmpD", Components.interfaces.nsIFile);
|
||||
|
||||
let testURL = "http://mochi.test:8888/browser/" +
|
||||
"browser/components/sessionstore/test/browser/browser_476161_sample.html";
|
||||
"browser/components/sessionstore/test/browser/browser_form_restore_events_sample.html";
|
||||
let tab = gBrowser.addTab(testURL);
|
||||
tab.linkedBrowser.addEventListener("load", function(aEvent) {
|
||||
tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
let doc = tab.linkedBrowser.contentDocument;
|
||||
|
||||
doc.getElementById("modify1").value += Math.random();
|
||||
doc.getElementById("modify2").value += " " + Date.now();
|
||||
|
||||
|
||||
// text fields
|
||||
doc.getElementById("modify01").value += Math.random();
|
||||
doc.getElementById("modify02").value += " " + Date.now();
|
||||
|
||||
// textareas
|
||||
doc.getElementById("modify03").value += Math.random();
|
||||
doc.getElementById("modify04").value += " " + Date.now();
|
||||
|
||||
// file
|
||||
doc.getElementById("modify05").value = file.path;
|
||||
|
||||
// select
|
||||
doc.getElementById("modify06").selectedIndex = 1;
|
||||
var multipleChange = doc.getElementById("modify07");
|
||||
Array.forEach(multipleChange.options, function(option) option.selected = true);
|
||||
|
||||
// checkbox
|
||||
doc.getElementById("modify08").checked = true;
|
||||
doc.getElementById("modify09").checked = false;
|
||||
|
||||
// radio
|
||||
// select one then another in the same group - only last one should get event on restore
|
||||
doc.getElementById("modify10").checked = true;
|
||||
doc.getElementById("modify11").checked = true;
|
||||
|
||||
|
||||
let tab2 = gBrowser.duplicateTab(tab);
|
||||
tab2.linkedBrowser.addEventListener("load", function(aEvent) {
|
||||
tab2.linkedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
let doc = tab2.linkedBrowser.contentDocument;
|
||||
let changed = doc.getElementById("changed").textContent.trim().split();
|
||||
|
||||
is(changed.sort().join(" "), "modify1 modify2",
|
||||
"input events were only dispatched for modified text fields");
|
||||
|
||||
let inputFired = doc.getElementById("inputFired").textContent.trim().split();
|
||||
let changeFired = doc.getElementById("changeFired").textContent.trim().split();
|
||||
|
||||
is(inputFired.sort().join(" "), "modify01 modify02 modify03 modify04 modify05",
|
||||
"input events were only dispatched for modified input, textarea fields");
|
||||
|
||||
is(changeFired.sort().join(" "), "modify06 unchanged06 modify07 modify08 modify09 modify11",
|
||||
"change events were only dispatched for modified select, checkbox, radio fields");
|
||||
|
||||
// clean up
|
||||
gBrowser.removeTab(tab2);
|
||||
gBrowser.removeTab(tab);
|
||||
|
||||
|
||||
finish();
|
||||
}, true);
|
||||
}, true);
|
|
@ -0,0 +1,98 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Test for form restore events (originally bug 476161)</title>
|
||||
|
||||
<script>
|
||||
|
||||
document.addEventListener("input", function(aEvent) {
|
||||
var inputEl = aEvent.originalTarget;
|
||||
var changedEl = document.getElementById("inputFired");
|
||||
changedEl.textContent += " " + inputEl.id;
|
||||
}, false);
|
||||
|
||||
document.addEventListener("change", function(aEvent) {
|
||||
var inputEl = aEvent.originalTarget;
|
||||
var changedEl = document.getElementById("changeFired");
|
||||
changedEl.textContent += " " + inputEl.id;
|
||||
}, false);
|
||||
|
||||
</script>
|
||||
|
||||
<!-- input events -->
|
||||
<h3>Text fields with changed text</h3>
|
||||
<input type="text" id="modify1">
|
||||
<input type="text" id="modify2" value="preset value">
|
||||
<input type="text" id="modify01">
|
||||
<input type="text" id="modify02" value="preset value">
|
||||
|
||||
<h3>Text fields with unchanged text</h3>
|
||||
<input type="text" id="unchanged1">
|
||||
<input type="text" id="unchanged2" value="preset value">
|
||||
<input type="text" id="unchanged01">
|
||||
<input type="text" id="unchanged02" value="preset value">
|
||||
|
||||
<h3>Textarea with changed text</h3>
|
||||
<textarea id="modify03"></textarea>
|
||||
<textarea id="modify04">preset value</textarea>
|
||||
|
||||
<h3>Textarea with unchanged text</h3>
|
||||
<textarea id="unchanged03"></textarea>
|
||||
<textarea id="unchanged04">preset value</textarea>
|
||||
|
||||
<h3>file field with changed value</h3>
|
||||
<input type="file" id="modify05">
|
||||
|
||||
<h3>file field with unchanged value</h3>
|
||||
<input type="file" id="unchanged05">
|
||||
|
||||
<!-- change events -->
|
||||
|
||||
<h3>Select menu with changed selection</h3>
|
||||
<select id="modify06">
|
||||
<option value="one">one</option>
|
||||
<option value="two">two</option>
|
||||
<option value="three">three</option>
|
||||
</select>
|
||||
|
||||
<h3>Select menu with unchanged selection (change event still fires)</h3>
|
||||
<select id="unchanged06">
|
||||
<option value="one">one</option>
|
||||
<option value="two" selected>two</option>
|
||||
<option value="three">three</option>
|
||||
</select>
|
||||
|
||||
<h3>Multiple Select menu with changed selection</h3>
|
||||
<select id="modify07" multiple>
|
||||
<option value="one">one</option>
|
||||
<option value="two" selected>two</option>
|
||||
<option value="three">three</option>
|
||||
</select>
|
||||
|
||||
<h3>Select menu with unchanged selection</h3>
|
||||
<select id="unchanged07" multiple>
|
||||
<option value="one">one</option>
|
||||
<option value="two" selected>two</option>
|
||||
<option value="three" selected>three</option>
|
||||
</select>
|
||||
|
||||
<h3>checkbox with changed value</h3>
|
||||
<input type="checkbox" id="modify08">
|
||||
<input type="checkbox" id="modify09" checked>
|
||||
|
||||
<h3>checkbox with unchanged value</h3>
|
||||
<input type="checkbox" id="unchanged08">
|
||||
<input type="checkbox" id="unchanged09" checked>
|
||||
|
||||
<h3>radio with changed value</h3>
|
||||
<input type="radio" id="modify10" name="group">Radio 1</input>
|
||||
<input type="radio" id="modify11" name="group">Radio 2</input>
|
||||
<input type="radio" id="modify12" name="group" checked>Radio 3</input>
|
||||
|
||||
<h3>radio with unchanged value</h3>
|
||||
<input type="radio" id="unchanged10" name="group2">Radio 4</input>
|
||||
<input type="radio" id="unchanged11" name="group2">Radio 5</input>
|
||||
<input type="radio" id="unchanged12" name="group2" checked>Radio 6</input>
|
||||
|
||||
<h3>Changed field IDs</h3>
|
||||
<div id="changed"></div>
|
||||
<div id="inputFired"></div>
|
||||
<div id="changeFired"></div>
|
|
@ -230,7 +230,14 @@ TreePanel.prototype = {
|
|||
treeBox.minHeight = 10;
|
||||
treeBox.flex = 1;
|
||||
toolbarParent.insertBefore(treeBox, toolbar);
|
||||
this.createResizer();
|
||||
|
||||
let resizerTop =
|
||||
this.IUI.browser.ownerDocument.getElementById("inspector-top-resizer");
|
||||
let resizerEnd =
|
||||
this.IUI.browser.ownerDocument.getElementById("inspector-end-resizer");
|
||||
resizerTop.removeAttribute("disabled");
|
||||
resizerEnd.removeAttribute("disabled");
|
||||
|
||||
treeBox.appendChild(this.treeIFrame);
|
||||
|
||||
let boundLoadedInitializeTreePanel = function loadedInitializeTreePanel()
|
||||
|
@ -251,28 +258,19 @@ TreePanel.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Lame resizer on the toolbar.
|
||||
*/
|
||||
createResizer: function TP_createResizer()
|
||||
{
|
||||
let resizer = this.document.createElement("resizer");
|
||||
resizer.id = "inspector-horizontal-splitter";
|
||||
resizer.setAttribute("dir", "top");
|
||||
resizer.flex = 1;
|
||||
resizer.setAttribute("element", "inspector-tree-box");
|
||||
resizer.height = 24;
|
||||
this.IUI.toolbar.appendChild(resizer);
|
||||
this.resizer = resizer;
|
||||
},
|
||||
|
||||
/**
|
||||
* Close the TreePanel.
|
||||
*/
|
||||
close: function TP_close()
|
||||
{
|
||||
if (this.openInDock) {
|
||||
this.IUI.toolbar.removeChild(this.resizer);
|
||||
let resizerTop =
|
||||
this.IUI.browser.ownerDocument.getElementById("inspector-top-resizer");
|
||||
let resizerEnd =
|
||||
this.IUI.browser.ownerDocument.getElementById("inspector-end-resizer");
|
||||
resizerTop.setAttribute("disabled", "true");
|
||||
resizerEnd.setAttribute("disabled", "true");
|
||||
|
||||
let treeBox = this.container;
|
||||
let treeBoxParent = treeBox.parentNode;
|
||||
treeBoxParent.removeChild(treeBox);
|
||||
|
@ -679,8 +677,6 @@ TreePanel.prototype = {
|
|||
|
||||
domplateUtils.setDOM(null);
|
||||
|
||||
delete this.resizer;
|
||||
|
||||
if (this.DOMHelpers) {
|
||||
this.DOMHelpers.destroy();
|
||||
delete this.DOMHelpers;
|
||||
|
|
|
@ -49,6 +49,7 @@ var EXPORTED_SYMBOLS = ["InspectorUI"];
|
|||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource:///modules/TreePanel.jsm");
|
||||
|
||||
const INSPECTOR_INVISIBLE_ELEMENTS = {
|
||||
"head": true,
|
||||
|
@ -874,9 +875,8 @@ InspectorUI.prototype = {
|
|||
|
||||
this.initTools();
|
||||
|
||||
if (!this.TreePanel && this.treePanelEnabled) {
|
||||
Cu.import("resource:///modules/TreePanel.jsm", this);
|
||||
this.treePanel = new this.TreePanel(this.chromeWin, this);
|
||||
if (this.treePanelEnabled) {
|
||||
this.treePanel = new TreePanel(this.chromeWin, this);
|
||||
}
|
||||
|
||||
if (Services.prefs.getBoolPref("devtools.styleinspector.enabled") &&
|
||||
|
@ -887,6 +887,9 @@ InspectorUI.prototype = {
|
|||
this.toolbar.hidden = false;
|
||||
this.inspectMenuitem.setAttribute("checked", true);
|
||||
|
||||
// initialize the HTML Breadcrumbs
|
||||
this.breadcrumbs = new HTMLBreadcrumbs(this);
|
||||
|
||||
this.isDirty = false;
|
||||
|
||||
this.progressListener = new InspectorProgressListener(this);
|
||||
|
@ -999,6 +1002,11 @@ InspectorUI.prototype = {
|
|||
this.highlighter = null;
|
||||
}
|
||||
|
||||
if (this.breadcrumbs) {
|
||||
this.breadcrumbs.destroy();
|
||||
this.breadcrumbs = null;
|
||||
}
|
||||
|
||||
this.inspectMenuitem.setAttribute("checked", false);
|
||||
this.browser = this.win = null; // null out references to browser and window
|
||||
this.winID = null;
|
||||
|
@ -1009,7 +1017,6 @@ InspectorUI.prototype = {
|
|||
delete this.treePanel;
|
||||
delete this.stylePanel;
|
||||
delete this.toolbar;
|
||||
delete this.TreePanel;
|
||||
Services.obs.notifyObservers(null, INSPECTOR_NOTIFICATIONS.CLOSED, null);
|
||||
},
|
||||
|
||||
|
@ -1093,6 +1100,8 @@ InspectorUI.prototype = {
|
|||
}
|
||||
}
|
||||
|
||||
this.breadcrumbs.update();
|
||||
|
||||
this.toolsSelect(aScroll);
|
||||
},
|
||||
|
||||
|
@ -1888,13 +1897,463 @@ InspectorProgressListener.prototype = {
|
|||
},
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//// HTML Breadcrumbs
|
||||
|
||||
/**
|
||||
* Display the ancestors of the current node and its children.
|
||||
* Only one "branch" of children are displayed (only one line).
|
||||
*
|
||||
* Mechanism:
|
||||
* . If no nodes displayed yet:
|
||||
* then display the ancestor of the selected node and the selected node;
|
||||
* else select the node;
|
||||
* . If the selected node is the last node displayed, append its first (if any).
|
||||
*
|
||||
* @param object aInspector
|
||||
* The InspectorUI instance.
|
||||
*/
|
||||
function HTMLBreadcrumbs(aInspector)
|
||||
{
|
||||
this.IUI = aInspector;
|
||||
this.DOMHelpers = new DOMHelpers(this.IUI.win);
|
||||
this._init();
|
||||
}
|
||||
|
||||
HTMLBreadcrumbs.prototype = {
|
||||
_init: function BC__init()
|
||||
{
|
||||
this.container = this.IUI.chromeDoc.getElementById("inspector-breadcrumbs");
|
||||
this.container.addEventListener("mousedown", this, true);
|
||||
|
||||
// We will save a list of already displayed nodes in this array.
|
||||
this.nodeHierarchy = [];
|
||||
|
||||
// Last selected node in nodeHierarchy.
|
||||
this.currentIndex = -1;
|
||||
|
||||
// Siblings menu
|
||||
this.menu = this.IUI.chromeDoc.createElement("menupopup");
|
||||
this.menu.id = "inspector-breadcrumbs-menu";
|
||||
|
||||
let popupSet = this.IUI.chromeDoc.getElementById("mainPopupSet");
|
||||
popupSet.appendChild(this.menu);
|
||||
|
||||
this.menu.addEventListener("popuphiding", (function() {
|
||||
while (this.menu.hasChildNodes()) {
|
||||
this.menu.removeChild(this.menu.firstChild);
|
||||
}
|
||||
let button = this.container.querySelector("button[siblings-menu-open]");
|
||||
button.removeAttribute("siblings-menu-open");
|
||||
}).bind(this), false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Build a string that represents the node: tagName#id.class1.class2.
|
||||
*
|
||||
* @param aNode The node to pretty-print
|
||||
* @returns a string
|
||||
*/
|
||||
prettyPrintNodeAsText: function BC_prettyPrintNodeText(aNode)
|
||||
{
|
||||
let text = aNode.tagName.toLowerCase();
|
||||
if (aNode.id) {
|
||||
text += "#" + aNode.id;
|
||||
}
|
||||
for (let i = 0; i < aNode.classList.length; i++) {
|
||||
text += "." + aNode.classList[i];
|
||||
}
|
||||
return text;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Build <label>s that represent the node:
|
||||
* <label class="inspector-breadcrumbs-tag">tagName</label>
|
||||
* <label class="inspector-breadcrumbs-id">#id</label>
|
||||
* <label class="inspector-breadcrumbs-classes">.class1.class2</label>
|
||||
*
|
||||
* @param aNode The node to pretty-print
|
||||
* @returns a document fragment.
|
||||
*/
|
||||
prettyPrintNodeAsXUL: function BC_prettyPrintNodeXUL(aNode)
|
||||
{
|
||||
let fragment = this.IUI.chromeDoc.createDocumentFragment();
|
||||
|
||||
let tagLabel = this.IUI.chromeDoc.createElement("label");
|
||||
tagLabel.className = "inspector-breadcrumbs-tag plain";
|
||||
|
||||
let idLabel = this.IUI.chromeDoc.createElement("label");
|
||||
idLabel.className = "inspector-breadcrumbs-id plain";
|
||||
|
||||
let classesLabel = this.IUI.chromeDoc.createElement("label");
|
||||
classesLabel.className = "inspector-breadcrumbs-classes plain";
|
||||
|
||||
tagLabel.textContent = aNode.tagName.toLowerCase();
|
||||
idLabel.textContent = aNode.id ? ("#" + aNode.id) : "";
|
||||
|
||||
let classesText = "";
|
||||
for (let i = 0; i < aNode.classList.length; i++) {
|
||||
classesText += "." + aNode.classList[i];
|
||||
}
|
||||
classesLabel.textContent = classesText;
|
||||
|
||||
fragment.appendChild(tagLabel);
|
||||
fragment.appendChild(idLabel);
|
||||
fragment.appendChild(classesLabel);
|
||||
|
||||
return fragment;
|
||||
},
|
||||
|
||||
/**
|
||||
* Open the sibling menu.
|
||||
*
|
||||
* @param aButton the button representing the node.
|
||||
* @param aNode the node we want the siblings from.
|
||||
*/
|
||||
openSiblingMenu: function BC_openSiblingMenu(aButton, aNode)
|
||||
{
|
||||
let title = this.IUI.chromeDoc.createElement("menuitem");
|
||||
title.setAttribute("label",
|
||||
this.IUI.strings.GetStringFromName("breadcrumbs.siblings"));
|
||||
title.setAttribute("disabled", "true");
|
||||
|
||||
let separator = this.IUI.chromeDoc.createElement("menuseparator");
|
||||
|
||||
this.menu.appendChild(title);
|
||||
this.menu.appendChild(separator);
|
||||
|
||||
let fragment = this.IUI.chromeDoc.createDocumentFragment();
|
||||
|
||||
let nodes = aNode.parentNode.childNodes;
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
if (nodes[i].nodeType == aNode.ELEMENT_NODE) {
|
||||
let item = this.IUI.chromeDoc.createElement("menuitem");
|
||||
let inspector = this.IUI;
|
||||
if (nodes[i] === aNode) {
|
||||
item.setAttribute("disabled", "true");
|
||||
item.setAttribute("checked", "true");
|
||||
}
|
||||
|
||||
item.setAttribute("type", "radio");
|
||||
item.setAttribute("label", this.prettyPrintNodeAsText(nodes[i]));
|
||||
|
||||
item.onmouseup = (function(aNode) {
|
||||
return function() {
|
||||
inspector.select(aNode, true, true);
|
||||
}
|
||||
})(nodes[i]);
|
||||
|
||||
fragment.appendChild(item);
|
||||
}
|
||||
}
|
||||
this.menu.appendChild(fragment);
|
||||
this.menu.openPopup(aButton, "before_start", 0, 0, true, false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Generic event handler.
|
||||
*
|
||||
* @param nsIDOMEvent aEvent
|
||||
* The DOM event object.
|
||||
*/
|
||||
handleEvent: function BC_handleEvent(aEvent)
|
||||
{
|
||||
if (aEvent.type == "mousedown") {
|
||||
// on Click and Hold, open the Siblings menu
|
||||
|
||||
let timer;
|
||||
let container = this.container;
|
||||
let window = this.IUI.win;
|
||||
|
||||
function openMenu(aEvent) {
|
||||
cancelHold();
|
||||
let target = aEvent.originalTarget;
|
||||
if (target.tagName == "button") {
|
||||
target.onBreadcrumbsHold();
|
||||
target.setAttribute("siblings-menu-open", "true");
|
||||
}
|
||||
}
|
||||
|
||||
function handleClick(aEvent) {
|
||||
cancelHold();
|
||||
let target = aEvent.originalTarget;
|
||||
if (target.tagName == "button") {
|
||||
target.onBreadcrumbsClick();
|
||||
}
|
||||
}
|
||||
|
||||
function cancelHold(aEvent) {
|
||||
window.clearTimeout(timer);
|
||||
container.removeEventListener("mouseout", cancelHold, false);
|
||||
container.removeEventListener("mouseup", handleClick, false);
|
||||
}
|
||||
|
||||
container.addEventListener("mouseout", cancelHold, false);
|
||||
container.addEventListener("mouseup", handleClick, false);
|
||||
timer = window.setTimeout(openMenu, 500, aEvent);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove nodes and delete properties.
|
||||
*/
|
||||
destroy: function BC_destroy()
|
||||
{
|
||||
this.empty();
|
||||
this.container.removeEventListener("mousedown", this, true);
|
||||
this.menu.parentNode.removeChild(this.menu);
|
||||
this.container = null;
|
||||
this.nodeHierarchy = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Empty the breadcrumbs container.
|
||||
*/
|
||||
empty: function BC_empty()
|
||||
{
|
||||
while (this.container.hasChildNodes()) {
|
||||
this.container.removeChild(this.container.firstChild);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Re-init the cache and remove all the buttons.
|
||||
*/
|
||||
invalidateHierarchy: function BC_invalidateHierarchy()
|
||||
{
|
||||
this.menu.hidePopup();
|
||||
this.nodeHierarchy = [];
|
||||
this.empty();
|
||||
},
|
||||
|
||||
/**
|
||||
* Set which button represent the selected node.
|
||||
*
|
||||
* @param aIdx Index of the displayed-button to select
|
||||
*/
|
||||
setCursor: function BC_setCursor(aIdx)
|
||||
{
|
||||
// Unselect the previously selected button
|
||||
if (this.currentIndex > -1 && this.currentIndex < this.nodeHierarchy.length) {
|
||||
this.nodeHierarchy[this.currentIndex].button.removeAttribute("checked");
|
||||
}
|
||||
if (aIdx > -1) {
|
||||
this.nodeHierarchy[aIdx].button.setAttribute("checked", "true");
|
||||
}
|
||||
this.currentIndex = aIdx;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the index of the node in the cache.
|
||||
*
|
||||
* @param aNode
|
||||
* @returns integer the index, -1 if not found
|
||||
*/
|
||||
indexOf: function BC_indexOf(aNode)
|
||||
{
|
||||
let i = this.nodeHierarchy.length - 1;
|
||||
for (let i = this.nodeHierarchy.length - 1; i >= 0; i--) {
|
||||
if (this.nodeHierarchy[i].node === aNode) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove all the buttons and their references in the cache
|
||||
* after a given index.
|
||||
*
|
||||
* @param aIdx
|
||||
*/
|
||||
cutAfter: function BC_cutAfter(aIdx)
|
||||
{
|
||||
while (this.nodeHierarchy.length > (aIdx + 1)) {
|
||||
let toRemove = this.nodeHierarchy.pop();
|
||||
this.container.removeChild(toRemove.button);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Build a button representing the node.
|
||||
*
|
||||
* @param aNode The node from the page.
|
||||
* @returns aNode The <button>.
|
||||
*/
|
||||
buildButton: function BC_buildButton(aNode)
|
||||
{
|
||||
let button = this.IUI.chromeDoc.createElement("button");
|
||||
let inspector = this.IUI;
|
||||
button.appendChild(this.prettyPrintNodeAsXUL(aNode));
|
||||
button.className = "inspector-breadcrumbs-button";
|
||||
|
||||
button.setAttribute("tooltiptext", this.prettyPrintNodeAsText(aNode));
|
||||
|
||||
button.onBreadcrumbsClick = function onBreadcrumbsClick() {
|
||||
inspector.stopInspecting();
|
||||
inspector.select(aNode, true, true);
|
||||
};
|
||||
|
||||
button.onclick = (function _onBreadcrumbsRightClick(aEvent) {
|
||||
if (aEvent.button == 2) {
|
||||
this.openSiblingMenu(button, aNode);
|
||||
}
|
||||
}).bind(this);
|
||||
|
||||
button.onBreadcrumbsHold = (function _onBreadcrumbsHold() {
|
||||
this.openSiblingMenu(button, aNode);
|
||||
}).bind(this);
|
||||
return button;
|
||||
},
|
||||
|
||||
/**
|
||||
* Connecting the end of the breadcrumbs to a node.
|
||||
*
|
||||
* @param aNode The node to reach.
|
||||
*/
|
||||
expand: function BC_expand(aNode)
|
||||
{
|
||||
let fragment = this.IUI.chromeDoc.createDocumentFragment();
|
||||
let toAppend = aNode;
|
||||
let lastButtonInserted = null;
|
||||
let originalLength = this.nodeHierarchy.length;
|
||||
let stopNode = null;
|
||||
if (originalLength > 0) {
|
||||
stopNode = this.nodeHierarchy[originalLength - 1].node;
|
||||
}
|
||||
while (toAppend && toAppend.tagName && toAppend != stopNode) {
|
||||
let button = this.buildButton(toAppend);
|
||||
fragment.insertBefore(button, lastButtonInserted);
|
||||
lastButtonInserted = button;
|
||||
this.nodeHierarchy.splice(originalLength, 0, {node: toAppend, button: button});
|
||||
toAppend = this.DOMHelpers.getParentObject(toAppend);
|
||||
}
|
||||
this.container.appendChild(fragment, this.container.firstChild);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get a child of a node that can be displayed in the breadcrumbs.
|
||||
* By default, we want a node that can highlighted by the highlighter.
|
||||
* If no highlightable child is found, we return the first node of type
|
||||
* ELEMENT_NODE.
|
||||
*
|
||||
* @param aNode The parent node.
|
||||
* @returns nsIDOMNode|null
|
||||
*/
|
||||
getFirstHighlightableChild: function BC_getFirstHighlightableChild(aNode)
|
||||
{
|
||||
let nextChild = this.DOMHelpers.getChildObject(aNode, 0);
|
||||
let fallback = null;
|
||||
|
||||
while (nextChild) {
|
||||
if (this.IUI.highlighter.isNodeHighlightable(nextChild)) {
|
||||
return nextChild;
|
||||
}
|
||||
if (!fallback && nextChild.nodeType == aNode.ELEMENT_NODE) {
|
||||
fallback = nextChild;
|
||||
}
|
||||
nextChild = this.DOMHelpers.getNextSibling(nextChild);
|
||||
}
|
||||
return fallback;
|
||||
},
|
||||
|
||||
/**
|
||||
* Find the "youngest" ancestor of a node which is already in the breadcrumbs.
|
||||
*
|
||||
* @param aNode
|
||||
* @returns Index of the ancestor in the cache
|
||||
*/
|
||||
getCommonAncestor: function BC_getCommonAncestor(aNode)
|
||||
{
|
||||
let node = aNode;
|
||||
while (node) {
|
||||
let idx = this.indexOf(node);
|
||||
if (idx > -1) {
|
||||
return idx;
|
||||
} else {
|
||||
node = this.DOMHelpers.getParentObject(node);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Make sure that the latest node in the breadcrumbs is not the selected node
|
||||
* if the selected node still has children.
|
||||
*/
|
||||
ensureFirstChild: function BC_ensureFirstChild()
|
||||
{
|
||||
// If the last displayed node is the selected node
|
||||
if (this.currentIndex == this.nodeHierarchy.length - 1) {
|
||||
let node = this.nodeHierarchy[this.currentIndex].node;
|
||||
let child = this.getFirstHighlightableChild(node);
|
||||
// If the node has a child
|
||||
if (child) {
|
||||
// Show this child
|
||||
this.expand(child);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Ensure the selected node is visible.
|
||||
*/
|
||||
scroll: function BC_scroll()
|
||||
{
|
||||
// FIXME bug 684352: make sure its immediate neighbors are visible too.
|
||||
|
||||
let scrollbox = this.container;
|
||||
let element = this.nodeHierarchy[this.currentIndex].button;
|
||||
scrollbox.ensureElementIsVisible(element);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the breadcrumbs display when a new node is selected.
|
||||
*/
|
||||
update: function BC_update()
|
||||
{
|
||||
this.menu.hidePopup();
|
||||
|
||||
let selection = this.IUI.selection;
|
||||
let idx = this.indexOf(selection);
|
||||
|
||||
// Is the node already displayed in the breadcrumbs?
|
||||
if (idx > -1) {
|
||||
// Yes. We select it.
|
||||
this.setCursor(idx);
|
||||
} else {
|
||||
// No. Is the breadcrumbs display empty?
|
||||
if (this.nodeHierarchy.length > 0) {
|
||||
// No. We drop all the element that are not direct ancestors
|
||||
// of the selection
|
||||
let parent = this.DOMHelpers.getParentObject(selection);
|
||||
let idx = this.getCommonAncestor(parent);
|
||||
this.cutAfter(idx);
|
||||
}
|
||||
// we append the missing button between the end of the breadcrumbs display
|
||||
// and the current node.
|
||||
this.expand(selection);
|
||||
|
||||
// we select the current node button
|
||||
idx = this.indexOf(selection);
|
||||
this.setCursor(idx);
|
||||
}
|
||||
// Add the first child of the very last node of the breadcrumbs if possible.
|
||||
this.ensureFirstChild();
|
||||
|
||||
// Make sure the selected node and its neighbours are visible.
|
||||
this.scroll();
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//// Initializers
|
||||
|
||||
XPCOMUtils.defineLazyGetter(InspectorUI.prototype, "strings",
|
||||
function () {
|
||||
return Services.strings.
|
||||
createBundle("chrome://browser/locale/inspector.properties");
|
||||
return Services.strings.createBundle(
|
||||
"chrome://browser/locale/devtools/inspector.properties");
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "StyleInspector", function () {
|
||||
|
|
|
@ -63,6 +63,8 @@ _BROWSER_FILES = \
|
|||
browser_inspector_bug_690361.js \
|
||||
browser_inspector_bug_672902_keyboard_shortcuts.js \
|
||||
browser_inspector_keybindings.js \
|
||||
browser_inspector_breadcrumbs.html \
|
||||
browser_inspector_breadcrumbs.js \
|
||||
$(NULL)
|
||||
|
||||
# Disabled due to constant failures
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
div {
|
||||
min-height: 10px; min-width: 10px;
|
||||
border: 1px solid red;
|
||||
margin: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<article id="i1">
|
||||
<div id="i11">
|
||||
<div id="i111">
|
||||
<div id="i1111">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
<article id="i2">
|
||||
<div id="i21">
|
||||
<div id="i211">
|
||||
<div id="i2111">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="i22">
|
||||
<div id="i221">
|
||||
</div>
|
||||
<div id="i222">
|
||||
<div id="i2221">
|
||||
<div id="i22211">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,105 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
let nodes = [
|
||||
{nodeId: "i1111", result: "i1 i11 i111 i1111"},
|
||||
{nodeId: "i22", result: "i2 i22 i221"},
|
||||
{nodeId: "i2111", result: "i2 i21 i211 i2111"},
|
||||
{nodeId: "i21", result: "i2 i21 i211 i2111"},
|
||||
{nodeId: "i22211", result: "i2 i22 i222 i2221 i22211"},
|
||||
{nodeId: "i22", result: "i2 i22 i222 i2221 i22211"},
|
||||
];
|
||||
|
||||
let doc;
|
||||
let nodes;
|
||||
let cursor;
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
doc = content.document;
|
||||
waitForFocus(setupTest, content);
|
||||
}, true);
|
||||
|
||||
content.location = "http://mochi.test:8888/browser/browser/devtools/highlighter/test/browser_inspector_breadcrumbs.html";
|
||||
|
||||
function setupTest()
|
||||
{
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
let node = doc.getElementById(nodes[i].nodeId);
|
||||
nodes[i].node = node;
|
||||
ok(nodes[i].node, "node " + nodes[i].nodeId + " found");
|
||||
}
|
||||
|
||||
Services.obs.addObserver(runTests,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
|
||||
InspectorUI.toggleInspectorUI();
|
||||
}
|
||||
|
||||
function runTests()
|
||||
{
|
||||
Services.obs.removeObserver(runTests,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED);
|
||||
|
||||
cursor = 0;
|
||||
executeSoon(function() {
|
||||
Services.obs.addObserver(nodeSelected,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.HIGHLIGHTING, false);
|
||||
|
||||
InspectorUI.inspectNode(nodes[0].node);
|
||||
});
|
||||
}
|
||||
|
||||
function nodeSelected()
|
||||
{
|
||||
executeSoon(function() {
|
||||
performTest();
|
||||
cursor++;
|
||||
if (cursor >= nodes.length) {
|
||||
|
||||
Services.obs.removeObserver(nodeSelected,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.HIGHLIGHTING);
|
||||
Services.obs.addObserver(finishUp,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED, false);
|
||||
|
||||
executeSoon(function() {
|
||||
InspectorUI.closeInspectorUI();
|
||||
});
|
||||
} else {
|
||||
let node = nodes[cursor].node;
|
||||
InspectorUI.inspectNode(node);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function performTest()
|
||||
{
|
||||
let container = document.getElementById("inspector-breadcrumbs");
|
||||
let buttonsLabelIds = nodes[cursor].result.split(" ");
|
||||
|
||||
// html > body > …
|
||||
is(container.childNodes.length, buttonsLabelIds.length + 2, "Node " + cursor + ": Items count");
|
||||
|
||||
for (let i = 2; i < container.childNodes.length; i++) {
|
||||
let expectedId = "#" + buttonsLabelIds[i - 2];
|
||||
let button = container.childNodes[i];
|
||||
let labelId = button.querySelector(".inspector-breadcrumbs-id");
|
||||
is(labelId.textContent, expectedId, "Node " + cursor + ": button " + i + " matches");
|
||||
}
|
||||
|
||||
let checkedButton = container.querySelector("button[checked]");
|
||||
let labelId = checkedButton.querySelector(".inspector-breadcrumbs-id");
|
||||
is(labelId.textContent, "#" + InspectorUI.selection.id, "Node " + cursor + ": selection matches");
|
||||
}
|
||||
|
||||
function finishUp() {
|
||||
Services.obs.removeObserver(finishUp, InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED);
|
||||
doc = nodes = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
}
|
|
@ -63,7 +63,7 @@ Cu.import("resource:///modules/source-editor.jsm");
|
|||
const SCRATCHPAD_CONTEXT_CONTENT = 1;
|
||||
const SCRATCHPAD_CONTEXT_BROWSER = 2;
|
||||
const SCRATCHPAD_WINDOW_URL = "chrome://browser/content/scratchpad.xul";
|
||||
const SCRATCHPAD_L10N = "chrome://browser/locale/scratchpad.properties";
|
||||
const SCRATCHPAD_L10N = "chrome://browser/locale/devtools/scratchpad.properties";
|
||||
const SCRATCHPAD_WINDOW_FEATURES = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no";
|
||||
const DEVTOOLS_CHROME_ENABLED = "devtools.chrome.enabled";
|
||||
|
||||
|
@ -84,10 +84,10 @@ var Scratchpad = {
|
|||
executionContext: SCRATCHPAD_CONTEXT_CONTENT,
|
||||
|
||||
/**
|
||||
* Retrieve the xul:statusbarpanel DOM element. The status bar tells the
|
||||
* current code execution context.
|
||||
* Retrieve the xul:notificationbox DOM element. It notifies the user when
|
||||
* the current code execution context is SCRATCHPAD_CONTEXT_BROWSER.
|
||||
*/
|
||||
get statusbarStatus() document.getElementById("scratchpad-status"),
|
||||
get notificationBox() document.getElementById("scratchpad-notificationbox"),
|
||||
|
||||
/**
|
||||
* Get the selected text from the editor.
|
||||
|
@ -599,11 +599,15 @@ var Scratchpad = {
|
|||
*/
|
||||
setContentContext: function SP_setContentContext()
|
||||
{
|
||||
if (this.executionContext == SCRATCHPAD_CONTEXT_CONTENT) {
|
||||
return;
|
||||
}
|
||||
|
||||
let content = document.getElementById("sp-menu-content");
|
||||
document.getElementById("sp-menu-browser").removeAttribute("checked");
|
||||
content.setAttribute("checked", true);
|
||||
this.executionContext = SCRATCHPAD_CONTEXT_CONTENT;
|
||||
this.statusbarStatus.label = content.getAttribute("label");
|
||||
this.notificationBox.removeAllNotifications(false);
|
||||
this.resetContext();
|
||||
},
|
||||
|
||||
|
@ -612,11 +616,20 @@ var Scratchpad = {
|
|||
*/
|
||||
setBrowserContext: function SP_setBrowserContext()
|
||||
{
|
||||
if (this.executionContext == SCRATCHPAD_CONTEXT_BROWSER) {
|
||||
return;
|
||||
}
|
||||
|
||||
let browser = document.getElementById("sp-menu-browser");
|
||||
document.getElementById("sp-menu-content").removeAttribute("checked");
|
||||
browser.setAttribute("checked", true);
|
||||
this.executionContext = SCRATCHPAD_CONTEXT_BROWSER;
|
||||
this.statusbarStatus.label = browser.getAttribute("label");
|
||||
this.notificationBox.appendNotification(
|
||||
this.strings.GetStringFromName("browserContext.notification"),
|
||||
SCRATCHPAD_CONTEXT_BROWSER,
|
||||
null,
|
||||
this.notificationBox.PRIORITY_WARNING_HIGH,
|
||||
null);
|
||||
this.resetContext();
|
||||
},
|
||||
|
||||
|
@ -657,17 +670,14 @@ var Scratchpad = {
|
|||
return;
|
||||
}
|
||||
|
||||
let chromeContextMenu = document.getElementById("sp-menu-browser");
|
||||
let errorConsoleMenu = document.getElementById("sp-menu-errorConsole");
|
||||
let errorConsoleCommand = document.getElementById("sp-cmd-errorConsole");
|
||||
let chromeContextCommand = document.getElementById("sp-cmd-browserContext");
|
||||
|
||||
let chrome = Services.prefs.getBoolPref(DEVTOOLS_CHROME_ENABLED);
|
||||
if (chrome) {
|
||||
chromeContextMenu.removeAttribute("hidden");
|
||||
errorConsoleMenu.removeAttribute("hidden");
|
||||
errorConsoleCommand.removeAttribute("disabled");
|
||||
let environmentMenu = document.getElementById("sp-environment-menu");
|
||||
let errorConsoleCommand = document.getElementById("sp-cmd-errorConsole");
|
||||
let chromeContextCommand = document.getElementById("sp-cmd-browserContext");
|
||||
environmentMenu.removeAttribute("hidden");
|
||||
chromeContextCommand.removeAttribute("disabled");
|
||||
errorConsoleCommand.removeAttribute("disabled");
|
||||
}
|
||||
|
||||
this.editor = new SourceEditor();
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
- ***** END LICENSE BLOCK ***** -->
|
||||
#endif
|
||||
<!DOCTYPE window [
|
||||
<!ENTITY % scratchpadDTD SYSTEM "chrome://browser/locale/scratchpad.dtd" >
|
||||
<!ENTITY % scratchpadDTD SYSTEM "chrome://browser/locale/devtools/scratchpad.dtd" >
|
||||
%scratchpadDTD;
|
||||
]>
|
||||
<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
|
||||
|
@ -261,12 +261,18 @@
|
|||
accesskey="&display.accesskey;"
|
||||
key="sp-key-display"
|
||||
command="sp-cmd-display"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="sp-text-resetContext"
|
||||
label="&resetContext2.label;"
|
||||
accesskey="&resetContext2.accesskey;"
|
||||
command="sp-cmd-resetContext"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
|
||||
<menu id="sp-environment-menu"
|
||||
label="&environmentMenu.label;"
|
||||
accesskey="&environmentMenu.accesskey;">
|
||||
accesskey="&environmentMenu.accesskey;"
|
||||
hidden="true">
|
||||
<menupopup id="sp-menu-environment">
|
||||
<menuitem id="sp-menu-content"
|
||||
label="&contentContext.label;"
|
||||
|
@ -274,33 +280,11 @@
|
|||
command="sp-cmd-contentContext"
|
||||
checked="true"
|
||||
type="radio"/>
|
||||
<menuitem id="sp-menu-browser" hidden="true"
|
||||
<menuitem id="sp-menu-browser"
|
||||
command="sp-cmd-browserContext"
|
||||
label="&browserContext.label;"
|
||||
accesskey="&browserContext.accesskey;"
|
||||
type="radio"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="sp-menu-resetContext"
|
||||
command="sp-cmd-resetContext"
|
||||
label="&resetContext.label;"
|
||||
accesskey="&resetContext.accesskey;"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
|
||||
<menu id="sp-tools-menu"
|
||||
label="&toolsMenu.label;"
|
||||
accesskey="&toolsMenu.accesskey;">
|
||||
<menupopup id="sp-menu-tools">
|
||||
<menuitem id="sp-menu-errorConsole" hidden="true"
|
||||
label="&errorConsoleCmd.label;"
|
||||
accesskey="&errorConsoleCmd.accesskey;"
|
||||
key="sp-key-errorConsole"
|
||||
command="sp-cmd-errorConsole"/>
|
||||
<menuitem id="sp-menu-webConsole"
|
||||
label="&webConsoleCmd.label;"
|
||||
accesskey="&webConsoleCmd.accesskey;"
|
||||
key="sp-key-webConsole"
|
||||
command="sp-cmd-webConsole"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</menubar>
|
||||
|
@ -329,15 +313,16 @@
|
|||
accesskey="&display.accesskey;"
|
||||
key="sp-key-display"
|
||||
command="sp-cmd-display"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="sp-text-resetContext"
|
||||
label="&resetContext2.label;"
|
||||
accesskey="&resetContext2.accesskey;"
|
||||
command="sp-cmd-resetContext"/>
|
||||
</menupopup>
|
||||
</popupset>
|
||||
|
||||
<hbox id="scratchpad-editor" flex="1" context="scratchpad-text-popup" />
|
||||
<notificationbox id="scratchpad-notificationbox" flex="1">
|
||||
<hbox id="scratchpad-editor" flex="1" context="scratchpad-text-popup" />
|
||||
</notificationbox>
|
||||
|
||||
<statusbar id="scratchpad-statusbar" align="end">
|
||||
<statusbarpanel id="scratchpad-status"
|
||||
label="&contentContext.label;"
|
||||
class="statusbarpanel-iconic-text"/>
|
||||
<spacer flex="1"/>
|
||||
</statusbar>
|
||||
</window>
|
||||
|
|
|
@ -35,11 +35,11 @@ function runTests()
|
|||
let sp = gScratchpadWindow.Scratchpad;
|
||||
ok(sp, "Scratchpad object exists in new window");
|
||||
|
||||
let chromeContextMenu = gScratchpadWindow.document.
|
||||
getElementById("sp-menu-browser");
|
||||
ok(chromeContextMenu, "Chrome context menuitem element exists");
|
||||
ok(!chromeContextMenu.hasAttribute("hidden"),
|
||||
"Chrome context menuitem is visible");
|
||||
let environmentMenu = gScratchpadWindow.document.
|
||||
getElementById("sp-environment-menu");
|
||||
ok(environmentMenu, "Environment menu element exists");
|
||||
ok(!environmentMenu.hasAttribute("hidden"),
|
||||
"Environment menu is visible");
|
||||
|
||||
let errorConsoleCommand = gScratchpadWindow.document.
|
||||
getElementById("sp-cmd-errorConsole");
|
||||
|
@ -47,12 +47,6 @@ function runTests()
|
|||
ok(!errorConsoleCommand.hasAttribute("disabled"),
|
||||
"Error console command is enabled");
|
||||
|
||||
let errorConsoleMenu = gScratchpadWindow.document.
|
||||
getElementById("sp-menu-errorConsole");
|
||||
ok(errorConsoleMenu, "Error console menu element exists");
|
||||
ok(!errorConsoleMenu.hasAttribute("hidden"),
|
||||
"Error console menuitem is visible");
|
||||
|
||||
let chromeContextCommand = gScratchpadWindow.document.
|
||||
getElementById("sp-cmd-browserContext");
|
||||
ok(chromeContextCommand, "Chrome context command element exists");
|
||||
|
|
|
@ -28,11 +28,11 @@ function runTests()
|
|||
|
||||
let contentMenu = gScratchpadWindow.document.getElementById("sp-menu-content");
|
||||
let chromeMenu = gScratchpadWindow.document.getElementById("sp-menu-browser");
|
||||
let statusbar = sp.statusbarStatus;
|
||||
let notificationBox = sp.notificationBox;
|
||||
|
||||
ok(contentMenu, "found #sp-menu-content");
|
||||
ok(chromeMenu, "found #sp-menu-browser");
|
||||
ok(statusbar, "found Scratchpad.statusbarStatus");
|
||||
ok(notificationBox, "found Scratchpad.notificationBox");
|
||||
|
||||
sp.setContentContext();
|
||||
|
||||
|
@ -45,8 +45,8 @@ function runTests()
|
|||
ok(!chromeMenu.hasAttribute("checked"),
|
||||
"chrome menuitem is not checked");
|
||||
|
||||
is(statusbar.getAttribute("label"), contentMenu.getAttribute("label"),
|
||||
"statusbar label is correct");
|
||||
ok(!notificationBox.currentNotification,
|
||||
"there is no notification in content context");
|
||||
|
||||
sp.setText("window.foobarBug636725 = 'aloha';");
|
||||
|
||||
|
@ -69,8 +69,8 @@ function runTests()
|
|||
ok(!contentMenu.hasAttribute("checked"),
|
||||
"content menuitem is not checked");
|
||||
|
||||
is(statusbar.getAttribute("label"), chromeMenu.getAttribute("label"),
|
||||
"statusbar label is correct");
|
||||
ok(notificationBox.currentNotification,
|
||||
"there is a notification in browser context");
|
||||
|
||||
sp.setText("2'", 31, 33);
|
||||
|
||||
|
|
|
@ -32,11 +32,11 @@ function runTests()
|
|||
is(typeof sp.inspect, "function", "Scratchpad.inspect() exists");
|
||||
is(typeof sp.display, "function", "Scratchpad.display() exists");
|
||||
|
||||
let chromeContextMenu = gScratchpadWindow.document.
|
||||
getElementById("sp-menu-browser");
|
||||
ok(chromeContextMenu, "Chrome context menuitem element exists");
|
||||
is(chromeContextMenu.getAttribute("hidden"), "true",
|
||||
"Chrome context menuitem is hidden");
|
||||
let environmentMenu = gScratchpadWindow.document.
|
||||
getElementById("sp-environment-menu");
|
||||
ok(environmentMenu, "Environment menu element exists");
|
||||
ok(environmentMenu.hasAttribute("hidden"),
|
||||
"Environment menu is not visible");
|
||||
|
||||
let errorConsoleCommand = gScratchpadWindow.document.
|
||||
getElementById("sp-cmd-errorConsole");
|
||||
|
@ -44,12 +44,6 @@ function runTests()
|
|||
is(errorConsoleCommand.getAttribute("disabled"), "true",
|
||||
"Error console command is disabled");
|
||||
|
||||
let errorConsoleMenu = gScratchpadWindow.document.
|
||||
getElementById("sp-menu-errorConsole");
|
||||
ok(errorConsoleMenu, "Error console menu element exists");
|
||||
is(errorConsoleMenu.getAttribute("hidden"), "true",
|
||||
"Error console menu item is hidden");
|
||||
|
||||
let chromeContextCommand = gScratchpadWindow.document.
|
||||
getElementById("sp-cmd-browserContext");
|
||||
ok(chromeContextCommand, "Chrome context command element exists");
|
||||
|
|
|
@ -38,11 +38,11 @@ function runTests()
|
|||
|
||||
let contentMenu = gScratchpadWindow.document.getElementById("sp-menu-content");
|
||||
let browserMenu = gScratchpadWindow.document.getElementById("sp-menu-browser");
|
||||
let statusbar = sp.statusbarStatus;
|
||||
let notificationBox = sp.notificationBox;
|
||||
|
||||
ok(contentMenu, "found #sp-menu-content");
|
||||
ok(browserMenu, "found #sp-menu-browser");
|
||||
ok(statusbar, "found Scratchpad.statusbarStatus");
|
||||
ok(notificationBox, "found Scratchpad.notificationBox");
|
||||
|
||||
sp.setContentContext();
|
||||
|
||||
|
@ -55,8 +55,8 @@ function runTests()
|
|||
ok(!browserMenu.hasAttribute("checked"),
|
||||
"chrome menuitem is not checked");
|
||||
|
||||
is(statusbar.getAttribute("label"), contentMenu.getAttribute("label"),
|
||||
"statusbar label is correct");
|
||||
is(notificationBox.currentNotification, null,
|
||||
"there is no notification currently shown for content context");
|
||||
|
||||
sp.setText("window.foosbug653108 = 'aloha';");
|
||||
|
||||
|
|
|
@ -36,11 +36,9 @@ function runTests()
|
|||
"sp-text-run": "run",
|
||||
"sp-text-inspect": "inspect",
|
||||
"sp-text-display": "display",
|
||||
"sp-text-resetContext": "resetContext",
|
||||
"sp-menu-content": "setContentContext",
|
||||
"sp-menu-browser": "setBrowserContext",
|
||||
"sp-menu-resetContext": "resetContext",
|
||||
"sp-menu-errorConsole": "openErrorConsole",
|
||||
"sp-menu-webConsole": "openWebConsole",
|
||||
"sp-menu-undo": "undo",
|
||||
"sp-menu-redo": "redo",
|
||||
};
|
||||
|
|
|
@ -130,7 +130,7 @@ CssHtmlTree.processTemplate = function CssHtmlTree_processTemplate(aTemplate,
|
|||
};
|
||||
|
||||
XPCOMUtils.defineLazyGetter(CssHtmlTree, "_strings", function() Services.strings
|
||||
.createBundle("chrome://browser/locale/styleinspector.properties"));
|
||||
.createBundle("chrome://browser/locale/devtools/styleinspector.properties"));
|
||||
|
||||
CssHtmlTree.prototype = {
|
||||
htmlComplete: false,
|
||||
|
@ -681,17 +681,17 @@ SelectorView.prototype = {
|
|||
text: function SelectorView_text(aElement) {
|
||||
let result = this.selectorInfo.selector.text;
|
||||
if (this.selectorInfo.elementStyle) {
|
||||
if (this.tree.styleInspector.IUI) {
|
||||
if (this.selectorInfo.sourceElement == this.tree.styleInspector.IUI.selection)
|
||||
{
|
||||
result = "this";
|
||||
} else {
|
||||
result = CssLogic.getShortName(this.selectorInfo.sourceElement);
|
||||
}
|
||||
let source = this.selectorInfo.sourceElement;
|
||||
let IUI = this.tree.styleInspector.IUI;
|
||||
if (IUI && IUI.selection == source) {
|
||||
result = "this";
|
||||
} else {
|
||||
result = CssLogic.getShortName(source);
|
||||
}
|
||||
|
||||
aElement.parentNode.querySelector(".rule-link > a").
|
||||
addEventListener("click", function(aEvent) {
|
||||
this.tree.styleInspector.selectFromPath(this.selectorInfo.sourceElement);
|
||||
this.tree.styleInspector.selectFromPath(source);
|
||||
aEvent.preventDefault();
|
||||
}.bind(this), false);
|
||||
result += ".style";
|
||||
|
|
|
@ -606,10 +606,12 @@ CssLogic.prototype = {
|
|||
|
||||
/**
|
||||
* Check if the highlighted element or it's parents have matched selectors.
|
||||
* If aCallback is provided then the domRules for the element are passed to
|
||||
* the callback function.
|
||||
*
|
||||
* @param {function} [aCallback] Simple callback method
|
||||
* @param {function} [aCallback] Simple callback method. If aCallback is
|
||||
* provided then the domRules for each element in the loop are passed to
|
||||
* the callback function. When the element has .style properties, the callback
|
||||
* receives {style: element.style}. If the callback returns true then the
|
||||
* element has matched rules, otherwise not.
|
||||
* @return {Boolean} true if the current element or it's parents have
|
||||
* matching CssSelector objects, false otherwise
|
||||
*/
|
||||
|
@ -628,11 +630,22 @@ CssLogic.prototype = {
|
|||
continue;
|
||||
}
|
||||
|
||||
// Check if the are DOM rules that we can consider as matched rules
|
||||
// (depending on the callback).
|
||||
if (domRules.Count() && (!aCallback || aCallback(domRules))) {
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if the element has any element.style properties that we can
|
||||
// consider as "matched" (depending on the callback).
|
||||
if (element.style.length > 0 &&
|
||||
(!aCallback || aCallback({style: element.style}))) {
|
||||
matched = true;
|
||||
}
|
||||
|
||||
if (matched) {
|
||||
break;
|
||||
}
|
||||
} while ((element = element.parentNode) &&
|
||||
element.nodeType === Ci.nsIDOMNode.ELEMENT_NODE);
|
||||
|
||||
|
@ -746,7 +759,7 @@ CssLogic.getShortNamePath = function CssLogic_getShortNamePath(aElement)
|
|||
CssLogic.l10n = function(aName) CssLogic._strings.GetStringFromName(aName);
|
||||
|
||||
XPCOMUtils.defineLazyGetter(CssLogic, "_strings", function() Services.strings
|
||||
.createBundle("chrome://browser/locale/styleinspector.properties"));
|
||||
.createBundle("chrome://browser/locale/devtools/styleinspector.properties"));
|
||||
|
||||
/**
|
||||
* Is the given property sheet a system (user agent) stylesheet?
|
||||
|
@ -1499,6 +1512,11 @@ CssPropertyInfo.prototype = {
|
|||
{
|
||||
if (this._hasMatchedSelectors === null) {
|
||||
this._hasMatchedSelectors = this._cssLogic.hasMatchedSelectors(function(aDomRules) {
|
||||
if (!aDomRules.Count) {
|
||||
// For element.style.
|
||||
return !!aDomRules.style.getPropertyValue(this.property);
|
||||
}
|
||||
|
||||
for (let i = 0; i < aDomRules.Count(); i++) {
|
||||
let domRule = aDomRules.GetElementAt(i);
|
||||
|
||||
|
|
|
@ -314,7 +314,7 @@ StyleInspector.prototype = {
|
|||
};
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "_strings", function() Services.strings
|
||||
.createBundle("chrome://browser/locale/styleinspector.properties"));
|
||||
.createBundle("chrome://browser/locale/devtools/styleinspector.properties"));
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "CssLogic", function() {
|
||||
let tmp = {};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE html [
|
||||
<!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
|
||||
%htmlDTD;
|
||||
<!ENTITY % inspectorDTD SYSTEM "chrome://browser/locale/styleinspector.dtd">
|
||||
<!ENTITY % inspectorDTD SYSTEM "chrome://browser/locale/devtools/styleinspector.dtd">
|
||||
%inspectorDTD;
|
||||
<!ELEMENT loop ANY>
|
||||
<!ATTLIST li foreach CDATA #IMPLIED>
|
||||
|
|
|
@ -51,6 +51,7 @@ _BROWSER_TEST_FILES = \
|
|||
browser_bug683672.js \
|
||||
browser_styleinspector_bug_672746_default_styles.js \
|
||||
browser_styleinspector_bug_672744_search_filter.js \
|
||||
browser_bug_692400_element_style.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests for selector text errors.
|
||||
|
||||
let doc;
|
||||
let stylePanel;
|
||||
|
||||
function createDocument()
|
||||
{
|
||||
doc.body.innerHTML = "<div style='color:blue;'></div>";
|
||||
|
||||
doc.title = "Style Inspector Selector Text Test";
|
||||
ok(window.StyleInspector, "StyleInspector exists");
|
||||
stylePanel = new StyleInspector(window);
|
||||
|
||||
|
||||
stylePanel.createPanel(false, function() {
|
||||
Services.obs.addObserver(SI_checkText, "StyleInspector-populated", false);
|
||||
|
||||
let span = doc.querySelector("div");
|
||||
ok(span, "captain, we have the test div");
|
||||
stylePanel.open(span);
|
||||
});
|
||||
}
|
||||
|
||||
function SI_checkText()
|
||||
{
|
||||
Services.obs.removeObserver(SI_checkText, "StyleInspector-populated", false);
|
||||
|
||||
let propertyView = null;
|
||||
stylePanel.cssHtmlTree.propertyViews.some(function(aView) {
|
||||
if (aView.name == "color") {
|
||||
propertyView = aView;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
ok(propertyView, "found PropertyView for color");
|
||||
|
||||
is(propertyView.hasMatchedSelectors, true, "hasMatchedSelectors is true");
|
||||
|
||||
propertyView.matchedExpanded = true;
|
||||
propertyView.refreshMatchedSelectors();
|
||||
|
||||
let td = propertyView.matchedSelectorTable.querySelector("td.rule-text");
|
||||
ok(td, "found the first table row");
|
||||
|
||||
let selector = propertyView.matchedSelectorViews[0];
|
||||
ok(selector, "found the first matched selector view");
|
||||
|
||||
try {
|
||||
is(td.textContent.trim(), selector.humanReadableText(td).trim(),
|
||||
"selector text is correct");
|
||||
} catch (ex) {
|
||||
info("EXCEPTION: " + ex);
|
||||
ok(false, "getting the selector text should not raise an exception");
|
||||
}
|
||||
|
||||
Services.obs.addObserver(finishUp, "StyleInspector-closed", false);
|
||||
stylePanel.close();
|
||||
}
|
||||
|
||||
function finishUp()
|
||||
{
|
||||
Services.obs.removeObserver(finishUp, "StyleInspector-closed", false);
|
||||
doc = stylePanel = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad(evt) {
|
||||
gBrowser.selectedBrowser.removeEventListener(evt.type, onLoad, true);
|
||||
doc = content.document;
|
||||
waitForFocus(createDocument, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,selector text test, bug 692400";
|
||||
}
|
|
@ -164,7 +164,7 @@ function styleInspectorClosedByHide()
|
|||
{
|
||||
Services.obs.removeObserver(styleInspectorClosedByHide, "StyleInspector-closed", false);
|
||||
is(stylePanels[0].state, "open", "instance stylePanels[0] is still open");
|
||||
is(stylePanels[1].state, "closed", "instance stylePanels[1] is hidden");
|
||||
isnot(stylePanels[1].state, "open", "instance stylePanels[1] is not open");
|
||||
is(stylePanels[2].state, "open", "instance stylePanels[2] is still open");
|
||||
|
||||
info("closing web console");
|
||||
|
|
|
@ -42,7 +42,7 @@ const Cu = Components.utils;
|
|||
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
const XHTML_NS = "http://www.w3.org/1999/xhtml";
|
||||
|
||||
const HUD_STRINGS_URI = "chrome://global/locale/headsUpDisplay.properties";
|
||||
const HUD_STRINGS_URI = "chrome://browser/locale/devtools/webconsole.properties";
|
||||
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
|
|
@ -38,82 +38,21 @@
|
|||
|
||||
let EXPORTED_SYMBOLS = [ "GcliCommands" ];
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
Components.utils.import("resource:///modules/gcli.jsm");
|
||||
Components.utils.import("resource:///modules/HUDService.jsm");
|
||||
|
||||
let bundleName = "chrome://browser/locale/devtools/gclicommands.properties";
|
||||
let stringBundle = Services.strings.createBundle(bundleName);
|
||||
|
||||
let gcli = gcli._internal.require("gcli/index");
|
||||
let canon = gcli._internal.require("gcli/canon");
|
||||
|
||||
|
||||
let document;
|
||||
|
||||
/**
|
||||
* The exported API
|
||||
*/
|
||||
let GcliCommands = {
|
||||
/**
|
||||
* Allow HUDService to inform us of the document against which we work
|
||||
*/
|
||||
setDocument: function GcliCommands_setDocument(aDocument) {
|
||||
document = aDocument;
|
||||
},
|
||||
|
||||
/**
|
||||
* Undo the effects of GcliCommands.setDocument()
|
||||
*/
|
||||
unsetDocument: function GcliCommands_unsetDocument() {
|
||||
document = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Lookup a string in the GCLI string bundle
|
||||
* @param aName The name to lookup
|
||||
* @return The looked up name
|
||||
*/
|
||||
function lookup(aName)
|
||||
{
|
||||
try {
|
||||
return stringBundle.GetStringFromName(aName);
|
||||
} catch (ex) {
|
||||
throw new Error("Failure in lookup('" + aName + "')");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Lookup a string in the GCLI string bundle
|
||||
* @param aName The name to lookup
|
||||
* @param aSwaps An array of swaps. See stringBundle.formatStringFromName
|
||||
* @return The looked up name
|
||||
*/
|
||||
function lookupFormat(aName, aSwaps)
|
||||
{
|
||||
try {
|
||||
return stringBundle.formatStringFromName(aName, aSwaps, aSwaps.length);
|
||||
} catch (ex) {
|
||||
Services.console.logStringMessage("Failure in lookupFormat('" + aName + "')");
|
||||
throw new Error("Failure in lookupFormat('" + aName + "')");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 'echo' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "echo",
|
||||
description: lookup("echoDesc"),
|
||||
description: gcli.lookup("echoDesc"),
|
||||
params: [
|
||||
{
|
||||
name: "message",
|
||||
type: "string",
|
||||
description: lookup("echoMessageDesc")
|
||||
description: gcli.lookup("echoMessageDesc")
|
||||
}
|
||||
],
|
||||
returnType: "string",
|
||||
|
@ -123,17 +62,19 @@ gcli.addCommand({
|
|||
});
|
||||
|
||||
|
||||
let canon = gcli._internal.require("gcli/canon");
|
||||
|
||||
/**
|
||||
* 'help' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "help",
|
||||
returnType: "html",
|
||||
description: lookup("helpDesc"),
|
||||
description: gcli.lookup("helpDesc"),
|
||||
exec: function Command_help(args, context) {
|
||||
let output = [];
|
||||
|
||||
output.push("<strong>" + lookup("helpAvailable") + ":</strong><br/>");
|
||||
output.push("<strong>" + gcli.lookup("helpAvailable") + ":</strong><br/>");
|
||||
|
||||
let commandNames = canon.getCommandNames();
|
||||
commandNames.sort();
|
||||
|
@ -160,8 +101,8 @@ gcli.addCommand({
|
|||
*/
|
||||
gcli.addCommand({
|
||||
name: "console",
|
||||
description: lookup("consoleDesc"),
|
||||
manual: lookup("consoleManual")
|
||||
description: gcli.lookup("consoleDesc"),
|
||||
manual: gcli.lookup("consoleManual")
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -169,10 +110,32 @@ gcli.addCommand({
|
|||
*/
|
||||
gcli.addCommand({
|
||||
name: "console clear",
|
||||
description: lookup("consoleclearDesc"),
|
||||
description: gcli.lookup("consoleclearDesc"),
|
||||
exec: function(args, context) {
|
||||
let hud = HUDService.getHudReferenceById(context.environment.hudId);
|
||||
hud.gcliterm.clearOutput();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* 'inspect' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "inspect",
|
||||
description: gcli.lookup("inspectDesc"),
|
||||
manual: gcli.lookup("inspectManual"),
|
||||
params: [
|
||||
{
|
||||
name: "node",
|
||||
type: "node",
|
||||
description: gcli.lookup("inspectNodeDesc"),
|
||||
manual: gcli.lookup("inspectNodeManual")
|
||||
}
|
||||
],
|
||||
exec: function Command_inspect(args, context) {
|
||||
let hud = HUDService.getHudReferenceById(context.environment.hudId);
|
||||
let InspectorUI = hud.gcliterm.document.defaultView.InspectorUI;
|
||||
InspectorUI.openInspectorUI(args.node);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -79,12 +79,6 @@ XPCOMUtils.defineLazyGetter(this, "gcli", function () {
|
|||
return obj.gcli;
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "GcliCommands", function () {
|
||||
var obj = {};
|
||||
Cu.import("resource:///modules/GcliCommands.jsm", obj);
|
||||
return obj.GcliCommands;
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "StyleInspector", function () {
|
||||
var obj = {};
|
||||
Cu.import("resource:///modules/devtools/StyleInspector.jsm", obj);
|
||||
|
@ -133,9 +127,26 @@ function LogFactory(aMessagePrefix)
|
|||
return log;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the various Command JSMs.
|
||||
* Should be called when the console first opens.
|
||||
*
|
||||
* @return an object containing the EXPORTED_SYMBOLS from all the command
|
||||
* modules. In general there is no reason when JSMs need to export symbols
|
||||
* except when they need the host environment to inform them of things like the
|
||||
* current window/document/etc.
|
||||
*/
|
||||
function loadCommands() {
|
||||
let commandExports = {};
|
||||
|
||||
Cu.import("resource:///modules/GcliCommands.jsm", commandExports);
|
||||
|
||||
return commandExports;
|
||||
}
|
||||
|
||||
let log = LogFactory("*** HUDService:");
|
||||
|
||||
const HUD_STRINGS_URI = "chrome://global/locale/headsUpDisplay.properties";
|
||||
const HUD_STRINGS_URI = "chrome://browser/locale/devtools/webconsole.properties";
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "stringBundle", function () {
|
||||
return Services.strings.createBundle(HUD_STRINGS_URI);
|
||||
|
@ -6882,6 +6893,11 @@ catch (ex) {
|
|||
// GcliTerm
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Some commands need customization - this is how we get at them.
|
||||
*/
|
||||
let commandExports = undefined;
|
||||
|
||||
/**
|
||||
* GcliTerm
|
||||
*
|
||||
|
@ -6932,7 +6948,10 @@ function GcliTerm(aContentWindow, aHudId, aDocument, aConsole, aHintNode)
|
|||
|
||||
gcli._internal.commandOutputManager.addListener(this.onCommandOutput, this);
|
||||
gcli._internal.createView(this.opts);
|
||||
GcliCommands.setDocument(aContentWindow.document);
|
||||
|
||||
if (!commandExports) {
|
||||
commandExports = loadCommands();
|
||||
}
|
||||
}
|
||||
|
||||
GcliTerm.prototype = {
|
||||
|
@ -6957,7 +6976,6 @@ GcliTerm.prototype = {
|
|||
*/
|
||||
destroy: function Gcli_destroy()
|
||||
{
|
||||
GcliCommands.unsetDocument();
|
||||
gcli._internal.removeView(this.opts);
|
||||
gcli._internal.commandOutputManager.removeListener(this.onCommandOutput, this);
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
||||
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" [
|
||||
<!ENTITY % webConsoleDTD SYSTEM "chrome://global/locale/webConsole.dtd" >
|
||||
<!ENTITY % webConsoleDTD SYSTEM "chrome://browser/locale/devtools/webConsole.dtd" >
|
||||
%webConsoleDTD;
|
||||
]>
|
||||
|
||||
|
|
|
@ -630,11 +630,52 @@ var require = define.globalDomain.require.bind(define.globalDomain);
|
|||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
var mozl10n = {};
|
||||
|
||||
(function(aMozl10n) {
|
||||
var temp = {};
|
||||
Components.utils.import("resource://gre/modules/Services.jsm", temp);
|
||||
var stringBundle = temp.Services.strings.createBundle(
|
||||
"chrome://browser/locale/devtools/gclicommands.properties");
|
||||
|
||||
/**
|
||||
* Lookup a string in the GCLI string bundle
|
||||
* @param name The name to lookup
|
||||
* @return The looked up name
|
||||
*/
|
||||
aMozl10n.lookup = function(name) {
|
||||
try {
|
||||
return stringBundle.GetStringFromName(name);
|
||||
}
|
||||
catch (ex) {
|
||||
throw new Error("Failure in lookup('" + name + "')");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Lookup a string in the GCLI string bundle
|
||||
* @param name The name to lookup
|
||||
* @param swaps An array of swaps. See stringBundle.formatStringFromName
|
||||
* @return The looked up name
|
||||
*/
|
||||
aMozl10n.lookupFormat = function(name, swaps) {
|
||||
try {
|
||||
return stringBundle.formatStringFromName(name, swaps, swaps.length);
|
||||
}
|
||||
catch (ex) {
|
||||
throw new Error("Failure in lookupFormat('" + name + "')");
|
||||
}
|
||||
};
|
||||
|
||||
})(mozl10n);
|
||||
|
||||
define('gcli/index', ['require', 'exports', 'module' , 'gcli/canon', 'gcli/types/basic', 'gcli/types/javascript', 'gcli/types/node', 'gcli/cli', 'gcli/ui/inputter', 'gcli/ui/arg_fetch', 'gcli/ui/menu', 'gcli/ui/focus'], function(require, exports, module) {
|
||||
|
||||
// The API for use by command authors
|
||||
exports.addCommand = require('gcli/canon').addCommand;
|
||||
exports.removeCommand = require('gcli/canon').removeCommand;
|
||||
exports.lookup = mozl10n.lookup;
|
||||
exports.lookupFormat = mozl10n.lookupFormat;
|
||||
|
||||
// Internal startup process. Not exported
|
||||
require('gcli/types/basic').startup();
|
||||
|
@ -3437,9 +3478,10 @@ exports.JavascriptType = JavascriptType;
|
|||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
define('gcli/types/node', ['require', 'exports', 'module' , 'gcli/l10n', 'gcli/types'], function(require, exports, module) {
|
||||
define('gcli/types/node', ['require', 'exports', 'module' , 'gcli/host', 'gcli/l10n', 'gcli/types'], function(require, exports, module) {
|
||||
|
||||
|
||||
var host = require('gcli/host');
|
||||
var l10n = require('gcli/l10n');
|
||||
var types = require('gcli/types');
|
||||
var Type = require('gcli/types').Type;
|
||||
|
@ -3521,13 +3563,13 @@ NodeType.prototype.parse = function(arg) {
|
|||
var node = nodes.item(0);
|
||||
node.__gcliQuery = arg.text;
|
||||
|
||||
flashNode(node, 'green');
|
||||
host.flashNode(node, 'green');
|
||||
|
||||
return new Conversion(node, arg, Status.VALID, '');
|
||||
}
|
||||
|
||||
Array.prototype.forEach.call(nodes, function(n) {
|
||||
flashNode(n, 'red');
|
||||
host.flashNode(n, 'red');
|
||||
});
|
||||
|
||||
return new Conversion(null, arg, Status.ERROR,
|
||||
|
@ -3537,11 +3579,21 @@ NodeType.prototype.parse = function(arg) {
|
|||
NodeType.prototype.name = 'node';
|
||||
|
||||
|
||||
});
|
||||
/*
|
||||
* Copyright 2009-2011 Mozilla Foundation and contributors
|
||||
* Licensed under the New BSD license. See LICENSE.txt or:
|
||||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
define('gcli/host', ['require', 'exports', 'module' ], function(require, exports, module) {
|
||||
|
||||
|
||||
/**
|
||||
* Helper to turn a node background it's complementary color for 1 second.
|
||||
* There is likely a better way to do this, but this will do for now.
|
||||
*/
|
||||
function flashNode(node, color) {
|
||||
exports.flashNode = function(node, color) {
|
||||
if (!node.__gcliHighlighting) {
|
||||
node.__gcliHighlighting = true;
|
||||
var original = node.style.background;
|
||||
|
@ -3551,7 +3603,7 @@ function flashNode(node, color) {
|
|||
delete node.__gcliHighlighting;
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
});
|
||||
|
@ -4197,16 +4249,17 @@ Requisition.prototype._onCommandAssignmentChange = function(ev) {
|
|||
/**
|
||||
* Assignments have an order, so we need to store them in an array.
|
||||
* But we also need named access ...
|
||||
* @return The found assignment, or undefined, if no match was found
|
||||
*/
|
||||
Requisition.prototype.getAssignment = function(nameOrNumber) {
|
||||
var name = (typeof nameOrNumber === 'string') ?
|
||||
nameOrNumber :
|
||||
Object.keys(this._assignments)[nameOrNumber];
|
||||
return this._assignments[name];
|
||||
return this._assignments[name] || undefined;
|
||||
},
|
||||
|
||||
/**
|
||||
* Where parameter name == assignment names - they are the same.
|
||||
* Where parameter name == assignment names - they are the same
|
||||
*/
|
||||
Requisition.prototype.getParameterNames = function() {
|
||||
return Object.keys(this._assignments);
|
||||
|
@ -5041,210 +5094,8 @@ ExecutionContext.prototype.createPromise = function() {
|
|||
|
||||
define('gcli/promise', ['require', 'exports', 'module' ], function(require, exports, module) {
|
||||
|
||||
|
||||
/**
|
||||
* Create an unfulfilled promise
|
||||
* @constructor
|
||||
*/
|
||||
function Promise() {
|
||||
this._status = Promise.PENDING;
|
||||
this._value = undefined;
|
||||
this._onSuccessHandlers = [];
|
||||
this._onErrorHandlers = [];
|
||||
|
||||
// Debugging help
|
||||
this._id = Promise._nextId++;
|
||||
Promise._outstanding[this._id] = this;
|
||||
};
|
||||
|
||||
/**
|
||||
* We give promises and ID so we can track which are outstanding
|
||||
*/
|
||||
Promise._nextId = 0;
|
||||
|
||||
/**
|
||||
* Outstanding promises. Handy list for debugging only.
|
||||
*/
|
||||
Promise._outstanding = [];
|
||||
|
||||
/**
|
||||
* Recently resolved promises. Also for debugging only.
|
||||
*/
|
||||
Promise._recent = [];
|
||||
|
||||
/**
|
||||
* A promise can be in one of 2 states.
|
||||
* The ERROR and SUCCESS states are terminal, the PENDING state is the only
|
||||
* start state.
|
||||
*/
|
||||
Promise.ERROR = -1;
|
||||
Promise.PENDING = 0;
|
||||
Promise.SUCCESS = 1;
|
||||
|
||||
/**
|
||||
* Yeay for RTTI.
|
||||
*/
|
||||
Promise.prototype.isPromise = true;
|
||||
|
||||
/**
|
||||
* Have we either been resolve()ed or reject()ed?
|
||||
*/
|
||||
Promise.prototype.isComplete = function() {
|
||||
return this._status != Promise.PENDING;
|
||||
};
|
||||
|
||||
/**
|
||||
* Have we resolve()ed?
|
||||
*/
|
||||
Promise.prototype.isResolved = function() {
|
||||
return this._status == Promise.SUCCESS;
|
||||
};
|
||||
|
||||
/**
|
||||
* Have we reject()ed?
|
||||
*/
|
||||
Promise.prototype.isRejected = function() {
|
||||
return this._status == Promise.ERROR;
|
||||
};
|
||||
|
||||
/**
|
||||
* Take the specified action of fulfillment of a promise, and (optionally)
|
||||
* a different action on promise rejection.
|
||||
*/
|
||||
Promise.prototype.then = function(onSuccess, onError) {
|
||||
if (typeof onSuccess === 'function') {
|
||||
if (this._status === Promise.SUCCESS) {
|
||||
onSuccess.call(null, this._value);
|
||||
} else if (this._status === Promise.PENDING) {
|
||||
this._onSuccessHandlers.push(onSuccess);
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof onError === 'function') {
|
||||
if (this._status === Promise.ERROR) {
|
||||
onError.call(null, this._value);
|
||||
} else if (this._status === Promise.PENDING) {
|
||||
this._onErrorHandlers.push(onError);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Like then() except that rather than returning <tt>this</tt> we return
|
||||
* a promise which resolves when the original promise resolves.
|
||||
*/
|
||||
Promise.prototype.chainPromise = function(onSuccess) {
|
||||
var chain = new Promise();
|
||||
chain._chainedFrom = this;
|
||||
this.then(function(data) {
|
||||
try {
|
||||
chain.resolve(onSuccess(data));
|
||||
} catch (ex) {
|
||||
chain.reject(ex);
|
||||
}
|
||||
}, function(ex) {
|
||||
chain.reject(ex);
|
||||
});
|
||||
return chain;
|
||||
};
|
||||
|
||||
/**
|
||||
* Supply the fulfillment of a promise
|
||||
*/
|
||||
Promise.prototype.resolve = function(data) {
|
||||
return this._complete(this._onSuccessHandlers, Promise.SUCCESS, data, 'resolve');
|
||||
};
|
||||
|
||||
/**
|
||||
* Renege on a promise
|
||||
*/
|
||||
Promise.prototype.reject = function(data) {
|
||||
return this._complete(this._onErrorHandlers, Promise.ERROR, data, 'reject');
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal method to be called on resolve() or reject().
|
||||
* @private
|
||||
*/
|
||||
Promise.prototype._complete = function(list, status, data, name) {
|
||||
// Complain if we've already been completed
|
||||
if (this._status != Promise.PENDING) {
|
||||
console.group('Promise already closed');
|
||||
console.error('Attempted ' + name + '() with ', data);
|
||||
console.error('Previous status = ', this._status,
|
||||
', previous value = ', this._value);
|
||||
console.trace();
|
||||
|
||||
console.groupEnd();
|
||||
return this;
|
||||
}
|
||||
|
||||
this._status = status;
|
||||
this._value = data;
|
||||
|
||||
// Call all the handlers, and then delete them
|
||||
list.forEach(function(handler) {
|
||||
handler.call(null, this._value);
|
||||
}, this);
|
||||
delete this._onSuccessHandlers;
|
||||
delete this._onErrorHandlers;
|
||||
|
||||
// Remove the given {promise} from the _outstanding list, and add it to the
|
||||
// _recent list, pruning more than 20 recent promises from that list.
|
||||
delete Promise._outstanding[this._id];
|
||||
Promise._recent.push(this);
|
||||
while (Promise._recent.length > 20) {
|
||||
Promise._recent.shift();
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Takes an array of promises and returns a promise that that is fulfilled once
|
||||
* all the promises in the array are fulfilled
|
||||
* @param promiseList The array of promises
|
||||
* @return the promise that is fulfilled when all the array is fulfilled
|
||||
*/
|
||||
Promise.group = function(promiseList) {
|
||||
if (!(promiseList instanceof Array)) {
|
||||
promiseList = Array.prototype.slice.call(arguments);
|
||||
}
|
||||
|
||||
// If the original array has nothing in it, return now to avoid waiting
|
||||
if (promiseList.length === 0) {
|
||||
return new Promise().resolve([]);
|
||||
}
|
||||
|
||||
var groupPromise = new Promise();
|
||||
var results = [];
|
||||
var fulfilled = 0;
|
||||
|
||||
var onSuccessFactory = function(index) {
|
||||
return function(data) {
|
||||
results[index] = data;
|
||||
fulfilled++;
|
||||
// If the group has already failed, silently drop extra results
|
||||
if (groupPromise._status !== Promise.ERROR) {
|
||||
if (fulfilled === promiseList.length) {
|
||||
groupPromise.resolve(results);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
promiseList.forEach(function(promise, index) {
|
||||
var onSuccess = onSuccessFactory(index);
|
||||
var onError = groupPromise.reject.bind(groupPromise);
|
||||
promise.then(onSuccess, onError);
|
||||
});
|
||||
|
||||
return groupPromise;
|
||||
};
|
||||
|
||||
exports.Promise = Promise;
|
||||
Components.utils.import("resource:///modules/devtools/Promise.jsm");
|
||||
exports.Promise = Promise;
|
||||
|
||||
});
|
||||
/*
|
||||
|
|
|
@ -145,8 +145,9 @@ _BROWSER_TEST_FILES = \
|
|||
browser_webconsole_bug_659907_console_dir.js \
|
||||
browser_webconsole_bug_678816.js \
|
||||
browser_webconsole_bug_664131_console_group.js \
|
||||
browser_gcli_require.js \
|
||||
browser_gcli_inspect.js \
|
||||
browser_gcli_integrate.js \
|
||||
browser_gcli_require.js \
|
||||
browser_gcli_web.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
@ -218,6 +219,7 @@ _BROWSER_TEST_PAGES = \
|
|||
test-bug-646025-console-file-location.html \
|
||||
test-bug-678816-content.js \
|
||||
test-file-location.js \
|
||||
browser_gcli_inspect.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_BROWSER_TEST_FILES)
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>GCLI inspect command test</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- This is a list of 0 h1 elements -->
|
||||
|
||||
<!-- This is a list of 1 div elements -->
|
||||
<div>Hello, I'm a div</div>
|
||||
|
||||
<!-- This is a list of 2 span elements -->
|
||||
<span>Hello, I'm a span</span>
|
||||
<span>And me</span>
|
||||
|
||||
<!-- This is a collection of various things that match only once -->
|
||||
<p class="someclass">.someclass</p>
|
||||
<p id="someid">#someid</p>
|
||||
<button disabled>button[disabled]</button>
|
||||
<p><strong>p>strong</strong></p>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,93 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// For more information on GCLI see:
|
||||
// - https://github.com/mozilla/gcli/blob/master/docs/index.md
|
||||
// - https://wiki.mozilla.org/DevTools/Features/GCLI
|
||||
|
||||
// Tests that the inspect command works as it should
|
||||
|
||||
Components.utils.import("resource:///modules/gcli.jsm");
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gcliterm = undefined;
|
||||
requisition = undefined;
|
||||
|
||||
Services.prefs.clearUserPref("devtools.gcli.enable");
|
||||
});
|
||||
|
||||
function test() {
|
||||
Services.prefs.setBoolPref("devtools.gcli.enable", true);
|
||||
addTab("http://example.com/browser/browser/devtools/webconsole/test/browser/browser_gcli_inspect.html");
|
||||
browser.addEventListener("DOMContentLoaded", onLoad, false);
|
||||
}
|
||||
|
||||
let gcliterm;
|
||||
let requisition;
|
||||
|
||||
function onLoad() {
|
||||
browser.removeEventListener("DOMContentLoaded", onLoad, false);
|
||||
|
||||
try {
|
||||
openConsole();
|
||||
|
||||
let hud = HUDService.getHudByWindow(content);
|
||||
gcliterm = hud.gcliterm;
|
||||
requisition = gcliterm.opts.requisition;
|
||||
|
||||
testSetup();
|
||||
testCreateCommands();
|
||||
}
|
||||
catch (ex) {
|
||||
ok(false, "Caught exception: " + ex)
|
||||
gcli._internal.console.error("Test Failure", ex);
|
||||
}
|
||||
finally {
|
||||
closeConsole();
|
||||
finishTest();
|
||||
}
|
||||
}
|
||||
|
||||
function testSetup() {
|
||||
ok(gcliterm, "We have a GCLI term");
|
||||
ok(requisition, "We have a Requisition");
|
||||
}
|
||||
|
||||
function testCreateCommands() {
|
||||
type("inspec");
|
||||
is(gcliterm.completeNode.textContent, " inspect", "Completion for \"inspec\"");
|
||||
is(requisition.getStatus().toString(), "ERROR", "inspec is ERROR");
|
||||
|
||||
type("inspect");
|
||||
is(requisition.getStatus().toString(), "ERROR", "inspect is ERROR");
|
||||
|
||||
type("inspect h1");
|
||||
is(requisition.getStatus().toString(), "ERROR", "inspect h1 is ERROR");
|
||||
|
||||
type("inspect span");
|
||||
is(requisition.getStatus().toString(), "ERROR", "inspect span is ERROR");
|
||||
|
||||
type("inspect div");
|
||||
is(requisition.getStatus().toString(), "VALID", "inspect div is VALID");
|
||||
|
||||
type("inspect .someclass");
|
||||
is(requisition.getStatus().toString(), "VALID", "inspect .someclass is VALID");
|
||||
|
||||
type("inspect #someid");
|
||||
is(requisition.getStatus().toString(), "VALID", "inspect #someid is VALID");
|
||||
|
||||
type("inspect button[disabled]");
|
||||
is(requisition.getStatus().toString(), "VALID", "inspect button[disabled] is VALID");
|
||||
|
||||
type("inspect p>strong");
|
||||
is(requisition.getStatus().toString(), "VALID", "inspect p>strong is VALID");
|
||||
|
||||
type("inspect :root");
|
||||
is(requisition.getStatus().toString(), "VALID", "inspect :root is VALID");
|
||||
}
|
||||
|
||||
function type(command) {
|
||||
gcliterm.inputNode.value = command.slice(0, -1);
|
||||
gcliterm.inputNode.focus();
|
||||
EventUtils.synthesizeKey(command.slice(-1), {});
|
||||
}
|
|
@ -54,7 +54,7 @@ var Node = Components.interfaces.nsIDOMNode;
|
|||
* http://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
define('gclitest/index', ['require', 'exports', 'module' , 'gcli/index', 'test/examiner', 'gclitest/testTokenize', 'gclitest/testSplit', 'gclitest/testCli', 'gclitest/testHistory', 'gclitest/testRequire'], function(require, exports, module) {
|
||||
define('gclitest/suite', ['require', 'exports', 'module' , 'gcli/index', 'test/examiner', 'gclitest/testTokenize', 'gclitest/testSplit', 'gclitest/testCli', 'gclitest/testHistory', 'gclitest/testRequire'], function(require, exports, module) {
|
||||
|
||||
// We need to make sure GCLI is initialized before we begin testing it
|
||||
require('gcli/index');
|
||||
|
@ -65,7 +65,6 @@ define('gclitest/index', ['require', 'exports', 'module' , 'gcli/index', 'test/e
|
|||
examiner.addSuite('gclitest/testSplit', require('gclitest/testSplit'));
|
||||
examiner.addSuite('gclitest/testCli', require('gclitest/testCli'));
|
||||
examiner.addSuite('gclitest/testHistory', require('gclitest/testHistory'));
|
||||
|
||||
examiner.addSuite('gclitest/testRequire', require('gclitest/testRequire'));
|
||||
|
||||
examiner.run();
|
||||
|
@ -1373,7 +1372,7 @@ define('gclitest/requirable', ['require', 'exports', 'module' ], function(requir
|
|||
});
|
||||
|
||||
function undefine() {
|
||||
delete define.modules['gclitest/index'];
|
||||
delete define.modules['gclitest/suite'];
|
||||
delete define.modules['test/examiner'];
|
||||
delete define.modules['gclitest/testTokenize'];
|
||||
delete define.modules['test/assert'];
|
||||
|
@ -1384,7 +1383,7 @@ function undefine() {
|
|||
delete define.modules['gclitest/testRequire'];
|
||||
delete define.modules['gclitest/requirable'];
|
||||
|
||||
delete define.globalDomain.modules['gclitest/index'];
|
||||
delete define.globalDomain.modules['gclitest/suite'];
|
||||
delete define.globalDomain.modules['test/examiner'];
|
||||
delete define.globalDomain.modules['gclitest/testTokenize'];
|
||||
delete define.globalDomain.modules['test/assert'];
|
||||
|
|
|
@ -229,6 +229,7 @@ greprefs/xpinstall.js
|
|||
install.rdf
|
||||
modules/ISO8601DateUtils.jsm
|
||||
modules/JSON.jsm
|
||||
modules/utils.js
|
||||
mozilla-runtime@BIN_SUFFIX@
|
||||
old-homepage-default.properties
|
||||
README.txt
|
||||
|
@ -923,6 +924,42 @@ xpicleanup@BIN_SUFFIX@
|
|||
defaults/profile/mimeTypes.rdf
|
||||
defaults/profile/prefs.js
|
||||
greprefs.js
|
||||
hyphenation/
|
||||
hyphenation/hyph_af.dic
|
||||
hyphenation/hyph_bg.dic
|
||||
hyphenation/hyph_ca.dic
|
||||
hyphenation/hyph_cy.dic
|
||||
hyphenation/hyph_da.dic
|
||||
hyphenation/hyph_de-1901.dic
|
||||
hyphenation/hyph_de-1996.dic
|
||||
hyphenation/hyph_de-CH.dic
|
||||
hyphenation/hyph_en_US.dic
|
||||
hyphenation/hyph_eo.dic
|
||||
hyphenation/hyph_es.dic
|
||||
hyphenation/hyph_et.dic
|
||||
hyphenation/hyph_fi.dic
|
||||
hyphenation/hyph_fr.dic
|
||||
hyphenation/hyph_gl.dic
|
||||
hyphenation/hyph_hr.dic
|
||||
hyphenation/hyph_hsb.dic
|
||||
hyphenation/hyph_hu.dic
|
||||
hyphenation/hyph_ia.dic
|
||||
hyphenation/hyph_is.dic
|
||||
hyphenation/hyph_it.dic
|
||||
hyphenation/hyph_kmr.dic
|
||||
hyphenation/hyph_la.dic
|
||||
hyphenation/hyph_lt.dic
|
||||
hyphenation/hyph_mn.dic
|
||||
hyphenation/hyph_nb.dic
|
||||
hyphenation/hyph_nl.dic
|
||||
hyphenation/hyph_nn.dic
|
||||
hyphenation/hyph_pt.dic
|
||||
hyphenation/hyph_ru.dic
|
||||
hyphenation/hyph_sh.dic
|
||||
hyphenation/hyph_sl.dic
|
||||
hyphenation/hyph_sv.dic
|
||||
hyphenation/hyph_tr.dic
|
||||
hyphenation/hyph_uk.dic
|
||||
modules/AddonLogging.jsm
|
||||
modules/AddonManager.jsm
|
||||
modules/AddonRepository.jsm
|
||||
|
@ -997,7 +1034,6 @@ xpicleanup@BIN_SUFFIX@
|
|||
modules/tabview/AllTabs.jsm
|
||||
modules/tabview/groups.jsm
|
||||
modules/tabview/utils.jsm
|
||||
modules/utils.js
|
||||
modules/WindowDraggingUtils.jsm
|
||||
#ifdef XP_WIN
|
||||
modules/WindowsJumpLists.jsm
|
||||
|
|
|
@ -90,6 +90,7 @@ can reach it easily. -->
|
|||
<!ENTITY fullScreenAutohide.accesskey "H">
|
||||
<!ENTITY fullScreenExit.label "Exit Full Screen Mode">
|
||||
<!ENTITY fullScreenExit.accesskey "F">
|
||||
<!ENTITY domFullScreenWarning.label "Press ESC to leave full-screen mode">
|
||||
|
||||
<!ENTITY closeWindow.label "Close Window">
|
||||
<!ENTITY closeWindow.accesskey "d">
|
||||
|
|
|
@ -35,3 +35,25 @@ consoleManual=Filter, clear and close the web console
|
|||
# LOCALIZATION NOTE (consoleclearDesc) A very short string used to describe the
|
||||
# function of the 'console clear' command.
|
||||
consoleclearDesc=Clear the console
|
||||
|
||||
# LOCALIZATION NOTE (inspectDesc) A very short description of the 'inspect'
|
||||
# command. See inspectManual for a fuller description of what it does. This
|
||||
# string is designed to be shown in a menu alongside the command name, which
|
||||
# is why it should be as short as possible.
|
||||
inspectDesc=Inspect a node
|
||||
|
||||
# LOCALIZATION NOTE (inspectManual) A fuller description of the 'inspect'
|
||||
# command, displayed when the user asks for help on what it does.
|
||||
inspectManual=Investigate the dimensions and properties of an element using \
|
||||
a CSS selector to open the DOM highlighter
|
||||
|
||||
# LOCALIZATION NOTE (inspectNodeDesc) A very short string to describe the
|
||||
# 'node' parameter to the 'inspect' command, which is displayed in a dialog
|
||||
# when the user is using this command.
|
||||
inspectNodeDesc=CSS selector
|
||||
|
||||
# LOCALIZATION NOTE (inspectNodeManual) A fuller description of the 'node'
|
||||
# parameter to the 'inspect' command, displayed when the user asks for help
|
||||
# on what it does.
|
||||
inspectNodeManual=A CSS selector for use with Document.querySelector which \
|
||||
identifies a single element
|
||||
|
|
|
@ -7,6 +7,7 @@ confirmNavigationAway.buttonLeaveAccesskey=L
|
|||
confirmNavigationAway.buttonStay=Stay on Page
|
||||
confirmNavigationAway.buttonStayAccesskey=S
|
||||
|
||||
breadcrumbs.siblings=Siblings
|
||||
# LOCALIZATION NOTE (htmlPanel): Used in the Inspector tool's openInspectorUI
|
||||
# method when registering the HTML panel.
|
||||
|
|
@ -95,22 +95,23 @@
|
|||
<!ENTITY browserContext.label "Browser">
|
||||
<!ENTITY browserContext.accesskey "B">
|
||||
|
||||
<!-- LOCALIZATION NOTE (resetContext.label): This command allows the developer
|
||||
<!-- LOCALIZATION NOTE (resetContext2.label): This command allows the developer
|
||||
- to reset/clear the global object of the environment where the code executes.
|
||||
-->
|
||||
<!ENTITY resetContext.label "Reset">
|
||||
<!ENTITY resetContext.accesskey "R">
|
||||
<!ENTITY resetContext2.label "Reset Variables">
|
||||
<!ENTITY resetContext2.accesskey "T">
|
||||
|
||||
<!ENTITY executeMenu.label "Execute">
|
||||
<!ENTITY executeMenu.accesskey "X">
|
||||
|
||||
<!ENTITY toolsMenu.label "Tools">
|
||||
<!ENTITY toolsMenu.accesskey "T">
|
||||
|
||||
<!ENTITY errorConsoleCmd.label "Error Console">
|
||||
<!ENTITY errorConsoleCmd.accesskey "C">
|
||||
<!-- LOCALIZATION NOTE (errorConsoleCmd.commandkey): This command key launches
|
||||
- the browser Error Console, the key should be identical to the property of
|
||||
- the same name in browser.dtd.
|
||||
-->
|
||||
<!ENTITY errorConsoleCmd.commandkey "j">
|
||||
|
||||
<!ENTITY webConsoleCmd.label "Web Console">
|
||||
<!ENTITY webConsoleCmd.accesskey "W">
|
||||
<!-- LOCALIZATION NOTE (webConsoleCmd.commandkey): This command key launches
|
||||
- the browser WebConsole, the key should be identical to the property of
|
||||
- the same name in browser.dtd.
|
||||
-->
|
||||
<!ENTITY webConsoleCmd.commandkey "k">
|
|
@ -33,3 +33,7 @@ saveFile.failed=The file save operation failed.
|
|||
# how to use the Scratchpad. Note that this should be a valid JavaScript
|
||||
# comment inside /* and */.
|
||||
scratchpadIntro=/*\n * This is a JavaScript Scratchpad.\n *\n * Enter some JavaScript, then Right Click or choose from the Execute Menu:\n * 1. Run to evaluate the selected text,\n * 2. Inspect to bring up an Object Inspector on the result, or,\n * 3. Display to insert the result in a comment after the selection.\n */\n\n
|
||||
|
||||
# LOCALIZATION NOTE (notification.browserContext): This is the message displayed
|
||||
# over the top of the editor when the user has switched to browser context.
|
||||
browserContext.notification=This scratchpad executes in the Browser context.
|
|
@ -0,0 +1,174 @@
|
|||
typeError=Error:
|
||||
typeWarning=Warning:
|
||||
typeNetwork=Network:
|
||||
typeException=Exception:
|
||||
typeCssParser=CSS Parser:
|
||||
typeStrict=Strict Warning:
|
||||
msgCategory=Category:
|
||||
errLine=Line: %S
|
||||
btnHide=Hide
|
||||
btnPrefs=Preferences
|
||||
categoryPage=Page:
|
||||
categoryConsole=Console:
|
||||
btnMutation=DOM Mutation
|
||||
tipMutation=Toggle DOM Mutation event logging
|
||||
btnPageNet=Net
|
||||
tipPageNet=Log network access
|
||||
btnPageCSS=CSS
|
||||
tipPageCSS=Log CSS parsing errors
|
||||
btnPageJS=JS
|
||||
tipPageJS=Log JavaScript exceptions
|
||||
# LOCALIZATION NOTE (btnPageWebDeveloper):
|
||||
#
|
||||
# This is used as the text of the "Web Developer" button on the toolbar. It
|
||||
# shows or hides messages that the web developer inserted on the page for
|
||||
# debugging purposes, using calls such console.log() and console.error(). You
|
||||
# may wish to localize this as "Page" if that is clearer in your locale. See
|
||||
# bug 601667 for more information.
|
||||
btnPageWebDeveloper=Web Developer
|
||||
# LOCALIZATION NOTE (tipPageWebDeveloper):
|
||||
#
|
||||
# This is used as the text of the tool tip for the "Web Developer" button on
|
||||
# the toolbar.
|
||||
tipPageWebDeveloper=Log messages sent to the "console" object
|
||||
btnConsoleErrors=Errors
|
||||
tipConsoleErrors=Log calls to console.error()
|
||||
btnConsoleInfo=Info
|
||||
tipConsoleInfo=Log calls to console.info()
|
||||
btnConsoleWarnings=Warnings
|
||||
tipConsoleWarnings=Log calls to console.warn()
|
||||
btnConsoleLog=Log
|
||||
tipConsoleLog=Log calls to console.log()
|
||||
btnGlobal=Global Messages
|
||||
tipGlobal=Toggle Global Message logging
|
||||
localConsole=Local Console
|
||||
clearConsoleCmd.label=Clear Console
|
||||
clearConsoleCmd.accesskey=e
|
||||
# LOCALIZATION NOTE (btnClear):
|
||||
#
|
||||
# This is used as the text of the "Clear" button for the toolbar. It clears the
|
||||
# contents of the console.
|
||||
btnClear=Clear
|
||||
stringFilter=Filter
|
||||
close.button=Close
|
||||
close.accesskey=C
|
||||
update.button=Update
|
||||
update.accesskey=U
|
||||
# LOCALIZATION NOTE FOR `jsPropertyTitle` AND `jsPropertyInspectTitle`:
|
||||
#
|
||||
# The "PropertyPanel" is used to display a JS object to the user.
|
||||
# If it is clear which object is being inspected (e.g., window, document object)
|
||||
# the title of the panel is based on the `jsPropertyInspectTitle` string.
|
||||
# If it isn't clear which object is being inspected, the `jsPropertyTitle` string
|
||||
# gets used. This can be the case when the user logs an object to the WebConsole
|
||||
# output using the console.log(aObjectToInspect) method.
|
||||
#
|
||||
# You can find a screenshot of the PropertyPanel here:
|
||||
# https://bug585030.bugzilla.mozilla.org/attachment.cgi?id=464034
|
||||
jsPropertyTitle=Object Inspector
|
||||
# LOCALIZATION NOTE (jsPropertyInspectTitle):
|
||||
#
|
||||
# The %S is replaced by the evaluated code the user clicked on in the console.
|
||||
#
|
||||
# Example: The user executed `window.document` in the WebConsole. The `document`
|
||||
# object is written to the output. If the user clicks on the `document` output
|
||||
# in the console, a PropertyPanel will show up. The title of the PropertyPanel
|
||||
# is set to `Inspect: window.document` because the clicked `document` object was
|
||||
# evaluated based on the `window.document` string.
|
||||
jsPropertyInspectTitle=Inspect: %S
|
||||
saveBodies.label=Log Request and Response Bodies
|
||||
saveBodies.accesskey=L
|
||||
copyCmd.label=Copy
|
||||
copyCmd.accesskey=C
|
||||
selectAllCmd.label=Select All
|
||||
selectAllCmd.accesskey=A
|
||||
# LOCALIZATION NOTE (timestampFormat): %1$02S = hours (24-hour clock),
|
||||
# %2$02S = minutes, %3$02S = seconds, %4$03S = milliseconds.
|
||||
timestampFormat=%02S:%02S:%02S.%03S
|
||||
|
||||
helperFuncUnsupportedTypeError=Can't call pprint on this type of object.
|
||||
NetworkPanel.label=Inspect Network Request
|
||||
# LOCALIZATION NOTE (NetworkPanel.deltaDurationMS):
|
||||
#
|
||||
# This string is used to show the duration between two network events (e.g
|
||||
# request and respones header or response header and response body).
|
||||
NetworkPanel.durationMS=%Sms
|
||||
# LOCALIZATION NOTE (NetworkPanel.imageSizeDeltaDurationMS):
|
||||
# This string is used to show the duration between the response header and the
|
||||
# response body event. It also shows the size of the received or cached image.
|
||||
#
|
||||
# The first %S is replace by the width of the inspected image.
|
||||
# The second %S is replaced by the height of the inspected image.
|
||||
# The third %S is replaced by the duration between the response header and the
|
||||
# response body event.
|
||||
NetworkPanel.imageSizeDeltaDurationMS=%Sx%Spx, Δ%Sms
|
||||
# LOCALIZATION NOTE (NetworkPanel.responseBodyUnableToDisplay.content):
|
||||
#
|
||||
# This string is displayed within the response body section of the NetworkPanel
|
||||
# if the content type of the network request can't be displayed in the
|
||||
# NetworkPanel. E.g. any kind of text is easy to display, but some audio or
|
||||
# flash data received from the server can't be displayed.
|
||||
#
|
||||
# The %S is replaced by the content type, that can't be displayed, examples are
|
||||
# o application/x-shockwave-flash
|
||||
# o music/crescendo
|
||||
NetworkPanel.responseBodyUnableToDisplay.content=Unable to display responses of type "%S"
|
||||
ConsoleAPIDisabled=The Web Console logging API (console.log, console.info, console.warn, console.error) has been disabled by a script on this page.
|
||||
|
||||
# LOCALIZATION NOTE (inspectStyle.nullObjectPassed):
|
||||
# This message is returned when a null object is passed in to inspectstyle()
|
||||
inspectStyle.nullObjectPassed=Object is null
|
||||
|
||||
# LOCALIZATION NOTE (inspectStyle.mustBeDomNode):
|
||||
# This message is returned when a non-DOM node is passed in to inspectstyle()
|
||||
inspectStyle.mustBeDomNode=Object must be a valid DOM node
|
||||
|
||||
# LOCALIZATION NOTE (inspectStyle.nodeHasNoStyleProps):
|
||||
# This message is returned when an unstyleable object is passed in to inspectstyle()
|
||||
inspectStyle.nodeHasNoStyleProps=Object cannot be styled
|
||||
|
||||
# LOCALIZATION NOTE (inspectStyle.styleInspectorNotEnabled):
|
||||
# This message is returned when devtools.styleinspector.enabled is not set to
|
||||
# true
|
||||
inspectStyle.styleInspectorNotEnabled=The style inspector is not enabled. Please set the option devtools.styleinspector.enabled to true in about:config to use this command.
|
||||
|
||||
# LOCALIZATION NOTE (webConsolePosition): The label shown for the menu which
|
||||
# allows the user to toggle between the Web Console positioning types.
|
||||
webConsolePosition=Position
|
||||
|
||||
# LOCALIZATION NOTE (webConsolePositionTooltip): The tooltip shown when the user
|
||||
# hovers the Position button in the Web Console toolbar.
|
||||
webConsolePositionTooltip=Position the Web Console above or below the document
|
||||
|
||||
# LOCALIZATION NOTE (webConsolePositionAbove): When this option is selected the
|
||||
# Web Console interface is displayed above the web page.
|
||||
webConsolePositionAbove=Above
|
||||
|
||||
# LOCALIZATION NOTE (webConsolePositionBelow): When this option is selected the
|
||||
# Web Console interface is displayed below the web page.
|
||||
webConsolePositionBelow=Below
|
||||
|
||||
# LOCALIZATION NOTE (webConsolePositionWindow): When this option is selected the
|
||||
# Web Console interface is displayed in a floating panel.
|
||||
webConsolePositionWindow=Window
|
||||
|
||||
# LOCALIZATION NOTE (webConsoleWindowTitleAndURL): The Web Console floating
|
||||
# panel title, followed by the web page URL.
|
||||
# For RTL languages you need to set the LRM in the string to give the URL
|
||||
# the correct direction.
|
||||
webConsoleWindowTitleAndURL=Web Console - %S
|
||||
|
||||
# LOCALIZATION NOTE (Autocomplete.label):
|
||||
# The autocomplete popup panel label/title.
|
||||
Autocomplete.label=Autocomplete popup
|
||||
|
||||
# LOCALIZATION NOTE (stacktrace.anonymousFunction):
|
||||
# This string is used to display JavaScript functions that have no given name -
|
||||
# they are said to be anonymous. See stacktrace.outputMessage.
|
||||
stacktrace.anonymousFunction=<anonymous>
|
||||
|
||||
# LOCALIZATION NOTE (stacktrace.outputMessage):
|
||||
# This string is used in the Web Console output to identify a web developer call
|
||||
# to console.trace(). The stack trace of JavaScript function calls is displayed.
|
||||
# In this minimal message we only show the last call.
|
||||
stacktrace.outputMessage=Stack trace from %S, function %S, line %S.
|
|
@ -0,0 +1,11 @@
|
|||
<!ENTITY % brandDTD
|
||||
SYSTEM "chrome://branding/locale/brand.dtd">
|
||||
%brandDTD;
|
||||
|
||||
<!-- These strings are used in the sync progress upload page -->
|
||||
<!ENTITY syncProgress.pageTitle "Your First Sync">
|
||||
<!ENTITY syncProgress.textBlurb "Your data is now being encrypted and uploaded in the background. You can close this tab and continue using &brandShortName;.">
|
||||
<!ENTITY syncProgress.closeButton "Close">
|
||||
<!ENTITY syncProgress.logoAltText "&brandShortName; logo">
|
||||
<!ENTITY syncProgress.diffText "&brandShortName; will now automatically sync in the background. You can close this tab and continue using &brandShortName;.">
|
||||
|
|
@ -9,18 +9,21 @@
|
|||
locale/browser/aboutHome.dtd (%chrome/browser/aboutHome.dtd)
|
||||
locale/browser/aboutSessionRestore.dtd (%chrome/browser/aboutSessionRestore.dtd)
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
locale/browser/syncProgress.dtd (%chrome/browser/syncProgress.dtd)
|
||||
locale/browser/aboutSyncTabs.dtd (%chrome/browser/aboutSyncTabs.dtd)
|
||||
#endif
|
||||
* locale/browser/browser.dtd (%chrome/browser/browser.dtd)
|
||||
locale/browser/baseMenuOverlay.dtd (%chrome/browser/baseMenuOverlay.dtd)
|
||||
locale/browser/browser.properties (%chrome/browser/browser.properties)
|
||||
locale/browser/devtools/gcli.properties (%chrome/browser/devtools/gcli.properties)
|
||||
locale/browser/devtools/gclicommands.properties (%chrome/browser/devtools/gclicommands.properties)
|
||||
locale/browser/styleinspector.properties (%chrome/browser/styleinspector.properties)
|
||||
locale/browser/styleinspector.dtd (%chrome/browser/styleinspector.dtd)
|
||||
locale/browser/scratchpad.properties (%chrome/browser/scratchpad.properties)
|
||||
locale/browser/scratchpad.dtd (%chrome/browser/scratchpad.dtd)
|
||||
locale/browser/inspector.properties (%chrome/browser/inspector.properties)
|
||||
locale/browser/devtools/gcli.properties (%chrome/browser/devtools/gcli.properties)
|
||||
locale/browser/devtools/gclicommands.properties (%chrome/browser/devtools/gclicommands.properties)
|
||||
locale/browser/devtools/webconsole.properties (%chrome/browser/devtools/webconsole.properties)
|
||||
locale/browser/devtools/inspector.properties (%chrome/browser/devtools/inspector.properties)
|
||||
locale/browser/devtools/scratchpad.properties (%chrome/browser/devtools/scratchpad.properties)
|
||||
locale/browser/devtools/scratchpad.dtd (%chrome/browser/devtools/scratchpad.dtd)
|
||||
locale/browser/devtools/styleinspector.properties (%chrome/browser/devtools/styleinspector.properties)
|
||||
locale/browser/devtools/styleinspector.dtd (%chrome/browser/devtools/styleinspector.dtd)
|
||||
locale/browser/devtools/webConsole.dtd (%chrome/browser/devtools/webConsole.dtd)
|
||||
locale/browser/openLocation.dtd (%chrome/browser/openLocation.dtd)
|
||||
locale/browser/openLocation.properties (%chrome/browser/openLocation.properties)
|
||||
* locale/browser/pageInfo.dtd (%chrome/browser/pageInfo.dtd)
|
||||
|
|
|
@ -1585,10 +1585,6 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
|||
}
|
||||
|
||||
/* Tab drag and drop */
|
||||
.tab-drag-label {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.tab-drop-indicator {
|
||||
list-style-image: url(chrome://browser/skin/tabbrowser/tabDragIndicator.png);
|
||||
margin-bottom: -11px;
|
||||
|
@ -1958,7 +1954,7 @@ panel[dimmed="true"] {
|
|||
|
||||
#inspector-toolbar {
|
||||
-moz-appearance: none;
|
||||
padding: 4px 3px;
|
||||
padding: 0 3px 4px;
|
||||
border-top: 1px solid hsla(210, 8%, 5%, .65);
|
||||
box-shadow: 0 1px 0 0 hsla(210, 16%, 76%, .2) inset;
|
||||
background-image: -moz-linear-gradient(top, hsl(210,11%,36%), hsl(210,11%,18%));
|
||||
|
@ -2002,15 +1998,35 @@ panel[dimmed="true"] {
|
|||
background-color: hsla(210,8%,5%,.2) !important;
|
||||
}
|
||||
|
||||
/*
|
||||
* need a "bumpy" background image for this!
|
||||
*/
|
||||
#inspector-horizontal-splitter {
|
||||
background: none !important;
|
||||
/* Highlighter - toolbar resizers */
|
||||
|
||||
.inspector-resizer {
|
||||
-moz-appearance: none;
|
||||
cursor: n-resize;
|
||||
}
|
||||
|
||||
.inspector-resizer[disabled] {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#inspector-top-resizer {
|
||||
background: none;
|
||||
height: 4px;
|
||||
}
|
||||
|
||||
#inspector-end-resizer {
|
||||
width: 12px;
|
||||
height: 8px;
|
||||
background-image: -moz-linear-gradient(top, black 1px, rgba(255,255,255,0.2) 1px);
|
||||
background-size: 10px 2px;
|
||||
background-clip: padding-box;
|
||||
background-repeat: repeat-y;
|
||||
border-width: 1px 1px 0;
|
||||
border-style: solid;
|
||||
border-color: rgba(255, 255, 255, 0.05);
|
||||
margin: 7px 7px 8px;
|
||||
}
|
||||
|
||||
/* Highlighter - Node Infobar */
|
||||
|
||||
/* Highlighter - Node Infobar - text */
|
||||
|
@ -2070,3 +2086,181 @@ panel[dimmed="true"] {
|
|||
#highlighter-nodeinfobar-container[hide-arrow] > #highlighter-nodeinfobar {
|
||||
margin: 7px 0;
|
||||
}
|
||||
|
||||
#full-screen-warning-message {
|
||||
background-color: hsl(0,0%,15%);
|
||||
color: white;
|
||||
font-size: 32px;
|
||||
border-radius: 8px;
|
||||
margin-top: 30px;
|
||||
padding: 30px 50px;
|
||||
box-shadow: 0 0 2px white;
|
||||
}
|
||||
|
||||
#full-screen-warning-container[obscure-browser] {
|
||||
background-color: rgba(0,0,0,0.75);
|
||||
}
|
||||
|
||||
#full-screen-warning-container[stop-obscuring-browser] {
|
||||
-moz-transition-property: background-color;
|
||||
-moz-transition-duration: 500ms;
|
||||
background-color: rgba(0,0,0,0);
|
||||
}
|
||||
|
||||
/* Highlighter toolbar - breadcrumbs */
|
||||
|
||||
#inspector-breadcrumbs {
|
||||
padding: 0 6px;
|
||||
/* A fake 1px-shadow is included in the border-images of the
|
||||
inspector-breadcrumbs-buttons, to match toolbar-buttons style.
|
||||
This negative margin compensate the extra row of pixels created
|
||||
by the shadow.*/
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button {
|
||||
-moz-appearance: none;
|
||||
background-color: transparent;
|
||||
border-width: 1px 13px 2px 13px;
|
||||
color: hsl(210,30%,85%);
|
||||
max-width: 85px;
|
||||
/* The content of the button can be larger than the button */
|
||||
overflow: hidden;
|
||||
min-height: 25px;
|
||||
|
||||
margin: 0 -11px 0 0;
|
||||
padding: 0 9px;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button[checked] > .inspector-breadcrumbs-tag {
|
||||
color: hsl(208,100%,60%);
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button[checked] > .inspector-breadcrumbs-id {
|
||||
color: hsl(205,100%,70%);
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-id,
|
||||
.inspector-breadcrumbs-classes {
|
||||
color: #8d99a6;
|
||||
}
|
||||
|
||||
/* Highlighter toolbar - breadcrumbs - LTR */
|
||||
|
||||
.inspector-breadcrumbs-button:-moz-locale-dir(ltr):first-of-type {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button {
|
||||
-moz-border-image: url("chrome://browser/skin/devtools/breadcrumbs/ltr-middle.png") 1 13 2 13 stretch;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button[siblings-menu-open]:not([checked]),
|
||||
.inspector-breadcrumbs-button:not([checked]):hover:active {
|
||||
-moz-border-image: url("chrome://browser/skin/devtools/breadcrumbs/ltr-middle-pressed.png") 1 13 2 13 stretch;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button[checked] {
|
||||
-moz-border-image: url("chrome://browser/skin/devtools/breadcrumbs/ltr-middle-selected.png") 1 13 2 13 stretch;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button[checked][siblings-menu-open],
|
||||
.inspector-breadcrumbs-button[checked]:hover:active {
|
||||
-moz-border-image: url("chrome://browser/skin/devtools/breadcrumbs/ltr-middle-selected-pressed.png") 1 13 2 13 stretch;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button:first-of-type {
|
||||
-moz-border-image: url("chrome://browser/skin/devtools/breadcrumbs/ltr-start.png") 1 13 2 13 stretch;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button[siblings-menu-open]:first-of-type:not([checked]),
|
||||
.inspector-breadcrumbs-button:first-of-type:not([checked]):hover:active {
|
||||
-moz-border-image: url("chrome://browser/skin/devtools/breadcrumbs/ltr-start-pressed.png") 1 13 2 13 stretch;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button:first-of-type[checked] {
|
||||
-moz-border-image: url("chrome://browser/skin/devtools/breadcrumbs/ltr-start-selected.png") 1 13 2 13 stretch;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button[siblings-menu-open]:first-of-type[checked],
|
||||
.inspector-breadcrumbs-button:first-of-type[checked]:hover:active {
|
||||
-moz-border-image: url("chrome://browser/skin/devtools/breadcrumbs/ltr-start-selected-pressed.png") 1 13 2 13 stretch;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button:last-of-type {
|
||||
-moz-border-image: url("chrome://browser/skin/devtools/breadcrumbs/ltr-end.png") 1 13 2 13 stretch;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button[siblings-menu-open]:last-of-type:not([checked]),
|
||||
.inspector-breadcrumbs-button:last-of-type:not([checked]):hover:active {
|
||||
-moz-border-image: url("chrome://browser/skin/devtools/breadcrumbs/ltr-end-pressed.png") 1 13 2 13 stretch;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button:last-of-type[checked] {
|
||||
-moz-border-image: url("chrome://browser/skin/devtools/breadcrumbs/ltr-end-selected.png") 1 13 2 13 stretch;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button[siblings-menu-open]:last-of-type[checked],
|
||||
.inspector-breadcrumbs-button:last-of-type[checked]:hover:active {
|
||||
-moz-border-image: url("chrome://browser/skin/devtools/breadcrumbs/ltr-end-selected-pressed.png") 1 13 2 13 stretch;
|
||||
}
|
||||
|
||||
/* Highlighter toolbar - breadcrumbs - RTL */
|
||||
|
||||
.inspector-breadcrumbs-button:-moz-locale-dir(rtl):first-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button:-moz-locale-dir(rtl) {
|
||||
-moz-border-image: url("chrome://browser/skin/devtools/breadcrumbs/rtl-middle.png") 1 13 2 13 stretch;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button[siblings-menu-open]:not([checked]):-moz-locale-dir(rtl),
|
||||
.inspector-breadcrumbs-button:not([checked]):hover:active:-moz-locale-dir(rtl) {
|
||||
-moz-border-image: url("chrome://browser/skin/devtools/breadcrumbs/rtl-middle-pressed.png") 1 13 2 13 stretch;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button[checked]:-moz-locale-dir(rtl) {
|
||||
-moz-border-image: url("chrome://browser/skin/devtools/breadcrumbs/rtl-middle-selected.png") 1 13 2 13 stretch;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button[checked][siblings-menu-open]:-moz-locale-dir(rtl),
|
||||
.inspector-breadcrumbs-button[checked]:hover:active:-moz-locale-dir(rtl) {
|
||||
-moz-border-image: url("chrome://browser/skin/devtools/breadcrumbs/rtl-middle-selected-pressed.png") 1 13 2 13 stretch;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button:first-of-type:-moz-locale-dir(rtl) {
|
||||
-moz-border-image: url("chrome://browser/skin/devtools/breadcrumbs/rtl-start.png") 1 13 2 13 stretch;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button[siblings-menu-open]:first-of-type:not([checked]):-moz-locale-dir(rtl),
|
||||
.inspector-breadcrumbs-button:first-of-type:not([checked]):hover:active:-moz-locale-dir(rtl) {
|
||||
-moz-border-image: url("chrome://browser/skin/devtools/breadcrumbs/rtl-start-pressed.png") 1 13 2 13 stretch;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button:first-of-type[checked]:-moz-locale-dir(rtl) {
|
||||
-moz-border-image: url("chrome://browser/skin/devtools/breadcrumbs/rtl-start-selected.png") 1 13 2 13 stretch;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button[siblings-menu-open]:first-of-type[checked]:-moz-locale-dir(rtl),
|
||||
.inspector-breadcrumbs-button:first-of-type[checked]:hover:active:-moz-locale-dir(rtl) {
|
||||
-moz-border-image: url("chrome://browser/skin/devtools/breadcrumbs/rtl-start-selected-pressed.png") 1 13 2 13 stretch;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button:last-of-type:-moz-locale-dir(rtl) {
|
||||
-moz-border-image: url("chrome://browser/skin/devtools/breadcrumbs/rtl-end.png") 1 13 2 13 stretch;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button[siblings-menu-open]:last-of-type:not([checked]):-moz-locale-dir(rtl),
|
||||
.inspector-breadcrumbs-button:last-of-type:not([checked]):hover:active:-moz-locale-dir(rtl) {
|
||||
-moz-border-image: url("chrome://browser/skin/devtools/breadcrumbs/rtl-end-pressed.png") 1 13 2 13 stretch;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button:last-of-type[checked]:-moz-locale-dir(rtl) {
|
||||
-moz-border-image: url("chrome://browser/skin/devtools/breadcrumbs/rtl-end-selected.png") 1 13 2 13 stretch;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button[siblings-menu-open]:last-of-type[checked]:-moz-locale-dir(rtl),
|
||||
.inspector-breadcrumbs-button:last-of-type[checked]:hover:active:-moz-locale-dir(rtl) {
|
||||
-moz-border-image: url("chrome://browser/skin/devtools/breadcrumbs/rtl-end-selected-pressed.png") 1 13 2 13 stretch;
|
||||
}
|
||||
|
|
Двоичные данные
browser/themes/gnomestripe/browser/devtools/breadcrumbs/ltr-end-pressed.png
Normal file
После Ширина: | Высота: | Размер: 869 B |
Двоичные данные
browser/themes/gnomestripe/browser/devtools/breadcrumbs/ltr-end-selected-pressed.png
Normal file
После Ширина: | Высота: | Размер: 879 B |
Двоичные данные
browser/themes/gnomestripe/browser/devtools/breadcrumbs/ltr-end-selected.png
Normal file
После Ширина: | Высота: | Размер: 879 B |
После Ширина: | Высота: | Размер: 610 B |
Двоичные данные
browser/themes/gnomestripe/browser/devtools/breadcrumbs/ltr-middle-pressed.png
Normal file
После Ширина: | Высота: | Размер: 1012 B |
Двоичные данные
browser/themes/gnomestripe/browser/devtools/breadcrumbs/ltr-middle-selected-pressed.png
Normal file
После Ширина: | Высота: | Размер: 1.0 KiB |
Двоичные данные
browser/themes/gnomestripe/browser/devtools/breadcrumbs/ltr-middle-selected.png
Normal file
После Ширина: | Высота: | Размер: 982 B |
После Ширина: | Высота: | Размер: 640 B |
Двоичные данные
browser/themes/gnomestripe/browser/devtools/breadcrumbs/ltr-start-pressed.png
Normal file
После Ширина: | Высота: | Размер: 855 B |
Двоичные данные
browser/themes/gnomestripe/browser/devtools/breadcrumbs/ltr-start-selected-pressed.png
Normal file
После Ширина: | Высота: | Размер: 838 B |
Двоичные данные
browser/themes/gnomestripe/browser/devtools/breadcrumbs/ltr-start-selected.png
Normal file
После Ширина: | Высота: | Размер: 858 B |
После Ширина: | Высота: | Размер: 646 B |
Двоичные данные
browser/themes/gnomestripe/browser/devtools/breadcrumbs/rtl-end-pressed.png
Normal file
После Ширина: | Высота: | Размер: 872 B |
Двоичные данные
browser/themes/gnomestripe/browser/devtools/breadcrumbs/rtl-end-selected-pressed.png
Normal file
После Ширина: | Высота: | Размер: 871 B |
Двоичные данные
browser/themes/gnomestripe/browser/devtools/breadcrumbs/rtl-end-selected.png
Normal file
После Ширина: | Высота: | Размер: 871 B |
После Ширина: | Высота: | Размер: 600 B |
Двоичные данные
browser/themes/gnomestripe/browser/devtools/breadcrumbs/rtl-middle-pressed.png
Normal file
После Ширина: | Высота: | Размер: 1004 B |