This commit is contained in:
Phil Ringnalda 2014-04-06 10:41:35 -07:00
Родитель 73e0a8b88b 0cfd4fe15e
Коммит f6c8f279a5
322 изменённых файлов: 5024 добавлений и 1590 удалений

Просмотреть файл

@ -31,9 +31,8 @@ this.AccessFu = {
Utils.init(aWindow);
try {
let bridgeCc = Cc['@mozilla.org/android/bridge;1'];
bridgeCc.getService(Ci.nsIAndroidBridge).handleGeckoMessage(
JSON.stringify({ type: 'Accessibility:Ready' }));
Services.androidBridge.handleGeckoMessage(
{ type: 'Accessibility:Ready' });
Services.obs.addObserver(this, 'Accessibility:Settings', false);
} catch (x) {
// Not on Android
@ -702,8 +701,7 @@ var Output = {
get androidBridge() {
delete this.androidBridge;
if (Utils.MozBuildApp === 'mobile/android') {
this.androidBridge = Cc['@mozilla.org/android/bridge;1'].getService(
Ci.nsIAndroidBridge);
this.androidBridge = Services.androidBridge;
} else {
this.androidBridge = null;
}
@ -734,7 +732,7 @@ var Output = {
androidEvent.brailleOutput = this.brailleState.init(androidEvent.brailleOutput);
break;
}
this.androidBridge.handleGeckoMessage(JSON.stringify(androidEvent));
this.androidBridge.handleGeckoMessage(androidEvent);
}
},
@ -902,9 +900,8 @@ var Input = {
if (Utils.MozBuildApp == 'mobile/android')
// Return focus to native Android browser chrome.
Cc['@mozilla.org/android/bridge;1'].
getService(Ci.nsIAndroidBridge).handleGeckoMessage(
JSON.stringify({ type: 'ToggleChrome:Focus' }));
Services.androidBridge.handleGeckoMessage(
{ type: 'ToggleChrome:Focus' });
break;
case aEvent.DOM_VK_RETURN:
if (this.editState.editing)

Просмотреть файл

@ -1228,7 +1228,7 @@ pref("devtools.webconsole.filter.csserror", true);
pref("devtools.webconsole.filter.cssparser", false);
pref("devtools.webconsole.filter.csslog", false);
pref("devtools.webconsole.filter.exception", true);
pref("devtools.webconsole.filter.jswarn", false);
pref("devtools.webconsole.filter.jswarn", true);
pref("devtools.webconsole.filter.jslog", false);
pref("devtools.webconsole.filter.error", true);
pref("devtools.webconsole.filter.warn", true);

Просмотреть файл

@ -386,6 +386,11 @@ body[narrow] #restorePreviousSession::before {
transform-origin: 0 0;
}
.launchButton:-moz-dir(rtl)::before,
#aboutMozilla:-moz-dir(rtl)::before {
transform: scale(.5) translateX(32px);
}
#downloads::before {
content: url("chrome://browser/content/abouthome/downloads@2x.png");
}
@ -422,6 +427,11 @@ body[narrow] #restorePreviousSession::before {
content: url("chrome://browser/content/abouthome/restore@2x.png");
}
#restorePreviousSession:-moz-dir(rtl)::before {
transform: scale(-0.5, 0.5) translateX(24px);
transform-origin: top center;
}
#aboutMozilla::before {
content: url("chrome://browser/content/abouthome/mozilla@2x.png");
}

Просмотреть файл

@ -884,6 +884,10 @@ let PlacesToolbarHelper = {
if (!viewElt || viewElt._placesView)
return;
// CustomizableUI.addListener is idempotent, so we can safely
// call this multiple times.
CustomizableUI.addListener(this);
// If the bookmarks toolbar item is:
// - not in a toolbar, or;
// - the toolbar is collapsed, or;
@ -899,7 +903,11 @@ let PlacesToolbarHelper = {
if (forceToolbarOverflowCheck) {
viewElt._placesView.updateOverflowStatus();
}
this.customizeChange();
this._setupPlaceholder();
},
uninit: function PTH_uninit() {
CustomizableUI.removeListener(this);
},
customizeStart: function PTH_customizeStart() {
@ -914,10 +922,15 @@ let PlacesToolbarHelper = {
},
customizeChange: function PTH_customizeChange() {
this._setupPlaceholder();
},
_setupPlaceholder: function PTH_setupPlaceholder() {
let placeholder = this._placeholder;
if (!placeholder) {
return;
}
let shouldWrapNow = this._getShouldWrap();
if (this._shouldWrap != shouldWrapNow) {
if (shouldWrapNow) {
@ -958,7 +971,40 @@ let PlacesToolbarHelper = {
element = element.parentNode;
}
return null;
}
},
onWidgetUnderflow: function(aNode, aContainer) {
// The view gets broken by being removed and reinserted by the overflowable
// toolbar, so we have to force an uninit and reinit.
let win = aNode.ownerDocument.defaultView;
if (aNode.id == "personal-bookmarks" && win == window) {
this._resetView();
}
},
onWidgetAdded: function(aWidgetId, aArea, aPosition) {
if (aWidgetId == "personal-bookmarks" && !this._isCustomizing) {
// It's possible (with the "Add to Menu", "Add to Toolbar" context
// options) that the Places Toolbar Items have been moved without
// letting us prepare and handle it with with customizeStart and
// customizeDone. If that's the case, we need to reset the views
// since they're probably broken from the DOM reparenting.
this._resetView();
}
},
_resetView: function() {
if (this._viewElt) {
// It's possible that the placesView might not exist, and we need to
// do a full init. This could happen if the Bookmarks Toolbar Items are
// moved to the Menu Panel, and then to the toolbar with the "Add to Toolbar"
// context menu option, outside of customize mode.
if (this._viewElt._placesView) {
this._viewElt._placesView.uninit();
}
this.init(true);
}
},
};
////////////////////////////////////////////////////////////////////////////////
@ -1164,6 +1210,16 @@ let BookmarkingUI = {
// so kill current view and let popupshowing generate a new one.
if (this.button._placesView)
this.button._placesView.uninit();
// We have to do the same thing for the "special" views underneath the
// the bookmarks menu.
const kSpecialViewNodeIDs = ["BMB_bookmarksToolbar", "BMB_unsortedBookmarks"];
for (let viewNodeID of kSpecialViewNodeIDs) {
let elem = document.getElementById(viewNodeID);
if (elem && elem._placesView) {
elem._placesView.uninit();
}
}
},
onCustomizeStart: function BUI_customizeStart(aWindow) {

Просмотреть файл

@ -1289,6 +1289,8 @@ var gBrowserInit = {
} catch (ex) {
}
PlacesToolbarHelper.uninit();
BookmarkingUI.uninit();
TabsInTitlebar.uninit();

Просмотреть файл

@ -154,7 +154,9 @@ Site.prototype = {
*/
refreshThumbnail: function Site_refreshThumbnail() {
let thumbnail = this._querySelector(".newtab-thumbnail");
thumbnail.style.backgroundColor = this.link.bgColor;
if (this.link.bgColor) {
thumbnail.style.backgroundColor = this.link.bgColor;
}
let uri = this.link.imageURISpec || PageThumbs.getThumbnailURL(this.url);
thumbnail.style.backgroundImage = "url(" + uri + ")";
},

Просмотреть файл

@ -424,7 +424,7 @@
newPrompt.clientTop; // style flush to assure binding is attached
let tab = self._getTabForContentWindow(browser.contentWindow);
let tab = self._getTabForBrowser(browser);
newPrompt.init(args, tab, onCloseCallback);
return newPrompt;
},
@ -3196,7 +3196,13 @@
// We're about to open a modal dialog, make sure the opening
// tab is brought to the front.
this.selectedTab = this._getTabForContentWindow(event.target.top);
// If this is a same-process modal dialog, then we're given its DOM
// window as the event's target. For remote dialogs, we're given the
// browser, but that's in the originalTarget.
// XXX Why originalTarget for the browser?
this.selectedTab = (event.target instanceof Window) ?
this._getTabForContentWindow(event.target.top) :
this._getTabForBrowser(event.originalTarget);
]]>
</handler>
<handler event="DOMTitleChanged">

Просмотреть файл

@ -93,6 +93,10 @@ skip-if = os == "linux"
[browser_978084_dragEnd_after_move.js]
[browser_980155_add_overflow_toolbar.js]
[browser_981418-widget-onbeforecreated-handler.js]
[browser_984455_bookmarks_items_reparenting.js]
skip-if = os == "linux"
[browser_985815_propagate_setToolbarVisibility.js]
[browser_981305_separator_insertion.js]
[browser_987177_destroyWidget_xul.js]

Просмотреть файл

@ -10,7 +10,7 @@ const isOSX = (Services.appinfo.OS === "Darwin");
// show a context menu with options to move it.
add_task(function() {
let contextMenu = document.getElementById("toolbar-context-menu");
let shownPromise = contextMenuShown(contextMenu);
let shownPromise = popupShown(contextMenu);
let homeButton = document.getElementById("home-button");
EventUtils.synthesizeMouse(homeButton, 2, 2, {type: "contextmenu", button: 2 });
yield shownPromise;
@ -30,7 +30,7 @@ add_task(function() {
);
checkContextMenu(contextMenu, expectedEntries);
let hiddenPromise = contextMenuHidden(contextMenu);
let hiddenPromise = popupHidden(contextMenu);
contextMenu.hidePopup();
yield hiddenPromise;
});
@ -40,7 +40,7 @@ add_task(function() {
// and a toggle option for the extra toolbar
add_task(function() {
let contextMenu = document.getElementById("toolbar-context-menu");
let shownPromise = contextMenuShown(contextMenu);
let shownPromise = popupShown(contextMenu);
let toolbar = createToolbarWithPlacements("880164_empty_toolbar", []);
toolbar.setAttribute("context", "toolbar-context-menu");
toolbar.setAttribute("toolbarname", "Fancy Toolbar for Context Menu");
@ -63,7 +63,7 @@ add_task(function() {
);
checkContextMenu(contextMenu, expectedEntries);
let hiddenPromise = contextMenuHidden(contextMenu);
let hiddenPromise = popupHidden(contextMenu);
contextMenu.hidePopup();
yield hiddenPromise;
removeCustomToolbars();
@ -74,7 +74,7 @@ add_task(function() {
// show a context menu with disabled options to move it.
add_task(function() {
let contextMenu = document.getElementById("toolbar-context-menu");
let shownPromise = contextMenuShown(contextMenu);
let shownPromise = popupShown(contextMenu);
let urlBarContainer = document.getElementById("urlbar-container");
// Need to make sure not to click within an edit field.
let urlbarRect = urlBarContainer.getBoundingClientRect();
@ -96,7 +96,7 @@ add_task(function() {
);
checkContextMenu(contextMenu, expectedEntries);
let hiddenPromise = contextMenuHidden(contextMenu);
let hiddenPromise = popupHidden(contextMenu);
contextMenu.hidePopup();
yield hiddenPromise;
});
@ -135,7 +135,7 @@ add_task(function() {
yield shownPanelPromise;
let contextMenu = document.getElementById("customizationPanelItemContextMenu");
let shownContextPromise = contextMenuShown(contextMenu);
let shownContextPromise = popupShown(contextMenu);
let newWindowButton = document.getElementById("new-window-button");
ok(newWindowButton, "new-window-button was found");
EventUtils.synthesizeMouse(newWindowButton, 2, 2, {type: "contextmenu", button: 2});
@ -151,7 +151,7 @@ add_task(function() {
];
checkContextMenu(contextMenu, expectedEntries);
let hiddenContextPromise = contextMenuHidden(contextMenu);
let hiddenContextPromise = popupHidden(contextMenu);
contextMenu.hidePopup();
yield hiddenContextPromise;
@ -165,7 +165,7 @@ add_task(function() {
add_task(function() {
yield startCustomizing();
let contextMenu = document.getElementById("toolbar-context-menu");
let shownPromise = contextMenuShown(contextMenu);
let shownPromise = popupShown(contextMenu);
let homeButton = document.getElementById("wrapper-home-button");
EventUtils.synthesizeMouse(homeButton, 2, 2, {type: "contextmenu", button: 2});
yield shownPromise;
@ -185,7 +185,7 @@ add_task(function() {
);
checkContextMenu(contextMenu, expectedEntries);
let hiddenContextPromise = contextMenuHidden(contextMenu);
let hiddenContextPromise = popupHidden(contextMenu);
contextMenu.hidePopup();
yield hiddenContextPromise;
});
@ -194,7 +194,7 @@ add_task(function() {
// show a context menu with options to move it.
add_task(function() {
let contextMenu = document.getElementById("customizationPaletteItemContextMenu");
let shownPromise = contextMenuShown(contextMenu);
let shownPromise = popupShown(contextMenu);
let openFileButton = document.getElementById("wrapper-open-file-button");
EventUtils.synthesizeMouse(openFileButton, 2, 2, {type: "contextmenu", button: 2});
yield shownPromise;
@ -205,7 +205,7 @@ add_task(function() {
];
checkContextMenu(contextMenu, expectedEntries);
let hiddenContextPromise = contextMenuHidden(contextMenu);
let hiddenContextPromise = popupHidden(contextMenu);
contextMenu.hidePopup();
yield hiddenContextPromise;
});
@ -214,7 +214,7 @@ add_task(function() {
// should show a context menu with options to move it.
add_task(function() {
let contextMenu = document.getElementById("customizationPanelItemContextMenu");
let shownPromise = contextMenuShown(contextMenu);
let shownPromise = popupShown(contextMenu);
let newWindowButton = document.getElementById("wrapper-new-window-button");
EventUtils.synthesizeMouse(newWindowButton, 2, 2, {type: "contextmenu", button: 2});
yield shownPromise;
@ -227,7 +227,7 @@ add_task(function() {
];
checkContextMenu(contextMenu, expectedEntries);
let hiddenContextPromise = contextMenuHidden(contextMenu);
let hiddenContextPromise = popupHidden(contextMenu);
contextMenu.hidePopup();
yield hiddenContextPromise;
yield endCustomizing();
@ -241,7 +241,7 @@ add_task(function() {
yield startCustomizing(this.otherWin);
let contextMenu = this.otherWin.document.getElementById("customizationPanelItemContextMenu");
let shownPromise = contextMenuShown(contextMenu);
let shownPromise = popupShown(contextMenu);
let newWindowButton = this.otherWin.document.getElementById("wrapper-new-window-button");
EventUtils.synthesizeMouse(newWindowButton, 2, 2, {type: "contextmenu", button: 2}, this.otherWin);
yield shownPromise;
@ -254,7 +254,7 @@ add_task(function() {
];
checkContextMenu(contextMenu, expectedEntries, this.otherWin);
let hiddenContextPromise = contextMenuHidden(contextMenu);
let hiddenContextPromise = popupHidden(contextMenu);
contextMenu.hidePopup();
yield hiddenContextPromise;
yield endCustomizing(this.otherWin);
@ -267,13 +267,13 @@ add_task(function() {
add_task(function() {
yield startCustomizing();
let contextMenu = document.getElementById("customizationPanelItemContextMenu");
let shownPromise = contextMenuShown(contextMenu);
let shownPromise = popupShown(contextMenu);
let zoomControls = document.getElementById("wrapper-zoom-controls");
EventUtils.synthesizeMouse(zoomControls, 2, 2, {type: "contextmenu", button: 2});
yield shownPromise;
// Execute the command to move the item from the panel to the toolbar.
contextMenu.childNodes[0].doCommand();
let hiddenPromise = contextMenuHidden(contextMenu);
let hiddenPromise = popupHidden(contextMenu);
contextMenu.hidePopup();
yield hiddenPromise;
yield endCustomizing();
@ -282,7 +282,7 @@ add_task(function() {
is(zoomControls.parentNode.id, "nav-bar-customization-target", "Zoom-controls should be on the nav-bar");
contextMenu = document.getElementById("toolbar-context-menu");
shownPromise = contextMenuShown(contextMenu);
shownPromise = popupShown(contextMenu);
EventUtils.synthesizeMouse(zoomControls, 2, 2, {type: "contextmenu", button: 2});
yield shownPromise;
@ -301,7 +301,7 @@ add_task(function() {
);
checkContextMenu(contextMenu, expectedEntries);
hiddenPromise = contextMenuHidden(contextMenu);
hiddenPromise = popupHidden(contextMenu);
contextMenu.hidePopup();
yield hiddenPromise;
yield resetCustomization();
@ -315,7 +315,7 @@ add_task(function() {
yield PanelUI.show();
let contextMenu = document.getElementById("customizationPanelItemContextMenu");
let shownContextPromise = contextMenuShown(contextMenu);
let shownContextPromise = popupShown(contextMenu);
let newWindowButton = document.getElementById("new-window-button");
ok(newWindowButton, "new-window-button was found");
EventUtils.synthesizeMouse(newWindowButton, 2, 2, {type: "contextmenu", button: 2});
@ -331,7 +331,7 @@ add_task(function() {
];
checkContextMenu(contextMenu, expectedEntries);
let hiddenContextPromise = contextMenuHidden(contextMenu);
let hiddenContextPromise = popupHidden(contextMenu);
contextMenu.hidePopup();
yield hiddenContextPromise;

Просмотреть файл

@ -27,7 +27,7 @@ add_task(function() {
yield shownPanelPromise;
let contextMenu = document.getElementById("toolbar-context-menu");
let shownContextPromise = contextMenuShown(contextMenu);
let shownContextPromise = popupShown(contextMenu);
let homeButton = document.getElementById("home-button");
ok(homeButton, "home-button was found");
is(homeButton.getAttribute("overflowedItem"), "true", "Home button is overflowing");
@ -51,7 +51,7 @@ add_task(function() {
);
checkContextMenu(contextMenu, expectedEntries);
let hiddenContextPromise = contextMenuHidden(contextMenu);
let hiddenContextPromise = popupHidden(contextMenu);
let hiddenPromise = promisePanelElementHidden(window, overflowPanel);
let moveToPanel = contextMenu.querySelector(".customize-context-moveToPanel");
if (moveToPanel) {

Просмотреть файл

@ -0,0 +1,256 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
let gNavBar = document.getElementById(CustomizableUI.AREA_NAVBAR);
let gOverflowList = document.getElementById(gNavBar.getAttribute("overflowtarget"));
const kBookmarksButton = "bookmarks-menu-button";
const kBookmarksItems = "personal-bookmarks";
const kOriginalWindowWidth = window.outerWidth;
const kSmallWidth = 400;
/**
* Helper function that opens the bookmarks menu, and returns a Promise that
* resolves as soon as the menu is ready for interaction.
*/
function bookmarksMenuPanelShown() {
let deferred = Promise.defer();
let bookmarksMenuPopup = document.getElementById("BMB_bookmarksPopup");
let onTransitionEnd = (e) => {
if (e.target == bookmarksMenuPopup) {
bookmarksMenuPopup.removeEventListener("transitionend", onTransitionEnd);
deferred.resolve();
}
}
bookmarksMenuPopup.addEventListener("transitionend", onTransitionEnd);
return deferred.promise;
}
/**
* Checks that the placesContext menu is correctly attached to the
* controller of some view. Returns a Promise that resolves as soon
* as the context menu is closed.
*
* @param aItemWithContextMenu the item that we need to synthesize hte
* right click on in order to open the context menu.
*/
function checkPlacesContextMenu(aItemWithContextMenu) {
return Task.spawn(function* () {
let contextMenu = document.getElementById("placesContext");
let newBookmarkItem = document.getElementById("placesContext_new:bookmark");
let shownPromise = popupShown(contextMenu);
EventUtils.synthesizeMouseAtCenter(aItemWithContextMenu,
{type: "contextmenu", button: 2});
yield shownPromise;
ok(!newBookmarkItem.hasAttribute("disabled"),
"New bookmark item shouldn't be disabled");
yield closePopup(contextMenu);
});
}
/**
* Opens the bookmarks menu panel, and then opens each of the "special"
* submenus in that list. Then it checks that those submenu's context menus
* are properly hooked up to a controller.
*/
function checkSpecialContextMenus() {
return Task.spawn(function* () {
let contextMenu = document.getElementById("placesContext");
let bookmarksMenuButton = document.getElementById(kBookmarksButton);
let bookmarksMenuPopup = document.getElementById("BMB_bookmarksPopup");
const kSpecialItemIDs = {
"BMB_bookmarksToolbar": "BMB_bookmarksToolbarPopup",
"BMB_unsortedBookmarks": "BMB_unsortedBookmarksPopup",
};
// Open the bookmarks menu button context menus and ensure that
// they have the proper views attached.
let shownPromise = bookmarksMenuPanelShown();
let dropmarker = document.getAnonymousElementByAttribute(bookmarksMenuButton,
"anonid", "dropmarker");
EventUtils.synthesizeMouseAtCenter(dropmarker, {});
info("Waiting for bookmarks menu popup to show after clicking dropmarker.")
yield shownPromise;
for (let menuID in kSpecialItemIDs) {
let menuItem = document.getElementById(menuID);
let menuPopup = document.getElementById(kSpecialItemIDs[menuID]);
let shownPromise = popupShown(menuPopup);
EventUtils.synthesizeMouseAtCenter(menuItem, {});
yield shownPromise;
yield checkPlacesContextMenu(menuPopup);
yield closePopup(menuPopup);
}
yield closePopup(bookmarksMenuPopup);
});
}
/**
* Closes a focused popup by simulating pressing the Escape key,
* and returns a Promise that resolves as soon as the popup is closed.
*
* @param aPopup the popup node to close.
*/
function closePopup(aPopup) {
let hiddenPromise = popupHidden(aPopup);
EventUtils.synthesizeKey("VK_ESCAPE", {});
return hiddenPromise;
}
/**
* Helper function that checks that the context menu of the
* bookmark toolbar items chevron popup is correctly hooked up
* to the controller of a view.
*/
function checkBookmarksItemsChevronContextMenu() {
return Task.spawn(function*() {
let chevronPopup = document.getElementById("PlacesChevronPopup");
let shownPromise = popupShown(chevronPopup);
let chevron = document.getElementById("PlacesChevron");
EventUtils.synthesizeMouseAtCenter(chevron, {});
yield shownPromise;
yield waitForCondition(() => {
for (let child of chevronPopup.children) {
if (child.style.visibility != "hidden")
return true;
}
});
yield checkPlacesContextMenu(chevronPopup);
yield closePopup(chevronPopup);
});
}
/**
* Forces the window to a width that causes the nav-bar to overflow
* its contents. Returns a Promise that resolves as soon as the
* overflowable nav-bar is showing its chevron.
*/
function overflowEverything() {
window.resizeTo(kSmallWidth, window.outerHeight);
return waitForCondition(() => gNavBar.hasAttribute("overflowing"));
}
/**
* Returns the window to its original size from the start of the test,
* and returns a Promise that resolves when the nav-bar is no longer
* overflowing.
*/
function stopOverflowing() {
window.resizeTo(kOriginalWindowWidth, window.outerHeight);
return waitForCondition(() => !gNavBar.hasAttribute("overflowing"));
}
/**
* Checks that an item with ID aID is overflowing in the nav-bar.
*
* @param aID the ID of the node to check for overflowingness.
*/
function checkOverflowing(aID) {
ok(!gNavBar.querySelector("#" + aID),
"Item with ID " + aID + " should no longer be in the gNavBar");
let item = gOverflowList.querySelector("#" + aID);
ok(item, "Item with ID " + aID + " should be overflowing");
is(item.getAttribute("overflowedItem"), "true",
"Item with ID " + aID + " should have overflowedItem attribute");
}
/**
* Checks that an item with ID aID is not overflowing in the nav-bar.
*
* @param aID the ID of hte node to check for non-overflowingness.
*/
function checkNotOverflowing(aID) {
ok(!gOverflowList.querySelector("#" + aID),
"Item with ID " + aID + " should no longer be overflowing");
let item = gNavBar.querySelector("#" + aID);
ok(item, "Item with ID " + aID + " should be in the nav bar");
ok(!item.hasAttribute("overflowedItem"),
"Item with ID " + aID + " should not have overflowedItem attribute");
}
/**
* Test that overflowing the bookmarks menu button doesn't break the
* context menus for the Unsorted and Bookmarks Toolbar menu items.
*/
add_task(function* testOverflowingBookmarksButtonContextMenu() {
ok(!gNavBar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar.");
ok(CustomizableUI.inDefaultState, "Should start in default state.");
// Open the Unsorted and Bookmarks Toolbar context menus and ensure
// that they have views attached.
yield checkSpecialContextMenus();
yield overflowEverything();
checkOverflowing(kBookmarksButton);
yield stopOverflowing();
checkNotOverflowing(kBookmarksButton);
yield checkSpecialContextMenus();
});
/**
* Test that the bookmarks toolbar items context menu still works if moved
* to the menu from the overflow panel, and then back to the toolbar.
*/
add_task(function* testOverflowingBookmarksItemsContextMenu() {
yield PanelUI.ensureReady();
let bookmarksToolbarItems = document.getElementById(kBookmarksItems);
gCustomizeMode.addToToolbar(bookmarksToolbarItems);
yield checkPlacesContextMenu(bookmarksToolbarItems);
yield overflowEverything();
checkOverflowing(kBookmarksItems)
gCustomizeMode.addToPanel(bookmarksToolbarItems);
yield stopOverflowing();
gCustomizeMode.addToToolbar(bookmarksToolbarItems);
yield checkPlacesContextMenu(bookmarksToolbarItems);
});
/**
* Test that overflowing the bookmarks toolbar items doesn't cause the
* context menu in the bookmarks toolbar items chevron to stop working.
*/
add_task(function* testOverflowingBookmarksItemsChevronContextMenu() {
// If it's not already there, let's move the bookmarks toolbar items to
// the nav-bar.
let bookmarksToolbarItems = document.getElementById(kBookmarksItems);
gCustomizeMode.addToToolbar(bookmarksToolbarItems);
// We make the PlacesToolbarItems element be super tiny in order to force
// the bookmarks toolbar items into overflowing and making the chevron
// show itself.
let placesToolbarItems = document.getElementById("PlacesToolbarItems");
let placesChevron = document.getElementById("PlacesChevron");
placesToolbarItems.style.maxWidth = "10px";
yield waitForCondition(() => !placesChevron.collapsed);
yield checkBookmarksItemsChevronContextMenu();
yield overflowEverything();
checkOverflowing(kBookmarksItems);
yield stopOverflowing();
checkNotOverflowing(kBookmarksItems);
yield checkBookmarksItemsChevronContextMenu();
placesToolbarItems.style.removeProperty("max-width");
});
add_task(function* asyncCleanup() {
window.resizeTo(kOriginalWindowWidth, window.outerHeight);
yield resetCustomization();
});

Просмотреть файл

@ -428,36 +428,49 @@ function promiseTabHistoryNavigation(aDirection = -1, aConditionFn) {
return deferred.promise;
}
function contextMenuShown(aContextMenu) {
let deferred = Promise.defer();
let win = aContextMenu.ownerDocument.defaultView;
let timeoutId = win.setTimeout(() => {
deferred.reject("Context menu (" + aContextMenu.id + ") did not show within 20 seconds.");
}, 20000);
function onPopupShown(e) {
aContextMenu.removeEventListener("popupshown", onPopupShown);
win.clearTimeout(timeoutId);
deferred.resolve();
};
aContextMenu.addEventListener("popupshown", onPopupShown);
return deferred.promise;
function popupShown(aPopup) {
return promisePopupEvent(aPopup, "shown");
}
function contextMenuHidden(aContextMenu) {
let deferred = Promise.defer();
let win = aContextMenu.ownerDocument.defaultView;
let timeoutId = win.setTimeout(() => {
deferred.reject("Context menu (" + aContextMenu.id + ") did not hide within 20 seconds.");
}, 20000);
function onPopupHidden(e) {
win.clearTimeout(timeoutId);
aContextMenu.removeEventListener("popuphidden", onPopupHidden);
deferred.resolve();
};
aContextMenu.addEventListener("popuphidden", onPopupHidden);
return deferred.promise;
function popupHidden(aPopup) {
return promisePopupEvent(aPopup, "hidden");
}
/**
* Returns a Promise that resolves when aPopup fires an event of type
* aEventType. Times out and rejects after 20 seconds.
*
* @param aPopup the popup to monitor for events.
* @param aEventSuffix the _suffix_ for the popup event type to watch for.
*
* Example usage:
* let popupShownPromise = promisePopupEvent(somePopup, "shown");
* // ... something that opens a popup
* yield popupShownPromise;
*
* let popupHiddenPromise = promisePopupEvent(somePopup, "hidden");
* // ... something that hides a popup
* yield popupHiddenPromise;
*/
function promisePopupEvent(aPopup, aEventSuffix) {
let deferred = Promise.defer();
let win = aPopup.ownerDocument.defaultView;
let eventType = "popup" + aEventSuffix;
let timeoutId = win.setTimeout(() => {
deferred.reject("Context menu (" + aPopup.id + ") did not fire "
+ eventType + " within 20 seconds.");
}, 20000);
function onPopupEvent(e) {
win.clearTimeout(timeoutId);
aPopup.removeEventListener(eventType, onPopupEvent);
deferred.resolve();
};
aPopup.addEventListener(eventType, onPopupEvent);
return deferred.promise;
}
// This is a simpler version of the context menu check that
// exists in contextmenu_common.js.

Просмотреть файл

@ -81,6 +81,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "PlacesBackups",
XPCOMUtils.defineLazyModuleGetter(this, "OS",
"resource://gre/modules/osfile.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "RemotePrompt",
"resource:///modules/RemotePrompt.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "SessionStore",
"resource:///modules/sessionstore/SessionStore.jsm");
@ -495,8 +498,10 @@ BrowserGlue.prototype = {
SessionStore.init();
BrowserUITelemetry.init();
if (Services.appinfo.browserTabsRemote)
if (Services.appinfo.browserTabsRemote) {
ContentClick.init();
RemotePrompt.init();
}
Services.obs.notifyObservers(null, "browser-ui-startup-complete", "");
},

Просмотреть файл

@ -960,6 +960,10 @@ PlacesToolbar.prototype = {
this._removeEventListeners(window, ["resize", "unload"], false);
this._removeEventListeners(gBrowser.tabContainer, ["TabOpen", "TabClose"], false);
if (this._chevron._placesView) {
this._chevron._placesView.uninit();
}
PlacesViewBase.prototype.uninit.apply(this, arguments);
},

Просмотреть файл

@ -1,4 +1,10 @@
[DEFAULT]
support-files =
head.js
[browser_layoutview.js]
skip-if = true
[browser_editablemodel.js]
[browser_editablemodel_allproperties.js]
[browser_editablemodel_border.js]
[browser_editablemodel_stylerules.js]

Просмотреть файл

@ -0,0 +1,145 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function getStyle(node, property) {
return node.style.getPropertyValue(property);
}
let doc;
let inspector;
let test = asyncTest(function*() {
let style = "div { margin: 10px; padding: 3px } #div1 { margin-top: 5px } #div2 { border-bottom: 1em solid black; } #div3 { padding: 2em; }";
let html = "<style>" + style + "</style><div id='div1'></div><div id='div2'></div><div id='div3'></div>"
let content = yield loadTab("data:text/html," + encodeURIComponent(html));
doc = content.document;
let target = TargetFactory.forTab(gBrowser.selectedTab);
let toolbox = yield gDevTools.showToolbox(target, "inspector");
inspector = toolbox.getCurrentPanel();
inspector.sidebar.select("layoutview");
yield inspector.sidebar.once("layoutview-ready");
yield runTests();
yield gDevTools.closeToolbox(toolbox);
});
addTest("Test that editing margin dynamically updates the document, pressing escape cancels the changes",
function*() {
let node = doc.getElementById("div1");
is(getStyle(node, "margin-top"), "", "Should be no margin-top on the element.")
let view = yield selectNode(node);
let span = view.document.querySelector(".margin.top > span");
is(span.textContent, 5, "Should have the right value in the box model.");
EventUtils.synthesizeMouseAtCenter(span, {}, view);
let editor = view.document.querySelector(".styleinspector-propertyeditor");
ok(editor, "Should have opened the editor.");
is(editor.value, "5px", "Should have the right value in the editor.");
EventUtils.synthesizeKey("3", {}, view);
yield waitForUpdate();
is(getStyle(node, "margin-top"), "3px", "Should have updated the margin.");
EventUtils.synthesizeKey("VK_ESCAPE", {}, view);
yield waitForUpdate();
is(getStyle(node, "margin-top"), "", "Should be no margin-top on the element.")
is(span.textContent, 5, "Should have the right value in the box model.");
});
addTest("Test that arrow keys work correctly and pressing enter commits the changes",
function*() {
let node = doc.getElementById("div1");
is(getStyle(node, "margin-left"), "", "Should be no margin-top on the element.")
let view = yield selectNode(node);
let span = view.document.querySelector(".margin.left > span");
is(span.textContent, 10, "Should have the right value in the box model.");
EventUtils.synthesizeMouseAtCenter(span, {}, view);
let editor = view.document.querySelector(".styleinspector-propertyeditor");
ok(editor, "Should have opened the editor.");
is(editor.value, "10px", "Should have the right value in the editor.");
EventUtils.synthesizeKey("VK_UP", {}, view);
yield waitForUpdate();
is(editor.value, "11px", "Should have the right value in the editor.");
is(getStyle(node, "margin-left"), "11px", "Should have updated the margin.");
EventUtils.synthesizeKey("VK_DOWN", {}, view);
yield waitForUpdate();
is(editor.value, "10px", "Should have the right value in the editor.");
is(getStyle(node, "margin-left"), "10px", "Should have updated the margin.");
EventUtils.synthesizeKey("VK_UP", { shiftKey: true }, view);
yield waitForUpdate();
is(editor.value, "20px", "Should have the right value in the editor.");
is(getStyle(node, "margin-left"), "20px", "Should have updated the margin.");
EventUtils.synthesizeKey("VK_RETURN", {}, view);
yield waitForUpdate();
is(getStyle(node, "margin-left"), "20px", "Should be the right margin-top on the element.")
is(span.textContent, 20, "Should have the right value in the box model.");
});
addTest("Test that deleting the value removes the property but escape undoes that",
function*() {
let node = doc.getElementById("div1");
is(getStyle(node, "margin-left"), "20px", "Should be the right margin-top on the element.")
let view = yield selectNode(node);
let span = view.document.querySelector(".margin.left > span");
is(span.textContent, 20, "Should have the right value in the box model.");
EventUtils.synthesizeMouseAtCenter(span, {}, view);
let editor = view.document.querySelector(".styleinspector-propertyeditor");
ok(editor, "Should have opened the editor.");
is(editor.value, "20px", "Should have the right value in the editor.");
EventUtils.synthesizeKey("VK_DELETE", {}, view);
yield waitForUpdate();
is(editor.value, "", "Should have the right value in the editor.");
is(getStyle(node, "margin-left"), "", "Should have updated the margin.");
EventUtils.synthesizeKey("VK_ESCAPE", {}, view);
yield waitForUpdate();
is(getStyle(node, "margin-left"), "20px", "Should be the right margin-top on the element.")
is(span.textContent, 20, "Should have the right value in the box model.");
});
addTest("Test that deleting the value removes the property",
function*() {
let node = doc.getElementById("div1");
node.style.marginRight = "15px";
let view = yield selectNode(node);
let span = view.document.querySelector(".margin.right > span");
is(span.textContent, 15, "Should have the right value in the box model.");
EventUtils.synthesizeMouseAtCenter(span, {}, view);
let editor = view.document.querySelector(".styleinspector-propertyeditor");
ok(editor, "Should have opened the editor.");
is(editor.value, "15px", "Should have the right value in the editor.");
EventUtils.synthesizeKey("VK_DELETE", {}, view);
yield waitForUpdate();
is(editor.value, "", "Should have the right value in the editor.");
is(getStyle(node, "margin-right"), "", "Should have updated the margin.");
EventUtils.synthesizeKey("VK_RETURN", {}, view);
yield waitForUpdate();
is(getStyle(node, "margin-right"), "", "Should be the right margin-top on the element.")
is(span.textContent, 10, "Should have the right value in the box model.");
});

Просмотреть файл

@ -0,0 +1,134 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function getStyle(node, property) {
return node.style.getPropertyValue(property);
}
let doc;
let inspector;
let test = asyncTest(function*() {
let style = "div { margin: 10px; padding: 3px } #div1 { margin-top: 5px } #div2 { border-bottom: 1em solid black; } #div3 { padding: 2em; }";
let html = "<style>" + style + "</style><div id='div1'></div><div id='div2'></div><div id='div3'></div>"
let content = yield loadTab("data:text/html," + encodeURIComponent(html));
doc = content.document;
let target = TargetFactory.forTab(gBrowser.selectedTab);
let toolbox = yield gDevTools.showToolbox(target, "inspector");
inspector = toolbox.getCurrentPanel();
inspector.sidebar.select("layoutview");
yield inspector.sidebar.once("layoutview-ready");
yield runTests();
yield gDevTools.closeToolbox(toolbox);
});
addTest("When all properties are set on the node editing one should work",
function*() {
let node = doc.getElementById("div1");
node.style.padding = "5px";
let view = yield selectNode(node);
let span = view.document.querySelector(".padding.bottom > span");
is(span.textContent, 5, "Should have the right value in the box model.");
EventUtils.synthesizeMouseAtCenter(span, {}, view);
let editor = view.document.querySelector(".styleinspector-propertyeditor");
ok(editor, "Should have opened the editor.");
is(editor.value, "5px", "Should have the right value in the editor.");
EventUtils.synthesizeKey("7", {}, view);
yield waitForUpdate();
is(editor.value, "7", "Should have the right value in the editor.");
is(getStyle(node, "padding-bottom"), "7px", "Should have updated the padding");
EventUtils.synthesizeKey("VK_RETURN", {}, view);
yield waitForUpdate();
is(getStyle(node, "padding-bottom"), "7px", "Should be the right padding.")
is(span.textContent, 7, "Should have the right value in the box model.");
});
addTest("When all properties are set on the node editing one should work",
function*() {
let node = doc.getElementById("div1");
node.style.padding = "5px";
let view = yield selectNode(node);
let span = view.document.querySelector(".padding.left > span");
is(span.textContent, 5, "Should have the right value in the box model.");
EventUtils.synthesizeMouseAtCenter(span, {}, view);
let editor = view.document.querySelector(".styleinspector-propertyeditor");
ok(editor, "Should have opened the editor.");
is(editor.value, "5px", "Should have the right value in the editor.");
EventUtils.synthesizeKey("8", {}, view);
yield waitForUpdate();
is(editor.value, "8", "Should have the right value in the editor.");
is(getStyle(node, "padding-left"), "8px", "Should have updated the padding");
EventUtils.synthesizeKey("VK_ESCAPE", {}, view);
yield waitForUpdate();
is(getStyle(node, "padding-left"), "5px", "Should be the right padding.")
is(span.textContent, 5, "Should have the right value in the box model.");
});
addTest("When all properties are set on the node deleting one should work",
function*() {
let node = doc.getElementById("div1");
node.style.padding = "5px";
let view = yield selectNode(node);
let span = view.document.querySelector(".padding.left > span");
is(span.textContent, 5, "Should have the right value in the box model.");
EventUtils.synthesizeMouseAtCenter(span, {}, view);
let editor = view.document.querySelector(".styleinspector-propertyeditor");
ok(editor, "Should have opened the editor.");
is(editor.value, "5px", "Should have the right value in the editor.");
EventUtils.synthesizeKey("VK_DELETE", {}, view);
yield waitForUpdate();
is(editor.value, "", "Should have the right value in the editor.");
is(getStyle(node, "padding-left"), "", "Should have updated the padding");
EventUtils.synthesizeKey("VK_RETURN", {}, view);
yield waitForUpdate();
is(getStyle(node, "padding-left"), "", "Should be the right padding.")
is(span.textContent, 3, "Should have the right value in the box model.");
});
addTest("When all properties are set on the node deleting one then cancelling should work",
function*() {
let node = doc.getElementById("div1");
node.style.padding = "5px";
let view = yield selectNode(node);
let span = view.document.querySelector(".padding.left > span");
is(span.textContent, 5, "Should have the right value in the box model.");
EventUtils.synthesizeMouseAtCenter(span, {}, view);
let editor = view.document.querySelector(".styleinspector-propertyeditor");
ok(editor, "Should have opened the editor.");
is(editor.value, "5px", "Should have the right value in the editor.");
EventUtils.synthesizeKey("VK_DELETE", {}, view);
yield waitForUpdate();
is(editor.value, "", "Should have the right value in the editor.");
is(getStyle(node, "padding-left"), "", "Should have updated the padding");
EventUtils.synthesizeKey("VK_ESCAPE", {}, view);
yield waitForUpdate();
is(getStyle(node, "padding-left"), "5px", "Should be the right padding.")
is(span.textContent, 5, "Should have the right value in the box model.");
});

Просмотреть файл

@ -0,0 +1,56 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function getStyle(node, property) {
return node.style.getPropertyValue(property);
}
let doc;
let inspector;
let test = asyncTest(function*() {
let style = "div { margin: 10px; padding: 3px } #div1 { margin-top: 5px } #div2 { border-bottom: 1em solid black; } #div3 { padding: 2em; }";
let html = "<style>" + style + "</style><div id='div1'></div><div id='div2'></div><div id='div3'></div>"
let content = yield loadTab("data:text/html," + encodeURIComponent(html));
doc = content.document;
let target = TargetFactory.forTab(gBrowser.selectedTab);
let toolbox = yield gDevTools.showToolbox(target, "inspector");
inspector = toolbox.getCurrentPanel();
inspector.sidebar.select("layoutview");
yield inspector.sidebar.once("layoutview-ready");
yield runTests();
yield gDevTools.closeToolbox(toolbox);
});
addTest("Test that adding a border applies a border style when necessary",
function*() {
let node = doc.getElementById("div1");
is(getStyle(node, "border-top-width"), "", "Should have the right border");
is(getStyle(node, "border-top-style"), "", "Should have the right border");
let view = yield selectNode(node);
let span = view.document.querySelector(".border.top > span");
is(span.textContent, 0, "Should have the right value in the box model.");
EventUtils.synthesizeMouseAtCenter(span, {}, view);
let editor = view.document.querySelector(".styleinspector-propertyeditor");
ok(editor, "Should have opened the editor.");
is(editor.value, "0", "Should have the right value in the editor.");
EventUtils.synthesizeKey("1", {}, view);
yield waitForUpdate();
is(editor.value, "1", "Should have the right value in the editor.");
is(getStyle(node, "border-top-width"), "1px", "Should have the right border");
is(getStyle(node, "border-top-style"), "solid", "Should have the right border");
EventUtils.synthesizeKey("VK_ESCAPE", {}, view);
yield waitForUpdate();
is(getStyle(node, "border-top-width"), "", "Should be the right padding.")
is(getStyle(node, "border-top-style"), "", "Should have the right border");
is(span.textContent, 0, "Should have the right value in the box model.");
});

Просмотреть файл

@ -0,0 +1,108 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function getStyle(node, property) {
return node.style.getPropertyValue(property);
}
let doc;
let inspector;
let test = asyncTest(function*() {
let style = "div { margin: 10px; padding: 3px } #div1 { margin-top: 5px } #div2 { border-bottom: 1em solid black; } #div3 { padding: 2em; }";
let html = "<style>" + style + "</style><div id='div1'></div><div id='div2'></div><div id='div3'></div>"
let content = yield loadTab("data:text/html," + encodeURIComponent(html));
doc = content.document;
let target = TargetFactory.forTab(gBrowser.selectedTab);
let toolbox = yield gDevTools.showToolbox(target, "inspector");
inspector = toolbox.getCurrentPanel();
inspector.sidebar.select("layoutview");
yield inspector.sidebar.once("layoutview-ready");
yield runTests();
yield gDevTools.closeToolbox(toolbox);
});
addTest("Test that entering units works",
function*() {
let node = doc.getElementById("div1");
is(getStyle(node, "padding-top"), "", "Should have the right padding");
let view = yield selectNode(node);
let span = view.document.querySelector(".padding.top > span");
is(span.textContent, 3, "Should have the right value in the box model.");
EventUtils.synthesizeMouseAtCenter(span, {}, view);
let editor = view.document.querySelector(".styleinspector-propertyeditor");
ok(editor, "Should have opened the editor.");
is(editor.value, "3px", "Should have the right value in the editor.");
EventUtils.synthesizeKey("1", {}, view);
yield waitForUpdate();
EventUtils.synthesizeKey("e", {}, view);
yield waitForUpdate();
is(getStyle(node, "padding-top"), "", "An invalid value is handled cleanly");
EventUtils.synthesizeKey("m", {}, view);
yield waitForUpdate();
is(editor.value, "1em", "Should have the right value in the editor.");
is(getStyle(node, "padding-top"), "1em", "Should have updated the padding.");
EventUtils.synthesizeKey("VK_RETURN", {}, view);
yield waitForUpdate();
is(getStyle(node, "padding-top"), "1em", "Should be the right padding.")
is(span.textContent, 16, "Should have the right value in the box model.");
});
addTest("Test that we pick up the value from a higher style rule",
function*() {
let node = doc.getElementById("div2");
is(getStyle(node, "border-bottom-width"), "", "Should have the right border-bottom-width");
let view = yield selectNode(node);
let span = view.document.querySelector(".border.bottom > span");
is(span.textContent, 16, "Should have the right value in the box model.");
EventUtils.synthesizeMouseAtCenter(span, {}, view);
let editor = view.document.querySelector(".styleinspector-propertyeditor");
ok(editor, "Should have opened the editor.");
is(editor.value, "1em", "Should have the right value in the editor.");
EventUtils.synthesizeKey("0", {}, view);
yield waitForUpdate();
is(editor.value, "0", "Should have the right value in the editor.");
is(getStyle(node, "border-bottom-width"), "0px", "Should have updated the border.");
EventUtils.synthesizeKey("VK_RETURN", {}, view);
yield waitForUpdate();
is(getStyle(node, "border-bottom-width"), "0px", "Should be the right border-bottom-width.")
is(span.textContent, 0, "Should have the right value in the box model.");
});
addTest("Test that shorthand properties are parsed correctly",
function*() {
let node = doc.getElementById("div3");
is(getStyle(node, "padding-right"), "", "Should have the right padding");
let view = yield selectNode(node);
let span = view.document.querySelector(".padding.right > span");
is(span.textContent, 32, "Should have the right value in the box model.");
EventUtils.synthesizeMouseAtCenter(span, {}, view);
let editor = view.document.querySelector(".styleinspector-propertyeditor");
ok(editor, "Should have opened the editor.");
is(editor.value, "2em", "Should have the right value in the editor.");
EventUtils.synthesizeKey("VK_RETURN", {}, view);
yield waitForUpdate();
is(getStyle(node, "padding-right"), "", "Should be the right padding.")
is(span.textContent, 32, "Should have the right value in the box model.");
});

Просмотреть файл

@ -1,134 +1,99 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
let {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
let TargetFactory = devtools.TargetFactory;
// Expected values:
let res1 = [
{selector: "#element-size", value: "160x160"},
{selector: ".size > span", value: "100x100"},
{selector: ".margin.top > span", value: 30},
{selector: ".margin.left > span", value: "auto"},
{selector: ".margin.bottom > span", value: 30},
{selector: ".margin.right > span", value: "auto"},
{selector: ".padding.top > span", value: 20},
{selector: ".padding.left > span", value: 20},
{selector: ".padding.bottom > span", value: 20},
{selector: ".padding.right > span", value: 20},
{selector: ".border.top > span", value: 10},
{selector: ".border.left > span", value: 10},
{selector: ".border.bottom > span", value: 10},
{selector: ".border.right > span", value: 10},
];
function test() {
waitForExplicitFinish();
let res2 = [
{selector: "#element-size", value: "190x210"},
{selector: ".size > span", value: "100x150"},
{selector: ".margin.top > span", value: 30},
{selector: ".margin.left > span", value: "auto"},
{selector: ".margin.bottom > span", value: 30},
{selector: ".margin.right > span", value: "auto"},
{selector: ".padding.top > span", value: 20},
{selector: ".padding.left > span", value: 20},
{selector: ".padding.bottom > span", value: 20},
{selector: ".padding.right > span", value: 50},
{selector: ".border.top > span", value: 10},
{selector: ".border.left > span", value: 10},
{selector: ".border.bottom > span", value: 10},
{selector: ".border.right > span", value: 10},
];
gDevTools.testing = true;
SimpleTest.registerCleanupFunction(() => {
gDevTools.testing = false;
});
Services.prefs.setBoolPref("devtools.inspector.sidebarOpen", true);
let doc;
let node;
let view;
let inspector;
// Expected values:
let res1 = [
{selector: "#element-size", value: "160x160"},
{selector: ".size > span", value: "100x100"},
{selector: ".margin.top > span", value: 30},
{selector: ".margin.left > span", value: "auto"},
{selector: ".margin.bottom > span", value: 30},
{selector: ".margin.right > span", value: "auto"},
{selector: ".padding.top > span", value: 20},
{selector: ".padding.left > span", value: 20},
{selector: ".padding.bottom > span", value: 20},
{selector: ".padding.right > span", value: 20},
{selector: ".border.top > span", value: 10},
{selector: ".border.left > span", value: 10},
{selector: ".border.bottom > span", value: 10},
{selector: ".border.right > span", value: 10},
];
let res2 = [
{selector: "#element-size", value: "190x210"},
{selector: ".size > span", value: "100x150"},
{selector: ".margin.top > span", value: 30},
{selector: ".margin.left > span", value: "auto"},
{selector: ".margin.bottom > span", value: 30},
{selector: ".margin.right > span", value: "auto"},
{selector: ".padding.top > span", value: 20},
{selector: ".padding.left > span", value: 20},
{selector: ".padding.bottom > span", value: 20},
{selector: ".padding.right > span", value: 50},
{selector: ".border.top > span", value: 10},
{selector: ".border.left > span", value: 10},
{selector: ".border.bottom > span", value: 10},
{selector: ".border.right > span", value: 10},
];
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onload() {
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
doc = content.document;
waitForFocus(setupTest, content);
}, true);
let inspector;
let view;
let test = asyncTest(function*() {
let style = "div { position: absolute; top: 42px; left: 42px; height: 100px; width: 100px; border: 10px solid black; padding: 20px; margin: 30px auto;}";
let html = "<style>" + style + "</style><div></div>"
content.location = "data:text/html," + encodeURIComponent(html);
function setupTest() {
node = doc.querySelector("div");
ok(node, "node found");
let content = yield loadTab("data:text/html," + encodeURIComponent(html));
let node = content.document.querySelector("div");
ok(node, "node found");
let target = TargetFactory.forTab(gBrowser.selectedTab);
gDevTools.showToolbox(target, "inspector").then(function(toolbox) {
openLayoutView(toolbox.getCurrentPanel());
});
let target = TargetFactory.forTab(gBrowser.selectedTab);
let toolbox = yield gDevTools.showToolbox(target, "inspector");
inspector = toolbox.getCurrentPanel();
info("Inspector open");
inspector.sidebar.select("layoutview");
yield inspector.sidebar.once("layoutview-ready");
inspector.selection.setNode(node);
yield inspector.once("inspector-updated");
info("Layout view ready");
view = inspector.sidebar.getWindowForTab("layoutview");
ok(!!view.layoutview, "LayoutView document is alive.");
yield runTests();
executeSoon(function() {
inspector._toolbox.destroy();
});
yield gDevTools.once("toolbox-destroyed");
});
addTest("Test that the initial values of the box model are correct",
function*() {
let viewdoc = view.document;
for (let i = 0; i < res1.length; i++) {
let elt = viewdoc.querySelector(res1[i].selector);
is(elt.textContent, res1[i].value, res1[i].selector + " has the right value.");
}
});
function openLayoutView(aInspector) {
inspector = aInspector;
addTest("Test that changing the document updates the box model",
function*() {
let viewdoc = view.document;
info("Inspector open");
inspector.selection.node.style.height = "150px";
inspector.selection.node.style.paddingRight = "50px";
inspector.sidebar.select("layoutview");
inspector.sidebar.once("layoutview-ready", () => {
inspector.selection.setNode(node);
inspector.once("inspector-updated", viewReady);
});
yield waitForUpdate();
for (let i = 0; i < res2.length; i++) {
let elt = viewdoc.querySelector(res2[i].selector);
is(elt.textContent, res2[i].value, res2[i].selector + " has the right value after style update.");
}
function viewReady() {
info("Layout view ready");
view = inspector.sidebar.getWindowForTab("layoutview");
ok(!!view.layoutview, "LayoutView document is alive.");
test1();
}
function test1() {
let viewdoc = view.document;
for (let i = 0; i < res1.length; i++) {
let elt = viewdoc.querySelector(res1[i].selector);
is(elt.textContent, res1[i].value, res1[i].selector + " has the right value.");
}
inspector.once("layoutview-updated", test2);
inspector.selection.node.style.height = "150px";
inspector.selection.node.style.paddingRight = "50px";
}
function test2() {
let viewdoc = view.document;
for (let i = 0; i < res2.length; i++) {
let elt = viewdoc.querySelector(res2[i].selector);
is(elt.textContent, res2[i].value, res2[i].selector + " has the right value after style update.");
}
executeSoon(function() {
gDevTools.once("toolbox-destroyed", finishUp);
inspector._toolbox.destroy();
});
}
function finishUp() {
Services.prefs.clearUserPref("devtools.inspector.sidebarOpen");
gBrowser.removeCurrentTab();
finish();
}
}
});

Просмотреть файл

@ -0,0 +1,87 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
Cu.import("resource://gre/modules/Task.jsm");
let {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
const promise = devtools.require("sdk/core/promise");
let TargetFactory = devtools.TargetFactory;
Services.prefs.setBoolPref("devtools.inspector.sidebarOpen", true);
Services.prefs.setIntPref("devtools.toolbox.footer.height", 350);
gDevTools.testing = true;
SimpleTest.registerCleanupFunction(() => {
Services.prefs.clearUserPref("devtools.inspector.sidebarOpen");
Services.prefs.clearUserPref("devtools.toolbox.footer.height");
gDevTools.testing = false;
});
// All tests are async in general
waitForExplicitFinish();
function loadTab(url) {
let deferred = promise.defer();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onload() {
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
waitForFocus(function() {
deferred.resolve(content);
}, content);
}, true);
content.location = url;
return deferred.promise;
}
function selectNode(aNode) {
info("selecting node");
let onSelect = inspector.once("layoutview-updated");
inspector.selection.setNode(aNode, "test");
return onSelect.then(() => {
let view = inspector.sidebar.getWindowForTab("layoutview");
ok(!!view.layoutview, "LayoutView document is alive.");
return view;
});
}
function waitForUpdate() {
return inspector.once("layoutview-updated");
}
function asyncTest(testfunc) {
return Task.async(function*() {
let initialTab = gBrowser.selectedTab;
yield testfunc();
// Remove all tabs except for the initial tab. This is basically
// gBrowser.removeAllTabsBut without the animation
let tabs = gBrowser.visibleTabs;
gBrowser.selectedTab = initialTab;
for (let i = tabs.length - 1; i >= 0; i--) {
if (tabs[i] != initialTab)
gBrowser.removeTab(tabs[i]);
}
// Reset the sidebar back to the default
Services.prefs.setCharPref("devtools.inspector.activeSidebar", "ruleview");
finish();
});
}
var TESTS = [];
function addTest(message, func) {
TESTS.push([message, Task.async(func)])
}
var runTests = Task.async(function*() {
for (let [message, test] of TESTS) {
info(message);
yield test();
}
});

Просмотреть файл

@ -86,9 +86,16 @@ body {
#main > p > span {
vertical-align: middle;
pointer-events: auto;
}
.size > span {
cursor: default;
}
.editable {
-moz-user-select: text;
}
.top,
.bottom {
width: calc(100% - 2px);
@ -179,4 +186,3 @@ body.dim > #main > p,
body.dim > #main > .tooltip {
visibility: hidden;
}

Просмотреть файл

@ -11,10 +11,113 @@ const Ci = Components.interfaces;
const Cc = Components.classes;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/devtools/Loader.jsm");
Cu.import("resource://gre/modules/devtools/Console.jsm");
const promise = devtools.require("sdk/core/promise");
const {InplaceEditor, editableItem} = devtools.require("devtools/shared/inplace-editor");
const {parseDeclarations} = devtools.require("devtools/styleinspector/css-parsing-utils");
const NUMERIC = /^-?[\d\.]+$/;
/**
* An instance of EditingSession tracks changes that have been made during the
* modification of box model values. All of these changes can be reverted by
* calling revert.
*
* @param doc A DOM document that can be used to test style rules.
* @param rules An array of the style rules defined for the node being edited.
* These should be in order of priority, least important first.
*/
function EditingSession(doc, rules) {
this._doc = doc;
this._rules = rules;
this._modifications = new Map();
}
EditingSession.prototype = {
/**
* Gets the value of a single property from the CSS rule.
*
* @param rule The CSS rule
* @param property The name of the property
*/
getPropertyFromRule: function(rule, property) {
let dummyStyle = this._element.style;
dummyStyle.cssText = rule.cssText;
return dummyStyle.getPropertyValue(property);
},
/**
* Returns the current value for a property as a string or the empty string if
* no style rules affect the property.
*
* @param property The name of the property as a string
*/
getProperty: function(property) {
// Create a hidden element for getPropertyFromRule to use
let div = this._doc.createElement("div");
div.setAttribute("style", "display: none");
this._doc.body.appendChild(div);
this._element = this._doc.createElement("p");
div.appendChild(this._element);
// As the rules are in order of priority we can just iterate until we find
// the first that defines a value for the property and return that.
for (let rule of this._rules) {
let value = this.getPropertyFromRule(rule, property);
if (value !== "") {
div.remove();
return value;
}
}
div.remove();
return "";
},
/**
* Sets a number of properties on the node. Returns a promise that will be
* resolved when the modifications are complete.
*
* @param properties An array of properties, each is an object with name and
* value properties. If the value is "" then the property
* is removed.
*/
setProperties: function(properties) {
let modifications = this._rules[0].startModifyingProperties();
for (let property of properties) {
if (!this._modifications.has(property.name))
this._modifications.set(property.name, this.getPropertyFromRule(this._rules[0], property.name));
if (property.value == "")
modifications.removeProperty(property.name);
else
modifications.setProperty(property.name, property.value, "");
}
return modifications.apply().then(null, console.error);
},
/**
* Reverts all of the property changes made by this instance. Returns a
* promise that will be resolved when complete.
*/
revert: function() {
let modifications = this._rules[0].startModifyingProperties();
for (let [property, value] of this._modifications) {
if (value != "")
modifications.setProperty(property, value, "");
else
modifications.removeProperty(property);
}
return modifications.apply().then(null, console.error);
}
};
function LayoutView(aInspector, aWindow)
{
@ -54,11 +157,17 @@ LayoutView.prototype = {
marginBottom: {selector: ".margin.bottom > span",
property: "margin-bottom",
value: undefined},
// margin-left is a shorthand for some internal properties,
// margin-left-ltr-source and margin-left-rtl-source for example. The
// real margin value we want is in margin-left-value
marginLeft: {selector: ".margin.left > span",
property: "margin-left",
realProperty: "margin-left-value",
value: undefined},
// margin-right behaves the same as margin-left
marginRight: {selector: ".margin.right > span",
property: "margin-right",
realProperty: "margin-right-value",
value: undefined},
paddingTop: {selector: ".padding.top > span",
property: "padding-top",
@ -66,11 +175,15 @@ LayoutView.prototype = {
paddingBottom: {selector: ".padding.bottom > span",
property: "padding-bottom",
value: undefined},
// padding-left behaves the same as margin-left
paddingLeft: {selector: ".padding.left > span",
property: "padding-left",
realProperty: "padding-left-value",
value: undefined},
// padding-right behaves the same as margin-left
paddingRight: {selector: ".padding.right > span",
property: "padding-right",
realProperty: "padding-right-value",
value: undefined},
borderTop: {selector: ".border.top > span",
property: "border-top-width",
@ -86,9 +199,58 @@ LayoutView.prototype = {
value: undefined},
};
// Make each element the dimensions editable
for (let i in this.map) {
if (i == "position")
continue;
let dimension = this.map[i];
editableItem({ element: this.doc.querySelector(dimension.selector) }, (element, event) => {
this.initEditor(element, event, dimension);
});
}
this.onNewNode();
},
/**
* Called when the user clicks on one of the editable values in the layoutview
*/
initEditor: function LV_initEditor(element, event, dimension) {
let { property, realProperty } = dimension;
if (!realProperty)
realProperty = property;
let session = new EditingSession(document, this.elementRules);
let initialValue = session.getProperty(realProperty);
new InplaceEditor({
element: element,
initial: initialValue,
change: (value) => {
if (NUMERIC.test(value))
value += "px";
let properties = [
{ name: property, value: value }
]
if (property.substring(0, 7) == "border-") {
let bprop = property.substring(0, property.length - 5) + "style";
let style = session.getProperty(bprop);
if (!style || style == "none" || style == "hidden")
properties.push({ name: bprop, value: "solid" });
}
session.setProperties(properties);
},
done: (value, commit) => {
if (!commit)
session.revert();
}
}, event);
},
/**
* Is the layoutview visible in the sidebar?
*/
@ -158,23 +320,28 @@ LayoutView.prototype = {
/**
* Compute the dimensions of the node and update the values in
* the layoutview/view.xhtml document.
* the layoutview/view.xhtml document. Returns a promise that will be resolved
* when complete.
*/
update: function LV_update() {
if (!this.isActive() ||
!this.inspector.selection.isConnected() ||
!this.inspector.selection.isElementNode()) {
return promise.resolve(undefined);
}
let lastRequest = Task.spawn((function*() {
if (!this.isActive() ||
!this.inspector.selection.isConnected() ||
!this.inspector.selection.isElementNode()) {
return;
}
let node = this.inspector.selection.nodeFront;
let layout = yield this.inspector.pageStyle.getLayout(node, {
autoMargins: !this.dimmed
});
let styleEntries = yield this.inspector.pageStyle.getApplied(node, {});
let node = this.inspector.selection.nodeFront;
let lastRequest = this.inspector.pageStyle.getLayout(node, {
autoMargins: !this.dimmed
}).then(layout => {
// If a subsequent request has been made, wait for that one instead.
if (this._lastRequest != lastRequest) {
return this._lastRequest;
}
this._lastRequest = null;
let width = layout.width;
let height = layout.height;
@ -233,12 +400,12 @@ LayoutView.prototype = {
this.sizeLabel.textContent = newValue;
}
this.inspector.emit("layoutview-updated");
return null;
});
this.elementRules = [e.rule for (e of styleEntries)];
this._lastRequest = lastRequest;
return this._lastRequest;
this.inspector.emit("layoutview-updated");
}).bind(this)).then(null, console.error);
return this._lastRequest = lastRequest;
},
showBoxModel: function(options={}) {

Просмотреть файл

@ -39,20 +39,20 @@
</div>
</div>
<p class="border top"><span data-box="border" tooltip="border-top"></span></p>
<p class="border right"><span data-box="border" tooltip="border-right"></span></p>
<p class="border bottom"><span data-box="border" tooltip="border-bottom"></span></p>
<p class="border left"><span data-box="border" tooltip="border-left"></span></p>
<p class="border top"><span data-box="border" class="editable" tooltip="border-top"></span></p>
<p class="border right"><span data-box="border" class="editable" tooltip="border-right"></span></p>
<p class="border bottom"><span data-box="border" class="editable" tooltip="border-bottom"></span></p>
<p class="border left"><span data-box="border" class="editable" tooltip="border-left"></span></p>
<p class="margin top"><span data-box="margin" tooltip="margin-top"></span></p>
<p class="margin right"><span data-box="margin" tooltip="margin-right"></span></p>
<p class="margin bottom"><span data-box="margin" tooltip="margin-bottom"></span></p>
<p class="margin left"><span data-box="margin" tooltip="margin-left"></span></p>
<p class="margin top"><span data-box="margin" class="editable" tooltip="margin-top"></span></p>
<p class="margin right"><span data-box="margin" class="editable" tooltip="margin-right"></span></p>
<p class="margin bottom"><span data-box="margin" class="editable" tooltip="margin-bottom"></span></p>
<p class="margin left"><span data-box="margin" class="editable" tooltip="margin-left"></span></p>
<p class="padding top"><span data-box="padding" tooltip="padding-top"></span></p>
<p class="padding right"><span data-box="padding" tooltip="padding-right"></span></p>
<p class="padding bottom"><span data-box="padding" tooltip="padding-bottom"></span></p>
<p class="padding left"><span data-box="padding" tooltip="padding-left"></span></p>
<p class="padding top"><span data-box="padding" class="editable" tooltip="padding-top"></span></p>
<p class="padding right"><span data-box="padding" class="editable" tooltip="padding-right"></span></p>
<p class="padding bottom"><span data-box="padding" class="editable" tooltip="padding-bottom"></span></p>
<p class="padding left"><span data-box="padding" class="editable" tooltip="padding-left"></span></p>
<p class="size"><span data-box="content" tooltip="&content.tooltip;"></span></p>
@ -60,5 +60,8 @@
</div>
<div style="display: none">
<p id="dummy"></p>
</div>
</body>
</html>

Просмотреть файл

@ -211,7 +211,8 @@ function waitForNetworkEvents(aMonitor, aGetRequests, aPostRequests = 0) {
function verifyRequestItemTarget(aRequestItem, aMethod, aUrl, aData = {}) {
info("> Verifying: " + aMethod + " " + aUrl + " " + aData.toSource());
info("> Request: " + aRequestItem.attachment.toSource());
// This bloats log sizes significantly in automation (bug 992485)
//info("> Request: " + aRequestItem.attachment.toSource());
let requestsMenu = aRequestItem.ownerView;
let widgetIndex = requestsMenu.indexOfItem(aRequestItem);

Просмотреть файл

@ -376,6 +376,11 @@ InplaceEditor.prototype = {
this.input.setSelectionRange(newValue.start, newValue.end);
this._doValidation();
// Call the user's change handler if available.
if (this.change) {
this.change(this.input.value.trim());
}
return true;
},

Просмотреть файл

@ -73,6 +73,9 @@ add_task(function* test_setup() {
});
});
add_task(function* test_contract() {
Cc["@mozilla.org/browser/experiments-service;1"].getService();
});
// Test basic starting and stopping of experiments.

Просмотреть файл

@ -729,6 +729,8 @@ var ApplicationFactory = {
};
#include ../../../toolkit/components/exthelper/extApplication.js
//=================================================
// Application constructor
function Application() {
@ -737,60 +739,80 @@ function Application() {
//=================================================
// Application implementation
Application.prototype = {
function ApplicationPrototype() {
// for nsIClassInfo + XPCOMUtils
classID: APPLICATION_CID,
this.classID = APPLICATION_CID;
// redefine the default factory for XPCOMUtils
_xpcom_factory: ApplicationFactory,
this._xpcom_factory = ApplicationFactory;
// for nsISupports
QueryInterface: XPCOMUtils.generateQI([Ci.fuelIApplication, Ci.extIApplication,
Ci.nsIObserver, Ci.nsISupportsWeakReference]),
this.QueryInterface = XPCOMUtils.generateQI([
Ci.fuelIApplication,
Ci.extIApplication,
Ci.nsIObserver,
Ci.nsISupportsWeakReference
]);
// for nsIClassInfo
classInfo: XPCOMUtils.generateCI({classID: APPLICATION_CID,
contractID: APPLICATION_CONTRACTID,
interfaces: [Ci.fuelIApplication,
Ci.extIApplication,
Ci.nsIObserver],
flags: Ci.nsIClassInfo.SINGLETON}),
this.classInfo = XPCOMUtils.generateCI({
classID: APPLICATION_CID,
contractID: APPLICATION_CONTRACTID,
interfaces: [
Ci.fuelIApplication,
Ci.extIApplication,
Ci.nsIObserver
],
flags: Ci.nsIClassInfo.SINGLETON
});
// for nsIObserver
observe: function app_observe(aSubject, aTopic, aData) {
this.observe = function (aSubject, aTopic, aData) {
// Call the extApplication version of this function first
this.__proto__.__proto__.observe.call(this, aSubject, aTopic, aData);
var superPrototype = Object.getPrototypeOf(Object.getPrototypeOf(this));
superPrototype.observe.call(this, aSubject, aTopic, aData);
if (aTopic == "xpcom-shutdown") {
this._obs.removeObserver(this, "xpcom-shutdown");
Utilities.free();
}
},
};
get bookmarks() {
let bookmarks = new BookmarkRoots();
this.__defineGetter__("bookmarks", function() bookmarks);
return this.bookmarks;
},
Object.defineProperty(this, "bookmarks", {
get: function bookmarks () {
let bookmarks = new BookmarkRoots();
Object.defineProperty(this, "bookmarks", { value: bookmarks });
return this.bookmarks;
},
enumerable: true,
configurable: true
});
get windows() {
var win = [];
var browserEnum = Utilities.windowMediator.getEnumerator("navigator:browser");
Object.defineProperty(this, "windows", {
get: function windows() {
var win = [];
var browserEnum = Utilities.windowMediator.getEnumerator("navigator:browser");
while (browserEnum.hasMoreElements())
win.push(getWindow(browserEnum.getNext()));
while (browserEnum.hasMoreElements())
win.push(getWindow(browserEnum.getNext()));
return win;
},
return win;
},
enumerable: true,
configurable: true
});
Object.defineProperty(this, "activeWindow", {
get: () => getWindow(Utilities.windowMediator.getMostRecentWindow("navigator:browser")),
enumerable: true,
configurable: true
});
get activeWindow() {
return getWindow(Utilities.windowMediator.getMostRecentWindow("navigator:browser"));
}
};
#include ../../../toolkit/components/exthelper/extApplication.js
// set the proto, defined in extApplication.js
Application.prototype.__proto__ = extApplication.prototype;
ApplicationPrototype.prototype = extApplication.prototype;
Application.prototype = new ApplicationPrototype();
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([Application]);

Просмотреть файл

@ -368,6 +368,8 @@
@BINPATH@/browser/components/BrowserPlaces.manifest
@BINPATH@/browser/components/devtools-clhandler.manifest
@BINPATH@/browser/components/devtools-clhandler.js
@BINPATH@/browser/components/Experiments.manifest
@BINPATH@/browser/components/ExperimentsService.js
@BINPATH@/components/Downloads.manifest
@BINPATH@/components/DownloadLegacy.js
@BINPATH@/components/BrowserPageThumbs.manifest

Просмотреть файл

@ -707,7 +707,7 @@ Function SendPing
Call RelativeGotoPage
!else
${NSD_CreateTimer} OnPing ${DownloadIntervalMS}
InetBgDL::Get "${BaseURLStubPing}/${StubURLVersion}/${Channel}/${UpdateChannel}/${AB_CD}/$R0/$R1/$5/$6/$7/$8/$9/$ExitCode/$FirefoxLaunchCode/$DownloadRetryCount/$DownloadedBytes/$DownloadSizeBytes/$IntroPhaseSeconds/$OptionsPhaseSeconds/$0/$1/$DownloadFirstTransferSeconds/$2/$3/$4/$InitialInstallRequirementsCode/$OpenedDownloadPage/$ExistingProfile/$ExistingVersion/$ExistingBuildID/$R5/$R6/$R7/$R8/$R2/$R3/$DownloadServerIP" \
InetBgDL::Get "${BaseURLStubPing}/${StubURLVersion}${StubURLVersionAppend}/${Channel}/${UpdateChannel}/${AB_CD}/$R0/$R1/$5/$6/$7/$8/$9/$ExitCode/$FirefoxLaunchCode/$DownloadRetryCount/$DownloadedBytes/$DownloadSizeBytes/$IntroPhaseSeconds/$OptionsPhaseSeconds/$0/$1/$DownloadFirstTransferSeconds/$2/$3/$4/$InitialInstallRequirementsCode/$OpenedDownloadPage/$ExistingProfile/$ExistingVersion/$ExistingBuildID/$R5/$R6/$R7/$R8/$R2/$R3/$DownloadServerIP" \
"$PLUGINSDIR\_temp" /END
!endif
${Else}

Просмотреть файл

@ -99,7 +99,6 @@ VIAddVersionKey "OriginalFilename" "helper.exe"
!insertmacro un.CheckForFilesInUse
!insertmacro un.CleanUpdateDirectories
!insertmacro un.CleanVirtualStore
!insertmacro un.DeleteRelativeProfiles
!insertmacro un.DeleteShortcuts
!insertmacro un.GetLongPath
!insertmacro un.GetSecondInstallPath
@ -256,15 +255,6 @@ Section "Uninstall"
ClearErrors
${EndIf}
${MUI_INSTALLOPTIONS_READ} $0 "unconfirm.ini" "Field 3" "State"
${If} "$0" == "1"
${un.DeleteRelativeProfiles} "Mozilla\Firefox"
${un.DeleteRelativeProfiles} "Mozilla\MetroFirefox"
RmDir "$APPDATA\Mozilla\Extensions\{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"
RmDir "$APPDATA\Mozilla\Extensions"
RmDir "$APPDATA\Mozilla"
${EndIf}
; setup the application model id registration value
${un.InitHashAppModelId} "$INSTDIR" "Software\Mozilla\${AppName}\TaskBarIDs"
@ -551,7 +541,7 @@ Function un.preConfirm
${EndIf}
; Setup the unconfirm.ini file for the Custom Uninstall Confirm Page
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Settings" NumFields "5"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Settings" NumFields "3"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 1" Type "label"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 1" Text "$(UN_CONFIRM_UNINSTALLED_FROM)"
@ -571,44 +561,22 @@ Function un.preConfirm
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 2" Bottom "30"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 2" flags "READONLY"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Type "checkbox"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Text "$(UN_REMOVE_PROFILES)"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Type "label"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Text "$(UN_CONFIRM_CLICK)"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Left "0"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Right "-1"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Top "40"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Bottom "50"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" State "0"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" flags "NOTIFY"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 4" Type "text"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 4" State "$(UN_REMOVE_PROFILES_DESC)"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 4" Left "0"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 4" Right "-1"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 4" Top "52"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 4" Bottom "120"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 4" flags "MULTILINE|READONLY"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 5" Type "label"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 5" Text "$(UN_CONFIRM_CLICK)"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 5" Left "0"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 5" Right "-1"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 5" Top "130"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 5" Bottom "150"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Top "130"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Bottom "150"
${If} "$TmpVal" == "true"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 6" Type "label"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 6" Text "$(SUMMARY_REBOOT_REQUIRED_UNINSTALL)"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 6" Left "0"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 6" Right "-1"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 6" Top "35"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 6" Bottom "45"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 4" Type "label"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 4" Text "$(SUMMARY_REBOOT_REQUIRED_UNINSTALL)"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 4" Left "0"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 4" Right "-1"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 4" Top "35"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 4" Bottom "45"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Settings" NumFields "6"
; To insert this control reset Top / Bottom for controls below this one
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Top "55"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Bottom "65"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 4" Top "67"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Settings" NumFields "4"
${EndIf}
!insertmacro MUI_HEADER_TEXT "$(UN_CONFIRM_PAGE_TITLE)" "$(UN_CONFIRM_PAGE_SUBTITLE)"
@ -616,9 +584,6 @@ Function un.preConfirm
; focus. This sets the focus to the Install button instead.
!insertmacro MUI_INSTALLOPTIONS_INITDIALOG "unconfirm.ini"
GetDlgItem $0 $HWNDPARENT 1
${MUI_INSTALLOPTIONS_READ} $1 "unconfirm.ini" "Field 4" "HWND"
SetCtlColors $1 0x000000 0xFFFFEE
ShowWindow $1 ${SW_HIDE}
System::Call "user32::SetFocus(i r0, i 0x0007, i,i)i"
${MUI_INSTALLOPTIONS_READ} $1 "unconfirm.ini" "Field 2" "HWND"
SendMessage $1 ${WM_SETTEXT} 0 "STR:$INSTDIR"
@ -626,19 +591,6 @@ Function un.preConfirm
FunctionEnd
Function un.leaveConfirm
${MUI_INSTALLOPTIONS_READ} $0 "unconfirm.ini" "Settings" "State"
StrCmp $0 "3" +1 continue
${MUI_INSTALLOPTIONS_READ} $0 "unconfirm.ini" "Field 3" "State"
${MUI_INSTALLOPTIONS_READ} $1 "unconfirm.ini" "Field 4" "HWND"
StrCmp $0 1 +1 +3
ShowWindow $1 ${SW_SHOW}
Abort
ShowWindow $1 ${SW_HIDE}
Abort
continue:
; Try to delete the app executable and if we can't delete it try to find the
; app's message window and prompt the user to close the app. This allows
; running an instance that is located in another directory. If for whatever

Просмотреть файл

@ -58,8 +58,6 @@ UN_CONFIRM_PAGE_TITLE=Uninstall $BrandFullName
UN_CONFIRM_PAGE_SUBTITLE=Remove $BrandFullName from your computer.
UN_CONFIRM_UNINSTALLED_FROM=$BrandShortName will be uninstalled from the following location:
UN_CONFIRM_CLICK=Click Uninstall to continue.
UN_REMOVE_PROFILES=&Remove my $BrandShortName personal data and customizations
UN_REMOVE_PROFILES_DESC=This will permanently remove your bookmarks, saved passwords, cookies and customizations. You may wish to keep this information if you plan on installing another version of $BrandShortName in the future.
BANNER_CHECK_EXISTING=Checking existing installation…

Просмотреть файл

@ -0,0 +1,95 @@
/* vim: set ts=2 sw=2 et tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
let Cc = Components.classes;
let Ci = Components.interfaces;
let Cu = Components.utils;
this.EXPORTED_SYMBOLS = [ "RemotePrompt" ];
Cu.import("resource:///modules/PlacesUIUtils.jsm");
Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/SharedPromptUtils.jsm");
let RemotePrompt = {
init: function() {
let mm = Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIMessageListenerManager);
mm.addMessageListener("Prompt:Open", this);
},
receiveMessage: function(message) {
switch (message.name) {
case "Prompt:Open":
if (message.data.uri) {
this.openModalWindow(message.data, message.target);
} else {
this.openTabPrompt(message.data, message.target)
}
break;
}
},
openTabPrompt: function(args, browser) {
let window = browser.ownerDocument.defaultView;
let tabPrompt = window.gBrowser.getTabModalPromptBox(browser)
let callbackInvoked = false;
let newPrompt;
let promptId = args._remoteId;
function onPromptClose(forceCleanup) {
if (newPrompt)
tabPrompt.removePrompt(newPrompt);
PromptUtils.fireDialogEvent(window, "DOMModalDialogClosed", browser);
browser.messageManager.sendAsyncMessage("Prompt:Close", args);
}
browser.messageManager.addMessageListener("Prompt:ForceClose", function listener(message) {
// If this was for another prompt in the same tab, ignore it.
if (message.data._remoteId !== promptId) {
return;
}
browser.messageManager.removeMessageListener("Prompt:ForceClose", listener);
if (newPrompt) {
newPrompt.abortPrompt();
}
});
try {
PromptUtils.fireDialogEvent(window, "DOMWillOpenModalDialog", browser);
args.promptActive = true;
newPrompt = tabPrompt.appendPrompt(args, onPromptClose);
// TODO since we don't actually open a window, need to check if
// there's other stuff in nsWindowWatcher::OpenWindowInternal
// that we might need to do here as well.
} catch (ex) {
onPromptClose(true);
}
},
openModalWindow: function(args, browser) {
let window = browser.ownerDocument.defaultView;
try {
PromptUtils.fireDialogEvent(window, "DOMWillOpenModalDialog", browser);
let bag = PromptUtils.objectToPropBag(args);
Services.ww.openWindow(window, args.uri, "_blank",
"centerscreen,chrome,modal,titlebar", bag);
PromptUtils.propBagToObject(bag, args);
} finally {
PromptUtils.fireDialogEvent(window, "DOMModalDialogClosed", browser);
browser.messageManager.sendAsyncMessage("Prompt:Close", args);
}
}
};

Просмотреть файл

@ -15,6 +15,7 @@ EXTRA_JS_MODULES += [
'Feeds.jsm',
'NetworkPrioritizer.jsm',
'offlineAppCache.jsm',
'RemotePrompt.jsm',
'SharedFrame.jsm',
'SitePermissions.jsm',
'Social.jsm',

Просмотреть файл

@ -39,3 +39,16 @@
background-color: #d89b28;
opacity: 0.6;
}
.editable {
border-bottom: 1px dashed transparent;
}
.editable:hover {
border-bottom-color: hsl(0,0%,50%);
}
.styleinspector-propertyeditor {
border: 1px solid #CCC;
padding: 0;
}

Просмотреть файл

@ -132,7 +132,6 @@ button,
menulist {
-moz-appearance: none;
height: 30px;
max-height: 30px;
color: #737980;
line-height: 20px;
text-shadow: 0 1px 1px #FEFFFE;

Просмотреть файл

@ -123,21 +123,15 @@
* text and icons to not appear fuzzy.
*/
@media (-moz-windows-classic) {
#main-window[tabsintitlebar]:not([sizemode=fullscreen]) .tabbrowser-tab[selected=true] {
position: relative;
z-index: 3;
}
#main-window[tabsintitlebar]:not([sizemode=fullscreen]) .tabbrowser-tab:not([selected=true]) {
/**
* We need to bump up the z-index of the tabbrowser-tabs so that they appear
* over top of the fog we're applying for classic themes, as well as the nav-bar.
*/
#main-window[tabsintitlebar]:not([sizemode=fullscreen]) #tabbrowser-tabs {
position: relative;
z-index: 2;
}
#main-window[tabsintitlebar]:not([sizemode=fullscreen]) .tabs-newtab-button {
position: relative;
z-index: 1;
}
#main-window[tabsintitlebar] #TabsToolbar:not(:-moz-lwtheme) {
background-image: none;
position: relative;
@ -159,7 +153,6 @@
pointer-events: none;
top: 100%;
width: -moz-available;
z-index: 0;
}
#main-window[tabsintitlebar]:not([sizemode=fullscreen]) #TabsToolbar:not(:-moz-lwtheme):-moz-window-inactive::after {
@ -176,17 +169,31 @@
overflow: -moz-hidden-unscrollable;
}
#main-window[tabsintitlebar][sizemode=normal] .tabbrowser-arrowscrollbox > .arrowscrollbox-scrollbox > .scrollbox-innerbox:not(:-moz-lwtheme) {
position: relative;
/**
* When the tabstrip is overflowed, pinned tab separators get position: absolute,
* which makes the pinned tab separators leak over the nav-bar highlight. Forcing
* the element to snap to the bottom of the client rect works around the issue.
*/
#main-window[tabsintitlebar] #tabbrowser-tabs[positionpinnedtabs] > .tabbrowser-tab[pinned]::before {
bottom: 0px;
}
#main-window[tabsintitlebar]:not([sizemode=fullscreen]) #TabsToolbar .toolbarbutton-1,
#main-window[tabsintitlebar]:not([sizemode=fullscreen]) .tabbrowser-arrowscrollbox > .scrollbutton-up,
#main-window[tabsintitlebar]:not([sizemode=fullscreen]) .tabbrowser-arrowscrollbox > .scrollbutton-down {
#main-window[tabsintitlebar]:not([sizemode=fullscreen]) #TabsToolbar .toolbarbutton-1 {
position: relative;
z-index: 1;
}
/**
* With the tabbrowser-tabs element z-index'd above the nav-bar, we now get the
* scrollbox button borders leaking over the nav-bar highlight. This transparent bottom
* border forces the scrollbox button borders to terminate a pixel early, working
* around the issue.
*/
#main-window[tabsintitlebar]:not([sizemode=fullscreen]) .tabbrowser-arrowscrollbox > .scrollbutton-up,
#main-window[tabsintitlebar]:not([sizemode=fullscreen]) .tabbrowser-arrowscrollbox > .scrollbutton-down {
border-bottom: 1px solid transparent;
}
#main-window[tabsintitlebar]:not([inFullscreen]) .tab-close-button:not(:-moz-any(:hover,:-moz-lwtheme,[selected="true"])) {
-moz-image-region: rect(0, 64px, 16px, 48px);
}

Просмотреть файл

@ -632,6 +632,32 @@ public:
GetElementsByClassName(const nsAString& aClassNames);
bool MozMatchesSelector(const nsAString& aSelector,
ErrorResult& aError);
void SetPointerCapture(int32_t aPointerId, ErrorResult& aError)
{
bool activeState = false;
if (!nsIPresShell::GetPointerInfo(aPointerId, activeState)) {
aError.Throw(NS_ERROR_DOM_INVALID_POINTER_ERR);
return;
}
if (!activeState) {
return;
}
nsIPresShell::SetPointerCapturingContent(aPointerId, this);
}
void ReleasePointerCapture(int32_t aPointerId, ErrorResult& aError)
{
bool activeState = false;
if (!nsIPresShell::GetPointerInfo(aPointerId, activeState)) {
aError.Throw(NS_ERROR_DOM_INVALID_POINTER_ERR);
return;
}
// Ignoring ReleasePointerCapture call on incorrect element (on element
// that didn't have capture before).
if (nsIPresShell::GetPointerCapturingContent(aPointerId) == this) {
nsIPresShell::ReleasePointerCapturingContent(aPointerId, this);
}
}
void SetCapture(bool aRetargetToElement)
{
// If there is already an active capture, ignore this request. This would

Просмотреть файл

@ -5,11 +5,9 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=339494
-->
<window title="Mozilla Bug 339494"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 339494</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<body xmlns="http://www.w3.org/1999/xhtml">

Просмотреть файл

@ -7,10 +7,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=357450
-->
<window title="Mozilla Bug 357450"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 357450</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<!-- This file is shared with non-chrome tests -->

Просмотреть файл

@ -10,7 +10,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=607114.xul
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 607114</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>

Просмотреть файл

@ -39,7 +39,12 @@ public:
NS_INLINE_DECL_REFCOUNTING(WebGLActiveInfo)
protected:
private:
// Private destructor, to discourage deletion outside of Release():
~WebGLActiveInfo()
{
}
GLint mSize;
GLenum mType;
nsString mName;

Просмотреть файл

@ -39,7 +39,12 @@ public:
NS_INLINE_DECL_REFCOUNTING(WebGLShaderPrecisionFormat)
protected:
private:
// Private destructor, to discourage deletion outside of Release():
~WebGLShaderPrecisionFormat()
{
}
GLint mRangeMin;
GLint mRangeMax;
GLint mPrecision;

Просмотреть файл

@ -2,7 +2,7 @@
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
xmlns:html="http://www.w3.org/1999/xhtml"
title="Test for Bug 233643">
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=233643

Просмотреть файл

@ -100,7 +100,8 @@ const JSClass nsXULPDGlobalObject::gSharedGlobalClass = {
JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(0),
JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
JS_EnumerateStub, nsXULPDGlobalObject_resolve, JS_ConvertStub,
nsXULPDGlobalObject_finalize, nullptr, nullptr, nullptr, nullptr
nsXULPDGlobalObject_finalize, nullptr, nullptr, nullptr,
JS_GlobalObjectTraceHook
};

Просмотреть файл

@ -11,14 +11,16 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=199692
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<bindings xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="anon">
<content>
<xul:label id="anon-label" value="ANON"/>
</content>
</binding>
</bindings>
<vbox hidden="true">
<bindings xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="anon">
<content>
<xul:label id="anon-label" value="ANON"/>
</content>
</binding>
</bindings>
</vbox>
<body id="body" xmlns="http://www.w3.org/1999/xhtml">
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=199692">Mozilla Bug 199692</a>

Просмотреть файл

@ -8,7 +8,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=311681
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 311681</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<body xmlns="http://www.w3.org/1999/xhtml">

Просмотреть файл

@ -9,7 +9,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=335375
<window title="Mozilla Bug 335375"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="RunTest();">
<title>Mozilla Bug 335375</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>

Просмотреть файл

@ -8,20 +8,22 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=414907
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<bindings xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="anon">
<implementation>
<constructor>
<![CDATA[
var node = this.firstChild;
this.palette = node;
this.removeChild(node);
]]>
</constructor>
</implementation>
</binding>
<vbox hidden="true">
<bindings xmlns="http://www.mozilla.org/xbl" style="display: block;"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="anon">
<implementation>
<constructor>
<![CDATA[
var node = this.firstChild;
this.palette = node;
this.removeChild(node);
]]>
</constructor>
</implementation>
</binding>
</bindings>
</vbox>
<!-- test results are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml">

Просмотреть файл

@ -9,7 +9,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=497875
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 497875</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />

Просмотреть файл

@ -7,10 +7,8 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=476634
-->
<window title="Mozilla Bug 476634" onload="startup()"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 476634</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>

Просмотреть файл

@ -7,10 +7,8 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=112564
-->
<window title="Mozilla Bug 112564"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 112564</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>

Просмотреть файл

@ -7,10 +7,8 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=215405
-->
<window title="Mozilla Bug 215405"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 215405</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>

Просмотреть файл

@ -7,10 +7,8 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=293235.xul
-->
<window title="Mozilla Bug 293235"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 293235</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>

Просмотреть файл

@ -7,10 +7,8 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=294258.xul
-->
<window title="Mozilla Bug 294258"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 294258</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>

Просмотреть файл

@ -7,10 +7,8 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=298622.xul
-->
<window title="Mozilla Bug 298622"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 298622</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>

Просмотреть файл

@ -7,10 +7,8 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=301397.xul
-->
<window title="Mozilla Bug 301397"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 301397</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>

Просмотреть файл

@ -7,10 +7,8 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=303267.xul
-->
<window title="Mozilla Bug 303267"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 303267</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>

Просмотреть файл

@ -7,10 +7,8 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=311007.xul
-->
<window title="Mozilla Bug 311007"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 311007</title>
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript"

Просмотреть файл

@ -7,10 +7,8 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=321671.xul
-->
<window title="Mozilla Bug 321671"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 321671</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>

Просмотреть файл

@ -7,10 +7,8 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=360511.xul
-->
<window title="Mozilla Bug 360511"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 360511</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
</script>

Просмотреть файл

@ -7,10 +7,8 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=364461
-->
<window title="Mozilla Bug 364461"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 364461</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>

Просмотреть файл

@ -7,10 +7,8 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=396649.xul
-->
<window title="Mozilla Bug 396649"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 396649</title>
<script type="application/javascript"
src=
"chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">

Просмотреть файл

@ -7,7 +7,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=453650
<window title="Mozilla Bug 453650"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 453650</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>

Просмотреть файл

@ -7,7 +7,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=565388
<window title="Mozilla Bug 565388"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 565388</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>

Просмотреть файл

@ -7,10 +7,8 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=582176.xul
-->
<window title="Mozilla Bug 582176"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 582176</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>

Просмотреть файл

@ -7,10 +7,8 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=662200.xul
-->
<window title="Mozilla Bug 662200"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 662200</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>

Просмотреть файл

@ -7,7 +7,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=846906
<window title="Mozilla Bug 846906"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 846906</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>

Просмотреть файл

@ -7,10 +7,8 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=89419.xul
-->
<window title="Mozilla Bug 89419"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 89419</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>

Просмотреть файл

@ -7,10 +7,8 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=92598
-->
<window title="Mozilla Bug 92598"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 92598</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>

Просмотреть файл

@ -9,10 +9,8 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=769771
-->
<window title="Test mozFrameType attribute"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test mozFrameType attribute</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>

Просмотреть файл

@ -9,10 +9,8 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=719994
-->
<window title="Test principal inheriting"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test principal inheriting</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>

Просмотреть файл

@ -50,6 +50,7 @@ enum DOM4ErrorTypeCodeMap {
TimeoutError = nsIDOMDOMException::TIMEOUT_ERR,
InvalidNodeTypeError = nsIDOMDOMException::INVALID_NODE_TYPE_ERR,
DataCloneError = nsIDOMDOMException::DATA_CLONE_ERR,
InvalidPointerId = nsIDOMDOMException::INVALID_POINTER_ERR,
EncodingError = 0,
/* XXX Should be JavaScript native errors */

Просмотреть файл

@ -30,6 +30,7 @@ DOM4_MSG_DEF(QuotaExceededError, "The quota has been exceeded.", NS_ERROR_DOM_QU
DOM4_MSG_DEF(TimeoutError, "The operation timed out.", NS_ERROR_DOM_TIMEOUT_ERR)
DOM4_MSG_DEF(InvalidNodeTypeError, "The supplied node is incorrect or has an incorrect ancestor for this operation.", NS_ERROR_DOM_INVALID_NODE_TYPE_ERR)
DOM4_MSG_DEF(DataCloneError, "The object could not be cloned.", NS_ERROR_DOM_DATA_CLONE_ERR)
DOM4_MSG_DEF(InvalidPointerId, "Invalid pointer id.", NS_ERROR_DOM_INVALID_POINTER_ERR)
/* XXX Should be JavaScript native TypeError */
DOM4_MSG_DEF(TypeError, "The method parameter is missing or invalid.", NS_ERROR_TYPE_ERR)

Просмотреть файл

@ -67,6 +67,7 @@
#include "mozilla/dom/Element.h"
#include "mozilla/dom/file/FileHandle.h"
#include "mozilla/dom/FileHandleBinding.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/IDBFactoryBinding.h"
#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
#include "mozilla/dom/quota/PersistenceType.h"
@ -3623,6 +3624,12 @@ nsDOMWindowUtils::GetIsParentWindowMainWidgetVisible(bool* aIsVisible)
nsCOMPtr<nsIWidget> parentWidget;
nsIDocShell *docShell = window->GetDocShell();
if (docShell) {
if (TabChild *tabChild = TabChild::GetFrom(docShell)) {
if (!tabChild->SendIsParentWindowMainWidgetVisible(aIsVisible))
return NS_ERROR_FAILURE;
return NS_OK;
}
nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
docShell->GetTreeOwner(getter_AddRefs(parentTreeOwner));
nsCOMPtr<nsIBaseWindow> parentWindow(do_GetInterface(parentTreeOwner));

Просмотреть файл

@ -2917,21 +2917,6 @@ nsGlobalWindow::UpdateParentTarget()
mParentTarget = eventTarget;
}
bool
nsGlobalWindow::GetIsTabModalPromptAllowed()
{
MOZ_ASSERT(IsOuterWindow());
bool allowTabModal = true;
if (mDocShell) {
nsCOMPtr<nsIContentViewer> cv;
mDocShell->GetContentViewer(getter_AddRefs(cv));
cv->GetIsTabModalPromptAllowed(&allowTabModal);
}
return allowTabModal;
}
EventTarget*
nsGlobalWindow::GetTargetForDOMEvent()
{
@ -6166,10 +6151,6 @@ nsGlobalWindow::AlertOrConfirm(bool aAlert,
nsAutoString final;
nsContentUtils::StripNullChars(aMessage, final);
// Check if we're being called at a point where we can't use tab-modal
// prompts, because something doesn't want reentrancy.
bool allowTabModal = GetIsTabModalPromptAllowed();
nsresult rv;
nsCOMPtr<nsIPromptFactory> promptFac =
do_GetService("@mozilla.org/prompter;1", &rv);
@ -6185,9 +6166,10 @@ nsGlobalWindow::AlertOrConfirm(bool aAlert,
return false;
}
nsCOMPtr<nsIWritablePropertyBag2> promptBag = do_QueryInterface(prompt);
if (promptBag)
promptBag->SetPropertyAsBool(NS_LITERAL_STRING("allowTabModal"), allowTabModal);
// Always allow tab modal prompts for alert and confirm.
if (nsCOMPtr<nsIWritablePropertyBag2> promptBag = do_QueryInterface(prompt)) {
promptBag->SetPropertyAsBool(NS_LITERAL_STRING("allowTabModal"), true);
}
bool result = false;
nsAutoSyncOperation sync(mDoc);
@ -6281,10 +6263,6 @@ nsGlobalWindow::Prompt(const nsAString& aMessage, const nsAString& aInitial,
nsContentUtils::StripNullChars(aMessage, fixedMessage);
nsContentUtils::StripNullChars(aInitial, fixedInitial);
// Check if we're being called at a point where we can't use tab-modal
// prompts, because something doesn't want reentrancy.
bool allowTabModal = GetIsTabModalPromptAllowed();
nsresult rv;
nsCOMPtr<nsIPromptFactory> promptFac =
do_GetService("@mozilla.org/prompter;1", &rv);
@ -6300,9 +6278,10 @@ nsGlobalWindow::Prompt(const nsAString& aMessage, const nsAString& aInitial,
return;
}
nsCOMPtr<nsIWritablePropertyBag2> promptBag = do_QueryInterface(prompt);
if (promptBag)
promptBag->SetPropertyAsBool(NS_LITERAL_STRING("allowTabModal"), allowTabModal);
// Always allow tab modal prompts for prompt.
if (nsCOMPtr<nsIWritablePropertyBag2> promptBag = do_QueryInterface(prompt)) {
promptBag->SetPropertyAsBool(NS_LITERAL_STRING("allowTabModal"), true);
}
// Pass in the default value, if any.
char16_t *inoutValue = ToNewUnicode(fixedInitial);

Просмотреть файл

@ -1299,9 +1299,6 @@ protected:
virtual void UpdateParentTarget();
// Outer windows only.
bool GetIsTabModalPromptAllowed();
inline int32_t DOMMinTimeoutValue() const;
nsresult CloneStorageEvent(const nsAString& aType,

Просмотреть файл

@ -9,7 +9,6 @@
<window title="DOMRequestHelper Test"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="start();">
<title>DOMRequestHelper Test</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>

Просмотреть файл

@ -2554,6 +2554,8 @@ CreateGlobal(JSContext* aCx, T* aObject, nsWrapperCache* aCache,
{
MOZ_ASSERT(!NS_IsMainThread());
aOptions.setTrace(TraceGlobal);
JS::Rooted<JSObject*> global(aCx,
JS_NewGlobalObject(aCx, aClass, aPrincipal, JS::DontFireOnNewGlobalHook,
aOptions));

Просмотреть файл

@ -10,6 +10,7 @@ import re
import string
import math
import itertools
from textwrap import dedent
from WebIDL import BuiltinTypes, IDLBuiltinType, IDLNullValue, IDLSequenceType, IDLType, IDLAttribute, IDLUndefinedValue
from Configuration import NoSuchDescriptorError, getTypesFromDescriptor, getTypesFromDictionary, getTypesFromCallback, Descriptor
@ -55,6 +56,93 @@ def wantsAddProperty(desc):
not desc.interface.getExtendedAttribute("Global"))
# We'll want to insert the indent at the beginnings of lines, but we
# don't want to indent empty lines. So only indent lines that have a
# non-newline character on them.
lineStartDetector = re.compile("^(?=[^\n#])", re.MULTILINE)
def indent(s, indentLevel=2):
"""
Indent C++ code.
Weird secret feature: this doesn't indent lines that start with # (such as
#include lines).
"""
if s == "":
return s
return re.sub(lineStartDetector, indentLevel * " ", s)
def fill(template, **args):
"""
Convenience function for filling in a multiline template.
`fill(template, name1=v1, name2=v2)` is a lot like
`string.Template(template).substitute({"name1": v1, "name2": v2})`.
However, it's shorter, and has a few nice features:
* If `template` is indented, fill() automatically dedents it!
This makes code using fill() with Python's multiline strings
much nicer to look at.
* If `template` starts with a blank line, fill() strips it off.
(Again, convenient with multiline strings.)
* fill() recognizes a special kind of substitution
of the form `$*{name}`.
Use this to paste in, and automatically indent, multiple lines.
(Mnemonic: The `*` is for "multiple lines").
A `$*` substitution must appear by itself on a line, with optional
preceding indentation (spaces only). The whole line is replaced by the
corresponding keyword argument, indented appropriately. If the
argument is an empty string, no output is generated, not even a blank
line.
"""
# This works by transforming the fill()-template to an equivalent
# string.Template.
multiline_substitution_re = re.compile(r"( *)\$\*{(\w+)}(\n)?")
def replace(match):
"""
Replaces a line like ' $*{xyz}\n' with '${xyz_n}',
where n is the indent depth, and add a corresponding entry to args.
"""
indentation, name, nl = match.groups()
depth = len(indentation)
# Check that $*{xyz} appears by itself on a line.
prev = match.string[:match.start()]
if (prev and not prev.endswith("\n")) or nl is None:
raise ValueError("Invalid fill() template: $*{%s} must appear by itself on a line" % name)
# Multiline text without a newline at the end is probably a mistake.
if not (args[name] == "" or args[name].endswith("\n")):
raise ValueError("Argument %s with value %r is missing a newline" % (name, args[name]))
# Now replace this whole line of template with the indented equivalent.
modified_name = name + "_" + str(depth)
indented_value = indent(args[name], depth)
if modified_name in args:
assert args[modified_name] == indented_value
else:
args[modified_name] = indented_value
return "${" + modified_name + "}"
t = template
if t.startswith("\n"):
t = t[1:]
t = dedent(t)
assert t.endswith("\n") or "\n" not in t
t = re.sub(multiline_substitution_re, replace, t)
t = string.Template(t)
return t.substitute(args)
class CGThing():
"""
Abstract base class for things that spit out code.
@ -109,14 +197,20 @@ class CGStringTable(CGThing):
for s in self.strings:
indices.append(currentIndex)
currentIndex += len(s) + 1 # for the null terminator
return """const char *%s(unsigned int aIndex)
{
static const char table[] = %s;
static const uint16_t indices[] = { %s };
static_assert(%d <= UINT16_MAX, "string table overflow!");
return &table[indices[aIndex]];
}
""" % (self.accessorName, table, ", ".join("%d" % index for index in indices), currentIndex)
return fill(
"""
const char *${name}(unsigned int aIndex)
{
static const char table[] = ${table};
static const uint16_t indices[] = { ${indices} };
static_assert(${currentIndex} <= UINT16_MAX, "string table overflow!");
return &table[indices[aIndex]];
}
""",
name=self.accessorName,
table=table,
indices=", ".join("%d" % index for index in indices),
currentIndex=currentIndex)
class CGNativePropertyHooks(CGThing):
@ -203,20 +297,21 @@ def DOMClass(descriptor):
# is never the ID of any prototype, so it's safe to use as
# padding.
protoList.extend(['prototypes::id::_ID_Count'] * (descriptor.config.maxProtoChainLength - len(protoList)))
prototypeChainString = ', '.join(protoList)
participant = "GetCCParticipant<%s>::Get()" % descriptor.nativeType
getParentObject = "GetParentObject<%s>::Get" % descriptor.nativeType
return """{
{ %s },
IsBaseOf<nsISupports, %s >::value,
%s,
%s,
GetProtoObject,
%s
}""" % (prototypeChainString, descriptor.nativeType,
NativePropertyHooks(descriptor),
getParentObject,
participant)
return fill(
"""
{
{ ${protoChain} },
IsBaseOf<nsISupports, ${nativeType} >::value,
${hooks},
GetParentObject<${nativeType}>::Get,
GetProtoObject,
GetCCParticipant<${nativeType}>::Get()
}
""",
protoChain=', '.join(protoList),
nativeType=descriptor.nativeType,
hooks=NativePropertyHooks(descriptor))
class CGDOMJSClass(CGThing):
@ -237,7 +332,7 @@ class CGDOMJSClass(CGThing):
classFlags = "JSCLASS_IS_DOMJSCLASS | "
if self.descriptor.interface.getExtendedAttribute("Global"):
classFlags += "JSCLASS_DOM_GLOBAL | JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(DOM_GLOBAL_SLOTS) | JSCLASS_IMPLEMENTS_BARRIERS"
traceHook = "mozilla::dom::TraceGlobal"
traceHook = "JS_GlobalObjectTraceHook"
else:
classFlags += "JSCLASS_HAS_RESERVED_SLOTS(%d)" % slotCount
if self.descriptor.interface.getExtendedAttribute("NeedNewResolve"):
@ -251,34 +346,41 @@ class CGDOMJSClass(CGThing):
else:
newResolveHook = "JS_ResolveStub"
enumerateHook = "JS_EnumerateStub"
template = """
static const DOMJSClass Class = {
{ "%s",
%s,
%s, /* addProperty */
JS_DeletePropertyStub, /* delProperty */
JS_PropertyStub, /* getProperty */
JS_StrictPropertyStub, /* setProperty */
%s, /* enumerate */
%s, /* resolve */
JS_ConvertStub,
%s, /* finalize */
%s, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
%s, /* trace */
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
%s
};
"""
return template % (self.descriptor.interface.identifier.name,
classFlags,
ADDPROPERTY_HOOK_NAME if wantsAddProperty(self.descriptor) else 'JS_PropertyStub',
enumerateHook, newResolveHook, FINALIZE_HOOK_NAME, callHook, traceHook,
CGIndenter(CGGeneric(DOMClass(self.descriptor))).define())
return fill( # BOGUS extra blank line at the top
"""
static const DOMJSClass Class = {
{ "${name}",
${flags},
${addProperty}, /* addProperty */
JS_DeletePropertyStub, /* delProperty */
JS_PropertyStub, /* getProperty */
JS_StrictPropertyStub, /* setProperty */
${enumerate}, /* enumerate */
${resolve}, /* resolve */
JS_ConvertStub,
${finalize}, /* finalize */
${call}, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
${trace}, /* trace */
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
$*{descriptor}
};
""",
name=self.descriptor.interface.identifier.name,
flags=classFlags,
addProperty=ADDPROPERTY_HOOK_NAME if wantsAddProperty(self.descriptor) else 'JS_PropertyStub',
enumerate=enumerateHook,
resolve=newResolveHook,
finalize=FINALIZE_HOOK_NAME,
call=callHook,
trace=traceHook,
descriptor=DOMClass(self.descriptor))
class CGDOMProxyJSClass(CGThing):
@ -300,20 +402,22 @@ class CGDOMProxyJSClass(CGThing):
if self.descriptor.interface.identifier.name == "HTMLAllCollection":
flags.append("JSCLASS_EMULATES_UNDEFINED")
callHook = LEGACYCALLER_HOOK_NAME if self.descriptor.operations["LegacyCaller"] else 'nullptr'
template = """
static const DOMJSClass Class = {
PROXY_CLASS_DEF("%s",
0, /* extra slots */
%s,
%s, /* call */
nullptr /* construct */),
%s
};
"""
return template % (self.descriptor.interface.identifier.name,
" | ".join(flags),
callHook,
CGIndenter(CGGeneric(DOMClass(self.descriptor))).define())
return fill( # BOGUS extra blank line at the top
"""
static const DOMJSClass Class = {
PROXY_CLASS_DEF("${name}",
0, /* extra slots */
${flags},
${call}, /* call */
nullptr /* construct */),
$*{descriptor}
};
""",
name=self.descriptor.interface.identifier.name,
flags=" | ".join(flags),
call=callHook,
descriptor=DOMClass(self.descriptor))
def PrototypeIDAndDepth(descriptor):
@ -547,36 +651,27 @@ class CGGeneric(CGThing):
return set()
# We'll want to insert the indent at the beginnings of lines, but we
# don't want to indent empty lines. So only indent lines that have a
# non-newline character on them.
lineStartDetector = re.compile("^(?=[^\n#])", re.MULTILINE)
class CGIndenter(CGThing):
"""
A class that takes another CGThing and generates code that indents that
CGThing by some number of spaces. The default indent is two spaces.
"""
def __init__(self, child, indentLevel=2, declareOnly=False):
assert isinstance(child, CGThing)
CGThing.__init__(self)
self.child = child
self.indent = " " * indentLevel
self.indentLevel = indentLevel
self.declareOnly = declareOnly
def declare(self):
decl = self.child.declare()
if decl is not "":
return re.sub(lineStartDetector, self.indent, decl)
else:
return ""
return indent(self.child.declare(), self.indentLevel)
def define(self):
defn = self.child.define()
if defn is not "" and not self.declareOnly:
return re.sub(lineStartDetector, self.indent, defn)
else:
if self.declareOnly:
return defn
else:
return indent(defn, self.indentLevel)
class CGWrapper(CGThing):
@ -1418,26 +1513,32 @@ class CGNamedConstructors(CGThing):
constructorID += self.descriptor.name
else:
constructorID += "_ID_Count"
nativePropertyHooks = """const NativePropertyHooks sNamedConstructorNativePropertyHooks = {
nullptr,
nullptr,
{ nullptr, nullptr },
prototypes::id::%s,
%s,
nullptr
};
""" % (self.descriptor.name, constructorID)
namedConstructors = CGList([], ",\n")
namedConstructors = ""
for n in self.descriptor.interface.namedConstructors:
namedConstructors.append(
CGGeneric("{ \"%s\", { %s, &sNamedConstructorNativePropertyHooks }, %i }" %
(n.identifier.name, NamedConstructorName(n), methodLength(n))))
namedConstructors.append(CGGeneric("{ nullptr, { nullptr, nullptr }, 0 }"))
namedConstructors = CGWrapper(CGIndenter(namedConstructors),
pre="static const NamedConstructor namedConstructors[] = {\n",
post="\n};\n")
return nativePropertyHooks + namedConstructors.define()
namedConstructors += (
"{ \"%s\", { %s, &sNamedConstructorNativePropertyHooks }, %i },\n" %
(n.identifier.name, NamedConstructorName(n), methodLength(n)))
return fill(
"""
const NativePropertyHooks sNamedConstructorNativePropertyHooks = {
nullptr,
nullptr,
{ nullptr, nullptr },
prototypes::id::${name},
${constructorID},
nullptr
};
static const NamedConstructor namedConstructors[] = {
$*{namedConstructors}
{ nullptr, { nullptr, nullptr }, 0 }
};
""",
name=self.descriptor.name,
constructorID=constructorID,
namedConstructors=namedConstructors)
class CGClassHasInstanceHook(CGAbstractStaticMethod):

Просмотреть файл

@ -48,26 +48,21 @@ ConvertStringToPointerType(const nsAString& aPointerTypeArg)
return nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
}
//static
// static
already_AddRefed<PointerEvent>
PointerEvent::Constructor(const GlobalObject& aGlobal,
PointerEvent::Constructor(EventTarget* aOwner,
const nsAString& aType,
const PointerEventInit& aParam,
ErrorResult& aRv)
const PointerEventInit& aParam)
{
nsCOMPtr<EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports());
nsRefPtr<PointerEvent> e = new PointerEvent(t, nullptr, nullptr);
bool trusted = e->Init(t);
nsRefPtr<PointerEvent> e = new PointerEvent(aOwner, nullptr, nullptr);
bool trusted = e->Init(aOwner);
aRv = e->InitMouseEvent(aType, aParam.mBubbles, aParam.mCancelable,
aParam.mView, aParam.mDetail, aParam.mScreenX,
aParam.mScreenY, aParam.mClientX, aParam.mClientY,
aParam.mCtrlKey, aParam.mAltKey, aParam.mShiftKey,
aParam.mMetaKey, aParam.mButton,
aParam.mRelatedTarget);
if (aRv.Failed()) {
return nullptr;
}
e->InitMouseEvent(aType, aParam.mBubbles, aParam.mCancelable,
aParam.mView, aParam.mDetail, aParam.mScreenX,
aParam.mScreenY, aParam.mClientX, aParam.mClientY,
aParam.mCtrlKey, aParam.mAltKey, aParam.mShiftKey,
aParam.mMetaKey, aParam.mButton,
aParam.mRelatedTarget);
WidgetPointerEvent* widgetEvent = e->mEvent->AsPointerEvent();
widgetEvent->pointerId = aParam.mPointerId;
@ -84,6 +79,17 @@ PointerEvent::Constructor(const GlobalObject& aGlobal,
return e.forget();
}
// static
already_AddRefed<PointerEvent>
PointerEvent::Constructor(const GlobalObject& aGlobal,
const nsAString& aType,
const PointerEventInit& aParam,
ErrorResult& aRv)
{
nsCOMPtr<EventTarget> owner = do_QueryInterface(aGlobal.GetAsSupports());
return Constructor(owner, aType, aParam);
}
void
PointerEvent::GetPointerType(nsAString& aPointerType)
{

Просмотреть файл

@ -34,6 +34,11 @@ public:
const PointerEventInit& aParam,
ErrorResult& aRv);
static already_AddRefed<PointerEvent>
Constructor(EventTarget* aOwner,
const nsAString& aType,
const PointerEventInit& aParam);
int32_t PointerId();
int32_t Width();
int32_t Height();

Просмотреть файл

@ -9,7 +9,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=415498
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="init()">
<title>Test for Bug 415498</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"

Просмотреть файл

@ -7,7 +7,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=586961
<window title="Mozilla Bug 586961"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 586961</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<body xmlns="http://www.w3.org/1999/xhtml">

Просмотреть файл

@ -7,7 +7,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=602962
<window title="Mozilla Bug 602962" onload="openWindow()"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 602962</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<body xmlns="http://www.w3.org/1999/xhtml">

Просмотреть файл

@ -7,7 +7,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=67949
<window title="Mozilla Bug 67949" onload="doTest();"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Test for Bug 67949</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<body xmlns="http://www.w3.org/1999/xhtml">

Просмотреть файл

@ -685,7 +685,9 @@ const JSClass ThreadLocalJSRuntime::sGlobalClass = {
"IndexedDBTransactionThreadGlobal",
JSCLASS_GLOBAL_FLAGS,
JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
nullptr, nullptr, nullptr, nullptr,
JS_GlobalObjectTraceHook
};
inline

Просмотреть файл

@ -6,7 +6,7 @@
#include "domstubs.idl"
interface nsIContentFrameMessageManager;
[uuid( 60146bc6-31d8-450b-a9eb-4000b6403d5c)]
[scriptable, uuid(2eb3bc54-78bf-40f2-b301-a5b5b70f7da0)]
interface nsITabChild : nsISupports
{
readonly attribute nsIContentFrameMessageManager messageManager;

Просмотреть файл

@ -45,6 +45,7 @@ interface nsIDOMDOMException : nsISupports
const unsigned short TIMEOUT_ERR = 23;
const unsigned short INVALID_NODE_TYPE_ERR = 24;
const unsigned short DATA_CLONE_ERR = 25;
const unsigned short INVALID_POINTER_ERR = 26;
readonly attribute unsigned short code;
};

Просмотреть файл

@ -208,6 +208,8 @@ parent:
int32_t cause,
int32_t focusChange);
sync IsParentWindowMainWidgetVisible() returns (bool visible);
/**
* Gets the DPI of the screen corresponding to this browser.
*/

Просмотреть файл

@ -38,6 +38,7 @@
#include "nsIDOMElement.h"
#include "nsIDOMEvent.h"
#include "nsIDOMWindow.h"
#include "nsIDOMWindowUtils.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIPromptFactory.h"
#include "nsIURI.h"
@ -1504,6 +1505,18 @@ TabParent::RecvSetInputContext(const int32_t& aIMEEnabled,
return true;
}
bool
TabParent::RecvIsParentWindowMainWidgetVisible(bool* aIsVisible)
{
nsCOMPtr<nsIContent> frame = do_QueryInterface(mFrameElement);
if (!frame)
return true;
nsCOMPtr<nsIDOMWindowUtils> windowUtils =
do_QueryInterface(frame->OwnerDoc()->GetWindow());
nsresult rv = windowUtils->GetIsParentWindowMainWidgetVisible(aIsVisible);
return NS_SUCCEEDED(rv);
}
bool
TabParent::RecvGetDPI(float* aValue)
{

Просмотреть файл

@ -172,6 +172,7 @@ public:
virtual bool RecvSetCursor(const uint32_t& aValue) MOZ_OVERRIDE;
virtual bool RecvSetBackgroundColor(const nscolor& aValue) MOZ_OVERRIDE;
virtual bool RecvSetStatus(const uint32_t& aType, const nsString& aStatus) MOZ_OVERRIDE;
virtual bool RecvIsParentWindowMainWidgetVisible(bool* aIsVisible);
virtual bool RecvShowTooltip(const uint32_t& aX, const uint32_t& aY, const nsString& aTooltip);
virtual bool RecvHideTooltip();
virtual bool RecvGetDPI(float* aValue) MOZ_OVERRIDE;

Просмотреть файл

@ -3,9 +3,7 @@
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<window title="NPAPI Private Mode Tests"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>NPAPI Private Mode Tests</title>
<body xmlns="http://www.w3.org/1999/xhtml">
<embed id="plugin1" type="application/x-test" width="200" height="200"></embed>
<embed id="plugin2" type="application/x-test" width="200" height="200"></embed>

Просмотреть файл

@ -3,9 +3,7 @@
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<window title="NPAPI Set Undefined Value Test"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>NPAPI Set Undefined Value Test</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript" src="utils.js"></script>

Просмотреть файл

@ -3,9 +3,7 @@
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<window title="Basic Plugin Tests"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>NPN_ConvertPoint Tests</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript" src="utils.js"></script>

Просмотреть файл

@ -3,9 +3,7 @@
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<window title="Basic Plugin Tests"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Plugin Crash Notification Test</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript" src="utils.js"></script>

Просмотреть файл

@ -3,9 +3,7 @@
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<window title="Basic Plugin Tests"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Plugin Crash Notification Test</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript" src="utils.js"></script>

Просмотреть файл

@ -3,9 +3,7 @@
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<window title="Basic Plugin Tests"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Plugin Crash Notification Test</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript"

Просмотреть файл

@ -3,9 +3,7 @@
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<window title="Basic Plugin Tests"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Plugin Hang Submission Test</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript"

Просмотреть файл

@ -3,9 +3,7 @@
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<window title="Basic Plugin Tests"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<title>Basic Plugin Tests</title>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript" src="utils.js"></script>

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше