fune/toolkit/components/reader/Readerable.js
Kris Maglione 22d4bb0074 Bug 1484413: Split ReaderMode.jsm into separate checking and loading components. r=Gijs
Most of the ReaderMode.jsm and Readability.js code is only needed when we
actually need to render a document in reader mode, but also winds up loaded
into any process where we ever check if a page is readerable. This winds up
wasting a huge amount of memory (and probably a huge amount of CPU time)
loading code which is almost never used.

This patch splits ReaderMode.jsm into two modules, one for checking
readability, one for actually entering reader mode. It also separates out the
isProbablyReaderable checks from Readability.js, since the overhead of loading
that script before it's needed is unsupportable.

This means we're probably going to need some effort to keep Readerable.jsm and
Readability.js in sync, but the code in question is pretty trivial, so it
shouldn't be too difficult.

Differential Revision: https://phabricator.services.mozilla.com/D3687

--HG--
rename : toolkit/components/reader/Readability.js => toolkit/components/reader/Readability-readerable.js
rename : toolkit/components/reader/ReaderMode.jsm => toolkit/components/reader/Readerable.js
extra : rebase_source : 66712057591ae20dd66234e3dc78fbba90a6914e
extra : amend_source : f908f62f49ea54b9099ddb87d9f2fc11f12d4dee
2018-08-17 23:10:59 -07:00

79 lines
2.1 KiB
JavaScript

// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
// This file and Readability-readerable.js are merged together into
// Readerable.jsm.
/* exported Readerable */
/* import-globals-from Readability-readerable.js */
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
function isNodeVisible(node) {
return node.clientHeight > 0 && node.clientWidth > 0;
}
var Readerable = {
get isEnabledForParseOnLoad() {
return this.isEnabled || this.isForceEnabled;
},
/**
* Decides whether or not a document is reader-able without parsing the whole thing.
*
* @param doc A document to parse.
* @return boolean Whether or not we should show the reader mode button.
*/
isProbablyReaderable(doc) {
// Only care about 'real' HTML documents:
if (doc.mozSyntheticDocument || !(doc instanceof doc.defaultView.HTMLDocument)) {
return false;
}
let uri = Services.io.newURI(doc.location.href);
if (!this.shouldCheckUri(uri)) {
return false;
}
return isProbablyReaderable(doc, isNodeVisible);
},
_blockedHosts: [
"amazon.com",
"github.com",
"mail.google.com",
"pinterest.com",
"reddit.com",
"twitter.com",
"youtube.com",
],
shouldCheckUri(uri, isBaseUri = false) {
if (!["http", "https"].includes(uri.scheme)) {
return false;
}
if (!isBaseUri) {
// Sadly, some high-profile pages have false positives, so bail early for those:
let {host} = uri;
if (this._blockedHosts.some(blockedHost => host.endsWith(blockedHost))) {
return false;
}
if (uri.filePath == "/") {
return false;
}
}
return true;
},
};
XPCOMUtils.defineLazyPreferenceGetter(
Readerable, "isEnabled", "reader.parse-on-load.enabled", true);
XPCOMUtils.defineLazyPreferenceGetter(
Readerable, "isForceEnabled", "reader.parse-on-load.force-enabled", false);