[Pkg-mozext-commits] [adblock-plus] 14/87: Issue 2375 - Implement Filter list section in new options page advanced tab
David Prévot
taffit at moszumanska.debian.org
Sat Apr 30 17:59:03 UTC 2016
This is an automated email from the git hooks/post-receive script.
taffit pushed a commit to branch master
in repository adblock-plus.
commit d73d640fd8271096e967f00faab88fa3e11d5cf6
Author: Manvel Saroyan <manvel at adblockplus.org>
Date: Fri Feb 5 12:31:41 2016 +0100
Issue 2375 - Implement Filter list section in new options page advanced tab
---
README.md | 2 +
background.js | 41 +++++-
i18n.js | 46 +++++--
locale/en-US/options.json | 90 ++++++++----
messageResponder.js | 28 +++-
options.html | 81 +++++++----
options.js | 289 +++++++++++++++++++++++++++++----------
skin/options-sprite.png | Bin 2855 -> 4988 bytes
skin/options.css | 340 ++++++++++++++++++++++++++++++++++++----------
9 files changed, 710 insertions(+), 207 deletions(-)
diff --git a/README.md b/README.md
index 3bd7aa5..1ebbc51 100644
--- a/README.md
+++ b/README.md
@@ -78,3 +78,5 @@ The behavior of this page is affected by a number of URL parameters:
errors when adding new filters on the options page
* `blockedURLs`: a comma-separated list of URLs that should be considered
blocked (necessary to test the check for blocked scripts in sharing buttons).
+* `downloadStatus`: Sets downloadStatus parameter for filter lists, can be used
+ to trigger various filter list download errors
diff --git a/background.js b/background.js
index 3bb096f..acf4a51 100644
--- a/background.js
+++ b/background.js
@@ -36,7 +36,8 @@
seenDataCorruption: false,
filterlistsReinitialized: false,
addSubscription: false,
- filterError: false
+ filterError: false,
+ downloadStatus: "synchronize_ok"
};
updateFromURL(params);
@@ -71,7 +72,9 @@
this.url = url;
this.title = "Subscription " + url;
this.disabled = false;
- this.lastDownload = 1234;
+ this._lastDownload = 1234;
+ this.homepage = "https://easylist.adblockplus.org/";
+ this.downloadStatus = params.downloadStatus;
},
SpecialSubscription: function(url)
@@ -83,6 +86,9 @@
};
modules.subscriptionClasses.Subscription.fromURL = function(url)
{
+ if (url in knownSubscriptions)
+ return knownSubscriptions[url];
+
if (/^https?:\/\//.test(url))
return new modules.subscriptionClasses.Subscription(url);
else
@@ -90,6 +96,19 @@
};
modules.subscriptionClasses.DownloadableSubscription = modules.subscriptionClasses.Subscription;
+ modules.subscriptionClasses.Subscription.prototype =
+ {
+ get lastDownload()
+ {
+ return this._lastDownload;
+ },
+ set lastDownload(value)
+ {
+ this._lastDownload = value;
+ modules.filterNotifier.FilterNotifier.triggerListeners("subscription.lastDownload", this);
+ }
+ };
+
modules.filterStorage = {
FilterStorage: {
get subscriptions()
@@ -184,7 +203,23 @@
};
modules.synchronizer = {
- Synchronizer: {}
+ Synchronizer: {
+ _downloading: false,
+ execute: function(subscription, manual)
+ {
+ subscription.lastDownload = 0;
+ modules.synchronizer.Synchronizer._downloading = true;
+ setTimeout(function()
+ {
+ modules.synchronizer.Synchronizer._downloading = false;
+ subscription.lastDownload = Date.now() / 1000;
+ }, 500);
+ },
+ isExecuting: function(url)
+ {
+ return modules.synchronizer.Synchronizer._downloading;
+ }
+ }
};
modules.matcher = {
diff --git a/i18n.js b/i18n.js
index f5232a4..6db0881 100644
--- a/i18n.js
+++ b/i18n.js
@@ -65,21 +65,30 @@ ext.i18n.setElementText = function(element, stringName, arguments)
// Loads i18n strings
function loadI18nStrings()
{
- var nodes = document.querySelectorAll("[class^='i18n_']");
- for(var i = 0; i < nodes.length; i++)
+ function addI18nStringsToElements(containerElement)
{
- var node = nodes[i];
- var arguments = JSON.parse("[" + node.textContent + "]");
- if (arguments.length == 0)
- arguments = null;
+ var elements = containerElement.querySelectorAll("[class^='i18n_']");
+ for(var i = 0; i < elements.length; i++)
+ {
+ var node = elements[i];
+ var arguments = JSON.parse("[" + node.textContent + "]");
+ if (arguments.length == 0)
+ arguments = null;
- var className = node.className;
- if (className instanceof SVGAnimatedString)
- className = className.animVal;
- var stringName = className.split(/\s/)[0].substring(5);
+ var className = node.className;
+ if (className instanceof SVGAnimatedString)
+ className = className.animVal;
+ var stringName = className.split(/\s/)[0].substring(5);
- ext.i18n.setElementText(node, stringName, arguments);
+ ext.i18n.setElementText(node, stringName, arguments);
+ }
}
+ addI18nStringsToElements(document);
+ // Content of Template is not rendered on runtime so we need to add
+ // translation strings for each Template documentFragment content individually
+ var templates = document.querySelectorAll("template");
+ for (var i = 0; i < templates.length; i++)
+ addI18nStringsToElements(templates[i].content);
}
// Provides a more readable string of the current date and time
@@ -95,5 +104,20 @@ function i18n_timeDateStrings(when)
return [timeString, d.toLocaleDateString()];
}
+// Formats date string to ["YYYY-MM-DD", "mm:ss"] format
+function i18n_formatDateTime(when)
+{
+ var date = new Date(when);
+ var dateParts = [date.getFullYear(), date.getMonth() + 1, date.getDate(),
+ date.getHours(), date.getMinutes()];
+
+ var dateParts = dateParts.map(function(datePart)
+ {
+ return datePart < 10 ? "0" + datePart : datePart;
+ });
+
+ return [dateParts.splice(0, 3).join("-"), dateParts.join(":")];
+}
+
// Fill in the strings as soon as possible
window.addEventListener("DOMContentLoaded", loadI18nStrings, true);
diff --git a/locale/en-US/options.json b/locale/en-US/options.json
index 3abf9e6..df15b80 100644
--- a/locale/en-US/options.json
+++ b/locale/en-US/options.json
@@ -76,8 +76,8 @@
"message": "popular"
},
"options_furtherBlocking_add": {
- "description": "Button name for adding other blocking list in General tab",
- "message": "add other blocking list"
+ "description": "Button name for adding other filter list in General tab",
+ "message": "add other filter list"
},
"options_exceptions_title": {
"description": "Exceptions section name in General tab",
@@ -136,16 +136,16 @@
"message": "cancel"
},
"options_tweaks_title": {
- "description": "Tweaks section name in Advanced tab",
+ "description": "Section title in Advanced tab",
"message": "Tweaks"
},
"options_tweaks_blockElement": {
"description": "Show block Element option in Advanced tab",
"message": "Show <a>Block Element</a> right-click menu item"
},
- "options_blockingList_title": {
- "description": "Blocking list section title in Advanced tab",
- "message": "Blocking list"
+ "options_filterList_title": {
+ "description": "Section title in Advanced tab",
+ "message": "Filter lists"
},
"options_tab_overview": {
"description": "Tab name in Advanced tab",
@@ -153,32 +153,72 @@
},
"options_tab_ownList": {
"description": "Tab name in Advanced tab",
- "message": "Edit or create own blocking list"
+ "message": "Edit or create own filter list"
},
- "options_tableCol_name": {
+ "options_column_name": {
"description": "Name of column of subscription list table in Advanced tab",
"message": "Name"
},
- "options_tableCol_description": {
+ "options_column_date": {
"description": "Name of column of subscription list table in Advanced tab",
- "message": "Description"
+ "message": "Last update"
},
- "options_tableCol_date": {
- "description": "Name of column of subscription list table in Advanced tab",
- "message": "Date"
- },
- "options_blockingList_add": {
+ "options_filterList_add": {
"description": "Import button in Advanced tab",
- "message": "add/import other blocking list"
+ "message": "add/import other filter list"
},
- "options_blockingList_update": {
+ "options_filterList_update": {
"description": "Update button in Advanced tab",
- "message": "Update all blocking lists"
+ "message": "update all filter lists"
},
"options_customFilters_empty": {
"description": "Text shown when list of custom filters is empty",
"message": "There are no custom filters."
},
+ "options_filterList_lastDownload_invalidURL": {
+ "description": "Error message in advanced tab",
+ "message": "Failed, not a valid address"
+ },
+ "options_filterList_lastDownload_connectionError": {
+ "description": "Error message in advanced tab",
+ "message": "Failed, download failure"
+ },
+ "options_filterList_lastDownload_invalidData": {
+ "description": "Error message in advanced tab",
+ "message": "Failed, not a valid filter list"
+ },
+ "options_filterList_lastDownload_checksumMismatch": {
+ "description": "Error message in advanced tab",
+ "message": "Failed, checksum mismatch"
+ },
+ "options_filterList_lastDownload_inProgress": {
+ "description": "Progress message in advanced tab",
+ "message": "Downloading…"
+ },
+ "options_filterList_updateNow": {
+ "description": "Context menu item in advanced tab, appears after click on subscription",
+ "message": "update now"
+ },
+ "options_filterList_website": {
+ "description": "Context menu item in advanced tab, appears after click on subscription",
+ "message": "website"
+ },
+ "options_filterList_source": {
+ "description": "Context menu item in advanced tab, appears after click on subscription",
+ "message": "source"
+ },
+ "options_filterList_delete": {
+ "description": "Context menu item in advanced tab, appears after click on subscription",
+ "message": "delete"
+ },
+ "options_filterList_own_list": {
+ "description": "Name of custom subscription entry in filter list section in Advanced tab",
+ "message": "Own filter list"
+ },
+ "options_filterList_edit_own_list": {
+ "description": "Entry in filter list section in Advanced tab",
+ "message": "edit your filter list"
+ },
"options_customFilters_title": {
"description": "Custom filters option name in Advanced tab",
"message": "Blocking rules"
@@ -205,7 +245,7 @@
},
"options_faq_description": {
"description": "FAQ section description in Help tab",
- "message": "You only need to refresh your blocking list in \"Advanced\" very often, but there are also other known problems."
+ "message": "You only need to refresh your filter list in \"Advanced\" very often, but there are also other known problems."
},
"options_forum_title": {
"description": "Forum section name in Help tab",
@@ -229,15 +269,15 @@
},
"options_dialog_predefined_confirm": {
"description": "Confirming to add a predefined subscription when asked in a dialog",
- "message": "Yes, use this blocking list"
+ "message": "Yes, use this filter list"
},
"options_dialog_predefined_title": {
"description": "Dialog title for adding a predefined subscription",
- "message": "Do you really want to use this blocking list?"
+ "message": "Do you really want to use this filter list?"
},
"options_dialog_custom_title": {
"description": "Title of custom subscription modal dialog",
- "message": "Add other blocking list"
+ "message": "Add other filter list"
},
"options_close": {
"description": "Close modal button",
@@ -249,11 +289,11 @@
},
"options_dialog_custom_import": {
"description": "Button in add custom subscription modal dialog",
- "message": "import blocking list with this URL"
+ "message": "import filter list with this URL"
},
"options_dialog_edit_own_list": {
- "description": "Edit own blocking list section name in custom subscription modal dialog",
- "message": "edit own blocking list"
+ "description": "Edit own filter list section name in custom subscription modal dialog",
+ "message": "edit own filter list"
},
"options_dialog_create_own_list": {
"description": "Button in custom subscription modal dialog",
diff --git a/messageResponder.js b/messageResponder.js
index 90f2c9a..0708fcd 100644
--- a/messageResponder.js
+++ b/messageResponder.js
@@ -47,7 +47,7 @@
}
var convertSubscription = convertObject.bind(null, ["disabled",
- "downloadStatus", "homepage", "lastSuccess", "title", "url"]);
+ "downloadStatus", "homepage", "lastDownload", "title", "url"]);
var convertFilter = convertObject.bind(null, ["text"]);
var changeListeners = null;
@@ -333,8 +333,17 @@
break;
case "subscriptions.toggle":
var subscription = Subscription.fromURL(message.url);
- if (subscription.url in FilterStorage.knownSubscriptions && !subscription.disabled)
- FilterStorage.removeSubscription(subscription);
+ if (subscription.url in FilterStorage.knownSubscriptions)
+ {
+ if (subscription.disabled || message.keepInstalled)
+ {
+ subscription.disabled = !subscription.disabled;
+ FilterNotifier.triggerListeners("subscription.disabled",
+ subscription);
+ }
+ else
+ FilterStorage.removeSubscription(subscription);
+ }
else
{
subscription.disabled = false;
@@ -345,6 +354,19 @@
Synchronizer.execute(subscription);
}
break;
+ case "subscriptions.update":
+ var subscriptions = message.url ? [Subscription.fromURL(message.url)] :
+ FilterStorage.subscriptions;
+ for (var i = 0; i < subscriptions.length; i++)
+ {
+ var subscription = subscriptions[i];
+ if (subscription instanceof DownloadableSubscription)
+ Synchronizer.execute(subscription, true);
+ }
+ break;
+ case "subscriptions.isDownloading":
+ callback(Synchronizer.isExecuting(message.url));
+ break;
}
});
})(this);
diff --git a/options.html b/options.html
index a5e8695..9aca46c 100644
--- a/options.html
+++ b/options.html
@@ -43,7 +43,7 @@
<a class="i18n_options_tab_general"></a>
<span class="icon"></span>
</li>
- <li id="tab-advanced" data-action="switch-tab" data-tab="advanced">
+ <li id="tab-advanced" data-action="switch-tab" data-tab="advanced-allFilterLists">
<a class="i18n_options_tab_advanced"></a>
<span class="icon"></span>
</li>
@@ -124,7 +124,7 @@
<template>
<button role="checkbox" class="control"></button>
<span class="display"></span>
- <span class="popular"></span>
+ <span class="i18n_options_popular popular"></span>
</template>
</ul>
<ul id="custom-list-table" class="table list">
@@ -213,8 +213,11 @@
<!-- Advanced tab content -->
<div id="content-advanced" class="tab-content">
<div>
- <h1><span class="i18n_options_tweaks_title"></span><a class="i18n_options_readMore tooltip" href="#"></a></h1>
- <ul class="table" style="width: auto;">
+ <h1>
+ <span class="i18n_options_tweaks_title"></span>
+ <a class="i18n_options_readMore tooltip"></a>
+ </h1>
+ <ul class="table">
<li>
<button role="checkbox" id="easylist"></button>
<span id="block-element-explanation" class="i18n_options_tweaks_blockElement"></span>
@@ -222,31 +225,63 @@
</ul>
</div>
<div>
- <h1><span class="i18n_options_blockingList_title"></span><a class="i18n_options_readMore tooltip" href="#" target="_blank"></a></h1>
- <ul id="blocking-list-tabs" class="tabs horizontal">
- <li class="i18n_options_tab_overview active" data-show="blocking-list-overview"></li><li class="i18n_options_tab_ownList" data-show="custom-filters"></li>
+ <h1>
+ <span class="i18n_options_filterList_title"></span>
+ <a class="i18n_options_readMore tooltip"></a>
+ </h1>
+ <ul class="tabs horizontal">
+ <li class="i18n_options_tab_overview active" data-action="switch-tab" data-tab="advanced-allFilterLists"></li>
+ <li class="i18n_options_tab_ownList" data-action="switch-tab" data-tab="advanced-customFilters"></li>
</ul>
- <div id="blocking-list">
- <div id="blocking-list-overview">
- <ul class="table cols" style="width: auto;">
- <li class="col-name"><span class="i18n_options_tableCol_name"></span><span class="i18n_options_tableCol_description"></span><span class="i18n_options_tableCol_date"></span></li>
- <li><input type="checkbox" id="easylist"/><span>Easylist</span><span>Adblocking english sites</span><span>15 March 14 - 10:31</span></li>
- <li><input type="checkbox" id="easylist+de"/><span>Easylist Germany + Easylist</span><span>Adblocking english + german sites</span><span>15 March 14 - 10:31</span></li>
- <li><input type="checkbox" id="annoyance-fb"/><span>Facebook annoyance blocker</span><span>Blocks Facebook annoyances</span><span>15 March 14 - 10:31</span></li>
- <li><input type="checkbox" id="annoyance-youtube"/><span>Facebook annoyance blocker</span><span>Blocks Facebook annoyances</span><span>15 March 14 - 10:31</span></li>
- <li><input type="checkbox" id="own-list"/><span>Own blocking list</span><span>Your own blocking list</span><span><a href="#">edit your blocking list</a></span></li>
+ <div id="filter-lists">
+ <div id="all-filter-lists">
+ <div class="table-header">
+ <h3 class="i18n_options_column_name"></h3>
+ <h3 class="i18n_options_column_date"></h3>
+ </div>
+ <ul class="table cols" id="all-filter-lists-table">
+ <template>
+ <button role="checkbox" class="control"></button>
+ <div>
+ <span data-action="open-context-menu" class="display"></span>
+ <div data-action="open-context-menu" class="arrow">
+ <div class="context-menu">
+ <div class="content">
+ <a class="i18n_options_filterList_updateNow update-subscription" data-action="update-subscription"></a>
+ <a class="i18n_options_filterList_website website" target="_blank"></a>
+ <a class="i18n_options_filterList_source source" target="_blank"></a>
+ <a class="i18n_options_filterList_delete delete" data-action="remove-subscription"></a>
+ </div>
+ </div>
+ </div>
+ </div>
+ <span class="date"></span>
+ <span class="time"></span>
+ <span class="message"></span>
+ </template>
+ <li class="static">
+ <button role="checkbox" class="control" aria-checked="true" disabled="true"></button>
+ <div>
+ <span class="i18n_options_filterList_own_list"></span>
+ </div>
+ <span data-action="switch-tab,edit-custom-filters" data-tab="advanced-customFilters">
+ <a class="i18n_options_filterList_edit_own_list"></a>
+ </span>
+ </li>
</ul>
<div class="controls">
- <button>
- <span class="icon icon-add"></span><span class="i18n_options_blockingList_add"></span>
+ <button data-action="open-dialog" data-dialog="custom">
+ <span class="icon icon-add"></span>
+ <span class="i18n_options_filterList_add"></span>
</button>
- <button>
- <span class="icon icon-update"></span><span class="i18n_options_blockingList_update"></span>
+ <button data-action="update-all-subscriptions">
+ <span class="icon icon-update"></span>
+ <span class="i18n_options_filterList_update"></span>
</button>
</div>
</div>
<div id="custom-filters">
- <h2 id="custom-filters-header" class="i18n_options_customFilters_title"></h2>
+ <h3 id="custom-filters-header" class="i18n_options_customFilters_title"></h3>
<div id="custom-filters-wrapper">
<div id="custom-filters-list-wrapper">
<ul id="custom-filters-table" class="table list">
@@ -334,7 +369,7 @@
<ul id="all-lang-table" class="table list">
<template>
<button class="button-add control">
- +<span></span>
+ +<span class="i18n_options_button_add"></span>
</button>
<span class="display"></span>
</template>
@@ -352,7 +387,7 @@
</div>
<div class="dialog-content-block">
<h3 class="i18n_options_dialog_edit_own_list"></h3>
- <button class="i18n_options_dialog_create_own_list" data-action="close-dialog,switch-tab,edit-custom-filters" data-tab="advanced"></button>
+ <button class="i18n_options_dialog_create_own_list" data-action="close-dialog,switch-tab,edit-custom-filters" data-tab="advanced-customFilters"></button>
</div>
</div>
<!-- Add predefined subscription -->
diff --git a/options.js b/options.js
index 300c724..53000f3 100644
--- a/options.js
+++ b/options.js
@@ -24,6 +24,14 @@
var filtersMap = Object.create(null);
var collections = Object.create(null);
var maxLabelId = 0;
+ var getMessage = ext.i18n.getMessage;
+ var filterErrors =
+ {
+ "synchronize_invalid_url": "options_filterList_lastDownload_invalidURL",
+ "synchronize_connection_error": "options_filterList_lastDownload_connectionError",
+ "synchronize_invalid_data": "options_filterList_lastDownload_invalidData",
+ "synchronize_checksum_mismatch": "options_filterList_lastDownload_checksumMismatch"
+ };
function Collection(details)
{
@@ -38,13 +46,22 @@
{
placeholder = document.createElement("li");
placeholder.className = "empty-placeholder";
- placeholder.textContent = ext.i18n.getMessage(text);
+ placeholder.textContent = getMessage(text);
table.appendChild(placeholder);
}
else if (placeholder)
table.removeChild(placeholder);
}
+ Collection.prototype._createElementQuery = function(item)
+ {
+ var access = (item.url || item.text).replace(/'/g, "\\'");
+ return function(container)
+ {
+ return container.querySelector("[data-access='" + access + "']");
+ };
+ };
+
Collection.prototype.addItems = function()
{
var length = Array.prototype.push.apply(this.items, arguments);
@@ -82,7 +99,10 @@
this._setEmpty(table, null);
if (table.hasChildNodes())
- table.insertBefore(listItem, table.childNodes[this.items.indexOf(item)]);
+ {
+ table.insertBefore(listItem,
+ table.childNodes[this.items.indexOf(item)]);
+ }
else
table.appendChild(listItem);
this.updateItem(item);
@@ -98,10 +118,11 @@
return;
this.items.splice(index, 1);
+ var getListElement = this._createElementQuery(item);
for (var i = 0; i < this.details.length; i++)
{
var table = E(this.details[i].id);
- var element = table.childNodes[index];
+ var element = getListElement(table);
// Element gets removed so make sure to handle focus appropriately
var control = element.querySelector(".control");
@@ -139,13 +160,56 @@
if (!element)
continue;
- var text = item.title || item.url || item.text;
- element.querySelector(".display").textContent = text;
- if (text)
- element.setAttribute("data-search", text.toLowerCase());
+ var title = item.title || item.url || item.text;
+ element.querySelector(".display").textContent = title;
+ if (title)
+ element.setAttribute("data-search", title.toLowerCase());
var control = element.querySelector(".control[role='checkbox']");
if (control)
control.setAttribute("aria-checked", item.disabled == false);
+
+ var downloadStatus = item.downloadStatus;
+ var dateElement = element.querySelector(".date");
+ var timeElement = element.querySelector(".time");
+ if(dateElement && timeElement)
+ {
+ var message = element.querySelector(".message");
+ ext.backgroundPage.sendMessage(
+ {
+ type: "subscriptions.isDownloading",
+ url: item.url
+ },
+ function(isDownloading)
+ {
+ if (isDownloading)
+ {
+ var text = getMessage("options_filterList_lastDownload_inProgress");
+ message.textContent = text;
+ element.classList.add("show-message");
+ }
+ else if (downloadStatus && downloadStatus != "synchronize_ok")
+ {
+ if (downloadStatus in filterErrors)
+ message.textContent = getMessage(filterErrors[downloadStatus]);
+ else
+ message.textContent = item.downloadStatus;
+ element.classList.add("show-message");
+ }
+ else if (item.lastDownload > 0)
+ {
+ var dateTime = i18n_formatDateTime(item.lastDownload * 1000);
+ dateElement.textContent = dateTime[0];
+ timeElement.textContent = dateTime[1];
+ element.classList.remove("show-message");
+ }
+ });
+ }
+ var websiteElement = element.querySelector(".context-menu .website");
+ var sourceElement = element.querySelector(".context-menu .source");
+ if (websiteElement && item.homepage)
+ websiteElement.setAttribute("href", item.homepage);
+ if (sourceElement)
+ sourceElement.setAttribute("href", item.url);
}
};
@@ -155,9 +219,14 @@
for (var i = 0; i < this.details.length; i++)
{
var table = E(this.details[i].id);
- var template = table.querySelector("template");
- table.innerHTML = "";
- table.appendChild(template);
+ var element = table.firstChild;
+ while (element)
+ {
+ if (element.tagName == "LI" && !element.classList.contains("static"))
+ table.removeChild(element);
+ element = element.nextElementSibling;
+ }
+
this._setEmpty(table, this.details[i].emptyText);
}
};
@@ -177,12 +246,11 @@
return true;
}
- function onToggleSubscriptionClick(e)
+ function toggleRemoveSubscription(e)
{
e.preventDefault();
- var checkbox = e.target;
- var subscriptionUrl = checkbox.parentElement.getAttribute("data-access");
- if (checkbox.getAttribute("aria-checked") == "true")
+ var subscriptionUrl = findParentData(e.target, "access", false);
+ if (e.target.getAttribute("aria-checked") == "true")
{
ext.backgroundPage.sendMessage({
type: "subscriptions.remove",
@@ -193,16 +261,28 @@
addEnableSubscription(subscriptionUrl);
}
+ function toggleDisableSubscription(e)
+ {
+ e.preventDefault();
+ var subscriptionUrl = findParentData(e.target, "access", false);
+ ext.backgroundPage.sendMessage(
+ {
+ type: "subscriptions.toggle",
+ keepInstalled: true,
+ url: subscriptionUrl
+ });
+ }
+
function onAddLanguageSubscriptionClick(e)
{
e.preventDefault();
- var url = this.parentNode.getAttribute("data-access");
+ var url = findParentData(this, "access", false);
addEnableSubscription(url);
}
function onRemoveFilterClick()
{
- var filter = this.parentNode.getAttribute("data-access");
+ var filter = findParentData(this, "access", false);
ext.backgroundPage.sendMessage(
{
type: "filters.remove",
@@ -214,7 +294,7 @@
[
{
id: "recommend-list-table",
- onClick: onToggleSubscriptionClick
+ onClick: toggleRemoveSubscription
}
]);
collections.langs = new Collection(
@@ -222,7 +302,7 @@
{
id: "blocking-languages-table",
emptyText: "options_dialog_language_added_empty",
- onClick: onToggleSubscriptionClick
+ onClick: toggleRemoveSubscription
},
{
id: "blocking-languages-dialog-table",
@@ -241,14 +321,14 @@
[
{
id: "acceptableads-table",
- onClick: onToggleSubscriptionClick
+ onClick: toggleRemoveSubscription
}
]);
collections.custom = new Collection(
[
{
id: "custom-list-table",
- onClick: onToggleSubscriptionClick
+ onClick: toggleRemoveSubscription
}
]);
collections.whitelist = new Collection(
@@ -266,23 +346,23 @@
emptyText: "options_customFilters_empty"
}
]);
+ collections.filterLists = new Collection(
+ [
+ {
+ id: "all-filter-lists-table",
+ onClick: toggleDisableSubscription
+ }
+ ]);
- function updateSubscription(subscription)
+ function observeSubscription(subscription)
{
- var subscriptionUrl = subscription.url;
- var knownSubscription = subscriptionsMap[subscriptionUrl];
- if (knownSubscription)
- knownSubscription.disabled = subscription.disabled;
- else
+ function onObjectChanged(change)
{
- getAcceptableAdsURL(function(acceptableAdsUrl)
+ for (var i = 0; i < change.length; i++)
{
- function onObjectChanged()
+ if (change[i].name == "disabled")
{
- for (var i in collections)
- collections[i].updateItem(subscription);
-
- var recommendation = recommendationsMap[subscriptionUrl];
+ var recommendation = recommendationsMap[subscription.url];
if (recommendation && recommendation.type == "ads")
{
if (subscription.disabled == false)
@@ -297,33 +377,57 @@
}
}
}
+ for (var i in collections)
+ collections[i].updateItem(subscription);
+ }
+ }
- if (!Object.observe)
+ if (!Object.observe)
+ {
+ ["disabled", "lastDownload"].forEach(function(property)
+ {
+ subscription["$" + property] = subscription[property];
+ Object.defineProperty(subscription, property,
{
- // Currently only "disabled" property of subscription used for observation
- // but with Advanced tab implementation we should also add more properties.
- ["disabled"].forEach(function(property)
+ get: function()
{
- subscription["$" + property] = subscription[property];
- Object.defineProperty(subscription, property,
+ return this["$" + property];
+ },
+ set: function(newValue)
+ {
+ var oldValue = this["$" + property];
+ if (oldValue != newValue)
{
- get: function()
- {
- return this["$" + property];
- },
- set: function(value)
- {
- this["$" + property] = value;
- onObjectChanged();
- }
- });
- });
- }
- else
- {
- Object.observe(subscription, onObjectChanged);
- }
+ this["$" + property] = newValue;
+ var change = Object.create(null);
+ change.name = property;
+ onObjectChanged([change]);
+ }
+ }
+ });
+ });
+ }
+ else
+ {
+ Object.observe(subscription, onObjectChanged);
+ }
+ }
+ function updateSubscription(subscription)
+ {
+ var subscriptionUrl = subscription.url;
+ var knownSubscription = subscriptionsMap[subscriptionUrl];
+ if (knownSubscription)
+ {
+ for (var property in subscription)
+ if (property != "title")
+ knownSubscription[property] = subscription[property];
+ }
+ else
+ {
+ observeSubscription(subscription);
+ getAcceptableAdsURL(function(acceptableAdsUrl)
+ {
var collection = null;
if (subscriptionUrl in recommendationsMap)
{
@@ -381,19 +485,18 @@
subscription.disabled = null;
subscription.downloadStatus = null;
subscription.homepage = null;
- subscription.lastSuccess = null;
var recommendation = Object.create(null);
recommendation.type = element.getAttribute("type");
var prefix = element.getAttribute("prefixes");
if (prefix)
{
prefix = prefix.replace(/\W/g, "_");
- subscription.title = ext.i18n.getMessage("options_language_" + prefix);
+ subscription.title = getMessage("options_language_" + prefix);
}
else
{
var type = recommendation.type.replace(/\W/g, "_");
- subscription.title = ext.i18n.getMessage("common_feature_" + type + "_title");
+ subscription.title = getMessage("common_feature_" + type + "_title");
}
recommendationsMap[subscription.url] = recommendation;
@@ -402,8 +505,24 @@
});
}
+ function findParentData(element, dataName, returnElement)
+ {
+ while (element)
+ {
+ if (element.hasAttribute("data-" + dataName))
+ return returnElement ? element : element.getAttribute("data-" + dataName);
+
+ element = element.parentElement;
+ }
+ return null;
+ }
+
function onClick(e)
{
+ var context = document.querySelector(".show-context-menu");
+ if (context)
+ context.classList.remove("show-context-menu");
+
var element = e.target;
while (true)
{
@@ -469,21 +588,38 @@
document.body.setAttribute("data-tab",
element.getAttribute("data-tab"));
break;
+ case "update-all-subscriptions":
+ ext.backgroundPage.sendMessage(
+ {
+ type: "subscriptions.update"
+ });
+ break;
+ case "open-context-menu":
+ var listItem = findParentData(element, "access", true);
+ if (listItem != context)
+ listItem.classList.add("show-context-menu");
+ break;
+ case "update-subscription":
+ ext.backgroundPage.sendMessage(
+ {
+ type: "subscriptions.update",
+ url: findParentData(element, "access", false)
+ });
+ break;
+ case "remove-subscription":
+ ext.backgroundPage.sendMessage(
+ {
+ type: "subscriptions.remove",
+ url: findParentData(element, "access", false)
+ });
+ break;
}
}
}
function onDOMLoaded()
{
- var recommendationTemplate = document.querySelector("#recommend-list-table template");
- var popularText = ext.i18n.getMessage("options_popular");
- recommendationTemplate.content.querySelector(".popular").textContent = popularText;
- var languagesTemplate = document.querySelector("#all-lang-table template");
- var buttonText = ext.i18n.getMessage("options_button_add");
- languagesTemplate.content.querySelector(".button-add span").textContent = buttonText;
-
populateLists();
-
function onFindLanguageKeyUp()
{
var searchStyle = E("search-style");
@@ -530,7 +666,7 @@
// Initialize interactive UI elements
document.body.addEventListener("click", onClick, false);
- var placeholderValue = ext.i18n.getMessage("options_dialog_language_find");
+ var placeholderValue = getMessage("options_dialog_language_find");
E("find-language").setAttribute("placeholder", placeholderValue);
E("find-language").addEventListener("keyup", onFindLanguageKeyUp, false);
E("whitelisting-textbox").addEventListener("keypress", function(e)
@@ -541,7 +677,7 @@
// Advanced tab
var filterTextbox = document.querySelector("#custom-filters-add input");
- placeholderValue = ext.i18n.getMessage("options_customFilters_textbox_placeholder");
+ placeholderValue = getMessage("options_customFilters_textbox_placeholder");
filterTextbox.setAttribute("placeholder", placeholderValue);
function addCustomFilters()
{
@@ -649,7 +785,7 @@
var subscription = Object.create(null);
subscription.url = acceptableAdsUrl;
subscription.disabled = true;
- subscription.title = ext.i18n.getMessage("options_acceptableAds_description");
+ subscription.title = getMessage("options_acceptableAds_description");
updateSubscription(subscription);
// Load user subscriptions
@@ -755,14 +891,27 @@
switch (action)
{
case "added":
+ updateSubscription(subscription);
+ updateShareLink();
+
+ var knownSubscription = subscriptionsMap[subscription.url];
+ if (knownSubscription)
+ collections.filterLists.addItems(knownSubscription);
+ else
+ collections.filterLists.addItems(subscription);
+ break;
case "disabled":
updateSubscription(subscription);
updateShareLink();
break;
+ case "lastDownload":
+ updateSubscription(subscription);
+ break;
case "homepage":
// TODO: NYI
break;
case "removed":
+ var knownSubscription = subscriptionsMap[subscription.url];
getAcceptableAdsURL(function(acceptableAdsUrl)
{
if (subscription.url == acceptableAdsUrl)
@@ -772,7 +921,6 @@
}
else
{
- var knownSubscription = subscriptionsMap[subscription.url];
if (subscription.url in recommendationsMap)
knownSubscription.disabled = true;
else
@@ -782,6 +930,7 @@
}
}
updateShareLink();
+ collections.filterLists.removeItem(knownSubscription);
});
break;
case "title":
@@ -871,7 +1020,7 @@
ext.backgroundPage.sendMessage(
{
type: "subscriptions.listen",
- filter: ["added", "disabled", "homepage", "removed", "title"]
+ filter: ["added", "disabled", "homepage", "lastDownload", "removed", "title"]
});
window.addEventListener("DOMContentLoaded", onDOMLoaded, false);
diff --git a/skin/options-sprite.png b/skin/options-sprite.png
index 535e418..3d6ef68 100755
Binary files a/skin/options-sprite.png and b/skin/options-sprite.png differ
diff --git a/skin/options.css b/skin/options.css
index a667cf0..273c481 100644
--- a/skin/options.css
+++ b/skin/options.css
@@ -202,9 +202,9 @@ button[role="checkbox"][aria-checked="true"]
padding: 14px 20px;
}
-body[data-tab="general"] #tab-general,
-body[data-tab="advanced"] #tab-advanced,
-body[data-tab="help"] #tab-help
+body[data-tab|="general"] #tab-general,
+body[data-tab|="advanced"] #tab-advanced,
+body[data-tab|="help"] #tab-help
{
background-color: #FFFFFF;
border-radius: 3px 0px 0px 3px;
@@ -222,9 +222,9 @@ body[data-tab="help"] #tab-help
-webkit-padding-start: 21px;
}
-html[dir="rtl"] body[data-tab="general"] #tab-general,
-html[dir="rtl"] body[data-tab="advanced"] #tab-advanced,
-html[dir="rtl"] body[data-tab="help"] #tab-help
+html[dir="rtl"] body[data-tab|="general"] #tab-general,
+html[dir="rtl"] body[data-tab|="advanced"] #tab-advanced,
+html[dir="rtl"] body[data-tab|="help"] #tab-help
{
border-radius: 0px 3px 3px 0px;
}
@@ -329,9 +329,9 @@ html[dir="rtl"] body[data-tab="help"] #tab-help
display: none;
}
-body[data-tab="general"] #content-general,
-body[data-tab="advanced"] #content-advanced,
-body[data-tab="help"] #content-help
+body[data-tab|="general"] #content-general,
+body[data-tab|="advanced"] #content-advanced,
+body[data-tab|="help"] #content-help
{
display: block;
}
@@ -368,8 +368,8 @@ div.button
white-space: nowrap;
}
-.table.list li:nth-child(odd),
-.table.cols li:nth-child(even),
+.table.list li:nth-of-type(odd),
+.table.cols li:nth-of-type(odd),
.table li.empty-placeholder
{
background-color: #F5F5F5;
@@ -380,55 +380,16 @@ div.button
vertical-align: top;
}
-.table.cols span
-{
- display: inline-block;
- width: 30%;
-}
-
-.table.cols .col-name
+.table.cols
{
border-bottom: 1px solid #CDCDCD;
+ border-top: 1px solid #CDCDCD;
}
-.table.cols .col-name span
-{
- display: inline-block;
- width: 30%;
-}
-
-.table.cols .col-name span:first-child
-{
- -webkit-padding-start: 38px;
- -moz-padding-start: 38px;
-}
-
-.table input[type="checkbox"]
-{
- margin-top: 0px;
- -moz-margin-end: 20px;
- -webkit-margin-end: 20px;
- padding: 0px 0px 0px 0px;
- visibility: hidden;
-}
-
-.table input[type="checkbox"]::before
-{
- content: "";
- background-position: -51px 0px;
- height: 18px;
- width: 18px;
- visibility: visible;
-}
-
-.table input[type="checkbox"]:checked::before
+button[disabled="true"]
{
- content: "";
- background-position: -68px 0px;
- height: 18px;
- padding: 0px;
- width: 18px;
- visibility: visible;
+ border-radius: 2px;
+ background-color: #ccc;
}
.table button.delete
@@ -455,32 +416,31 @@ div.button
.tabs.horizontal
{
+ display: flex;
margin-bottom: 0px;
padding: 0px;
}
.tabs.horizontal li
{
- border-bottom: 1px solid #A1A1A1;
display: inline-block;
+ border-bottom: 1px solid #A1A1A1;
+ padding: 10px 46px;
color: #3A7BA6;
- padding: 10px 0px 11px 0px;
text-align: center;
- width: 50%;
-}
-
-.tabs.horizontal li.active
-{
- border-bottom: 2px solid #1E8728;
- color: black;
- font-weight: 600;
- padding-bottom: 10px;
}
-.icon, .table button[role="checkbox"], .table button.delete,
-#content-help a::before, #dialog-close::before,
+.icon,
+button[role="checkbox"],
+.table button.delete,
+#content-help a::before,
+#dialog-close::before,
#custom-filters-add button::after,
-#dialog-body button::before
+#dialog-body button::before,
+.date::before,
+.time::before,
+#all-filter-lists .arrow,
+.context-menu .content a::before
{
background-image: url(options-sprite.png);
display: inline-block;
@@ -624,7 +584,7 @@ div.button
.icon-enter
{
- background-position: -18px -85px;
+ background-position: -18px -32px;
cursor: pointer;
height: 10px;
position: absolute;
@@ -646,6 +606,138 @@ div.button
Advanced tab content
*/
+#filter-lists > div
+{
+ display: none;
+}
+
+body[data-tab="advanced-allFilterLists"] #all-filter-lists,
+body[data-tab="advanced-customFilters"] #custom-filters
+{
+ display: block;
+}
+
+body[data-tab="advanced-allFilterLists"] #content-advanced [data-tab="advanced-allFilterLists"],
+body[data-tab="advanced-customFilters"] #content-advanced [data-tab="advanced-customFilters"]
+{
+ border-bottom: 2px solid #1E8728;
+ padding-bottom: 10px;
+ color: black;
+ font-weight: 600;
+}
+
+#all-filter-lists .table
+{
+ display: inline-block;
+}
+
+#all-filter-lists .table li
+{
+ padding-left: 16px;
+ padding-right: 16px;
+}
+
+#all-filter-lists .table li > div
+{
+ display: flex;
+ width: 330px;
+}
+
+.table-header
+{
+ display: flex;
+}
+
+#filter-lists h3
+{
+ display: inline-block;
+ margin-bottom: 7px;
+ font-size: 14px;
+}
+
+.table-header h3:first-child
+{
+ width: 330px;
+ -webkit-padding-start: 54px;
+ -moz-padding-start: 54px;
+}
+
+#all-filter-lists .table li span.display
+{
+ cursor: pointer;
+}
+
+#all-filter-lists .table .head span:first-child
+{
+ -webkit-padding-start: 38px;
+ -moz-padding-start: 38px;
+}
+
+#all-filter-lists .controls
+{
+ padding-top: 0px;
+ border-top: none;
+}
+
+#all-filter-lists .controls button
+{
+ margin-top: 14px;
+}
+
+#all-filter-lists .arrow
+{
+ position: relative;
+ margin: auto 6px;
+ border-style: none;
+ padding: 0px;
+ width: 6px;
+ height: 4px;
+ background-position: -1px -54px;
+ cursor: pointer;
+}
+
+#all-filter-lists .table li:last-of-type a
+{
+ color: #3A7BA6;
+ text-decoration: none;
+ cursor: pointer;
+}
+
+#all-filter-lists .table li:last-of-type > span:last-child
+{
+ -webkit-margin-start: auto;
+ -moz-margin-start: auto;
+}
+
+#all-filter-lists li.show-message .date,
+#all-filter-lists li.show-message .time,
+#all-filter-lists li:not(.show-message) .message
+{
+ display: none;
+}
+
+.date::before
+{
+ content: "";
+ -webkit-margin-end: 6px;
+ -moz-margin-end: 6px;
+ height: 12px;
+ width: 12px;
+ background-position: -7px -49px;
+}
+
+.time::before
+{
+ content: "";
+ -webkit-margin-end: 6px;
+ -moz-margin-end: 6px;
+ -webkit-margin-start: 12px;
+ -moz-margin-start: 12px;
+ height: 12px;
+ width: 12px;
+ background-position: -20px -49px;
+}
+
#custom-filters-header
{
padding: 0px 20px;
@@ -768,7 +860,7 @@ div.button
#custom-filters-add button::after
{
content: "";
- background-position: -28px -85px;
+ background-position: -28px -32px;
cursor: pointer;
height: 10px;
-webkit-margin-start: 6px;
@@ -793,6 +885,20 @@ div.button
text-decoration: none;
}
+.context-menu
+{
+ display: inline-block;
+ position: relative;
+ border-bottom: none;
+}
+
+.context-menu a
+{
+ vertical-align: middle;
+ white-space: nowrap;
+ color: #FFF;
+}
+
#content-advanced .tooltip
{
-moz-margin-start: 8px;
@@ -846,7 +952,8 @@ div[role="tooltip"]:hover
transition-delay: 0ms;
}
-div[role="tooltip"]::before
+div[role="tooltip"]::before,
+div.context-menu::before
{
background-image: url(options-sprite.png);
background-position: -8px -42px;
@@ -858,6 +965,95 @@ div[role="tooltip"]::before
left: 30px;
}
+div.context-menu
+{
+ position: absolute;
+ top: 16px;
+ z-index: 1;
+ visibility: hidden;
+}
+
+div.context-menu::before
+{
+ left: -4px;
+}
+
+html[dir="rtl"] div.context-menu::before
+{
+ left: inherit;
+ right: -4px;
+}
+
+div.context-menu .content
+{
+ position: relative;
+ left: calc(-50% + 2px);
+ border-radius: 3px;
+ padding: 4px 10px;
+ background-color: rgba(45, 45, 45, 0.95);
+ cursor: default;
+}
+
+html[dir="rtl"] div.context-menu .content
+{
+ left: inherit;
+ right: -50%;
+}
+
+li.show-context-menu div.context-menu
+{
+ visibility: visible;
+}
+
+div.context-menu > div a::before
+{
+ content: "";
+ -moz-margin-end: 8px;
+ -webkit-margin-end: 8px;
+}
+
+div.context-menu > div a
+{
+ display: block;
+ padding: 7px 4px;
+ border-bottom: 1px solid #CDCDCD;
+ text-decoration: none;
+ cursor: pointer;
+ vertical-align: middle;
+}
+
+div.context-menu > div a::before
+{
+ vertical-align: middle;
+ height: 16px;
+ width: 16px;
+}
+
+div.context-menu > div a:last-child
+{
+ border: none;
+}
+
+.context-menu .update-subscription::before
+{
+ background-position: -38px -31px;
+}
+
+.context-menu .website::before
+{
+ background-position: -33px -47px;
+}
+
+.context-menu .source::before
+{
+ background-position: -53px -34px;
+}
+
+.context-menu .delete::before
+{
+ background-position: -71px -34px;
+}
+
html[dir="ltr"] div[role="tooltip"].flip-vertical::before,
html[dir="rtl"] div[role="tooltip"]:not(.flip-vertical)::before
{
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/adblock-plus.git
More information about the Pkg-mozext-commits
mailing list