Index: new-options.js |
=================================================================== |
--- a/new-options.js |
+++ b/new-options.js |
@@ -38,6 +38,8 @@ |
"options_filterList_lastDownload_checksumMismatch"] |
]); |
+ const whitelistedDomainRegexp = /^@@\|\|([^/:]+)\^\$document$/; |
+ |
function Collection(details) |
{ |
this.details = details; |
@@ -100,7 +102,8 @@ |
for (let j = 0; j < this.details.length; j++) |
{ |
- let table = E(this.details[j].id); |
+ let detail = this.details[j]; |
+ let table = E(detail.id); |
let template = table.querySelector("template"); |
let listItem = document.createElement("li"); |
listItem.appendChild(document.importNode(template.content, true)); |
@@ -128,11 +131,13 @@ |
this._setEmpty(table, null); |
if (table.hasChildNodes()) |
{ |
- table.insertBefore(listItem, |
- table.childNodes[this.items.indexOf(item)]); |
+ let beforeIndex = this.items.indexOf(item) + (detail.useHeader == true); |
+ table.insertBefore(listItem, table.children[beforeIndex]); |
} |
else |
+ { |
table.appendChild(listItem); |
+ } |
this.updateItem(item); |
} |
return length; |
@@ -200,9 +205,8 @@ |
control.setAttribute("disabled", true); |
} |
- let dateElement = element.querySelector(".date"); |
- let timeElement = element.querySelector(".time"); |
- if (dateElement && timeElement) |
+ let lastUpdateElem = element.querySelector(".last-update"); |
+ if (lastUpdateElem) |
{ |
let message = element.querySelector(".message"); |
if (item.isDownloading) |
@@ -222,9 +226,40 @@ |
} |
else if (item.lastDownload > 0) |
{ |
- let dateTime = i18nFormatDateTime(item.lastDownload * 1000); |
- dateElement.textContent = dateTime[0]; |
- timeElement.textContent = dateTime[1]; |
+ let timer = setInterval(lastUpdateLive, 60000); |
+ let lastUpdate = item.lastDownload * 1000; |
+ function lastUpdateLive() |
+ { |
+ let sinceUpdate = Date.now() - lastUpdate; |
+ if(sinceUpdate > 86400000) |
+ { |
+ let lastUpdateDate = new Date(item.lastDownload * 1000); |
+ let monthName = lastUpdateDate.toLocaleString("en-US", |
saroyanm
2017/06/11 15:40:12
For reference: Make sense to find a way to pass th
saroyanm
2017/06/12 16:44:42
Create a function in i18n, that returns month: "sh
saroyanm
2017/06/14 10:59:00
I used different approach while we do have the val
Thomas Greiner
2017/07/07 13:01:07
This looks like a race condition because the "lang
|
+ { month: "short" }); |
+ let day = lastUpdateDate.getDate(); |
+ day = day < 10 ? "0" + day : day; |
+ lastUpdateElem.textContent = day + " " + monthName + " " + |
saroyanm
2017/06/12 16:44:42
Note: Make sense to discuss if we need to localize
|
+ lastUpdateDate.getFullYear(); |
+ clearInterval(timer); |
+ return; |
+ } |
+ else if (sinceUpdate > 3600000) |
+ { |
+ lastUpdateElem.textContent = Math.round(sinceUpdate / 3600000) + |
+ " " + getMessage("options_filterList_hours"); |
+ } |
+ else if (sinceUpdate > 60000) |
+ { |
+ lastUpdateElem.textContent = Math.round(sinceUpdate / 60000) + |
+ " " + getMessage("options_filterList_minutes"); |
+ } |
+ else |
+ { |
+ lastUpdateElem.textContent = |
+ getMessage("options_filterList_just"); |
+ } |
+ } |
+ lastUpdateLive(); |
element.classList.remove("show-message"); |
} |
} |
@@ -315,16 +350,11 @@ |
emptyText: "options_whitelisted_empty" |
} |
]); |
- collections.customFilters = new Collection([ |
- { |
- id: "custom-filters-table", |
- emptyText: "options_customFilters_empty" |
- } |
- ]); |
collections.filterLists = new Collection([ |
{ |
id: "all-filter-lists-table", |
- useOriginalTitle: true |
+ useOriginalTitle: true, |
+ useHeader: true |
} |
]); |
@@ -378,18 +408,50 @@ |
function updateFilter(filter) |
{ |
- let match = filter.text.match(/^@@\|\|([^/:]+)\^\$document$/); |
+ let match = filter.text.match(whitelistedDomainRegexp); |
if (match && !filtersMap[filter.text]) |
{ |
filter.title = match[1]; |
collections.whitelist.addItem(filter); |
} |
else |
- collections.customFilters.addItem(filter); |
+ addCustomFilter(filter); |
filtersMap[filter.text] = filter; |
} |
+ function addCustomFilter(filter) |
+ { |
+ customFiltersView("read"); |
+ |
+ // Note: document.createElement("option") is unreliable in Opera |
saroyanm
2017/06/11 15:40:12
I'm not sure if this still true, I took this from
saroyanm
2017/06/12 16:44:42
Check if it's still an issue in the supported Oper
saroyanm
2017/06/14 10:59:00
Done.
This was added back in 2012 -> https://hg.a
Thomas Greiner
2017/07/07 13:01:08
Acknowledged.
|
+ let elt = new Option(); |
+ elt.text = filter.text; |
+ elt.value = filter.text; |
+ E("custom-filters-box").appendChild(elt); |
+ } |
+ |
+ function removeCustomFilter(text) |
+ { |
+ let list = E("custom-filters-box"); |
+ let selector = "option[value=" + CSS.escape(text) + "]"; |
+ for (let option of list.querySelectorAll(selector)) |
+ list.removeChild(option); |
+ |
+ if (E("custom-filters-box").options.length == 0) |
+ customFiltersView("empty") |
+ } |
+ |
+ function convertToRawFormat(event) |
+ { |
+ let filters = []; |
+ |
+ for (let option of E("custom-filters-box").options) |
+ filters.push(option.value); |
+ |
+ document.getElementById("custom-filters-raw").value = filters.join("\n"); |
+ } |
+ |
function loadRecommendations() |
{ |
fetch("subscriptions.xml") |
@@ -493,7 +555,7 @@ |
break; |
} |
case "cancel-custom-filters": |
- E("custom-filters").classList.remove("mode-edit"); |
+ customFiltersView("read"); |
break; |
case "cancel-domain-exception": |
E("whitelisting-textbox").value = ""; |
@@ -504,7 +566,7 @@ |
closeDialog(); |
break; |
case "edit-custom-filters": |
- editCustomFilters(); |
+ customFiltersView("write"); |
break; |
case "edit-domain-exception": |
document.querySelector("#whitelisting .controls").classList |
@@ -553,7 +615,7 @@ |
}, |
() => |
{ |
- E("custom-filters").classList.remove("mode-edit"); |
+ customFiltersView("read"); |
}); |
break; |
case "switch-tab": |
@@ -599,6 +661,36 @@ |
} |
} |
+ function customFiltersView(mode) |
+ { |
+ switch (mode) |
+ { |
+ case "read": |
+ if (E("custom-filters-box").options.length == 0) |
+ { |
+ customFiltersView("empty"); |
+ } |
+ else |
+ { |
+ E("custom-filters").classList.add("mode-view"); |
+ E("custom-filters").classList.remove("mode-edit"); |
+ E("custom-filters").classList.remove("mode-empty"); |
+ } |
+ break; |
+ case "write": |
+ convertToRawFormat(); |
+ E("custom-filters").classList.remove("mode-view"); |
+ E("custom-filters").classList.add("mode-edit"); |
+ E("custom-filters").classList.remove("mode-empty"); |
+ break; |
+ case "empty": |
+ E("custom-filters").classList.remove("mode-view"); |
+ E("custom-filters").classList.remove("mode-edit"); |
+ E("custom-filters").classList.add("mode-empty"); |
+ break; |
+ } |
+ } |
+ |
function onClick(e) |
{ |
let context = document.querySelector(".show-context-menu"); |
@@ -684,10 +776,6 @@ |
let tabContentId = tab.getAttribute("aria-controls"); |
let tabContent = document.getElementById(tabContentId); |
- // Select sub tabs |
- if (tab.hasAttribute("data-subtab")) |
- selectTabItem(tab.getAttribute("data-subtab"), tabContent, false); |
- |
if (tab && focus) |
tab.focus(); |
@@ -757,12 +845,12 @@ |
}, false); |
// Advanced tab |
- let tweaks = document.querySelectorAll("#tweaks li[data-pref]"); |
- tweaks = Array.prototype.map.call(tweaks, (checkbox) => |
+ let customize = document.querySelectorAll("#customize li[data-pref]"); |
+ customize = Array.prototype.map.call(customize, (checkbox) => |
{ |
return checkbox.getAttribute("data-pref"); |
}); |
- for (let key of tweaks) |
+ for (let key of customize) |
{ |
getPref(key, (value) => |
{ |
@@ -778,26 +866,10 @@ |
hidePref("show_devtools_panel", !features.devToolsPanel); |
}); |
- let filterTextbox = document.querySelector("#custom-filters-add input"); |
- placeholderValue = getMessage("options_customFilters_textbox_placeholder"); |
- filterTextbox.setAttribute("placeholder", placeholderValue); |
- function addCustomFilters() |
+ getDocLink("filterdoc", (link) => |
{ |
- let filterText = filterTextbox.value; |
- sendMessageHandleErrors({ |
- type: "filters.add", |
- text: filterText |
- }, |
- () => |
- { |
- filterTextbox.value = ""; |
- }); |
- } |
- E("custom-filters-add").addEventListener("submit", (e) => |
- { |
- e.preventDefault(); |
- addCustomFilters(); |
- }, false); |
+ E("link-filters").setAttribute("href", link); |
+ }); |
// Help tab |
getDocLink("faq", (link) => |
@@ -1024,8 +1096,11 @@ |
break; |
case "removed": |
let knownFilter = filtersMap[filter.text]; |
- collections.whitelist.removeItem(knownFilter); |
- collections.customFilters.removeItem(knownFilter); |
+ if (whitelistedDomainRegexp.test(knownFilter.text)) |
+ collections.whitelist.removeItem(knownFilter); |
+ else |
+ removeCustomFilter(filter.text); |
+ |
delete filtersMap[filter.text]; |
updateShareLink(); |
break; |