Bug 1349823 - Populate bookmark panel before showing it r=enndeakin+6102,mak

When panel behavior became asynchronous, |StarUI._doShowEditBookmarkPanel| needed to be changed to wait for the panel to finish opening before initializing it. Although the content of the panel can be changed successfully before the panel opens, the element focus at the end of initialization fails. This prevents the capturing of certain events, such as an Esc keypress (which should close the panel).

However, this introduced the problem where there is a short delay between when the bookmark panel opens and when the correct content is displayed in it. To fix this, the initialization function |gEditItemOverlay.initPanel| will now be called before the panel opens, but the element focus code will wait for the panel's popupshown event.

MozReview-Commit-ID: 6SrcCz963qW

--HG--
extra : rebase_source : c45f16913597b336dcae2717c0f902dbbe8025f2
This commit is contained in:
Kirk Steuber 2017-04-05 15:38:37 -07:00
Родитель a5b280bf5b
Коммит 6d0283fc61
2 изменённых файлов: 66 добавлений и 43 удалений

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

@ -298,24 +298,23 @@ var StarUI = {
parent.setAttribute("open", "true");
}
}
let panel = this.panel;
let target = panel;
let onPanelReady = fn => {
let target = this.panel;
if (target.parentNode) {
// By targeting the panel's parent and using a capturing listener, we
// can have our listener called before others waiting for the panel to
// be shown (which probably expect the panel to be fully initialized)
target = target.parentNode;
}
target.addEventListener("popupshown", function shownListener(event) {
if (event.target == panel) {
target.removeEventListener("popupshown", shownListener, true);
target.addEventListener("popupshown", function(event) {
fn();
}, {"capture": true, "once": true});
};
gEditItemOverlay.initPanel({ node: aNode
, onPanelReady
, hiddenRows: ["description", "location",
"loadInSidebar", "keyword"]
, focusedElement: "preferred"});
}
}, true);
this.panel.openPopup(aAnchorElement, aPosition);
}),

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

@ -57,12 +57,14 @@ var gEditItemOverlay = {
}
}
let focusedElement = aInitInfo.focusedElement;
let onPanelReady = aInitInfo.onPanelReady;
return this._paneInfo = { itemId, itemGuid, isItem,
isURI, uri, title,
isBookmark, isFolderShortcut, isParentReadOnly,
bulkTagging, uris,
visibleRows, postData, isTag, focusedElement };
visibleRows, postData, isTag, focusedElement,
onPanelReady };
},
get initialized() {
@ -207,7 +209,8 @@ var gEditItemOverlay = {
let { itemId, isItem, isURI,
isBookmark, bulkTagging, uris,
visibleRows, focusedElement } = this._setPaneInfo(aInfo);
visibleRows, focusedElement,
onPanelReady } = this._setPaneInfo(aInfo);
let showOrCollapse =
(rowId, isAppropriateForInput, nameInHiddenRows = null) => {
@ -279,6 +282,7 @@ var gEditItemOverlay = {
this._observersAdded = true;
}
let focusElement = () => {
// The focusedElement possible values are:
// * preferred: focus the field that the user touched first the last
// time the pane was shown (either namePicker or tagsField)
@ -300,6 +304,13 @@ var gEditItemOverlay = {
elt.focus();
elt.select();
}
};
if (onPanelReady) {
onPanelReady(focusElement);
} else {
focusElement();
}
},
/**
@ -332,10 +343,23 @@ var gEditItemOverlay = {
if (aElement.value != aValue) {
aElement.value = aValue;
// Clear the undo stack
let editor = aElement.editor;
if (editor)
editor.transactionManager.clear();
// Clear the editor's undo stack
let transactionManager;
try {
transactionManager = aElement.editor.transactionManager;
} catch (e) {
// When retrieving the transaction manager, editor may be null resulting
// in a TypeError. Additionally, the transaction manager may not
// exist yet, which causes access to it to throw NS_ERROR_FAILURE.
// In either event, the transaction manager doesn't exist it, so we
// don't need to worry about clearing it.
if (!(e instanceof TypeError) && e.result != Cr.NS_ERROR_FAILURE) {
throw e;
}
}
if (transactionManager) {
transactionManager.clear();
}
}
},