diff options
| -rw-r--r-- | Cakefile | 2 | ||||
| -rw-r--r-- | background_scripts/main.js | 14 | ||||
| -rw-r--r-- | lib/dom_utils.coffee | 25 | ||||
| -rw-r--r-- | manifest.json | 2 | ||||
| -rw-r--r-- | options.js | 112 | ||||
| -rw-r--r-- | options/options.coffee | 90 | ||||
| -rw-r--r-- | options/options.html (renamed from options.html) | 16 |
7 files changed, 118 insertions, 143 deletions
@@ -8,7 +8,7 @@ spawn_with_opts = (proc_name, opts) -> opt_array.push "--#{key}=#{value}" spawn proc_name, opt_array -src_directories = ["tests", "background_scripts", "content_scripts", "lib"] +src_directories = ["tests", "background_scripts", "content_scripts", "lib", "options"] task "build", "compile all coffeescript files to javascript", -> coffee = spawn "coffee", ["-c"].concat(src_directories) diff --git a/background_scripts/main.js b/background_scripts/main.js index 605eeb0c..5f5df508 100644 --- a/background_scripts/main.js +++ b/background_scripts/main.js @@ -762,13 +762,13 @@ function init() { for (var j in windows[i].tabs) { var tab = windows[i].tabs[j]; updateOpenTabs(tab); - chrome.tabs.sendRequest(tab.id, { name: "getScrollPosition" }, function() { - return function(response) { - if (response === undefined) - return; - updateScrollPosition(tab, response.scrollX, response.scrollY); - }; - }()); + chrome.tabs.sendRequest(tab.id, { name: "getScrollPosition" }, function() { + return function(response) { + if (response === undefined) + return; + updateScrollPosition(tab, response.scrollX, response.scrollY); + }; + }()); } } }); diff --git a/lib/dom_utils.coffee b/lib/dom_utils.coffee index c0efd344..924afbbe 100644 --- a/lib/dom_utils.coffee +++ b/lib/dom_utils.coffee @@ -2,11 +2,10 @@ DomUtils = # # Runs :callback if the DOM has loaded, otherwise runs it on load # - documentReady: (-> + documentReady: do -> loaded = false window.addEventListener("DOMContentLoaded", -> loaded = true) (callback) -> if loaded then callback() else window.addEventListener("DOMContentLoaded", callback) - )() # # Remove an element from its DOM tree. @@ -35,14 +34,13 @@ DomUtils = getVisibleClientRect: (element) -> # Note: this call will be expensive if we modify the DOM in between calls. clientRects = element.getClientRects() - clientRectsLength = clientRects.length - for i in [0...clientRectsLength] - if (clientRects[i].top < -2 || clientRects[i].top >= window.innerHeight - 4 || - clientRects[i].left < -2 || clientRects[i].left >= window.innerWidth - 4) + for clientRect in clientRects + if (clientRect.top < -2 || clientRect.top >= window.innerHeight - 4 || + clientRect.left < -2 || clientRect.left >= window.innerWidth - 4) continue - if (clientRects[i].width < 3 || clientRects[i].height < 3) + if (clientRect.width < 3 || clientRect.height < 3) continue # eliminate invisible elements (see test_harnesses/visibility_test.html) @@ -51,19 +49,18 @@ DomUtils = computedStyle.getPropertyValue('display') == 'none') continue - return clientRects[i] + return clientRect - for i in [0...clientRectsLength] + for clientRect in clientRects # If the link has zero dimensions, it may be wrapping visible # but floated elements. Check for this. - if (clientRects[i].width == 0 || clientRects[i].height == 0) - childrenCount = element.children.length - for j in [0...childrenCount] - computedStyle = window.getComputedStyle(element.children[j], null) + if (clientRect.width == 0 || clientRect.height == 0) + for child in element.children + computedStyle = window.getComputedStyle(child, null) # Ignore child elements which are not floated and not absolutely positioned for parent elements with zero width/height if (computedStyle.getPropertyValue('float') == 'none' && computedStyle.getPropertyValue('position') != 'absolute') continue - childClientRect = this.getVisibleClientRect(element.children[j]) + childClientRect = @getVisibleClientRect(child) if (childClientRect == null) continue return childClientRect diff --git a/manifest.json b/manifest.json index f872660d..2e8dac72 100644 --- a/manifest.json +++ b/manifest.json @@ -16,7 +16,7 @@ "background_scripts/main.js" ] }, - "options_page": "options.html", + "options_page": "options/options.html", "permissions": [ "tabs", "bookmarks", diff --git a/options.js b/options.js deleted file mode 100644 index bc624882..00000000 --- a/options.js +++ /dev/null @@ -1,112 +0,0 @@ -$ = function(id) { return document.getElementById(id); }; -var bgSettings = chrome.extension.getBackgroundPage().Settings; - -var editableFields = ["scrollStepSize", "excludedUrls", "linkHintCharacters", "userDefinedLinkHintCss", - "keyMappings", "filterLinkHints", "previousPatterns", "nextPatterns", "hideHud"]; - -var canBeEmptyFields = ["excludedUrls", "keyMappings", "userDefinedLinkHintCss"]; - -var postSaveHooks = { - keyMappings: function (value) { - commands = chrome.extension.getBackgroundPage().Commands; - commands.clearKeyMappingsAndSetDefaults(); - commands.parseCustomKeyMappings(value); - chrome.extension.getBackgroundPage().refreshCompletionKeysAfterMappingSave(); - } -}; - -document.addEventListener("DOMContentLoaded", function() { - populateOptions(); - - for (var i = 0; i < editableFields.length; i++) { - $(editableFields[i]).addEventListener("keyup", onOptionKeyup, false); - $(editableFields[i]).addEventListener("change", enableSaveButton, false); - $(editableFields[i]).addEventListener("change", onDataLoaded, false); - } - - $("advancedOptions").addEventListener("click", openAdvancedOptions, false); - $("showCommands").addEventListener("click", function () { - showHelpDialog( - chrome.extension.getBackgroundPage().helpDialogHtml(true, true, "Command Listing"), frameId); - }, false); - - document.getElementById("restoreSettings").addEventListener("click", restoreToDefaults); - document.getElementById("saveOptions").addEventListener("click", saveOptions); -}); - -function onOptionKeyup(event) { - if (event.target.getAttribute("type") !== "checkbox" && - event.target.getAttribute("savedValue") != event.target.value) - enableSaveButton(); -} - -function onDataLoaded() { - $("linkHintCharacters").readOnly = $("filterLinkHints").checked; -} - -function enableSaveButton() { $("saveOptions").removeAttribute("disabled"); } - -// Saves options to localStorage. -function saveOptions() { - // If the value is unchanged from the default, delete the preference from localStorage; this gives us - // the freedom to change the defaults in the future. - for (var i = 0; i < editableFields.length; i++) { - var fieldName = editableFields[i]; - var field = $(fieldName); - - var fieldValue; - if (field.getAttribute("type") == "checkbox") { - fieldValue = field.checked; - } else { - fieldValue = field.value.trim(); - field.value = fieldValue; - } - - // If it's empty and not a field that we allow to be empty, restore to the default value - if (!fieldValue && canBeEmptyFields.indexOf(fieldName) == -1) { - bgSettings.clear(fieldName); - fieldValue = bgSettings.get(fieldName); - } else - bgSettings.set(fieldName, fieldValue); - - $(fieldName).value = fieldValue; - $(fieldName).setAttribute("savedValue", fieldValue); - - if (postSaveHooks[fieldName]) { postSaveHooks[fieldName](fieldValue); } - } - $("saveOptions").disabled = true; -} - -// Restores select box state to saved value from localStorage. -function populateOptions() { - for (var i = 0; i < editableFields.length; i++) { - var val = bgSettings.get(editableFields[i]) || ""; - setFieldValue($(editableFields[i]), val); - } - onDataLoaded(); -} - -function restoreToDefaults() { - for (var i = 0; i < editableFields.length; i++) { - var val = bgSettings.defaults[editableFields[i]] || ""; - setFieldValue($(editableFields[i]), val); - } - onDataLoaded(); - enableSaveButton(); -} - -function setFieldValue(field, value) { - if (field.getAttribute('type') == 'checkbox') - field.checked = value; - else { - field.value = value; - field.setAttribute("savedValue", value); - } -} - -function openAdvancedOptions(event) { - var elements = document.getElementsByClassName("advancedOption"); - for (var i = 0; i < elements.length; i++) - elements[i].style.display = (elements[i].style.display == "table-row") ? "none" : "table-row"; - event.preventDefault(); -} diff --git a/options/options.coffee b/options/options.coffee new file mode 100644 index 00000000..6300dbcd --- /dev/null +++ b/options/options.coffee @@ -0,0 +1,90 @@ +$ = (id) -> document.getElementById id + +bgSettings = chrome.extension.getBackgroundPage().Settings + +editableFields = ["scrollStepSize", "excludedUrls", "linkHintCharacters", "userDefinedLinkHintCss", + "keyMappings", "filterLinkHints", "previousPatterns", "nextPatterns", "hideHud"] + +canBeEmptyFields = ["excludedUrls", "keyMappings", "userDefinedLinkHintCss"] + +postSaveHooks = keyMappings: (value) -> + commands = chrome.extension.getBackgroundPage().Commands + commands.clearKeyMappingsAndSetDefaults() + commands.parseCustomKeyMappings value + chrome.extension.getBackgroundPage().refreshCompletionKeysAfterMappingSave() + +document.addEventListener "DOMContentLoaded", -> + populateOptions() + + for field in editableFields + $(field).addEventListener "keyup", onOptionKeyup, false + $(field).addEventListener "change", enableSaveButton, false + $(field).addEventListener "change", onDataLoaded, false + + $("advancedOptions").addEventListener "click", openAdvancedOptions, false + $("showCommands").addEventListener "click", (-> + showHelpDialog chrome.extension.getBackgroundPage().helpDialogHtml(true, true, "Command Listing"), frameId + ), false + document.getElementById("restoreSettings").addEventListener "click", restoreToDefaults + document.getElementById("saveOptions").addEventListener "click", saveOptions + +onOptionKeyup = (event) -> + if (event.target.getAttribute("type") isnt "checkbox" and + event.target.getAttribute("savedValue") isnt event.target.value) + enableSaveButton() + +onDataLoaded = -> + $("linkHintCharacters").readOnly = $("filterLinkHints").checked + +enableSaveButton = -> + $("saveOptions").removeAttribute "disabled" + +# Saves options to localStorage. +saveOptions = -> + + # If the value is unchanged from the default, delete the preference from localStorage; this gives us + # the freedom to change the defaults in the future. + for fieldName in editableFields + field = $(fieldName) + if field.getAttribute("type") is "checkbox" + fieldValue = field.checked + else + fieldValue = field.value.trim() + field.value = fieldValue + + # If it's empty and not a field that we allow to be empty, restore to the default value + if not fieldValue and canBeEmptyFields.indexOf(fieldName) is -1 + bgSettings.clear fieldName + fieldValue = bgSettings.get(fieldName) + else + bgSettings.set fieldName, fieldValue + $(fieldName).value = fieldValue + $(fieldName).setAttribute "savedValue", fieldValue + postSaveHooks[fieldName] fieldValue if postSaveHooks[fieldName] + + $("saveOptions").disabled = true + +# Restores select box state to saved value from localStorage. +populateOptions = -> + for field in editableFields + val = bgSettings.get(field) or "" + setFieldValue $(field), val + onDataLoaded() + +restoreToDefaults = -> + for field in editableFields + val = bgSettings.defaults[field] or "" + setFieldValue $(field), val + onDataLoaded() + enableSaveButton() + +setFieldValue = (field, value) -> + unless field.getAttribute("type") is "checkbox" + field.value = value + field.setAttribute "savedValue", value + +openAdvancedOptions = (event) -> + elements = document.getElementsByClassName("advancedOption") + for element in elements + element.style.display = (if (element.style.display is "table-row") then "none" else "table-row") + event.preventDefault() diff --git a/options.html b/options/options.html index 730c9bff..93a402fb 100644 --- a/options.html +++ b/options/options.html @@ -1,13 +1,13 @@ <html> <head> <title>Vimium Options</title> - <script src="lib/utils.js"></script> - <script src="lib/keyboard_utils.js"></script> - <script src="lib/dom_utils.js"></script> - <script src="lib/clipboard.js"></script> - <script src="content_scripts/link_hints.js"></script> - <script src="content_scripts/vomnibar.js"></script> - <script src="content_scripts/vimium_frontend.js"></script> + <script src="../lib/utils.js"></script> + <script src="../lib/keyboard_utils.js"></script> + <script src="../lib/dom_utils.js"></script> + <script src="../lib/clipboard.js"></script> + <script src="../content_scripts/link_hints.js"></script> + <script src="../content_scripts/vomnibar.js"></script> + <script src="../content_scripts/vimium_frontend.js"></script> <style type="text/css" media="screen"> body { font-family:"helvetica neue", "helvetica", "arial", "sans"; @@ -82,7 +82,7 @@ /* Boolean options have a tighter form representation than text options. */ td.booleanOption { font-size: 12px; } </style> - <link rel="stylesheet" type="text/css" href="vimium.css" /> + <link rel="stylesheet" type="text/css" href="../vimium.css" /> <script type="text/javascript" src="options.js"></script> |
