Commit 1e0b5f64 authored by Thomas Greiner's avatar Thomas Greiner

Issue 6743 - Deterministically assign actions to links in translations

parent 31b6b7bb
......@@ -33,31 +33,6 @@ function getDocLink(link, callback)
}, callback);
}
function setLinks(id, ...args)
{
const element = E(id);
if (!element)
{
return;
}
const links = element.getElementsByTagName("a");
for (let i = 0; i < links.length; i++)
{
if (typeof args[i] == "string")
{
links[i].href = args[i];
links[i].setAttribute("target", "_blank");
}
else if (typeof args[i] == "function")
{
links[i].href = "javascript:void(0);";
links[i].addEventListener("click", args[i], false);
}
}
}
function checkShareResource(url, callback)
{
browser.runtime.sendMessage({
......
......@@ -15,7 +15,7 @@
* along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
*/
/* globals checkShareResource, getDocLink, openSharePopup, setLinks, E */
/* globals checkShareResource, getDocLink, openSharePopup, E */
"use strict";
......@@ -47,12 +47,12 @@
getDocLink("acceptable_ads_criteria", (link) =>
{
setLinks("acceptable-ads-explanation", link, openFilters);
ext.i18n.setElementLinks("acceptable-ads-explanation", link, openFilters);
});
getDocLink("contribute", (link) =>
{
setLinks("share-headline", link);
ext.i18n.setElementLinks("share-headline", link);
});
browser.runtime.sendMessage({
......@@ -66,18 +66,18 @@
E("datacorrupted-warning").removeAttribute("hidden");
getDocLink("adblock_plus", (link) =>
{
setLinks("datacorrupted-reinstall", link);
ext.i18n.setElementLinks("datacorrupted-reinstall", link);
});
getDocLink("help_center", (link) =>
{
setLinks("datacorrupted-support", link);
ext.i18n.setElementLinks("datacorrupted-support", link);
});
}
// Show warning if filterlists settings were reinitialized
else if (issues.filterlistsReinitialized)
{
E("filterlistsReinitializedWarning").removeAttribute("hidden");
setLinks("filterlistsReinitializedWarning", openFilters);
ext.i18n.setElementLinks("filterlistsReinitializedWarning", openFilters);
}
});
......
......@@ -33,7 +33,61 @@ browser.runtime.sendMessage(
}
);
function assignAction(elements, action)
{
for (const element of elements)
{
switch (typeof action)
{
case "string":
element.href = action;
element.target = "_blank";
break;
case "function":
element.href = "#";
element.addEventListener("click", action);
break;
}
}
}
function* getRemainingLinks(parent)
{
const links = parent.querySelectorAll("a:not([data-i18n-index])");
for (const link of links)
{
yield link;
}
}
ext.i18n = {
setElementLinks(elementId, ...actions)
{
const element = document.getElementById(elementId);
const remainingLinks = getRemainingLinks(element);
for (let i = 0; i < actions.length; i++)
{
// Assign action to links with matching index
const links = element.querySelectorAll(`a[data-i18n-index='${i}']`);
if (links.length)
{
assignAction(links, actions[i]);
continue;
}
// Assign action to non-indexed link in the order they appear
// Note that this behavior is deprecated and only exists
// for backwards compatibility
// https://issues.adblockplus.org/ticket/6743
const link = remainingLinks.next();
if (link.done)
continue;
assignAction([link.value], actions[i]);
}
},
// Inserts i18n strings into matching elements. Any inner HTML already
// in the element is parsed as JSON and used as parameters to
// substitute into placeholders in the i18n message.
......@@ -41,16 +95,21 @@ ext.i18n = {
{
function processString(str, currentElement)
{
const match = /^(.*?)<(a|strong)>(.*?)<\/\2>(.*)$/.exec(str);
const match = /^(.*?)<(a|strong)(\d)?>(.*?)<\/\2\3>(.*)$/.exec(str);
if (match)
{
processString(match[1], currentElement);
const [, before, name, index, innerText, after] = match;
processString(before, currentElement);
const e = document.createElement(match[2]);
processString(match[3], e);
const e = document.createElement(name);
if (typeof index != "undefined")
{
e.dataset.i18nIndex = index;
}
processString(innerText, e);
currentElement.appendChild(e);
processString(match[4], currentElement);
processString(after, currentElement);
}
else
currentElement.appendChild(document.createTextNode(str));
......
......@@ -16,7 +16,7 @@
*/
/* globals checkShareResource, getDocLink, i18nFormatDateTime, openSharePopup,
setLinks, E */
E */
"use strict";
......@@ -29,7 +29,7 @@ let additionalSubscriptions = [];
const collections = Object.create(null);
const {getMessage} = browser.i18n;
const {setElementText} = ext.i18n;
const {setElementLinks, setElementText} = ext.i18n;
const customFilters = [];
const filterErrors = new Map([
["synchronize_invalid_url",
......@@ -922,7 +922,7 @@ function onDOMLoaded()
});
getDocLink("acceptable_ads_criteria", (link) =>
{
setLinks("enable-acceptable-ads-description", link);
setElementLinks("enable-acceptable-ads-description", link);
});
setElementText(E("tracking-warning-1"), "options_tracking_warning_1",
[getMessage("common_feature_privacy_title"),
......@@ -936,7 +936,7 @@ function onDOMLoaded()
});
getDocLink("adblock_plus_{browser}_dnt", url =>
{
setLinks("dnt", url);
setElementLinks("dnt", url);
});
// Whitelisted tab
......@@ -983,11 +983,11 @@ function onDOMLoaded()
// Help tab
getDocLink("adblock_plus_report_bug", (link) =>
{
setLinks("report-bug", link);
setElementLinks("report-bug", link);
});
getDocLink("{browser}_support", url =>
{
setLinks("visit-forum", url);
setElementLinks("visit-forum", url);
});
getDocLink("social_twitter", (link) =>
{
......
......@@ -15,7 +15,7 @@
* along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
*/
/* globals getDocLink, setLinks, E */
/* globals getDocLink, E */
"use strict";
......@@ -43,7 +43,7 @@
});
getDocLink("adblock_browser_website", (url) =>
{
setLinks("adblock-browser-text", url);
ext.i18n.setElementLinks("adblock-browser-text", url);
});
}
document.addEventListener("DOMContentLoaded", onDOMLoaded, false);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment