mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to inbound on a CLOSED TREE.
This commit is contained in:
commit
f40fe712d0
@ -36,10 +36,7 @@ let CustomizationHandler = {
|
||||
let cmd = document.getElementById("cmd_CustomizeToolbars");
|
||||
cmd.setAttribute("disabled", "true");
|
||||
|
||||
let splitter = document.getElementById("urlbar-search-splitter");
|
||||
if (splitter) {
|
||||
splitter.parentNode.removeChild(splitter);
|
||||
}
|
||||
UpdateUrlbarSearchSplitterState();
|
||||
|
||||
CombinedStopReload.uninit();
|
||||
CombinedBackForward.uninit();
|
||||
|
@ -980,8 +980,15 @@ let BookmarkingUI = {
|
||||
if (widget.overflowed)
|
||||
return widget.anchor;
|
||||
|
||||
return document.getAnonymousElementByAttribute(this.star, "class",
|
||||
"toolbarbutton-icon");
|
||||
let star = this.star;
|
||||
return star ? document.getAnonymousElementByAttribute(star, "class",
|
||||
"toolbarbutton-icon")
|
||||
: null;
|
||||
},
|
||||
|
||||
get notifier() {
|
||||
delete this.notifier;
|
||||
return this.notifier = document.getElementById("bookmarked-notification-anchor");
|
||||
},
|
||||
|
||||
get broadcaster() {
|
||||
@ -1087,7 +1094,7 @@ let BookmarkingUI = {
|
||||
* Handles star styling based on page proxy state changes.
|
||||
*/
|
||||
onPageProxyStateChanged: function BUI_onPageProxyStateChanged(aState) {
|
||||
if (!this._shouldUpdateStarState()) {
|
||||
if (!this._shouldUpdateStarState() || !this.star) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1158,6 +1165,7 @@ let BookmarkingUI = {
|
||||
},
|
||||
|
||||
_hasBookmarksObserver: false,
|
||||
_itemIds: [],
|
||||
uninit: function BUI_uninit() {
|
||||
this._updateBookmarkPageMenuItem(true);
|
||||
CustomizableUI.removeListener(this);
|
||||
@ -1232,7 +1240,7 @@ let BookmarkingUI = {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._itemIds && this._itemIds.length > 0) {
|
||||
if (this._itemIds.length > 0) {
|
||||
this.button.setAttribute("starred", "true");
|
||||
this.button.setAttribute("buttontooltiptext", this._starredTooltip);
|
||||
}
|
||||
@ -1247,7 +1255,7 @@ let BookmarkingUI = {
|
||||
* to the default (Bookmark This Page) for OS X.
|
||||
*/
|
||||
_updateBookmarkPageMenuItem: function BUI__updateBookmarkPageMenuItem(forceReset) {
|
||||
let isStarred = !forceReset && this._itemIds && this._itemIds.length > 0;
|
||||
let isStarred = !forceReset && this._itemIds.length > 0;
|
||||
let label = isStarred ? "editlabel" : "bookmarklabel";
|
||||
this.broadcaster.setAttribute("label", this.broadcaster.getAttribute(label));
|
||||
},
|
||||
@ -1257,6 +1265,42 @@ let BookmarkingUI = {
|
||||
PlacesCommandHook.updateBookmarkAllTabsCommand();
|
||||
},
|
||||
|
||||
_showBookmarkedNotification: function BUI_showBookmarkedNotification() {
|
||||
|
||||
if (this._notificationTimeout) {
|
||||
clearTimeout(this._notificationTimeout);
|
||||
}
|
||||
|
||||
if (this.notifier.style.transform == '') {
|
||||
let buttonRect = this.button.getBoundingClientRect();
|
||||
let notifierRect = this.notifier.getBoundingClientRect();
|
||||
let topDiff = buttonRect.top - notifierRect.top;
|
||||
let leftDiff = buttonRect.left - notifierRect.left;
|
||||
let heightDiff = buttonRect.height - notifierRect.height;
|
||||
let widthDiff = buttonRect.width - notifierRect.width;
|
||||
let translateX = (leftDiff + .5 * widthDiff) + "px";
|
||||
let translateY = (topDiff + .5 * heightDiff) + "px";
|
||||
this.notifier.style.transform = "translate(" + translateX + ", " + translateY + ")";
|
||||
}
|
||||
|
||||
let isInBookmarksToolbar = this.button.classList.contains("bookmark-item");
|
||||
if (isInBookmarksToolbar)
|
||||
this.notifier.setAttribute("in-bookmarks-toolbar", true);
|
||||
|
||||
let isInOverflowPanel = this.button.classList.contains("overflowedItem");
|
||||
if (!isInOverflowPanel) {
|
||||
this.notifier.setAttribute("notification", "finish");
|
||||
this.button.setAttribute("notification", "finish");
|
||||
}
|
||||
|
||||
this._notificationTimeout = setTimeout( () => {
|
||||
this.notifier.removeAttribute("notification");
|
||||
this.notifier.removeAttribute("in-bookmarks-toolbar");
|
||||
this.button.removeAttribute("notification");
|
||||
this.notifier.style.transform = '';
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
onCommand: function BUI_onCommand(aEvent) {
|
||||
if (aEvent.target != aEvent.currentTarget) {
|
||||
return;
|
||||
@ -1265,6 +1309,8 @@ let BookmarkingUI = {
|
||||
// Handle special case when the button is in the panel.
|
||||
let widget = CustomizableUI.getWidget("bookmarks-menu-button")
|
||||
.forWindow(window);
|
||||
let isBookmarked = this._itemIds.length > 0;
|
||||
|
||||
if (this._currentAreaType == CustomizableUI.TYPE_MENU_PANEL) {
|
||||
let view = document.getElementById("PanelUI-bookmarks");
|
||||
view.addEventListener("ViewShowing", this);
|
||||
@ -1277,7 +1323,7 @@ let BookmarkingUI = {
|
||||
if (widget.overflowed) {
|
||||
// Allow to close the panel if the page is already bookmarked, cause
|
||||
// we are going to open the edit bookmark panel.
|
||||
if (this._itemIds.length > 0)
|
||||
if (isBookmarked)
|
||||
widget.node.removeAttribute("closemenu");
|
||||
else
|
||||
widget.node.setAttribute("closemenu", "none");
|
||||
@ -1285,7 +1331,9 @@ let BookmarkingUI = {
|
||||
|
||||
// Ignore clicks on the star if we are updating its state.
|
||||
if (!this._pendingStmt) {
|
||||
PlacesCommandHook.bookmarkCurrentPage(this._itemIds.length > 0);
|
||||
if (!isBookmarked)
|
||||
this._showBookmarkedNotification();
|
||||
PlacesCommandHook.bookmarkCurrentPage(isBookmarked);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -2123,6 +2123,13 @@ function UpdateUrlbarSearchSplitterState()
|
||||
var urlbar = document.getElementById("urlbar-container");
|
||||
var searchbar = document.getElementById("search-container");
|
||||
|
||||
if (document.documentElement.getAttribute("customizing") == "true") {
|
||||
if (splitter) {
|
||||
splitter.remove();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If the splitter is already in the right place, we don't need to do anything:
|
||||
if (splitter &&
|
||||
((splitter.nextSibling == searchbar && splitter.previousSibling == urlbar) ||
|
||||
|
@ -462,6 +462,12 @@
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
<hbox id="bookmarked-notification-container" mousethrough="always">
|
||||
<vbox id="bookmarked-notification-anchor">
|
||||
<vbox id="bookmarked-notification"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
<tooltip id="dynamic-shortcut-tooltip"
|
||||
onpopupshowing="UpdateDynamicShortcutTooltipText(this.triggerNode)">
|
||||
<label id="dynamic-shortcut-tooltip-label"/>
|
||||
|
@ -37,6 +37,7 @@
|
||||
<toolbarbutton id="PanelUI-quit"
|
||||
#ifdef XP_WIN
|
||||
label="&quitApplicationCmdWin.label;"
|
||||
tooltiptext="&quitApplicationCmdWin.tooltip;"
|
||||
#else
|
||||
#ifdef XP_MACOSX
|
||||
label="&quitApplicationCmdMac.label;"
|
||||
|
@ -420,12 +420,11 @@ const PanelUI = {
|
||||
#ifndef XP_WIN
|
||||
#ifdef XP_MACOSX
|
||||
let tooltipId = "quit-button.tooltiptext.mac";
|
||||
#else
|
||||
let tooltipId = "quit-button.tooltiptext.linux2";
|
||||
#endif
|
||||
let brands = Services.strings.createBundle("chrome://branding/locale/brand.properties");
|
||||
let stringArgs = [brands.GetStringFromName("brandShortName")];
|
||||
#else
|
||||
let tooltipId = "quit-button.tooltiptext.linux";
|
||||
let stringArgs = [];
|
||||
#endif
|
||||
|
||||
let key = document.getElementById("key_quitApplication");
|
||||
stringArgs.push(ShortcutUtils.prettifyShortcut(key));
|
||||
|
@ -703,6 +703,8 @@ let CustomizableUIInternal = {
|
||||
// We remove location attributes here to make sure they're gone too when a
|
||||
// widget is removed from a toolbar to the palette. See bug 930950.
|
||||
this.removeLocationAttributes(widgetNode);
|
||||
// We also need to remove the panel context menu if it's there:
|
||||
this.ensureButtonContextMenu(widgetNode);
|
||||
widgetNode.removeAttribute("wrap");
|
||||
if (gPalette.has(aWidgetId) || this.isSpecialWidget(aWidgetId)) {
|
||||
container.removeChild(widgetNode);
|
||||
@ -1139,8 +1141,6 @@ let CustomizableUIInternal = {
|
||||
LOG("handleWidgetCommand");
|
||||
|
||||
if (aWidget.type == "button") {
|
||||
this.maybeAutoHidePanel(aEvent);
|
||||
|
||||
if (aWidget.onCommand) {
|
||||
try {
|
||||
aWidget.onCommand.call(null, aEvent);
|
||||
@ -1162,10 +1162,6 @@ let CustomizableUIInternal = {
|
||||
|
||||
handleWidgetClick: function(aWidget, aNode, aEvent) {
|
||||
LOG("handleWidgetClick");
|
||||
if (aWidget.type == "button") {
|
||||
this.maybeAutoHidePanel(aEvent);
|
||||
}
|
||||
|
||||
if (aWidget.onClick) {
|
||||
try {
|
||||
aWidget.onClick.call(null, aEvent);
|
||||
@ -1322,7 +1318,7 @@ let CustomizableUIInternal = {
|
||||
let target = aEvent.originalTarget;
|
||||
let closemenu = "auto";
|
||||
let widgetType = "button";
|
||||
while (target.localName != "panel") {
|
||||
while (target.parentNode && target.localName != "panel") {
|
||||
closemenu = target.getAttribute("closemenu");
|
||||
widgetType = target.getAttribute("widget-type");
|
||||
if (closemenu == "none" || closemenu == "single" ||
|
||||
|
@ -19,6 +19,9 @@ const kToolbarVisibilityBtn = "customization-toolbar-visibility-button";
|
||||
const kDrawInTitlebarPref = "browser.tabs.drawInTitlebar";
|
||||
const kMaxTransitionDurationMs = 2000;
|
||||
|
||||
const kPanelItemContextMenu = "customizationPanelItemContextMenu";
|
||||
const kPaletteItemContextMenu = "customizationPaletteItemContextMenu";
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource:///modules/CustomizableUI.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
@ -35,6 +38,8 @@ let gModuleName = "[CustomizeMode]";
|
||||
|
||||
let gDisableAnimation = null;
|
||||
|
||||
let gDraggingInToolbars;
|
||||
|
||||
function CustomizeMode(aWindow) {
|
||||
if (gDisableAnimation === null) {
|
||||
gDisableAnimation = Services.prefs.getPrefType(kPrefCustomizationAnimation) == Ci.nsIPrefBranch.PREF_BOOL &&
|
||||
@ -655,9 +660,6 @@ CustomizeMode.prototype = {
|
||||
wrapper.setAttribute("flex", aNode.getAttribute("flex"));
|
||||
}
|
||||
|
||||
|
||||
const kPanelItemContextMenu = "customizationPanelItemContextMenu";
|
||||
const kPaletteItemContextMenu = "customizationPaletteItemContextMenu";
|
||||
let contextMenuAttrName = aNode.getAttribute("context") ? "context" :
|
||||
aNode.getAttribute("contextmenu") ? "contextmenu" : "";
|
||||
let currentContextMenu = aNode.getAttribute(contextMenuAttrName);
|
||||
@ -704,6 +706,8 @@ CustomizeMode.prototype = {
|
||||
aWrapper.removeEventListener("mousedown", this);
|
||||
aWrapper.removeEventListener("mouseup", this);
|
||||
|
||||
let place = aWrapper.getAttribute("place");
|
||||
|
||||
let toolbarItem = aWrapper.firstChild;
|
||||
if (!toolbarItem) {
|
||||
ERROR("no toolbarItem child for " + aWrapper.tagName + "#" + aWrapper.id);
|
||||
@ -736,6 +740,8 @@ CustomizeMode.prototype = {
|
||||
toolbarItem.setAttribute(contextAttrName, wrappedContext);
|
||||
toolbarItem.removeAttribute("wrapped-contextAttrName");
|
||||
toolbarItem.removeAttribute("wrapped-context");
|
||||
} else if (place == "panel") {
|
||||
toolbarItem.setAttribute("context", kPanelItemContextMenu);
|
||||
}
|
||||
|
||||
if (aWrapper.parentNode) {
|
||||
@ -1048,6 +1054,8 @@ CustomizeMode.prototype = {
|
||||
this._dragOffset = {x: aEvent.clientX - itemCenter.x,
|
||||
y: aEvent.clientY - itemCenter.y};
|
||||
|
||||
gDraggingInToolbars = new Set();
|
||||
|
||||
// Hack needed so that the dragimage will still show the
|
||||
// item as it appeared before it was hidden.
|
||||
this._initializeDragAfterMove = function() {
|
||||
@ -1058,8 +1066,10 @@ CustomizeMode.prototype = {
|
||||
item.hidden = true;
|
||||
this._showPanelCustomizationPlaceholders();
|
||||
DragPositionManager.start(this.window);
|
||||
if (!isInToolbar && item.nextSibling) {
|
||||
this._setDragActive(item.nextSibling, "before", draggedItem.id, false);
|
||||
if (item.nextSibling) {
|
||||
this._setDragActive(item.nextSibling, "before", draggedItem.id, isInToolbar);
|
||||
} else if (isInToolbar && item.previousSibling) {
|
||||
this._setDragActive(item.previousSibling, "after", draggedItem.id, isInToolbar);
|
||||
}
|
||||
}
|
||||
this._initializeDragAfterMove = null;
|
||||
@ -1408,7 +1418,7 @@ CustomizeMode.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aItem.hasAttribute("dragover") != aValue) {
|
||||
if (aItem.getAttribute("dragover") != aValue) {
|
||||
aItem.setAttribute("dragover", aValue);
|
||||
|
||||
let window = aItem.ownerDocument.defaultView;
|
||||
@ -1416,6 +1426,14 @@ CustomizeMode.prototype = {
|
||||
if (!aInToolbar) {
|
||||
this._setGridDragActive(aItem, draggedItem, aValue);
|
||||
} else {
|
||||
let targetArea = this._getCustomizableParent(aItem);
|
||||
let makeSpaceImmediately = false;
|
||||
if (!gDraggingInToolbars.has(targetArea.id)) {
|
||||
gDraggingInToolbars.add(targetArea.id);
|
||||
let draggedWrapper = this.document.getElementById("wrapper-" + aDraggedItemId);
|
||||
let originArea = this._getCustomizableParent(draggedWrapper);
|
||||
makeSpaceImmediately = originArea == targetArea;
|
||||
}
|
||||
// Calculate width of the item when it'd be dropped in this position
|
||||
let width = this._getDragItemSize(aItem, draggedItem).width;
|
||||
let direction = window.getComputedStyle(aItem).direction;
|
||||
@ -1429,8 +1447,16 @@ CustomizeMode.prototype = {
|
||||
prop = "borderRightWidth";
|
||||
otherProp = "border-left-width";
|
||||
}
|
||||
if (makeSpaceImmediately) {
|
||||
aItem.setAttribute("notransition", "true");
|
||||
}
|
||||
aItem.style[prop] = width + 'px';
|
||||
aItem.style.removeProperty(otherProp);
|
||||
if (makeSpaceImmediately) {
|
||||
// Force a layout flush:
|
||||
aItem.getBoundingClientRect();
|
||||
aItem.removeAttribute("notransition");
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -1441,12 +1467,21 @@ CustomizeMode.prototype = {
|
||||
}
|
||||
let isToolbar = CustomizableUI.getAreaType(currentArea.id) == "toolbar";
|
||||
if (isToolbar) {
|
||||
if (aNoTransition) {
|
||||
aItem.setAttribute("notransition", "true");
|
||||
}
|
||||
aItem.removeAttribute("dragover");
|
||||
// Remove both property values in the case that the end padding
|
||||
// had been set.
|
||||
aItem.style.removeProperty("border-left-width");
|
||||
aItem.style.removeProperty("border-right-width");
|
||||
if (aNoTransition) {
|
||||
// Force a layout flush:
|
||||
aItem.getBoundingClientRect();
|
||||
aItem.removeAttribute("notransition");
|
||||
}
|
||||
} else {
|
||||
aItem.removeAttribute("dragover");
|
||||
if (aNextItem) {
|
||||
let nextArea = this._getCustomizableParent(aNextItem);
|
||||
if (nextArea == currentArea) {
|
||||
|
@ -274,6 +274,39 @@ add_task(function() {
|
||||
yield resetCustomization();
|
||||
});
|
||||
|
||||
// Bug 947586 - After customization, panel items show wrong context menu options
|
||||
add_task(function() {
|
||||
yield startCustomizing();
|
||||
yield endCustomizing();
|
||||
|
||||
yield PanelUI.show();
|
||||
|
||||
let contextMenu = document.getElementById("customizationPanelItemContextMenu");
|
||||
let shownContextPromise = contextMenuShown(contextMenu);
|
||||
let newWindowButton = document.getElementById("new-window-button");
|
||||
ok(newWindowButton, "new-window-button was found");
|
||||
EventUtils.synthesizeMouse(newWindowButton, 2, 2, {type: "contextmenu", button: 2});
|
||||
yield shownContextPromise;
|
||||
|
||||
is(PanelUI.panel.state, "open", "The PanelUI should still be open.");
|
||||
|
||||
let expectedEntries = [
|
||||
[".customize-context-moveToToolbar", true],
|
||||
[".customize-context-removeFromPanel", true],
|
||||
["---"],
|
||||
[".viewCustomizeToolbar", true]
|
||||
];
|
||||
checkContextMenu(contextMenu, expectedEntries);
|
||||
|
||||
let hiddenContextPromise = contextMenuHidden(contextMenu);
|
||||
contextMenu.hidePopup();
|
||||
yield hiddenContextPromise;
|
||||
|
||||
let hiddenPromise = promisePanelHidden(window);
|
||||
PanelUI.hide();
|
||||
yield hiddenPromise;
|
||||
});
|
||||
|
||||
function contextMenuShown(aContextMenu) {
|
||||
let deferred = Promise.defer();
|
||||
let win = aContextMenu.ownerDocument.defaultView;
|
||||
|
@ -28,6 +28,7 @@ this.EXPORTED_SYMBOLS = ["SessionFile"];
|
||||
const Cu = Components.utils;
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
@ -35,6 +36,8 @@ Cu.import("resource://gre/modules/osfile.jsm");
|
||||
Cu.import("resource://gre/modules/osfile/_PromiseWorker.jsm", this);
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
Cu.import("resource://gre/modules/AsyncShutdown.jsm");
|
||||
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||
Cu.import("resource://gre/modules/FileUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "console",
|
||||
"resource://gre/modules/devtools/Console.jsm");
|
||||
@ -125,10 +128,57 @@ let SessionFileInternal = {
|
||||
_isClosed: false,
|
||||
|
||||
read: function () {
|
||||
return SessionWorker.post("read").then(msg => {
|
||||
this._recordTelemetry(msg.telemetry);
|
||||
return msg.ok;
|
||||
// We must initialize the worker during startup so it will be ready to
|
||||
// perform the final write. If shutdown happens soon after startup and
|
||||
// the worker has not started yet we may not write.
|
||||
// See Bug 964531.
|
||||
SessionWorker.post("init");
|
||||
|
||||
return Task.spawn(function () {
|
||||
let data = null;
|
||||
for (let filename of [this.path, this.backupPath]) {
|
||||
try {
|
||||
data = yield this._readSessionFile(filename);
|
||||
break;
|
||||
} catch (ex if ex == Cr.NS_ERROR_FILE_NOT_FOUND) {
|
||||
// Ignore exceptions about non-existent files.
|
||||
}
|
||||
}
|
||||
|
||||
throw new Task.Result(data || "");
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Read the session file asynchronously.
|
||||
*
|
||||
* @param filename
|
||||
* string The name of the session file.
|
||||
* @returns {promise}
|
||||
*/
|
||||
_readSessionFile: function (path) {
|
||||
let deferred = Promise.defer();
|
||||
let file = FileUtils.File(path);
|
||||
let durationMs = Date.now();
|
||||
|
||||
NetUtil.asyncFetch(file, function(inputStream, status) {
|
||||
if (!Components.isSuccessCode(status)) {
|
||||
deferred.reject(status);
|
||||
return;
|
||||
}
|
||||
|
||||
let byteLength = inputStream.available();
|
||||
let data = NetUtil.readInputStreamToString(inputStream, byteLength,
|
||||
{ charset: "UTF-8" });
|
||||
durationMs = Date.now() - durationMs;
|
||||
|
||||
deferred.resolve(data);
|
||||
|
||||
Telemetry.getHistogramById("FX_SESSION_RESTORE_READ_FILE_MS").add(durationMs);
|
||||
Telemetry.getHistogramById("FX_SESSION_RESTORE_FILE_SIZE_BYTES").add(byteLength);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
gatherTelemetry: function(aStateString) {
|
||||
|
@ -67,27 +67,10 @@ let Agent = {
|
||||
backupPath: OS.Path.join(OS.Constants.Path.profileDir, "sessionstore.bak"),
|
||||
|
||||
/**
|
||||
* Read the session from disk.
|
||||
* In case sessionstore.js does not exist, attempt to read sessionstore.bak.
|
||||
* NO-OP to start the worker.
|
||||
*/
|
||||
read: function () {
|
||||
for (let path of [this.path, this.backupPath]) {
|
||||
try {
|
||||
let durationMs = Date.now();
|
||||
let bytes = File.read(path);
|
||||
durationMs = Date.now() - durationMs;
|
||||
|
||||
return {
|
||||
result: Decoder.decode(bytes),
|
||||
telemetry: {FX_SESSION_RESTORE_READ_FILE_MS: durationMs,
|
||||
FX_SESSION_RESTORE_FILE_SIZE_BYTES: bytes.byteLength}
|
||||
};
|
||||
} catch (ex if isNoSuchFileEx(ex)) {
|
||||
// Ignore exceptions about non-existent files.
|
||||
}
|
||||
}
|
||||
// No sessionstore data files found. Return an empty string.
|
||||
return {result: ""};
|
||||
init: function () {
|
||||
return {result: true};
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -35,6 +35,9 @@
|
||||
<!ENTITY helpFeedbackPage.label "Submit Feedback…">
|
||||
<!ENTITY helpFeedbackPage.accesskey "S">
|
||||
|
||||
<!ENTITY helpShowTour.label "&brandShortName; Tour">
|
||||
<!ENTITY helpShowTour.accesskey "o">
|
||||
|
||||
<!ENTITY preferencesCmdMac.label "Preferences…">
|
||||
<!ENTITY preferencesCmdMac.commandkey ",">
|
||||
|
||||
|
@ -570,6 +570,7 @@ you can use these alternative items. Otherwise, their values should be empty. -
|
||||
|
||||
<!ENTITY quitApplicationCmdWin.label "Exit">
|
||||
<!ENTITY quitApplicationCmdWin.accesskey "x">
|
||||
<!ENTITY quitApplicationCmdWin.tooltip "Exit &brandShortName;">
|
||||
<!ENTITY goBackCmd.commandKey "[">
|
||||
<!ENTITY goForwardCmd.commandKey "]">
|
||||
<!ENTITY quitApplicationCmd.label "Quit">
|
||||
|
@ -91,8 +91,9 @@ email-link-button.label = Email Link
|
||||
# \u2026, or use "..." if \u2026 doesn't suit traditions in your locale.
|
||||
email-link-button.tooltiptext2 = Email Link…
|
||||
|
||||
# LOCALIZATION NOTE(quit-button.tooltiptext.linux): %S is the keyboard shortcut
|
||||
quit-button.tooltiptext.linux = Quit (%S)
|
||||
# LOCALIZATION NOTE(quit-button.tooltiptext.linux2): %1$S is the brand name (e.g. Firefox),
|
||||
# %2$S is the keyboard shortcut
|
||||
quit-button.tooltiptext.linux2 = Quit %1$S (%2$S)
|
||||
# LOCALIZATION NOTE(quit-button.tooltiptext.mac): %1$S is the brand name (e.g. Firefox),
|
||||
# %2$S is the keyboard shortcut
|
||||
quit-button.tooltiptext.mac = Quit %1$S (%2$S)
|
||||
|
@ -1260,7 +1260,7 @@ function Tab(aURI, aParams, aOwner) {
|
||||
if ("private" in aParams) {
|
||||
this._private = aParams.private;
|
||||
} else if (aOwner) {
|
||||
this._private = aOwner.private;
|
||||
this._private = aOwner._private;
|
||||
}
|
||||
|
||||
this.owner = aOwner || null;
|
||||
|
@ -167,6 +167,7 @@ var ContextMenuUI = {
|
||||
|
||||
for (let command of Array.slice(this.commands.childNodes)) {
|
||||
command.hidden = true;
|
||||
command.selected = false;
|
||||
}
|
||||
|
||||
let optionsAvailable = false;
|
||||
|
@ -874,6 +874,43 @@ gTests.push({
|
||||
}
|
||||
});
|
||||
|
||||
gTests.push({
|
||||
desc: "Bug 963067 - 'Cut' in the cut, copy, paste menu is always active " +
|
||||
"after a browser launch.",
|
||||
run: function test() {
|
||||
info(chromeRoot + "browser_context_menu_tests_02.html");
|
||||
yield addTab(chromeRoot + "browser_context_menu_tests_02.html");
|
||||
|
||||
purgeEventQueue();
|
||||
emptyClipboard();
|
||||
|
||||
ContextUI.dismiss();
|
||||
yield waitForCondition(() => !ContextUI.navbarVisible);
|
||||
|
||||
let tabWindow = Browser.selectedTab.browser.contentWindow;
|
||||
let input = tabWindow.document.getElementById("text3-input");
|
||||
let cutMenuItem = document.getElementById("context-cut");
|
||||
|
||||
input.select();
|
||||
|
||||
// Emulate RichListBox's behavior and set first item selected by default.
|
||||
cutMenuItem.selected = true;
|
||||
|
||||
let promise = waitForEvent(document, "popupshown");
|
||||
sendContextMenuClickToElement(tabWindow, input);
|
||||
yield promise;
|
||||
|
||||
ok(!cutMenuItem.hidden && !cutMenuItem.selected,
|
||||
"Cut menu item is visible and not selected.");
|
||||
|
||||
promise = waitForEvent(document, "popuphidden");
|
||||
ContextMenuUI.hide();
|
||||
yield promise;
|
||||
|
||||
Browser.closeTab(Browser.selectedTab, { forceClose: true });
|
||||
}
|
||||
});
|
||||
|
||||
function test() {
|
||||
setDevPixelEqualToPx();
|
||||
runTests();
|
||||
|
@ -16,12 +16,22 @@ gTests.push({
|
||||
is(tab.isPrivate, false, "Tabs are not private by default");
|
||||
is(tab.chromeTab.hasAttribute("private"), false,
|
||||
"non-private tab has no private attribute");
|
||||
|
||||
let child = Browser.addTab("about:mozilla", false, tab);
|
||||
is(child.isPrivate, false, "Child of a non-private tab is not private");
|
||||
|
||||
Browser.closeTab(child, { forceClose: true });
|
||||
Browser.closeTab(tab, { forceClose: true });
|
||||
|
||||
tab = Browser.addTab("about:mozilla", false, null, { private: true });
|
||||
is(tab.isPrivate, true, "Create a private tab");
|
||||
is(tab.chromeTab.getAttribute("private"), "true",
|
||||
"private tab has private attribute");
|
||||
|
||||
child = Browser.addTab("about:mozilla", false, tab);
|
||||
is(child.isPrivate, true, "Child of a private tab is private");
|
||||
|
||||
Browser.closeTab(child, { forceClose: true });
|
||||
Browser.closeTab(tab, { forceClose: true });
|
||||
}
|
||||
});
|
||||
|
@ -117,6 +117,62 @@ toolbarpaletteitem[place="palette"] > #personal-bookmarks > #bookmarks-toolbar-p
|
||||
list-style-image: url("chrome://browser/skin/places/bookmarksToolbar-menuPanel.png") !important;
|
||||
}
|
||||
|
||||
/* ----- BOOKMARK STAR ANIMATION ----- */
|
||||
|
||||
@keyframes animation-bookmarkAdded {
|
||||
from { transform: rotate(0deg) translateX(-20px) rotate(0deg) scale(1); opacity: 0; }
|
||||
60% { transform: rotate(180deg) translateX(-20px) rotate(-180deg) scale(2.2); opacity: 1; }
|
||||
80% { opacity: 1; }
|
||||
to { transform: rotate(180deg) translateX(-20px) rotate(-180deg) scale(1); opacity: 0; }
|
||||
}
|
||||
|
||||
@keyframes animation-bookmarkAddedToBookmarksBar {
|
||||
from { transform: rotate(0deg) translateX(-12px) rotate(0deg) scale(1); opacity: 0; }
|
||||
60% { transform: rotate(180deg) translateX(-12px) rotate(-180deg) scale(2.2); opacity: 1; }
|
||||
80% { opacity: 1; }
|
||||
to { transform: rotate(180deg) translateX(-12px) rotate(-180deg) scale(1); opacity: 0; }
|
||||
}
|
||||
|
||||
@keyframes animation-bookmarkPulse {
|
||||
from { transform: scale(1); }
|
||||
50% { transform: scale(1.3); }
|
||||
to { transform: scale(1); }
|
||||
}
|
||||
|
||||
#bookmarked-notification-container {
|
||||
min-height: 1px;
|
||||
min-width: 1px;
|
||||
height: 1px;
|
||||
margin-bottom: -1px;
|
||||
z-index: 5;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#bookmarked-notification {
|
||||
background-size: 16px;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#bookmarked-notification-anchor[notification="finish"] > #bookmarked-notification {
|
||||
background-image: url("chrome://browser/skin/places/bookmarks-notification-finish.png");
|
||||
animation: animation-bookmarkAdded 800ms;
|
||||
animation-timing-function: ease ease ease linear;
|
||||
}
|
||||
|
||||
#bookmarked-notification-anchor[notification="finish"][in-bookmarks-toolbar=true] > #bookmarked-notification {
|
||||
animation: animation-bookmarkAddedToBookmarksBar 800ms;
|
||||
}
|
||||
|
||||
#bookmarks-menu-button[notification="finish"] > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon {
|
||||
animation: animation-bookmarkPulse 300ms;
|
||||
animation-delay: 600ms;
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
|
||||
/* Bookmark menus */
|
||||
menu.bookmark-item,
|
||||
menuitem.bookmark-item {
|
||||
|
@ -95,6 +95,7 @@ browser.jar:
|
||||
skin/classic/browser/newtab/controls.png (newtab/controls.png)
|
||||
skin/classic/browser/places/bookmarksMenu.png (places/bookmarksMenu.png)
|
||||
skin/classic/browser/places/bookmarksToolbar.png (places/bookmarksToolbar.png)
|
||||
skin/classic/browser/places/bookmarks-notification-finish.png (places/bookmarks-notification-finish.png)
|
||||
skin/classic/browser/places/bookmarksToolbar-menuPanel.png (places/bookmarksToolbar-menuPanel.png)
|
||||
skin/classic/browser/places/calendar.png (places/calendar.png)
|
||||
* skin/classic/browser/places/editBookmarkOverlay.css (places/editBookmarkOverlay.css)
|
||||
|
BIN
browser/themes/linux/places/bookmarks-notification-finish.png
Normal file
BIN
browser/themes/linux/places/bookmarks-notification-finish.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
@ -361,6 +361,68 @@ toolbarpaletteitem[place="palette"] > #personal-bookmarks > #bookmarks-toolbar-p
|
||||
}
|
||||
}
|
||||
|
||||
/* ----- BOOKMARK STAR ANIMATION ----- */
|
||||
|
||||
@keyframes animation-bookmarkAdded {
|
||||
from { transform: rotate(0deg) translateX(-20px) rotate(0deg) scale(1); opacity: 0; }
|
||||
60% { transform: rotate(180deg) translateX(-20px) rotate(-180deg) scale(2.2); opacity: 1; }
|
||||
80% { opacity: 1; }
|
||||
to { transform: rotate(180deg) translateX(-20px) rotate(-180deg) scale(1); opacity: 0; }
|
||||
}
|
||||
|
||||
@keyframes animation-bookmarkAddedToBookmarksBar {
|
||||
from { transform: rotate(0deg) translateX(-12px) rotate(0deg) scale(1); opacity: 0; }
|
||||
60% { transform: rotate(180deg) translateX(-12px) rotate(-180deg) scale(2.2); opacity: 1; }
|
||||
80% { opacity: 1; }
|
||||
to { transform: rotate(180deg) translateX(-12px) rotate(-180deg) scale(1); opacity: 0; }
|
||||
}
|
||||
|
||||
@keyframes animation-bookmarkPulse {
|
||||
from { transform: scale(1); }
|
||||
50% { transform: scale(1.3); }
|
||||
to { transform: scale(1); }
|
||||
}
|
||||
|
||||
#bookmarked-notification-container {
|
||||
min-height: 1px;
|
||||
min-width: 1px;
|
||||
height: 1px;
|
||||
margin-bottom: -1px;
|
||||
z-index: 5;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#bookmarked-notification {
|
||||
background-size: 16px;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#bookmarked-notification-anchor[notification="finish"] > #bookmarked-notification {
|
||||
background-image: url("chrome://browser/skin/places/bookmarks-notification-finish.png");
|
||||
animation: animation-bookmarkAdded 800ms;
|
||||
animation-timing-function: ease ease ease linear;
|
||||
}
|
||||
|
||||
#bookmarked-notification-anchor[notification="finish"][in-bookmarks-toolbar=true] > #bookmarked-notification {
|
||||
animation: animation-bookmarkAddedToBookmarksBar 800ms;
|
||||
}
|
||||
|
||||
@media (min-resolution: 2dppx) {
|
||||
#bookmarked-notification-anchor[notification="finish"] > #bookmarked-notification {
|
||||
background-image: url("chrome://browser/skin/places/bookmarks-notification-finish@2x.png");
|
||||
}
|
||||
}
|
||||
|
||||
#bookmarks-menu-button[notification="finish"] > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon {
|
||||
animation: animation-bookmarkPulse 300ms;
|
||||
animation-delay: 600ms;
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
|
||||
/* ----- BOOKMARK MENUS ----- */
|
||||
|
||||
.bookmark-item > .menu-iconic-left > .menu-iconic-icon {
|
||||
|
@ -157,6 +157,8 @@ browser.jar:
|
||||
skin/classic/browser/places/bookmarksMenu.png (places/bookmarksMenu.png)
|
||||
skin/classic/browser/places/bookmarksToolbar.png (places/bookmarksToolbar.png)
|
||||
skin/classic/browser/places/bookmarksToolbar@2x.png (places/bookmarksToolbar@2x.png)
|
||||
skin/classic/browser/places/bookmarks-notification-finish.png (places/bookmarks-notification-finish.png)
|
||||
skin/classic/browser/places/bookmarks-notification-finish@2x.png (places/bookmarks-notification-finish@2x.png)
|
||||
skin/classic/browser/places/bookmarksToolbar-menuPanel.png (places/bookmarksToolbar-menuPanel.png)
|
||||
skin/classic/browser/places/bookmarksToolbar-menuPanel@2x.png (places/bookmarksToolbar-menuPanel@2x.png)
|
||||
skin/classic/browser/places/history.png (places/history.png)
|
||||
|
BIN
browser/themes/osx/places/bookmarks-notification-finish.png
Normal file
BIN
browser/themes/osx/places/bookmarks-notification-finish.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
BIN
browser/themes/osx/places/bookmarks-notification-finish@2x.png
Normal file
BIN
browser/themes/osx/places/bookmarks-notification-finish@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.3 KiB |
@ -51,6 +51,7 @@
|
||||
}
|
||||
|
||||
#UITourTooltipClose {
|
||||
visibility: hidden; /* XXX Temporarily disabled by bug 966913 */
|
||||
-moz-appearance: none;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
|
@ -117,7 +117,7 @@
|
||||
background-attachment: scroll, scroll, fixed, fixed, scroll;
|
||||
}
|
||||
|
||||
toolbarpaletteitem {
|
||||
toolbarpaletteitem[place="toolbar"] {
|
||||
transition: border-width 250ms ease-in-out;
|
||||
}
|
||||
|
||||
@ -132,6 +132,7 @@ toolbarpaletteitem[place="panel"] {
|
||||
}
|
||||
|
||||
toolbarpaletteitem[notransition].panel-customization-placeholder,
|
||||
toolbarpaletteitem[notransition][place="toolbar"],
|
||||
toolbarpaletteitem[notransition][place="palette"],
|
||||
toolbarpaletteitem[notransition][place="panel"] {
|
||||
transition: none;
|
||||
|
@ -318,6 +318,51 @@ toolbarpaletteitem[place="palette"] > #personal-bookmarks > #bookmarks-toolbar-p
|
||||
list-style-image: url("chrome://browser/skin/places/bookmarksToolbar-menuPanel.png") !important;
|
||||
}
|
||||
|
||||
/* ----- BOOKMARK STAR ANIMATION ----- */
|
||||
|
||||
@keyframes animation-bookmarkAdded {
|
||||
from { transform: rotate(0deg) translateX(-16px) rotate(0deg) scale(1); opacity: 0; }
|
||||
60% { transform: rotate(180deg) translateX(-16px) rotate(-180deg) scale(2.2); opacity: 1; }
|
||||
80% { opacity: 1; }
|
||||
to { transform: rotate(180deg) translateX(-16px) rotate(-180deg) scale(1); opacity: 0; }
|
||||
}
|
||||
|
||||
@keyframes animation-bookmarkPulse {
|
||||
from { transform: scale(1); }
|
||||
50% { transform: scale(1.3); }
|
||||
to { transform: scale(1); }
|
||||
}
|
||||
|
||||
#bookmarked-notification-container {
|
||||
min-height: 1px;
|
||||
min-width: 1px;
|
||||
height: 1px;
|
||||
margin-bottom: -1px;
|
||||
z-index: 5;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#bookmarked-notification {
|
||||
background-size: 16px;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#bookmarked-notification-anchor[notification="finish"] > #bookmarked-notification {
|
||||
background-image: url("chrome://browser/skin/places/bookmarks-notification-finish.png");
|
||||
animation: animation-bookmarkAdded 800ms;
|
||||
animation-timing-function: ease ease ease linear;
|
||||
}
|
||||
|
||||
#bookmarks-menu-button[notification="finish"] > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon {
|
||||
animation: animation-bookmarkPulse 300ms;
|
||||
animation-delay: 600ms;
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
|
||||
/* ::::: bookmark menus ::::: */
|
||||
|
||||
menu.bookmark-item,
|
||||
|
@ -119,6 +119,7 @@ browser.jar:
|
||||
skin/classic/browser/places/bookmarksMenu.png (places/bookmarksMenu.png)
|
||||
skin/classic/browser/places/bookmarksToolbar.png (places/bookmarksToolbar.png)
|
||||
skin/classic/browser/places/bookmarksToolbar-menuPanel.png (places/bookmarksToolbar-menuPanel.png)
|
||||
skin/classic/browser/places/bookmarks-notification-finish.png (places/bookmarks-notification-finish.png)
|
||||
skin/classic/browser/places/calendar.png (places/calendar.png)
|
||||
skin/classic/browser/places/toolbarDropMarker.png (places/toolbarDropMarker.png)
|
||||
skin/classic/browser/places/editBookmarkOverlay.css (places/editBookmarkOverlay.css)
|
||||
|
BIN
browser/themes/windows/places/bookmarks-notification-finish.png
Normal file
BIN
browser/themes/windows/places/bookmarks-notification-finish.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
@ -520,15 +520,6 @@ abstract public class BrowserApp extends GeckoApp
|
||||
}
|
||||
});
|
||||
|
||||
mBrowserToolbar.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
if (isHomePagerVisible()) {
|
||||
mHomePager.onToolbarFocusChange(hasFocus);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Intercept key events for gamepad shortcuts
|
||||
mBrowserToolbar.setOnKeyListener(this);
|
||||
|
||||
@ -1658,7 +1649,7 @@ abstract public class BrowserApp extends GeckoApp
|
||||
|
||||
if (mHomePager == null) {
|
||||
final ViewStub homePagerStub = (ViewStub) findViewById(R.id.home_pager_stub);
|
||||
mHomePager = (HomePager) homePagerStub.inflate().findViewById(R.id.home_pager);
|
||||
mHomePager = (HomePager) homePagerStub.inflate();
|
||||
}
|
||||
|
||||
mHomePager.show(getSupportLoaderManager(),
|
||||
|
@ -5,10 +5,6 @@
|
||||
|
||||
package org.mozilla.gecko.home;
|
||||
|
||||
import org.mozilla.gecko.animation.PropertyAnimator;
|
||||
import org.mozilla.gecko.animation.PropertyAnimator.Property;
|
||||
import org.mozilla.gecko.animation.PropertyAnimator.PropertyAnimationListener;
|
||||
import org.mozilla.gecko.animation.ViewHelper;
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.GeckoEvent;
|
||||
import org.mozilla.gecko.R;
|
||||
@ -27,7 +23,6 @@ import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
@ -38,22 +33,6 @@ public class HomeBanner extends LinearLayout
|
||||
implements GeckoEventListener {
|
||||
private static final String LOGTAG = "GeckoHomeBanner";
|
||||
|
||||
final TextView mTextView;
|
||||
final ImageView mIconView;
|
||||
final ImageButton mCloseButton;
|
||||
|
||||
// Used for tracking scroll length
|
||||
private float mTouchY = -1;
|
||||
|
||||
// Used to detect for upwards scroll to push banner all the way up
|
||||
private boolean mSnapBannerToTop;
|
||||
|
||||
// Used so that we don't move the banner when scrolling between pages
|
||||
private boolean mScrollingPages = false;
|
||||
|
||||
// User has dismissed the banner using the close button
|
||||
private boolean mDismissed = false;
|
||||
|
||||
public HomeBanner(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
@ -62,18 +41,23 @@ public class HomeBanner extends LinearLayout
|
||||
super(context, attrs);
|
||||
|
||||
LayoutInflater.from(context).inflate(R.layout.home_banner, this);
|
||||
mTextView = (TextView) findViewById(R.id.text);
|
||||
mIconView = (ImageView) findViewById(R.id.icon);
|
||||
mCloseButton = (ImageButton) findViewById(R.id.close);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
|
||||
mCloseButton.getDrawable().setAlpha(127);
|
||||
// Tapping on the close button will ensure that the banner is never
|
||||
// showed again on this session.
|
||||
mCloseButton.setOnClickListener(new View.OnClickListener() {
|
||||
final ImageButton closeButton = (ImageButton) findViewById(R.id.close);
|
||||
|
||||
// The drawable should have 50% opacity.
|
||||
closeButton.getDrawable().setAlpha(127);
|
||||
|
||||
closeButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
animateDown();
|
||||
mDismissed = true;
|
||||
HomeBanner.this.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
|
||||
@ -81,66 +65,54 @@ public class HomeBanner extends LinearLayout
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
// Send the current message id back to JS.
|
||||
GeckoAppShell.sendEventToGecko(
|
||||
GeckoEvent.createBroadcastEvent("HomeBanner:Click",(String) getTag()));
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("HomeBanner:Click", (String) getTag()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachedToWindow() {
|
||||
GeckoAppShell.getEventDispatcher().registerEventListener("HomeBanner:Data", this);
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("HomeBanner:Get", null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
|
||||
GeckoAppShell.getEventDispatcher().unregisterEventListener("HomeBanner:Data", this);
|
||||
}
|
||||
}
|
||||
|
||||
public void show() {
|
||||
if (!mDismissed) {
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("HomeBanner:Get", null));
|
||||
}
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
animateDown();
|
||||
}
|
||||
|
||||
public void setScrollingPages(boolean scrollingPages) {
|
||||
mScrollingPages = scrollingPages;
|
||||
public boolean isDismissed() {
|
||||
return (getVisibility() == View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(final String event, final JSONObject message) {
|
||||
ThreadUtils.postToUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// Store the current message id to pass back to JS in the view's OnClickListener.
|
||||
setTag(message.getString("id"));
|
||||
setText(message.getString("text"));
|
||||
setIcon(message.optString("iconURI"));
|
||||
animateUp();
|
||||
} catch (JSONException e) {
|
||||
Log.e(LOGTAG, "Exception handling " + event + " message", e);
|
||||
public void handleMessage(String event, JSONObject message) {
|
||||
try {
|
||||
// Store the current message id to pass back to JS in the view's OnClickListener.
|
||||
setTag(message.getString("id"));
|
||||
|
||||
// Display styled text from an HTML string.
|
||||
final Spanned text = Html.fromHtml(message.getString("text"));
|
||||
final TextView textView = (TextView) findViewById(R.id.text);
|
||||
|
||||
// Update the banner message on the UI thread.
|
||||
ThreadUtils.postToUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
textView.setText(text);
|
||||
setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} catch (JSONException e) {
|
||||
Log.e(LOGTAG, "Exception handling " + event + " message", e);
|
||||
return;
|
||||
}
|
||||
|
||||
private void setText(String text) {
|
||||
// Display styled text from an HTML string.
|
||||
final Spanned html = Html.fromHtml(text);
|
||||
final String iconURI = message.optString("iconURI");
|
||||
final ImageView iconView = (ImageView) findViewById(R.id.icon);
|
||||
|
||||
// Update the banner message on the UI thread.
|
||||
mTextView.setText(html);
|
||||
}
|
||||
|
||||
private void setIcon(String iconURI) {
|
||||
if (TextUtils.isEmpty(iconURI)) {
|
||||
// Hide the image view if we don't have an icon to show.
|
||||
mIconView.setVisibility(View.GONE);
|
||||
iconView.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -149,102 +121,18 @@ public class HomeBanner extends LinearLayout
|
||||
public void onBitmapFound(final Drawable d) {
|
||||
// Bail if getDrawable doesn't find anything.
|
||||
if (d == null) {
|
||||
mIconView.setVisibility(View.GONE);
|
||||
iconView.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the banner icon
|
||||
mIconView.setImageDrawable(d);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void animateDown() {
|
||||
// No need to animate if already translated.
|
||||
if (getVisibility() == GONE && ViewHelper.getTranslationY(this) == getHeight()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final PropertyAnimator animator = new PropertyAnimator(100);
|
||||
animator.attach(this, Property.TRANSLATION_Y, getHeight());
|
||||
animator.start();
|
||||
animator.addPropertyAnimationListener(new PropertyAnimationListener() {
|
||||
@Override
|
||||
public void onPropertyAnimationStart() {}
|
||||
public void onPropertyAnimationEnd() {
|
||||
HomeBanner.this.setVisibility(GONE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void animateUp() {
|
||||
// No need to animate if already translated.
|
||||
if (getVisibility() == VISIBLE && ViewHelper.getTranslationY(this) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
setVisibility(View.VISIBLE);
|
||||
final PropertyAnimator animator = new PropertyAnimator(100);
|
||||
animator.attach(this, Property.TRANSLATION_Y, 0);
|
||||
animator.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Touches to the HomePager are forwarded here to handle the hiding / showing of the banner
|
||||
* on scroll.
|
||||
*/
|
||||
public void handleHomeTouch(MotionEvent event) {
|
||||
if (mDismissed || mScrollingPages) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event.getActionMasked()) {
|
||||
case MotionEvent.ACTION_DOWN: {
|
||||
mTouchY = event.getRawY();
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
// There is a chance that we won't receive ACTION_DOWN, if the touch event
|
||||
// actually started on the Grid instead of the List. Treat this as first event.
|
||||
if (mTouchY == -1) {
|
||||
mTouchY = event.getRawY();
|
||||
return;
|
||||
}
|
||||
|
||||
final float curY = event.getRawY();
|
||||
final float delta = mTouchY - curY;
|
||||
mSnapBannerToTop = delta <= 0.0f;
|
||||
|
||||
final float height = getHeight();
|
||||
float newTranslationY = ViewHelper.getTranslationY(this) + delta;
|
||||
|
||||
// Clamp the values to be between 0 and height.
|
||||
if (newTranslationY < 0.0f) {
|
||||
newTranslationY = 0.0f;
|
||||
} else if (newTranslationY > height) {
|
||||
newTranslationY = height;
|
||||
}
|
||||
|
||||
ViewHelper.setTranslationY(this, newTranslationY);
|
||||
mTouchY = curY;
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_CANCEL: {
|
||||
mTouchY = -1;
|
||||
final float y = ViewHelper.getTranslationY(this);
|
||||
final float height = getHeight();
|
||||
if (y > 0.0f && y < height) {
|
||||
if (mSnapBannerToTop) {
|
||||
animateUp();
|
||||
} else {
|
||||
animateDown();
|
||||
// Update the banner icon on the UI thread.
|
||||
ThreadUtils.postToUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
iconView.setImageDrawable(d);
|
||||
}
|
||||
}
|
||||
break;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -24,10 +24,8 @@ import android.support.v4.content.Loader;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.view.View;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -35,7 +33,6 @@ import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
public class HomePager extends ViewPager {
|
||||
private static final String LOGTAG = "GeckoHomePager";
|
||||
|
||||
private static final int LOADER_ID_CONFIG = 0;
|
||||
|
||||
@ -43,7 +40,6 @@ public class HomePager extends ViewPager {
|
||||
private volatile boolean mLoaded;
|
||||
private Decor mDecor;
|
||||
private View mTabStrip;
|
||||
private HomeBanner mHomeBanner;
|
||||
|
||||
private final OnAddPanelListener mAddPanelListener;
|
||||
|
||||
@ -51,7 +47,6 @@ public class HomePager extends ViewPager {
|
||||
private ConfigLoaderCallbacks mConfigLoaderCallbacks;
|
||||
|
||||
private String mInitialPanelId;
|
||||
private int mDefaultPanelIndex;
|
||||
|
||||
// Whether or not we need to restart the loader when we show the HomePager.
|
||||
private boolean mRestartLoader;
|
||||
@ -244,10 +239,6 @@ public class HomePager extends ViewPager {
|
||||
PropertyAnimator.Property.ALPHA,
|
||||
1.0f);
|
||||
}
|
||||
|
||||
// Setup banner and decor listeners
|
||||
mHomeBanner = (HomeBanner) ((ViewGroup) getParent()).findViewById(R.id.home_banner);
|
||||
setOnPageChangeListener(new HomePagerOnPageChangeListener());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -259,15 +250,6 @@ public class HomePager extends ViewPager {
|
||||
setAdapter(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisibility(int visibility) {
|
||||
// Ensure that no decorations are overlaying the mainlayout
|
||||
if (mHomeBanner != null) {
|
||||
mHomeBanner.setVisibility(visibility);
|
||||
}
|
||||
super.setVisibility(visibility);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the pager is visible.
|
||||
*
|
||||
@ -287,13 +269,6 @@ public class HomePager extends ViewPager {
|
||||
if (mDecor != null) {
|
||||
mDecor.onPageSelected(item);
|
||||
}
|
||||
if (mHomeBanner != null) {
|
||||
if (item == mDefaultPanelIndex) {
|
||||
mHomeBanner.show();
|
||||
} else {
|
||||
mHomeBanner.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -306,24 +281,6 @@ public class HomePager extends ViewPager {
|
||||
return super.onInterceptTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchTouchEvent(MotionEvent event) {
|
||||
// Get touches to pages, pass to banner, and forward to pages.
|
||||
if (mHomeBanner != null) {
|
||||
mHomeBanner.handleHomeTouch(event);
|
||||
}
|
||||
|
||||
return super.dispatchTouchEvent(event);
|
||||
}
|
||||
|
||||
public void onToolbarFocusChange(boolean hasFocus) {
|
||||
if (hasFocus) {
|
||||
mHomeBanner.hide();
|
||||
} else if (mDefaultPanelIndex == getCurrentItem() || getAdapter().getCount() == 0) {
|
||||
mHomeBanner.show();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateUiFromPanelConfigs(List<PanelConfig> panelConfigs) {
|
||||
// We only care about the adapter if HomePager is currently
|
||||
// loaded, which means it's visible in the activity.
|
||||
@ -347,9 +304,6 @@ public class HomePager extends ViewPager {
|
||||
for (PanelConfig panelConfig : panelConfigs) {
|
||||
if (!panelConfig.isDisabled()) {
|
||||
enabledPanels.add(panelConfig);
|
||||
if (panelConfig.isDefault()) {
|
||||
mDefaultPanelIndex = enabledPanels.size() - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -395,35 +349,4 @@ public class HomePager extends ViewPager {
|
||||
public void onLoaderReset(Loader<List<PanelConfig>> loader) {
|
||||
}
|
||||
}
|
||||
|
||||
private class HomePagerOnPageChangeListener implements ViewPager.OnPageChangeListener {
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
if (mDecor != null) {
|
||||
mDecor.onPageSelected(position);
|
||||
}
|
||||
|
||||
if (mHomeBanner != null) {
|
||||
if (position == mDefaultPanelIndex) {
|
||||
mHomeBanner.show();
|
||||
} else {
|
||||
mHomeBanner.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
if (mDecor != null) {
|
||||
mDecor.onPageScrolled(position, positionOffset, positionOffsetPixels);
|
||||
}
|
||||
|
||||
if (mHomeBanner != null) {
|
||||
mHomeBanner.setScrollingPages(positionOffsetPixels > 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) { }
|
||||
}
|
||||
}
|
||||
|
@ -86,6 +86,15 @@ public class TopSitesPanel extends HomeFragment {
|
||||
// Grid of top sites
|
||||
private TopSitesGridView mGrid;
|
||||
|
||||
// Banner to show snippets.
|
||||
private HomeBanner mBanner;
|
||||
|
||||
// Raw Y value of the last event that happened on the list view.
|
||||
private float mListTouchY = -1;
|
||||
|
||||
// Scrolling direction of the banner.
|
||||
private boolean mSnapBannerToTop;
|
||||
|
||||
// Callbacks used for the search and favicon cursor loaders
|
||||
private CursorLoaderCallbacks mCursorLoaderCallbacks;
|
||||
|
||||
@ -197,6 +206,15 @@ public class TopSitesPanel extends HomeFragment {
|
||||
|
||||
registerForContextMenu(mList);
|
||||
registerForContextMenu(mGrid);
|
||||
|
||||
mBanner = (HomeBanner) view.findViewById(R.id.home_banner);
|
||||
mList.setOnTouchListener(new OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
TopSitesPanel.this.handleListTouchEvent(event);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -435,6 +453,60 @@ public class TopSitesPanel extends HomeFragment {
|
||||
}
|
||||
}
|
||||
|
||||
private void handleListTouchEvent(MotionEvent event) {
|
||||
// Ignore the event if the banner is hidden for this session.
|
||||
if (mBanner.isDismissed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event.getActionMasked()) {
|
||||
case MotionEvent.ACTION_DOWN: {
|
||||
mListTouchY = event.getRawY();
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
// There is a chance that we won't receive ACTION_DOWN, if the touch event
|
||||
// actually started on the Grid instead of the List. Treat this as first event.
|
||||
if (mListTouchY == -1) {
|
||||
mListTouchY = event.getRawY();
|
||||
return;
|
||||
}
|
||||
|
||||
final float curY = event.getRawY();
|
||||
final float delta = mListTouchY - curY;
|
||||
mSnapBannerToTop = (delta > 0.0f) ? false : true;
|
||||
|
||||
final float height = mBanner.getHeight();
|
||||
float newTranslationY = ViewHelper.getTranslationY(mBanner) + delta;
|
||||
|
||||
// Clamp the values to be between 0 and height.
|
||||
if (newTranslationY < 0.0f) {
|
||||
newTranslationY = 0.0f;
|
||||
} else if (newTranslationY > height) {
|
||||
newTranslationY = height;
|
||||
}
|
||||
|
||||
ViewHelper.setTranslationY(mBanner, newTranslationY);
|
||||
mListTouchY = curY;
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_CANCEL: {
|
||||
mListTouchY = -1;
|
||||
final float y = ViewHelper.getTranslationY(mBanner);
|
||||
final float height = mBanner.getHeight();
|
||||
if (y > 0.0f && y < height) {
|
||||
final PropertyAnimator animator = new PropertyAnimator(100);
|
||||
animator.attach(mBanner, Property.TRANSLATION_Y, mSnapBannerToTop ? 0 : height);
|
||||
animator.start();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateUiFromCursor(Cursor c) {
|
||||
mList.setHeaderDividersEnabled(c != null && c.getCount() > mMaxGridEntries);
|
||||
}
|
||||
|
@ -14,8 +14,7 @@
|
||||
android:background="@android:color/white"
|
||||
android:visibility="gone">
|
||||
|
||||
<org.mozilla.gecko.home.TabMenuStrip android:id="@+id/tablet_menu_strip"
|
||||
android:layout_width="fill_parent"
|
||||
<org.mozilla.gecko.home.TabMenuStrip android:layout_width="fill_parent"
|
||||
android:layout_height="32dip"
|
||||
android:background="@color/background_light"
|
||||
android:layout_gravity="top"
|
||||
|
@ -36,16 +36,6 @@
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"/>
|
||||
|
||||
<org.mozilla.gecko.home.HomeBanner android:id="@+id/home_banner"
|
||||
style="@style/Widget.HomeBanner"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="@dimen/home_banner_height"
|
||||
android:background="@drawable/home_banner"
|
||||
android:layout_gravity="bottom"
|
||||
android:gravity="center_vertical"
|
||||
android:visibility="gone"
|
||||
android:clickable="true"
|
||||
android:focusable="true"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
|
@ -14,8 +14,7 @@
|
||||
android:background="@android:color/white"
|
||||
android:visibility="gone">
|
||||
|
||||
<org.mozilla.gecko.home.HomePagerTabStrip android:id="@+id/phone_menu_strip"
|
||||
android:layout_width="fill_parent"
|
||||
<org.mozilla.gecko.home.HomePagerTabStrip android:layout_width="fill_parent"
|
||||
android:layout_height="32dip"
|
||||
android:layout_gravity="top"
|
||||
android:gravity="bottom"
|
||||
|
@ -3,8 +3,26 @@
|
||||
- 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/. -->
|
||||
|
||||
<org.mozilla.gecko.home.HomeListView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/list"
|
||||
style="@style/Widget.TopSitesListView"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" />
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<org.mozilla.gecko.home.HomeListView
|
||||
android:id="@+id/list"
|
||||
style="@style/Widget.TopSitesListView"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"/>
|
||||
|
||||
<org.mozilla.gecko.home.HomeBanner android:id="@+id/home_banner"
|
||||
style="@style/Widget.HomeBanner"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="@dimen/home_banner_height"
|
||||
android:background="@drawable/home_banner"
|
||||
android:layout_gravity="bottom"
|
||||
android:gravity="center_vertical"
|
||||
android:visibility="gone"
|
||||
android:clickable="true"
|
||||
android:focusable="true"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
@ -142,7 +142,6 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
||||
private OnFilterListener mFilterListener;
|
||||
private OnStartEditingListener mStartEditingListener;
|
||||
private OnStopEditingListener mStopEditingListener;
|
||||
private OnFocusChangeListener mFocusChangeListener;
|
||||
|
||||
final private BrowserApp mActivity;
|
||||
private boolean mHasSoftMenuButton;
|
||||
@ -316,9 +315,6 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
setSelected(hasFocus);
|
||||
if (mFocusChangeListener != null) {
|
||||
mFocusChangeListener.onFocusChange(v, hasFocus);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -797,10 +793,6 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
||||
mStopEditingListener = listener;
|
||||
}
|
||||
|
||||
public void setOnFocusChangeListener(OnFocusChangeListener listener) {
|
||||
mFocusChangeListener = listener;
|
||||
}
|
||||
|
||||
private void showUrlEditLayout() {
|
||||
setUrlEditLayoutVisibility(true, null);
|
||||
}
|
||||
|
@ -34,12 +34,15 @@
|
||||
this.EXPORTED_SYMBOLS = [ "CrashMonitor" ];
|
||||
|
||||
const Cu = Components.utils;
|
||||
const Cr = Components.results;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/osfile.jsm");
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
Cu.import("resource://gre/modules/AsyncShutdown.jsm");
|
||||
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||
Cu.import("resource://gre/modules/FileUtils.jsm");
|
||||
|
||||
const NOTIFICATIONS = [
|
||||
"final-ui-startup",
|
||||
@ -93,25 +96,42 @@ let CrashMonitorInternal = {
|
||||
* @return {Promise} A promise that resolves/rejects once loading is complete
|
||||
*/
|
||||
loadPreviousCheckpoints: function () {
|
||||
let promise = Task.spawn(function () {
|
||||
let notifications;
|
||||
try {
|
||||
let decoder = new TextDecoder();
|
||||
let data = yield OS.File.read(CrashMonitorInternal.path);
|
||||
let contents = decoder.decode(data);
|
||||
notifications = JSON.parse(contents);
|
||||
} catch (ex if ex instanceof OS.File.Error && ex.becauseNoSuchFile) {
|
||||
// If checkpoint file cannot be read
|
||||
throw new Task.Result(null);
|
||||
} catch (ex) {
|
||||
Cu.reportError("Error while loading crash monitor data: " + ex);
|
||||
throw new Task.Result(null);
|
||||
let deferred = Promise.defer();
|
||||
CrashMonitorInternal.previousCheckpoints = deferred.promise;
|
||||
|
||||
let file = FileUtils.File(CrashMonitorInternal.path);
|
||||
NetUtil.asyncFetch(file, function(inputStream, status) {
|
||||
if (!Components.isSuccessCode(status)) {
|
||||
if (status != Cr.NS_ERROR_FILE_NOT_FOUND) {
|
||||
Cu.reportError("Error while loading crash monitor data: " + status);
|
||||
}
|
||||
|
||||
deferred.resolve(null);
|
||||
return;
|
||||
}
|
||||
|
||||
let data = NetUtil.readInputStreamToString(inputStream,
|
||||
inputStream.available(), { charset: "UTF-8" });
|
||||
|
||||
let notifications = null;
|
||||
try {
|
||||
notifications = JSON.parse(data);
|
||||
} catch (ex) {
|
||||
Cu.reportError("Error while parsing crash monitor data: " + ex);
|
||||
deferred.resolve(null);
|
||||
}
|
||||
|
||||
try {
|
||||
deferred.resolve(Object.freeze(notifications));
|
||||
} catch (ex) {
|
||||
// The only exception we reject from is if notifications is not
|
||||
// an object. This happens when the checkpoints file contained
|
||||
// just a numeric string.
|
||||
deferred.reject(ex);
|
||||
}
|
||||
throw new Task.Result(Object.freeze(notifications));
|
||||
});
|
||||
|
||||
CrashMonitorInternal.previousCheckpoints = promise;
|
||||
return promise;
|
||||
return deferred.promise;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -265,9 +265,9 @@ function checkPanelPosition(panel)
|
||||
panel.hidePopup();
|
||||
}
|
||||
|
||||
function isWithinHalfPixel(a, b)
|
||||
function isWithinHalfPixel(a, b, desc)
|
||||
{
|
||||
return Math.abs(a - b) <= 0.5;
|
||||
ok(Math.abs(a - b) <= 0.5, desc);
|
||||
}
|
||||
|
||||
function checkBigPanel(panel)
|
||||
|
@ -59,35 +59,46 @@
|
||||
<implementation implements="nsIDOMXULLabelElement">
|
||||
<constructor>
|
||||
<![CDATA[
|
||||
try {
|
||||
var prefs = Components.classes["@mozilla.org/preferences-service;1"].
|
||||
getService(Components.interfaces.nsIPrefBranch);
|
||||
this.mUnderlineAccesskey = (prefs.getIntPref("ui.key.menuAccessKey") != 0);
|
||||
|
||||
const nsIPrefLocalizedString =
|
||||
Components.interfaces.nsIPrefLocalizedString;
|
||||
|
||||
const prefNameInsertSeparator =
|
||||
"intl.menuitems.insertseparatorbeforeaccesskeys";
|
||||
const prefNameAlwaysAppendAccessKey =
|
||||
"intl.menuitems.alwaysappendaccesskeys";
|
||||
|
||||
var val = prefs.getComplexValue(prefNameInsertSeparator,
|
||||
nsIPrefLocalizedString).data;
|
||||
this.mInsertSeparator = (val == "true");
|
||||
|
||||
val = prefs.getComplexValue(prefNameAlwaysAppendAccessKey,
|
||||
nsIPrefLocalizedString).data;
|
||||
this.mAlwaysAppendAccessKey = (val == "true");
|
||||
}
|
||||
catch (e) { }
|
||||
this.formatAccessKey();
|
||||
this.formatAccessKey(true);
|
||||
]]>
|
||||
</constructor>
|
||||
|
||||
<method name="formatAccessKey">
|
||||
<parameter name="firstTime"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
var accessKey = this.accessKey;
|
||||
// No need to remove existing formatting the first time.
|
||||
if (firstTime && !accessKey)
|
||||
return;
|
||||
|
||||
if (this.mInsertSeparator === undefined) {
|
||||
try {
|
||||
var prefs = Components.classes["@mozilla.org/preferences-service;1"].
|
||||
getService(Components.interfaces.nsIPrefBranch);
|
||||
this.mUnderlineAccesskey = (prefs.getIntPref("ui.key.menuAccessKey") != 0);
|
||||
|
||||
const nsIPrefLocalizedString =
|
||||
Components.interfaces.nsIPrefLocalizedString;
|
||||
|
||||
const prefNameInsertSeparator =
|
||||
"intl.menuitems.insertseparatorbeforeaccesskeys";
|
||||
const prefNameAlwaysAppendAccessKey =
|
||||
"intl.menuitems.alwaysappendaccesskeys";
|
||||
|
||||
var val = prefs.getComplexValue(prefNameInsertSeparator,
|
||||
nsIPrefLocalizedString).data;
|
||||
this.mInsertSeparator = (val == "true");
|
||||
|
||||
val = prefs.getComplexValue(prefNameAlwaysAppendAccessKey,
|
||||
nsIPrefLocalizedString).data;
|
||||
this.mAlwaysAppendAccessKey = (val == "true");
|
||||
}
|
||||
catch (e) {
|
||||
this.mInsertSeparator = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.mUnderlineAccesskey)
|
||||
return;
|
||||
|
||||
@ -116,7 +127,6 @@
|
||||
this.mergeElement(oldHiddenSpan);
|
||||
}
|
||||
|
||||
var accessKey = this.accessKey;
|
||||
var labelText = this.textContent;
|
||||
if (!accessKey || !labelText || !control) {
|
||||
return;
|
||||
@ -218,7 +228,7 @@
|
||||
<field name="mUnderlineAccesskey">
|
||||
!/Mac/.test(navigator.platform)
|
||||
</field>
|
||||
<field name="mInsertSeparator">true</field>
|
||||
<field name="mInsertSeparator"/>
|
||||
<field name="mAlwaysAppendAccessKey">false</field>
|
||||
|
||||
<property name="accessKey">
|
||||
@ -245,7 +255,7 @@
|
||||
if (control) {
|
||||
control.setAttribute('accesskey', val);
|
||||
}
|
||||
this.formatAccessKey();
|
||||
this.formatAccessKey(false);
|
||||
return val;
|
||||
]]>
|
||||
</setter>
|
||||
@ -262,7 +272,7 @@
|
||||
control.labelElement = null; // No longer pointed to be this label
|
||||
}
|
||||
this.setAttribute('control', val);
|
||||
this.formatAccessKey();
|
||||
this.formatAccessKey(false);
|
||||
return val;
|
||||
]]>
|
||||
</setter>
|
||||
|
@ -1,33 +1,43 @@
|
||||
const {DevToolsUtils} = Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {});
|
||||
const {DebuggerServer, ActorPool} = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {});
|
||||
/* 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/. */
|
||||
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init();
|
||||
}
|
||||
"use strict";
|
||||
|
||||
// In case of apps being loaded in parent process, DebuggerServer is already
|
||||
// initialized, but child specific actors are not registered.
|
||||
// Otherwise, for apps in child process, we need to load actors the first
|
||||
// time we load child.js
|
||||
DebuggerServer.addChildActors();
|
||||
// Encapsulate in its own scope to allows loading this frame script
|
||||
// more than once.
|
||||
(function () {
|
||||
const {DevToolsUtils} = Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {});
|
||||
const {DebuggerServer, ActorPool} = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {});
|
||||
|
||||
let onConnect = DevToolsUtils.makeInfallible(function (msg) {
|
||||
removeMessageListener("debug:connect", onConnect);
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init();
|
||||
}
|
||||
|
||||
let mm = msg.target;
|
||||
// In case of apps being loaded in parent process, DebuggerServer is already
|
||||
// initialized, but child specific actors are not registered.
|
||||
// Otherwise, for apps in child process, we need to load actors the first
|
||||
// time we load child.js
|
||||
DebuggerServer.addChildActors();
|
||||
|
||||
let prefix = msg.data.prefix + docShell.appId;
|
||||
let onConnect = DevToolsUtils.makeInfallible(function (msg) {
|
||||
removeMessageListener("debug:connect", onConnect);
|
||||
|
||||
let conn = DebuggerServer.connectToParent(prefix, mm);
|
||||
let mm = msg.target;
|
||||
|
||||
let actor = new DebuggerServer.ContentAppActor(conn, content);
|
||||
let actorPool = new ActorPool(conn);
|
||||
actorPool.addActor(actor);
|
||||
conn.addActorPool(actorPool);
|
||||
let prefix = msg.data.prefix + docShell.appId;
|
||||
|
||||
sendAsyncMessage("debug:actor", {actor: actor.grip(),
|
||||
appId: docShell.appId,
|
||||
prefix: prefix});
|
||||
});
|
||||
let conn = DebuggerServer.connectToParent(prefix, mm);
|
||||
|
||||
addMessageListener("debug:connect", onConnect);
|
||||
let actor = new DebuggerServer.ContentAppActor(conn, content);
|
||||
let actorPool = new ActorPool(conn);
|
||||
actorPool.addActor(actor);
|
||||
conn.addActorPool(actorPool);
|
||||
|
||||
sendAsyncMessage("debug:actor", {actor: actor.grip(),
|
||||
appId: docShell.appId,
|
||||
prefix: prefix});
|
||||
});
|
||||
|
||||
addMessageListener("debug:connect", onConnect);
|
||||
})();
|
||||
|
Loading…
Reference in New Issue
Block a user