From 5af19f40a320c2c2914f7a5e9534734bc2432e40 Mon Sep 17 00:00:00 2001 From: Anton Bershanskiy Date: Sat, 4 May 2019 01:10:36 -0500 Subject: [PATCH 01/15] Options menu allows to disable HTTPS Everywhere for specific domains (#17434) This allows user to add a domain name to the whitelist from within Options menu (without visiting the site). No domain validation is performed. --- chromium/pages/options/index.html | 5 ++ chromium/pages/options/style.css | 2 +- chromium/pages/options/ux.js | 59 ++++++++++++++--------- src/chrome/locale/en/https-everywhere.dtd | 3 ++ 4 files changed, 44 insertions(+), 25 deletions(-) diff --git a/chromium/pages/options/index.html b/chromium/pages/options/index.html index f351d1773c45..06673f00d10b 100644 --- a/chromium/pages/options/index.html +++ b/chromium/pages/options/index.html @@ -24,6 +24,11 @@

+
+ + + +
diff --git a/chromium/pages/options/style.css b/chromium/pages/options/style.css index d1ff21e51798..75e86977f24c 100644 --- a/chromium/pages/options/style.css +++ b/chromium/pages/options/style.css @@ -135,7 +135,7 @@ div.update-channel-row-scope { border-radius: 7px; } -button#add-update-channel{ +button#add-update-channel, button#add-disabled-rule { float: right; margin: 0px 10px 10px 10px; border-radius: 7px; diff --git a/chromium/pages/options/ux.js b/chromium/pages/options/ux.js index 9ffb4cc3c533..72f16f325c21 100644 --- a/chromium/pages/options/ux.js +++ b/chromium/pages/options/ux.js @@ -268,40 +268,51 @@ document.addEventListener("DOMContentLoaded", () => { } }) - // HTTPS Everywhere Sites Disabled section in General Settings module - getOption_("disabledList", [], function(item) { + function addDisabledSite (domains) { let rule_host_parent = e("disabled-rules-wrapper"); - if( 0 === item.disabledList.length ) { - hide(rule_host_parent); - return; - } // img element "remove button" let templateRemove = document.createElement("img"); templateRemove.src = chrome.runtime.getURL("images/remove.png"); templateRemove.className = "remove"; - if( item ) { - for (const key of item.disabledList) { - let rule_host = document.createElement("div"); - let remove = templateRemove.cloneNode(true); - let rule_host_site_name = document.createElement("p"); - - rule_host.className = "disabled-rule-list-item"; - rule_host_site_name.className = "disabled-rule-list-item_single" - rule_host_site_name.innerText = key; - rule_host.appendChild( rule_host_site_name); - rule_host_parent.appendChild(rule_host); - rule_host.appendChild(remove); - - remove.addEventListener("click", () => { - hide( rule_host ); - sendMessage("enable_on_site", key); - }); - } + for (const key of domains) { + let rule_host = document.createElement("div"); + let remove = templateRemove.cloneNode(true); + let rule_host_site_name = document.createElement("p"); + + rule_host.className = "disabled-rule-list-item"; + rule_host_site_name.className = "disabled-rule-list-item_single" + rule_host_site_name.innerText = key; + rule_host.appendChild( rule_host_site_name); + rule_host_parent.appendChild(rule_host); + rule_host.appendChild(remove); + + remove.addEventListener("click", () => { + hide( rule_host ); + sendMessage("enable_on_site", key); + }); + } + } + + // HTTPS Everywhere Sites Disabled section in General Settings module + getOption_("disabledList", [], function(item) { + if (item && item.disabledList && item.disabledList.length > 0) { + addDisabledSite(item.disabledList); } }); + // Allow user t disable HTTPSE for a site + const add_disabled_site = document.getElementById("add-disabled-rule"); + const disabled_site_name = document.getElementById("disabled-domain-name"); + disabled_site_name.setAttribute("placeholder", chrome.i18n.getMessage("options_enterDisabledUrl")); + add_disabled_site.addEventListener("click", () => { + const host = disabled_site_name.value; + disabled_site_name.value = ""; + addDisabledSite([host]); + sendMessage("disable_on_site", host); + }) + add_update_channel.addEventListener("click", () => { const update_channel_name = update_channel_name_div.value; if(update_channel_name.trim() == "") { diff --git a/src/chrome/locale/en/https-everywhere.dtd b/src/chrome/locale/en/https-everywhere.dtd index e1eaddb1f0ff..298fc6c7fb66 100644 --- a/src/chrome/locale/en/https-everywhere.dtd +++ b/src/chrome/locale/en/https-everywhere.dtd @@ -26,6 +26,9 @@ + + + From 7272b33ab2fe4a0f8d767e08da48e686984ca15d Mon Sep 17 00:00:00 2001 From: Anton Bershanskiy Date: Sat, 4 May 2019 17:50:54 -0500 Subject: [PATCH 02/15] Refactor: camelCase (no real code changes) --- chromium/pages/options/ux.js | 386 ++++++++++++++++++----------------- 1 file changed, 194 insertions(+), 192 deletions(-) diff --git a/chromium/pages/options/ux.js b/chromium/pages/options/ux.js index 72f16f325c21..d202dcf48edd 100644 --- a/chromium/pages/options/ux.js +++ b/chromium/pages/options/ux.js @@ -43,16 +43,16 @@ document.addEventListener("DOMContentLoaded", () => { }); function onlyShowSection(sectionId) { - document.querySelectorAll('.section-wrapper').forEach(sw => { + document.querySelectorAll(".section-wrapper").forEach(sw => { sw.style.display = "none"; }); document.getElementById(sectionId).style.display = "block"; } - onlyShowSection('general-settings-wrapper'); + onlyShowSection("general-settings-wrapper"); - document.querySelectorAll('.section-header-span').forEach(shs => { + document.querySelectorAll(".section-header-span").forEach(shs => { shs.addEventListener("click", () => { - document.querySelectorAll('.section-header-span').forEach(shs => { + document.querySelectorAll(".section-header-span").forEach(shs => { shs.classList.remove("active"); shs.classList.add("inactive"); }); @@ -62,144 +62,144 @@ document.addEventListener("DOMContentLoaded", () => { }); }); - function create_update_channel_element(update_channel, last_updated, pinned) { - let ruleset_version_string; + function createUpdateChannelElement(updateChannel, lastUpdated, pinned) { + let rulesetVersionString; - if(last_updated) { - const ruleset_date = new Date(last_updated * 1000); - ruleset_version_string = ruleset_date.getUTCFullYear() + "." + (ruleset_date.getUTCMonth() + 1) + "." + ruleset_date.getUTCDate(); + if(lastUpdated) { + const rulesetDate = new Date(lastUpdated * 1000); + rulesetVersionString = rulesetDate.getUTCFullYear() + "." + (rulesetDate.getUTCMonth() + 1) + "." + rulesetDate.getUTCDate(); } else { - ruleset_version_string = "n/a"; + rulesetVersionString = "n/a"; } - const update_channel_div = document.createElement('div'); - update_channel_div.className = "update-channel"; - - const update_channel_name = document.createElement('div'); - update_channel_name.className = "update-channel-name"; - update_channel_name.innerText = update_channel.name; - update_channel_div.appendChild(update_channel_name); - const update_channel_last_updated = document.createElement('div'); - update_channel_last_updated.className = "update-channel-last-updated"; - update_channel_last_updated.innerText = chrome.i18n.getMessage("options_storedRulesetsVersion") + ruleset_version_string; - update_channel_name.appendChild(update_channel_last_updated); - - const update_channel_row_jwk = document.createElement('div'); - update_channel_row_jwk.className = "update-channel-row-jwk"; - update_channel_div.appendChild(update_channel_row_jwk); - const update_channel_jwk_column_left = document.createElement('div'); - update_channel_jwk_column_left.className = "update-channel-column-left"; - update_channel_jwk_column_left.innerText = "JWK:"; - update_channel_row_jwk.appendChild(update_channel_jwk_column_left); - const update_channel_jwk_column_right = document.createElement('div'); - update_channel_jwk_column_right.className = "update-channel-column-right"; - update_channel_row_jwk.appendChild(update_channel_jwk_column_right); - const update_channel_jwk = document.createElement('textarea'); - update_channel_jwk.className = "update-channel-jwk"; - update_channel_jwk.setAttribute("data-name", update_channel.name); - update_channel_jwk.disabled = pinned; - update_channel_jwk.innerText = JSON.stringify(update_channel.jwk); - update_channel_jwk_column_right.appendChild(update_channel_jwk); - - const update_channel_row_path_prefix = document.createElement('div'); - update_channel_row_path_prefix.className = "update-channel-row-path-prefix"; - update_channel_div.appendChild(update_channel_row_path_prefix); - const update_channel_path_prefix_column_left = document.createElement('div'); - update_channel_path_prefix_column_left.className = "update-channel-column-left"; - update_channel_path_prefix_column_left.innerText = "Path Prefix:"; - update_channel_row_path_prefix.appendChild(update_channel_path_prefix_column_left); - const update_channel_path_prefix_column_right = document.createElement('div'); - update_channel_path_prefix_column_right.className = "update-channel-column-right"; - update_channel_row_path_prefix.appendChild(update_channel_path_prefix_column_right); - const update_channel_path_prefix = document.createElement('input'); - update_channel_path_prefix.setAttribute("type", "text"); - update_channel_path_prefix.className = "update-channel-path-prefix"; - update_channel_path_prefix.setAttribute("data-name", update_channel.name); - update_channel_path_prefix.disabled = pinned; - update_channel_path_prefix.value = update_channel.update_path_prefix; - update_channel_path_prefix_column_right.appendChild(update_channel_path_prefix); - - let clearer = document.createElement('div'); + const updateChannelDiv = document.createElement("div"); + updateChannelDiv.className = "update-channel"; + + const updateChannelName = document.createElement("div"); + updateChannelName.className = "update-channel-name"; + updateChannelName.innerText = updateChannel.name; + updateChannelDiv.appendChild(updateChannelName); + const updateChannelLastUpdated = document.createElement("div"); + updateChannelLastUpdated.className = "update-channel-last-updated"; + updateChannelLastUpdated.innerText = chrome.i18n.getMessage("options_storedRulesetsVersion") + rulesetVersionString; + updateChannelName.appendChild(updateChannelLastUpdated); + + const updateChannelRowJwk = document.createElement("div"); + updateChannelRowJwk.className = "update-channel-row-jwk"; + updateChannelDiv.appendChild(updateChannelRowJwk); + const updateChannelJwkColumnLeft = document.createElement("div"); + updateChannelJwkColumnLeft.className = "update-channel-column-left"; + updateChannelJwkColumnLeft.innerText = "JWK:"; + updateChannelRowJwk.appendChild(updateChannelJwkColumnLeft); + const updateChannelJwkColumnRight = document.createElement("div"); + updateChannelJwkColumnRight.className = "update-channel-column-right"; + updateChannelRowJwk.appendChild(updateChannelJwkColumnRight); + const updateChannelJwk = document.createElement("textarea"); + updateChannelJwk.className = "update-channel-jwk"; + updateChannelJwk.setAttribute("data-name", updateChannel.name); + updateChannelJwk.disabled = pinned; + updateChannelJwk.innerText = JSON.stringify(updateChannel.jwk); + updateChannelJwkColumnRight.appendChild(updateChannelJwk); + + const updateChannelRowPathPrefix = document.createElement("div"); + updateChannelRowPathPrefix.className = "update-channel-row-path-prefix"; + updateChannelDiv.appendChild(updateChannelRowPathPrefix); + const updateChannelPathPrefixColumnLeft = document.createElement("div"); + updateChannelPathPrefixColumnLeft.className = "update-channel-column-left"; + updateChannelPathPrefixColumnLeft.innerText = "Path Prefix:"; + updateChannelRowPathPrefix.appendChild(updateChannelPathPrefixColumnLeft); + const updateChannelPathPrefixColumnRight = document.createElement("div"); + updateChannelPathPrefixColumnRight.className = "update-channel-column-right"; + updateChannelRowPathPrefix.appendChild(updateChannelPathPrefixColumnRight); + const updateChannelPathPrefix = document.createElement("input"); + updateChannelPathPrefix.setAttribute("type", "text"); + updateChannelPathPrefix.className = "update-channel-path-prefix"; + updateChannelPathPrefix.setAttribute("data-name", updateChannel.name); + updateChannelPathPrefix.disabled = pinned; + updateChannelPathPrefix.value = updateChannel.update_path_prefix; + updateChannelPathPrefixColumnRight.appendChild(updateChannelPathPrefix); + + let clearer = document.createElement("div"); clearer.className = "clearer"; - update_channel_div.appendChild(clearer); - - const update_channel_row_scope = document.createElement('div'); - update_channel_row_scope.className = "update-channel-row-scope"; - update_channel_div.appendChild(update_channel_row_scope); - const update_channel_scope_column_left = document.createElement('div'); - update_channel_scope_column_left.className = "update-channel-column-left"; - update_channel_scope_column_left.innerText = "Scope:"; - update_channel_row_scope.appendChild(update_channel_scope_column_left); - const update_channel_scope_column_right = document.createElement('div'); - update_channel_scope_column_right.className = "update-channel-column-right"; - update_channel_row_scope.appendChild(update_channel_scope_column_right); - const update_channel_scope = document.createElement('input'); - update_channel_scope.setAttribute("type", "text"); - update_channel_scope.className = "update-channel-scope"; - update_channel_scope.setAttribute("data-name", update_channel.name); - update_channel_scope.disabled = pinned; - update_channel_scope.value = update_channel.scope; - update_channel_scope_column_right.appendChild(update_channel_scope); - - const update_channel_row_controls = document.createElement('div'); - update_channel_row_controls.className = "update-channel-row-controls"; - update_channel_div.appendChild(update_channel_row_controls); - const update_channel_controls_column_left = document.createElement('div'); - update_channel_controls_column_left.className = "update-channel-column-left"; - update_channel_controls_column_left.innerText = " "; - update_channel_row_controls.appendChild(update_channel_controls_column_left); - const update_channel_controls_column_right = document.createElement('div'); - update_channel_controls_column_right.className = "update-channel-column-right"; - update_channel_row_controls.appendChild(update_channel_controls_column_right); - const update_channel_update = document.createElement('button'); - update_channel_update.className = "update-channel-update"; - update_channel_update.setAttribute("data-name", update_channel.name); - update_channel_update.disabled = pinned; - update_channel_update.innerText = chrome.i18n.getMessage("options_update"); - update_channel_controls_column_right.appendChild(update_channel_update); - const update_channel_delete = document.createElement('button'); - update_channel_delete.className = "update-channel-update"; - update_channel_delete.setAttribute("data-name", update_channel.name); - update_channel_delete.disabled = pinned; - update_channel_delete.innerText = chrome.i18n.getMessage("options_delete"); - update_channel_controls_column_right.appendChild(update_channel_delete); - - clearer = document.createElement('div'); + updateChannelDiv.appendChild(clearer); + + const updateChannelRowScope = document.createElement("div"); + updateChannelRowScope.className = "update-channel-row-scope"; + updateChannelDiv.appendChild(updateChannelRowScope); + const updateChannelScopeColumnLeft = document.createElement("div"); + updateChannelScopeColumnLeft.className = "update-channel-column-left"; + updateChannelScopeColumnLeft.innerText = "Scope:"; + updateChannelRowScope.appendChild(updateChannelScopeColumnLeft); + const updateChannelScopeColumnRight = document.createElement("div"); + updateChannelScopeColumnRight.className = "update-channel-column-right"; + updateChannelRowScope.appendChild(updateChannelScopeColumnRight); + const updateChannelScope = document.createElement("input"); + updateChannelScope.setAttribute("type", "text"); + updateChannelScope.className = "update-channel-scope"; + updateChannelScope.setAttribute("data-name", updateChannel.name); + updateChannelScope.disabled = pinned; + updateChannelScope.value = updateChannel.scope; + updateChannelScopeColumnRight.appendChild(updateChannelScope); + + const updateChannelRowControls = document.createElement("div"); + updateChannelRowControls.className = "update-channel-row-controls"; + updateChannelDiv.appendChild(updateChannelRowControls); + const updateChannelControlsColumnLeft = document.createElement("div"); + updateChannelControlsColumnLeft.className = "update-channel-column-left"; + updateChannelControlsColumnLeft.innerText = " "; + updateChannelRowControls.appendChild(updateChannelControlsColumnLeft); + const updateChannelControlsColumnRight = document.createElement("div"); + updateChannelControlsColumnRight.className = "update-channel-column-right"; + updateChannelRowControls.appendChild(updateChannelControlsColumnRight); + const updateChannelUpdate = document.createElement("button"); + updateChannelUpdate.className = "update-channel-update"; + updateChannelUpdate.setAttribute("data-name", updateChannel.name); + updateChannelUpdate.disabled = pinned; + updateChannelUpdate.innerText = chrome.i18n.getMessage("options_update"); + updateChannelControlsColumnRight.appendChild(updateChannelUpdate); + const updateChannelDelete = document.createElement("button"); + updateChannelDelete.className = "update-channel-update"; + updateChannelDelete.setAttribute("data-name", updateChannel.name); + updateChannelDelete.disabled = pinned; + updateChannelDelete.innerText = chrome.i18n.getMessage("options_delete"); + updateChannelControlsColumnRight.appendChild(updateChannelDelete); + + clearer = document.createElement("div"); clearer.className = "clearer"; - update_channel_div.appendChild(clearer); + updateChannelDiv.appendChild(clearer); - update_channel_delete.addEventListener("click", () => { - sendMessage("delete_update_channel", update_channel.name, () => { - render_update_channels(); + updateChannelDelete.addEventListener("click", () => { + sendMessage("delete_update_channel", updateChannel.name, () => { + renderUpdateChannels(); }); }); - update_channel_update.addEventListener("click", () => { + updateChannelUpdate.addEventListener("click", () => { sendMessage("update_update_channel", { - name: update_channel.name, - jwk: JSON.parse(update_channel_jwk.value), - update_path_prefix: update_channel_path_prefix.value, - scope: update_channel_scope.value + name: updateChannel.name, + jwk: JSON.parse(updateChannelJwk.value), + update_path_prefix: updateChannelPathPrefix.value, + scope: updateChannelScope.value }, () => { - render_update_channels(); + renderUpdateChannels(); }); }); - return update_channel_div; + return updateChannelDiv; } - function render_update_channels() { - const update_channels_list = document.getElementById("update-channels-list"); - while(update_channels_list.firstChild) { - update_channels_list.removeChild(update_channels_list.firstChild); + function renderUpdateChannels() { + const updateChannelsList = document.getElementById("update-channels-list"); + while(updateChannelsList.firstChild) { + updateChannelsList.removeChild(updateChannelsList.firstChild); } sendMessage("get_pinned_update_channels", null, item => { - for(const update_channel of item.update_channels) { - update_channels_list.appendChild( - create_update_channel_element( - update_channel, - item.last_updated[update_channel.name], + for(const updateChannel of item.update_channels) { + updateChannelsList.appendChild( + createUpdateChannelElement( + updateChannel, + item.last_updated[updateChannel.name], true ) ); @@ -208,88 +208,89 @@ document.addEventListener("DOMContentLoaded", () => { }); sendMessage("get_stored_update_channels", null, item => { - for(const update_channel of item.update_channels) { - update_channels_list.appendChild( - create_update_channel_element( - update_channel, - item.last_updated[update_channel.name], + for(const updateChannel of item.update_channels) { + updateChannelsList.appendChild( + createUpdateChannelElement( + updateChannel, + item.last_updated[updateChannel.name], false ) ); } }); } - render_update_channels(); + renderUpdateChannels(); - const add_update_channel = document.getElementById("add-update-channel"); - const update_channel_name_div = document.getElementById("update-channel-name"); - const update_channels_error_text = document.getElementById("update-channels-error-text"); - const update_channels_error = document.getElementById("update-channels-error"); - update_channel_name_div.setAttribute("placeholder", chrome.i18n.getMessage("options_enterUpdateChannelName")); + const addApdateChannel = document.getElementById("add-update-channel"); + const updateChannelNameDiv = document.getElementById("update-channel-name"); + const updateChannelsErrorText = document.getElementById("update-channels-error-text"); + const updateChannelsError = document.getElementById("update-channels-error"); + updateChannelNameDiv.setAttribute("placeholder", chrome.i18n.getMessage("options_enterUpdateChannelName")); function displayError(text) { - update_channels_error_text.innerText = text; - update_channels_error.style.display = "block"; + updateChannelsErrorText.innerText = text; + updateChannelsError.style.display = "block"; window.scrollTo(0,0); } // Get a list of user Rules sendMessage("get_user_rules", null, userRules => { - let user_rules_parent = e("user-rules-wrapper"); + const userRulesParent = e("user-rules-wrapper"); if ( 0 === userRules.length) { - hide(user_rules_parent); + hide(userRulesParent); return ; } // img element "remove button" - let templateRemove = document.createElement("img"); + const templateRemove = document.createElement("img"); templateRemove.src = chrome.runtime.getURL("images/remove.png"); templateRemove.className = "remove"; for (const userRule of userRules) { - let user_rule_host = document.createElement("div"); - let user_rule_name = document.createElement("p"); - let remove = templateRemove.cloneNode(true); + const userRuleHost = document.createElement("div"); + const userRuleName = document.createElement("p"); + const remove = templateRemove.cloneNode(true); - user_rule_host.className = "user-rules-list-item"; - user_rule_name.className = "user-rules-list-item-single" - user_rule_name.innerText = userRule.name; - user_rule_host.appendChild(user_rule_name); - user_rules_parent.appendChild(user_rule_host); - user_rule_host.appendChild(remove); + userRuleHost.className = "user-rules-list-item"; + userRuleName.className = "user-rules-list-item-single" + userRuleName.innerText = userRule.name; + userRuleHost.appendChild(userRuleName); + userRulesParent.appendChild(userRuleHost); + userRuleHost.appendChild(remove); remove.addEventListener("click", () => { // assume the removal is successful and hide ui element - hide( user_rule_host ); + hide(userRuleHost); // remove the user rule - sendMessage("remove_rule", { ruleset: userRule, src: 'options' }); + sendMessage("remove_rule", { ruleset: userRule, src: "options" }); }); } }) + // Displays a list of disabled sites for a list of domains function addDisabledSite (domains) { - let rule_host_parent = e("disabled-rules-wrapper"); + const ruleHostParent = e("disabled-rules-wrapper"); // img element "remove button" - let templateRemove = document.createElement("img"); + const templateRemove = document.createElement("img"); templateRemove.src = chrome.runtime.getURL("images/remove.png"); templateRemove.className = "remove"; for (const key of domains) { - let rule_host = document.createElement("div"); - let remove = templateRemove.cloneNode(true); - let rule_host_site_name = document.createElement("p"); + const ruleHost = document.createElement("div"); + const remove = templateRemove.cloneNode(true); + const ruleHostSiteName = document.createElement("p"); - rule_host.className = "disabled-rule-list-item"; - rule_host_site_name.className = "disabled-rule-list-item_single" - rule_host_site_name.innerText = key; - rule_host.appendChild( rule_host_site_name); - rule_host_parent.appendChild(rule_host); - rule_host.appendChild(remove); + ruleHost.className = "disabled-rule-list-item"; + ruleHostSiteName.className = "disabled-rule-list-item_single" + ruleHostSiteName.innerText = key; + ruleHost.appendChild(ruleHostSiteName); + ruleHostParent.appendChild(ruleHost); + ruleHost.appendChild(remove); remove.addEventListener("click", () => { - hide( rule_host ); + hide(ruleHost); sendMessage("enable_on_site", key); }); } @@ -302,26 +303,27 @@ document.addEventListener("DOMContentLoaded", () => { } }); - // Allow user t disable HTTPSE for a site - const add_disabled_site = document.getElementById("add-disabled-rule"); - const disabled_site_name = document.getElementById("disabled-domain-name"); - disabled_site_name.setAttribute("placeholder", chrome.i18n.getMessage("options_enterDisabledUrl")); - add_disabled_site.addEventListener("click", () => { - const host = disabled_site_name.value; - disabled_site_name.value = ""; + // Allow user to disable HTTPSE for a site + const addDisabledSiteBtn = document.getElementById("add-disabled-rule"); + const disabledSiteName = document.getElementById("disabled-domain-name"); + disabledSiteName.setAttribute("placeholder", chrome.i18n.getMessage("options_enterDisabledUrl")); + addDisabledSiteBtn.addEventListener("click", () => { + // TODO: use form submit event instead? + const host = disabledSiteName.value; + disabledSiteName.value = ""; addDisabledSite([host]); sendMessage("disable_on_site", host); }) - add_update_channel.addEventListener("click", () => { - const update_channel_name = update_channel_name_div.value; - if(update_channel_name.trim() == "") { + addApdateChannel.addEventListener("click", () => { + const updateChannelName = updateChannelNameDiv.value; + if(updateChannelName.trim() == "") { displayError("Error: The update channel name is blank. Please enter another name."); } else { - update_channel_name_div.value = ""; - sendMessage("create_update_channel", update_channel_name, result => { + updateChannelNameDiv.value = ""; + sendMessage("create_update_channel", updateChannelName, result => { if(result == true) { - render_update_channels(); + renderUpdateChannels(); } else { displayError("Error: There already exists an update channel with this name."); } @@ -329,30 +331,30 @@ document.addEventListener("DOMContentLoaded", () => { } }); - const update_channels_error_hide = document.getElementById("update-channels-error-hide"); - update_channels_error_hide.addEventListener("click", () => { - update_channels_error.style.display = "none"; + const updateChannelsErrorHide = document.getElementById("update-channels-error-hide"); + updateChannelsErrorHide.addEventListener("click", () => { + updateChannelsError.style.display = "none"; }); - const update_channels_last_checked = document.getElementById("update-channels-last-checked"); - sendMessage("get_last_checked", null, last_checked => { - let last_checked_string; - if(last_checked) { - const last_checked_date = new Date(last_checked * 1000); + const updateChannelsLastChecked = document.getElementById("update-channels-last-checked"); + sendMessage("get_last_checked", null, lastChecked => { + let lastCheckedString; + if(lastChecked) { + const lastCheckedDate = new Date(lastChecked * 1000); const options = { - year: '2-digit', - month: '2-digit', - day: '2-digit', - hour: '2-digit', - minute: '2-digit', - timeZoneName: 'short' + year: "2-digit", + month: "2-digit", + day: "2-digit", + hour: "2-digit", + minute: "2-digit", + timeZoneName: "short" }; - const customDateTime = new Intl.DateTimeFormat('default', options).format; - last_checked_string = customDateTime(last_checked_date); + const customDateTime = new Intl.DateTimeFormat("default", options).format; + lastCheckedString = customDateTime(lastCheckedDate); } else { - last_checked_string = chrome.i18n.getMessage("options_updatesLastCheckedNever"); + lastCheckedString = chrome.i18n.getMessage("options_updatesLastCheckedNever"); } - update_channels_last_checked.innerText = chrome.i18n.getMessage("options_updatesLastChecked") + last_checked_string; + updateChannelsLastChecked.innerText = chrome.i18n.getMessage("options_updatesLastChecked") + lastCheckedString; }); document.onkeydown = function(evt) { From 780990829221d46c64bf585b601d6f850a20903e Mon Sep 17 00:00:00 2001 From: Anton Bershanskiy Date: Sat, 4 May 2019 18:25:38 -0500 Subject: [PATCH 03/15] WIP: Add Options menu to disable extension on a domain --- chromium/pages/options/index.html | 21 ++++----- chromium/pages/options/style.css | 10 ++--- chromium/pages/options/ux.js | 74 ++++++++++++++++++++++--------- 3 files changed, 68 insertions(+), 37 deletions(-) diff --git a/chromium/pages/options/index.html b/chromium/pages/options/index.html index 06673f00d10b..bfa0d067c13a 100644 --- a/chromium/pages/options/index.html +++ b/chromium/pages/options/index.html @@ -10,6 +10,11 @@ +
+ + +
+
@@ -24,11 +29,11 @@

-
+
- -
+ +
@@ -44,18 +49,14 @@
-
- - -
-
- +
+ -
+
diff --git a/chromium/pages/options/style.css b/chromium/pages/options/style.css index 75e86977f24c..904f150a0627 100644 --- a/chromium/pages/options/style.css +++ b/chromium/pages/options/style.css @@ -135,7 +135,7 @@ div.update-channel-row-scope { border-radius: 7px; } -button#add-update-channel, button#add-disabled-rule { +input#add-update-channel, input#add-disabled-rule { float: right; margin: 0px 10px 10px 10px; border-radius: 7px; @@ -155,14 +155,14 @@ input#update-channel-name{ font-size: 10px; } -div#update-channels-error, div#update-channels-warning { +div#user-input-error, div#update-channels-warning { margin-top: 20px; font-weight: bold; padding: 10px; border-radius: 10px; } -div#update-channels-error { +div#user-input-error { background-color: #CC3333; display: none; color: white; @@ -173,12 +173,12 @@ div#update-channels-warning { font-color: black; } -#update-channels-error-text{ +#user-input-error-text{ display: inline-block; width: 460px; } -img#update-channels-error-hide { +img#user-input-error-hide { float: right; } diff --git a/chromium/pages/options/ux.js b/chromium/pages/options/ux.js index d202dcf48edd..8c2f2bbc0665 100644 --- a/chromium/pages/options/ux.js +++ b/chromium/pages/options/ux.js @@ -42,7 +42,23 @@ document.addEventListener("DOMContentLoaded", () => { }); }); + // Display feedback to incorrect user input + const userInputError = document.getElementById("user-input-error"); + function displayError(text) { + const userInputErrorText = document.getElementById("user-input-error-text"); + userInputErrorText.innerText = text; + userInputError.style.display = "block"; + window.scrollTo(0,0); + } + + function hideErrors() { + userInputError.style.display = "none"; + } + + document.getElementById("user-input-error-hide").addEventListener("click", hideErrors); + function onlyShowSection(sectionId) { + hideErrors(); document.querySelectorAll(".section-wrapper").forEach(sw => { sw.style.display = "none"; }); @@ -221,18 +237,10 @@ document.addEventListener("DOMContentLoaded", () => { } renderUpdateChannels(); - const addApdateChannel = document.getElementById("add-update-channel"); + const addUpdateChannelForm = document.getElementById("add-update-channel-form"); const updateChannelNameDiv = document.getElementById("update-channel-name"); - const updateChannelsErrorText = document.getElementById("update-channels-error-text"); - const updateChannelsError = document.getElementById("update-channels-error"); updateChannelNameDiv.setAttribute("placeholder", chrome.i18n.getMessage("options_enterUpdateChannelName")); - function displayError(text) { - updateChannelsErrorText.innerText = text; - updateChannelsError.style.display = "block"; - window.scrollTo(0,0); - } - // Get a list of user Rules sendMessage("get_user_rules", null, userRules => { const userRulesParent = e("user-rules-wrapper"); @@ -303,19 +311,45 @@ document.addEventListener("DOMContentLoaded", () => { } }); - // Allow user to disable HTTPSE for a site - const addDisabledSiteBtn = document.getElementById("add-disabled-rule"); + function validateDomain(domain) { + // TODO: + // this is incredibly simplistic placeholder + // the actual function will be implemented by @pipboy96 + // enter "error" to test error message + if (domain === "error") + return null + // "No Error" + domain = domain.trim().toLowerCase() + return domain + } + + // Allow user to disable HTTPS Everywhere for a site + const addDisabledSiteForm = document.getElementById("add-disabled-rule-form"); const disabledSiteName = document.getElementById("disabled-domain-name"); disabledSiteName.setAttribute("placeholder", chrome.i18n.getMessage("options_enterDisabledUrl")); - addDisabledSiteBtn.addEventListener("click", () => { - // TODO: use form submit event instead? - const host = disabledSiteName.value; - disabledSiteName.value = ""; - addDisabledSite([host]); - sendMessage("disable_on_site", host); + addDisabledSiteForm.addEventListener("submit", (e) => { + // TODO: check if this domain is already in the disabled list + // this would be trivial if the disabled list was stored, but then we would need to update it when user interacts with Popup UI + // prevent page reload + e.preventDefault(); + // hide past feedback, if there was any + hideErrors(); + const domain = disabledSiteName.value; + const validated = validateDomain(domain); + if (validated === null) { + // incorrect domain + displayError("TODO: what is the error?"); + } else { + // correct domain + disabledSiteName.value = ""; + addDisabledSite([validated]); + sendMessage("disable_on_site", validated); + } }) - addApdateChannel.addEventListener("click", () => { + addUpdateChannelForm.addEventListener("submit", (e) => { + e.preventDefault(); + hideErrors(); const updateChannelName = updateChannelNameDiv.value; if(updateChannelName.trim() == "") { displayError("Error: The update channel name is blank. Please enter another name."); @@ -331,10 +365,6 @@ document.addEventListener("DOMContentLoaded", () => { } }); - const updateChannelsErrorHide = document.getElementById("update-channels-error-hide"); - updateChannelsErrorHide.addEventListener("click", () => { - updateChannelsError.style.display = "none"; - }); const updateChannelsLastChecked = document.getElementById("update-channels-last-checked"); sendMessage("get_last_checked", null, lastChecked => { From c49d3a0e55ab916653e8319c66f9e37cb8005f7c Mon Sep 17 00:00:00 2001 From: Anton Bershanskiy Date: Sat, 4 May 2019 21:53:46 -0500 Subject: [PATCH 04/15] Refactor: more const --- chromium/pages/options/ux.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/chromium/pages/options/ux.js b/chromium/pages/options/ux.js index 8c2f2bbc0665..2cacc1dcbea3 100644 --- a/chromium/pages/options/ux.js +++ b/chromium/pages/options/ux.js @@ -135,9 +135,9 @@ document.addEventListener("DOMContentLoaded", () => { updateChannelPathPrefix.value = updateChannel.update_path_prefix; updateChannelPathPrefixColumnRight.appendChild(updateChannelPathPrefix); - let clearer = document.createElement("div"); - clearer.className = "clearer"; - updateChannelDiv.appendChild(clearer); + const clearer1 = document.createElement("div"); + clearer1.className = "clearer"; + updateChannelDiv.appendChild(clearer1); const updateChannelRowScope = document.createElement("div"); updateChannelRowScope.className = "update-channel-row-scope"; @@ -180,9 +180,9 @@ document.addEventListener("DOMContentLoaded", () => { updateChannelDelete.innerText = chrome.i18n.getMessage("options_delete"); updateChannelControlsColumnRight.appendChild(updateChannelDelete); - clearer = document.createElement("div"); - clearer.className = "clearer"; - updateChannelDiv.appendChild(clearer); + const clearer2 = document.createElement("div"); + clearer2.className = "clearer"; + updateChannelDiv.appendChild(clearer2); updateChannelDelete.addEventListener("click", () => { sendMessage("delete_update_channel", updateChannel.name, () => { From 827a07a8e3f452e99afd56b621701a17cd52acc6 Mon Sep 17 00:00:00 2001 From: Anton Bershanskiy Date: Sat, 4 May 2019 22:27:48 -0500 Subject: [PATCH 05/15] refactor --- chromium/pages/options/index.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chromium/pages/options/index.html b/chromium/pages/options/index.html index bfa0d067c13a..7a141c67cfff 100644 --- a/chromium/pages/options/index.html +++ b/chromium/pages/options/index.html @@ -4,6 +4,9 @@ + + + @@ -59,8 +62,5 @@ - - - From b2bddf18a5e50b1242d0f74a3b9345b98505b40d Mon Sep 17 00:00:00 2001 From: Anton Bershanskiy Date: Sat, 4 May 2019 23:54:15 -0500 Subject: [PATCH 06/15] WIP: refactor and allow to disable for domain from Options --- chromium/pages/options/index.html | 1 + chromium/pages/options/ux.js | 59 ++++-- chromium/pages/punycode.js | 247 ++++++++++++++++++++++ src/chrome/locale/en/https-everywhere.dtd | 3 + 4 files changed, 290 insertions(+), 20 deletions(-) create mode 100644 chromium/pages/punycode.js diff --git a/chromium/pages/options/index.html b/chromium/pages/options/index.html index 7a141c67cfff..bc007cc20df1 100644 --- a/chromium/pages/options/index.html +++ b/chromium/pages/options/index.html @@ -5,6 +5,7 @@ + diff --git a/chromium/pages/options/ux.js b/chromium/pages/options/ux.js index 2cacc1dcbea3..2a02e5d6875c 100644 --- a/chromium/pages/options/ux.js +++ b/chromium/pages/options/ux.js @@ -219,7 +219,6 @@ document.addEventListener("DOMContentLoaded", () => { true ) ); - } }); @@ -261,7 +260,7 @@ document.addEventListener("DOMContentLoaded", () => { const remove = templateRemove.cloneNode(true); userRuleHost.className = "user-rules-list-item"; - userRuleName.className = "user-rules-list-item-single" + userRuleName.className = "user-rules-list-item-single"; userRuleName.innerText = userRule.name; userRuleHost.appendChild(userRuleName); userRulesParent.appendChild(userRuleHost); @@ -274,7 +273,7 @@ document.addEventListener("DOMContentLoaded", () => { sendMessage("remove_rule", { ruleset: userRule, src: "options" }); }); } - }) + }); // Displays a list of disabled sites for a list of domains function addDisabledSite (domains) { @@ -286,13 +285,22 @@ document.addEventListener("DOMContentLoaded", () => { templateRemove.className = "remove"; for (const key of domains) { + // If it is valid Punycode, display Unicode label + let display; + try { + const unicode = toUnicode(key); + display = unicode; + } catch(e) { + display = key; + } + const ruleHost = document.createElement("div"); const remove = templateRemove.cloneNode(true); const ruleHostSiteName = document.createElement("p"); ruleHost.className = "disabled-rule-list-item"; - ruleHostSiteName.className = "disabled-rule-list-item_single" - ruleHostSiteName.innerText = key; + ruleHostSiteName.className = "disabled-rule-list-item_single"; + ruleHostSiteName.innerText = display; ruleHost.appendChild(ruleHostSiteName); ruleHostParent.appendChild(ruleHost); ruleHost.appendChild(remove); @@ -312,15 +320,23 @@ document.addEventListener("DOMContentLoaded", () => { }); function validateDomain(domain) { - // TODO: - // this is incredibly simplistic placeholder - // the actual function will be implemented by @pipboy96 - // enter "error" to test error message - if (domain === "error") + // Checks whether input is a valid domain and returns it in a canonocal form + // TODO: should apply Punycode before or after toLowerCase()? + // TODO: what if toASCII errors out? + domain = domain.trim(); + try { + domain = toASCII(domain); + } catch(e) { + // This domain is not representable as Punycode return null - // "No Error" - domain = domain.trim().toLowerCase() - return domain + } + domain = domain.toLowerCase(); + const pattern = /^(\*|[a-z0-9_-]+)(\.[a-z0-9_-]+)*$/ + const match = pattern.test(domain); + if (match !== true){ + domain = null; + } + return domain; } // Allow user to disable HTTPS Everywhere for a site @@ -338,28 +354,31 @@ document.addEventListener("DOMContentLoaded", () => { const validated = validateDomain(domain); if (validated === null) { // incorrect domain - displayError("TODO: what is the error?"); + const message = chrome.i18n.getMessage("options_addDisabledSiteFormatError"); + displayError(message); } else { // correct domain disabledSiteName.value = ""; addDisabledSite([validated]); sendMessage("disable_on_site", validated); } - }) + }); addUpdateChannelForm.addEventListener("submit", (e) => { e.preventDefault(); hideErrors(); const updateChannelName = updateChannelNameDiv.value; - if(updateChannelName.trim() == "") { - displayError("Error: The update channel name is blank. Please enter another name."); + if(updateChannelName.trim() === "") { + const message = chrome.i18n.getMessage("options_addUpdateChannelErrorBlank"); + displayError(message); } else { updateChannelNameDiv.value = ""; sendMessage("create_update_channel", updateChannelName, result => { - if(result == true) { + if(result === true) { renderUpdateChannels(); } else { - displayError("Error: There already exists an update channel with this name."); + const message = chrome.i18n.getMessage("options_addUpdateChannelErrorExists"); + displayError(message); } }); } @@ -389,7 +408,7 @@ document.addEventListener("DOMContentLoaded", () => { document.onkeydown = function(evt) { evt = evt || window.event; - if (evt.ctrlKey && evt.keyCode == 90) { + if (evt.ctrlKey && evt.keyCode === 90) { window.open("/pages/debugging-rulesets/index.html"); } }; diff --git a/chromium/pages/punycode.js b/chromium/pages/punycode.js new file mode 100644 index 000000000000..9eb4707bdde1 --- /dev/null +++ b/chromium/pages/punycode.js @@ -0,0 +1,247 @@ +const { toASCII, toUnicode } = (() => { + /** + * This code is derived from punycode.js (https://github.com/bestiejs/punycode.js). + * + * Copyright Mathias Bynens + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + const maxInt = 2147483647 + + const base = 36 + const tMin = 1 + const tMax = 26 + const skew = 38 + const damp = 700 + const initialBias = 72 + const initialN = 128 + const delimiter = '-' + + const regexPunycode = /^xn--/ + const regexNonASCII = /[^\0-\x7E]/ + const regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g + + const baseMinusTMin = base - tMin + + const mapDomain = (string, fn) => { + const parts = string.split('@') + let result = '' + if (parts.length > 1) { + result = parts[0] + '@' + string = parts[1] + } + + string = string.replace(regexSeparators, '.') + const labels = string.split('.') + const encoded = labels.map(fn).join('.') + return result + encoded + } + + const ucs2decode = string => { + const output = [] + let counter = 0 + const length = string.length + while (counter < length) { + const value = string.charCodeAt(counter++) + if (value >= 0xD800 && value <= 0xDBFF && counter < length) { + const extra = string.charCodeAt(counter++) + if ((extra & 0xFC00) === 0xDC00) { + output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000) + } else { + output.push(value) + counter-- + } + } else { + output.push(value) + } + } + return output + } + + const basicToDigit = codePoint => { + if (codePoint - 0x30 < 0x0A) { + return codePoint - 0x16 + } + if (codePoint - 0x41 < 0x1A) { + return codePoint - 0x41 + } + if (codePoint - 0x61 < 0x1A) { + return codePoint - 0x61 + } + return base + } + + const digitToBasic = (digit, flag) => digit + 22 + 75 * (digit < 26) - ((flag !== 0) << 5) + + const adapt = (delta, numPoints, firstTime) => { + let k = 0 + delta = firstTime ? Math.floor(delta / damp) : delta >> 1 + delta += Math.floor(delta / numPoints) + for (; delta > baseMinusTMin * tMax >> 1; k += base) { + delta = Math.floor(delta / baseMinusTMin) + } + return Math.floor(k + (baseMinusTMin + 1) * delta / (delta + skew)) + } + + const decode = input => { + const output = [] + const inputLength = input.length + let i = 0 + let n = initialN + let bias = initialBias + + let basic = input.lastIndexOf(delimiter) + if (basic < 0) { + basic = 0 + } + + for (let j = 0; j < basic; ++j) { + if (input.charCodeAt(j) >= 0x80) { + throw new Error('Illegal input >= 0x80 (not a basic code point)') + } + output.push(input.charCodeAt(j)) + } + + for (let index = basic > 0 ? basic + 1 : 0; index < inputLength;) { + const oldi = i + for (let w = 1, k = base; ; k += base) { + if (index >= inputLength) { + throw new Error('Invalid input') + } + + const digit = basicToDigit(input.charCodeAt(index++)) + + if (digit >= base || digit > Math.floor((maxInt - i) / w)) { + throw new Error('Overflow: input needs wider integers to process') + } + + i += digit * w + const t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias) + + if (digit < t) { + break + } + + const baseMinusT = base - t + if (w > Math.floor(maxInt / baseMinusT)) { + throw new Error('Overflow: input needs wider integers to process') + } + + w *= baseMinusT + } + + const out = output.length + 1 + bias = adapt(i - oldi, out, oldi === 0) + + if (Math.floor(i / out) > maxInt - n) { + throw new Error('Overflow: input needs wider integers to process') + } + + n += Math.floor(i / out) + i %= out + + output.splice(i++, 0, n) + } + + return String.fromCodePoint(...output) + } + + const encode = input => { + const output = [] + + input = ucs2decode(input) + + const inputLength = input.length + + let n = initialN + let delta = 0 + let bias = initialBias + + for (const currentValue of input) { + if (currentValue < 0x80) { + output.push(String.fromCharCode(currentValue)) + } + } + + const basicLength = output.length + let handledCPCount = basicLength + + if (basicLength) { + output.push(delimiter) + } + + while (handledCPCount < inputLength) { + let m = maxInt + for (const currentValue of input) { + if (currentValue >= n && currentValue < m) { + m = currentValue + } + } + + const handledCPCountPlusOne = handledCPCount + 1 + if (m - n > Math.floor((maxInt - delta) / handledCPCountPlusOne)) { + throw new Error('Overflow: input needs wider integers to process') + } + + delta += (m - n) * handledCPCountPlusOne + n = m + + for (const currentValue of input) { + if (currentValue < n && ++delta > maxInt) { + throw new Error('Overflow: input needs wider integers to process') + } + + if (currentValue === n) { + let q = delta + for (let k = base; ; k += base) { + const t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias) + + if (q < t) { + break + } + + const qMinusT = q - t + const baseMinusT = base - t + output.push( + String.fromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) + ) + q = Math.floor(qMinusT / baseMinusT) + } + + output.push(String.fromCharCode(digitToBasic(q, 0))) + bias = adapt(delta, handledCPCountPlusOne, handledCPCount === basicLength) + delta = 0 + ++handledCPCount + } + } + + ++delta + ++n + } + return output.join('') + } + + const toUnicode = input => mapDomain(input, string => regexPunycode.test(string) ? decode(string.slice(4).toLowerCase()) : string) + + const toASCII = input => mapDomain(input, string => regexNonASCII.test(string) ? 'xn--' + encode(string) : string) + + return { toASCII, toUnicode } +})() \ No newline at end of file diff --git a/src/chrome/locale/en/https-everywhere.dtd b/src/chrome/locale/en/https-everywhere.dtd index 298fc6c7fb66..a280c64fbdc7 100644 --- a/src/chrome/locale/en/https-everywhere.dtd +++ b/src/chrome/locale/en/https-everywhere.dtd @@ -26,11 +26,14 @@ + + + From 416d8728fc1050dae620cfb7b98ffddb6e107be1 Mon Sep 17 00:00:00 2001 From: pipboy96 Date: Sun, 5 May 2019 08:02:34 +0300 Subject: [PATCH 07/15] newline --- chromium/pages/punycode.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chromium/pages/punycode.js b/chromium/pages/punycode.js index 9eb4707bdde1..36e0f0a536e1 100644 --- a/chromium/pages/punycode.js +++ b/chromium/pages/punycode.js @@ -244,4 +244,4 @@ const { toASCII, toUnicode } = (() => { const toASCII = input => mapDomain(input, string => regexNonASCII.test(string) ? 'xn--' + encode(string) : string) return { toASCII, toUnicode } -})() \ No newline at end of file +})() From 3fd7992e381c30cbc45efd486e62c0a42c4e308b Mon Sep 17 00:00:00 2001 From: Anton Bershanskiy Date: Sun, 5 May 2019 00:22:10 -0500 Subject: [PATCH 08/15] minor --- chromium/pages/options/ux.js | 8 +++++--- chromium/pages/punycode.js | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/chromium/pages/options/ux.js b/chromium/pages/options/ux.js index 2a02e5d6875c..5cbfd21c7b16 100644 --- a/chromium/pages/options/ux.js +++ b/chromium/pages/options/ux.js @@ -286,10 +286,12 @@ document.addEventListener("DOMContentLoaded", () => { for (const key of domains) { // If it is valid Punycode, display Unicode label - let display; + let display = key; try { const unicode = toUnicode(key); - display = unicode; + if (key !== unicode) { + display += " (" + unicode +")"; + } } catch(e) { display = key; } @@ -333,7 +335,7 @@ document.addEventListener("DOMContentLoaded", () => { domain = domain.toLowerCase(); const pattern = /^(\*|[a-z0-9_-]+)(\.[a-z0-9_-]+)*$/ const match = pattern.test(domain); - if (match !== true){ + if (match !== true) { domain = null; } return domain; diff --git a/chromium/pages/punycode.js b/chromium/pages/punycode.js index 36e0f0a536e1..8bf5e99cb37f 100644 --- a/chromium/pages/punycode.js +++ b/chromium/pages/punycode.js @@ -1,3 +1,5 @@ +"use strict"; + const { toASCII, toUnicode } = (() => { /** * This code is derived from punycode.js (https://github.com/bestiejs/punycode.js). From 629347635923751288892c7ff03e803278724599 Mon Sep 17 00:00:00 2001 From: pipboy96 Date: Sun, 5 May 2019 08:30:59 +0300 Subject: [PATCH 09/15] Update punycode.js --- chromium/pages/punycode.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chromium/pages/punycode.js b/chromium/pages/punycode.js index 8bf5e99cb37f..30d1270aaa83 100644 --- a/chromium/pages/punycode.js +++ b/chromium/pages/punycode.js @@ -1,6 +1,6 @@ "use strict"; -const { toASCII, toUnicode } = (() => { +window.punycode = (() => { /** * This code is derived from punycode.js (https://github.com/bestiejs/punycode.js). * From 0cda4245167f7e121bc6848048c2321d8b944ba8 Mon Sep 17 00:00:00 2001 From: pipboy96 Date: Sun, 5 May 2019 08:32:06 +0300 Subject: [PATCH 10/15] Update ux.js --- chromium/pages/options/ux.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chromium/pages/options/ux.js b/chromium/pages/options/ux.js index 5cbfd21c7b16..7b8944df929c 100644 --- a/chromium/pages/options/ux.js +++ b/chromium/pages/options/ux.js @@ -288,7 +288,7 @@ document.addEventListener("DOMContentLoaded", () => { // If it is valid Punycode, display Unicode label let display = key; try { - const unicode = toUnicode(key); + const unicode = window.punycode.toUnicode(key); if (key !== unicode) { display += " (" + unicode +")"; } @@ -327,7 +327,7 @@ document.addEventListener("DOMContentLoaded", () => { // TODO: what if toASCII errors out? domain = domain.trim(); try { - domain = toASCII(domain); + domain = window.punycode.toASCII(domain); } catch(e) { // This domain is not representable as Punycode return null From bd603432a446baf40bbbaefbbc7e217c533fb6fa Mon Sep 17 00:00:00 2001 From: Anton Bershanskiy Date: Sun, 5 May 2019 01:10:35 -0500 Subject: [PATCH 11/15] linter --- chromium/pages/punycode.js | 382 ++++++++++++++++++------------------- 1 file changed, 191 insertions(+), 191 deletions(-) diff --git a/chromium/pages/punycode.js b/chromium/pages/punycode.js index 30d1270aaa83..2a3a007d5fae 100644 --- a/chromium/pages/punycode.js +++ b/chromium/pages/punycode.js @@ -1,249 +1,249 @@ "use strict"; window.punycode = (() => { - /** - * This code is derived from punycode.js (https://github.com/bestiejs/punycode.js). - * - * Copyright Mathias Bynens - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - const maxInt = 2147483647 - - const base = 36 - const tMin = 1 - const tMax = 26 - const skew = 38 - const damp = 700 - const initialBias = 72 - const initialN = 128 - const delimiter = '-' - - const regexPunycode = /^xn--/ - const regexNonASCII = /[^\0-\x7E]/ - const regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g - - const baseMinusTMin = base - tMin - - const mapDomain = (string, fn) => { - const parts = string.split('@') - let result = '' - if (parts.length > 1) { - result = parts[0] + '@' - string = parts[1] - } - - string = string.replace(regexSeparators, '.') - const labels = string.split('.') - const encoded = labels.map(fn).join('.') - return result + encoded +/** + * This code is derived from punycode.js (https://github.com/bestiejs/punycode.js). + * + * Copyright Mathias Bynens + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +const maxInt = 2147483647 + +const base = 36 +const tMin = 1 +const tMax = 26 +const skew = 38 +const damp = 700 +const initialBias = 72 +const initialN = 128 +const delimiter = '-' + +const regexPunycode = /^xn--/ +const regexNonASCII = /[^\0-\x7E]/ +const regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g + +const baseMinusTMin = base - tMin + +const mapDomain = (string, fn) => { + const parts = string.split('@') + let result = '' + if (parts.length > 1) { + result = parts[0] + '@' + string = parts[1] } - const ucs2decode = string => { - const output = [] - let counter = 0 - const length = string.length - while (counter < length) { - const value = string.charCodeAt(counter++) - if (value >= 0xD800 && value <= 0xDBFF && counter < length) { - const extra = string.charCodeAt(counter++) - if ((extra & 0xFC00) === 0xDC00) { - output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000) - } else { - output.push(value) - counter-- - } + string = string.replace(regexSeparators, '.') + const labels = string.split('.') + const encoded = labels.map(fn).join('.') + return result + encoded +} + +const ucs2decode = string => { + const output = [] + let counter = 0 + const length = string.length + while (counter < length) { + const value = string.charCodeAt(counter++) + if (value >= 0xD800 && value <= 0xDBFF && counter < length) { + const extra = string.charCodeAt(counter++) + if ((extra & 0xFC00) === 0xDC00) { + output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000) } else { output.push(value) + counter-- } + } else { + output.push(value) } - return output } + return output +} - const basicToDigit = codePoint => { - if (codePoint - 0x30 < 0x0A) { - return codePoint - 0x16 - } - if (codePoint - 0x41 < 0x1A) { - return codePoint - 0x41 - } - if (codePoint - 0x61 < 0x1A) { - return codePoint - 0x61 - } - return base +const basicToDigit = codePoint => { + if (codePoint - 0x30 < 0x0A) { + return codePoint - 0x16 } + if (codePoint - 0x41 < 0x1A) { + return codePoint - 0x41 + } + if (codePoint - 0x61 < 0x1A) { + return codePoint - 0x61 + } + return base +} - const digitToBasic = (digit, flag) => digit + 22 + 75 * (digit < 26) - ((flag !== 0) << 5) +const digitToBasic = (digit, flag) => digit + 22 + 75 * (digit < 26) - ((flag !== 0) << 5) - const adapt = (delta, numPoints, firstTime) => { - let k = 0 - delta = firstTime ? Math.floor(delta / damp) : delta >> 1 - delta += Math.floor(delta / numPoints) - for (; delta > baseMinusTMin * tMax >> 1; k += base) { - delta = Math.floor(delta / baseMinusTMin) - } - return Math.floor(k + (baseMinusTMin + 1) * delta / (delta + skew)) +const adapt = (delta, numPoints, firstTime) => { + let k = 0 + delta = firstTime ? Math.floor(delta / damp) : delta >> 1 + delta += Math.floor(delta / numPoints) + for (; delta > baseMinusTMin * tMax >> 1; k += base) { + delta = Math.floor(delta / baseMinusTMin) + } + return Math.floor(k + (baseMinusTMin + 1) * delta / (delta + skew)) +} + +const decode = input => { + const output = [] + const inputLength = input.length + let i = 0 + let n = initialN + let bias = initialBias + + let basic = input.lastIndexOf(delimiter) + if (basic < 0) { + basic = 0 } - const decode = input => { - const output = [] - const inputLength = input.length - let i = 0 - let n = initialN - let bias = initialBias - - let basic = input.lastIndexOf(delimiter) - if (basic < 0) { - basic = 0 + for (let j = 0; j < basic; ++j) { + if (input.charCodeAt(j) >= 0x80) { + throw new Error('Illegal input >= 0x80 (not a basic code point)') } + output.push(input.charCodeAt(j)) + } - for (let j = 0; j < basic; ++j) { - if (input.charCodeAt(j) >= 0x80) { - throw new Error('Illegal input >= 0x80 (not a basic code point)') + for (let index = basic > 0 ? basic + 1 : 0; index < inputLength;) { + const oldi = i + for (let w = 1, k = base; ; k += base) { + if (index >= inputLength) { + throw new Error('Invalid input') } - output.push(input.charCodeAt(j)) - } - - for (let index = basic > 0 ? basic + 1 : 0; index < inputLength;) { - const oldi = i - for (let w = 1, k = base; ; k += base) { - if (index >= inputLength) { - throw new Error('Invalid input') - } - - const digit = basicToDigit(input.charCodeAt(index++)) - if (digit >= base || digit > Math.floor((maxInt - i) / w)) { - throw new Error('Overflow: input needs wider integers to process') - } - - i += digit * w - const t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias) + const digit = basicToDigit(input.charCodeAt(index++)) - if (digit < t) { - break - } + if (digit >= base || digit > Math.floor((maxInt - i) / w)) { + throw new Error('Overflow: input needs wider integers to process') + } - const baseMinusT = base - t - if (w > Math.floor(maxInt / baseMinusT)) { - throw new Error('Overflow: input needs wider integers to process') - } + i += digit * w + const t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias) - w *= baseMinusT + if (digit < t) { + break } - const out = output.length + 1 - bias = adapt(i - oldi, out, oldi === 0) - - if (Math.floor(i / out) > maxInt - n) { + const baseMinusT = base - t + if (w > Math.floor(maxInt / baseMinusT)) { throw new Error('Overflow: input needs wider integers to process') } - n += Math.floor(i / out) - i %= out + w *= baseMinusT + } + + const out = output.length + 1 + bias = adapt(i - oldi, out, oldi === 0) - output.splice(i++, 0, n) + if (Math.floor(i / out) > maxInt - n) { + throw new Error('Overflow: input needs wider integers to process') } - return String.fromCodePoint(...output) + n += Math.floor(i / out) + i %= out + + output.splice(i++, 0, n) } - const encode = input => { - const output = [] + return String.fromCodePoint(...output) +} + +const encode = input => { + const output = [] - input = ucs2decode(input) + input = ucs2decode(input) - const inputLength = input.length + const inputLength = input.length - let n = initialN - let delta = 0 - let bias = initialBias + let n = initialN + let delta = 0 + let bias = initialBias + for (const currentValue of input) { + if (currentValue < 0x80) { + output.push(String.fromCharCode(currentValue)) + } + } + + const basicLength = output.length + let handledCPCount = basicLength + + if (basicLength) { + output.push(delimiter) + } + + while (handledCPCount < inputLength) { + let m = maxInt for (const currentValue of input) { - if (currentValue < 0x80) { - output.push(String.fromCharCode(currentValue)) + if (currentValue >= n && currentValue < m) { + m = currentValue } } - const basicLength = output.length - let handledCPCount = basicLength - - if (basicLength) { - output.push(delimiter) + const handledCPCountPlusOne = handledCPCount + 1 + if (m - n > Math.floor((maxInt - delta) / handledCPCountPlusOne)) { + throw new Error('Overflow: input needs wider integers to process') } - while (handledCPCount < inputLength) { - let m = maxInt - for (const currentValue of input) { - if (currentValue >= n && currentValue < m) { - m = currentValue - } - } + delta += (m - n) * handledCPCountPlusOne + n = m - const handledCPCountPlusOne = handledCPCount + 1 - if (m - n > Math.floor((maxInt - delta) / handledCPCountPlusOne)) { + for (const currentValue of input) { + if (currentValue < n && ++delta > maxInt) { throw new Error('Overflow: input needs wider integers to process') } - delta += (m - n) * handledCPCountPlusOne - n = m + if (currentValue === n) { + let q = delta + for (let k = base; ; k += base) { + const t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias) - for (const currentValue of input) { - if (currentValue < n && ++delta > maxInt) { - throw new Error('Overflow: input needs wider integers to process') - } - - if (currentValue === n) { - let q = delta - for (let k = base; ; k += base) { - const t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias) - - if (q < t) { - break - } - - const qMinusT = q - t - const baseMinusT = base - t - output.push( - String.fromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) - ) - q = Math.floor(qMinusT / baseMinusT) + if (q < t) { + break } - output.push(String.fromCharCode(digitToBasic(q, 0))) - bias = adapt(delta, handledCPCountPlusOne, handledCPCount === basicLength) - delta = 0 - ++handledCPCount + const qMinusT = q - t + const baseMinusT = base - t + output.push( + String.fromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) + ) + q = Math.floor(qMinusT / baseMinusT) } - } - ++delta - ++n + output.push(String.fromCharCode(digitToBasic(q, 0))) + bias = adapt(delta, handledCPCountPlusOne, handledCPCount === basicLength) + delta = 0 + ++handledCPCount + } } - return output.join('') + + ++delta + ++n } + return output.join('') +} - const toUnicode = input => mapDomain(input, string => regexPunycode.test(string) ? decode(string.slice(4).toLowerCase()) : string) +const toUnicode = input => mapDomain(input, string => regexPunycode.test(string) ? decode(string.slice(4).toLowerCase()) : string) - const toASCII = input => mapDomain(input, string => regexNonASCII.test(string) ? 'xn--' + encode(string) : string) +const toASCII = input => mapDomain(input, string => regexNonASCII.test(string) ? 'xn--' + encode(string) : string) - return { toASCII, toUnicode } +return { toASCII, toUnicode } })() From 395bb05414aa5209604a7994ad0f860c27fa90de Mon Sep 17 00:00:00 2001 From: Anton Bershanskiy Date: Sun, 5 May 2019 10:31:34 -0500 Subject: [PATCH 12/15] minor --- chromium/pages/options/index.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/chromium/pages/options/index.html b/chromium/pages/options/index.html index bc007cc20df1..89f107acb61b 100644 --- a/chromium/pages/options/index.html +++ b/chromium/pages/options/index.html @@ -4,10 +4,6 @@ - - - - @@ -63,5 +59,9 @@ + + + + From 8562c125b81774ba1fbab3070aee4e6f252e02b0 Mon Sep 17 00:00:00 2001 From: dirlbec7 <50303174+dirlbec7@users.noreply.github.com> Date: Sun, 5 May 2019 18:28:30 -0500 Subject: [PATCH 13/15] Adding new ruleset web.illinois.edu.xml --- src/chrome/content/rules/web.illinois.edu.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/chrome/content/rules/web.illinois.edu.xml diff --git a/src/chrome/content/rules/web.illinois.edu.xml b/src/chrome/content/rules/web.illinois.edu.xml new file mode 100644 index 000000000000..0f34fb632c11 --- /dev/null +++ b/src/chrome/content/rules/web.illinois.edu.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + From cc948db818aa457ddf276951ae9e52595b886d84 Mon Sep 17 00:00:00 2001 From: dirlbec7 <50303174+dirlbec7@users.noreply.github.com> Date: Sun, 5 May 2019 18:41:37 -0500 Subject: [PATCH 14/15] Adding new ruleset AwesomeRuleset.xml --- src/chrome/content/rules/AwesomeRuleset.xml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/chrome/content/rules/AwesomeRuleset.xml diff --git a/src/chrome/content/rules/AwesomeRuleset.xml b/src/chrome/content/rules/AwesomeRuleset.xml new file mode 100644 index 000000000000..18e6638a0399 --- /dev/null +++ b/src/chrome/content/rules/AwesomeRuleset.xml @@ -0,0 +1,7 @@ + + + + + + + From 454550d4ad7a26b1de2f80b59a6aa337849d1cc7 Mon Sep 17 00:00:00 2001 From: dirlbec7 <50303174+dirlbec7@users.noreply.github.com> Date: Tue, 7 May 2019 17:34:48 -0500 Subject: [PATCH 15/15] Adding new ruleset fileName.xml --- src/chrome/content/rules/fileName.xml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/chrome/content/rules/fileName.xml diff --git a/src/chrome/content/rules/fileName.xml b/src/chrome/content/rules/fileName.xml new file mode 100644 index 000000000000..c35e3a8a0e9d --- /dev/null +++ b/src/chrome/content/rules/fileName.xml @@ -0,0 +1,9 @@ + + + + + + + + +