From c06b8691e3cc33682fe2b8b614ec36ce0aada079 Mon Sep 17 00:00:00 2001 From: janekptacijarabaci Date: Tue, 13 Feb 2018 16:57:41 +0100 Subject: Places - throws an error: 0x80004005 (NS_ERROR_FAILURE) [nsIEditor.transactionManager] Steps to reproduce: 1) The main menu: "Tools" - "Options" - "Privacy" - "History": [x] "Remember my browsing and download history" 2) The main menu: "History" - "Clear Recent History...": "Today"/"Everything" - "Browsing & Download History" - "OK" 3) Go to: "https://www.palemoon.org/" 4) The main menu: "History" - "Show All History" 5) Clicking right mouse button on an item "https://www.palemoon.org" in "History", clicking on "Delete This Page". 6) Clicking on "History": Throws an error in Browser Console: NS_ERROR_FAILURE: Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIEditor.transactionManager] editBookmarkOverlay.js:341 --- browser/base/content/browser-places.js | 33 +++++----- .../places/content/editBookmarkOverlay.js | 72 +++++++++++++++------- 2 files changed, 66 insertions(+), 39 deletions(-) (limited to 'browser') diff --git a/browser/base/content/browser-places.js b/browser/base/content/browser-places.js index 14e90cde2c..3a9fb9d96e 100644 --- a/browser/base/content/browser-places.js +++ b/browser/base/content/browser-places.js @@ -299,24 +299,23 @@ var StarUI = { parent.setAttribute("open", "true"); } } - let panel = this.panel; - let target = 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); - - gEditItemOverlay.initPanel({ node: aNode - , hiddenRows: ["description", "location", - "loadInSidebar", "keyword"] - , focusedElement: "preferred"}); + 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; } - }, true); + target.addEventListener("popupshown", function(event) { + fn(); + }, {"capture": true, "once": true}); + }; + gEditItemOverlay.initPanel({ node: aNode + , onPanelReady + , hiddenRows: ["description", "location", + "loadInSidebar", "keyword"] + , focusedElement: "preferred"}); this.panel.openPopup(aAnchorElement, aPosition); }), diff --git a/browser/components/places/content/editBookmarkOverlay.js b/browser/components/places/content/editBookmarkOverlay.js index e26cfb1387..d59f5c7643 100644 --- a/browser/components/places/content/editBookmarkOverlay.js +++ b/browser/components/places/content/editBookmarkOverlay.js @@ -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() { @@ -214,7 +216,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) => { @@ -286,22 +289,34 @@ var gEditItemOverlay = { this._observersAdded = true; } - // 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) - // * first: focus the first non collapsed textbox - // Note: since all controls are collapsed by default, we don't get the - // default XUL dialog behavior, that selects the first control, so we set - // the focus explicitly. - let elt; - if (focusedElement === "preferred") { - elt = this._element(gPrefService.getCharPref("browser.bookmarks.editDialog.firstEditField")); - } else if (focusedElement === "first") { - elt = document.querySelector("textbox:not([collapsed=true])"); - } - if (elt) { - elt.focus(); - elt.select(); + 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) + // * first: focus the first non collapsed textbox + // Note: since all controls are collapsed by default, we don't get the + // default XUL dialog behavior, that selects the first control, so we set + // the focus explicitly. + // Note: If focusedElement === "preferred", this file expects gPrefService + // to be defined in the global scope. + let elt; + if (focusedElement === "preferred") { + /* eslint-disable no-undef */ + elt = this._element(gPrefService.getCharPref("browser.bookmarks.editDialog.firstEditField")); + /* eslint-enable no-undef */ + } else if (focusedElement === "first") { + elt = document.querySelector("textbox:not([collapsed=true])"); + } + if (elt) { + elt.focus(); + elt.select(); + } + }; + + if (onPanelReady) { + onPanelReady(focusElement); + } else { + focusElement(); } }, @@ -335,10 +350,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(); + } } }, -- cgit v1.2.3