Commit d73d640f authored by Manvel Saroyan's avatar Manvel Saroyan

Issue 2375 - Implement Filter list section in new options page advanced tab

parent b845b0d1
......@@ -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
......@@ -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 = {
......
......@@ -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);
......@@ -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",
......
......@@ -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);
......@@ -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 -->
......
This diff is collapsed.
skin/options-sprite.png

2.79 KB | W: | H:

skin/options-sprite.png

4.87 KB | W: | H:

skin/options-sprite.png
skin/options-sprite.png
skin/options-sprite.png
skin/options-sprite.png
  • 2-up
  • Swipe
  • Onion skin
......@@ -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;