mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-29 20:07:30 +09:00
Change Reader API to use events, remove messaging.
This commit is contained in:
parent
1c494e80a6
commit
f0af6dce04
4 changed files with 50 additions and 151 deletions
|
|
@ -307,7 +307,7 @@ var AboutReaderListener = {
|
||||||
if (content.document.body) {
|
if (content.document.body) {
|
||||||
// Update the toolbar icon to show the "reader active" icon.
|
// Update the toolbar icon to show the "reader active" icon.
|
||||||
sendAsyncMessage("Reader:UpdateReaderButton");
|
sendAsyncMessage("Reader:UpdateReaderButton");
|
||||||
new AboutReader(global, content, this._articlePromise);
|
new AboutReader(content, this._articlePromise);
|
||||||
this._articlePromise = null;
|
this._articlePromise = null;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,6 @@ const gStringBundle = Services.strings.createBundle("chrome://global/locale/abou
|
||||||
|
|
||||||
var ReaderParent = {
|
var ReaderParent = {
|
||||||
MESSAGES: [
|
MESSAGES: [
|
||||||
"Reader:ArticleGet",
|
|
||||||
"Reader:FaviconRequest",
|
|
||||||
"Reader:UpdateReaderButton",
|
"Reader:UpdateReaderButton",
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
@ -33,38 +31,6 @@ var ReaderParent = {
|
||||||
|
|
||||||
receiveMessage(message) {
|
receiveMessage(message) {
|
||||||
switch (message.name) {
|
switch (message.name) {
|
||||||
case "Reader:ArticleGet":
|
|
||||||
this._getArticle(message.data.url, message.target).then((article) => {
|
|
||||||
// Make sure the target browser is still alive before trying to send data back.
|
|
||||||
if (message.target.messageManager) {
|
|
||||||
message.target.messageManager.sendAsyncMessage("Reader:ArticleData", { article: article });
|
|
||||||
}
|
|
||||||
}, e => {
|
|
||||||
if (e && e.newURL) {
|
|
||||||
// Make sure the target browser is still alive before trying to send data back.
|
|
||||||
if (message.target.messageManager) {
|
|
||||||
message.target.messageManager.sendAsyncMessage("Reader:ArticleData", { newURL: e.newURL });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "Reader:FaviconRequest": {
|
|
||||||
if (message.target.messageManager) {
|
|
||||||
let faviconUrl = PlacesUtils.promiseFaviconLinkUrl(message.data.url);
|
|
||||||
faviconUrl.then(function onResolution(favicon) {
|
|
||||||
message.target.messageManager.sendAsyncMessage("Reader:FaviconReturn", {
|
|
||||||
url: message.data.url,
|
|
||||||
faviconUrl: favicon.path.replace(/^favicon:/, "")
|
|
||||||
});
|
|
||||||
},
|
|
||||||
function onRejection(reason) {
|
|
||||||
Cu.reportError("Error requesting favicon URL for about:reader content: " + reason);
|
|
||||||
}).catch(Cu.reportError);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "Reader:UpdateReaderButton": {
|
case "Reader:UpdateReaderButton": {
|
||||||
let browser = message.target;
|
let browser = message.target;
|
||||||
if (message.data && message.data.isArticle !== undefined) {
|
if (message.data && message.data.isArticle !== undefined) {
|
||||||
|
|
@ -132,24 +98,5 @@ var ReaderParent = {
|
||||||
let win = event.target.ownerGlobal;
|
let win = event.target.ownerGlobal;
|
||||||
let browser = win.gBrowser.selectedBrowser;
|
let browser = win.gBrowser.selectedBrowser;
|
||||||
browser.messageManager.sendAsyncMessage("Reader:ToggleReaderMode");
|
browser.messageManager.sendAsyncMessage("Reader:ToggleReaderMode");
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets an article for a given URL. This method will download and parse a document.
|
|
||||||
*
|
|
||||||
* @param url The article URL.
|
|
||||||
* @param browser The browser where the article is currently loaded.
|
|
||||||
* @return {Promise}
|
|
||||||
* @resolves JS object representing the article, or null if no article is found.
|
|
||||||
*/
|
|
||||||
async _getArticle(url, browser) {
|
|
||||||
return await ReaderMode.downloadAndParseDocument(url).catch(e => {
|
|
||||||
if (e && e.newURL) {
|
|
||||||
// Pass up the error so we can navigate the browser in question to the new URL:
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
Cu.reportError("Error downloading and parsing document: " + e);
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,7 @@ this.EXPORTED_SYMBOLS = ["NarrateControls"];
|
||||||
|
|
||||||
var gStrings = Services.strings.createBundle("chrome://global/locale/narrate.properties");
|
var gStrings = Services.strings.createBundle("chrome://global/locale/narrate.properties");
|
||||||
|
|
||||||
function NarrateControls(mm, win, languagePromise) {
|
function NarrateControls(win, languagePromise) {
|
||||||
this._mm = mm;
|
|
||||||
this._winRef = Cu.getWeakReference(win);
|
this._winRef = Cu.getWeakReference(win);
|
||||||
this._languagePromise = languagePromise;
|
this._languagePromise = languagePromise;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,11 @@ XPCOMUtils.defineLazyModuleGetter(this, "AsyncPrefs", "resource://gre/modules/As
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "NarrateControls", "resource://gre/modules/narrate/NarrateControls.jsm");
|
XPCOMUtils.defineLazyModuleGetter(this, "NarrateControls", "resource://gre/modules/narrate/NarrateControls.jsm");
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "Rect", "resource://gre/modules/Geometry.jsm");
|
XPCOMUtils.defineLazyModuleGetter(this, "Rect", "resource://gre/modules/Geometry.jsm");
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm", "resource://gre/modules/PluralForm.jsm");
|
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm", "resource://gre/modules/PluralForm.jsm");
|
||||||
|
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", "resource://gre/modules/PlacesUtils.jsm");
|
||||||
|
|
||||||
var gStrings = Services.strings.createBundle("chrome://global/locale/aboutReader.properties");
|
var gStrings = Services.strings.createBundle("chrome://global/locale/aboutReader.properties");
|
||||||
|
|
||||||
var AboutReader = function(mm, win, articlePromise) {
|
var AboutReader = function(win, articlePromise) {
|
||||||
let url = this._getOriginalUrl(win);
|
let url = this._getOriginalUrl(win);
|
||||||
if (!(url.startsWith("http://") || url.startsWith("https://"))) {
|
if (!(url.startsWith("http://") || url.startsWith("https://"))) {
|
||||||
let errorMsg = "Only http:// and https:// URLs can be loaded in about:reader.";
|
let errorMsg = "Only http:// and https:// URLs can be loaded in about:reader.";
|
||||||
|
|
@ -32,12 +33,6 @@ var AboutReader = function(mm, win, articlePromise) {
|
||||||
|
|
||||||
let doc = win.document;
|
let doc = win.document;
|
||||||
|
|
||||||
this._mm = mm;
|
|
||||||
this._mm.addMessageListener("Reader:CloseDropdown", this);
|
|
||||||
this._mm.addMessageListener("Reader:AddButton", this);
|
|
||||||
this._mm.addMessageListener("Reader:RemoveButton", this);
|
|
||||||
this._mm.addMessageListener("Reader:GetStoredArticleData", this);
|
|
||||||
|
|
||||||
this._docRef = Cu.getWeakReference(doc);
|
this._docRef = Cu.getWeakReference(doc);
|
||||||
this._winRef = Cu.getWeakReference(win);
|
this._winRef = Cu.getWeakReference(win);
|
||||||
this._innerWindowId = win.QueryInterface(Ci.nsIInterfaceRequestor)
|
this._innerWindowId = win.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||||
|
|
@ -70,6 +65,9 @@ var AboutReader = function(mm, win, articlePromise) {
|
||||||
win.addEventListener("scroll", this);
|
win.addEventListener("scroll", this);
|
||||||
win.addEventListener("resize", this);
|
win.addEventListener("resize", this);
|
||||||
|
|
||||||
|
win.addEventListener("AboutReaderAddButton", this, false, true);
|
||||||
|
win.addEventListener("AboutReaderRemoveButton", this, false, true);
|
||||||
|
|
||||||
Services.obs.addObserver(this, "inner-window-destroyed", false);
|
Services.obs.addObserver(this, "inner-window-destroyed", false);
|
||||||
|
|
||||||
doc.addEventListener("visibilitychange", this);
|
doc.addEventListener("visibilitychange", this);
|
||||||
|
|
@ -78,7 +76,8 @@ var AboutReader = function(mm, win, articlePromise) {
|
||||||
this._setupButton("close-button", this._onReaderClose.bind(this), "aboutReader.toolbar.close");
|
this._setupButton("close-button", this._onReaderClose.bind(this), "aboutReader.toolbar.close");
|
||||||
|
|
||||||
// we're ready for any external setup, send a signal for that.
|
// we're ready for any external setup, send a signal for that.
|
||||||
this._mm.sendAsyncMessage("Reader:OnSetup");
|
doc.dispatchEvent(
|
||||||
|
new win.CustomEvent("AboutReaderOnSetup", { bubbles: true, cancelable: false }));
|
||||||
|
|
||||||
let colorSchemeValues = JSON.parse(Services.prefs.getCharPref("reader.color_scheme.values"));
|
let colorSchemeValues = JSON.parse(Services.prefs.getCharPref("reader.color_scheme.values"));
|
||||||
let colorSchemeOptions = colorSchemeValues.map((value) => {
|
let colorSchemeOptions = colorSchemeValues.map((value) => {
|
||||||
|
|
@ -117,7 +116,7 @@ var AboutReader = function(mm, win, articlePromise) {
|
||||||
this._setupLineHeightButtons();
|
this._setupLineHeightButtons();
|
||||||
|
|
||||||
if (win.speechSynthesis && Services.prefs.getBoolPref("narrate.enabled")) {
|
if (win.speechSynthesis && Services.prefs.getBoolPref("narrate.enabled")) {
|
||||||
new NarrateControls(mm, win, this._languagePromise);
|
new NarrateControls(win, this._languagePromise);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._loadArticle();
|
this._loadArticle();
|
||||||
|
|
@ -189,48 +188,6 @@ AboutReader.prototype = {
|
||||||
return _viewId;
|
return _viewId;
|
||||||
},
|
},
|
||||||
|
|
||||||
receiveMessage (message) {
|
|
||||||
switch (message.name) {
|
|
||||||
// Triggered by Android user pressing BACK while the banner font-dropdown is open.
|
|
||||||
case "Reader:CloseDropdown": {
|
|
||||||
// Just close it.
|
|
||||||
this._closeDropdowns();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "Reader:AddButton": {
|
|
||||||
if (message.data.id && message.data.image &&
|
|
||||||
!this._doc.getElementById(message.data.id)) {
|
|
||||||
let btn = this._doc.createElement("button");
|
|
||||||
btn.setAttribute("class", "button " + message.data.id);
|
|
||||||
btn.setAttribute("style", "background-image: url('" + message.data.image + "')");
|
|
||||||
btn.setAttribute("id", message.data.id);
|
|
||||||
if (message.data.title)
|
|
||||||
btn.setAttribute("title", message.data.title);
|
|
||||||
if (message.data.text)
|
|
||||||
btn.textContent = message.data.text;
|
|
||||||
let tb = this._toolbarElement;
|
|
||||||
tb.appendChild(btn);
|
|
||||||
this._setupButton(message.data.id, button => {
|
|
||||||
this._mm.sendAsyncMessage("Reader:Clicked-" + button.getAttribute("id"), { article: this._article });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "Reader:RemoveButton": {
|
|
||||||
if (message.data.id) {
|
|
||||||
let btn = this._doc.getElementById(message.data.id);
|
|
||||||
if (btn)
|
|
||||||
btn.remove();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "Reader:GetStoredArticleData": {
|
|
||||||
this._mm.sendAsyncMessage("Reader:StoredArticleData", { article: this._article });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
handleEvent(aEvent) {
|
handleEvent(aEvent) {
|
||||||
if (!aEvent.isTrusted)
|
if (!aEvent.isTrusted)
|
||||||
return;
|
return;
|
||||||
|
|
@ -249,8 +206,6 @@ AboutReader.prototype = {
|
||||||
break;
|
break;
|
||||||
case "scroll":
|
case "scroll":
|
||||||
this._closeDropdowns(true);
|
this._closeDropdowns(true);
|
||||||
let isScrollingUp = this._scrollOffset > aEvent.pageY;
|
|
||||||
this._setSystemUIVisibility(isScrollingUp);
|
|
||||||
this._scrollOffset = aEvent.pageY;
|
this._scrollOffset = aEvent.pageY;
|
||||||
break;
|
break;
|
||||||
case "resize":
|
case "resize":
|
||||||
|
|
@ -275,13 +230,39 @@ AboutReader.prototype = {
|
||||||
case "pagehide":
|
case "pagehide":
|
||||||
// Close the Banners Font-dropdown, cleanup Android BackPressListener.
|
// Close the Banners Font-dropdown, cleanup Android BackPressListener.
|
||||||
this._closeDropdowns();
|
this._closeDropdowns();
|
||||||
|
|
||||||
this._mm.removeMessageListener("Reader:CloseDropdown", this);
|
|
||||||
this._mm.removeMessageListener("Reader:AddButton", this);
|
|
||||||
this._mm.removeMessageListener("Reader:RemoveButton", this);
|
|
||||||
this._mm.removeMessageListener("Reader:GetStoredArticleData", this);
|
|
||||||
this._windowUnloaded = true;
|
this._windowUnloaded = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "AboutReaderAddButton": {
|
||||||
|
if (aEvent.detail.id && aEvent.detail.image &&
|
||||||
|
!this._doc.getElementById(aEvent.detail.id)) {
|
||||||
|
let btn = this._doc.createElement("button");
|
||||||
|
btn.setAttribute("class", "button " + aEvent.detail.id);
|
||||||
|
btn.setAttribute("style", "background-image: url('" + aEvent.detail.image + "')");
|
||||||
|
btn.setAttribute("id", aEvent.detail.id);
|
||||||
|
if (aEvent.detail.title)
|
||||||
|
btn.setAttribute("title", aEvent.detail.title);
|
||||||
|
if (aEvent.detail.text)
|
||||||
|
btn.textContent = aEvent.detail.text;
|
||||||
|
let tb = this._toolbarElement;
|
||||||
|
tb.appendChild(btn);
|
||||||
|
this._setupButton(aEvent.detail.id, button => {
|
||||||
|
var data = { article: this._article };
|
||||||
|
this._doc.dispatchEvent(
|
||||||
|
new this._win.CustomEvent("AboutReaderButtonClicked-" + button.getAttribute("id"), {detail: data, bubbles: true, cancelable: false}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "AboutReaderRemoveButton": {
|
||||||
|
if (aEvent.detail.id) {
|
||||||
|
let btn = this._doc.getElementById(aEvent.detail.id);
|
||||||
|
if (btn)
|
||||||
|
btn.remove();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -291,15 +272,11 @@ AboutReader.prototype = {
|
||||||
}
|
}
|
||||||
|
|
||||||
Services.obs.removeObserver(this, "inner-window-destroyed");
|
Services.obs.removeObserver(this, "inner-window-destroyed");
|
||||||
|
|
||||||
this._mm.removeMessageListener("Reader:CloseDropdown", this);
|
|
||||||
this._mm.removeMessageListener("Reader:AddButton", this);
|
|
||||||
this._mm.removeMessageListener("Reader:RemoveButton", this);
|
|
||||||
this._windowUnloaded = true;
|
this._windowUnloaded = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onReaderClose() {
|
_onReaderClose() {
|
||||||
ReaderMode.leaveReaderMode(this._mm.docShell, this._win);
|
ReaderMode.leaveReaderMode(this._win.document.docShell, this._win);
|
||||||
},
|
},
|
||||||
|
|
||||||
_setFontSize(newFontSize) {
|
_setFontSize(newFontSize) {
|
||||||
|
|
@ -616,10 +593,6 @@ AboutReader.prototype = {
|
||||||
AsyncPrefs.set("reader.font_type", this._fontType);
|
AsyncPrefs.set("reader.font_type", this._fontType);
|
||||||
},
|
},
|
||||||
|
|
||||||
_setSystemUIVisibility(visible) {
|
|
||||||
this._mm.sendAsyncMessage("Reader:SystemUIVisibility", { visible: visible });
|
|
||||||
},
|
|
||||||
|
|
||||||
_setToolbarVisibility(visible) {
|
_setToolbarVisibility(visible) {
|
||||||
let tb = this._toolbarElement;
|
let tb = this._toolbarElement;
|
||||||
|
|
||||||
|
|
@ -673,30 +646,18 @@ AboutReader.prototype = {
|
||||||
},
|
},
|
||||||
|
|
||||||
_getArticle(url) {
|
_getArticle(url) {
|
||||||
// return new Promise((resolve, reject) => {
|
|
||||||
// let listener = (message) => {
|
|
||||||
// this._mm.removeMessageListener("Reader:ArticleData", listener);
|
|
||||||
// if (message.data.newURL) {
|
|
||||||
// reject({ newURL: message.data.newURL });
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// resolve(message.data.article);
|
|
||||||
// };
|
|
||||||
// this._mm.addMessageListener("Reader:ArticleData", listener);
|
|
||||||
// this._mm.sendAsyncMessage("Reader:ArticleGet", { url });
|
|
||||||
// });
|
|
||||||
//}
|
|
||||||
return ReaderMode.downloadAndParseDocument(url);
|
return ReaderMode.downloadAndParseDocument(url);
|
||||||
},
|
},
|
||||||
|
|
||||||
_requestFavicon() {
|
_requestFavicon() {
|
||||||
let handleFaviconReturn = (message) => {
|
let faviconUrl = PlacesUtils.promiseFaviconLinkUrl(this._article.url);
|
||||||
this._mm.removeMessageListener("Reader:FaviconReturn", handleFaviconReturn);
|
var self = this;
|
||||||
this._loadFavicon(message.data.url, message.data.faviconUrl);
|
faviconUrl.then(function onResolution(favicon) {
|
||||||
};
|
self._loadFavicon(self._article.url, favicon.path.replace(/^favicon:/, ""));
|
||||||
|
},
|
||||||
this._mm.addMessageListener("Reader:FaviconReturn", handleFaviconReturn);
|
function onRejection(reason) {
|
||||||
this._mm.sendAsyncMessage("Reader:FaviconRequest", { url: this._article.url });
|
Cu.reportError("Error requesting favicon URL for about:reader content: " + reason);
|
||||||
|
}).catch(Cu.reportError);
|
||||||
},
|
},
|
||||||
|
|
||||||
_loadFavicon(url, faviconUrl) {
|
_loadFavicon(url, faviconUrl) {
|
||||||
|
|
@ -996,10 +957,7 @@ AboutReader.prototype = {
|
||||||
}
|
}
|
||||||
|
|
||||||
this._closeDropdowns();
|
this._closeDropdowns();
|
||||||
|
|
||||||
// Trigger BackPressListener initialization in Android.
|
|
||||||
dropdown.classList.add("open");
|
dropdown.classList.add("open");
|
||||||
this._mm.sendAsyncMessage("Reader:DropdownOpened", this.viewId);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1017,11 +975,6 @@ AboutReader.prototype = {
|
||||||
for (let dropdown of openDropdowns) {
|
for (let dropdown of openDropdowns) {
|
||||||
dropdown.classList.remove("open");
|
dropdown.classList.remove("open");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trigger BackPressListener cleanup in Android.
|
|
||||||
if (openDropdowns.length) {
|
|
||||||
this._mm.sendAsyncMessage("Reader:DropdownClosed", this.viewId);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue