Merge autoland to central, a=merge

MozReview-Commit-ID: LJgJXsmBQcx
This commit is contained in:
Wes Kocher 2017-09-29 14:45:37 -07:00
Родитель f2b181af94 71707c56ca
Коммит 1b5b528b2e
247 изменённых файлов: 3554 добавлений и 2815 удалений

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

@ -144,17 +144,7 @@ var BrowserPageActions = {
this.multiViewNode.appendChild(panelViewNode);
}
buttonNode.addEventListener("command", event => {
if (panelViewNode) {
action.subview.onShowing(panelViewNode);
this.multiViewNode.showSubView(panelViewNode, buttonNode);
return;
}
if (action.wantsIframe) {
this._toggleActivatedActionPanelForAction(action);
return;
}
this.panelNode.hidePopup();
action.onCommand(event, buttonNode);
this.doCommandForAction(action, event, buttonNode);
});
return [buttonNode, panelViewNode];
},
@ -381,14 +371,7 @@ var BrowserPageActions = {
}
}
buttonNode.addEventListener("click", event => {
if (event.button != 0) {
return;
}
if (action.subview || action.wantsIframe) {
this._toggleActivatedActionPanelForAction(action);
return;
}
action.onCommand(event, buttonNode);
this.doCommandForAction(action, event, buttonNode);
});
return buttonNode;
},
@ -477,12 +460,32 @@ var BrowserPageActions = {
}
},
doCommandForAction(action) {
doCommandForAction(action, event, buttonNode) {
if (event.type == "click" && event.button != 0) {
return;
}
PageActions.logTelemetry("used", action, buttonNode);
// If we're in the panel, open a subview inside the panel:
// Note that we can't use this.panelNode.contains(buttonNode) here
// because of XBL boundaries breaking ELement.contains.
if (action.subview && buttonNode && buttonNode.closest("panel") == this.panelNode) {
let panelViewNodeID = this._panelViewNodeIDForActionID(action.id, false);
let panelViewNode = document.getElementById(panelViewNodeID);
action.subview.onShowing(panelViewNode);
this.multiViewNode.showSubView(panelViewNode, buttonNode);
return;
}
// Otherwise, hide the main popup in case it was open:
this.panelNode.hidePopup();
// Toggle the activated action's panel if necessary
if (action.subview || action.wantsIframe) {
this._toggleActivatedActionPanelForAction(action);
return;
}
action.onCommand();
// Otherwise, run the action.
action.onCommand(event, buttonNode);
},
/**
@ -666,6 +669,8 @@ var BrowserPageActions = {
if (!this._contextAction) {
return;
}
let telemetryType = this._contextAction.shownInUrlbar ? "removed" : "added";
PageActions.logTelemetry(telemetryType, this._contextAction);
this._contextAction.shownInUrlbar = !this._contextAction.shownInUrlbar;
},
@ -761,13 +766,6 @@ BrowserPageActions.bookmark = {
BrowserPageActions.panelNode.hidePopup();
BookmarkingUI.onStarCommand(event);
},
onUrlbarNodeClicked(event) {
if (event.type == "click" && event.button != 0) {
return;
}
BookmarkingUI.onStarCommand(event);
},
};
// copy URL

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

@ -288,26 +288,11 @@ var TabsInTitlebar = {
function updateTitlebarDisplay() {
if (AppConstants.platform == "macosx") {
// OS X and the other platforms differ enough to necessitate this kind of
// special-casing. Like the other platforms where we CAN_DRAW_IN_TITLEBAR,
// we draw in the OS X titlebar when putting the tabs up there. However, OS X
// also draws in the titlebar when a lightweight theme is applied, regardless
// of whether or not the tabs are drawn in the titlebar.
if (TabsInTitlebar.enabled) {
document.documentElement.setAttribute("chromemargin-nonlwtheme", "0,-1,-1,-1");
document.documentElement.setAttribute("chromemargin", "0,-1,-1,-1");
document.documentElement.removeAttribute("drawtitle");
} else {
// We set chromemargin-nonlwtheme to "" instead of removing it as a way of
// making sure that LightweightThemeConsumer doesn't take it upon itself to
// detect this value again if and when we do a lwtheme state change.
document.documentElement.setAttribute("chromemargin-nonlwtheme", "");
let isCustomizing = document.documentElement.hasAttribute("customizing");
let hasLWTheme = document.documentElement.hasAttribute("lwtheme");
let isPrivate = PrivateBrowsingUtils.isWindowPrivate(window);
if ((!hasLWTheme || isCustomizing) && !isPrivate) {
document.documentElement.removeAttribute("chromemargin");
}
document.documentElement.removeAttribute("chromemargin");
document.documentElement.setAttribute("drawtitle", "true");
}
} else if (TabsInTitlebar.enabled) {

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

@ -90,12 +90,12 @@ panel[hidden] panelview {
transition: transform var(--panelui-subview-transition-duration);
}
panelview:not([mainview]):not([current]) {
panelview:not([mainview]):not([current]):not([in-transition]) {
transition: visibility 0s linear var(--panelui-subview-transition-duration);
visibility: collapse;
}
photonpanelmultiview panelview:not([current]) {
photonpanelmultiview panelview:not([current]):not([in-transition]) {
transition: none;
visibility: collapse;
}
@ -243,6 +243,10 @@ window:not([chromehidden~="toolbar"]) #nav-bar[nonemptyoverflow] > .overflow-but
%ifdef MENUBAR_CAN_AUTOHIDE
#toolbar-menubar:not([autohide=true]) ~ #TabsToolbar > .titlebar-placeholder,
%endif
%ifndef MOZ_WIDGET_COCOA
#main-window:not([sizemode=normal]) .titlebar-placeholder[type="pre-tabs"],
#main-window:not([sizemode=normal]) .titlebar-placeholder[type="post-tabs"],
%endif
#main-window:not([chromemargin]) > #titlebar,
#main-window[inFullscreen] > #titlebar,
#main-window[inFullscreen] .titlebar-placeholder,

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

@ -4944,6 +4944,18 @@ var CombinedStopReload = {
if (XULBrowserWindow.stopCommand.getAttribute("disabled") != "true")
reload.setAttribute("displaystop", "true");
stop.addEventListener("click", this);
// Removing attributes based on the observed command doesn't happen if the button
// is in the palette when the command's attribute is removed (cf. bug 309953)
for (let button of [stop, reload]) {
if (button.hasAttribute("disabled")) {
let command = document.getElementById(button.getAttribute("command"));
if (!command.hasAttribute("disabled")) {
button.removeAttribute("disabled");
}
}
}
this.reload = reload;
this.stop = stop;
this.stopReloadContainer = this.reload.parentNode;

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

@ -900,7 +900,7 @@
class="urlbar-icon-wrapper urlbar-page-action"
context="pageActionPanelContextMenu"
oncontextmenu="BrowserPageActions.onContextMenu(event);"
onclick="BrowserPageActions.bookmark.onUrlbarNodeClicked(event);">
onclick="BrowserPageActions.doCommandForAction(PageActions.actionForID('bookmark'), event, this);">
<image id="star-button"
class="urlbar-icon"
role="button"

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

@ -68,7 +68,7 @@ const EXPECTED_APPMENU_SUBVIEW_REFLOWS = [
{
stack: [
"descriptionHeightWorkaround@resource:///modules/PanelMultiView.jsm",
"_cleanupTransitionPhase@resource:///modules/PanelMultiView.jsm",
"hideAllViewsExcept@resource:///modules/PanelMultiView.jsm",
],
times: 2, // This number should only ever go down - never up.

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

@ -1311,7 +1311,9 @@ CustomizeMode.prototype = {
onLWThemesMenuShowing(aEvent) {
const DEFAULT_THEME_ID = "{972ce4c6-7e08-4474-a285-3208198ce6fd}";
const RECENT_LWT_COUNT = 5;
const LIGHT_THEME_ID = "firefox-compact-light@mozilla.org";
const DARK_THEME_ID = "firefox-compact-dark@mozilla.org";
const MAX_THEME_COUNT = 6;
this._clearLWThemesMenu(aEvent.target);
@ -1366,20 +1368,28 @@ CustomizeMode.prototype = {
let themes = [aDefaultTheme];
let lwts = LightweightThemeManager.usedThemes;
let currentLwt = LightweightThemeManager.currentTheme;
let currentLwtIndex = lwts.indexOf(currentLwt);
if (currentLwtIndex > -1) {
// Make sure that the current lightweight theme
// is at the beginning of the array to avoid truncation
// in the next step.
lwts = lwts.splice(currentLwtIndex, 1).concat(lwts);
}
if (lwts.length > RECENT_LWT_COUNT)
lwts.length = RECENT_LWT_COUNT;
// The lwts besides the builtin themes don't have an isActive property:
for (let lwt of lwts) {
lwt.isActive = !!currentLwt && (lwt.id == currentLwt.id);
themes.push(lwt);
if (!lwt.hasOwnProperty("isActive")) {
lwt.isActive = !!currentLwt && (lwt.id == currentLwt.id);
}
}
// Move the current theme (if any) and the light/dark themes to the start:
let importantThemes = [LIGHT_THEME_ID, DARK_THEME_ID];
if (currentLwt && !importantThemes.includes(currentLwt.id)) {
importantThemes.push(currentLwt.id);
}
for (let importantTheme of importantThemes) {
let themeIndex = lwts.findIndex(theme => theme.id == importantTheme);
if (themeIndex > -1) {
themes.push(...lwts.splice(themeIndex, 1));
}
}
themes = themes.concat(lwts);
if (themes.length > MAX_THEME_COUNT)
themes.length = MAX_THEME_COUNT;
let footer = doc.getElementById("customization-lwtheme-menu-footer");
let panel = footer.parentNode;
let recommendedLabel = doc.getElementById("customization-lwtheme-menu-recommended");
@ -1400,8 +1410,15 @@ CustomizeMode.prototype = {
recommendedThemes = JSON.parse(recommendedThemes);
let sb = Services.strings.createBundle("chrome://browser/locale/lightweightThemes.properties");
for (let theme of recommendedThemes) {
theme.name = sb.GetStringFromName("lightweightThemes." + theme.id + ".name");
theme.description = sb.GetStringFromName("lightweightThemes." + theme.id + ".description");
try {
theme.name = sb.GetStringFromName("lightweightThemes." + theme.id + ".name");
theme.description = sb.GetStringFromName("lightweightThemes." + theme.id + ".description");
} catch (ex) {
// If finding strings for this failed, just don't build it. This can
// happen for users with 'older' recommended themes lists, some of which
// have since been removed from Firefox.
continue;
}
let button = buildToolbarButton(theme);
button.addEventListener("command", () => {
LightweightThemeManager.setLocalTheme(button.theme);

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

@ -191,6 +191,15 @@ this.PanelMultiView = class {
}
}
/**
* @return {Boolean} |true| when the 'ephemeral' attribute is set, which means
* that this instance should be ready to be thrown away at
* any time.
*/
get _ephemeral() {
return this.node.hasAttribute("ephemeral");
}
get panelViews() {
// If there's a dedicated subViews container, we're not in the right binding
// to use SlidingPanelViews.
@ -217,10 +226,9 @@ this.PanelMultiView = class {
.getService(Ci.nsIScreenManager);
}
/**
* Getter that returns the currently visible subview OR the subview that is
* about to be shown whilst a 'ViewShowing' event is being dispatched.
*
* @return {panelview}
* @return {panelview} the currently visible subview OR the subview that is
* about to be shown whilst a 'ViewShowing' event is being
* dispatched.
*/
get current() {
return this._viewShowing || this._currentSubView
@ -235,6 +243,13 @@ this.PanelMultiView = class {
this.__currentSubView = panel;
return panel;
}
/**
* @return {Promise} showSubView() returns a promise, which is kept here for
* random access.
*/
get currentShowPromise() {
return this._currentShowPromise || Promise.resolve();
}
get _keyNavigationMap() {
if (!this.__keyNavigationMap)
this.__keyNavigationMap = new Map();
@ -316,9 +331,11 @@ this.PanelMultiView = class {
value: (...args) => this[method](...args)
});
});
Object.defineProperty(this.node, "current", {
enumerable: true,
get: () => this.current
["current", "currentShowPromise"].forEach(property => {
Object.defineProperty(this.node, property, {
enumerable: true,
get: () => this[property]
});
});
}
@ -327,8 +344,10 @@ this.PanelMultiView = class {
if (!this.node)
return;
if (this._mainView) {
let mainView = this._mainView;
if (this._ephemeral)
this.hideAllViewsExcept(null);
let mainView = this._mainView;
if (mainView) {
if (this._panelViewCache)
this._panelViewCache.appendChild(mainView);
mainView.removeAttribute("mainview");
@ -395,10 +414,13 @@ this.PanelMultiView = class {
* @return {Boolean}
*/
_canGoBack(view = this._currentSubView) {
return view != this._mainView;
return view.id != this._mainViewId;
}
setMainView(aNewMainView) {
if (!aNewMainView)
return;
if (this._mainView) {
if (!this.panelViews)
this._subViews.appendChild(this._mainView);
@ -418,38 +440,59 @@ this.PanelMultiView = class {
}
showMainView() {
if (!this._mainViewId)
return Promise.resolve();
if (this.panelViews)
return this.showSubView(this._mainView);
if (this.showingSubView) {
let viewNode = this._currentSubView;
this._dispatchViewEvent(viewNode, "ViewHiding");
if (this.panelViews) {
this._transitionHeight(() => {
viewNode.removeAttribute("current");
this.showSubView(this._mainViewId);
} else {
this._transitionHeight(() => {
viewNode.removeAttribute("current");
this._currentSubView = null;
this.node.setAttribute("viewtype", "main");
});
}
} else if (this.panelViews) {
// Make sure to hide all subviews, except for the mainView.
let mainView = this._mainView;
for (let panelview of this._panelViews) {
if (panelview == mainView)
panelview.setAttribute("current", true);
else
panelview.removeAttribute("current");
}
this.node.setAttribute("viewtype", "main");
this._currentSubView = null;
this.node.setAttribute("viewtype", "main");
});
}
if (!this.panelViews) {
this._shiftMainView();
this._shiftMainView();
return Promise.resolve();
}
/**
* Ensures that all the panelviews, that are currently part of this instance,
* are hidden, except one specifically.
*
* @param {panelview} [theOne] The panelview DOM node to ensure is visible.
* Optional.
*/
hideAllViewsExcept(theOne = null) {
for (let panelview of this._panelViews) {
// When the panelview was already reparented, don't interfere any more.
if (panelview == theOne || !this.node || panelview.panelMultiView != this.node)
continue;
if (panelview.hasAttribute("current"))
this._dispatchViewEvent(panelview, "ViewHiding");
panelview.removeAttribute("current");
}
this._viewShowing = null;
if (!this.node || !theOne)
return;
this._currentSubView = theOne;
if (!theOne.hasAttribute("current")) {
theOne.setAttribute("current", true);
this.descriptionHeightWorkaround(theOne);
this._dispatchViewEvent(theOne, "ViewShown");
}
this.node.setAttribute("viewtype", (theOne.id == this._mainViewId) ? "main" : "subview");
}
showSubView(aViewId, aAnchor, aPreviousView) {
return (async () => {
this._currentShowPromise = (async () => {
// Support passing in the node directly.
let viewNode = typeof aViewId == "string" ? this.node.querySelector("#" + aViewId) : aViewId;
if (!viewNode) {
@ -465,8 +508,10 @@ this.PanelMultiView = class {
let reverse = !!aPreviousView;
let previousViewNode = aPreviousView || this._currentSubView;
let playTransition = (!!previousViewNode && previousViewNode != viewNode &&
this._panel.state == "open");
// If the panelview to show is the same as the previous one, the 'ViewShowing'
// event has already been dispatched. Don't do it twice.
let showingSameView = viewNode == previousViewNode;
let playTransition = (!!previousViewNode && !showingSameView && this._panel.state == "open");
let dwu, previousRect;
if (playTransition || this.panelViews) {
@ -492,6 +537,13 @@ this.PanelMultiView = class {
}
this._viewShowing = viewNode;
// Because the 'mainview' attribute may be out-of-sync, due to view node
// reparenting in combination with ephemeral PanelMultiView instances,
// this is the best place to correct it (just before showing).
if (viewNode.id == this._mainViewId)
viewNode.setAttribute("mainview", true);
else
viewNode.removeAttribute("mainview");
// Make sure that new panels always have a title set.
if (this.panelViews && aAnchor) {
@ -502,53 +554,45 @@ this.PanelMultiView = class {
if (this.panelViews && this._mainViewWidth)
viewNode.style.maxWidth = viewNode.style.minWidth = this._mainViewWidth + "px";
// Emit the ViewShowing event so that the widget definition has a chance
// to lazily populate the subview with things or perhaps even cancel this
// whole operation.
let detail = {
blockers: new Set(),
addBlocker(promise) {
this.blockers.add(promise);
if (!showingSameView || !viewNode.hasAttribute("current")) {
// Emit the ViewShowing event so that the widget definition has a chance
// to lazily populate the subview with things or perhaps even cancel this
// whole operation.
let detail = {
blockers: new Set(),
addBlocker(promise) {
this.blockers.add(promise);
}
};
let cancel = this._dispatchViewEvent(viewNode, "ViewShowing", aAnchor, detail);
if (detail.blockers.size) {
try {
let results = await Promise.all(detail.blockers);
cancel = cancel || results.some(val => val === false);
} catch (e) {
Cu.reportError(e);
cancel = true;
}
}
};
let cancel = this._dispatchViewEvent(viewNode, "ViewShowing", aAnchor, detail);
if (detail.blockers.size) {
try {
let results = await Promise.all(detail.blockers);
cancel = cancel || results.some(val => val === false);
} catch (e) {
Cu.reportError(e);
cancel = true;
}
}
this._viewShowing = null;
if (cancel) {
return;
}
this._currentSubView = viewNode;
if (this.panelViews) {
if (viewNode.id == this._mainViewId) {
this.node.setAttribute("viewtype", "main");
} else {
this.node.setAttribute("viewtype", "subview");
}
// If we've got an older transition still running, make sure to clean it up.
await this._cleanupTransitionPhase();
if (!playTransition) {
viewNode.setAttribute("current", true);
this.descriptionHeightWorkaround(viewNode);
if (cancel) {
this._viewShowing = null;
return;
}
}
// Now we have to transition the panel.
if (this.panelViews && playTransition) {
await this._transitionViews(previousViewNode, viewNode, reverse, previousRect, aAnchor);
this._dispatchViewEvent(viewNode, "ViewShown");
this._updateKeyboardFocus(viewNode);
} else if (!this.panelViews) {
if (this.panelViews) {
// If we've got an older transition still running, make sure to clean it up.
await this._cleanupTransitionPhase();
if (playTransition) {
await this._transitionViews(previousViewNode, viewNode, reverse, previousRect, aAnchor);
this._updateKeyboardFocus(viewNode);
} else {
this.hideAllViewsExcept(viewNode);
}
} else {
this._currentSubView = viewNode;
this._transitionHeight(() => {
viewNode.setAttribute("current", true);
if (viewNode.id == this._mainViewId) {
@ -564,6 +608,7 @@ this.PanelMultiView = class {
this._shiftMainView(aAnchor);
}
})().catch(e => Cu.reportError(e));
return this._currentShowPromise;
}
/**
@ -596,7 +641,7 @@ this.PanelMultiView = class {
if (this._autoResizeWorkaroundTimer)
window.clearTimeout(this._autoResizeWorkaroundTimer);
this._transitionDetails = {
let details = this._transitionDetails = {
phase: TRANSITION_PHASES.START,
previousViewNode, viewNode, reverse, anchor
};
@ -604,6 +649,10 @@ this.PanelMultiView = class {
if (anchor)
anchor.setAttribute("open", "true");
// Since we're going to show two subview at the same time, don't abuse the
// 'current' attribute, since it's needed for other state-keeping, but use
// a separate 'in-transition' attribute instead.
previousViewNode.setAttribute("in-transition", true);
// Set the viewContainer dimensions to make sure only the current view is
// visible.
this._viewContainer.style.height = Math.max(previousRect.height, this._mainViewHeight) + "px";
@ -616,7 +665,7 @@ this.PanelMultiView = class {
let viewRect;
if (viewNode.__lastKnownBoundingRect) {
viewRect = viewNode.__lastKnownBoundingRect;
viewNode.setAttribute("current", true);
viewNode.setAttribute("in-transition", true);
} else if (viewNode.customRectGetter) {
// Can't use Object.assign directly with a DOM Rect object because its properties
// aren't enumerable.
@ -626,11 +675,11 @@ this.PanelMultiView = class {
if (header) {
viewRect.height += this._dwu.getBoundsWithoutFlushing(header).height;
}
viewNode.setAttribute("current", true);
viewNode.setAttribute("in-transition", true);
} else {
let oldSibling = viewNode.nextSibling || null;
this._offscreenViewStack.appendChild(viewNode);
viewNode.setAttribute("current", true);
viewNode.setAttribute("in-transition", true);
viewRect = await BrowserUtils.promiseLayoutFlushed(this.document, "layout", () => {
return this._dwu.getBoundsWithoutFlushing(viewNode);
@ -644,7 +693,7 @@ this.PanelMultiView = class {
}
this._transitioning = true;
this._transitionDetails.phase = TRANSITION_PHASES.PREPARE;
details.phase = TRANSITION_PHASES.PREPARE;
// The 'magic' part: build up the amount of pixels to move right or left.
let moveToLeft = (this._dir == "rtl" && !reverse) || (this._dir == "ltr" && reverse);
@ -679,26 +728,26 @@ this.PanelMultiView = class {
await BrowserUtils.promiseLayoutFlushed(document, "layout", () => {});
// Kick off the transition!
this._transitionDetails.phase = TRANSITION_PHASES.TRANSITION;
details.phase = TRANSITION_PHASES.TRANSITION;
this._viewStack.style.transform = "translateX(" + (moveToLeft ? "" : "-") + deltaX + "px)";
await new Promise(resolve => {
this._transitionDetails.resolve = resolve;
this._viewContainer.addEventListener("transitionend", this._transitionDetails.listener = ev => {
details.resolve = resolve;
this._viewContainer.addEventListener("transitionend", details.listener = ev => {
// It's quite common that `height` on the view container doesn't need
// to transition, so we make sure to do all the work on the transform
// transition-end, because that is guaranteed to happen.
if (ev.target != this._viewStack || ev.propertyName != "transform")
return;
this._viewContainer.removeEventListener("transitionend", this._transitionDetails.listener);
delete this._transitionDetails.listener;
this._viewContainer.removeEventListener("transitionend", details.listener);
delete details.listener;
resolve();
});
});
this._transitionDetails.phase = TRANSITION_PHASES.END;
details.phase = TRANSITION_PHASES.END;
await this._cleanupTransitionPhase();
await this._cleanupTransitionPhase(details);
}
/**
@ -706,8 +755,9 @@ this.PanelMultiView = class {
* above. Which attributes and properties depends on the phase the transition
* was left from - normally that'd be `TRANSITION_PHASES.END`.
*/
async _cleanupTransitionPhase() {
if (!this._transitionDetails)
async _cleanupTransitionPhase(details = this._transitionDetails) {
// Make sure to only clean up a phase from the most recent transition.
if (!this._transitionDetails || details != this._transitionDetails)
return;
let {phase, previousViewNode, viewNode, reverse, resolve, listener, anchor} = this._transitionDetails;
@ -715,11 +765,11 @@ this.PanelMultiView = class {
// Do the things we _always_ need to do whenever the transition ends or is
// interrupted.
this._dispatchViewEvent(previousViewNode, "ViewHiding");
previousViewNode.removeAttribute("current");
this.hideAllViewsExcept(viewNode);
previousViewNode.removeAttribute("in-transition");
viewNode.removeAttribute("in-transition");
if (reverse)
this._resetKeyNavigation(previousViewNode);
this.descriptionHeightWorkaround(viewNode);
if (anchor)
anchor.removeAttribute("open");
@ -915,7 +965,7 @@ this.PanelMultiView = class {
case "mousemove":
this._resetKeyNavigation();
break;
case "popupshowing":
case "popupshowing": {
this.node.setAttribute("panelopen", "true");
// Bug 941196 - The panel can get taller when opening a subview. Disabling
// autoPositioning means that the panel won't jump around if an opened
@ -971,13 +1021,14 @@ this.PanelMultiView = class {
// without any scrolling (using "display: flex;"), and only if the view
// exceeds the available space we set the height explicitly and enable
// scrolling.
if (this._mainView.hasAttribute("blockinboxworkaround")) {
let mainView = this._mainView;
if (mainView && mainView.hasAttribute("blockinboxworkaround")) {
let blockInBoxWorkaround = () => {
let mainViewHeight =
this._dwu.getBoundsWithoutFlushing(this._mainView).height;
this._dwu.getBoundsWithoutFlushing(mainView).height;
if (mainViewHeight > maxHeight) {
this._mainView.style.height = maxHeight + "px";
this._mainView.setAttribute("exceeding", "true");
mainView.style.height = maxHeight + "px";
mainView.setAttribute("exceeding", "true");
}
};
// On Windows, we cannot measure the full height of the main view
@ -993,12 +1044,14 @@ this.PanelMultiView = class {
}
}
break;
}
case "popupshown":
// Now that the main view is visible, we can check the height of the
// description elements it contains.
this.descriptionHeightWorkaround();
if (!this.panelViews)
this.descriptionHeightWorkaround();
break;
case "popuphidden":
case "popuphidden": {
// WebExtensions consumers can hide the popup from viewshowing, or
// mid-transition, which disrupts our state:
this._viewShowing = null;
@ -1029,12 +1082,14 @@ this.PanelMultiView = class {
// Always try to layout the panel normally when reopening it. This is
// also the layout that will be used in customize mode.
if (this._mainView.hasAttribute("blockinboxworkaround")) {
this._mainView.style.removeProperty("height");
this._mainView.removeAttribute("exceeding");
let mainView = this._mainView;
if (mainView && mainView.hasAttribute("blockinboxworkaround")) {
mainView.style.removeProperty("height");
mainView.removeAttribute("exceeding");
}
this._dispatchViewEvent(this.node, "PanelMultiViewHidden");
break;
}
}
}
@ -1257,7 +1312,7 @@ this.PanelMultiView = class {
* view if omitted.
*/
descriptionHeightWorkaround(viewNode = this._mainView) {
if (!viewNode.hasAttribute("descriptionheightworkaround")) {
if (!viewNode || !viewNode.hasAttribute("descriptionheightworkaround")) {
// This view does not require the workaround.
return;
}

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

@ -419,31 +419,37 @@ const PanelUI = {
tempPanel.setAttribute("animate", "false");
}
tempPanel.setAttribute("context", "");
tempPanel.setAttribute("photon", true);
document.getElementById(CustomizableUI.AREA_NAVBAR).appendChild(tempPanel);
// If the view has a footer, set a convenience class on the panel.
tempPanel.classList.toggle("cui-widget-panelWithFooter",
viewNode.querySelector(".panel-subview-footer"));
// If the panelview is already selected in another PanelMultiView instance
// as a subview, make sure to properly hide it there.
let oldMultiView = viewNode.panelMultiView;
if (oldMultiView && oldMultiView.current == viewNode) {
await oldMultiView.showMainView();
}
let viewShown = false;
let listener = () => viewShown = true;
viewNode.addEventListener("ViewShown", listener, {once: true});
let multiView = document.createElement("photonpanelmultiview");
multiView.setAttribute("id", "customizationui-widget-multiview");
multiView.setAttribute("nosubviews", "true");
multiView.setAttribute("viewCacheId", "appMenu-viewCache");
tempPanel.setAttribute("photon", true);
multiView.setAttribute("mainViewId", viewNode.id);
multiView.appendChild(viewNode);
multiView.setAttribute("ephemeral", true);
document.getElementById("appMenu-viewCache").appendChild(viewNode);
tempPanel.appendChild(multiView);
viewNode.classList.add("cui-widget-panelview");
let viewShown = false;
let panelRemover = () => {
viewNode.classList.remove("cui-widget-panelview");
if (viewShown) {
CustomizableUI.removePanelCloseListeners(tempPanel);
tempPanel.removeEventListener("popuphidden", panelRemover);
let currentView = multiView.current || viewNode;
let evt = new CustomEvent("ViewHiding", {detail: currentView});
currentView.dispatchEvent(evt);
}
aAnchor.open = false;
@ -453,35 +459,15 @@ const PanelUI = {
tempPanel.remove();
};
// Emit the ViewShowing event so that the widget definition has a chance
// to lazily populate the subview with things.
let detail = {
blockers: new Set(),
addBlocker(aPromise) {
this.blockers.add(aPromise);
},
};
// Wait until all the tasks needed to show a view are done.
await multiView.currentShowPromise;
let evt = new CustomEvent("ViewShowing", { bubbles: true, cancelable: true, detail });
viewNode.dispatchEvent(evt);
let cancel = evt.defaultPrevented;
if (detail.blockers.size) {
try {
let results = await Promise.all(detail.blockers);
cancel = cancel || results.some(val => val === false);
} catch (e) {
Components.utils.reportError(e);
cancel = true;
}
}
if (cancel) {
if (!viewShown) {
viewNode.removeEventListener("ViewShown", listener);
panelRemover();
return;
}
viewShown = true;
CustomizableUI.addPanelCloseListeners(tempPanel);
tempPanel.addEventListener("popuphidden", panelRemover);
@ -539,7 +525,8 @@ const PanelUI = {
withFavicons: true
});
// If there's nothing to display, or the panel is already hidden, get out.
if (!highlights.length || viewNode.panelMultiView.getAttribute("panelopen") != "true") {
let multiView = viewNode.panelMultiView;
if (!highlights.length || (multiView && multiView.getAttribute("panelopen") != "true")) {
this._loadingRecentHighlights = false;
return;
}

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

@ -5,12 +5,13 @@
"use strict";
const DEFAULT_THEME_ID = "{972ce4c6-7e08-4474-a285-3208198ce6fd}";
const LIGHT_THEME_ID = "firefox-compact-light@mozilla.org";
const DARK_THEME_ID = "firefox-compact-dark@mozilla.org";
const {LightweightThemeManager} = Components.utils.import("resource://gre/modules/LightweightThemeManager.jsm", {});
add_task(async function() {
Services.prefs.clearUserPref("lightweightThemes.usedThemes");
Services.prefs.clearUserPref("lightweightThemes.recommendedThemes");
LightweightThemeManager.clearBuiltInThemes();
await startCustomizing();
@ -35,9 +36,14 @@ add_task(async function() {
let header = document.getElementById("customization-lwtheme-menu-header");
let recommendedHeader = document.getElementById("customization-lwtheme-menu-recommended");
is(header.nextSibling.nextSibling, recommendedHeader,
"There should only be one theme (default) in the 'My Themes' section by default");
is(header.nextSibling.theme.id, DEFAULT_THEME_ID, "That theme should be the default theme");
is(header.nextSibling.nextSibling.nextSibling.nextSibling, recommendedHeader,
"There should only be three themes (default, light, dark) in the 'My Themes' section by default");
is(header.nextSibling.theme.id, DEFAULT_THEME_ID,
"The first theme should be the default theme");
is(header.nextSibling.nextSibling.theme.id, LIGHT_THEME_ID,
"The second theme should be the light theme");
is(header.nextSibling.nextSibling.nextSibling.theme.id, DARK_THEME_ID,
"The third theme should be the dark theme");
let firstLWTheme = recommendedHeader.nextSibling;
let firstLWThemeId = firstLWTheme.theme.id;
@ -52,12 +58,18 @@ add_task(async function() {
await popupShownPromise;
is(header.nextSibling.theme.id, DEFAULT_THEME_ID, "The first theme should be the Default theme");
let installedThemeId = header.nextSibling.nextSibling.theme.id;
let installedThemeId = header.nextSibling.nextSibling.nextSibling.nextSibling.theme.id;
ok(installedThemeId.startsWith(firstLWThemeId),
"The second theme in the 'My Themes' section should be the newly installed theme: " +
"Installed theme id: " + installedThemeId + "; First theme ID: " + firstLWThemeId);
is(header.nextSibling.nextSibling.nextSibling, recommendedHeader,
"There should be two themes in the 'My Themes' section");
let themeCount = 0;
let iterNode = header;
while (iterNode.nextSibling && iterNode.nextSibling.theme) {
themeCount++;
iterNode = iterNode.nextSibling;
}
is(themeCount, 4,
"There should be four themes in the 'My Themes' section");
let defaultTheme = header.nextSibling;
defaultTheme.doCommand();
@ -90,11 +102,21 @@ add_task(async function() {
await popupShownPromise;
header = document.getElementById("customization-lwtheme-menu-header");
is(header.hidden, false, "Header should never be hidden");
is(header.nextSibling.theme.id, DEFAULT_THEME_ID, "The first theme should be the Default theme");
is(header.nextSibling.hidden, false, "The default theme should never be hidden");
let themeNode = header.nextSibling;
is(themeNode.theme.id, DEFAULT_THEME_ID, "The first theme should be the Default theme");
is(themeNode.hidden, false, "The default theme should never be hidden");
themeNode = themeNode.nextSibling;
is(themeNode.theme.id, LIGHT_THEME_ID, "The second theme should be the Light theme");
is(themeNode.hidden, false, "The light theme should never be hidden");
themeNode = themeNode.nextSibling;
is(themeNode.theme.id, DARK_THEME_ID, "The third theme should be the Dark theme");
is(themeNode.hidden, false, "The dark theme should never be hidden");
recommendedHeader = document.getElementById("customization-lwtheme-menu-recommended");
is(header.nextSibling.nextSibling, recommendedHeader,
"There should only be one theme (default) in the 'My Themes' section by default");
is(themeNode.nextSibling, recommendedHeader,
"There should only be three themes (default, light, dark) in the 'My Themes' section now");
let footer = document.getElementById("customization-lwtheme-menu-footer");
is(recommendedHeader.nextSibling.id, footer.id, "There should be no recommended themes in the menu");
is(recommendedHeader.hidden, true, "The recommendedHeader should be hidden since there are no recommended themes");

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

@ -35,15 +35,16 @@ function checkSeparatorInsertion(menuId, buttonId, subviewId) {
await document.getElementById("nav-bar").overflowable.show();
let subview = document.getElementById(subviewId);
let button = document.getElementById(buttonId);
button.click();
await BrowserTestUtils.waitForEvent(subview, "ViewShown");
await BrowserTestUtils.waitForEvent(PanelUI.overflowPanel, "ViewShown");
let subview = document.getElementById(subviewId);
ok(subview.firstChild, "Subview should have a kid");
is(subview.firstChild.localName, "toolbarbutton", "There should be no separators to start with");
let subviewBody = subview.firstChild;
ok(subviewBody.firstChild, "Subview should have a kid");
is(subviewBody.firstChild.localName, "toolbarbutton", "There should be no separators to start with");
for (let kid of subview.children) {
for (let kid of subviewBody.children) {
if (kid.localName == "menuseparator") {
ok(kid.previousSibling && kid.previousSibling.localName != "menuseparator",
"Separators should never have another separator next to them, and should never be the first node.");
@ -58,7 +59,7 @@ function checkSeparatorInsertion(menuId, buttonId, subviewId) {
};
}
add_task(checkSeparatorInsertion("menuWebDeveloperPopup", "developer-button", "PanelUI-developerItems"));
add_task(checkSeparatorInsertion("menuWebDeveloperPopup", "developer-button", "PanelUI-developer"));
registerCleanupFunction(function() {
for (let el of tempElements) {

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

@ -8,7 +8,6 @@ const kWidgetId = "test-981418-widget-onbeforecreated";
// Should be able to add broken view widget
add_task(async function testAddOnBeforeCreatedWidget() {
let viewShownDeferred = Promise.defer();
let onBeforeCreatedCalled = false;
let widgetSpec = {
id: kWidgetId,
@ -17,73 +16,47 @@ add_task(async function testAddOnBeforeCreatedWidget() {
onBeforeCreated(doc) {
let view = doc.createElement("panelview");
view.id = kWidgetId + "idontexistyet";
document.getElementById("PanelUI-multiView").appendChild(view);
document.getElementById("appMenu-viewCache").appendChild(view);
onBeforeCreatedCalled = true;
},
onViewShowing() {
viewShownDeferred.resolve();
}
};
let noError = true;
try {
CustomizableUI.createWidget(widgetSpec);
CustomizableUI.addWidgetToArea(kWidgetId, CustomizableUI.AREA_NAVBAR);
} catch (ex) {
Cu.reportError(ex);
noError = false;
}
ok(noError, "Should not throw an exception trying to add the widget.");
CustomizableUI.createWidget(widgetSpec);
CustomizableUI.addWidgetToArea(kWidgetId, CustomizableUI.AREA_NAVBAR);
ok(onBeforeCreatedCalled, "onBeforeCreated should have been called");
let widgetNode = document.getElementById(kWidgetId);
let viewNode = document.getElementById(kWidgetId + "idontexistyet");
ok(widgetNode, "Widget should exist");
if (widgetNode) {
try {
widgetNode.click();
ok(viewNode, "Panelview should exist");
widgetNode.click();
let tempPanel = document.getElementById("customizationui-widget-panel");
let panelShownPromise = promisePanelElementShown(window, tempPanel);
let tempPanel = document.getElementById("customizationui-widget-panel");
let panelShownPromise = promisePanelElementShown(window, tempPanel);
let shownTimeout = setTimeout(() => viewShownDeferred.reject("Panel not shown within 20s"), 20000);
await viewShownDeferred.promise;
await panelShownPromise;
clearTimeout(shownTimeout);
ok(true, "Found view shown");
await Promise.all([
BrowserTestUtils.waitForEvent(viewNode, "ViewShown"),
panelShownPromise
]);
let panelHiddenPromise = promisePanelElementHidden(window, tempPanel);
tempPanel.hidePopup();
await panelHiddenPromise;
let panelHiddenPromise = promisePanelElementHidden(window, tempPanel);
tempPanel.hidePopup();
await panelHiddenPromise;
CustomizableUI.addWidgetToArea(kWidgetId, CustomizableUI.AREA_FIXED_OVERFLOW_PANEL);
await waitForOverflowButtonShown();
await document.getElementById("nav-bar").overflowable.show();
CustomizableUI.addWidgetToArea(kWidgetId, CustomizableUI.AREA_FIXED_OVERFLOW_PANEL);
await waitForOverflowButtonShown();
await document.getElementById("nav-bar").overflowable.show();
viewShownDeferred = Promise.defer();
widgetNode.click();
widgetNode.click();
shownTimeout = setTimeout(() => viewShownDeferred.reject("Panel not shown within 20s"), 20000);
await viewShownDeferred.promise;
clearTimeout(shownTimeout);
ok(true, "Found view shown");
await BrowserTestUtils.waitForEvent(viewNode, "ViewShown");
let panelHidden = promiseOverflowHidden(window);
PanelUI.overflowPanel.hidePopup();
await panelHidden;
} catch (ex) {
ok(false, "Unexpected exception (like a timeout for one of the yields) " +
"when testing view widget.");
}
}
let panelHidden = promiseOverflowHidden(window);
PanelUI.overflowPanel.hidePopup();
await panelHidden;
noError = true;
try {
CustomizableUI.destroyWidget(kWidgetId);
} catch (ex) {
Cu.reportError(ex);
noError = false;
}
ok(noError, "Should not throw an exception trying to remove the broken view widget.");
CustomizableUI.destroyWidget(kWidgetId);
});
add_task(async function asyncCleanup() {

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

@ -7,7 +7,7 @@
let syncService = {};
Components.utils.import("resource://services-sync/service.js", syncService);
const service = syncService.Service;
Components.utils.import("resource://services-sync/UIState.jsm");
const {UIState} = Components.utils.import("resource://services-sync/UIState.jsm", {});
let getState;
let originalSync;

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

@ -316,12 +316,12 @@ function subviewShown(aSubview) {
let timeoutId = win.setTimeout(() => {
reject("Subview (" + aSubview.id + ") did not show within 20 seconds.");
}, 20000);
function onViewShowing(e) {
aSubview.removeEventListener("ViewShowing", onViewShowing);
function onViewShown(e) {
aSubview.removeEventListener("ViewShown", onViewShown);
win.clearTimeout(timeoutId);
resolve();
}
aSubview.addEventListener("ViewShowing", onViewShowing);
aSubview.addEventListener("ViewShown", onViewShown);
});
}

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

@ -214,26 +214,32 @@ richlistitem.download button {
-moz-binding: url("chrome://browser/content/downloads/download.xml#download-subview-toolbarbutton");
}
/* When a Download is hovered that has an [openLabel] attribute set, which means
that the file exists and can be opened, hide the status label.
When a Download is hovered - specifically on the secondary action button - that
has a [retryLabel] attribute set, which means that the file does not exist and
the download failed earlier, hide the status label. */
.subviewbutton.download:hover:-moz-any([openLabel],[retryLabel][buttonover]) > .toolbarbutton-text > .status-full,
/* When a Download is not hovered at all or the secondary action button is hovered,
hide the 'Open File' status label. */
.subviewbutton.download:-moz-any(:not(:hover),[buttonover]) > .toolbarbutton-text > .status-open,
/* When a Download is not hovered at all, or when it's hovered but specifically
not the secondary action button or when the [retryLabel] is not set, hide the
'Retry Downloads' label. */
.subviewbutton.download:-moz-any(:not(:hover),:hover:not([buttonover]),:not([retryLabel])) > .toolbarbutton-text > .status-retry,
/* When a Download is not hovered at all, or when it's hovered but specifically
not the secondary action button or when the file does not exist, hide the
'Open Containing Folder' label. */
.subviewbutton.download:-moz-any(:not(:hover),:hover:not([buttonover]),:not([exists])) > .toolbarbutton-text > .status-show,
/* Hide all status labels by default and selectively display one at a time,
depending on the state of the Download. */
.subviewbutton.download > .toolbarbutton-text > .status-text,
/* When a Download is not hovered at all, hide the secondary action button. */
.subviewbutton.download:not(:hover) > .action-button,
/* Always hide the label of the secondary action button. */
.subviewbutton.download > .action-button > .toolbarbutton-text {
display: none;
}
/* When a Download is _not_ hovered, display the full status message. */
.subviewbutton.download:not(:hover) > .toolbarbutton-text > .status-full,
/* When a Download is hovered when the file doesn't exist and cannot be retried,
keep showing the full status message. */
.subviewbutton.download:hover:-moz-any(:not([openLabel]),:not([exists])):not([retryLabel]) > .toolbarbutton-text > .status-full,
/* When a Download is hovered and the it can be retried, but the action button
is _not_ hovered, keep showing the full status message. */
.subviewbutton.download:hover[retryLabel]:not([buttonover]) > .toolbarbutton-text > .status-full,
/* When a Download is hovered and the file can be opened, but the action button
is _not_ hovered, show the 'Open File' status label. */
.subviewbutton.download:hover[openLabel][exists]:not([buttonover]) > .toolbarbutton-text > .status-open,
/* When a Download is hovered - its action button explicitly - and it can be
retried, show the 'Retry Download' label. */
.subviewbutton.download:hover[retryLabel][buttonover] > .toolbarbutton-text > .status-retry,
/* When a Download is hovered - its action button explicitly - and the file can
be shown in the OS's shell, show the 'Open Containing Folder' label. */
.subviewbutton.download:hover[openLabel][exists][buttonover] > .toolbarbutton-text > .status-show {
display: inline;
}

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

@ -150,7 +150,7 @@ this.browserAction = class extends ExtensionAPI {
view.setAttribute("flex", "1");
view.setAttribute("extension", true);
document.getElementById("PanelUI-multiView").appendChild(view);
document.getElementById("appMenu-viewCache").appendChild(view);
if (this.extension.hasPermission("menus") ||
this.extension.hasPermission("contextMenus")) {

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

@ -40,6 +40,8 @@ const FAVICON_REQUEST_TIMEOUT = 60 * 1000;
// Map from windows to arrays of data about pending favicon loads.
let gFaviconLoadDataMap = new Map();
const ITEM_CHANGED_BATCH_NOTIFICATION_THRESHOLD = 10;
// copied from utilityOverlay.js
const TAB_DROP_TYPE = "application/x-moz-tabbrowser-tab";
const PREF_LOAD_BOOKMARKS_IN_BACKGROUND = "browser.tabs.loadBookmarksInBackground";
@ -1539,7 +1541,41 @@ this.PlacesUIUtils = {
if (!info)
return null;
return this.promiseNodeLikeFromFetchInfo(info);
}
},
/**
* This function wraps potentially large places transaction operations
* with batch notifications to the result node, hence switching the views
* to batch mode.
*
* @param {nsINavHistoryResult} resultNode The result node to turn on batching.
* @note If resultNode is not supplied, the function will pass-through to
* functionToWrap.
* @param {Integer} itemsBeingChanged The count of items being changed. If the
* count is lower than a threshold, then
* batching won't be set.
* @param {Function} functionToWrap The function to
*/
async batchUpdatesForNode(resultNode, itemsBeingChanged, functionToWrap) {
if (!resultNode) {
await functionToWrap();
return;
}
resultNode = resultNode.QueryInterface(Ci.nsINavBookmarkObserver);
if (itemsBeingChanged > ITEM_CHANGED_BATCH_NOTIFICATION_THRESHOLD) {
resultNode.onBeginUpdateBatch();
}
try {
await functionToWrap();
} finally {
if (itemsBeingChanged > ITEM_CHANGED_BATCH_NOTIFICATION_THRESHOLD) {
resultNode.onEndUpdateBatch();
}
}
},
};

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

@ -808,7 +808,9 @@ PlacesController.prototype = {
}
if (transactions.length) {
await PlacesTransactions.batch(transactions);
await PlacesUIUtils.batchUpdatesForNode(this._view.result, transactions.length, async () => {
await PlacesTransactions.batch(transactions);
});
}
},
@ -966,7 +968,9 @@ PlacesController.prototype = {
if (transactions.length > 0) {
if (PlacesUIUtils.useAsyncTransactions) {
await PlacesTransactions.batch(transactions);
await PlacesUIUtils.batchUpdatesForNode(this._view.result, transactions.length, async () => {
await PlacesTransactions.batch(transactions);
});
} else {
var txn = new PlacesAggregatedTransaction(txnName, transactions);
PlacesUtils.transactionManager.doTransaction(txn);
@ -1304,30 +1308,39 @@ PlacesController.prototype = {
let urls = items.filter(item => "uri" in item).map(item => Services.io.newURI(item.uri));
await PlacesTransactions.Tag({ urls, tag: ip.tagName }).transact();
} else {
await PlacesTransactions.batch(async function() {
let insertionIndex = await ip.getIndex();
let parent = ip.guid;
let transactionData = [];
for (let item of items) {
let doCopy = action == "copy";
let insertionIndex = await ip.getIndex();
let parent = ip.guid;
// If this is not a copy, check for safety that we can move the
// source, otherwise report an error and fallback to a copy.
if (!doCopy &&
!PlacesControllerDragHelper.canMoveUnwrappedNode(item)) {
Components.utils.reportError("Tried to move an unmovable " +
"Places node, reverting to a copy operation.");
doCopy = true;
}
let guid = await PlacesUIUtils.getTransactionForData(
item, type, parent, insertionIndex, doCopy).transact();
itemsToSelect.push(await PlacesUtils.promiseItemId(guid));
for (let item of items) {
let doCopy = action == "copy";
// Adjust index to make sure items are pasted in the correct
// position. If index is DEFAULT_INDEX, items are just appended.
if (insertionIndex != PlacesUtils.bookmarks.DEFAULT_INDEX)
insertionIndex++;
// If this is not a copy, check for safety that we can move the
// source, otherwise report an error and fallback to a copy.
if (!doCopy &&
!PlacesControllerDragHelper.canMoveUnwrappedNode(item)) {
Components.utils.reportError("Tried to move an unmovable " +
"Places node, reverting to a copy operation.");
doCopy = true;
}
transactionData.push([item, type, parent, insertionIndex, doCopy]);
// Adjust index to make sure items are pasted in the correct
// position. If index is DEFAULT_INDEX, items are just appended.
if (insertionIndex != PlacesUtils.bookmarks.DEFAULT_INDEX)
insertionIndex++;
}
await PlacesUIUtils.batchUpdatesForNode(this._view.result, transactionData.length, async () => {
await PlacesTransactions.batch(async () => {
for (let item of transactionData) {
let guid = await PlacesUIUtils.getTransactionForData(
...item).transact();
itemsToSelect.push(await PlacesUtils.promiseItemId(guid));
}
});
});
}
} else {
@ -1581,10 +1594,15 @@ var PlacesControllerDragHelper = {
/**
* Handles the drop of one or more items onto a view.
* @param insertionPoint
* The insertion point where the items should be dropped
*
* @param {Object} insertionPoint The insertion point where the items should
* be dropped.
* @param {Object} dt The dataTransfer information for the drop.
* @param {Object} view The tree view where this object is being
* dropped to. This allows batching to take
* place.
*/
async onDrop(insertionPoint, dt) {
async onDrop(insertionPoint, dt, view) {
let doCopy = ["copy", "link"].includes(dt.dropEffect);
let transactions = [];
@ -1707,7 +1725,9 @@ var PlacesControllerDragHelper = {
return;
}
if (PlacesUIUtils.useAsyncTransactions) {
await PlacesTransactions.batch(transactions);
await PlacesUIUtils.batchUpdatesForNode(view && view.result, transactions.length, async () => {
await PlacesTransactions.batch(transactions);
});
} else {
let txn = new PlacesAggregatedTransaction("DropItems", transactions);
PlacesUtils.transactionManager.doTransaction(txn);

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

@ -1453,11 +1453,14 @@ PlacesTreeView.prototype = {
// since this information is specific to the tree view.
let ip = this._getInsertionPoint(aRow, aOrientation);
if (ip) {
PlacesControllerDragHelper.onDrop(ip, aDataTransfer)
.catch(Components.utils.reportError);
PlacesControllerDragHelper.onDrop(ip, aDataTransfer, this)
.catch(Components.utils.reportError)
.then(() => {
// We should only clear the drop target once
// the onDrop is complete, as it is an async function.
PlacesControllerDragHelper.currentDropTarget = null;
});
}
PlacesControllerDragHelper.currentDropTarget = null;
},
getParentIndex: function PTV_getParentIndex(aRow) {

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

@ -1078,15 +1078,16 @@ this.UITour = {
shouldOpenAppMenu = true;
} else if (this.targetIsInPageActionPanel(aTarget)) {
shouldOpenPageActionPanel = true;
// Ensure the panel visibility so as to ensure the visibility of
// the target element inside the panel otherwise
// we would be rejected in the below `isElementVisible` checking.
// Ensure the panel visibility so as to ensure the visibility of the target
// element inside the panel otherwise we would be rejected in the below
// `isElementVisible` checking.
aChromeWindow.BrowserPageActions.panelNode.hidden = false;
}
// Prevent showing a panel at an undefined position.
if (!this.isElementVisible(aTarget.node)) {
return Promise.reject(`_ensureTarget: Reject the ${aTarget.name} target since it isn't visible.`);
// Prevent showing a panel at an undefined position, but when it's tucked
// away inside a panel, we skip this check.
if (!aTarget.node.closest("panelview") && !this.isElementVisible(aTarget.node)) {
return Promise.reject(`_ensureTarget: Reject the ${aTarget.name || aTarget.targetName} target since it isn't visible.`);
}
let menuToOpen = null;

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

@ -64,6 +64,8 @@ for (const type of [
"SECTION_REGISTER",
"SECTION_UPDATE",
"SECTION_UPDATE_CARD",
"SETTINGS_CLOSE",
"SETTINGS_OPEN",
"SET_PREF",
"SHOW_FIREFOX_ACCOUNTS",
"SNIPPETS_DATA",

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

@ -45,7 +45,8 @@ const INITIAL_STATE = {
visible: false,
data: {}
},
Sections: []
Sections: [],
PreferencesPane: {visible: false}
};
function App(prevState = INITIAL_STATE.App, action) {
@ -310,11 +311,22 @@ function Snippets(prevState = INITIAL_STATE.Snippets, action) {
}
}
function PreferencesPane(prevState = INITIAL_STATE.PreferencesPane, action) {
switch (action.type) {
case at.SETTINGS_OPEN:
return Object.assign({}, prevState, {visible: true});
case at.SETTINGS_CLOSE:
return Object.assign({}, prevState, {visible: false});
default:
return prevState;
}
}
this.INITIAL_STATE = INITIAL_STATE;
this.TOP_SITES_DEFAULT_LENGTH = TOP_SITES_DEFAULT_LENGTH;
this.TOP_SITES_SHOWMORE_LENGTH = TOP_SITES_SHOWMORE_LENGTH;
this.reducers = {TopSites, App, Snippets, Prefs, Dialog, Sections};
this.reducers = {TopSites, App, Snippets, Prefs, Dialog, Sections, PreferencesPane};
this.insertPinned = insertPinned;
this.EXPORTED_SYMBOLS = ["reducers", "INITIAL_STATE", "insertPinned", "TOP_SITES_DEFAULT_LENGTH", "TOP_SITES_SHOWMORE_LENGTH"];

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

@ -151,5 +151,8 @@
"icon": "highlights",
"initialized": false
}
]
],
"PreferencesPane": {
"visible": false
}
};

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -418,8 +418,12 @@ main {
.edit-topsites-wrapper .edit-topsites-button {
position: absolute;
offset-inline-end: 0;
top: -2px; }
offset-inline-end: 21px;
top: -2px;
opacity: 0;
transition: opacity 0.2s cubic-bezier(0.07, 0.95, 0, 1); }
.edit-topsites-wrapper .edit-topsites-button:focus, .edit-topsites-wrapper .edit-topsites-button:active {
opacity: 1; }
.edit-topsites-wrapper .edit-topsites-button button {
background: none;
border: 0;
@ -457,6 +461,9 @@ main {
.edit-topsites-wrapper .show-less span {
padding-inline-start: 3px; }
section.top-sites:hover .edit-topsites-button {
opacity: 1; }
.topsite-form .form-wrapper {
margin: auto;
max-width: 350px;
@ -517,13 +524,13 @@ main {
opacity: 1;
transform: translateY(0); } }
.sections-list .section-top-bar {
.section-top-bar {
position: relative; }
.sections-list .section-top-bar .section-info-option {
.section-top-bar .section-info-option {
offset-inline-end: 0;
position: absolute;
top: 0; }
.sections-list .section-top-bar .info-option-icon {
.section-top-bar .info-option-icon {
background-image: url("assets/glyph-info-option-12.svg");
background-size: 12px 12px;
background-repeat: no-repeat;
@ -533,19 +540,30 @@ main {
height: 16px;
width: 16px;
display: inline-block;
margin-bottom: -2px; }
.sections-list .section-top-bar .info-option-icon[aria-expanded="true"] {
margin-bottom: -2px;
opacity: 0;
transition: opacity 0.2s cubic-bezier(0.07, 0.95, 0, 1); }
.section-top-bar .info-option-icon:focus, .section-top-bar .info-option-icon:active {
opacity: 1; }
.section-top-bar .info-option-icon[aria-expanded="true"] {
fill: rgba(12, 12, 13, 0.8); }
.sections-list .section-top-bar .section-info-option .info-option {
.section-top-bar .section-info-option .info-option {
visibility: hidden;
opacity: 0;
transition: visibility 0.2s, opacity 0.2s ease-out;
transition-delay: 0.5s; }
.sections-list .section-top-bar .info-option-icon[aria-expanded="true"] + .info-option {
transition: visibility 0.2s, opacity 0.2s cubic-bezier(0.07, 0.95, 0, 1); }
.section-top-bar .section-info-option .info-option::before {
content: "";
display: block;
height: 32px;
left: 50%;
position: absolute;
right: 0;
top: -32px; }
.section-top-bar .info-option-icon[aria-expanded="true"] + .info-option {
visibility: visible;
opacity: 1;
transition: visibility 0.2s, opacity 0.2s ease-out; }
.sections-list .section-top-bar .info-option {
transition: visibility 0.2s, opacity 0.2s cubic-bezier(0.07, 0.95, 0, 1); }
.section-top-bar .info-option {
z-index: 9999;
position: absolute;
background: #FFF;
@ -553,23 +571,45 @@ main {
border-radius: 3px;
font-size: 13px;
line-height: 120%;
margin-inline-end: -13px;
margin-inline-end: -9px;
offset-inline-end: 0;
top: 20px;
width: 320px;
padding: 24px;
box-shadow: 0 1px 4px 0 rgba(12, 12, 13, 0.1);
-moz-user-select: none; }
.sections-list .section-top-bar .info-option-header {
.section-top-bar .info-option-header {
font-size: 15px;
font-weight: 600; }
.sections-list .section-top-bar .info-option-body {
.section-top-bar .info-option-body {
margin: 0;
margin-top: 12px; }
.sections-list .section-top-bar .info-option-link {
display: block;
margin-top: 12px;
color: #0060DF; }
.section-top-bar .info-option-link {
color: #0060DF;
margin-left: 7px; }
.section-top-bar .info-option-manage {
margin-top: 24px; }
.section-top-bar .info-option-manage button {
background: none;
border: none;
color: #0060DF;
cursor: pointer;
margin: 0;
padding: 0; }
.section-top-bar .info-option-manage button::after {
background-image: url("assets/topic-show-more-12.svg");
background-repeat: no-repeat;
content: '';
-moz-context-properties: fill;
display: inline-block;
fill: #0060DF;
height: 16px;
margin-inline-start: 5px;
margin-top: 1px;
vertical-align: middle;
width: 12px; }
.section-top-bar .info-option-manage button:dir(rtl)::after {
transform: scaleX(-1); }
.sections-list .section-list {
margin: 0;
@ -622,6 +662,9 @@ main {
color: #737373;
text-align: center; }
section.section:hover .info-option-icon {
opacity: 1; }
.topic {
font-size: 12px;
color: #737373;

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

@ -2808,6 +2808,7 @@
"default_label_loading": "בטעינה…",
"header_top_sites": "אתרים מובילים",
"header_stories": "סיפורים מובילים",
"header_highlights": "מומלצים",
"header_visit_again": "ביקור חוזר",
"header_bookmarks": "סימניות אחרונות",
"header_recommended_by": "מומלץ על ידי {provider}",
@ -2839,6 +2840,8 @@
"search_web_placeholder": "חיפוש ברשת",
"search_settings": "שינוי הגדרות חיפוש",
"section_info_option": "מידע",
"section_info_send_feedback": "שליחת משוב",
"section_info_privacy_notice": "הצהרת פרטיות",
"welcome_title": "ברוכים הבאים לדף הלשונית החדשה",
"welcome_body": "Firefox ישתמש באזור זה כדי להציג את הסימניות הרלוונטיות ביותר, מאמרים, סרטוני וידאו ודפים שביקרת בהם לאחרונה, כך שניתן יהיה לגשת אליהם שוב בקלות.",
"welcome_label": "תחומי העניין שלך מזוהים",
@ -2848,7 +2851,7 @@
"time_label_day": "{number} ימים",
"settings_pane_button_label": "התאמה אישית של דף הלשונית החדשה שלך",
"settings_pane_header": "העדפות לשונית חדשה",
"settings_pane_body": "ניתן לבחור מה יופיע בפניך בעת פתיחת לשונית חדשה.",
"settings_pane_body2": "בחירה של מה שיופיע בעמוד הזה.",
"settings_pane_search_header": "חיפוש",
"settings_pane_search_body": "חיפוש באינטרנט ישירות מהלשונית החדשה שלך.",
"settings_pane_topsites_header": "אתרים מובילים",
@ -2858,8 +2861,12 @@
"settings_pane_bookmarks_body": "הסימניות החדשות שיצרת במיקום נוח ואחיד.",
"settings_pane_visit_again_header": "ביקור חוזר",
"settings_pane_visit_again_body": "Firefox תציג לך חלקים מהיסטוריית הגלישה שלך שאולי יעניין אותך להיזכר בהם או לחזור אליהם.",
"settings_pane_pocketstories_header": "סיפורים מובילים",
"settings_pane_pocketstories_body": "Pocket, חלק ממשפחת Mozilla, יסייע לך להתחבר לתוכן באיכות גבוהה שיתכן שלא היה מגיע אליך בדרך אחרת.",
"settings_pane_highlights_header": "מומלצים",
"settings_pane_highlights_body2": "מציאת הדרך חזרה לדברים שמעניינים אותך בהתאם לפריטים בהם ביקרת לאחרונה או הוספת לסימניות.",
"settings_pane_highlights_options_bookmarks": "סימניות",
"settings_pane_highlights_options_visited": "אתרים בהם ביקרת",
"settings_pane_snippets_header": "פתקיות",
"settings_pane_snippets_body": "ניתן לקרוא עדכונים קטנים ומתוקים מ־Mozilla לגבי Firefox, תרבות האינטרנט ומם אקראי מדי פעם בפעם.",
"settings_pane_done_button": "סיום",
"edit_topsites_button_text": "עריכה",
"edit_topsites_button_label": "התאמת אגף האתרים המובילים שלך",
@ -2882,9 +2889,10 @@
"pocket_read_more": "נושאים פופולריים:",
"pocket_read_even_more": "צפייה בחדשות נוספות",
"pocket_feedback_header": "המיטב מרחבי האינטרנט, נאסף על ידי 25 מיליון אנשים.",
"pocket_feedback_body": "Pocket, חלק ממשפחת Mozilla, יסייע לך להתחבר לתוכן באיכות גבוהה שיתכן שלא היה מגיע אליך בדרך אחרת.",
"pocket_send_feedback": "שליחת משוב",
"manual_migration_explanation": "נסו את Firefox עם האתרים המועדפים עליך והסימניות שלך מדפדפן אחר.",
"pocket_description": "ניתן להחשף לתוכן באיכות גבוהה שיתכן שלא היית רואה, בעזרת Pocket, שכיום מהווה חלק מ־Mozilla.",
"highlights_empty_state": "ניתן להתחיל בגלישה ואנו נציג בפניך מספר כתבות, סרטונים ועמודים שונים מעולים בהם ביקרת לאחרונה או שהוספת לסימניות.",
"topstories_empty_state": "התעדכנת בכל הסיפורים. כדאי לנסות שוב מאוחר יותר כדי לקבל עוד סיפורים מובילים מאת {provider}. לא רוצה לחכות? ניתן לבחור נושא נפוץ כדי למצוא עוד סיפורים נפלאים מרחבי הרשת.",
"manual_migration_explanation2": "ניתן להתנסות ב־Firefox עם הסימניות, ההיסטוריה והססמאות מדפדפן אחר.",
"manual_migration_cancel_button": "לא תודה",
"manual_migration_import_button": "ייבוא כעת"
},
@ -5391,11 +5399,17 @@
"newtab_page_title": "Filă nouă",
"default_label_loading": "Se încarcă…",
"header_top_sites": "Site-uri de top",
"header_stories": "Articole de top",
"header_highlights": "Evidențieri",
"header_visit_again": "Vizitează din nou",
"header_bookmarks": "Marcaje recente",
"header_recommended_by": "Recomandat de {provider}",
"header_bookmarks_placeholder": "Nu ai niciun marcaj încă.",
"header_stories_from": "de la",
"type_label_visited": "Vizitate",
"type_label_bookmarked": "Însemnat",
"type_label_synced": "Sincronizat de pe alt dispozitiv",
"type_label_recommended": "În tendințe",
"type_label_open": "Deschise",
"type_label_topic": "Subiect",
"type_label_now": "Acum",
@ -5407,6 +5421,9 @@
"menu_action_open_private_window": "Deschide într-o fereastră privată nouă",
"menu_action_dismiss": "Înlătură",
"menu_action_delete": "Șterge din istoric",
"menu_action_pin": "Fixează",
"menu_action_unpin": "Anulează fixarea",
"confirm_history_delete_p1": "Sigur dorești să ştergi fiecare instanţă a acestei pagini din istoric?",
"confirm_history_delete_notice_p2": "Această acțiune este ireversibilă.",
"menu_action_save_to_pocket": "Salvează în Pocket",
"search_for_something_with": "Caută {search_term} cu: ",
@ -5415,6 +5432,8 @@
"search_web_placeholder": "Caută pe web",
"search_settings": "Schimbă setările de căutare",
"section_info_option": "Informații",
"section_info_send_feedback": "Trimite feedback",
"section_info_privacy_notice": "Politica de confidențialitate",
"welcome_title": "Bun venit în noua filă",
"welcome_body": "Firefox va folosi acest spațiu pentru a arăta cele mai relevante semne de carte, articole, videouri și pagini vizitate recent pentru a reveni la acestea ușor.",
"welcome_label": "Se identifică evidențierile tale",
@ -5424,11 +5443,17 @@
"time_label_day": "{number}d",
"settings_pane_button_label": "Particularizează pagina de filă nouă",
"settings_pane_header": "Preferințe pentru filă nouă",
"settings_pane_body2": "Alege ceea ce vezi pe această pagină.",
"settings_pane_search_header": "Caută",
"settings_pane_search_body": "Caută pe web din noua filă.",
"settings_pane_topsites_header": "Site-uri de top",
"settings_pane_topsites_body": "Accesează site-urile pe care le vizitezi mai des.",
"settings_pane_topsites_options_showmore": "Arată două rânduri",
"settings_pane_bookmarks_header": "Marcaje recente",
"settings_pane_visit_again_header": "Vizitează din nou",
"settings_pane_highlights_header": "Evidențieri",
"settings_pane_highlights_options_bookmarks": "Marcaje",
"settings_pane_highlights_options_visited": "Site-uri vizitate",
"settings_pane_done_button": "Gata",
"edit_topsites_button_text": "Editează",
"edit_topsites_button_label": "Particularizează secțiunea site-urilor de top",
@ -5436,6 +5461,7 @@
"edit_topsites_showless_button": "Arată mai puțin",
"edit_topsites_done_button": "Gata",
"edit_topsites_pin_button": "Fixează acest site",
"edit_topsites_unpin_button": "Anulează fixarea acestui site",
"edit_topsites_edit_button": "Editează acest site",
"edit_topsites_dismiss_button": "Înlătură acest site",
"edit_topsites_add_button": "Adaugă",
@ -5448,6 +5474,7 @@
"topsites_form_cancel_button": "Renunță",
"topsites_form_url_validation": "URL valid necesar",
"pocket_read_more": "Subiecte populare:",
"pocket_read_even_more": "Vezi mai multe articole",
"manual_migration_cancel_button": "Nu, mulțumesc"
},
"ru": {

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

@ -8,7 +8,7 @@
<em:type>2</em:type>
<em:bootstrap>true</em:bootstrap>
<em:unpack>false</em:unpack>
<em:version>2017.09.28.0954-66ebf91c</em:version>
<em:version>2017.09.29.0895-52552f5e</em:version>
<em:name>Activity Stream</em:name>
<em:description>A rich visual history feed and a reimagined home page make it easier than ever to find exactly what you're looking for in Firefox.</em:description>
<em:multiprocessCompatible>true</em:multiprocessCompatible>

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

@ -52,6 +52,10 @@ const BUILT_IN_SECTIONS = {
title: {id: "header_highlights"},
maxRows: 3,
availableContextMenuOptions: ["CheckBookmark", "SaveToPocket", "Separator", "OpenInNewWindow", "OpenInPrivateWindow", "Separator", "BlockUrl", "DeleteUrl"],
infoOption: {
header: {id: "settings_pane_highlights_header"},
body: {id: "settings_pane_highlights_body2"}
},
emptyState: {
message: {id: "highlights_empty_state"},
icon: "highlights"

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

@ -1,5 +1,5 @@
const {reducers, INITIAL_STATE, insertPinned} = require("common/Reducers.jsm");
const {TopSites, App, Snippets, Prefs, Dialog, Sections} = reducers;
const {TopSites, App, Snippets, Prefs, Dialog, Sections, PreferencesPane} = reducers;
const {actionTypes: at} = require("common/Actions.jsm");
@ -524,4 +524,19 @@ describe("Reducers", () => {
assert.equal(state, INITIAL_STATE.Snippets);
});
});
describe("PreferencesPane", () => {
it("should return INITIAL_STATE by default", () => {
assert.equal(INITIAL_STATE.PreferencesPane, PreferencesPane(undefined, {type: "non_existent"}));
});
it("should toggle visible to true on SETTINGS_OPEN", () => {
const action = {type: at.SETTINGS_OPEN};
const nextState = PreferencesPane(INITIAL_STATE.PreferencesPane, action);
assert.isTrue(nextState.visible);
});
it("should toggle visible to false on SETTINGS_CLOSE", () => {
const action = {type: at.SETTINGS_CLOSE};
const nextState = PreferencesPane(INITIAL_STATE.PreferencesPane, action);
assert.isFalse(nextState.visible);
});
});
});

17
browser/extensions/e10srollout/bootstrap.js поставляемый
Просмотреть файл

@ -21,20 +21,17 @@ const TEST_THRESHOLD = {
// If a user qualifies for the e10s-multi experiement, this is how many
// content processes to use and whether to allow addons for the experiment.
const MULTI_EXPERIMENT = {
"beta": { buckets: { 4: 1, }, // 4 processes: 100%
"beta": { buckets: { 4: 1 }, // 4 processes: 100%
// When on the "beta" channel, getAddonsDisqualifyForMulti
// will return true if any addon installed is not a web extension.
// Therefore, this returns true if and only if all addons
// installed are web extensions or if no addons are installed
// at all.
addonsDisableExperiment(prefix) { return getAddonsDisqualifyForMulti(); } },
// The extensions code only allows webextensions and legacy-style
// extensions that have been verified to work with multi.
// Therefore, we can allow all extensions.
addonsDisableExperiment(prefix) { return false; } },
"release": { buckets: { 4: 1 }, // 4 processes: 100%
// See above for an explanation of this: we only allow users
// with no extensions or users with WebExtensions.
addonsDisableExperiment(prefix) { return getAddonsDisqualifyForMulti(); } }
// See the comment above the "beta" addonsDisableExperiment.
addonsDisableExperiment(prefix) { return false; } }
};
const ADDON_ROLLOUT_POLICY = {

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

@ -10,7 +10,7 @@
<Description about="urn:mozilla:install-manifest">
<em:id>e10srollout@mozilla.org</em:id>
<em:version>3.00</em:version>
<em:version>3.05</em:version>
<em:type>2</em:type>
<em:bootstrap>true</em:bootstrap>
<em:multiprocessCompatible>true</em:multiprocessCompatible>

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

@ -516,6 +516,26 @@ FormAutofillHandler.prototype = {
fieldDetail.state = nextState;
},
_isAddressRecordCreatable(record) {
let hasName = 0;
let length = 0;
for (let key of Object.keys(record)) {
if (!record[key]) {
continue;
}
if (FormAutofillUtils.getCategoryFromFieldName(key) == "name") {
hasName = 1;
continue;
}
length++;
}
return (length + hasName) >= FormAutofillUtils.AUTOFILL_FIELDS_THRESHOLD;
},
_isCreditCardRecordCreatable(record) {
return record["cc-number"] && FormAutofillUtils.isCCNumber(record["cc-number"]);
},
/**
* Return the records that is converted from address/creditCard fieldDetails and
* only valid form records are included.
@ -581,17 +601,14 @@ FormAutofillHandler.prototype = {
this._normalizeAddress(data.address);
if (data.address &&
Object.values(data.address.record).filter(v => v).length <
FormAutofillUtils.AUTOFILL_FIELDS_THRESHOLD) {
if (data.address && !this._isAddressRecordCreatable(data.address.record)) {
log.debug("No address record saving since there are only",
Object.keys(data.address.record).length,
"usable fields");
delete data.address;
}
if (data.creditCard && (!data.creditCard.record["cc-number"] ||
!FormAutofillUtils.isCCNumber(data.creditCard.record["cc-number"]))) {
if (data.creditCard && !this._isCreditCardRecordCreatable(data.creditCard.record)) {
log.debug("No credit card record saving since card number is invalid");
delete data.creditCard;
}

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

@ -26,19 +26,19 @@ const TESTCASES = [
description: "\"country\" using @autocomplete shouldn't be identified aggressively",
document: `<form>
<input id="given-name" autocomplete="given-name">
<input id="family-name" autocomplete="family-name">
<input id="organization" autocomplete="organization">
<input id="country" autocomplete="country">
</form>`,
formValue: {
"given-name": "John",
"family-name": "Doe",
country: "United States",
"organization": "Mozilla",
"country": "United States",
},
expectedRecord: {
address: {
"given-name": "John",
"family-name": "Doe",
country: "United States",
"organization": "Mozilla",
"country": "United States",
},
},
},
@ -46,19 +46,19 @@ const TESTCASES = [
description: "\"country\" using heuristics should be identified aggressively",
document: `<form>
<input id="given-name" autocomplete="given-name">
<input id="family-name" autocomplete="family-name">
<input id="organization" autocomplete="organization">
<input id="country" name="country">
</form>`,
formValue: {
"given-name": "John",
"family-name": "Doe",
country: "United States",
"organization": "Mozilla",
"country": "United States",
},
expectedRecord: {
address: {
"given-name": "John",
"family-name": "Doe",
country: "US",
"organization": "Mozilla",
"country": "US",
},
},
},
@ -66,20 +66,20 @@ const TESTCASES = [
description: "\"tel\" related fields should be concatenated",
document: `<form>
<input id="given-name" autocomplete="given-name">
<input id="family-name" autocomplete="family-name">
<input id="organization" autocomplete="organization">
<input id="tel-country-code" autocomplete="tel-country-code">
<input id="tel-national" autocomplete="tel-national">
</form>`,
formValue: {
"given-name": "John",
"family-name": "Doe",
"organization": "Mozilla",
"tel-country-code": "+1",
"tel-national": "1234567890",
},
expectedRecord: {
address: {
"given-name": "John",
"family-name": "Doe",
"organization": "Mozilla",
"tel": "+11234567890",
},
},
@ -88,21 +88,21 @@ const TESTCASES = [
description: "\"tel\" should be removed if it's too short",
document: `<form>
<input id="given-name" autocomplete="given-name">
<input id="family-name" autocomplete="family-name">
<input id="organization" autocomplete="organization">
<input id="country" autocomplete="country">
<input id="tel" autocomplete="tel-national">
</form>`,
formValue: {
"given-name": "John",
"family-name": "Doe",
"organization": "Mozilla",
"country": "United States",
"tel": "1234",
},
expectedRecord: {
address: {
"given-name": "John",
"family-name": "Doe",
"organization": "Mozilla",
"country": "United States",
"tel": "",
},
},
@ -111,21 +111,21 @@ const TESTCASES = [
description: "\"tel\" should be removed if it's too long",
document: `<form>
<input id="given-name" autocomplete="given-name">
<input id="family-name" autocomplete="family-name">
<input id="organization" autocomplete="organization">
<input id="country" autocomplete="country">
<input id="tel" autocomplete="tel-national">
</form>`,
formValue: {
"given-name": "John",
"family-name": "Doe",
"organization": "Mozilla",
"country": "United States",
"tel": "1234567890123456",
},
expectedRecord: {
address: {
"given-name": "John",
"family-name": "Doe",
"organization": "Mozilla",
"country": "United States",
"tel": "",
},
},
@ -134,25 +134,123 @@ const TESTCASES = [
description: "\"tel\" should be removed if it contains invalid characters",
document: `<form>
<input id="given-name" autocomplete="given-name">
<input id="family-name" autocomplete="family-name">
<input id="organization" autocomplete="organization">
<input id="country" autocomplete="country">
<input id="tel" autocomplete="tel-national">
</form>`,
formValue: {
"given-name": "John",
"family-name": "Doe",
"organization": "Mozilla",
"country": "United States",
"tel": "12345###!!!",
},
expectedRecord: {
address: {
"given-name": "John",
"family-name": "Doe",
"organization": "Mozilla",
"country": "United States",
"tel": "",
},
},
},
{
description: "All name related fields should be counted as 1 field only.",
document: `<form>
<input id="given-name" autocomplete="given-name">
<input id="family-name" autocomplete="family-name">
<input id="organization" autocomplete="organization">
</form>`,
formValue: {
"given-name": "John",
"family-name": "Doe",
"organization": "Mozilla",
},
expectedRecord: {
address: undefined,
},
},
{
description: "All telephone related fields should be counted as 1 field only.",
document: `<form>
<input id="tel-country-code" autocomplete="tel-country-code">
<input id="tel-area-code" autocomplete="tel-area-code">
<input id="tel-local" autocomplete="tel-local">
<input id="organization" autocomplete="organization">
</form>`,
formValue: {
"tel-country-code": "+1",
"tel-area-code": "123",
"tel-local": "4567890",
"organization": "Mozilla",
},
expectedRecord: {
address: undefined,
},
},
{
description: "A credit card form with the value of cc-number, cc-exp, and cc-name.",
document: `<form>
<input id="cc-number" autocomplete="cc-number">
<input id="cc-name" autocomplete="cc-name">
<input id="cc-exp" autocomplete="cc-exp">
</form>`,
formValue: {
"cc-number": "4444000022220000",
"cc-name": "Foo Bar",
"cc-exp": "2022-06",
},
expectedRecord: {
creditCard: {
"cc-number": "4444000022220000",
"cc-name": "Foo Bar",
"cc-exp": "2022-06",
},
},
},
{
description: "A credit card form with cc-number value only.",
document: `<form>
<input id="cc-number" autocomplete="cc-number">
</form>`,
formValue: {
"cc-number": "4444000022220000",
},
expectedRecord: {
creditCard: {
"cc-number": "4444000022220000",
},
},
},
{
description: "A credit card form must have cc-number value.",
document: `<form>
<input id="cc-number" autocomplete="cc-number">
<input id="cc-name" autocomplete="cc-name">
<input id="cc-exp" autocomplete="cc-exp">
</form>`,
formValue: {
"cc-number": "",
"cc-name": "Foo Bar",
"cc-exp": "2022-06",
},
expectedRecord: {
creditCard: undefined,
},
},
{
description: "A credit card form must have cc-number field.",
document: `<form>
<input id="cc-name" autocomplete="cc-name">
<input id="cc-exp" autocomplete="cc-exp">
</form>`,
formValue: {
"cc-name": "Foo Bar",
"cc-exp": "2022-06",
},
expectedRecord: {
creditCard: undefined,
},
},
];
for (let testcase of TESTCASES) {

6
browser/extensions/pocket/bootstrap.js поставляемый
Просмотреть файл

@ -136,10 +136,8 @@ var PocketPageAction = {
wrapper.hidden = true;
wrapper.addEventListener("click", event => {
if (event.type == "click" && event.button != 0) {
return;
}
this.doCommand(event.target.ownerGlobal);
let {BrowserPageActions} = wrapper.ownerGlobal;
BrowserPageActions.doCommandForAction(this, event, wrapper);
});
},
onPlacedInPanel(panelNode, urlbarNode) {

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

@ -30,6 +30,7 @@ let WebCompatReporter = {
id: "webcompat-reporter-button",
title: wcStrings.GetStringFromName("wc-reporter.label2"),
iconURL: "chrome://webcompat-reporter/skin/lightbulb.svg",
labelForHistogram: "webcompat",
onCommand: (e) => this.reportIssue(e.target.ownerGlobal),
onShowingInPanel: (buttonNode) => this.onShowingInPanel(buttonNode)
}));

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

@ -399,6 +399,27 @@ this.PageActions = {
}
},
logTelemetry(type, action, node = null) {
const kAllowedLabels = ["pocket", "screenshots", "webcompat"].concat(
gBuiltInActions.filter(a => !a.__isSeparator).map(a => a.id)
);
if (type == "used") {
type = (node && node.closest("#urlbar-container")) ? "urlbar_used" : "panel_used";
}
let histogramID = "FX_PAGE_ACTION_" + type.toUpperCase();
try {
let histogram = Services.telemetry.getHistogramById(histogramID);
if (kAllowedLabels.includes(action.labelForHistogram)) {
histogram.add(action.labelForHistogram);
} else {
histogram.add("other");
}
} catch (ex) {
Cu.reportError(ex);
}
},
_storePersistedActions() {
let json = JSON.stringify(this._persistedActions);
Services.prefs.setStringPref(PREF_PERSISTED_ACTIONS, json);
@ -538,6 +559,7 @@ function Action(options) {
title: !options._isSeparator,
anchorIDOverride: false,
iconURL: false,
labelForHistogram: false,
nodeAttributes: false,
onBeforePlacedInWindow: false,
onCommand: false,
@ -667,6 +689,10 @@ Action.prototype = {
return this._subview;
},
get labelForHistogram() {
return this._labelForHistogram || this._id;
},
/**
* Performs the command for an action. If the action has an onCommand
* handler, then it's called. If the action has a subview or iframe, then a
@ -959,6 +985,9 @@ this.PageActions.ACTION_ID_BUILT_IN_SEPARATOR = ACTION_ID_BUILT_IN_SEPARATOR;
// Sorted in the order in which they should appear in the page action panel.
// Does not include the page actions of extensions bundled with the browser.
// They're added by the relevant extension code.
// NOTE: If you add items to this list (or system add-on actions that we
// want to keep track of), make sure to also update Histograms.json for the
// new actions.
var gBuiltInActions = [
// bookmark

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

@ -11,7 +11,7 @@
}
#sidebar-search-container {
padding: 4px;
padding: 8px;
}
#search-box {

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

@ -730,11 +730,11 @@ html|span.ac-emphasize-text-url {
#sidebar-box {
-moz-appearance: -moz-mac-source-list;
-moz-font-smoothing-background-color: -moz-mac-source-list;
/* Default font size is 11px on mac, so this is 12px */
font-size: 1.0909rem;
}
#sidebar-header {
/* system font size is a bit smaller in mac, so need more ems. */
font-size: 1.4545em;
border-bottom: 1px solid hsla(240, 5%, 5%, .1);
background-color: transparent;
}

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

@ -56,6 +56,12 @@
display: none;
}
#sidebar-search-container {
/* Native searchbar styling already adds 4px margin on Mac, so
* adding 4px padding results in 8px of total whitespace. */
padding: 4px;
}
.sidebar-placesTreechildren::-moz-tree-twisty {
-moz-appearance: none;
padding: 0 2px;

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

@ -85,7 +85,8 @@ toolbar[brighttext] .toolbarbutton-1 {
/* Default findbar text color doesn't look good - Bug 1125677 */
.browserContainer > findbar .findbar-find-status,
.browserContainer > findbar .found-matches {
.browserContainer > findbar .found-matches,
.browserContainer > findbar .findbar-button {
color: inherit;
}

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

@ -194,10 +194,6 @@
transform: translateX(-@menuPanelWidth@);
}
panelmultiview[nosubviews=true] > .panel-viewcontainer > .panel-viewstack > .panel-subviews {
display: none;
}
panelview {
-moz-box-orient: vertical;
-moz-box-flex: 1;

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

@ -601,6 +601,7 @@ tabbrowser {
-moz-context-properties: fill, fill-opacity;
fill: currentColor;
fill-opacity: var(--toolbarbutton-icon-fill-opacity);
color: inherit;
}
.tabbrowser-arrowscrollbox > .scrollbutton-up:-moz-locale-dir(rtl),

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

@ -48,6 +48,11 @@
min-height: 32px;
}
:root[chromehidden~="toolbar"] #urlbar {
/* Remove excess space between the address bar and the menu button in popups. */
margin-inline-end: 0;
}
#urlbar-container {
-moz-box-align: center;
}

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

@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
%filter substitution
%define toolbarShadowColor hsla(209,67%,12%,0.35)
%define glassActiveBorderColor rgb(37, 44, 51)
%define glassInactiveBorderColor rgb(102, 102, 102)
@ -260,7 +259,7 @@
/* Artificially draw window borders that are covered by lwtheme, see bug 591930.
* Borders for win7 are below, win10 doesn't need them. */
#main-window[sizemode="normal"] > #tab-view-deck > #browser-panel:-moz-lwtheme {
border-top: 1px solid @toolbarShadowColor@;
border-top: 1px solid @glassShadowColor@;
}
}
@ -290,13 +289,13 @@
/* Vertical toolbar border */
#main-window[sizemode=normal] #navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar):not(:-moz-lwtheme),
#main-window[sizemode=normal] #navigator-toolbox:-moz-lwtheme {
border-left: 1px solid @toolbarShadowColor@;
border-right: 1px solid @toolbarShadowColor@;
border-left: 1px solid @glassShadowColor@;
border-right: 1px solid @glassShadowColor@;
background-clip: padding-box;
}
#main-window[sizemode=normal] #navigator-toolbox:not(:-moz-lwtheme)::after {
box-shadow: 1px 0 0 @toolbarShadowColor@, -1px 0 0 @toolbarShadowColor@;
box-shadow: 1px 0 0 @glassShadowColor@, -1px 0 0 @glassShadowColor@;
margin-left: 1px;
margin-right: 1px;
}
@ -304,12 +303,12 @@
#main-window[sizemode=normal] #browser-border-start,
#main-window[sizemode=normal] #browser-border-end {
display: -moz-box;
background-color: @toolbarShadowColor@;
background-color: @glassShadowColor@;
width: 1px;
}
#main-window[sizemode=normal] #browser-bottombox {
border: 1px solid @toolbarShadowColor@;
border: 1px solid @glassShadowColor@;
border-top-style: none;
background-clip: padding-box;
}
@ -321,11 +320,6 @@
}
@media (-moz-windows-glass) {
#main-window[sizemode=normal] #nav-bar {
border-top-left-radius: 2.5px;
border-top-right-radius: 2.5px;
}
/* Set to full fill-opacity to improve visibility of toolbar buttons on aero glass. */
#TabsToolbar:not(:-moz-lwtheme) {
--toolbarbutton-icon-fill-opacity: 1;

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

@ -8,6 +8,8 @@
@namespace html url("http://www.w3.org/1999/xhtml");
%include ../shared/browser.inc.css
%filter substitution
%define glassShadowColor hsla(209,67%,12%,0.35)
:root {
--titlebar-text-color: currentColor;
@ -112,11 +114,10 @@
@media (-moz-os-version: windows-win7) {
@media (-moz-windows-default-theme) {
:root:not(:-moz-lwtheme) {
--tabs-border: #4A4A4F;
--tabs-border: @glassShadowColor@;
}
#TabsToolbar:not(:-moz-lwtheme),
#TabsToolbar:not(:-moz-lwtheme) toolbarbutton[disabled="true"] {
#TabsToolbar:not(:-moz-lwtheme) {
color: hsl(240,9%,98%);
}

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

@ -27,8 +27,7 @@
@media (-moz-os-version: windows-win7) {
@media (-moz-windows-default-theme) {
/* Always show light toolbar elements on aero surface. */
#TabsToolbar,
#TabsToolbar toolbarbutton[disabled="true"] {
#TabsToolbar {
color: hsl(240,9%,98%);
}
@ -121,11 +120,6 @@
border-right: none !important;
}
/* Disable dragging like in the default theme: */
#main-window[tabsintitlebar] #navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar):-moz-lwtheme {
-moz-window-dragging: no-drag;
}
@media (-moz-os-version: windows-win10) {
.titlebar-button:-moz-lwtheme {
-moz-context-properties: stroke;

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

@ -10,7 +10,7 @@
}
#sidebar-search-container {
padding: 4px;
padding: 8px;
}
.sidebar-placesTree {

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

@ -5,16 +5,15 @@
import os
import sys
from mozbuild.base import MozbuildObject
from mozbuild.backend.configenvironment import PartialConfigEnvironment
config = MozbuildObject.from_environment()
partial_config = PartialConfigEnvironment(config.topobjdir)
for var in ('topsrcdir', 'topobjdir', 'defines', 'non_global_defines',
'substs'):
for var in ('topsrcdir', 'topobjdir'):
value = getattr(config, var)
setattr(sys.modules[__name__], var, value)
substs = dict(substs)
for var in os.environ:
if var not in ('CPP', 'CXXCPP', 'SHELL') and var in substs:
substs[var] = os.environ[var]
for var in ('defines', 'substs', 'get_dependencies'):
value = getattr(partial_config, var)
setattr(sys.modules[__name__], var, value)

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

@ -17,6 +17,7 @@ sys.path.insert(0, os.path.join(base_dir, 'python', 'mozbuild'))
from mozbuild.configure import ConfigureSandbox
from mozbuild.makeutil import Makefile
from mozbuild.pythonutil import iter_modules_in_path
from mozbuild.backend.configenvironment import PartialConfigEnvironment
from mozbuild.util import (
indented_repr,
encode,
@ -90,6 +91,9 @@ def config_status(config):
config_status(**args)
'''))
partial_config = PartialConfigEnvironment(config['TOPOBJDIR'])
partial_config.write_vars(sanitized_config)
# Write out a depfile so Make knows to re-run configure when relevant Python
# changes.
mk = Makefile()

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

@ -7,7 +7,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<link rel="stylesheet" href="chrome://devtools/skin/animationinspector.css" type="text/css"/>
<link rel="stylesheet" href="resource://devtools/client/shared/components/splitter/split-box.css"/>
<link rel="stylesheet" href="resource://devtools/client/shared/components/splitter/SplitBox.css"/>
<script type="application/javascript" src="chrome://devtools/content/shared/theme-switching.js"/>
</head>
<body class="theme-sidebar" role="application" empty="true">

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

@ -89,7 +89,7 @@ AnimationsTimeline.prototype = {
const ReactDOM = browserRequire("devtools/client/shared/vendor/react-dom");
const SplitBox = React.createFactory(
browserRequire("devtools/client/shared/components/splitter/split-box"));
browserRequire("devtools/client/shared/components/splitter/SplitBox"));
const splitter = SplitBox({
className: "animation-root",

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

@ -9,7 +9,7 @@
const React = require("devtools/client/shared/vendor/react");
const { connect } = require("devtools/client/shared/vendor/react-redux");
const TreeView = React.createFactory(require("devtools/client/shared/components/tree/tree-view"));
const TreeView = React.createFactory(require("devtools/client/shared/components/tree/TreeView"));
// Reps
const { REPS, MODE } = require("devtools/client/shared/components/reps/reps");

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

@ -14,7 +14,7 @@ const { createFactories } = require("devtools/client/shared/react-utils");
const { Toolbar, ToolbarButton } = createFactories(require("devtools/client/jsonview/components/reps/toolbar"));
// DOM Panel
const SearchBox = React.createFactory(require("devtools/client/shared/components/search-box"));
const SearchBox = React.createFactory(require("devtools/client/shared/components/SearchBox"));
// Actions
const { fetchProperties } = require("../actions/grips");

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

@ -9,7 +9,7 @@
<link href="resource://devtools/client/dom/content/dom-view.css" rel="stylesheet" />
<link href="resource://devtools/client/jsonview/css/toolbar.css" rel="stylesheet" />
<link href="resource://devtools/client/shared/components/tree/tree-view.css" rel="stylesheet" />
<link href="resource://devtools/client/shared/components/tree/TreeView.css" rel="stylesheet" />
<script type="text/javascript"
src="chrome://devtools/content/shared/theme-switching.js"></script>

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

@ -1022,7 +1022,7 @@ Toolbox.prototype = {
if (!this._notificationBox) {
let { NotificationBox, PriorityLevels } =
this.browserRequire(
"devtools/client/shared/components/notification-box");
"devtools/client/shared/components/NotificationBox");
NotificationBox = this.React.createFactory(NotificationBox);

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

@ -4,7 +4,7 @@
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/toolbox.css" type="text/css"?>
<?xml-stylesheet href="resource://devtools/client/shared/components/notification-box.css" type="text/css"?>
<?xml-stylesheet href="resource://devtools/client/shared/components/NotificationBox.css" type="text/css"?>
<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>

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

@ -12,7 +12,7 @@ const {
const { REPS, MODE } = require("devtools/client/shared/components/reps/reps");
const { Rep } = REPS;
const TreeViewClass = require("devtools/client/shared/components/tree/tree-view");
const TreeViewClass = require("devtools/client/shared/components/tree/TreeView");
const TreeView = createFactory(TreeViewClass);
/**

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

@ -8,7 +8,7 @@ const { addons, createClass, createFactory, DOM: dom, PropTypes } =
require("devtools/client/shared/vendor/react");
const { connect } = require("devtools/client/shared/vendor/react-redux");
const SearchBox = createFactory(require("devtools/client/shared/components/search-box"));
const SearchBox = createFactory(require("devtools/client/shared/components/SearchBox"));
const FontList = createFactory(require("./FontList"));
const { getStr } = require("../utils/l10n");

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

@ -487,7 +487,7 @@ Inspector.prototype = {
*/
setupSplitter: function () {
let SplitBox = this.React.createFactory(this.browserRequire(
"devtools/client/shared/components/splitter/split-box"));
"devtools/client/shared/components/splitter/SplitBox"));
let { width, height } = this.getSidebarSize();
let splitter = SplitBox({

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

@ -16,13 +16,13 @@
<link rel="stylesheet" href="chrome://devtools/skin/boxmodel.css"/>
<link rel="stylesheet" href="chrome://devtools/skin/layout.css"/>
<link rel="stylesheet" href="chrome://devtools/skin/animationinspector.css"/>
<link rel="stylesheet" href="resource://devtools/client/shared/components/tabs/tabs.css"/>
<link rel="stylesheet" href="resource://devtools/client/shared/components/tabs/tabbar.css"/>
<link rel="stylesheet" href="resource://devtools/client/shared/components/tabs/Tabs.css"/>
<link rel="stylesheet" href="resource://devtools/client/shared/components/tabs/TabBar.css"/>
<link rel="stylesheet" href="resource://devtools/client/inspector/components/InspectorTabPanel.css"/>
<link rel="stylesheet" href="resource://devtools/client/shared/components/splitter/split-box.css"/>
<link rel="stylesheet" href="resource://devtools/client/shared/components/splitter/SplitBox.css"/>
<link rel="stylesheet" href="resource://devtools/client/inspector/layout/components/Accordion.css"/>
<link rel="stylesheet" href="resource://devtools/client/shared/components/reps/reps.css"/>
<link rel="stylesheet" href="resource://devtools/client/shared/components/tree/tree-view.css"/>
<link rel="stylesheet" href="resource://devtools/client/shared/components/tree/TreeView.css"/>
<script type="application/javascript"
src="chrome://devtools/content/shared/theme-switching.js"></script>

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

@ -73,7 +73,7 @@ ToolSidebar.prototype = {
render: function () {
let Tabbar = this.React.createFactory(this.browserRequire(
"devtools/client/shared/components/tabs/tabbar"));
"devtools/client/shared/components/tabs/TabBar"));
let sidebar = Tabbar({
menuDocument: this._toolPanel._toolbox.doc,

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

@ -8,7 +8,7 @@
define(function (require, exports, module) {
const { DOM: dom, createFactory, createClass, PropTypes } = require("devtools/client/shared/vendor/react");
const TreeViewClass = require("devtools/client/shared/components/tree/tree-view");
const TreeViewClass = require("devtools/client/shared/components/tree/TreeView");
const TreeView = createFactory(TreeViewClass);
const { REPS, MODE } = require("devtools/client/shared/components/reps/reps");

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

@ -13,7 +13,7 @@ define(function (require, exports, module) {
const { JsonPanel } = createFactories(require("./json-panel"));
const { TextPanel } = createFactories(require("./text-panel"));
const { HeadersPanel } = createFactories(require("./headers-panel"));
const { Tabs, TabPanel } = createFactories(require("devtools/client/shared/components/tabs/tabs"));
const { Tabs, TabPanel } = createFactories(require("devtools/client/shared/components/tabs/Tabs"));
/**
* This object represents the root application template

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

@ -7,8 +7,8 @@
@import "resource://devtools/client/themes/common.css";
@import "resource://devtools/client/themes/toolbars.css";
@import "resource://devtools/client/shared/components/tree/tree-view.css";
@import "resource://devtools/client/shared/components/tabs/tabs.css";
@import "resource://devtools/client/shared/components/tree/TreeView.css";
@import "resource://devtools/client/shared/components/tabs/Tabs.css";
@import "general.css";
@import "search-box.css";

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

@ -11,7 +11,7 @@ const {
PropTypes
} = require("devtools/client/shared/vendor/react");
const { L10N, formatNumber, formatPercent } = require("../utils");
const Frame = createFactory(require("devtools/client/shared/components/frame"));
const Frame = createFactory(require("devtools/client/shared/components/Frame"));
const { TREE_ROW_HEIGHT } = require("../constants");
const models = require("../models");

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

@ -5,7 +5,7 @@
"use strict";
const { createClass, PropTypes, createFactory } = require("devtools/client/shared/vendor/react");
const Tree = createFactory(require("devtools/client/shared/components/tree"));
const Tree = createFactory(require("devtools/client/shared/components/Tree"));
const CensusTreeItem = createFactory(require("./census-tree-item"));
const { TREE_ROW_HEIGHT } = require("../constants");
const { censusModel, diffingModel } = require("../models");

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

@ -7,7 +7,7 @@
const { assert, isSavedFrame } = require("devtools/shared/DevToolsUtils");
const { DOM: dom, createClass, createFactory, PropTypes } = require("devtools/client/shared/vendor/react");
const { L10N, formatNumber, formatPercent } = require("../utils");
const Frame = createFactory(require("devtools/client/shared/components/frame"));
const Frame = createFactory(require("devtools/client/shared/components/Frame"));
const { TREE_ROW_HEIGHT } = require("../constants");
const Separator = createFactory(createClass({

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

@ -7,7 +7,7 @@
const { DOM: dom, createClass, PropTypes, createFactory } = require("devtools/client/shared/vendor/react");
const { assert } = require("devtools/shared/DevToolsUtils");
const { createParentMap } = require("devtools/shared/heapsnapshot/CensusUtils");
const Tree = createFactory(require("devtools/client/shared/components/tree"));
const Tree = createFactory(require("devtools/client/shared/components/Tree"));
const DominatorTreeItem = createFactory(require("./dominator-tree-item"));
const { L10N } = require("../utils");
const { TREE_ROW_HEIGHT, dominatorTreeState } = require("../constants");

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

@ -11,7 +11,7 @@ const CensusHeader = createFactory(require("./census-header"));
const DominatorTree = createFactory(require("./dominator-tree"));
const DominatorTreeHeader = createFactory(require("./dominator-tree-header"));
const TreeMap = createFactory(require("./tree-map"));
const HSplitBox = createFactory(require("devtools/client/shared/components/h-split-box"));
const HSplitBox = createFactory(require("devtools/client/shared/components/HSplitBox"));
const Individuals = createFactory(require("./individuals"));
const IndividualsHeader = createFactory(require("./individuals-header"));
const ShortestPaths = createFactory(require("./shortest-paths"));

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

@ -5,7 +5,7 @@
"use strict";
const { createClass, PropTypes, createFactory } = require("devtools/client/shared/vendor/react");
const Tree = createFactory(require("devtools/client/shared/components/tree"));
const Tree = createFactory(require("devtools/client/shared/components/Tree"));
const DominatorTreeItem = createFactory(require("./dominator-tree-item"));
const { TREE_ROW_HEIGHT } = require("../constants");
const models = require("../models");

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

@ -4,10 +4,10 @@
@import "chrome://devtools/skin/widgets.css";
@import "resource://devtools/client/themes/light-theme.css";
@import "resource://devtools/client/shared/components/splitter/split-box.css";
@import "resource://devtools/client/shared/components/tree/tree-view.css";
@import "resource://devtools/client/shared/components/tabs/tabs.css";
@import "resource://devtools/client/shared/components/tabs/tabbar.css";
@import "resource://devtools/client/shared/components/splitter/SplitBox.css";
@import "resource://devtools/client/shared/components/tree/TreeView.css";
@import "resource://devtools/client/shared/components/tabs/Tabs.css";
@import "resource://devtools/client/shared/components/tabs/TabBar.css";
@import "chrome://devtools/skin/components-frame.css";
@import "chrome://devtools/content/sourceeditor/codemirror/lib/codemirror.css";
@import "chrome://devtools/content/sourceeditor/codemirror/addon/dialog/dialog.css";

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

@ -19,7 +19,7 @@ const { getFormDataSections } = require("../utils/request-utils");
const { getSelectedRequest } = require("../selectors/index");
// Components
const SplitBox = createFactory(require("devtools/client/shared/components/splitter/split-box"));
const SplitBox = createFactory(require("devtools/client/shared/components/splitter/SplitBox"));
const NetworkDetailsPanel = createFactory(require("./network-details-panel"));
const RequestList = createFactory(require("./request-list"));
const Toolbar = createFactory(require("./toolbar"));

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

@ -19,10 +19,10 @@ const { Rep } = REPS;
const { FILTER_SEARCH_DELAY } = require("../constants");
// Components
const SearchBox = createFactory(require("devtools/client/shared/components/search-box"));
const TreeViewClass = require("devtools/client/shared/components/tree/tree-view");
const SearchBox = createFactory(require("devtools/client/shared/components/SearchBox"));
const TreeViewClass = require("devtools/client/shared/components/tree/TreeView");
const TreeView = createFactory(TreeViewClass);
const TreeRow = createFactory(require("devtools/client/shared/components/tree/tree-row"));
const TreeRow = createFactory(require("devtools/client/shared/components/tree/TreeRow"));
const SourceEditor = createFactory(require("./source-editor"));
const { div, tr, td } = DOM;

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

@ -13,7 +13,7 @@ const { L10N } = require("../utils/l10n");
const { getUrlHost } = require("../utils/request-utils");
// Components
const TreeViewClass = require("devtools/client/shared/components/tree/tree-view");
const TreeViewClass = require("devtools/client/shared/components/tree/TreeView");
const PropertiesView = createFactory(require("./properties-view"));
const { div, input, span } = DOM;

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

@ -14,7 +14,7 @@ const { viewSourceInDebugger } = require("../connector/index");
const { div } = DOM;
// Components
const StackTrace = createFactory(require("devtools/client/shared/components/stack-trace"));
const StackTrace = createFactory(require("devtools/client/shared/components/StackTrace"));
function StackTracePanel({
openLink,

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

@ -13,8 +13,8 @@ const { L10N } = require("../utils/l10n");
const { PANELS } = require("../constants");
// Components
const Tabbar = createFactory(require("devtools/client/shared/components/tabs/tabbar"));
const TabPanel = createFactory(require("devtools/client/shared/components/tabs/tabs").TabPanel);
const Tabbar = createFactory(require("devtools/client/shared/components/tabs/TabBar"));
const TabPanel = createFactory(require("devtools/client/shared/components/tabs/Tabs").TabPanel);
const CookiesPanel = createFactory(require("./cookies-panel"));
const HeadersPanel = createFactory(require("./headers-panel"));
const ParamsPanel = createFactory(require("./params-panel"));

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

@ -25,7 +25,7 @@ const { autocompleteProvider } = require("../utils/filter-autocomplete-provider"
const { L10N } = require("../utils/l10n");
// Components
const SearchBox = createFactory(require("devtools/client/shared/components/search-box"));
const SearchBox = createFactory(require("devtools/client/shared/components/SearchBox"));
const { button, div, input, label, span } = DOM;

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

@ -9,7 +9,7 @@ const L10N = new LocalizationHelper(STRINGS_URI);
const {PluralForm} = require("devtools/shared/plural-form");
const { DOM: dom, PropTypes, createClass, createFactory } = require("devtools/client/shared/vendor/react");
const Frame = createFactory(require("devtools/client/shared/components/frame"));
const Frame = createFactory(require("devtools/client/shared/components/Frame"));
const PROPNAME_MAX_LENGTH = 4;
// If TREE_ROW_HEIGHT changes, be sure to change `var(--jit-tree-row-height)`
// in `devtools/client/themes/jit-optimizations.css`

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

@ -9,9 +9,9 @@ const L10N = new LocalizationHelper(STRINGS_URI);
const { assert } = require("devtools/shared/DevToolsUtils");
const { DOM: dom, createClass, createFactory, PropTypes } = require("devtools/client/shared/vendor/react");
const Tree = createFactory(require("../../shared/components/tree"));
const Tree = createFactory(require("../../shared/components/Tree"));
const OptimizationsItem = createFactory(require("./jit-optimizations-item"));
const FrameView = createFactory(require("../../shared/components/frame"));
const FrameView = createFactory(require("../../shared/components/Frame"));
const JIT_TITLE = L10N.getStr("jit.title");
// If TREE_ROW_HEIGHT changes, be sure to change `var(--jit-tree-row-height)`
// in `devtools/client/themes/jit-optimizations.css`

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

@ -4,7 +4,7 @@
"use strict";
const { createClass, createFactory, PropTypes } = require("devtools/client/shared/vendor/react");
const Tree = createFactory(require("devtools/client/shared/components/tree"));
const Tree = createFactory(require("devtools/client/shared/components/Tree"));
const WaterfallTreeRow = createFactory(require("./waterfall-tree-row"));
// Keep in sync with var(--waterfall-tree-row-height) in performance.css

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

@ -8,7 +8,7 @@
const { DOM: dom, createClass, PropTypes, createFactory } = require("devtools/client/shared/vendor/react");
const KeyShortcuts = require("devtools/client/shared/key-shortcuts");
const AutocompletePopup = createFactory(require("devtools/client/shared/components/autocomplete-popup"));
const AutocompletePopup = createFactory(require("devtools/client/shared/components/AutoCompletePopup"));
/**
* A generic search box component for use across devtools

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

@ -7,7 +7,7 @@
const React = require("devtools/client/shared/vendor/react");
const { DOM: dom, createClass, createFactory, PropTypes } = React;
const { LocalizationHelper } = require("devtools/shared/l10n");
const Frame = createFactory(require("./frame"));
const Frame = createFactory(require("./Frame"));
const l10n = new LocalizationHelper("devtools/client/locales/webconsole.properties");

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

@ -12,16 +12,16 @@ DIRS += [
]
DevToolsModules(
'autocomplete-popup.js',
'frame.js',
'h-split-box.js',
'notification-box.css',
'notification-box.js',
'search-box.js',
'sidebar-toggle.css',
'sidebar-toggle.js',
'stack-trace.js',
'tree.js',
'AutoCompletePopup.js',
'Frame.js',
'HSplitBox.js',
'NotificationBox.css',
'NotificationBox.js',
'SearchBox.js',
'SidebarToggle.css',
'SidebarToggle.js',
'StackTrace.js',
'Tree.js',
)
MOCHITEST_CHROME_MANIFESTS += ['test/mochitest/chrome.ini']

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

@ -6,7 +6,7 @@
const React = require("devtools/client/shared/vendor/react");
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
const Draggable = React.createFactory(require("devtools/client/shared/components/splitter/draggable"));
const Draggable = React.createFactory(require("devtools/client/shared/components/splitter/Draggable"));
const { DOM: dom, PropTypes } = React;
/**

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

@ -5,7 +5,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
'draggable.js',
'split-box.css',
'split-box.js',
'Draggable.js',
'SplitBox.css',
'SplitBox.js',
)

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

@ -9,7 +9,7 @@
"use strict";
const { DOM, createClass, PropTypes, createFactory } = require("devtools/client/shared/vendor/react");
const Tabs = createFactory(require("devtools/client/shared/components/tabs/tabs").Tabs);
const Tabs = createFactory(require("devtools/client/shared/components/tabs/Tabs").Tabs);
const Menu = require("devtools/client/framework/menu");
const MenuItem = require("devtools/client/framework/menu-item");

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