From d6ec816ea96bbd7bb5d2bb1718f353babe94d24f Mon Sep 17 00:00:00 2001 From: Jeremy Schomery Date: Tue, 14 Feb 2017 19:05:53 +0330 Subject: [PATCH] adding options UI (fixes #22, #24) --- _locales/en/messages.json | 875 ++++++++++++++++++++------------------ background.js | 3 +- manage.js | 4 + manifest.json | 121 +++--- messaging.js | 4 +- options/index.css | 22 + options/index.html | 55 +++ options/index.js | 88 ++++ storage.js | 5 + update.js | 49 ++- 10 files changed, 734 insertions(+), 492 deletions(-) create mode 100644 options/index.css create mode 100644 options/index.html create mode 100644 options/index.js diff --git a/_locales/en/messages.json b/_locales/en/messages.json index e2156853..530841e9 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -1,425 +1,456 @@ { - "addStyleLabel": { - "message": "Write new style", - "description": "Label for the button to go to the add style page" - }, - "addStyleTitle": { - "message": "Add Style", - "description": "Title of the page for adding styles" - }, - "appliesAdd": { - "message": "Add", - "description": "Label for the button to add an 'applies' entry" - }, - "appliesDisplay": { - "message": "Applies to: $applies$", - "description": "Text on the manage screen to describe what the style applies to", - "placeholders": { - "applies": { - "content": "$1" - } - } - }, - "appliesDisplayTruncatedSuffix": { - "message": "and more", - "description": "Text added to appliesDisplay when there are more sites for the style than are displayed" - }, - "appliesDomainOption": { - "message": "URLs on the domain", - "description": "Option to make the style apply to the entered string as a domain" - }, - "appliesHelp": { - "message": "Use the 'Applies to' controls to limit what URLs the code in this section applies to.", - "description": "Help text for 'applies to' section" - }, - "appliesLabel": { - "message": "Applies to", - "description": "Label for 'applies to' fields on the edit\/add screen" - }, - "appliesRegexpOption": { - "message": "URLs matching the regexp", - "description": "Option to make the style apply to the entered string as a regular expression" - }, - "appliesRemove": { - "message": "Remove", - "description": "Label for the button to remove an 'applies' entry" - }, - "appliesSpecify": { - "message": "Specify", - "description": "Label for the button to make a style apply only to specific sites" - }, - "appliesToEverything": { - "message": "Everything", - "description": "Text displayed for styles that apply to all sites" - }, - "appliesUrlOption": { - "message": "URL", - "description": "Option to make the style apply to the entered string as a URL" - }, - "appliesUrlPrefixOption": { - "message": "URLs starting with", - "description": "Option to make the style apply to the entered string as a URL prefix" - }, - "applyAllUpdates": { - "message": "Apply all updates", - "description": "Label for the button to apply all detected updates" - }, - "checkAllUpdates": { - "message": "Check all styles for updates", - "description": "Label for the button to check all styles for updates" - }, - "checkForUpdate": { - "message": "Check for update", - "description": "Label for the button to check a single style for an update" - }, - "checkingForUpdate": { - "message": "Checking...", - "description": "Text to display when checking a style for an update" - }, - "cm_indentWithTabs": { - "message": "Use tabs with smart indentation", - "description": "Label for the checkbox controlling tabs with smart indentation option for the style editor." - }, - "cm_keyMap": { - "message": "Keymap", - "description": "Label for the drop-down list controlling the keymap for the style editor." - }, - "cm_lineWrapping": { - "message": "Word wrap", - "description": "Label for the checkbox controlling word wrap option for the style editor." - }, - "cm_smartIndent": { - "message": "Use smart indentation", - "description": "Label for the checkbox controlling smart indentation option for the style editor." - }, - "cm_tabSize": { - "message": "Tab size", - "description": "Label for the text box controlling tab size option for the style editor." - }, - "cm_theme": { - "message": "Theme", - "description": "Label for the style editor's CSS theme." - }, - "confirmNo": { - "message": "No", - "description": "'No' button in a confirm dialog" - }, - "confirmStop": { - "message": "Stop", - "description": "'Stop' button in a confirm dialog" - }, - "confirmYes": { - "message": "Yes", - "description": "'Yes' button in a confirm dialog" - }, - "dbError": { - "message": "An error has occurred using the Stylus database. Would you like to visit a web page with possible solutions?", - "description": "Prompt when a DB error is encountered" - }, - "defaultTheme": { - "message": "default", - "description": "Default CodeMirror CSS theme option on the edit style page" - }, - "deleteStyleLabel": { - "message": "Delete", - "description": "Label for the button to delete a style" - }, - "deleteStyleConfirm": { - "message": "Are you sure you want to delete this style?", - "description": "Confirmation before deleting a style" - }, - "description": { - "message": "Restyle the web with Stylus, a user styles manager. Stylus lets you easily install themes and skins for many popular sites.", - "description": "Extension description" - }, - "disableAllStyles": { - "message": "Turn all styles off", - "description": "Label for the checkbox that turns all enabled styles off." - }, - "disableStyleLabel": { - "message": "Disable", - "description": "Label for the button to disable a style" - }, - "editGotoLine": { - "message": "Goto line (or line:col)", - "description": "Go to line or line:column on Ctrl-G in style code editor" - }, - "editStyleHeading": { - "message": "Edit Style", - "description": "Title of the page for editing styles" - }, - "editStyleLabel": { - "message": "Edit", - "description": "Label for the button to go to the edit style page" - }, - "editStyleTitle": { - "message": "Edit Style $stylename$", - "description": "Title of the page for editing styles", - "placeholders": { - "stylename": { - "content": "$1" - } - } - }, - "enableStyleLabel": { - "message": "Enable", - "description": "Label for the button to enable a style" - }, - "exportLabel": { - "message": "Export", - "description": "Label for the button to export a style ('edit' page) or all styles ('manage' page)" - }, - "findStylesForSite": { - "message": "Find more styles for this site.", - "description": "Text for a link that gets a list of styles for the current site" - }, - "helpAlt": { - "message": "Help", - "description": "Alternate text for help buttons" - }, - "helpKeyMapHotkey": { - "message": "Press a hotkey", - "description": "Placeholder text of inputbox in keymap help popup on the edit style page. Must be very short" - }, - "helpKeyMapCommand": { - "message": "Type a command name", - "description": "Placeholder text of inputbox in keymap help popup on the edit style page. Must be very short" - }, - "importLabel": { - "message": "Import", - "description": "Label for the button to import a style ('edit' page) or all styles ('manage' page)" - }, - "importAppendLabel": { - "message": "Append to style", - "description": "Label for the button to import a style and append to the existing sections" - }, - "importAppendTooltip": { - "message": "Append the imported style to current style", - "description": "Tooltip for the button to import a style and append to the existing sections" - }, - "importReplaceLabel": { - "message": "Overwrite style", - "description": "Label for the button to import and overwrite current style" - }, - "importReplaceTooltip": { - "message": "Discard contents of current style and overwrite it with the imported style", - "description": "Label for the button to import and overwrite current style" - }, - "installUpdate": { - "message": "Install update", - "description": "Label for the button to install an update for a single style" - }, - "issues": { - "message": "Issues", - "description": "Label for the CSSLint issues block on the style edit page" - }, - "issuesHelp": { - "message": "The issues found by CSSLint<\/a> with these rules enabled:", - "description": "Help popup message for the CSSLint issues block on the style edit page" - }, - "manageFilters": { - "message": "Filters", - "description": "Label for filters container" - }, - "manageHeading": { - "message": "Installed Styles", - "description": "Heading for the manage page" - }, - "manageOnlyEnabled": { - "message": "Only enabled styles", - "description": "Checkbox to show only enabled styles" - }, - "manageOnlyEdited": { - "message": "Only edited styles", - "description": "Checkbox to show only locally edited styles" - }, - "manageText": { - "message": "Get styles on userstyles.org<\/a> | Get help<\/a>", - "description": "Help text on the manage page" - }, - "manageTitle": { - "message": "Stylus", - "description": "Title for the manage page" - }, - "menuShowBadge": { - "message": "Show active style count", - "description": "Label (must be very short) for the checkbox in the toolbar button context menu controlling toolbar badge text." - }, - "noStylesForSite": { - "message": "No styles installed for this site.", - "description": "Text displayed when no styles are installed for the current site" - }, - "openManage": { - "message": "Manage installed styles.", - "description": "Link to open the manage page." - }, - "optionsHeading": { - "message": "Options", - "description": "Heading for options section on manage page." - }, - "popupStylesFirst": { - "message": "List styles before commands in the toolbar button menu", - "description": "Label for the checkbox controlling section order in the toolbar button menu." - }, - "prefShowBadge": { - "message": "Show number of styles active for the current site on the toolbar button", - "description": "Label for the checkbox controlling toolbar badge text." - }, - "replace": { - "message": "Replace", - "description": "Label before the replace input field in the editor shown on Ctrl-H" - }, - "replaceAll": { - "message": "Replace all", - "description": "Label before the replace input field in the editor shown on 'replaceAll' hotkey" - }, - "replaceWith": { - "message": "Replace with", - "description": "Label before the replace-with input field in the editor shown on Ctrl-H etc." - }, - "search": { - "message": "Search", - "description": "Label before the search input field in the editor shown on Ctrl-F" - }, - "searchRegexp": { - "message": "Use /re/ syntax for regexp search", - "description": "Label after the search input field in the editor shown on Ctrl-F" - }, - "searchStyles": { - "message": "Search contents", - "description": "Label for the search filter textbox on the Manage styles page" - }, - "sectionAdd": { - "message": "Add another section", - "description": "Label for the button to add a section" - }, - "sectionCode": { - "message": "Code", - "description": "Label for the code for a section" - }, - "sectionHelp": { - "message": "Sections let you define different pieces of code to apply to different sets of URLs in the same style. For example, a single style could change the homepage of a site one way, while changing the rest of a site another way.", - "description": "Help text for sections" - }, - "sectionRemove": { - "message": "Remove section", - "description": "Label for the button to remove a section" - }, - "styleBadRegexp": { - "message": "Regexp is invalid.", - "description": "Validation message for a bad regexp in a style" - }, - "styleBeautify": { - "message": "Beautify", - "description": "Label for the CSS-beautifier button on the edit style page" - }, - "styleCancelEditLabel": { - "message": "Back to manage", - "description": "Label for cancel button for style editing" - }, - "styleChangesNotSaved": { - "message": "You've made changes to this style without saving.", - "description": "Text for the prompt when changes are made to a style and the user tries to leave without saving" - }, - "styleEnabledLabel": { - "message": "Enabled", - "description": "Label for the enabled state of styles" - }, - "styleInstall": { - "message": "Install '$stylename$' into Stylus?", - "description": "Confirmation when installing a style", - "placeholders": { - "stylename": { - "content": "$1" - } - } - }, - "styleMissingName": { - "message": "Enter a name.", - "description": "Error displayed when user saves without providing a name" - }, - "styleSaveLabel": { - "message": "Save", - "description": "Label for save button for style editing" - }, - "styleSectionsTitle": { - "message": "Sections", - "description": "Title for the style sections section" - }, - "styleMozillaFormatHeading": { - "message": "Mozilla Format", - "description": "Heading for the section with buttons to import/export Mozilla format of the style" - }, - "styleFromMozillaFormatPrompt": { - "message": "Paste the Mozilla-format code", - "description": "Prompt in the dialog displayed after clicking 'Import from Mozilla format' button" - }, - "styleToMozillaFormatTitle": { - "message": "Style in Mozilla format", - "description": "Title of the popup with the style code in Mozilla format, shown after pressing the Export button on Edit style page" - }, - "styleToMozillaFormatHelp": { - "message": "The Mozilla format of the code can be used with Stylus for Firefox and can be submitted to userstyles.org.", - "description": "Help info for the Mozilla format header section that converts the code to/from Mozilla format" - }, - "styleUpdate": { - "message": "Are you sure you want to update '$stylename$'?", - "description": "Confirmation when updating a style", - "placeholders": { - "stylename": { - "content": "$1" - } - } - }, - "stylishUnavailableForURL": { - "message": "(Stylus can't affect this page.)", - "description": "Note in the toolbar pop-up when on a URL Stylus can't affect" - }, - "undo": { - "message": "Undo", - "description": "Button label" - }, - "undoGlobal": { - "message": "Undo (global)", - "description": "CSS-beautify global Undo button label" - }, - "updateCheckFailBadResponseCode": { - "message": "Update failed - server responded with code $code$.", - "description": "Text that displays when an update check failed because the response code indicates an error", - "placeholders": { - "code": { - "content": "$1" - } - } - }, - "updateCheckFailServerUnreachable": { - "message": "Update failed - server unreachable.", - "description": "Text that displays when an update check failed because the update server is unreachable" - }, - "updateCheckSucceededNoUpdate": { - "message": "Style is up to date.", - "description": "Text that displays when an update check completed and no update is available" - }, - "updateAllCheckSucceededNoUpdate": { - "message": "All styles are up to date.", - "description": "Text that displays when an update all check completed and no updates are available" - }, - "updateCompleted": { - "message": "Update completed.", - "description": "Text that displays when an update completed" - }, - "writeStyleFor": { - "message": "Write style for: ", - "description": "Label for toolbar pop-up that precedes the links to write a new style" - }, - "writeStyleForURL": { - "message": "this URL", - "description": "Text for link in toolbar pop-up to write a new style for the current URL" - }, - "bckpInstStyles": { - "message": "Export Styles" - }, - "retrieveBckp": { - "message": "Import Styles" + "addStyleLabel": { + "message": "Write new style", + "description": "Label for the button to go to the add style page" + }, + "addStyleTitle": { + "message": "Add Style", + "description": "Title of the page for adding styles" + }, + "appliesAdd": { + "message": "Add", + "description": "Label for the button to add an 'applies' entry" + }, + "appliesDisplay": { + "message": "Applies to: $applies$", + "description": "Text on the manage screen to describe what the style applies to", + "placeholders": { + "applies": { + "content": "$1" + } } + }, + "appliesDisplayTruncatedSuffix": { + "message": "and more", + "description": "Text added to appliesDisplay when there are more sites for the style than are displayed" + }, + "appliesDomainOption": { + "message": "URLs on the domain", + "description": "Option to make the style apply to the entered string as a domain" + }, + "appliesHelp": { + "message": "Use the 'Applies to' controls to limit what URLs the code in this section applies to.", + "description": "Help text for 'applies to' section" + }, + "appliesLabel": { + "message": "Applies to", + "description": "Label for 'applies to' fields on the edit\/add screen" + }, + "appliesRegexpOption": { + "message": "URLs matching the regexp", + "description": "Option to make the style apply to the entered string as a regular expression" + }, + "appliesRemove": { + "message": "Remove", + "description": "Label for the button to remove an 'applies' entry" + }, + "appliesSpecify": { + "message": "Specify", + "description": "Label for the button to make a style apply only to specific sites" + }, + "appliesToEverything": { + "message": "Everything", + "description": "Text displayed for styles that apply to all sites" + }, + "appliesUrlOption": { + "message": "URL", + "description": "Option to make the style apply to the entered string as a URL" + }, + "appliesUrlPrefixOption": { + "message": "URLs starting with", + "description": "Option to make the style apply to the entered string as a URL prefix" + }, + "applyAllUpdates": { + "message": "Apply all updates", + "description": "Label for the button to apply all detected updates" + }, + "checkAllUpdates": { + "message": "Check all styles for updates", + "description": "Label for the button to check all styles for updates" + }, + "checkForUpdate": { + "message": "Check for update", + "description": "Label for the button to check a single style for an update" + }, + "checkingForUpdate": { + "message": "Checking...", + "description": "Text to display when checking a style for an update" + }, + "cm_indentWithTabs": { + "message": "Use tabs with smart indentation", + "description": "Label for the checkbox controlling tabs with smart indentation option for the style editor." + }, + "cm_keyMap": { + "message": "Keymap", + "description": "Label for the drop-down list controlling the keymap for the style editor." + }, + "cm_lineWrapping": { + "message": "Word wrap", + "description": "Label for the checkbox controlling word wrap option for the style editor." + }, + "cm_smartIndent": { + "message": "Use smart indentation", + "description": "Label for the checkbox controlling smart indentation option for the style editor." + }, + "cm_tabSize": { + "message": "Tab size", + "description": "Label for the text box controlling tab size option for the style editor." + }, + "cm_theme": { + "message": "Theme", + "description": "Label for the style editor's CSS theme." + }, + "confirmNo": { + "message": "No", + "description": "'No' button in a confirm dialog" + }, + "confirmStop": { + "message": "Stop", + "description": "'Stop' button in a confirm dialog" + }, + "confirmYes": { + "message": "Yes", + "description": "'Yes' button in a confirm dialog" + }, + "dbError": { + "message": "An error has occurred using the Stylus database. Would you like to visit a web page with possible solutions?", + "description": "Prompt when a DB error is encountered" + }, + "defaultTheme": { + "message": "default", + "description": "Default CodeMirror CSS theme option on the edit style page" + }, + "deleteStyleLabel": { + "message": "Delete", + "description": "Label for the button to delete a style" + }, + "deleteStyleConfirm": { + "message": "Are you sure you want to delete this style?", + "description": "Confirmation before deleting a style" + }, + "description": { + "message": "Restyle the web with Stylus, a user styles manager. Stylus lets you easily install themes and skins for many popular sites.", + "description": "Extension description" + }, + "disableAllStyles": { + "message": "Turn all styles off", + "description": "Label for the checkbox that turns all enabled styles off." + }, + "disableStyleLabel": { + "message": "Disable", + "description": "Label for the button to disable a style" + }, + "editGotoLine": { + "message": "Goto line (or line:col)", + "description": "Go to line or line:column on Ctrl-G in style code editor" + }, + "editStyleHeading": { + "message": "Edit Style", + "description": "Title of the page for editing styles" + }, + "editStyleLabel": { + "message": "Edit", + "description": "Label for the button to go to the edit style page" + }, + "editStyleTitle": { + "message": "Edit Style $stylename$", + "description": "Title of the page for editing styles", + "placeholders": { + "stylename": { + "content": "$1" + } + } + }, + "enableStyleLabel": { + "message": "Enable", + "description": "Label for the button to enable a style" + }, + "exportLabel": { + "message": "Export", + "description": "Label for the button to export a style ('edit' page) or all styles ('manage' page)" + }, + "findStylesForSite": { + "message": "Find more styles for this site.", + "description": "Text for a link that gets a list of styles for the current site" + }, + "helpAlt": { + "message": "Help", + "description": "Alternate text for help buttons" + }, + "helpKeyMapHotkey": { + "message": "Press a hotkey", + "description": "Placeholder text of inputbox in keymap help popup on the edit style page. Must be very short" + }, + "helpKeyMapCommand": { + "message": "Type a command name", + "description": "Placeholder text of inputbox in keymap help popup on the edit style page. Must be very short" + }, + "importLabel": { + "message": "Import", + "description": "Label for the button to import a style ('edit' page) or all styles ('manage' page)" + }, + "importAppendLabel": { + "message": "Append to style", + "description": "Label for the button to import a style and append to the existing sections" + }, + "importAppendTooltip": { + "message": "Append the imported style to current style", + "description": "Tooltip for the button to import a style and append to the existing sections" + }, + "importReplaceLabel": { + "message": "Overwrite style", + "description": "Label for the button to import and overwrite current style" + }, + "importReplaceTooltip": { + "message": "Discard contents of current style and overwrite it with the imported style", + "description": "Label for the button to import and overwrite current style" + }, + "installUpdate": { + "message": "Install update", + "description": "Label for the button to install an update for a single style" + }, + "issues": { + "message": "Issues", + "description": "Label for the CSSLint issues block on the style edit page" + }, + "issuesHelp": { + "message": "The issues found by CSSLint<\/a> with these rules enabled:", + "description": "Help popup message for the CSSLint issues block on the style edit page" + }, + "manageFilters": { + "message": "Filters", + "description": "Label for filters container" + }, + "manageHeading": { + "message": "Installed Styles", + "description": "Heading for the manage page" + }, + "manageOnlyEnabled": { + "message": "Only enabled styles", + "description": "Checkbox to show only enabled styles" + }, + "manageOnlyEdited": { + "message": "Only edited styles", + "description": "Checkbox to show only locally edited styles" + }, + "manageText": { + "message": "Get styles on userstyles.org<\/a> | Get help<\/a>", + "description": "Help text on the manage page" + }, + "manageTitle": { + "message": "Stylus", + "description": "Title for the manage page" + }, + "menuShowBadge": { + "message": "Show active style count", + "description": "Label (must be very short) for the checkbox in the toolbar button context menu controlling toolbar badge text." + }, + "noStylesForSite": { + "message": "No styles installed for this site.", + "description": "Text displayed when no styles are installed for the current site" + }, + "openManage": { + "message": "Manage installed styles.", + "description": "Link to open the manage page." + }, + "optionsHeading": { + "message": "Options", + "description": "Heading for options section on manage page." + }, + "popupStylesFirst": { + "message": "List styles before commands in the toolbar button menu", + "description": "Label for the checkbox controlling section order in the toolbar button menu." + }, + "prefShowBadge": { + "message": "Show number of styles active for the current site on the toolbar button", + "description": "Label for the checkbox controlling toolbar badge text." + }, + "replace": { + "message": "Replace", + "description": "Label before the replace input field in the editor shown on Ctrl-H" + }, + "replaceAll": { + "message": "Replace all", + "description": "Label before the replace input field in the editor shown on 'replaceAll' hotkey" + }, + "replaceWith": { + "message": "Replace with", + "description": "Label before the replace-with input field in the editor shown on Ctrl-H etc." + }, + "search": { + "message": "Search", + "description": "Label before the search input field in the editor shown on Ctrl-F" + }, + "searchRegexp": { + "message": "Use /re/ syntax for regexp search", + "description": "Label after the search input field in the editor shown on Ctrl-F" + }, + "searchStyles": { + "message": "Search contents", + "description": "Label for the search filter textbox on the Manage styles page" + }, + "sectionAdd": { + "message": "Add another section", + "description": "Label for the button to add a section" + }, + "sectionCode": { + "message": "Code", + "description": "Label for the code for a section" + }, + "sectionHelp": { + "message": "Sections let you define different pieces of code to apply to different sets of URLs in the same style. For example, a single style could change the homepage of a site one way, while changing the rest of a site another way.", + "description": "Help text for sections" + }, + "sectionRemove": { + "message": "Remove section", + "description": "Label for the button to remove a section" + }, + "styleBadRegexp": { + "message": "Regexp is invalid.", + "description": "Validation message for a bad regexp in a style" + }, + "styleBeautify": { + "message": "Beautify", + "description": "Label for the CSS-beautifier button on the edit style page" + }, + "styleCancelEditLabel": { + "message": "Back to manage", + "description": "Label for cancel button for style editing" + }, + "styleChangesNotSaved": { + "message": "You've made changes to this style without saving.", + "description": "Text for the prompt when changes are made to a style and the user tries to leave without saving" + }, + "styleEnabledLabel": { + "message": "Enabled", + "description": "Label for the enabled state of styles" + }, + "styleInstall": { + "message": "Install '$stylename$' into Stylus?", + "description": "Confirmation when installing a style", + "placeholders": { + "stylename": { + "content": "$1" + } + } + }, + "styleMissingName": { + "message": "Enter a name.", + "description": "Error displayed when user saves without providing a name" + }, + "styleSaveLabel": { + "message": "Save", + "description": "Label for save button for style editing" + }, + "styleSectionsTitle": { + "message": "Sections", + "description": "Title for the style sections section" + }, + "styleMozillaFormatHeading": { + "message": "Mozilla Format", + "description": "Heading for the section with buttons to import/export Mozilla format of the style" + }, + "styleFromMozillaFormatPrompt": { + "message": "Paste the Mozilla-format code", + "description": "Prompt in the dialog displayed after clicking 'Import from Mozilla format' button" + }, + "styleToMozillaFormatTitle": { + "message": "Style in Mozilla format", + "description": "Title of the popup with the style code in Mozilla format, shown after pressing the Export button on Edit style page" + }, + "styleToMozillaFormatHelp": { + "message": "The Mozilla format of the code can be used with Stylus for Firefox and can be submitted to userstyles.org.", + "description": "Help info for the Mozilla format header section that converts the code to/from Mozilla format" + }, + "styleUpdate": { + "message": "Are you sure you want to update '$stylename$'?", + "description": "Confirmation when updating a style", + "placeholders": { + "stylename": { + "content": "$1" + } + } + }, + "stylishUnavailableForURL": { + "message": "(Stylus can't affect this page.)", + "description": "Note in the toolbar pop-up when on a URL Stylus can't affect" + }, + "undo": { + "message": "Undo", + "description": "Button label" + }, + "undoGlobal": { + "message": "Undo (global)", + "description": "CSS-beautify global Undo button label" + }, + "updateCheckFailBadResponseCode": { + "message": "Update failed - server responded with code $code$.", + "description": "Text that displays when an update check failed because the response code indicates an error", + "placeholders": { + "code": { + "content": "$1" + } + } + }, + "updateCheckFailServerUnreachable": { + "message": "Update failed - server unreachable.", + "description": "Text that displays when an update check failed because the update server is unreachable" + }, + "updateCheckSucceededNoUpdate": { + "message": "Style is up to date.", + "description": "Text that displays when an update check completed and no update is available" + }, + "updateAllCheckSucceededNoUpdate": { + "message": "All styles are up to date.", + "description": "Text that displays when an update all check completed and no updates are available" + }, + "updateCompleted": { + "message": "Update completed.", + "description": "Text that displays when an update completed" + }, + "writeStyleFor": { + "message": "Write style for: ", + "description": "Label for toolbar pop-up that precedes the links to write a new style" + }, + "writeStyleForURL": { + "message": "this URL", + "description": "Text for link in toolbar pop-up to write a new style for the current URL" + }, + "bckpInstStyles": { + "message": "Export Styles" + }, + "retrieveBckp": { + "message": "Import Styles" + }, + // options page + "optionsBadgeNormal": { + "message": "Badge background color" + }, + "optionsBadgeDisabled": { + "message": "Badge background color (when disabled)" + }, + "optionsUpdateInterval": { + "message": "Automatically check for user-style updates (in hours)" + }, + "optionsUpdateIntervalNote": { + "message": "To disable the automatic user-style update checks, set interval to zero" + }, + "optionsCustomize": { + "message": "UI Customizations" + }, + "optionsActions": { + "message": "Actions" + }, + "optionsOpenManager": { + "message": "Open styles manager" + }, + "optionsCheckUpdate": { + "message": "Check for updates" + }, + "optionsOpen": { + "message": "Open" + }, + "optionsCheck": { + "message": "Check" + } } diff --git a/background.js b/background.js index 213a2276..a0b720f0 100644 --- a/background.js +++ b/background.js @@ -120,7 +120,8 @@ runTryCatch(function() { chrome.contextMenus.onClicked.addListener(function(info, tab) { if (info.menuItemId == "disableAll") { disableAllStylesToggle(info.checked); - } else { + } + else { prefs.set(info.menuItemId, info.checked); } }); diff --git a/manage.js b/manage.js index 3d4d239f..465ca650 100644 --- a/manage.js +++ b/manage.js @@ -238,6 +238,10 @@ function checkUpdateAll() { } }); }); + // notify the automatic updater to reset the next automatic update accordingly + chrome.runtime.sendMessage({ + method: 'resetInterval' + }); } function checkUpdate(element, callback) { diff --git a/manifest.json b/manifest.json index da2e2b44..813c30bc 100644 --- a/manifest.json +++ b/manifest.json @@ -1,61 +1,64 @@ { - "name": "Stylus", - "version": "1.0.1", - "description": "__MSG_description__", - "homepage_url": "https://github.com/schomery/stylish-chrome", - "manifest_version": 2, - "icons": { - "16": "16.png", - "48": "48.png", - "128": "128.png" - }, - "permissions": [ - "tabs", - "webNavigation", - "webRequest", - "webRequestBlocking", - "contextMenus", - "storage", - "*://*/*" - ], - "optional_permissions": [ - "downloads" - ], - "background": { - "scripts": ["messaging.js", "storage-websql.js", "storage.js", "background.js", "update.js"] - }, - "commands": { - "openManage": { - "description": "__MSG_openManage__" - }, - "styleDisableAll": { - "description": "__MSG_disableAllStyles__" - } - }, - "content_scripts": [ - { - "matches": [""], - "run_at": "document_start", - "all_frames": true, - "js": ["apply.js"] - }, - { - "matches": ["http://userstyles.org/*", "https://userstyles.org/*"], - "run_at": "document_end", - "all_frames": false, - "js": ["install.js"] - } - ], - "options_page": "manage.html", - "browser_action": { - "default_icon": { - "16": "16w.png", - "32": "32w.png", - "19": "19w.png", - "38": "38w.png" - }, - "default_title": "Stylus", - "default_popup": "popup.html" - }, - "default_locale": "en" + "name": "Stylus", + "version": "1.0.1", + "description": "__MSG_description__", + "homepage_url": "https://github.com/schomery/stylish-chrome", + "manifest_version": 2, + "icons": { + "16": "16.png", + "48": "48.png", + "128": "128.png" + }, + "permissions": [ + "tabs", + "webNavigation", + "webRequest", + "webRequestBlocking", + "contextMenus", + "storage", + "*://*/*" + ], + "optional_permissions": [ + "downloads" + ], + "background": { + "scripts": ["messaging.js", "storage-websql.js", "storage.js", "background.js", "update.js"] + }, + "commands": { + "openManage": { + "description": "__MSG_openManage__" + }, + "styleDisableAll": { + "description": "__MSG_disableAllStyles__" + } + }, + "content_scripts": [ + { + "matches": [""], + "run_at": "document_start", + "all_frames": true, + "js": ["apply.js"] + }, + { + "matches": ["http://userstyles.org/*", "https://userstyles.org/*"], + "run_at": "document_end", + "all_frames": false, + "js": ["install.js"] + } + ], + "browser_action": { + "default_icon": { + "16": "16w.png", + "32": "32w.png", + "19": "19w.png", + "38": "38w.png" + }, + "default_title": "Stylus", + "default_popup": "popup.html" + }, + "default_locale": "en", + "options_ui": { + "page": "options/index.html", + "chrome_style": true + } } diff --git a/messaging.js b/messaging.js index b6f09893..6e378546 100644 --- a/messaging.js +++ b/messaging.js @@ -60,7 +60,9 @@ function updateIcon(tab, styles) { if (!chrome.runtime.lastError) { var t = prefs.get("show-badge") && styles.length ? ("" + styles.length) : ""; chrome.browserAction.setBadgeText({text: t, tabId: tab.id}); - chrome.browserAction.setBadgeBackgroundColor({color: disableAll ? "darkred" : '#006666'}); + chrome.browserAction.setBadgeBackgroundColor({ + color: prefs.get(disableAll ? 'badgeDisabled' : 'badgeNormal') + }); } }); //console.log("Tab " + tab.id + " (" + tab.url + ") badge text set to '" + t + "'."); diff --git a/options/index.css b/options/index.css new file mode 100644 index 00000000..06a02eea --- /dev/null +++ b/options/index.css @@ -0,0 +1,22 @@ +body { + margin: 10px; + font-family: "Helvetica Neue",Helvetica,sans-serif; + font-size: 12px; +} + +table { + width: 100%; +} +td:last-child { + text-align: right; +} + +input[type=number], +button { + width: 80px; +} + +.notes { + font-size: 90%; + color: #999; +} diff --git a/options/index.html b/options/index.html new file mode 100644 index 00000000..82f47b46 --- /dev/null +++ b/options/index.html @@ -0,0 +1,55 @@ + + + + Stylus Options + + + + + +

+ + + + + + + + + + + + + + + +
1
+
+ + +
+ +

+ + + + + + + + + + + +
+ + +
+
+
+ 1: +
+ + + + diff --git a/options/index.js b/options/index.js new file mode 100644 index 00000000..c3990846 --- /dev/null +++ b/options/index.js @@ -0,0 +1,88 @@ +'use strict'; + +function restore () { + chrome.runtime.getBackgroundPage(bg => { + document.getElementById('badgeDisabled').value = bg.prefs.get('badgeDisabled'); + document.getElementById('badgeNormal').value = bg.prefs.get('badgeNormal'); + document.getElementById('updateInterval').value = bg.prefs.get('updateInterval'); + }); +} + +function save () { + chrome.runtime.getBackgroundPage(bg => { + bg.prefs.set('badgeDisabled', document.getElementById('badgeDisabled').value); + bg.prefs.set('badgeNormal', document.getElementById('badgeNormal').value); + bg.prefs.set( + 'updateInterval', + Math.max(0, +document.getElementById('updateInterval').value) + ); + // display notification + let status = document.getElementById('status'); + status.textContent = 'Options saved.'; + setTimeout(() => status.textContent = '', 750); + }); +} + +document.addEventListener('DOMContentLoaded', restore); +document.getElementById('save').addEventListener('click', save); + +// actions +document.addEventListener('click', e => { + let cmd = e.target.dataset.cmd; + let total = 0, updated = 0; + + function update () { + document.getElementById('update-counter').textContent = `${updated}/${total}`; + } + function done (target) { + target.disabled = false; + window.setTimeout(() => { + document.getElementById('update-counter').textContent = ''; + }, 750); + } + + if (cmd === 'open-manage') { + chrome.tabs.query({ + url: chrome.runtime.getURL('manage.html') + }, tabs => { + if (tabs.length) { + chrome.tabs.update(tabs[0].id, { + active: true, + }, () => { + chrome.windows.update(tabs[0].windowId, { + focused: true + }); + }); + } + else { + chrome.tabs.create({ + url: chrome.runtime.getURL('manage.html') + }); + } + }); + } + else if (cmd === 'check-updates') { + e.target.disabled = true; + chrome.runtime.getBackgroundPage(bg => { + bg.update.perform((cmd, value) => { + if (cmd === 'count') { + total = value; + if (!total) { + done(e.target); + } + } + else if (cmd === 'single-updated' || cmd === 'single-skipped') { + updated += 1; + if (total && updated === total) { + done(e.target); + } + } + update(); + }); + }); + // notify the automatic updater to reset the next automatic update accordingly + chrome.runtime.sendMessage({ + method: 'resetInterval' + }); + } +}); diff --git a/storage.js b/storage.js index eea5b236..e02fe8f0 100644 --- a/storage.js +++ b/storage.js @@ -348,6 +348,11 @@ var prefs = chrome.extension.getBackgroundPage().prefs || new function Prefs() { }, "editor.lintDelay": 500, // lint gutter marker update delay, ms "editor.lintReportDelay": 4500, // lint report update delay, ms + + "badgeDisabled": "darkred", // badge background color when disabled + "badgeNormal": "#006666", // badge background color + + "updateInterval": 12 // user-style automatic update interval, hour }; var values = deepCopy(defaults); diff --git a/update.js b/update.js index 29adf508..cf7e4645 100644 --- a/update.js +++ b/update.js @@ -1,4 +1,4 @@ -/* globals getStyles, saveStyle */ +/* globals getStyles, saveStyle, prefs */ 'use strict'; var update = { @@ -11,7 +11,7 @@ var update = { req.onerror = req.ontimeout = () => callback(); req.send(data); }, - md5Check: (style, callback) => { + md5Check: (style, callback, skipped) => { let req = new XMLHttpRequest(); req.open('GET', style.md5Url, true); req.onload = () => { @@ -20,16 +20,16 @@ var update = { callback(style); } else { - console.log(`"${style.name}" style is up-to-date`); + skipped(`"${style.name}" style is up-to-date`); } }; - req.onerror = req.ontimeout = () => console.log('Error validating MD5 checksum'); + req.onerror = req.ontimeout = () => skipped('Error validating MD5 checksum'); req.send(); }, list: (callback) => { getStyles({}, (styles) => callback(styles.filter(style => style.updateUrl))); }, - perform: () => { + perform: (observe = function () {}) => { // from install.js function arraysAreEqual (a, b) { // treat empty array and undefined as equivalent @@ -57,6 +57,7 @@ var update = { } update.list(styles => { + observe('count', styles.length); styles.forEach(style => update.md5Check(style, style => update.fetch(style.updateUrl, response => { if (response) { let json = JSON.parse(response); @@ -65,20 +66,50 @@ var update = { if (json.sections.every((section) => { return style.sections.some(installedSection => sectionsAreEqual(section, installedSection)); })) { - return console.log('everything is the same'); + return observe('single-skipped', '2'); // everything is the same } json.method = 'saveStyle'; json.id = style.id; saveStyle(json, function () { - console.log(`"${style.name}" style is updated`); + observe('single-updated', style.name); }); } else { - console.log('style sections mismatch'); + return observe('single-skipped', '3'); // style sections mismatch } } - }))); + }), () => observe('single-skipped', '1'))); }); } }; +// automatically update all user-styles if "updateInterval" pref is set +window.setTimeout(function () { + let id; + function run () { + update.perform(/*(cmd, value) => console.log(cmd, value)*/); + reset(); + } + function reset () { + window.clearTimeout(id); + let interval = prefs.get('updateInterval'); + // if interval === 0 => automatic update is disabled + if (interval) { + /* console.log('next update', interval); */ + id = window.setTimeout(run, interval * 60 * 60 * 1000); + } + } + if (prefs.get('updateInterval')) { + run(); + } + chrome.runtime.onMessage.addListener(request => { + // when user has changed the predefined time interval in the settings page + if (request.method === 'prefChanged' && request.prefName === 'updateInterval') { + reset(); + } + // when user just manually checked for updates + if (request.method === 'resetInterval') { + reset(); + } + }); +}, 10000);