mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-10 02:08:38 +09:00
Remove about:home snippets.
This commit is contained in:
parent
b79a4ce07d
commit
5934916122
6 changed files with 5 additions and 380 deletions
|
|
@ -229,11 +229,6 @@ pref("browser.slowStartup.notificationDisabled", false);
|
|||
pref("browser.slowStartup.timeThreshold", 40000);
|
||||
pref("browser.slowStartup.maxSamples", 5);
|
||||
|
||||
// This url, if changed, MUST continue to point to an https url. Pulling arbitrary content to inject into
|
||||
// this page over http opens us up to a man-in-the-middle attack that we'd rather not face. If you are a downstream
|
||||
// repackager of this code using an alternate snippet url, please keep your users safe
|
||||
pref("browser.aboutHomeSnippets.updateUrl", "https://snippets.cdn.mozilla.net/%STARTPAGE_VERSION%/%NAME%/%VERSION%/%APPBUILDID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/");
|
||||
|
||||
pref("browser.enable_automatic_image_resizing", true);
|
||||
pref("browser.casting.enabled", false);
|
||||
pref("browser.chrome.site_icons", true);
|
||||
|
|
|
|||
|
|
@ -49,8 +49,7 @@ a {
|
|||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
#searchIconAndTextContainer,
|
||||
#snippets {
|
||||
#searchIconAndTextContainer {
|
||||
width: 470px;
|
||||
}
|
||||
|
||||
|
|
@ -168,48 +167,6 @@ a {
|
|||
transition-duration: 0ms;
|
||||
}
|
||||
|
||||
#defaultSnippet1,
|
||||
#defaultSnippet2,
|
||||
#rightsSnippet {
|
||||
display: block;
|
||||
min-height: 38px;
|
||||
background: 0 center no-repeat;
|
||||
padding: 6px 0;
|
||||
padding-inline-start: 49px;
|
||||
}
|
||||
|
||||
#rightsSnippet[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#defaultSnippet1:dir(rtl),
|
||||
#defaultSnippet2:dir(rtl),
|
||||
#rightsSnippet:dir(rtl) {
|
||||
background-position: right 0 center;
|
||||
}
|
||||
|
||||
#defaultSnippet1 {
|
||||
background-image: url("chrome://browser/content/abouthome/snippet1.png");
|
||||
}
|
||||
|
||||
#defaultSnippet2 {
|
||||
background-image: url("chrome://browser/content/abouthome/snippet2.png");
|
||||
}
|
||||
|
||||
#snippets {
|
||||
display: inline-block;
|
||||
text-align: start;
|
||||
margin: 12px 0;
|
||||
color: #3c3c3c;
|
||||
font-size: 75%;
|
||||
/* 12px is the computed font size, 15px the computed line height of the snippets
|
||||
with Segoe UI on a default Windows 7 setup. The 15/12 multiplier approximately
|
||||
converts em from units of font-size to units of line-height. The goal is to
|
||||
preset the height of a three-line snippet to avoid visual moving/flickering as
|
||||
the snippets load. */
|
||||
min-height: calc(15/12 * 3em);
|
||||
}
|
||||
|
||||
#launcher {
|
||||
display: -moz-box;
|
||||
-moz-box-align: center;
|
||||
|
|
@ -385,20 +342,6 @@ body[narrow] #restorePreviousSession::before {
|
|||
background-image: url("chrome://branding/content/about-logo@2x.png");
|
||||
}
|
||||
|
||||
#defaultSnippet1,
|
||||
#defaultSnippet2,
|
||||
#rightsSnippet {
|
||||
background-size: 40px;
|
||||
}
|
||||
|
||||
#defaultSnippet1 {
|
||||
background-image: url("chrome://browser/content/abouthome/snippet1@2x.png");
|
||||
}
|
||||
|
||||
#defaultSnippet2 {
|
||||
background-image: url("chrome://browser/content/abouthome/snippet2@2x.png");
|
||||
}
|
||||
|
||||
.launchButton::before,
|
||||
#aboutMozilla::before {
|
||||
transform: scale(.5);
|
||||
|
|
|
|||
|
|
@ -6,23 +6,10 @@
|
|||
|
||||
/* import-globals-from ../contentSearchUI.js */
|
||||
|
||||
// The process of adding a new default snippet involves:
|
||||
// * add a new entity to aboutHome.dtd
|
||||
// * add a <span/> for it in aboutHome.xhtml
|
||||
// * add an entry here in the proper ordering (based on spans)
|
||||
// The <a/> part of the snippet will be linked to the corresponding url.
|
||||
const DEFAULT_SNIPPETS_URLS = [
|
||||
"https://www.mozilla.org/firefox/features/?utm_source=snippet&utm_medium=snippet&utm_campaign=default+feature+snippet"
|
||||
, "https://addons.mozilla.org/firefox/?utm_source=snippet&utm_medium=snippet&utm_campaign=addons"
|
||||
];
|
||||
|
||||
const SNIPPETS_UPDATE_INTERVAL_MS = 14400000; // 4 hours.
|
||||
|
||||
// IndexedDB storage constants.
|
||||
const DATABASE_NAME = "abouthome";
|
||||
const DATABASE_VERSION = 1;
|
||||
const DATABASE_STORAGE = "persistent";
|
||||
const SNIPPETS_OBJECTSTORE_NAME = "snippets";
|
||||
var searchText;
|
||||
|
||||
// This global tracks if the page has been set up before, to prevent double inits
|
||||
|
|
@ -33,13 +20,6 @@ var gObserver = new MutationObserver(function (mutations) {
|
|||
if (mutation.attributeName == "session") {
|
||||
fitToWidth();
|
||||
}
|
||||
if (mutation.attributeName == "snippetsVersion") {
|
||||
if (!gInitialized) {
|
||||
ensureSnippetsMapThen(loadSnippets);
|
||||
gInitialized = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -90,126 +70,6 @@ window.addEventListener("keypress", ev => {
|
|||
searchText.value += ev.key;
|
||||
});
|
||||
|
||||
// This object has the same interface as Map and is used to store and retrieve
|
||||
// the snippets data. It is lazily initialized by ensureSnippetsMapThen(), so
|
||||
// be sure its callback returned before trying to use it.
|
||||
var gSnippetsMap;
|
||||
var gSnippetsMapCallbacks = [];
|
||||
|
||||
/**
|
||||
* Ensure the snippets map is properly initialized.
|
||||
*
|
||||
* @param aCallback
|
||||
* Invoked once the map has been initialized, gets the map as argument.
|
||||
* @note Snippets should never directly manage the underlying storage, since
|
||||
* it may change inadvertently.
|
||||
*/
|
||||
function ensureSnippetsMapThen(aCallback)
|
||||
{
|
||||
if (gSnippetsMap) {
|
||||
aCallback(gSnippetsMap);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle multiple requests during the async initialization.
|
||||
gSnippetsMapCallbacks.push(aCallback);
|
||||
if (gSnippetsMapCallbacks.length > 1) {
|
||||
// We are already updating, the callbacks will be invoked when done.
|
||||
return;
|
||||
}
|
||||
|
||||
let invokeCallbacks = function () {
|
||||
if (!gSnippetsMap) {
|
||||
gSnippetsMap = Object.freeze(new Map());
|
||||
}
|
||||
|
||||
for (let callback of gSnippetsMapCallbacks) {
|
||||
callback(gSnippetsMap);
|
||||
}
|
||||
gSnippetsMapCallbacks.length = 0;
|
||||
}
|
||||
|
||||
let openRequest = indexedDB.open(DATABASE_NAME, {version: DATABASE_VERSION,
|
||||
storage: DATABASE_STORAGE});
|
||||
|
||||
openRequest.onerror = function (event) {
|
||||
// Try to delete the old database so that we can start this process over
|
||||
// next time.
|
||||
indexedDB.deleteDatabase(DATABASE_NAME);
|
||||
invokeCallbacks();
|
||||
};
|
||||
|
||||
openRequest.onupgradeneeded = function (event) {
|
||||
let db = event.target.result;
|
||||
if (!db.objectStoreNames.contains(SNIPPETS_OBJECTSTORE_NAME)) {
|
||||
db.createObjectStore(SNIPPETS_OBJECTSTORE_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
openRequest.onsuccess = function (event) {
|
||||
let db = event.target.result;
|
||||
|
||||
db.onerror = function (event) {
|
||||
invokeCallbacks();
|
||||
}
|
||||
|
||||
db.onversionchange = function (event) {
|
||||
event.target.close();
|
||||
invokeCallbacks();
|
||||
}
|
||||
|
||||
let cache = new Map();
|
||||
let cursorRequest;
|
||||
try {
|
||||
cursorRequest = db.transaction(SNIPPETS_OBJECTSTORE_NAME)
|
||||
.objectStore(SNIPPETS_OBJECTSTORE_NAME).openCursor();
|
||||
} catch (ex) {
|
||||
console.error(ex);
|
||||
invokeCallbacks();
|
||||
return;
|
||||
}
|
||||
|
||||
cursorRequest.onerror = function (event) {
|
||||
invokeCallbacks();
|
||||
}
|
||||
|
||||
cursorRequest.onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
|
||||
// Populate the cache from the persistent storage.
|
||||
if (cursor) {
|
||||
cache.set(cursor.key, cursor.value);
|
||||
cursor.continue();
|
||||
return;
|
||||
}
|
||||
|
||||
// The cache has been filled up, create the snippets map.
|
||||
gSnippetsMap = Object.freeze({
|
||||
get: (aKey) => cache.get(aKey),
|
||||
set: function (aKey, aValue) {
|
||||
db.transaction(SNIPPETS_OBJECTSTORE_NAME, "readwrite")
|
||||
.objectStore(SNIPPETS_OBJECTSTORE_NAME).put(aValue, aKey);
|
||||
return cache.set(aKey, aValue);
|
||||
},
|
||||
has: (aKey) => cache.has(aKey),
|
||||
delete: function (aKey) {
|
||||
db.transaction(SNIPPETS_OBJECTSTORE_NAME, "readwrite")
|
||||
.objectStore(SNIPPETS_OBJECTSTORE_NAME).delete(aKey);
|
||||
return cache.delete(aKey);
|
||||
},
|
||||
clear: function () {
|
||||
db.transaction(SNIPPETS_OBJECTSTORE_NAME, "readwrite")
|
||||
.objectStore(SNIPPETS_OBJECTSTORE_NAME).clear();
|
||||
return cache.clear();
|
||||
},
|
||||
get size() { return cache.size; },
|
||||
});
|
||||
|
||||
setTimeout(invokeCallbacks, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onSearchSubmit(aEvent)
|
||||
{
|
||||
gContentSearchController.search(aEvent);
|
||||
|
|
@ -246,146 +106,6 @@ function setupSearch()
|
|||
*/
|
||||
function loadCompleted()
|
||||
{
|
||||
var event = new CustomEvent("AboutHomeLoadSnippetsCompleted", {bubbles:true});
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the local snippets from the remote storage, then show them through
|
||||
* showSnippets.
|
||||
*/
|
||||
function loadSnippets()
|
||||
{
|
||||
if (!gSnippetsMap)
|
||||
throw new Error("Snippets map has not properly been initialized");
|
||||
|
||||
// Allow tests to modify the snippets map before using it.
|
||||
var event = new CustomEvent("AboutHomeLoadSnippets", {bubbles:true});
|
||||
document.dispatchEvent(event);
|
||||
|
||||
// Check cached snippets version.
|
||||
let cachedVersion = gSnippetsMap.get("snippets-cached-version") || 0;
|
||||
let currentVersion = document.documentElement.getAttribute("snippetsVersion");
|
||||
if (cachedVersion < currentVersion) {
|
||||
// The cached snippets are old and unsupported, restart from scratch.
|
||||
gSnippetsMap.clear();
|
||||
}
|
||||
|
||||
// Check last snippets update.
|
||||
let lastUpdate = gSnippetsMap.get("snippets-last-update");
|
||||
let updateURL = document.documentElement.getAttribute("snippetsURL");
|
||||
let shouldUpdate = !lastUpdate ||
|
||||
Date.now() - lastUpdate > SNIPPETS_UPDATE_INTERVAL_MS;
|
||||
if (updateURL && shouldUpdate) {
|
||||
// Try to update from network.
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.timeout = 5000;
|
||||
// Even if fetching should fail we don't want to spam the server, thus
|
||||
// set the last update time regardless its results. Will retry tomorrow.
|
||||
gSnippetsMap.set("snippets-last-update", Date.now());
|
||||
xhr.onloadend = function (event) {
|
||||
if (xhr.status == 200) {
|
||||
gSnippetsMap.set("snippets", xhr.responseText);
|
||||
gSnippetsMap.set("snippets-cached-version", currentVersion);
|
||||
}
|
||||
showSnippets();
|
||||
loadCompleted();
|
||||
};
|
||||
try {
|
||||
xhr.open("GET", updateURL, true);
|
||||
xhr.send(null);
|
||||
} catch (ex) {
|
||||
showSnippets();
|
||||
loadCompleted();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
showSnippets();
|
||||
loadCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows locally cached remote snippets, or default ones when not available.
|
||||
*
|
||||
* @note: snippets should never invoke showSnippets(), or they may cause
|
||||
* a "too much recursion" exception.
|
||||
*/
|
||||
var _snippetsShown = false;
|
||||
function showSnippets()
|
||||
{
|
||||
let snippetsElt = document.getElementById("snippets");
|
||||
|
||||
// Show about:rights notification, if needed.
|
||||
let showRights = document.documentElement.getAttribute("showKnowYourRights");
|
||||
if (showRights) {
|
||||
let rightsElt = document.getElementById("rightsSnippet");
|
||||
let anchor = rightsElt.getElementsByTagName("a")[0];
|
||||
anchor.href = "about:rights";
|
||||
snippetsElt.appendChild(rightsElt);
|
||||
rightsElt.removeAttribute("hidden");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!gSnippetsMap)
|
||||
throw new Error("Snippets map has not properly been initialized");
|
||||
if (_snippetsShown) {
|
||||
// There's something wrong with the remote snippets, just in case fall back
|
||||
// to the default snippets.
|
||||
showDefaultSnippets();
|
||||
throw new Error("showSnippets should never be invoked multiple times");
|
||||
}
|
||||
_snippetsShown = true;
|
||||
|
||||
let snippets = gSnippetsMap.get("snippets");
|
||||
// If there are remotely fetched snippets, try to to show them.
|
||||
if (snippets) {
|
||||
// Injecting snippets can throw if they're invalid XML.
|
||||
try {
|
||||
snippetsElt.innerHTML = snippets;
|
||||
// Scripts injected by innerHTML are inactive, so we have to relocate them
|
||||
// through DOM manipulation to activate their contents.
|
||||
Array.forEach(snippetsElt.getElementsByTagName("script"), function(elt) {
|
||||
let relocatedScript = document.createElement("script");
|
||||
relocatedScript.type = "text/javascript;version=1.8";
|
||||
relocatedScript.text = elt.text;
|
||||
elt.parentNode.replaceChild(relocatedScript, elt);
|
||||
});
|
||||
return;
|
||||
} catch (ex) {
|
||||
// Bad content, continue to show default snippets.
|
||||
}
|
||||
}
|
||||
|
||||
showDefaultSnippets();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear snippets element contents and show default snippets.
|
||||
*/
|
||||
function showDefaultSnippets()
|
||||
{
|
||||
// Clear eventual contents...
|
||||
let snippetsElt = document.getElementById("snippets");
|
||||
snippetsElt.innerHTML = "";
|
||||
|
||||
// ...then show default snippets.
|
||||
let defaultSnippetsElt = document.getElementById("defaultSnippets");
|
||||
let entries = defaultSnippetsElt.querySelectorAll("span");
|
||||
// Choose a random snippet. Assume there is always at least one.
|
||||
let randIndex = Math.floor(Math.random() * entries.length);
|
||||
let entry = entries[randIndex];
|
||||
// Inject url in the eventual link.
|
||||
if (DEFAULT_SNIPPETS_URLS[randIndex]) {
|
||||
let links = entry.getElementsByTagName("a");
|
||||
// Default snippets can have only one link, otherwise something is messed
|
||||
// up in the translation.
|
||||
if (links.length == 1) {
|
||||
links[0].href = DEFAULT_SNIPPETS_URLS[randIndex];
|
||||
}
|
||||
}
|
||||
// Move the default snippet to the snippets element.
|
||||
snippetsElt.appendChild(entry);
|
||||
}
|
||||
|
||||
function fitToWidth() {
|
||||
|
|
|
|||
|
|
@ -46,15 +46,6 @@
|
|||
<input id="searchSubmit" type="button" onclick="onSearchSubmit(event)"
|
||||
title="&contentSearchSubmit.tooltip;"/>
|
||||
</div>
|
||||
|
||||
<div id="snippetContainer">
|
||||
<div id="defaultSnippets" hidden="true">
|
||||
<span id="defaultSnippet1">&abouthome.defaultSnippet1.v1;</span>
|
||||
<span id="defaultSnippet2">&abouthome.defaultSnippet2.v1;</span>
|
||||
</div>
|
||||
<span id="rightsSnippet" hidden="true">&abouthome.rightsSnippet;</span>
|
||||
<div id="snippets"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="spacer"/>
|
||||
|
||||
|
|
@ -73,7 +64,5 @@
|
|||
<button class="launchButton" id="restorePreviousSession">&historyRestoreLastSession.label;</button>
|
||||
</div>
|
||||
|
||||
<a id="aboutMozilla" href="https://www.mozilla.org/about/?utm_source=about-home&utm_medium=Referral"
|
||||
aria-label="&abouthome.aboutMozilla.label;"/>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -147,13 +147,10 @@ var AboutHomeListener = {
|
|||
if (aData.showRestoreLastSession && !PrivateBrowsingUtils.isContentWindowPrivate(content))
|
||||
doc.getElementById("launcher").setAttribute("session", "true");
|
||||
|
||||
// Inject search engine and snippets URL.
|
||||
// Inject search engine URL.
|
||||
let docElt = doc.documentElement;
|
||||
// Set snippetsVersion last, which triggers to show the snippets when it's set.
|
||||
docElt.setAttribute("snippetsURL", aData.snippetsURL);
|
||||
if (aData.showKnowYourRights)
|
||||
docElt.setAttribute("showKnowYourRights", "true");
|
||||
docElt.setAttribute("snippetsVersion", aData.snippetsVersion);
|
||||
},
|
||||
|
||||
onPageLoad: function() {
|
||||
|
|
|
|||
|
|
@ -24,17 +24,10 @@ XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
|
|||
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
"resource://gre/modules/Promise.jsm");
|
||||
|
||||
// Url to fetch snippets, in the urlFormatter service format.
|
||||
const SNIPPETS_URL_PREF = "browser.aboutHomeSnippets.updateUrl";
|
||||
|
||||
// Should be bumped up if the snippets content format changes.
|
||||
const STARTPAGE_VERSION = 4;
|
||||
// Should be bumped up if any data content format changes.
|
||||
const STARTPAGE_VERSION = 5;
|
||||
|
||||
this.AboutHomeUtils = {
|
||||
get snippetsVersion() {
|
||||
return STARTPAGE_VERSION;
|
||||
},
|
||||
|
||||
/*
|
||||
* showKnowYourRights - Determines if the user should be shown the
|
||||
* about:rights notification. The notification should *not* be shown if
|
||||
|
|
@ -76,16 +69,6 @@ this.AboutHomeUtils = {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the URL to fetch snippets from, in the urlFormatter service format.
|
||||
*/
|
||||
XPCOMUtils.defineLazyGetter(AboutHomeUtils, "snippetsURL", function() {
|
||||
let updateURL = Services.prefs
|
||||
.getCharPref(SNIPPETS_URL_PREF)
|
||||
.replace("%STARTPAGE_VERSION%", STARTPAGE_VERSION);
|
||||
return Services.urlFormatter.formatURL(updateURL);
|
||||
});
|
||||
|
||||
/**
|
||||
* This code provides services to the about:home page. Whenever
|
||||
* about:home needs to do something chrome-privileged, it sends a
|
||||
|
|
@ -169,9 +152,7 @@ var AboutHome = {
|
|||
ss.promiseInitialized.then(function() {
|
||||
let data = {
|
||||
showRestoreLastSession: ss.canRestoreLastSession,
|
||||
snippetsURL: AboutHomeUtils.snippetsURL,
|
||||
showKnowYourRights: AboutHomeUtils.showKnowYourRights,
|
||||
snippetsVersion: AboutHomeUtils.snippetsVersion,
|
||||
showKnowYourRights: AboutHomeUtils.showKnowYourRights
|
||||
};
|
||||
|
||||
if (AboutHomeUtils.showKnowYourRights) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue