diff --git a/.eslintignore b/.eslintignore index a710e413..f1fc323f 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,2 +1,3 @@ vendor/ -vendor-overwrites/ +vendor-overwrites/* +!vendor-overwrites/colorpicker diff --git a/.eslintrc b/.eslintrc index b72d8204..3d844c56 100644 --- a/.eslintrc +++ b/.eslintrc @@ -17,6 +17,7 @@ globals: URLS: false BG: false notifyAllTabs: false + sendMessage: false queryTabs: false getTab: false getOwnTab: false diff --git a/README.md b/README.md index 4f137088..be20a223 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,13 @@ Stylus is a fork of Stylish for Chrome, also compatible with Firefox as a WebExt ## Help +[![Discord][chat-image]][chat-link] + See the [help docs](http://userstyles.org/help/stylish_chrome) or [ask in userstyles.org forum](https://forum.userstyles.org). For Stylus specific questions and suggestions please use [review section](http://add0n.com/stylus.html#reviews) of the FAQs page. +[chat-image]: https://img.shields.io/discord/379521691774353408.svg +[chat-link]: https://discordapp.com/widget?id=379521691774353408 + ## Contributing The source is hosted on [GitHub](https://github.com/openstyles/stylus) and pull requests are welcome. diff --git a/_locales/ar/messages.json b/_locales/ar/messages.json index 56ca799a..1eda8a03 100644 --- a/_locales/ar/messages.json +++ b/_locales/ar/messages.json @@ -8,7 +8,7 @@ "description": "Label for the button to enable a style" }, "styleMissingName": { - "message": "أدخل اسمًا.", + "message": "أدخل اسمًا", "description": "Error displayed when user saves without providing a name" }, "appliesDomainOption": { diff --git a/_locales/bg/messages.json b/_locales/bg/messages.json index 6dfa70e3..6af23aa4 100644 --- a/_locales/bg/messages.json +++ b/_locales/bg/messages.json @@ -48,7 +48,7 @@ "description": "Label for the button to enable a style" }, "styleMissingName": { - "message": "Въведете име.", + "message": "Въведете име", "description": "Error displayed when user saves without providing a name" }, "genericHistoryLabel": { diff --git a/_locales/de/messages.json b/_locales/de/messages.json index e436ca3c..af462191 100644 --- a/_locales/de/messages.json +++ b/_locales/de/messages.json @@ -19,6 +19,10 @@ "message": "Styles Exportieren", "description": "" }, + "manageOnlyUsercss": { + "message": "Nur Usercss styles", + "description": "Checkbox to show only Usercss styles" + }, "optionsUpdateInterval": { "message": "Automatischer Update- und Installations-Intervall (in Stunden)", "description": "" @@ -31,6 +35,14 @@ "message": "Exportieren", "description": "Label for the button to export a style ('edit' page) or all styles ('manage' page)" }, + "installButton": { + "message": "Installieren", + "description": "Label for install button" + }, + "styleMetaErrorCheckbox": { + "message": "Ungültige @var Checkbox: Wert muss 0 oder 1 sein", + "description": "Error displayed when the value of @var checkbox is invalid" + }, "linterJSONError": { "message": "Ungültiges JSON Format", "description": "Setting linter config with invalid JSON" @@ -40,7 +52,7 @@ "description": "" }, "updateCheckHistory": { - "message": "Verlauf der Aktualisierungs-Überprüfungen", + "message": "Verlauf der Updatesuche", "description": "" }, "cm_tabSize": { @@ -52,7 +64,7 @@ "description": "Label for the button to enable a style" }, "styleMissingName": { - "message": "Bitte einen Namen eingeben.", + "message": "Bitte Namen eingeben", "description": "Error displayed when user saves without providing a name" }, "genericHistoryLabel": { @@ -68,13 +80,17 @@ "description": "Option to make the style apply to the entered string as a domain" }, "checkForUpdate": { - "message": "Nach Aktualisierung suchen", + "message": "Nach Update suchen", "description": "Label for the button to check a single style for an update" }, "styleNotAppliedRegexpProblemTooltip": { "message": "Der Style wurde aufgrund ungültiger Regulärer Ausdrücke nicht angewandt.", "description": "Tooltip in the popup for styles that were not applied at all" }, + "colorpickerSwitchFormatTooltip": { + "message": "Formate wechseln: HEX -> RGB ->HSL.\nShift-Klick, um Richtung umzukehren.\nKürzel: Bild auf- und Bild ab-Tasten.", + "description": "Tooltip for the switch button in the color picker popup in the style editor." + }, "styleRegexpInvalidExplanation": { "message": "Einige Regeln der Regulären Ausdrücke konnten nicht überprüft werden.", "description": "" @@ -83,6 +99,10 @@ "message": "Dunkle Browser-Themes", "description": "" }, + "styleFromMozillaFormatError": { + "message": "Import vom Mozilla Format fehlgeschlagen", + "description": "Label for the import error" + }, "importAppendLabel": { "message": "Zum Style anfügen", "description": "Label for the button to import a style and append to the existing sections" @@ -92,7 +112,7 @@ "description": "" }, "updateAllCheckSucceededNoUpdate": { - "message": "Keine Aktualisierung gefunden.", + "message": "Keine Updates gefunden.", "description": "Text that displays when an update all check completed and no updates are available" }, "importReportLegendAdded": { @@ -119,6 +139,10 @@ "message": "Ausgegraut", "description": "Label for the checkbox that toggles grayed out mode of applies-to favicons in the new UI on manage page" }, + "versionInvalidOlder": { + "message": "Die Version des Styles ist älter als die des bereits installierten.", + "description": "Displayed when the version of style is older than the installed one" + }, "confirmYes": { "message": "Ja", "description": "'Yes' button in a confirm dialog" @@ -167,10 +191,18 @@ "message": "Löschen", "description": "" }, + "confirmDefault": { + "message": "Voreinstellung verwenden", + "description": "'Set to default' button in a confirm dialog" + }, "confirmCancel": { "message": "Abbrechen", "description": "" }, + "cm_autoCloseBracketsTooltip": { + "message": "Wenn ( [ { ' \" geschrieben werden, automatisch schließende ) ] } ' \" setzen", + "description": "Label for the checkbox in the style editor." + }, "retrieveBckp": { "message": "Styles Importieren", "description": "" @@ -196,7 +228,7 @@ "description": "Option to make the style apply to the entered string as a regular expression" }, "optionsAdvancedExposeIframesNote": { - "message": "Aktiviert die iFrame-spezifische CSS Auszeichnung wie 'html[stylus-iframe] h1 { display:none; }'", + "message": "Aktiviert die iFrame-spezifische CSS Auszeichnung wie \"html[stylus-iframe] h1 { display:none; }\"", "description": "" }, "importReportLegendUpdatedCode": { @@ -228,6 +260,15 @@ "message": "Nur lokale Styles", "description": "Checkbox to show only locally created styles i.e. non-updatable" }, + "styleMetaErrorPreprocessor": { + "message": "Nicht unterstützter @preprocessor: $preprocessor$", + "description": "Error displayed when the value of @preprocessor is not supported", + "placeholders": { + "preprocessor": { + "content": "$1" + } + } + }, "linterIssuesHelp": { "message": "Folgende Probleme wurden von $link$ gefunden:", "description": "Help popup message for the selected CSS linter issues block on the style edit page", @@ -237,18 +278,30 @@ } } }, + "parseUsercssError": { + "message": "Usercss parsen fehlgeschlagen:", + "description": "The error message to show when stylus failed to parse usercss" + }, "searchStyles": { "message": "Inhalte durchsuchen", "description": "Label for the search filter textbox on the Manage styles page" }, "optionsUpdateImportNote": { - "message": "Nach dem Importieren von Styles aus einer alten Version oder von Stylish ist eine einmalige manuelle Überprüfung der Aktualisierungen (Updates) in der Verwaltung nötig. Dies stellt sicher, dass alle Styles auf dem aktuellsten Stand sind.", + "message": "Nach dem Importieren von Styles aus einer alten Version oder von Stylish ist eine einmalige manuelle Updatesuche in der Verwaltung nötig. Dies stellt sicher, dass alle Styles auf dem aktuellsten Stand sind.", "description": "" }, "checkAllUpdatesForce": { "message": "Nochmals überprüfen, ich habe keine Styles bearbeitet!", "description": "Label for the button to apply all detected updates" }, + "manageOnlyNonUsercss": { + "message": "Keine Usercss styles", + "description": "Checkbox to show only non-Usercss (standard) styles" + }, + "liveReloadLabel": { + "message": "Echtzeitaktualisierung", + "description": "The label of live-reload feature" + }, "unreachableFileHint": { "message": "Stylus kann nur auf das file:// Protokoll in der URL zugreifen, wenn dies in den Einstellungen der Erweiterung unter chrome://extensions festgelegt wurde.", "description": "Note in the toolbar popup for file:// URLs" @@ -262,7 +315,7 @@ "description": "Label for the checkbox controlling toolbar badge text." }, "manageFavicons": { - "message": "Favicons in der 'Gilt für' Spalte anzeigen", + "message": "Favicons in der \"Gilt für\" Spalte anzeigen", "description": "Label for the checkbox that toggles applies-to favicons in the new UI on manage page" }, "menuShowBadge": { @@ -313,6 +366,10 @@ "message": "Regulärer Ausdruck ist ungültig.", "description": "Validation message for a bad regexp in a style" }, + "license": { + "message": "Lizenz", + "description": "Label for the license" + }, "optionsHeading": { "message": "Optionen", "description": "Heading for options section on manage page." @@ -335,7 +392,7 @@ "description": "Label for the style maanger opener in the browser action context menu." }, "styleUpdate": { - "message": "Möchtest Du '$stylename$' wirklich aktualisieren?", + "message": "Möchtest Du \"$stylename$\" wirklich aktualisieren?", "description": "Confirmation when updating a style", "placeholders": { "stylename": { @@ -355,6 +412,10 @@ "message": "Ungültige übersprungen", "description": "Text after the number of styles skipped due to being invalid (not a Stylus/Stylish backup file probably) in the report shown after importing styles" }, + "optionsAdvancedNewStyleAsUsercss": { + "message": "Schreibe neuen Style als usercss", + "description": "" + }, "genericResetLabel": { "message": "Zurücksetzen", "description": "Used in various parts of UI to indicate that something may be reset to its original state" @@ -384,6 +445,10 @@ "message": "Verwende die /re/ Syntax zur Suche als Regulärer Ausdruck", "description": "Label after the search input field in the editor shown on Ctrl-F" }, + "popupBordersTooltip": { + "message": "Nützlich für dunkle Themes im neuen Chrome, da dort die Seitenränder nicht mehr gefärbt werden", + "description": "" + }, "updateCheckManualUpdateHint": { "message": "Eine erzwungene Aktualisierung wird die lokalen Änderungen überschreiben.", "description": "Additional text displayed when an update check skipped updating the style to avoid losing local modifications" @@ -396,6 +461,10 @@ "message": "Verwerfe den aktuellen Style-Inhalt und überschreibe ihn mit dem importierten", "description": "Label for the button to import and overwrite current style" }, + "installUpdateFromLabel": { + "message": "Nach Updates suchen", + "description": "Label for the checkbox to save current URL for update check" + }, "cm_resizeGripHint": { "message": "Doppelklick, um Höhe zu maximieren / wiederherzustellen", "description": "Tooltip for the resize grip in style editor" @@ -421,13 +490,17 @@ "description": "Label for the button to remove an 'applies' entry" }, "updatesCurrentlyInstalled": { - "message": "Installierte Aktualisierungen:", + "message": "Installierte Updates:", "description": "Text that displays when an update is installed on options page. Followed by the number of currently installed updates." }, "styleToMozillaFormatTitle": { "message": "Style im Mozilla Format", "description": "Title of the popup with the style code in Mozilla format, shown after pressing the Export button on Edit style page" }, + "cm_colorpicker": { + "message": "Farbwähler für CSS-Farben", + "description": "Label for the checkbox controlling colorpicker option for the style editor." + }, "writeStyleFor": { "message": "Style erstellen für:", "description": "Label for toolbar pop-up that precedes the links to write a new style" @@ -470,11 +543,11 @@ "description": "Label for the button to make a style apply only to specific sites" }, "installUpdate": { - "message": "Aktualisierung installieren", + "message": "Update installieren", "description": "Label for the button to install an update for a single style" }, "optionsCheckUpdate": { - "message": "Alle verfügbaren Aktualisierungen Installieren", + "message": "Alle verfügbaren Updates Installieren", "description": "" }, "filteredStyles": { @@ -525,6 +598,10 @@ "message": "Alle Styles deaktivieren", "description": "Label for the checkbox that turns all enabled styles off." }, + "appliesLineWidgetLabel": { + "message": "Zeige \"Gilt für\" Info", + "description": "Label for the checkbox to display applies-to information in the single editor" + }, "updateCheckSkippedMaybeLocallyEdited": { "message": "Dieser Style scheint lokal bearbeitet worden zu sein.", "description": "Text that displays when an update check skipped updating the style to avoid losing possible local modifications" @@ -546,7 +623,7 @@ "description": "Displayed in style manager when unable to connect to the background page" }, "checkingForUpdate": { - "message": "Suche nach Aktualisierungen...", + "message": "Suche nach Updates...", "description": "Text to display when checking a style for an update" }, "styleRegexpTestFull": { @@ -554,7 +631,7 @@ "description": "RegExp test report: label for the fully matching expressions" }, "manageMaxTargets": { - "message": "Anzahl der 'Gilt für' Elemente", + "message": "Anzahl der \"Gilt für\" Elemente", "description": "Label for the numeric input box to limit max number of applies-to targets in the new UI on manage page" }, "popupManageTooltip": { @@ -565,20 +642,43 @@ "message": "Stylus nutzt hierzu den externen Dienst https://www.google.com/s2/favicons", "description": "Label for the checkbox that toggles applies-to favicons in the new UI on manage page" }, + "styleInstallOverwrite": { + "message": "\"$stylename$\" ist bereits installiert. Überschreiben?\nVersion: $oldVersion$ -> $newVersion$", + "description": "Confirmation when re-installing a style", + "placeholders": { + "stylename": { + "content": "$1" + }, + "newVersion": { + "content": "$3" + }, + "oldVersion": { + "content": "$2" + } + } + }, "updateCheckSkippedLocallyEdited": { "message": "Dieser Style wurde lokal bearbeitet.", "description": "Text that displays when an update check skipped updating the style to avoid losing local modifications" }, "linterRulesLink": { - "message": "Vollständige Liste der Regeln anzeigen", + "message": "Vollständige Liste der Regeln anzeigen für", "description": "Stylelint or CSSLint rules label added immediately before a link" }, + "styleUpdateDiscardChanges": { + "message": "Der Style wurde außerhalb des Editors verändert. Style neu laden?", + "description": "Confirmation to update the style in the editor" + }, "optionsResetButton": { "message": "Optionen zurücksetzen", "description": "" }, + "externalUsercssDocument": { + "message": "Dokumentation für Usercss", + "description": "Label for the external link to usercss documentation" + }, "optionsAdvancedContextDelete": { - "message": "'Löschen' im Editor-Kontextmenü hinzufügen", + "message": "\"Löschen\" im Editor-Kontextmenü hinzufügen", "description": "" }, "linterConfigPopupTitle": { @@ -590,6 +690,10 @@ } } }, + "configureStyle": { + "message": "Konfigurieren", + "description": "Label for the button to configure userstyle" + }, "importReportLegendUpdatedBoth": { "message": "Aktualisierte Meta Infos und Codes", "description": "Text after the number of styles updated entirely in the report shown after importing styles" @@ -603,7 +707,7 @@ "description": "RegExp test button label in the editor shown when applies-to list has a regexp value" }, "appliesHelp": { - "message": "Lege mit den Einstellungen von 'Gilt für' fest, für welche URLs der Code in diesem Bereich gelten soll.", + "message": "Lege mit den Einstellungen von \"Gilt für\" fest, für welche URLs der Code in diesem Bereich gelten soll.", "description": "Help text for 'applies to' section" }, "editStyleHeading": { @@ -618,6 +722,28 @@ "message": "Autovervollständigen bei Eingabe", "description": "Label for the checkbox in the style editor." }, + "linterCSSLintIncompatible": { + "message": "CSSLint unterstützt $preprocessorname$ nicht", + "description": "The label to display when the preprocessor isn't compatible with CSSLint", + "placeholders": { + "preprocessorname": { + "content": "$1" + } + } + }, + "styleMetaErrorSelectValueMismatch": { + "message": "Ungültiges @select: Wert existiert nicht in der Liste", + "description": "Error displayed when the value of @select is invalid" + }, + "styleMetaErrorColor": { + "message": "$color$ist kein gültiger Farbcode", + "description": "Error displayed when the value of @var color is invalid", + "placeholders": { + "color": { + "content": "$1" + } + } + }, "manageOnlyDisabled": { "message": "Nur deaktivierte Styles", "description": "Checkbox to show only disabled styles" @@ -631,21 +757,29 @@ "description": "Style editor's 'highglight' drop-down list option: highlight the occurrences of currently selected text" }, "updateAllCheckSucceededSomeEdited": { - "message": "Einige Styles wurden nicht überprüft, um dem Verlust von lokalen Bearbeitungen vorzubeugen. Die Aktualisierungen können entweder durch einzelne manuelle Überprüfung oder durch eine erneute Ausführung der Aktualisierung und anschließendem Update für alle Styles erzwungen werden (Lokale Bearbeitungen werden dann überschrieben).", + "message": "Einige Styles wurden nicht überprüft, um dem Verlust von lokalen Bearbeitungen vorzubeugen. Die Aktualisierungen können entweder durch einzelne manuelle Überprüfung oder durch eine erneute Ausführung der Updatesuche (und anschließendem Update) für alle Styles erzwungen werden. Lokale Bearbeitungen werden dann überschrieben.", "description": "Text that displays when an update all check completed and no updates are available" }, "stylusUnavailableForURL": { "message": "Stylus funktioniert nicht auf Seiten wie diesen.", "description": "Note in the toolbar pop-up when on a URL Stylus can't affect" }, + "popupBorders": { + "message": "Weiße Rahmen an den Seiten hinzufügen", + "description": "" + }, "manageOnlyUpdates": { - "message": "Nur mit Aktualisierungen oder Problemen", + "message": "Nur mit Updates oder Problemen", "description": "Checkbox to show only styles that have updates after check-all-styles-for-updates was performed" }, "addStyleTitle": { "message": "Style hinzufügen", "description": "Title of the page for adding styles" }, + "externalLink": { + "message": "Externer Link", + "description": "Label for external links" + }, "importReplaceLabel": { "message": "Style überschreiben", "description": "Label for the button to import and overwrite current style" @@ -662,6 +796,10 @@ "message": "Erweitert", "description": "" }, + "alphaChannel": { + "message": "Deckkraft", + "description": "Label of color's opacity" + }, "importAppendTooltip": { "message": "Füge den importierten Style an den aktuellen", "description": "Tooltip for the button to import a style and append to the existing sections" @@ -707,25 +845,50 @@ "description": "Tooltip for the checkbox to show only locally created styles i.e. non-updatable" }, "checkAllUpdates": { - "message": "Nach Aktualisierungen suchen", + "message": "Nach Updates suchen", "description": "Label for the button to check all styles for updates" }, "openOptionsManage": { "message": "Optionen", "description": "Go to Options UI" }, + "colorpickerTooltip": { + "message": "Farbwähler öffnen", + "description": "Tooltip for the colored squares shown before CSS colors in the style editor." + }, "optionsCustomizeBadge": { "message": "Badge auf dem Toolbar-Icon", "description": "" }, + "installUpdateFrom": { + "message": "Style erhält momentan Updates von $url$", + "description": "Label to describe where the style gets update", + "placeholders": { + "url": { + "content": "$1" + } + } + }, "importReportLegendIdentical": { "message": "Identische übersprungen", "description": "Text after the number of styles skipped due to being identical to the already installed ones in the report shown after importing styles" }, + "manageNewStyleAsUsercss": { + "message": "als Usercss", + "description": "VERY SHORT label for the checkbox next to the 'Write new style' button in the style manager" + }, "optionsPopupWidth": { "message": "Popup-Breite (in Pixeln)", "description": "" }, + "cm_autoCloseBrackets": { + "message": "Klammern automatisch schließen", + "description": "Label for the checkbox in the style editor." + }, + "installButtonReinstall": { + "message": "Neuinstallieren", + "description": "Label for reinstall button" + }, "linterInvalidConfigError": { "message": "Nicht gespeichert aufgrund folgender ungültiger Einstellungen:", "description": "Invalid linter config will show a message followed by a list of invalid entries" @@ -734,6 +897,19 @@ "message": "Nein", "description": "'No' button in a confirm dialog" }, + "styleMissingMeta": { + "message": "Erforderliche Metadaten fehlen: @$key$", + "description": "Error displayed when a mandatory metadata is missing", + "placeholders": { + "key": { + "content": "$1" + } + } + }, + "appliesLineWidgetWarning": { + "message": "Funktioniert nicht mit minified CSS", + "description": "A warning that applies-to information won't show properly with minified CSS" + }, "undo": { "message": "Rückgängig", "description": "Button label" @@ -742,6 +918,14 @@ "message": "Tastaturbelegung", "description": "Label for the drop-down list controlling the keymap for the style editor." }, + "externalSupport": { + "message": "zur Supportseite", + "description": "Label for the external link to style's support site" + }, + "confirmSave": { + "message": "Speichern", + "description": "'Save' button in a confirm dialog" + }, "manageNewUI": { "message": "Neues Verwaltungs Design-Layout.", "description": "Label for the checkbox that toggles the new UI on manage page" @@ -762,14 +946,27 @@ "message": "Ersetzen durch", "description": "Label before the replace-with input field in the editor shown on Ctrl-H etc." }, + "liveReloadError": { + "message": "Bei der Echtzeitaktualisierung der Datei ist ein Fehler aufgetreten", + "description": "The label of live-reload error" + }, "deleteStyleLabel": { "message": "Löschen", "description": "Label for the button to delete a style" }, "updateCheckManualUpdateForce": { - "message": "Aktualisierungen installieren (Lokale Bearbeitungen werden überschrieben)", + "message": "Updates installieren (Lokale Bearbeitungen werden überschrieben)", "description": "Additional text displayed when an update check skipped updating the style to avoid losing local modifications" }, + "styleInstallFailed": { + "message": "Installation des Userstyles fehlgeschlagen!\n$error$", + "description": "Warning when installation failed", + "placeholders": { + "error": { + "content": "$1" + } + } + }, "optionsAdvancedExposeIframes": { "message": "Ermögliche Iframes via HTML[stylus-iframe]", "description": "" @@ -779,9 +976,13 @@ "description": "Label for the button to go to the add style page" }, "optionsUpdateIntervalNote": { - "message": "Zum Deaktivieren der automatischen Aktualisierungs-Überprüfung den Wert auf 0 setzen.", + "message": "Zum Deaktivieren der automatischen Updateüberprüfung den Wert auf 0 setzen.", "description": "" }, + "installButtonUpdate": { + "message": "Aktualisieren", + "description": "Label for update button" + }, "backupButtons": { "message": "Datensicherung", "description": "Heading for backup" @@ -794,10 +995,22 @@ "message": "Bearbeiten", "description": "Label for the button to go to the edit style page" }, + "installButtonInstalled": { + "message": "Installiert", + "description": "Text displayed when the style is successfully installed" + }, + "author": { + "message": "Autor", + "description": "Label for the style author" + }, "popupOpenEditInWindow": { "message": "Editor in neuem Fenster öffnen", "description": "Label for the checkbox controlling 'edit' action behavior in the popup." }, + "appliesRemoveError": { + "message": "Kann letzten \"Gilt für\" Eintrag nicht entfernen", + "description": "Error displayed when the last 'applies' is going to be removed" + }, "backupMessage": { "message": "Wähle eine Datei aus oder ziehe die Datei auf diese Seite. (Drag and Drop)", "description": "Message for backup" @@ -817,5 +1030,9 @@ "description": { "message": "Gestalte das Web neu mit Stylus, dem Style Manager. Stylus ermöglicht dir ganz einfach Themes und Designs für viele populäre Websites zu installieren.", "description": "Extension description" + }, + "confirmClose": { + "message": "Schließen", + "description": "'Close' button in a confirm dialog" } } \ No newline at end of file diff --git a/_locales/el/messages.json b/_locales/el/messages.json index a6e0de1a..473ab9ea 100644 --- a/_locales/el/messages.json +++ b/_locales/el/messages.json @@ -12,7 +12,7 @@ "description": "Label for the button to enable a style" }, "styleMissingName": { - "message": "Εισάγετε ένα όνομα.", + "message": "Εισάγετε ένα όνομα", "description": "Error displayed when user saves without providing a name" }, "appliesDomainOption": { diff --git a/_locales/en/messages.json b/_locales/en/messages.json index b75b6027..2c6a1ee6 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -127,6 +127,10 @@ "message": "Autocomplete on typing", "description": "Label for the checkbox in the style editor." }, + "cm_colorpicker": { + "message": "Colorpickers for CSS colors", + "description": "Label for the checkbox controlling colorpicker option for the style editor." + }, "cm_indentWithTabs": { "message": "Use tabs with smart indentation", "description": "Label for the checkbox controlling tabs with smart indentation option for the style editor." @@ -171,6 +175,14 @@ "message": "Theme", "description": "Label for the style editor's CSS theme." }, + "colorpickerSwitchFormatTooltip": { + "message": "Switch formats: HEX -> RGB -> HSL.\nShift-click to reverse the direction.\nAlso via PgUp (PageUp), PgDn (PageDown) keys.", + "description": "Tooltip for the switch button in the color picker popup in the style editor." + }, + "colorpickerTooltip": { + "message": "Open color picker", + "description": "Tooltip for the colored squares shown before CSS colors in the style editor." + }, "dysfunctional": { "message": "Stylus cannot function in private windows because Firefox disallows direct connection to the internal background page context of the extension.", "description": "Displayed in Firefox when its settings make Stylus dysfunctional" @@ -203,6 +215,10 @@ "message": "Use default", "description": "'Set to default' button in a confirm dialog" }, + "confirmDiscardChanges": { + "message": "Discard the changes?", + "description": "Generic label or title displayed when trying to close something (not a style) with unsaved changes" + }, "confirmSave": { "message": "Save", "description": "'Save' button in a confirm dialog" @@ -422,19 +438,19 @@ "description": "Label for the button to import and overwrite current style" }, "installButton": { - "message": "Install", + "message": "Install style", "description": "Label for install button" }, "installButtonInstalled": { - "message": "Installed", + "message": "Style installed", "description": "Text displayed when the style is successfully installed" }, "installButtonUpdate": { - "message": "Update", + "message": "Update style", "description": "Label for update button" }, "installButtonReinstall": { - "message": "Reinstall", + "message": "Reinstall style", "description": "Label for reinstall button" }, "installUpdate": { @@ -529,6 +545,10 @@ "message": "Installed Styles", "description": "Heading for the manage page" }, + "manageNewStyleAsUsercss": { + "message": "as Usercss", + "description": "VERY SHORT label for the checkbox next to the 'Write new style' button in the style manager" + }, "manageOnlyEnabled": { "message": "Only enabled styles", "description": "Checkbox to show only enabled styles" @@ -549,6 +569,14 @@ "message": "(the styles not installed through a userstyles.org page)", "description": "Tooltip for the checkbox to show only locally created styles i.e. non-updatable" }, + "manageOnlyNonUsercss": { + "message": "Only non-Usercss styles", + "description": "Checkbox to show only non-Usercss (standard) styles" + }, + "manageOnlyUsercss": { + "message": "Only Usercss styles", + "description": "Checkbox to show only Usercss styles" + }, "manageOnlyUpdates": { "message": "Only with updates or issues", "description": "Checkbox to show only styles that have updates after check-all-styles-for-updates was performed" @@ -623,6 +651,14 @@ "message": "Shift-click or right-click opens manager with styles applicable for current site", "description": "Tooltip for the 'Manage' button in the popup." }, + "popupHotkeysInfo": { + "message": "<1>-<9>, <0>, also on numpad - toggles Nth style (0 is 10)\n- toggles first style with a name that starts with the letter\n opens editor instead of toggling\n enables listed styles\n disables listed styles\n and <`> (backtick) - toggles initially enabled styles; doesn't apply to subsequently enabled styles while the popup is open so you can restore the initial selection after testing stuff: simply disable all, then toggle i.e. \nMore info on wiki", + "description": "NOTE1: preserve < and > symbols so that is styled as a key.\nNOTE2: the last line is displayed as a text of the link to the wiki page.\nNOTE3: this is the list of hotkeys displayed after clicking the right edge of the extension popup." + }, + "popupHotkeysTooltip": { + "message": "Click to see available hotkeys", + "description": "Tooltip displayed when hovering the right edge of the extension popup" + }, "popupOpenEditInWindow": { "message": "Open editor in a new window", "description": "Label for the checkbox controlling 'edit' action behavior in the popup." @@ -825,7 +861,7 @@ } }, "styleMissingName": { - "message": "Enter a name.", + "message": "Enter a name", "description": "Error displayed when user saves without providing a name" }, "styleSaveLabel": { @@ -877,6 +913,10 @@ "message": "As a security precaution, the browser prohibits extensions from affecting its built-in pages (like chrome://version, the standard new tab page as of Chrome 61, about:addons, and so on) as well as other extensions' pages. Each browser also restricts access to its own extensions gallery (like Chrome Web Store or AMO).", "description": "Sub-note in the toolbar pop-up when on a URL Stylus can't affect" }, + "syncStorageErrorSaving": { + "message": "The value cannot be saved. Try reducing the amount of text.", + "description": "Displayed when trying to save an excessively big value via storage.sync API" + }, "toggleStyle": { "message": "Toggle style", "description": "Label for the checkbox to enable/disable a style" @@ -946,6 +986,20 @@ "message": "Updates installed:", "description": "Text that displays when an update is installed on options page. Followed by the number of currently installed updates." }, + "usercssEditorNamePlaceholder": { + "message": "Specify @name in the code", + "description": "Placeholder text for the empty name input field when creating a new Usercss style" + }, + "usercssReplaceTemplateName": { + "message": "Empty @name replaces the default template", + "description": "The text shown after @name when creating a new Usercss style" + }, + "usercssReplaceTemplateConfirmation": { + "message": "Replace the default template for new Usercss styles with the current code?" + }, + "usercssConfigIncomplete": { + "message": "The style was updated or deleted after the configuration dialog was shown. These variables were not saved to avoid corrupting the style's metadata:" + }, "versionInvalidOlder": { "message": "The version is older than the installed style.", "description": "Displayed when the version of style is older than the installed one" diff --git a/_locales/es/messages.json b/_locales/es/messages.json index d9ee12a6..b2c232f1 100644 --- a/_locales/es/messages.json +++ b/_locales/es/messages.json @@ -19,6 +19,10 @@ "message": "Exportar estilos", "description": "" }, + "manageOnlyUsercss": { + "message": "Sólo estilos Usercss", + "description": "Checkbox to show only Usercss styles" + }, "optionsUpdateInterval": { "message": "Buscar e instalar automáticamente todas las actualizaciones disponibles de estilos de usuario (en horas)", "description": "" @@ -31,6 +35,14 @@ "message": "Exportar", "description": "Label for the button to export a style ('edit' page) or all styles ('manage' page)" }, + "installButton": { + "message": "Instalar", + "description": "Label for install button" + }, + "styleMetaErrorCheckbox": { + "message": "Casilla @var no válida: El valor debe estar ser 0 o 1", + "description": "Error displayed when the value of @var checkbox is invalid" + }, "linterJSONError": { "message": "Formato JSON no válido", "description": "Setting linter config with invalid JSON" @@ -75,6 +87,10 @@ "message": "El estilo no se aplicó debido a su uso incorrecto de 'regexp()'", "description": "Tooltip in the popup for styles that were not applied at all" }, + "colorpickerSwitchFormatTooltip": { + "message": "Alternar formatos: HEX -> RGB -> HSL.\nMayús+Clic para invertir la dirección.\nTambién con las teclas RePág (Retroceso de página), AvPág (Avance de página).", + "description": "Tooltip for the switch button in the color picker popup in the style editor." + }, "styleRegexpInvalidExplanation": { "message": "Algunas reglas «regexp()» que no se pudieron compilar en absoluto.", "description": "" @@ -83,6 +99,10 @@ "message": "Temas de navegador oscuros", "description": "" }, + "styleFromMozillaFormatError": { + "message": "No se pudo importar desde el formato Mozilla", + "description": "Label for the import error" + }, "importAppendLabel": { "message": "Agregar al estilo", "description": "Label for the button to import a style and append to the existing sections" @@ -123,6 +143,10 @@ "message": "Atenuado", "description": "Label for the checkbox that toggles grayed out mode of applies-to favicons in the new UI on manage page" }, + "versionInvalidOlder": { + "message": "Esta versión es posterior al estilo instalado.", + "description": "Displayed when the version of style is older than the installed one" + }, "confirmYes": { "message": "Sí", "description": "'Yes' button in a confirm dialog" @@ -175,10 +199,18 @@ "message": "Eliminar", "description": "" }, + "confirmDefault": { + "message": "Usar predeterminado", + "description": "'Set to default' button in a confirm dialog" + }, "confirmCancel": { "message": "Cancelar", "description": "" }, + "cm_autoCloseBracketsTooltip": { + "message": "Añade automáticamente un equivalente de cierre al escribir uno de apertura de ()[]{}''\"\"", + "description": "Label for the checkbox in the style editor." + }, "retrieveBckp": { "message": "Importar estilos", "description": "" @@ -236,6 +268,15 @@ "message": "Sólo estilos creados localmente", "description": "Checkbox to show only locally created styles i.e. non-updatable" }, + "styleMetaErrorPreprocessor": { + "message": "@preprocessor no soportado: $preprocessor$", + "description": "Error displayed when the value of @preprocessor is not supported", + "placeholders": { + "preprocessor": { + "content": "$1" + } + } + }, "linterIssuesHelp": { "message": "Estos problemas fueron encontrados por $link$:", "description": "Help popup message for the selected CSS linter issues block on the style edit page", @@ -245,6 +286,10 @@ } } }, + "parseUsercssError": { + "message": "Stylus no pudo interpretar usercss:", + "description": "The error message to show when stylus failed to parse usercss" + }, "searchStyles": { "message": "Buscar contenidos", "description": "Label for the search filter textbox on the Manage styles page" @@ -257,6 +302,14 @@ "message": "Comprobar de nuevo, ¡no he editado ningún estilo!", "description": "Label for the button to apply all detected updates" }, + "manageOnlyNonUsercss": { + "message": "Sólo estilos no-Usercss", + "description": "Checkbox to show only non-Usercss (standard) styles" + }, + "liveReloadLabel": { + "message": "Recargar sobre la marcha", + "description": "The label of live-reload feature" + }, "unreachableFileHint": { "message": "Stylus puede acceder a URL file:// solo si activa la casilla correspondiente para la extensión Stylus en la página chrome://extensions.", "description": "Note in the toolbar popup for file:// URLs" @@ -329,6 +382,10 @@ "message": "La expresión regular proporcionada no es válida.", "description": "Validation message for a bad regexp in a style" }, + "license": { + "message": "Licencia", + "description": "Label for the license" + }, "optionsHeading": { "message": "Opciones", "description": "Heading for options section on manage page." @@ -371,6 +428,10 @@ "message": "no válidos omitidos", "description": "Text after the number of styles skipped due to being invalid (not a Stylus/Stylish backup file probably) in the report shown after importing styles" }, + "optionsAdvancedNewStyleAsUsercss": { + "message": "Escribir nuevo estilo como usercss", + "description": "" + }, "genericResetLabel": { "message": "Restablecer", "description": "Used in various parts of UI to indicate that something may be reset to its original state" @@ -400,6 +461,10 @@ "message": "Use la sintaxis /re/ para búsquedas con expresiones regulares", "description": "Label after the search input field in the editor shown on Ctrl-F" }, + "popupBordersTooltip": { + "message": "Útil para temas oscuros en el nuevo Chrome pues ya no pinta los bordes laterales", + "description": "" + }, "updateCheckManualUpdateHint": { "message": "Forzar una actualización sobrescribirá cualquier edición local.", "description": "Additional text displayed when an update check skipped updating the style to avoid losing local modifications" @@ -412,6 +477,10 @@ "message": "Descarta contenidos del estilo actual y los sobrescribe con el estilo importado", "description": "Label for the button to import and overwrite current style" }, + "installUpdateFromLabel": { + "message": "Buscar actualizaciones", + "description": "Label for the checkbox to save current URL for update check" + }, "cm_resizeGripHint": { "message": "Doble-clic para maximizar/restaurar la altura", "description": "Tooltip for the resize grip in style editor" @@ -444,6 +513,10 @@ "message": "Estilo en formato Mozilla", "description": "Title of the popup with the style code in Mozilla format, shown after pressing the Export button on Edit style page" }, + "cm_colorpicker": { + "message": "Selectores de color para colores CSS", + "description": "Label for the checkbox controlling colorpicker option for the style editor." + }, "writeStyleFor": { "message": "Escribir estilo para:", "description": "Label for toolbar pop-up that precedes the links to write a new style" @@ -545,6 +618,10 @@ "message": "Desactivar todos los estilos", "description": "Label for the checkbox that turns all enabled styles off." }, + "appliesLineWidgetLabel": { + "message": "Muestra la información 'Se aplica a'", + "description": "Label for the checkbox to display applies-to information in the single editor" + }, "updateCheckSkippedMaybeLocallyEdited": { "message": "Este estilo podría haberse editado localmente.", "description": "Text that displays when an update check skipped updating the style to avoid losing possible local modifications" @@ -585,6 +662,21 @@ "message": "Stylus usa un servicio externo https://www.google.com/s2/favicons", "description": "Label for the checkbox that toggles applies-to favicons in the new UI on manage page" }, + "styleInstallOverwrite": { + "message": "'$stylename$' ya está instalado ¿Sobrescribirlo?\nVersión: $oldVersion$ -> $newVersion$", + "description": "Confirmation when re-installing a style", + "placeholders": { + "stylename": { + "content": "$1" + }, + "newVersion": { + "content": "$3" + }, + "oldVersion": { + "content": "$2" + } + } + }, "updateCheckSkippedLocallyEdited": { "message": "Este estilo se editó localmente.", "description": "Text that displays when an update check skipped updating the style to avoid losing local modifications" @@ -593,6 +685,10 @@ "message": "Vea una lista completa de reglas", "description": "Stylelint or CSSLint rules label added immediately before a link" }, + "styleUpdateDiscardChanges": { + "message": "El estilo se cambió fuera del editor. ¿Desea recagar el estilo?", + "description": "Confirmation to update the style in the editor" + }, "optionsResetButton": { "message": "Restablecer opciones", "description": "" @@ -601,6 +697,10 @@ "message": "Código", "description": "Label for the code for a section" }, + "externalUsercssDocument": { + "message": "Documentación para Usercss", + "description": "Label for the external link to usercss documentation" + }, "optionsAdvancedContextDelete": { "message": "Añadir 'Eliminar' al menú contextual del editor", "description": "" @@ -614,6 +714,10 @@ } } }, + "configureStyle": { + "message": "Configurar", + "description": "Label for the button to configure userstyle" + }, "importReportLegendUpdatedBoth": { "message": "actualizarón tanto meta información como código", "description": "Text after the number of styles updated entirely in the report shown after importing styles" @@ -642,6 +746,32 @@ "message": "Autocompletar al escribir", "description": "Label for the checkbox in the style editor." }, + "linterCSSLintIncompatible": { + "message": "CSSLint no soporta el 'preprocessor' $preprocessorname$", + "description": "The label to display when the preprocessor isn't compatible with CSSLint", + "placeholders": { + "preprocessorname": { + "content": "$1" + } + } + }, + "styleMetaErrorSelectValueMismatch": { + "message": "@select no válido: El valor no existe en la lista", + "description": "Error displayed when the value of @select is invalid" + }, + "styleMetaErrorColor": { + "message": "$color$ no es un color válido", + "description": "Error displayed when the value of @var color is invalid", + "placeholders": { + "color": { + "content": "$1" + } + } + }, + "externalFeedback": { + "message": "Comentarios", + "description": "Label for the external link to send feedback for the style" + }, "manageOnlyDisabled": { "message": "Sólo estilos deshabilitados", "description": "Checkbox to show only disabled styles" @@ -662,6 +792,10 @@ "message": "Stylus no funciona en páginas como esta.", "description": "Note in the toolbar pop-up when on a URL Stylus can't affect" }, + "popupBorders": { + "message": "Añadir bordes blancos en los laterales", + "description": "" + }, "manageOnlyUpdates": { "message": "Sólo con actualizaciones o problemas", "description": "Checkbox to show only styles that have updates after check-all-styles-for-updates was performed" @@ -670,6 +804,14 @@ "message": "Añadir estilo", "description": "Title of the page for adding styles" }, + "externalLink": { + "message": "Enlace externo", + "description": "Label for external links" + }, + "externalHomepage": { + "message": "Página principal", + "description": "Label for the external link to style's homepage" + }, "importReplaceLabel": { "message": "Sobrescribir estilo", "description": "Label for the button to import and overwrite current style" @@ -686,6 +828,10 @@ "message": "Avanzadas", "description": "" }, + "alphaChannel": { + "message": "Opacidad", + "description": "Label of color's opacity" + }, "importAppendTooltip": { "message": "Agrega el estilo importado al estilo actual", "description": "Tooltip for the button to import a style and append to the existing sections" @@ -738,22 +884,60 @@ "message": "Interfaz de opciones", "description": "Go to Options UI" }, + "colorpickerTooltip": { + "message": "Abrir selector de color", + "description": "Tooltip for the colored squares shown before CSS colors in the style editor." + }, "optionsCustomizeBadge": { "message": "Distintivo en el icono de barra de herramientas", "description": "" }, + "installUpdateFrom": { + "message": "Actualmente el estilo se actualiza desde $url$", + "description": "Label to describe where the style gets update", + "placeholders": { + "url": { + "content": "$1" + } + } + }, "importReportLegendIdentical": { "message": "idénticos omitidos", "description": "Text after the number of styles skipped due to being identical to the already installed ones in the report shown after importing styles" }, + "manageNewStyleAsUsercss": { + "message": "como Usercss", + "description": "VERY SHORT label for the checkbox next to the 'Write new style' button in the style manager" + }, "optionsPopupWidth": { "message": "Anchura del diálogo emergente (en píxeles)", "description": "" }, + "cm_autoCloseBrackets": { + "message": "Cerrar automáticamente corchetes y comillas", + "description": "Label for the checkbox in the style editor." + }, + "installButtonReinstall": { + "message": "Reinstalar", + "description": "Label for reinstall button" + }, "linterInvalidConfigError": { "message": "No se guardó debido a estos ajustes de configuración no válidos:", "description": "Invalid linter config will show a message followed by a list of invalid entries" }, + "styleMissingMeta": { + "message": "Metadatos @$key$ ausentes", + "description": "Error displayed when a mandatory metadata is missing", + "placeholders": { + "key": { + "content": "$1" + } + } + }, + "appliesLineWidgetWarning": { + "message": "No funciona con CSS minificado", + "description": "A warning that applies-to information won't show properly with minified CSS" + }, "undo": { "message": "Deshacer", "description": "Button label" @@ -762,6 +946,14 @@ "message": "Mapa de teclado", "description": "Label for the drop-down list controlling the keymap for the style editor." }, + "externalSupport": { + "message": "Asistencia", + "description": "Label for the external link to style's support site" + }, + "confirmSave": { + "message": "Guardar", + "description": "'Save' button in a confirm dialog" + }, "manageNewUI": { "message": "Nuevo diseño de interfaz de gestión", "description": "Label for the checkbox that toggles the new UI on manage page" @@ -782,6 +974,10 @@ "message": "Reemplazar con", "description": "Label before the replace-with input field in the editor shown on Ctrl-H etc." }, + "liveReloadError": { + "message": "Ocurrió un error al vigilar el fichero", + "description": "The label of live-reload error" + }, "deleteStyleLabel": { "message": "Eliminar", "description": "Label for the button to delete a style" @@ -790,6 +986,15 @@ "message": "Instalar actualización (se sobrescribirán las ediciones locales)", "description": "Additional text displayed when an update check skipped updating the style to avoid losing local modifications" }, + "styleInstallFailed": { + "message": "¡No se pudo instalar el estilo de usuario!\n$error$", + "description": "Warning when installation failed", + "placeholders": { + "error": { + "content": "$1" + } + } + }, "optionsAdvancedExposeIframes": { "message": "Exponer marcos integrados (iframes) vía HTML[stylus-iframe]", "description": "" @@ -802,6 +1007,10 @@ "message": "Para desactivar las búsquedas automáticas de actualizaciones, establezca el intervalo a 0", "description": "" }, + "installButtonUpdate": { + "message": "Actualizar", + "description": "Label for update button" + }, "backupButtons": { "message": "Copia de seguridad", "description": "Heading for backup" @@ -814,6 +1023,14 @@ "message": "Editar", "description": "Label for the button to go to the edit style page" }, + "installButtonInstalled": { + "message": "Instalado", + "description": "Text displayed when the style is successfully installed" + }, + "author": { + "message": "Autor", + "description": "Label for the style author" + }, "cm_theme": { "message": "Temas", "description": "Label for the style editor's CSS theme." @@ -822,6 +1039,10 @@ "message": "Abrir editor en una nueva ventana", "description": "Label for the checkbox controlling 'edit' action behavior in the popup." }, + "appliesRemoveError": { + "message": "No se puede eliminar la última entrada 'se aplica a'", + "description": "Error displayed when the last 'applies' is going to be removed" + }, "backupMessage": { "message": "Seleccione un fichero o arrástrelo y suéltelo en esta página.", "description": "Message for backup" @@ -841,5 +1062,9 @@ "description": { "message": "Rediseñe la web con Stylus, un administrador de estilos de usuario. Stylus le permite instalar fácilmente temas y coberturas para muchos sitios populares.", "description": "Extension description" + }, + "confirmClose": { + "message": "Cerrar", + "description": "'Close' button in a confirm dialog" } } \ No newline at end of file diff --git a/_locales/et/messages.json b/_locales/et/messages.json index 60e10258..a95565c8 100644 --- a/_locales/et/messages.json +++ b/_locales/et/messages.json @@ -31,6 +31,14 @@ "message": "Ekspordi", "description": "Label for the button to export a style ('edit' page) or all styles ('manage' page)" }, + "installButton": { + "message": "Installi", + "description": "Label for install button" + }, + "styleMetaErrorCheckbox": { + "message": "Vigane @var märkeruut: väärtus peab olema 0 või 1", + "description": "Error displayed when the value of @var checkbox is invalid" + }, "linterJSONError": { "message": "Vigane JSON-formaat", "description": "Setting linter config with invalid JSON" @@ -52,7 +60,7 @@ "description": "Label for the button to enable a style" }, "styleMissingName": { - "message": "Sisesta nimi.", + "message": "Sisesta nimi", "description": "Error displayed when user saves without providing a name" }, "genericHistoryLabel": { @@ -83,6 +91,10 @@ "message": "Tumedad brauseriteemad", "description": "" }, + "styleFromMozillaFormatError": { + "message": "Mozilla-vormingust importimine ebaõnnestus", + "description": "Label for the import error" + }, "importAppendLabel": { "message": "Lisa stiilile", "description": "Label for the button to import a style and append to the existing sections" @@ -119,6 +131,10 @@ "message": "Tee halliks", "description": "Label for the checkbox that toggles grayed out mode of applies-to favicons in the new UI on manage page" }, + "versionInvalidOlder": { + "message": "Versioon on installitud stiilist vanem.", + "description": "Displayed when the version of style is older than the installed one" + }, "confirmYes": { "message": "Jah", "description": "'Yes' button in a confirm dialog" @@ -171,6 +187,10 @@ "message": "Kustuta", "description": "" }, + "confirmDefault": { + "message": "Kasuta vaikesätet", + "description": "'Set to default' button in a confirm dialog" + }, "confirmCancel": { "message": "Tühista", "description": "" @@ -241,6 +261,10 @@ } } }, + "parseUsercssError": { + "message": "Stylus ei suutnud usercss-i analüüsida:", + "description": "The error message to show when stylus failed to parse usercss" + }, "searchStyles": { "message": "Otsi sisu", "description": "Label for the search filter textbox on the Manage styles page" @@ -253,6 +277,10 @@ "message": "Kontrolli uuesti, ma ei muutnud ühtegi stiili!", "description": "Label for the button to apply all detected updates" }, + "liveReloadLabel": { + "message": "Reaalajas uuestilaadimine", + "description": "The label of live-reload feature" + }, "unreachableFileHint": { "message": "Stylus saab ligi pääseda file:// URLidele ainult siis, kui märgistad vastava kasti Stylus laiendusel chrome://extensions lehel", "description": "Note in the toolbar popup for file:// URLs" @@ -325,6 +353,10 @@ "message": "Regulaaravaldis on sobimatu.", "description": "Validation message for a bad regexp in a style" }, + "license": { + "message": "Litsents", + "description": "Label for the license" + }, "optionsHeading": { "message": "Valikud", "description": "Heading for options section on manage page." @@ -367,6 +399,10 @@ "message": "sobimatut vahele jäetud", "description": "Text after the number of styles skipped due to being invalid (not a Stylus/Stylish backup file probably) in the report shown after importing styles" }, + "optionsAdvancedNewStyleAsUsercss": { + "message": "Kirjuta uus stiil usercss-ina", + "description": "" + }, "genericResetLabel": { "message": "Lähtesta", "description": "Used in various parts of UI to indicate that something may be reset to its original state" @@ -396,6 +432,10 @@ "message": "Kasuta /re/ süntaksit regulaaravaldise otsinguks", "description": "Label after the search input field in the editor shown on Ctrl-F" }, + "popupBordersTooltip": { + "message": "Kasulik tumedate teemade puhul Chrome'is, kuna see ei joonista enam külje piirjooni", + "description": "" + }, "updateCheckManualUpdateHint": { "message": "Uuenduse sundimine kirjutab üle mistahes kohalikud muutused.", "description": "Additional text displayed when an update check skipped updating the style to avoid losing local modifications" @@ -408,6 +448,10 @@ "message": "Tühista praeguse stiili sisu ja kirjuta see üle imporditud stiiliga", "description": "Label for the button to import and overwrite current style" }, + "installUpdateFromLabel": { + "message": "Kontrolli uuendusi", + "description": "Label for the checkbox to save current URL for update check" + }, "cm_resizeGripHint": { "message": "Topeltklõpsa, et maksimeerida/taastada kõrgus", "description": "Tooltip for the resize grip in style editor" @@ -440,6 +484,10 @@ "message": "Stiil Mozilla-vormingus", "description": "Title of the popup with the style code in Mozilla format, shown after pressing the Export button on Edit style page" }, + "cm_colorpicker": { + "message": "CSS-värvide värvivalijad", + "description": "Label for the checkbox controlling colorpicker option for the style editor." + }, "writeStyleFor": { "message": "Kirjuta stiil:", "description": "Label for toolbar pop-up that precedes the links to write a new style" @@ -541,6 +589,10 @@ "message": "Lülita kõik stiilid välja", "description": "Label for the checkbox that turns all enabled styles off." }, + "appliesLineWidgetLabel": { + "message": "Näita 'Rakendub' teavet", + "description": "Label for the checkbox to display applies-to information in the single editor" + }, "updateCheckSkippedMaybeLocallyEdited": { "message": "Seda stiili võib olla kohalikult muudetud.", "description": "Text that displays when an update check skipped updating the style to avoid losing possible local modifications" @@ -581,6 +633,21 @@ "message": "Stylus kasutab välist teenust https://www.google.com/s2/favicons", "description": "Label for the checkbox that toggles applies-to favicons in the new UI on manage page" }, + "styleInstallOverwrite": { + "message": "'$stylename$' on juba installitud. Kas kirjutada üle?\nVersioon: $oldVersion$ -> $newVersion$", + "description": "Confirmation when re-installing a style", + "placeholders": { + "stylename": { + "content": "$1" + }, + "newVersion": { + "content": "$3" + }, + "oldVersion": { + "content": "$2" + } + } + }, "updateCheckSkippedLocallyEdited": { "message": "Seda stiili muudeti kohalikult.", "description": "Text that displays when an update check skipped updating the style to avoid losing local modifications" @@ -589,6 +656,10 @@ "message": "Vaata reeglite täielikku loendit", "description": "Stylelint or CSSLint rules label added immediately before a link" }, + "styleUpdateDiscardChanges": { + "message": "Stiili on redaktoriväliselt muudetud. Kas soovid stiili uuesti laadida?", + "description": "Confirmation to update the style in the editor" + }, "optionsResetButton": { "message": "Lähtesta valikud", "description": "" @@ -597,6 +668,10 @@ "message": "Kood", "description": "Label for the code for a section" }, + "externalUsercssDocument": { + "message": "Usercss dokumentatsioon", + "description": "Label for the external link to usercss documentation" + }, "optionsAdvancedContextDelete": { "message": "Lisa \"Kustuta\" redaktori kontekstmenüüsse", "description": "" @@ -610,6 +685,10 @@ } } }, + "configureStyle": { + "message": "Seadista", + "description": "Label for the button to configure userstyle" + }, "importReportLegendUpdatedBoth": { "message": "said uuenduse nii metaandmetele kui koodile", "description": "Text after the number of styles updated entirely in the report shown after importing styles" @@ -638,6 +717,23 @@ "message": "Automaattäide kirjutamisel", "description": "Label for the checkbox in the style editor." }, + "styleMetaErrorSelectValueMismatch": { + "message": "Vigane @select: väärtust pole loendis olemas", + "description": "Error displayed when the value of @select is invalid" + }, + "styleMetaErrorColor": { + "message": "$color$ ei ole sobiv värv", + "description": "Error displayed when the value of @var color is invalid", + "placeholders": { + "color": { + "content": "$1" + } + } + }, + "externalFeedback": { + "message": "Tagasiside", + "description": "Label for the external link to send feedback for the style" + }, "manageOnlyDisabled": { "message": "Ainult keelatud stiilid", "description": "Checkbox to show only disabled styles" @@ -658,6 +754,10 @@ "message": "Stylus ei tööta sellistel lehtedel.", "description": "Note in the toolbar pop-up when on a URL Stylus can't affect" }, + "popupBorders": { + "message": "Lisa äärtesse valged piirjooned", + "description": "" + }, "manageOnlyUpdates": { "message": "Ainult uuenduste ja vigadega", "description": "Checkbox to show only styles that have updates after check-all-styles-for-updates was performed" @@ -666,6 +766,14 @@ "message": "Lisa stiil", "description": "Title of the page for adding styles" }, + "externalLink": { + "message": "Väline link", + "description": "Label for external links" + }, + "externalHomepage": { + "message": "Koduleht", + "description": "Label for the external link to style's homepage" + }, "importReplaceLabel": { "message": "Kirjuta stiil üle", "description": "Label for the button to import and overwrite current style" @@ -682,6 +790,10 @@ "message": "Täpsem", "description": "" }, + "alphaChannel": { + "message": "Läbipaistmatus", + "description": "Label of color's opacity" + }, "importAppendTooltip": { "message": "Lisa imporditud stiil praegusele stiilile", "description": "Tooltip for the button to import a style and append to the existing sections" @@ -734,10 +846,23 @@ "message": "Valikute liides", "description": "Go to Options UI" }, + "colorpickerTooltip": { + "message": "Ava värvivalija", + "description": "Tooltip for the colored squares shown before CSS colors in the style editor." + }, "optionsCustomizeBadge": { "message": "Number tööriistaribaikoonil", "description": "" }, + "installUpdateFrom": { + "message": "Praegu uuendatakse stiili aadressilt $url$", + "description": "Label to describe where the style gets update", + "placeholders": { + "url": { + "content": "$1" + } + } + }, "importReportLegendIdentical": { "message": "identset vahele jäetud", "description": "Text after the number of styles skipped due to being identical to the already installed ones in the report shown after importing styles" @@ -746,6 +871,14 @@ "message": "Hüpikakna laius (pikslites)", "description": "" }, + "cm_autoCloseBrackets": { + "message": "Automaatselt sulge sulud ja jutumärgid", + "description": "Label for the checkbox in the style editor." + }, + "installButtonReinstall": { + "message": "Installi uuesti", + "description": "Label for reinstall button" + }, "linterInvalidConfigError": { "message": "Ei salvestatud nende vigaste seadistuste tõttu:", "description": "Invalid linter config will show a message followed by a list of invalid entries" @@ -754,6 +887,10 @@ "message": "Ei", "description": "'No' button in a confirm dialog" }, + "appliesLineWidgetWarning": { + "message": "Ei tööta minimeeritud CSS-iga", + "description": "A warning that applies-to information won't show properly with minified CSS" + }, "undo": { "message": "Võta tagasi", "description": "Button label" @@ -762,6 +899,14 @@ "message": "Klahvimäärangud", "description": "Label for the drop-down list controlling the keymap for the style editor." }, + "externalSupport": { + "message": "Kasutajatugi", + "description": "Label for the external link to style's support site" + }, + "confirmSave": { + "message": "Salvesta", + "description": "'Save' button in a confirm dialog" + }, "manageNewUI": { "message": "Uus haldusliidese välimus", "description": "Label for the checkbox that toggles the new UI on manage page" @@ -790,6 +935,15 @@ "message": "Installi uuendus (kohalikud muutused kirjutatakse üle)", "description": "Additional text displayed when an update check skipped updating the style to avoid losing local modifications" }, + "styleInstallFailed": { + "message": "Kasutajastiili installimine ebaõnnestus!\n$error$", + "description": "Warning when installation failed", + "placeholders": { + "error": { + "content": "$1" + } + } + }, "optionsAdvancedExposeIframes": { "message": "Paljasta iframe-id HTML [stylus-iframe] kaudu", "description": "" @@ -802,6 +956,10 @@ "message": "Et keelata automaatsed kasutajastiilide uuenduste kontrollid, sea intervalliks 0", "description": "" }, + "installButtonUpdate": { + "message": "Uuenda", + "description": "Label for update button" + }, "backupButtons": { "message": "Varunda", "description": "Heading for backup" @@ -814,6 +972,14 @@ "message": "Muuda", "description": "Label for the button to go to the edit style page" }, + "installButtonInstalled": { + "message": "Installitud", + "description": "Text displayed when the style is successfully installed" + }, + "author": { + "message": "Autor", + "description": "Label for the style author" + }, "cm_theme": { "message": "Teema", "description": "Label for the style editor's CSS theme." @@ -822,6 +988,10 @@ "message": "Ava redaktor uues aknas", "description": "Label for the checkbox controlling 'edit' action behavior in the popup." }, + "appliesRemoveError": { + "message": "Viimast 'rakendub'-sisestust ei saa eemaldada", + "description": "Error displayed when the last 'applies' is going to be removed" + }, "backupMessage": { "message": "Vali fail või lohista see siia lehele.", "description": "Message for backup" @@ -841,5 +1011,9 @@ "description": { "message": "Disaini veeb ümber kasutajastiilide halduri Stylus'iga. Stylus võimaldab sul lihtsalt installida teemasid ja välimusi mitmetele populaarsetele saitidele.", "description": "Extension description" + }, + "confirmClose": { + "message": "Sulge", + "description": "'Close' button in a confirm dialog" } } \ No newline at end of file diff --git a/_locales/fi/messages.json b/_locales/fi/messages.json index 3a751e01..2b09680c 100644 --- a/_locales/fi/messages.json +++ b/_locales/fi/messages.json @@ -8,7 +8,7 @@ "description": "Label for the button to enable a style" }, "styleMissingName": { - "message": "Syötä nimi.", + "message": "Syötä nimi", "description": "Error displayed when user saves without providing a name" }, "appliesDomainOption": { diff --git a/_locales/fr/messages.json b/_locales/fr/messages.json index 892244cf..a0d3ec2b 100644 --- a/_locales/fr/messages.json +++ b/_locales/fr/messages.json @@ -20,7 +20,7 @@ "description": "Label for the button to enable a style" }, "styleMissingName": { - "message": "Veuillez saisir un nom.", + "message": "Veuillez saisir un nom", "description": "Error displayed when user saves without providing a name" }, "appliesDomainOption": { diff --git a/_locales/hu/messages.json b/_locales/hu/messages.json index 9cba268a..bcc71601 100644 --- a/_locales/hu/messages.json +++ b/_locales/hu/messages.json @@ -7,6 +7,10 @@ "message": "alapértelmezett", "description": "Default CodeMirror CSS theme option on the edit style page" }, + "styleRegexpTestTitle": { + "message": "Illeszkedő megnyitott fülek megjelenítése (kattints az URL-re az arra a fülre való ugráshoz)", + "description": "RegExp test report: title of the report" + }, "bckpInstStyles": { "message": "Stílusok exportálása", "description": "" @@ -15,6 +19,10 @@ "message": "Az összes stílus elérhető frissítéseinek automatikus ellenőrzése és telepítése (órában)", "description": "" }, + "styleEnabledToggleHint": { + "message": "Nyomj Alt-Entert az állapot engedélyezéséhez/letiltásához és a stílus mentéséhez", + "description": "Help text for the '[x] enable' checkbox in the editor" + }, "exportLabel": { "message": "Exportálás", "description": "Label for the button to export a style ('edit' page) or all styles ('manage' page)" @@ -23,6 +31,10 @@ "message": "Háttérszín", "description": "" }, + "updateCheckHistory": { + "message": "Frissítések ellenőrzésének előzményei", + "description": "" + }, "cm_tabSize": { "message": "Tabulátorméret", "description": "Label for the text box controlling tab size option for the style editor." @@ -35,6 +47,14 @@ "message": "Írj be egy nevet!", "description": "Error displayed when user saves without providing a name" }, + "genericHistoryLabel": { + "message": "Előzmények", + "description": "Used in various places to show a history log of something" + }, + "shortcutsNote": { + "message": "Gyorsbillentyűk megadása", + "description": "" + }, "appliesDomainOption": { "message": "URL-ek a doménon", "description": "Option to make the style apply to the entered string as a domain" @@ -43,6 +63,18 @@ "message": "Frissítések ellenőrzése", "description": "Label for the button to check a single style for an update" }, + "styleNotAppliedRegexpProblemTooltip": { + "message": "A stílus nem lett alkalmazva a „regexp()” helytelen használata miatt", + "description": "Tooltip in the popup for styles that were not applied at all" + }, + "styleRegexpInvalidExplanation": { + "message": "Egyes „regexp()” szabályokat nem lehetett lefordítani.", + "description": "" + }, + "optionsIconDark": { + "message": "Sötét böngészőtémák", + "description": "" + }, "importAppendLabel": { "message": "Hozzáadás stílushoz", "description": "Label for the button to import a style and append to the existing sections" @@ -55,10 +87,18 @@ "message": "Nem találhatók frissítések.", "description": "Text that displays when an update all check completed and no updates are available" }, + "importReportLegendAdded": { + "message": "hozzáadva", + "description": "Text after the number of styles added in the report shown after importing styles" + }, "styleFromMozillaFormatPrompt": { "message": "Mozilla formátumú kód beillesztése", "description": "Prompt in the dialog displayed after clicking 'Import from Mozilla format' button" }, + "dragDropMessage": { + "message": "Ejtsd a biztonsági másolat fájlt bárhova erre az oldalra az importáláshoz!", + "description": "Drag'n'drop message" + }, "helpAlt": { "message": "Segítség", "description": "Alternate text for help buttons" @@ -67,6 +107,10 @@ "message": "Keresés", "description": "Label before the search input field in the editor shown on Ctrl-F" }, + "manageFaviconsGray": { + "message": "Szürke mód", + "description": "Label for the checkbox that toggles grayed out mode of applies-to favicons in the new UI on manage page" + }, "confirmYes": { "message": "Igen", "description": "'Yes' button in a confirm dialog" @@ -83,6 +127,10 @@ "message": "Csinosít", "description": "Label for the CSS-beautifier button on the edit style page" }, + "styleRegexpProblemTooltip": { + "message": "A nem alkalmazott szeckiók száma helytelen 'regexp()' használat miatt", + "description": "Tooltip in the popup for styles that were applied only partially" + }, "styleEnabledLabel": { "message": "Engedélyezve", "description": "Label for the enabled state of styles" @@ -95,10 +143,18 @@ "message": "Egy újabb szekció hozzáadása", "description": "Label for the button to add a section" }, + "styleRegexpTestPartial": { + "message": "Nincs teljes egyezés, így ki vagy hagyva", + "description": "RegExp test report: label for the partially matching expressions" + }, "styleSaveLabel": { "message": "Mentés", "description": "Label for save button for style editing" }, + "confirmDelete": { + "message": "Törlés", + "description": "" + }, "confirmCancel": { "message": "Mégsem", "description": "" @@ -127,6 +183,14 @@ "message": "Reguláris kifejezésekre (regexp) illeszkedő URL-ek", "description": "Option to make the style apply to the entered string as a regular expression" }, + "optionsAdvancedExposeIframesNote": { + "message": "Engedélyezi az olyan iframe-specifikus CSS írását, mint a „html[stylus-iframe] h1 { display:none }”", + "description": "" + }, + "importReportLegendUpdatedCode": { + "message": "frissített kód", + "description": "Text after the number of styles with updated code (meta info is unchanged) in the report shown after importing styles" + }, "styleInstall": { "message": "Telepíted a(z) „$stylename$” nevű stílust a Stylusba?", "description": "Confirmation when installing a style", @@ -148,10 +212,26 @@ "message": "Szerezz be stílusokat a userstyles.org-on | Kérj segítséget", "description": "Help text on the manage page" }, + "manageOnlyLocal": { + "message": "Csak helyileg létrehozott stílusok", + "description": "Checkbox to show only locally created styles i.e. non-updatable" + }, "searchStyles": { "message": "Tartalom keresése", "description": "Label for the search filter textbox on the Manage styles page" }, + "optionsUpdateImportNote": { + "message": "Amikor régebbi verzióból vagy a Stylishból importálsz stílusokat, egyszer manuálisan frissítsd a stílusokat a stíluskezelőben, hogy megbizonyosodj afelől, hogy mindegyik frissítve van!", + "description": "" + }, + "checkAllUpdatesForce": { + "message": "Ellenőrizd újra, nem módosítottam egy stílust sem!", + "description": "Label for the button to apply all detected updates" + }, + "unreachableFileHint": { + "message": "A Stylus csak akkor képes hozzáférni a file:// URL-ekhez, ha engedélyezed az erre vonatkozó beállítást a Stylus kiegészítőre a chrome://extensions oldalon.", + "description": "Note in the toolbar popup for file:// URLs" + }, "disableStyleLabel": { "message": "Letiltás", "description": "Label for the button to disable a style" @@ -160,6 +240,10 @@ "message": "A jelenlegi oldalon aktív stílusok száma", "description": "Label for the checkbox controlling toolbar badge text." }, + "manageFavicons": { + "message": "Faviconok az alkalmazási oszlopban", + "description": "Label for the checkbox that toggles applies-to favicons in the new UI on manage page" + }, "menuShowBadge": { "message": "Aktív stílusok számlálójának mutatása", "description": "Label (must be very short) for the checkbox in the toolbar button context menu controlling toolbar badge text." @@ -180,6 +264,10 @@ "message": "Importálás", "description": "Label for the button to import a style ('edit' page) or all styles ('manage' page)" }, + "shortcuts": { + "message": "Gyorsbillentyűk", + "description": "Go to shortcut configuration" + }, "updateCheckFailServerUnreachable": { "message": "Sikertelen frissítés: nem érhető el a szerver.", "description": "Text that displays when an update check failed because the update server is unreachable" @@ -192,10 +280,22 @@ "message": "Minden módosítás alkalmazása", "description": "Label for the button to apply all detected updates" }, + "optionsReset": { + "message": "Beállítások visszaállítása alapértelmezett értékekre.", + "description": "" + }, + "optionsCustomizeUpdate": { + "message": "Frissítések", + "description": "" + }, "deleteStyleConfirm": { "message": "Biztos, hogy törölni akarod ezt a stílust?", "description": "Confirmation before deleting a style" }, + "optionsCustomizePopup": { + "message": "Felugró", + "description": "" + }, "styleBadRegexp": { "message": "Érvénytelen regexp.", "description": "Validation message for a bad regexp in a style" @@ -213,6 +313,10 @@ } } }, + "optionsIconLight": { + "message": "Világos böngészőtémák", + "description": "" + }, "openStylesManager": { "message": "A frissítéskezelő megnyitása", "description": "Label for the style maanger opener in the browser action context menu." @@ -230,6 +334,10 @@ "message": "Szekciók", "description": "Title for the style sections section" }, + "importReportLegendInvalid": { + "message": "kihagyott érvénytelen", + "description": "Text after the number of styles skipped due to being invalid (not a Stylus/Stylish backup file probably) in the report shown after importing styles" + }, "editStyleTitle": { "message": "A(z) $stylename$ stílus szerkesztése", "description": "Title of the page for editing styles", @@ -247,14 +355,30 @@ "message": "URL-ek adott kezdettel", "description": "Option to make the style apply to the entered string as a URL prefix" }, + "cm_matchHighlightToken": { + "message": "Kurzor alatti kifejezés", + "description": "Style editor's 'highglight' drop-down list option: highlight the occurrences of of the word/token under cursor even if nothing is selected" + }, "searchRegexp": { "message": "Használd a /re/ szintaxist a regexp kereséshez", "description": "Label after the search input field in the editor shown on Ctrl-F" }, + "updateCheckManualUpdateHint": { + "message": "Egy frissítés erőltetése minden helyi szerkesztést felül fog írni.", + "description": "Additional text displayed when an update check skipped updating the style to avoid losing local modifications" + }, + "toggleStyle": { + "message": "Stílus be-/kikapcsolása", + "description": "Label for the checkbox to enable/disable a style" + }, "importReplaceTooltip": { "message": "A jelenlegi stílus tartalmának elvetése és annak felülírása az importált stílussal", "description": "Label for the button to import and overwrite current style" }, + "cm_resizeGripHint": { + "message": "Kattints duplán a magasság maximalizálásához/visszaállításához", + "description": "Tooltip for the resize grip in style editor" + }, "popupStylesFirst": { "message": "Parancsok előtti stílusok", "description": "Label for the checkbox controlling section order in the popup." @@ -275,6 +399,10 @@ "message": "Eltávolítás", "description": "Label for the button to remove an 'applies' entry" }, + "updatesCurrentlyInstalled": { + "message": "Frissítve:", + "description": "Text that displays when an update is installed on options page. Followed by the number of currently installed updates." + }, "styleToMozillaFormatTitle": { "message": "Mozilla formátumú stílus", "description": "Title of the popup with the style code in Mozilla format, shown after pressing the Export button on Edit style page" @@ -287,6 +415,14 @@ "message": "Csere", "description": "Label before the replace input field in the editor shown on Ctrl-H" }, + "styleRegexpTestNone": { + "message": "Nincs illeszkedő fül", + "description": "RegExp test report: label for expressions that didn't match any tabs" + }, + "importReportLegendUpdatedMeta": { + "message": "metainfó frissítve", + "description": "Text after the number of styles with updated meta info like name/url in the report shown after importing styles" + }, "appliesLabel": { "message": "Amire érvényesül", "description": "Label for 'applies to' fields on the edit/add screen" @@ -320,22 +456,66 @@ "message": "Az összes frissítés ellenőrzése és telepítése", "description": "" }, + "filteredStyles": { + "message": "$numShown$ mutatva $numTotal$-ból/-ből", + "description": "TL note - make this message short", + "placeholders": { + "numTotal": { + "content": "$2" + }, + "numShown": { + "content": "$1" + } + } + }, + "importReportTitle": { + "message": "A stílusok importálása befejeződött", + "description": "Title of the report shown after importing styles" + }, "styleMozillaFormatHeading": { "message": "Mozilla formátum", "description": "Heading for the section with buttons to import/export Mozilla format of the style" }, + "cm_matchHighlight": { + "message": "Kijelöl", + "description": "Label for the drop-down list controlling the automatic highlighting of current word/selection occurrences in the style editor." + }, + "styleRegexpPartialExplanation": { + "message": "Ez a stílus olyan részlegesen illeszkedő reguláris kifejezéseket használ, melyek sértik aCSS4@dokumentumspecifikációt, mely szerint egy teljes URL-illeszkedésre van szükség. Az érintett CSS-szekciók nem kerültek alkalmazásra az oldalon. Ez a stílus valószínűleg a Stylish Chrome-kiegészítőben lett létrehozva, amely helytelenül ellenőrzi a „regexp()” szabályokat az első verziótól fogva (ismert hiba).", + "description": "" + }, + "styleBeautifyIndentConditional": { + "message": "@media, @supports behúzása", + "description": "CSS-beautifier option" + }, + "unreachableContentScript": { + "message": "Nem sikerült az oldallal történő kommunikáció. Próbáld meg újratölteni az oldalt!", + "description": "Note in the toolbar popup usually on file:// URLs after [re]loading Stylus" + }, "sectionRemove": { "message": "Szekció eltávolítása", "description": "Label for the button to remove a section" }, + "searchStylesTooltip": { + "message": "A URL alapján történő szűréshez írd előre, hogy „url:”\nPéldául: url:https://github.com/openstyles/stylus", + "description": "Label for the search filter textbox on the Manage styles page" + }, "disableAllStyles": { "message": "Az összes stílus kikapcsolása", "description": "Label for the checkbox that turns all enabled styles off." }, + "updateCheckSkippedMaybeLocallyEdited": { + "message": "Lehet, hogy ezt a stílust helyileg szerkesztették", + "description": "Text that displays when an update check skipped updating the style to avoid losing possible local modifications" + }, "undoGlobal": { "message": "VIsszavonás mindegyik szekcióban", "description": "CSS-beautify global Undo button label" }, + "optionsCustomizeIcon": { + "message": "Eszköztárikon", + "description": "" + }, "updateCompleted": { "message": "A frissítés befejeződött.", "description": "Text that displays when an update completed" @@ -344,14 +524,46 @@ "message": "Ellenőrzés...", "description": "Text to display when checking a style for an update" }, + "styleRegexpTestFull": { + "message": "Illeszkedő fülek", + "description": "RegExp test report: label for the fully matching expressions" + }, + "manageMaxTargets": { + "message": "Megjelenítendő célok száma", + "description": "Label for the numeric input box to limit max number of applies-to targets in the new UI on manage page" + }, + "manageFaviconsHelp": { + "message": "A Stylus egy külső szolgáltatást használ (https://www.google.com/s2/favicons)", + "description": "Label for the checkbox that toggles applies-to favicons in the new UI on manage page" + }, + "updateCheckSkippedLocallyEdited": { + "message": "Ez a stílus helyileg lett szerkesztve.", + "description": "Text that displays when an update check skipped updating the style to avoid losing local modifications" + }, + "optionsResetButton": { + "message": "Beállítások visszaállítása alapra", + "description": "" + }, "sectionCode": { "message": "Kód", "description": "Label for the code for a section" }, + "optionsAdvancedContextDelete": { + "message": "Delete hozzáadása a gyorsmenühöz", + "description": "" + }, + "importReportLegendUpdatedBoth": { + "message": "metainformáció és kód frissítve", + "description": "Text after the number of styles updated entirely in the report shown after importing styles" + }, "cm_smartIndent": { "message": "Intelligens behúzás használata", "description": "Label for the checkbox controlling smart indentation option for the style editor." }, + "styleRegexpTestButton": { + "message": "RegExp teszt", + "description": "RegExp test button label in the editor shown when applies-to list has a regexp value" + }, "appliesHelp": { "message": "Használd az \"A következőre érvényesül\" részt, hogy korlátozd, milyen URL-ekre vonatkozzon az itt lévő kód!", "description": "Help text for 'applies to' section" @@ -360,6 +572,38 @@ "message": "Stílus szerkesztése", "description": "Title of the page for editing styles" }, + "editDeleteText": { + "message": "Törlés", + "description": "Label for the context menu item in the editor to delete selected text" + }, + "cm_autocompleteOnTyping": { + "message": "Automatikus kiegészítés gépeléskor", + "description": "Label for the checkbox in the style editor." + }, + "manageOnlyDisabled": { + "message": "Csak letiltott stílusok", + "description": "Checkbox to show only disabled styles" + }, + "stylusUnavailableForURLdetails": { + "message": "Biztonsági okokból a böngésző megtiltja, hogy a kiegészítők változtatásokat tegyenek a beépített oldalain (pl. chrome://verzió, a Chrome 61 alapértelmezett „új lap” oldala, about:addons és így tovább) valamint más kiterjesztések oldalain. Ezen kívül mindegyik böngésző korlátozza a saját kiegészítőgalériájának elérését (pl. Chrome webáruház vagy a Mozilla kiegészítők oldala)", + "description": "Sub-note in the toolbar pop-up when on a URL Stylus can't affect" + }, + "cm_matchHighlightSelection": { + "message": "Csak kiválasztás", + "description": "Style editor's 'highglight' drop-down list option: highlight the occurrences of currently selected text" + }, + "updateAllCheckSucceededSomeEdited": { + "message": "Egyes frissíthető stílusok nem lettek ellenőrizve, nehogy elvesszenek a helyi változtatások. A frissítéseket lehet erőltetni egyéni ellenőrzéssel külön-külön vagy az összes stílus ismételt ellenőrzésével (ez felülírja a helyi módosításokat).", + "description": "Text that displays when an update all check completed and no updates are available" + }, + "stylusUnavailableForURL": { + "message": "A Stylus nem működik az ilyen oldalakon.", + "description": "Note in the toolbar pop-up when on a URL Stylus can't affect" + }, + "manageOnlyUpdates": { + "message": "Csak frissíthetőek vagy problémásak", + "description": "Checkbox to show only styles that have updates after check-all-styles-for-updates was performed" + }, "addStyleTitle": { "message": "Stílus hozzáadása", "description": "Title of the page for adding styles" @@ -372,6 +616,10 @@ "message": "Hiba történt a Stylus adatbázisának használatakor. Szeretnéd meglátogatni a lehetséges megoldásokat tartalmazó weboldalt?", "description": "Prompt when a DB error is encountered" }, + "optionsAdvanced": { + "message": "Haladó", + "description": "" + }, "importAppendTooltip": { "message": "Az importált stílus hozzáadása a jelenlegi stílushoz", "description": "Tooltip for the button to import a style and append to the existing sections" @@ -388,10 +636,22 @@ "message": "Gyorsgomb", "description": "Placeholder text of inputbox in keymap help popup on the edit style page. Must be very short" }, + "styleRegexpTestInvalid": { + "message": "Kihagyott érvénytelen reguláris kifejezések", + "description": "RegExp test report: label for the invalid expressions" + }, + "manageOnlyExternal": { + "message": "Csak külső stílusok", + "description": "Checkbox to show only externally installed styles i.e. updatable" + }, "replaceAll": { "message": "Az összes cseréje", "description": "Label before the replace input field in the editor shown on 'replaceAll' hotkey" }, + "importReportUnchanged": { + "message": "Semmi sem változott.", + "description": "Message in the report shown after importing styles" + }, "optionsActions": { "message": "Műveletek", "description": "" @@ -400,6 +660,10 @@ "message": "Sorra (vagy sor:oszlopra) ugrás", "description": "Go to line or line:column on Ctrl-G in style code editor" }, + "manageOnlyLocalTooltip": { + "message": "(a stílusok nem egy userstyles.org oldalon lettek telepítve)", + "description": "Tooltip for the checkbox to show only locally created styles i.e. non-updatable" + }, "checkAllUpdates": { "message": "Az összes stílus frissítésének ellenőrzése", "description": "Label for the button to check all styles for updates" @@ -408,6 +672,14 @@ "message": "A beállítások felülete", "description": "Go to Options UI" }, + "optionsCustomizeBadge": { + "message": "Jelvény az eszköztárikonon", + "description": "" + }, + "importReportLegendIdentical": { + "message": "kihagyott egyezések", + "description": "Text after the number of styles skipped due to being identical to the already installed ones in the report shown after importing styles" + }, "optionsPopupWidth": { "message": "Felugró ablak szélessége (pixelben)", "description": "" @@ -424,6 +696,18 @@ "message": "Billentyűműveletek", "description": "Label for the drop-down list controlling the keymap for the style editor." }, + "manageNewUI": { + "message": "Az új kezelési felületkiosztás", + "description": "Label for the checkbox that toggles the new UI on manage page" + }, + "importReportUndoneTitle": { + "message": "Az importálás vissza lett vonva", + "description": "Title of the message box shown after undoing the import of styles" + }, + "genericDisabledLabel": { + "message": "Letiltott", + "description": "Used in various lists/options to indicate that something is disabled" + }, "cm_indentWithTabs": { "message": "Tabulátorok használata intelligens behúzásra", "description": "Label for the checkbox controlling tabs with smart indentation option for the style editor." @@ -436,6 +720,14 @@ "message": "Törlés", "description": "Label for the button to delete a style" }, + "updateCheckManualUpdateForce": { + "message": "Frissítés telepítése (a helyi módosítások felül lesznek írva)", + "description": "Additional text displayed when an update check skipped updating the style to avoid losing local modifications" + }, + "optionsAdvancedExposeIframes": { + "message": "iframe-ek kitevése HTML[stylus-iframe]-en keresztül", + "description": "" + }, "addStyleLabel": { "message": "Új stílus írása", "description": "Label for the button to go to the add style page" @@ -464,6 +756,10 @@ "message": "Válassz ki egy fájlt vagy húzd erre az oldalra!", "description": "Message for backup" }, + "importReportUndone": { + "message": "stílusok visszavonva", + "description": "Text after the number of styles reverted in the message box shown after undoing the import of styles" + }, "helpKeyMapCommand": { "message": "Írj be egy parancsot", "description": "Placeholder text of inputbox in keymap help popup on the edit style page. Must be very short" diff --git a/_locales/it/messages.json b/_locales/it/messages.json index 50b41173..8789feb3 100644 --- a/_locales/it/messages.json +++ b/_locales/it/messages.json @@ -3,6 +3,10 @@ "message": "Tutto", "description": "Text displayed for styles that apply to all sites" }, + "linterIssues": { + "message": "Problemi", + "description": "Label for the CSS linter issues block on the style edit page" + }, "defaultTheme": { "message": "predefinito", "description": "Default CodeMirror CSS theme option on the edit style page" @@ -19,6 +23,10 @@ "message": "Esporta", "description": "Label for the button to export a style ('edit' page) or all styles ('manage' page)" }, + "installButton": { + "message": "Installa", + "description": "Label for install button" + }, "linterJSONError": { "message": "Formato JSON non valido", "description": "Setting linter config with invalid JSON" @@ -36,13 +44,17 @@ "description": "Label for the button to enable a style" }, "styleMissingName": { - "message": "Inserisci un nome.", + "message": "Inserisci un nome", "description": "Error displayed when user saves without providing a name" }, "genericHistoryLabel": { "message": "Cronologia", "description": "Used in various places to show a history log of something" }, + "shortcutsNote": { + "message": "Definisci scorciatoie da tastiera", + "description": "" + }, "appliesDomainOption": { "message": "URL nel dominio", "description": "Option to make the style apply to the entered string as a domain" @@ -55,6 +67,10 @@ "message": "Temi browser scuri", "description": "" }, + "styleFromMozillaFormatError": { + "message": "Importazione da formato Mozilla fallita", + "description": "Label for the import error" + }, "optionsOpenManager": { "message": "Organizza stili", "description": "" @@ -79,6 +95,10 @@ "message": "Cerca", "description": "Label before the search input field in the editor shown on Ctrl-F" }, + "versionInvalidOlder": { + "message": "La versione dello stile è più vecchia di quella installata.", + "description": "Displayed when the version of style is older than the installed one" + }, "confirmYes": { "message": "Si", "description": "'Yes' button in a confirm dialog" @@ -115,6 +135,10 @@ "message": "Elimina", "description": "" }, + "confirmDefault": { + "message": "Utilizza predefinito", + "description": "'Set to default' button in a confirm dialog" + }, "confirmCancel": { "message": "Annulla", "description": "" @@ -160,6 +184,10 @@ "message": "Aggiorna stili", "description": "" }, + "manageText": { + "message": "Ottieni stili da userstyles.org | Otteini aiuto", + "description": "Help text on the manage page" + }, "manageOnlyLocal": { "message": "Solo stili creati localmente", "description": "Checkbox to show only locally created styles i.e. non-updatable" @@ -176,6 +204,10 @@ "message": "Disattiva", "description": "Label for the button to disable a style" }, + "prefShowBadge": { + "message": "Stili attivi per il sito attuale", + "description": "Label for the checkbox controlling toolbar badge text." + }, "styleCancelEditLabel": { "message": "Torna a gestione", "description": "Label for cancel button for style editing" @@ -188,6 +220,10 @@ "message": "Importa", "description": "Label for the button to import a style ('edit' page) or all styles ('manage' page)" }, + "shortcuts": { + "message": "Scorciatoie", + "description": "Go to shortcut configuration" + }, "updateCheckFailServerUnreachable": { "message": "Aggiornamento non riuscito: server non raggiungibile.", "description": "Text that displays when an update check failed because the update server is unreachable" @@ -216,6 +252,10 @@ "message": "Regexp non valida.", "description": "Validation message for a bad regexp in a style" }, + "license": { + "message": "Licenza", + "description": "Label for the license" + }, "optionsHeading": { "message": "Opzioni", "description": "Heading for options section on manage page." @@ -237,6 +277,15 @@ "message": "Apri gestore stili", "description": "Label for the style maanger opener in the browser action context menu." }, + "styleUpdate": { + "message": "Sei sicuro di voler aggiornare '$stylename$'?", + "description": "Confirmation when updating a style", + "placeholders": { + "stylename": { + "content": "$1" + } + } + }, "dysfunctional": { "message": "Stylus non può funzionare in finestre anonime perché Firefox disattiva la connessione diretta al contesto della pagina di background interna dell'estensione.", "description": "Displayed in Firefox when its settings make Stylus dysfunctional" @@ -266,6 +315,18 @@ "message": "URL che iniziano con", "description": "Option to make the style apply to the entered string as a URL prefix" }, + "popupBordersTooltip": { + "message": "Utile per temi scuri nelle nuove versioni di Chrome dato che non colora più i bordi laterali", + "description": "" + }, + "updateCheckManualUpdateHint": { + "message": "Forzare un aggiornamento sovrascriverà tutte le modifiche locali", + "description": "Additional text displayed when an update check skipped updating the style to avoid losing local modifications" + }, + "installUpdateFromLabel": { + "message": "Controlla aggiornamenti", + "description": "Label for the checkbox to save current URL for update check" + }, "sectionHelp": { "message": "Le sezioni consentono di definire diverse parti di codice da applicare a diversi insiemi di URL dello stesso stile. Ad esempio, un unico stile potrebbe modificare la home page di un sito diversamente da come modificherebbe il resto del sito.", "description": "Help text for sections" @@ -290,6 +351,10 @@ "message": "Stile in formato Mozilla", "description": "Title of the popup with the style code in Mozilla format, shown after pressing the Export button on Edit style page" }, + "cm_colorpicker": { + "message": "Selezionatore colore per colori CSS", + "description": "Label for the checkbox controlling colorpicker option for the style editor." + }, "writeStyleFor": { "message": "Scrivi stile per:", "description": "Label for toolbar pop-up that precedes the links to write a new style" @@ -327,6 +392,10 @@ "message": "Installa aggiornamento", "description": "Label for the button to install an update for a single style" }, + "optionsCheckUpdate": { + "message": "Controlla e installa gli aggiornamenti disponibili", + "description": "" + }, "filteredStyles": { "message": "$numShown$ mostrati di $numTotal$ totali", "description": "TL note - make this message short", @@ -339,6 +408,10 @@ } } }, + "importReportTitle": { + "message": "Importazione stili terminata", + "description": "Title of the report shown after importing styles" + }, "styleMozillaFormatHeading": { "message": "Formato Mozilla", "description": "Heading for the section with buttons to import/export Mozilla format of the style" @@ -355,6 +428,10 @@ "message": "Disattiva tutti gli stili", "description": "Label for the checkbox that turns all enabled styles off." }, + "undoGlobal": { + "message": "Annulla in tutte le sezioni", + "description": "CSS-beautify global Undo button label" + }, "updateCompleted": { "message": "Aggiornamento completato.", "description": "Text that displays when an update completed" @@ -375,6 +452,21 @@ "message": "Stylus utilizza un servizio esterno https://www.google.com/s2/favicons", "description": "Label for the checkbox that toggles applies-to favicons in the new UI on manage page" }, + "styleInstallOverwrite": { + "message": "'$stylename$' è già installato. Vuoi sovrascriverlo?\nVersione: $oldVersion$ -> $newVersion$", + "description": "Confirmation when re-installing a style", + "placeholders": { + "stylename": { + "content": "$1" + }, + "newVersion": { + "content": "$3" + }, + "oldVersion": { + "content": "$2" + } + } + }, "updateCheckSkippedLocallyEdited": { "message": "Questo stile è stato editato localmente.", "description": "Text that displays when an update check skipped updating the style to avoid losing local modifications" @@ -391,6 +483,18 @@ "message": "Codice", "description": "Label for the code for a section" }, + "optionsAdvancedContextDelete": { + "message": "Aggiungi 'Elimina' al menu contestuale dell'editor", + "description": "" + }, + "configureStyle": { + "message": "Configura", + "description": "Label for the button to configure userstyle" + }, + "cm_smartIndent": { + "message": "Usa indentazione intelligente", + "description": "Label for the checkbox controlling smart indentation option for the style editor." + }, "styleRegexpTestButton": { "message": "Test RegExp", "description": "RegExp test button label in the editor shown when applies-to list has a regexp value" @@ -407,18 +511,47 @@ "message": "Elimina", "description": "Label for the context menu item in the editor to delete selected text" }, + "cm_autocompleteOnTyping": { + "message": "Completamento automatico durante digitazione", + "description": "Label for the checkbox in the style editor." + }, + "styleMetaErrorColor": { + "message": "$color$ non è un colore valido", + "description": "Error displayed when the value of @var color is invalid", + "placeholders": { + "color": { + "content": "$1" + } + } + }, "manageOnlyDisabled": { "message": "Solo stili disattivati", "description": "Checkbox to show only disabled styles" }, + "cm_matchHighlightSelection": { + "message": "Solo selezione", + "description": "Style editor's 'highglight' drop-down list option: highlight the occurrences of currently selected text" + }, "stylusUnavailableForURL": { "message": "Stylus non funziona in pagine come questa.", "description": "Note in the toolbar pop-up when on a URL Stylus can't affect" }, + "popupBorders": { + "message": "Aggiungi bordi bianchi sui lati", + "description": "" + }, + "manageOnlyUpdates": { + "message": "Solo con aggiornamenti o problemi", + "description": "Checkbox to show only styles that have updates after check-all-styles-for-updates was performed" + }, "addStyleTitle": { "message": "Aggiunta di stili", "description": "Title of the page for adding styles" }, + "externalLink": { + "message": "Link esterno", + "description": "Label for external links" + }, "importReplaceLabel": { "message": "Sovrascrivi stile", "description": "Label for the button to import and overwrite current style" @@ -427,6 +560,14 @@ "message": "Avanzato", "description": "" }, + "alphaChannel": { + "message": "Opacità", + "description": "Label of color's opacity" + }, + "editorStylesButton": { + "message": "Cerca stili editor", + "description": "Find styles for the editor" + }, "optionsOpen": { "message": "Apri", "description": "" @@ -455,10 +596,39 @@ "message": "Opzioni UI", "description": "Go to Options UI" }, + "installUpdateFrom": { + "message": "Attualmente lo stile è aggiornato da $url$", + "description": "Label to describe where the style gets update", + "placeholders": { + "url": { + "content": "$1" + } + } + }, "optionsPopupWidth": { "message": "Larghezza popup (in pixel)", "description": "" }, + "installButtonReinstall": { + "message": "Reinstalla", + "description": "Label for reinstall button" + }, + "appliesLineWidgetWarning": { + "message": "Non funziona con CSS minificato", + "description": "A warning that applies-to information won't show properly with minified CSS" + }, + "undo": { + "message": "Annulla", + "description": "Button label" + }, + "externalSupport": { + "message": "Supporto", + "description": "Label for the external link to style's support site" + }, + "confirmSave": { + "message": "Salva", + "description": "'Save' button in a confirm dialog" + }, "genericDisabledLabel": { "message": "Disattivato", "description": "Used in various lists/options to indicate that something is disabled" @@ -471,6 +641,19 @@ "message": "Elimina", "description": "Label for the button to delete a style" }, + "updateCheckManualUpdateForce": { + "message": "Installa aggiornamento (le modifiche locali verranno sovrascritte)", + "description": "Additional text displayed when an update check skipped updating the style to avoid losing local modifications" + }, + "styleInstallFailed": { + "message": "Installazione stile fallita!\n$error$", + "description": "Warning when installation failed", + "placeholders": { + "error": { + "content": "$1" + } + } + }, "addStyleLabel": { "message": "Scrivi nuovo stile", "description": "Label for the button to go to the add style page" @@ -479,6 +662,10 @@ "message": "Per disattivare il controllo automatico degli aggiornamenti degli stili, imposta l'intervallo a 0", "description": "" }, + "installButtonUpdate": { + "message": "Aggiorna", + "description": "Label for update button" + }, "manageOnlyEnabled": { "message": "Solo stili attivati", "description": "Checkbox to show only enabled styles" @@ -487,6 +674,14 @@ "message": "Modifica", "description": "Label for the button to go to the edit style page" }, + "installButtonInstalled": { + "message": "Installato", + "description": "Text displayed when the style is successfully installed" + }, + "author": { + "message": "Autore", + "description": "Label for the style author" + }, "cm_theme": { "message": "Tema", "description": "Label for the style editor's CSS theme." @@ -499,6 +694,10 @@ "message": "Seleziona un file o trascinalo in questa pagina.", "description": "Message for backup" }, + "importReportUndone": { + "message": "gli stili sono stati ripristinati", + "description": "Text after the number of styles reverted in the message box shown after undoing the import of styles" + }, "helpKeyMapCommand": { "message": "Inserisci il nome di un comando", "description": "Placeholder text of inputbox in keymap help popup on the edit style page. Must be very short" @@ -506,5 +705,9 @@ "description": { "message": "Modifica lo stile del Web con Stylus, un gestore di stili utente. Stylus consente di installare facilmente temi e skin per Google, Facebook, YouTube, Orkut e moltissimi altri siti.", "description": "Extension description" + }, + "confirmClose": { + "message": "Chiudi", + "description": "'Close' button in a confirm dialog" } } \ No newline at end of file diff --git a/_locales/ja/messages.json b/_locales/ja/messages.json index 405f9835..a4aa01a4 100644 --- a/_locales/ja/messages.json +++ b/_locales/ja/messages.json @@ -24,13 +24,21 @@ "description": "" }, "styleEnabledToggleHint": { - "message": "Alt-Enterを押して、有効/無効の状態を切り替え、スタイルを保存します", + "message": "Alt-Enterを押すと、有効/無効の状態を切り替え、スタイルを保存します", "description": "Help text for the '[x] enable' checkbox in the editor" }, "exportLabel": { "message": "エクスポート", "description": "Label for the button to export a style ('edit' page) or all styles ('manage' page)" }, + "installButton": { + "message": "インストール", + "description": "Label for install button" + }, + "styleMetaErrorCheckbox": { + "message": "不正な @var チェックボックス: 値は0か1である必要があります", + "description": "Error displayed when the value of @var checkbox is invalid" + }, "linterJSONError": { "message": "不正なJSONフォーマットです", "description": "Setting linter config with invalid JSON" @@ -52,7 +60,7 @@ "description": "Label for the button to enable a style" }, "styleMissingName": { - "message": "名前を入力してください。", + "message": "名前を入力してください", "description": "Error displayed when user saves without providing a name" }, "genericHistoryLabel": { @@ -83,6 +91,10 @@ "message": "暗いブラウザのテーマ", "description": "" }, + "styleFromMozillaFormatError": { + "message": "Mozilla形式のインポートに失敗しました", + "description": "Label for the import error" + }, "importAppendLabel": { "message": "スタイルに追加", "description": "Label for the button to import a style and append to the existing sections" @@ -119,6 +131,10 @@ "message": "グレー表示", "description": "Label for the checkbox that toggles grayed out mode of applies-to favicons in the new UI on manage page" }, + "versionInvalidOlder": { + "message": "インストール済みのスタイルより古いバージョンです。", + "description": "Displayed when the version of style is older than the installed one" + }, "confirmYes": { "message": "はい", "description": "'Yes' button in a confirm dialog" @@ -148,7 +164,7 @@ "description": "Icon tooltip to indicate that it opens a popup with the selected linter configuration" }, "styleToMozillaFormatHelp": { - "message": "Mozilla 形式のコードは、userstyles.org に投稿することができ、また従来の Stylish for Firefox でも使用できます。", + "message": "Mozilla 形式のコードは、userstyles.org に投稿することができ、また従来の Stylish for Firefox でも使用できます", "description": "Help info for the Mozilla format header section that converts the code to/from Mozilla format" }, "sectionAdd": { @@ -171,10 +187,18 @@ "message": "削除", "description": "" }, + "confirmDefault": { + "message": "デフォルトを使用", + "description": "'Set to default' button in a confirm dialog" + }, "confirmCancel": { "message": "キャンセル", "description": "" }, + "cm_autoCloseBracketsTooltip": { + "message": "()[]{}''\"\" の開き括弧/引用符の入力時に、対応する閉じ括弧/引用符を自動的に追加します", + "description": "Label for the checkbox in the style editor." + }, "retrieveBckp": { "message": "スタイルをインポート", "description": "" @@ -200,7 +224,7 @@ "description": "Option to make the style apply to the entered string as a regular expression" }, "optionsAdvancedExposeIframesNote": { - "message": "'html[stylus-iframe] h1 { display:none }' のようにiframe用のCSSを書くことができるようになります。", + "message": "「 html[stylus-iframe] h1 { display:none } 」のようにiframe用のCSSを書くことができるようになります。", "description": "" }, "importReportLegendUpdatedCode": { @@ -232,6 +256,15 @@ "message": "ローカル作成スタイルのみ", "description": "Checkbox to show only locally created styles i.e. non-updatable" }, + "styleMetaErrorPreprocessor": { + "message": "未サポートの @preprocessor: $preprocessor$", + "description": "Error displayed when the value of @preprocessor is not supported", + "placeholders": { + "preprocessor": { + "content": "$1" + } + } + }, "linterIssuesHelp": { "message": "$link$ によってこれらの問題点が見つかりました :", "description": "Help popup message for the selected CSS linter issues block on the style edit page", @@ -241,6 +274,10 @@ } } }, + "parseUsercssError": { + "message": "Stylusはusercssの解析に失敗しました: ", + "description": "The error message to show when stylus failed to parse usercss" + }, "searchStyles": { "message": "コンテンツの検索", "description": "Label for the search filter textbox on the Manage styles page" @@ -253,6 +290,10 @@ "message": "全スタイルを再チェックします。私はスタイルを編集していません!", "description": "Label for the button to apply all detected updates" }, + "liveReloadLabel": { + "message": "自動リロード", + "description": "The label of live-reload feature" + }, "unreachableFileHint": { "message": "chrome://extensions ページでStylus拡張機能の当該チェックボックスを有効にした場合にのみ、Stylusは file:// URLにアクセスできます。", "description": "Note in the toolbar popup for file:// URLs" @@ -325,6 +366,10 @@ "message": "正規表現は無効です。", "description": "Validation message for a bad regexp in a style" }, + "license": { + "message": "ライセンス", + "description": "Label for the license" + }, "optionsHeading": { "message": "オプション", "description": "Heading for options section on manage page." @@ -367,6 +412,10 @@ "message": "件の無効なスタイルをスキップしました", "description": "Text after the number of styles skipped due to being invalid (not a Stylus/Stylish backup file probably) in the report shown after importing styles" }, + "optionsAdvancedNewStyleAsUsercss": { + "message": "新しいスタイルを usercss として作成します", + "description": "" + }, "genericResetLabel": { "message": "リセット", "description": "Used in various parts of UI to indicate that something may be reset to its original state" @@ -381,7 +430,7 @@ } }, "updateCheckSucceededNoUpdate": { - "message": "スタイルは最新の状態です", + "message": "スタイルは最新の状態です。", "description": "Text that displays when an update check completed and no update is available" }, "appliesUrlPrefixOption": { @@ -396,6 +445,10 @@ "message": "正規表現検索に /re/ シンタックスを使用する", "description": "Label after the search input field in the editor shown on Ctrl-F" }, + "popupBordersTooltip": { + "message": "新しいChromeが横の境界線を描かなくなったため、暗いテーマで有効です", + "description": "" + }, "updateCheckManualUpdateHint": { "message": "更新を強制すると、すべてのローカルでの編集内容が上書きされます。", "description": "Additional text displayed when an update check skipped updating the style to avoid losing local modifications" @@ -408,6 +461,10 @@ "message": "現在のスタイルの内容を破棄し、インポートされたスタイルで上書きする", "description": "Label for the button to import and overwrite current style" }, + "installUpdateFromLabel": { + "message": "更新をチェック", + "description": "Label for the checkbox to save current URL for update check" + }, "cm_resizeGripHint": { "message": "ダブルクリックで高さを最大化/元に戻す", "description": "Tooltip for the resize grip in style editor" @@ -425,7 +482,7 @@ "description": "Text displayed when no styles are installed for the current site" }, "appliesDisplayTruncatedSuffix": { - "message": "サイトを追加", + "message": "さらに表示", "description": "Text added to appliesDisplay when there are more sites for the style than are displayed" }, "appliesRemove": { @@ -440,6 +497,10 @@ "message": "Mozilla形式のスタイル", "description": "Title of the popup with the style code in Mozilla format, shown after pressing the Export button on Edit style page" }, + "cm_colorpicker": { + "message": "CSSの色選択ツール", + "description": "Label for the checkbox controlling colorpicker option for the style editor." + }, "writeStyleFor": { "message": "次のスタイルを書く:", "description": "Label for toolbar pop-up that precedes the links to write a new style" @@ -510,7 +571,7 @@ "description": "Label for the drop-down list controlling the automatic highlighting of current word/selection occurrences in the style editor." }, "styleRegexpPartialExplanation": { - "message": "このスタイルは、完全なURLの一致を要求する CSS4 @document 仕様 に違反した部分一致の正規表現を使用しています。影響を受けるCSSセクションはページに適用されませんでした。このスタイルは、'regexp()' のルールを誤ってチェックしていた かなり初期のバージョンの Stylish-for-Chrome で作成された可能性があります(既知のバグです)", + "message": "このスタイルは、完全なURLの一致を要求する CSS4 @document 仕様 に違反した部分一致の正規表現を使用しています。影響を受けるCSSセクションはページに適用されませんでした。このスタイルは、'regexp()' のルールを誤ってチェックしていた かなり初期のバージョンの Stylish-for-Chrome で作成された可能性があります(既知のバグです)。", "description": "" }, "linterCSSLintSettings": { @@ -537,6 +598,10 @@ "message": "すべてのスタイルをオフにする", "description": "Label for the checkbox that turns all enabled styles off." }, + "appliesLineWidgetLabel": { + "message": "「適用先」の情報を表示", + "description": "Label for the checkbox to display applies-to information in the single editor" + }, "updateCheckSkippedMaybeLocallyEdited": { "message": "このスタイルはローカルで編集されている可能性があります。", "description": "Text that displays when an update check skipped updating the style to avoid losing possible local modifications" @@ -550,7 +615,7 @@ "description": "" }, "updateCompleted": { - "message": "更新が完了しました", + "message": "更新が完了しました。", "description": "Text that displays when an update completed" }, "dysfunctionalBackgroundConnection": { @@ -570,13 +635,28 @@ "description": "Label for the numeric input box to limit max number of applies-to targets in the new UI on manage page" }, "popupManageTooltip": { - "message": "Shift-クリック または 右クリック で、現在のサイトに適用可能なスタイルの管理画面を開きます。", + "message": "Shift-クリック または 右クリック で、現在のサイトに適用可能なスタイルの管理画面を開きます", "description": "Tooltip for the 'Manage' button in the popup." }, "manageFaviconsHelp": { "message": "Stylusは外部サービスを使用します https://www.google.com/s2/favicons", "description": "Label for the checkbox that toggles applies-to favicons in the new UI on manage page" }, + "styleInstallOverwrite": { + "message": "「$stylename$」はすでにインストール済みです。上書きしますか?\nバージョン: $oldVersion$ -> $newVersion$", + "description": "Confirmation when re-installing a style", + "placeholders": { + "stylename": { + "content": "$1" + }, + "newVersion": { + "content": "$3" + }, + "oldVersion": { + "content": "$2" + } + } + }, "updateCheckSkippedLocallyEdited": { "message": "このスタイルはローカルで編集されました。", "description": "Text that displays when an update check skipped updating the style to avoid losing local modifications" @@ -585,6 +665,10 @@ "message": "ルールの完全なリストを見る", "description": "Stylelint or CSSLint rules label added immediately before a link" }, + "styleUpdateDiscardChanges": { + "message": "このスタイルはエディタの外部で変更されました。このスタイルをリロードしますか?", + "description": "Confirmation to update the style in the editor" + }, "optionsResetButton": { "message": "オプションをリセット", "description": "" @@ -593,6 +677,10 @@ "message": "コード", "description": "Label for the code for a section" }, + "externalUsercssDocument": { + "message": "Usercssの文書", + "description": "Label for the external link to usercss documentation" + }, "optionsAdvancedContextDelete": { "message": "エディタのコンテキストメニューに「削除」を追加します", "description": "" @@ -606,6 +694,10 @@ } } }, + "configureStyle": { + "message": "設定", + "description": "Label for the button to configure userstyle" + }, "importReportLegendUpdatedBoth": { "message": "件のメタ情報とコードを更新しました", "description": "Text after the number of styles updated entirely in the report shown after importing styles" @@ -634,12 +726,38 @@ "message": "入力の自動補完", "description": "Label for the checkbox in the style editor." }, + "linterCSSLintIncompatible": { + "message": "CSSLintは「$preprocessorname$」プリプロセッサをサポートしていません", + "description": "The label to display when the preprocessor isn't compatible with CSSLint", + "placeholders": { + "preprocessorname": { + "content": "$1" + } + } + }, + "styleMetaErrorSelectValueMismatch": { + "message": "不正な @select: 値がリストに存在しません", + "description": "Error displayed when the value of @select is invalid" + }, + "styleMetaErrorColor": { + "message": "$color$ は有効な色ではありません", + "description": "Error displayed when the value of @var color is invalid", + "placeholders": { + "color": { + "content": "$1" + } + } + }, + "externalFeedback": { + "message": "フィードバック", + "description": "Label for the external link to send feedback for the style" + }, "manageOnlyDisabled": { "message": "無効なスタイルのみ", "description": "Checkbox to show only disabled styles" }, "stylusUnavailableForURLdetails": { - "message": "セキュリティ上の予防措置として、ブラウザは拡張機能がビルトイン ページ(chrome://version, Chrome 61 の標準の新しいタブページ, about:addons 等)に影響を与えることを禁止しています。これは他の拡張機能のページについても同様です。各ブラウザはまた、自身の拡張機能ギャラリーへのアクセスについても制限しています(Chrome Web ストア や AMO 等)", + "message": "セキュリティ上の予防措置として、ブラウザは拡張機能がビルトイン ページ(chrome://version, Chrome 61 の標準の新しいタブページ, about:addons 等)に影響を与えることを禁止しています。これは他の拡張機能のページについても同様です。各ブラウザはまた、自身の拡張機能ギャラリーへのアクセスについても制限しています(Chrome Web ストア や AMO 等)。", "description": "Sub-note in the toolbar pop-up when on a URL Stylus can't affect" }, "cm_matchHighlightSelection": { @@ -654,6 +772,10 @@ "message": "このようなページではStylusは動作しません。", "description": "Note in the toolbar pop-up when on a URL Stylus can't affect" }, + "popupBorders": { + "message": "横に白い境界線を追加する", + "description": "" + }, "manageOnlyUpdates": { "message": "更新または問題があるスタイルのみ", "description": "Checkbox to show only styles that have updates after check-all-styles-for-updates was performed" @@ -662,6 +784,14 @@ "message": "スタイルを追加", "description": "Title of the page for adding styles" }, + "externalLink": { + "message": "外部リンク", + "description": "Label for external links" + }, + "externalHomepage": { + "message": "ホームページ", + "description": "Label for the external link to style's homepage" + }, "importReplaceLabel": { "message": "スタイルを上書き", "description": "Label for the button to import and overwrite current style" @@ -678,6 +808,10 @@ "message": "上級者向け", "description": "" }, + "alphaChannel": { + "message": "透明度", + "description": "Label of color's opacity" + }, "importAppendTooltip": { "message": "インポートされたスタイルを現在のスタイルに追加する", "description": "Tooltip for the button to import a style and append to the existing sections" @@ -707,7 +841,7 @@ "description": "Label before the replace input field in the editor shown on 'replaceAll' hotkey" }, "importReportUnchanged": { - "message": "変更がありませんでした", + "message": "変更がありませんでした。", "description": "Message in the report shown after importing styles" }, "optionsActions": { @@ -730,10 +864,23 @@ "message": "オプション UI", "description": "Go to Options UI" }, + "colorpickerTooltip": { + "message": "色選択ツールを開きます", + "description": "Tooltip for the colored squares shown before CSS colors in the style editor." + }, "optionsCustomizeBadge": { "message": "ツールバーアイコンのバッジ", "description": "" }, + "installUpdateFrom": { + "message": "現在、このスタイルは「$url$」から更新されます", + "description": "Label to describe where the style gets update", + "placeholders": { + "url": { + "content": "$1" + } + } + }, "importReportLegendIdentical": { "message": "件の同一のスタイルをスキップしました", "description": "Text after the number of styles skipped due to being identical to the already installed ones in the report shown after importing styles" @@ -742,6 +889,14 @@ "message": "ポップアップの幅(ピクセル単位)", "description": "" }, + "cm_autoCloseBrackets": { + "message": "括弧と引用符を自動的に閉じる", + "description": "Label for the checkbox in the style editor." + }, + "installButtonReinstall": { + "message": "再インストール", + "description": "Label for reinstall button" + }, "linterInvalidConfigError": { "message": "これらの不正な設定のために保存されませんでした :", "description": "Invalid linter config will show a message followed by a list of invalid entries" @@ -750,6 +905,19 @@ "message": "いいえ", "description": "'No' button in a confirm dialog" }, + "styleMissingMeta": { + "message": "メタデータがありません @$key$", + "description": "Error displayed when a mandatory metadata is missing", + "placeholders": { + "key": { + "content": "$1" + } + } + }, + "appliesLineWidgetWarning": { + "message": "圧縮されたCSSでは機能しません", + "description": "A warning that applies-to information won't show properly with minified CSS" + }, "undo": { "message": "元に戻す", "description": "Button label" @@ -758,6 +926,14 @@ "message": "キーマップ", "description": "Label for the drop-down list controlling the keymap for the style editor." }, + "externalSupport": { + "message": "サポート", + "description": "Label for the external link to style's support site" + }, + "confirmSave": { + "message": "保存", + "description": "'Save' button in a confirm dialog" + }, "manageNewUI": { "message": "新しい管理UIレイアウト", "description": "Label for the checkbox that toggles the new UI on manage page" @@ -778,6 +954,10 @@ "message": "次に置換", "description": "Label before the replace-with input field in the editor shown on Ctrl-H etc." }, + "liveReloadError": { + "message": "ファイルの監視中にエラーが発生しました", + "description": "The label of live-reload error" + }, "deleteStyleLabel": { "message": "削除", "description": "Label for the button to delete a style" @@ -786,6 +966,15 @@ "message": "更新をインストール(ローカルでの編集内容は上書きされます)", "description": "Additional text displayed when an update check skipped updating the style to avoid losing local modifications" }, + "styleInstallFailed": { + "message": "ユーザースタイルのインストールに失敗しました!\n$error$", + "description": "Warning when installation failed", + "placeholders": { + "error": { + "content": "$1" + } + } + }, "optionsAdvancedExposeIframes": { "message": "HTML[stylus-iframe] によってiframeへのアクセスを可能にします", "description": "" @@ -798,6 +987,10 @@ "message": "ユーザースタイルの自動更新チェックを無効にするには、間隔を0に設定します。", "description": "" }, + "installButtonUpdate": { + "message": "更新", + "description": "Label for update button" + }, "backupButtons": { "message": "バックアップ", "description": "Heading for backup" @@ -810,6 +1003,14 @@ "message": "編集", "description": "Label for the button to go to the edit style page" }, + "installButtonInstalled": { + "message": "インストール済み", + "description": "Text displayed when the style is successfully installed" + }, + "author": { + "message": "作者", + "description": "Label for the style author" + }, "cm_theme": { "message": "テーマ", "description": "Label for the style editor's CSS theme." @@ -818,6 +1019,10 @@ "message": "新しいウィンドウでエディタを開く", "description": "Label for the checkbox controlling 'edit' action behavior in the popup." }, + "appliesRemoveError": { + "message": "「適用先」の最後の項目を削除することはできません", + "description": "Error displayed when the last 'applies' is going to be removed" + }, "backupMessage": { "message": "ファイルを選択するか、このページにドラッグ&ドロップします。", "description": "Message for backup" @@ -837,5 +1042,9 @@ "description": { "message": "Stylus でウェブのデザインを変更しましょう。これは、ユーザースタイルを管理するツールです。Stylus を利用すると、多くの人気サイト向けのテーマやスキンを簡単にインストールできます。", "description": "Extension description" + }, + "confirmClose": { + "message": "閉じる", + "description": "'Close' button in a confirm dialog" } } \ No newline at end of file diff --git a/_locales/nl/messages.json b/_locales/nl/messages.json index c71d4d7d..a9ce5425 100644 --- a/_locales/nl/messages.json +++ b/_locales/nl/messages.json @@ -24,7 +24,7 @@ "description": "Label for the button to enable a style" }, "styleMissingName": { - "message": "Vul een naam in.", + "message": "Vul een naam in", "description": "Error displayed when user saves without providing a name" }, "appliesDomainOption": { diff --git a/_locales/pl/messages.json b/_locales/pl/messages.json index 98cb0b6b..00a5f257 100644 --- a/_locales/pl/messages.json +++ b/_locales/pl/messages.json @@ -19,6 +19,10 @@ "message": "Eksportuj style", "description": "" }, + "manageOnlyUsercss": { + "message": "Tylko style Usercss", + "description": "Checkbox to show only Usercss styles" + }, "optionsUpdateInterval": { "message": "Automatycznie sprawdzaj i zainstaluj wszystkie dostępne aktualizacje stylów użytkownika (w godzinach)", "description": "" @@ -31,6 +35,14 @@ "message": "Eksportuj", "description": "Label for the button to export a style ('edit' page) or all styles ('manage' page)" }, + "installButton": { + "message": "Zainstaluj", + "description": "Label for install button" + }, + "styleMetaErrorCheckbox": { + "message": "Nieprawidłowe pole @var: wartość musi wynosić 0 lub 1", + "description": "Error displayed when the value of @var checkbox is invalid" + }, "linterJSONError": { "message": "Nieprawidłowy format JSON", "description": "Setting linter config with invalid JSON" @@ -44,7 +56,7 @@ "description": "" }, "cm_tabSize": { - "message": "Rozmiar tabulatora", + "message": "Szerokość tabulacji", "description": "Label for the text box controlling tab size option for the style editor." }, "enableStyleLabel": { @@ -52,7 +64,7 @@ "description": "Label for the button to enable a style" }, "styleMissingName": { - "message": "Wprowadź nazwę.", + "message": "Wpisz nazwę", "description": "Error displayed when user saves without providing a name" }, "genericHistoryLabel": { @@ -75,6 +87,10 @@ "message": "Styl nie został zastosowany z powodu nieprawidłowego użycia 'regexp()'", "description": "Tooltip in the popup for styles that were not applied at all" }, + "colorpickerSwitchFormatTooltip": { + "message": "Zmiana formatu: HEX -> RGB -> HSL.\nShift i kliknięcie do odwrócenia kierunku.\nTakże klawiszami PgUp (PageUp), PgDn (PageDown).", + "description": "Tooltip for the switch button in the color picker popup in the style editor." + }, "styleRegexpInvalidExplanation": { "message": "Niektóre reguły 'regexp()', których nie można było w ogóle skompilować.", "description": "" @@ -83,6 +99,10 @@ "message": "Ciemne motywy przeglądarki", "description": "" }, + "styleFromMozillaFormatError": { + "message": "Nie udało się zaimportować z formatu Mozilla", + "description": "Label for the import error" + }, "importAppendLabel": { "message": "Dołącz do stylu", "description": "Label for the button to import a style and append to the existing sections" @@ -119,6 +139,10 @@ "message": "Wyszarzone", "description": "Label for the checkbox that toggles grayed out mode of applies-to favicons in the new UI on manage page" }, + "versionInvalidOlder": { + "message": "Wersja jest starsza niż zainstalowany styl.", + "description": "Displayed when the version of style is older than the installed one" + }, "confirmYes": { "message": "Tak", "description": "'Yes' button in a confirm dialog" @@ -171,10 +195,18 @@ "message": "Usuń", "description": "" }, + "confirmDefault": { + "message": "Użyj domyślnych", + "description": "'Set to default' button in a confirm dialog" + }, "confirmCancel": { "message": "Anuluj", "description": "" }, + "cm_autoCloseBracketsTooltip": { + "message": "Automatycznie dodawaj zamknięcie pary podczas pisania jednego z otwarcia ()[]{}''\"\"", + "description": "Label for the checkbox in the style editor." + }, "retrieveBckp": { "message": "Importuj style", "description": "" @@ -232,6 +264,15 @@ "message": "Tylko style stworzone lokalnie", "description": "Checkbox to show only locally created styles i.e. non-updatable" }, + "styleMetaErrorPreprocessor": { + "message": "Nieobsługiwany @preprocessor: $preprocessor$", + "description": "Error displayed when the value of @preprocessor is not supported", + "placeholders": { + "preprocessor": { + "content": "$1" + } + } + }, "linterIssuesHelp": { "message": "Te problemy zostały znalezione przez $link$:", "description": "Help popup message for the selected CSS linter issues block on the style edit page", @@ -241,6 +282,10 @@ } } }, + "parseUsercssError": { + "message": "Stylusowi nie udało się sparsować usercss:", + "description": "The error message to show when stylus failed to parse usercss" + }, "searchStyles": { "message": "Szukaj treści", "description": "Label for the search filter textbox on the Manage styles page" @@ -253,6 +298,14 @@ "message": "Sprawdź ponownie, nie edytowałem żadnych stylów!", "description": "Label for the button to apply all detected updates" }, + "manageOnlyNonUsercss": { + "message": "Tylko style nie-Usercss", + "description": "Checkbox to show only non-Usercss (standard) styles" + }, + "liveReloadLabel": { + "message": "Przeładuj na żywo", + "description": "The label of live-reload feature" + }, "unreachableFileHint": { "message": "Stylus może uzyskać dostęp do adresów URL file:// tylko po włączeniu odpowiedniego pola wyboru rozszerzenia Stylus na stronie chrome://extensions.", "description": "Note in the toolbar popup for file:// URLs" @@ -325,6 +378,10 @@ "message": "Regexp jest nieprawidłowe.", "description": "Validation message for a bad regexp in a style" }, + "license": { + "message": "Licencja", + "description": "Label for the license" + }, "optionsHeading": { "message": "Opcje", "description": "Heading for options section on manage page." @@ -367,6 +424,10 @@ "message": "nieprawidłowe pominięte", "description": "Text after the number of styles skipped due to being invalid (not a Stylus/Stylish backup file probably) in the report shown after importing styles" }, + "optionsAdvancedNewStyleAsUsercss": { + "message": "Napisz nowy styl jako usercss", + "description": "" + }, "genericResetLabel": { "message": "Resetuj", "description": "Used in various parts of UI to indicate that something may be reset to its original state" @@ -396,6 +457,10 @@ "message": "Użyj składni /re/ dla wyszukiwania regexp", "description": "Label after the search input field in the editor shown on Ctrl-F" }, + "popupBordersTooltip": { + "message": "Przydaje się do ciemnych motywów w nowym Chrome, ponieważ nie maluje już bocznych krawędzi", + "description": "" + }, "updateCheckManualUpdateHint": { "message": "Wymuszenie aktualizacji spowoduje nadpisanie wszelkich lokalnych zmian.", "description": "Additional text displayed when an update check skipped updating the style to avoid losing local modifications" @@ -408,6 +473,10 @@ "message": "Odrzuć zawartość bieżącego stylu i nadpisz go przy użyciu importowanego stylu", "description": "Label for the button to import and overwrite current style" }, + "installUpdateFromLabel": { + "message": "Sprawdź aktualizacje", + "description": "Label for the checkbox to save current URL for update check" + }, "cm_resizeGripHint": { "message": "Kliknij dwukrotnie, aby zmaksymalizować lub przywrócić wysokość", "description": "Tooltip for the resize grip in style editor" @@ -440,6 +509,10 @@ "message": "Styl w formacie Mozilla", "description": "Title of the popup with the style code in Mozilla format, shown after pressing the Export button on Edit style page" }, + "cm_colorpicker": { + "message": "Próbniki kolorów CSS", + "description": "Label for the checkbox controlling colorpicker option for the style editor." + }, "writeStyleFor": { "message": "Napisz styl dla:", "description": "Label for toolbar pop-up that precedes the links to write a new style" @@ -541,6 +614,10 @@ "message": "Wyłącz wszystkie style", "description": "Label for the checkbox that turns all enabled styles off." }, + "appliesLineWidgetLabel": { + "message": "Wyświetl informacje 'Dotyczy'", + "description": "Label for the checkbox to display applies-to information in the single editor" + }, "updateCheckSkippedMaybeLocallyEdited": { "message": "Ten styl mógł być edytowany lokalnie.", "description": "Text that displays when an update check skipped updating the style to avoid losing possible local modifications" @@ -581,6 +658,21 @@ "message": "Stylus korzysta z usługi zewnętrznej https://www.google.com/s2/favicons", "description": "Label for the checkbox that toggles applies-to favicons in the new UI on manage page" }, + "styleInstallOverwrite": { + "message": "'$stylename$' jest już zainstalowany. Zastąpić?\nWersja: $oldVersion$ -> $newVersion$", + "description": "Confirmation when re-installing a style", + "placeholders": { + "stylename": { + "content": "$1" + }, + "newVersion": { + "content": "$3" + }, + "oldVersion": { + "content": "$2" + } + } + }, "updateCheckSkippedLocallyEdited": { "message": "Ten styl był edytowany lokalnie.", "description": "Text that displays when an update check skipped updating the style to avoid losing local modifications" @@ -589,6 +681,10 @@ "message": "Zobacz pełną listę reguł", "description": "Stylelint or CSSLint rules label added immediately before a link" }, + "styleUpdateDiscardChanges": { + "message": "Styl zmieniono poza edytorem. Czy chcesz przeładować styl?", + "description": "Confirmation to update the style in the editor" + }, "optionsResetButton": { "message": "Resetuj opcje", "description": "" @@ -597,6 +693,10 @@ "message": "Kod", "description": "Label for the code for a section" }, + "externalUsercssDocument": { + "message": "Dokumentacja Usercss", + "description": "Label for the external link to usercss documentation" + }, "optionsAdvancedContextDelete": { "message": "Dodaj 'Usuń' do menu kontekstowego edytora", "description": "" @@ -610,6 +710,10 @@ } } }, + "configureStyle": { + "message": "Skonfiguruj", + "description": "Label for the button to configure userstyle" + }, "importReportLegendUpdatedBoth": { "message": "zaktualizowano meta info i kod", "description": "Text after the number of styles updated entirely in the report shown after importing styles" @@ -638,6 +742,32 @@ "message": "Autouzupełnianie podczas pisania", "description": "Label for the checkbox in the style editor." }, + "linterCSSLintIncompatible": { + "message": "CSSLint nie obsługuje preprocesora $preprocessorname$", + "description": "The label to display when the preprocessor isn't compatible with CSSLint", + "placeholders": { + "preprocessorname": { + "content": "$1" + } + } + }, + "styleMetaErrorSelectValueMismatch": { + "message": "Nieprawidłowy @select: wartość nie istnieje na liście", + "description": "Error displayed when the value of @select is invalid" + }, + "styleMetaErrorColor": { + "message": "$color$ nie jest prawidłowym kolorem", + "description": "Error displayed when the value of @var color is invalid", + "placeholders": { + "color": { + "content": "$1" + } + } + }, + "externalFeedback": { + "message": "Informacje zwrotne", + "description": "Label for the external link to send feedback for the style" + }, "manageOnlyDisabled": { "message": "Tylko wyłączone style", "description": "Checkbox to show only disabled styles" @@ -662,6 +792,10 @@ "message": "Stylus nie działa na takich stronach.", "description": "Note in the toolbar pop-up when on a URL Stylus can't affect" }, + "popupBorders": { + "message": "Dodaj białe obramowania po bokach", + "description": "" + }, "manageOnlyUpdates": { "message": "Tylko z aktualizacjami lub problemami", "description": "Checkbox to show only styles that have updates after check-all-styles-for-updates was performed" @@ -670,6 +804,14 @@ "message": "Dodaj styl", "description": "Title of the page for adding styles" }, + "externalLink": { + "message": "Link zewnętrzny", + "description": "Label for external links" + }, + "externalHomepage": { + "message": "Strona główna", + "description": "Label for the external link to style's homepage" + }, "importReplaceLabel": { "message": "Nadpisz styl", "description": "Label for the button to import and overwrite current style" @@ -686,6 +828,10 @@ "message": "Zaawansowane", "description": "" }, + "alphaChannel": { + "message": "Nieprzezroczystość", + "description": "Label of color's opacity" + }, "importAppendTooltip": { "message": "Dołącz importowany styl do bieżącego stylu", "description": "Tooltip for the button to import a style and append to the existing sections" @@ -742,18 +888,43 @@ "message": "Opcje interfejsu", "description": "Go to Options UI" }, + "colorpickerTooltip": { + "message": "Otwórz próbnik kolorów", + "description": "Tooltip for the colored squares shown before CSS colors in the style editor." + }, "optionsCustomizeBadge": { "message": "Emblemat na ikonie paska narzędzi", "description": "" }, + "installUpdateFrom": { + "message": "Obecnie styl jest aktualizowany z $url$", + "description": "Label to describe where the style gets update", + "placeholders": { + "url": { + "content": "$1" + } + } + }, "importReportLegendIdentical": { "message": "identyczne pominięte", "description": "Text after the number of styles skipped due to being identical to the already installed ones in the report shown after importing styles" }, + "manageNewStyleAsUsercss": { + "message": "jako Usercss", + "description": "VERY SHORT label for the checkbox next to the 'Write new style' button in the style manager" + }, "optionsPopupWidth": { "message": "Szerokość okna (w pikselach)", "description": "" }, + "cm_autoCloseBrackets": { + "message": "Automatyczne zamykanie nawiasów i cytatów", + "description": "Label for the checkbox in the style editor." + }, + "installButtonReinstall": { + "message": "Przeinstaluj", + "description": "Label for reinstall button" + }, "linterInvalidConfigError": { "message": "Nie zapisano z powodu tych nieprawidłowych ustawień konfiguracji:", "description": "Invalid linter config will show a message followed by a list of invalid entries" @@ -762,6 +933,19 @@ "message": "Nie", "description": "'No' button in a confirm dialog" }, + "styleMissingMeta": { + "message": "Brakujące metadane @$key$", + "description": "Error displayed when a mandatory metadata is missing", + "placeholders": { + "key": { + "content": "$1" + } + } + }, + "appliesLineWidgetWarning": { + "message": "Nie działa ze zminifikowanym CSS", + "description": "A warning that applies-to information won't show properly with minified CSS" + }, "undo": { "message": "Cofnij", "description": "Button label" @@ -770,6 +954,14 @@ "message": "Mapa klawiszy", "description": "Label for the drop-down list controlling the keymap for the style editor." }, + "externalSupport": { + "message": "Wsparcie", + "description": "Label for the external link to style's support site" + }, + "confirmSave": { + "message": "Zapisz", + "description": "'Save' button in a confirm dialog" + }, "manageNewUI": { "message": "Nowy układ interfejsu zarządzania", "description": "Label for the checkbox that toggles the new UI on manage page" @@ -790,6 +982,10 @@ "message": "Zamień na", "description": "Label before the replace-with input field in the editor shown on Ctrl-H etc." }, + "liveReloadError": { + "message": "Wystąpił błąd podczas oglądania pliku", + "description": "The label of live-reload error" + }, "deleteStyleLabel": { "message": "Usuń", "description": "Label for the button to delete a style" @@ -798,6 +994,15 @@ "message": "Zainstaluj aktualizację (lokalne zmiany zostaną nadpisane)", "description": "Additional text displayed when an update check skipped updating the style to avoid losing local modifications" }, + "styleInstallFailed": { + "message": "Nie udało się zainstalować stylu!\n$error$", + "description": "Warning when installation failed", + "placeholders": { + "error": { + "content": "$1" + } + } + }, "optionsAdvancedExposeIframes": { "message": "Odsłoń ramki pływające za pomocą HTML[stylus-iframe]", "description": "" @@ -810,6 +1015,10 @@ "message": "Aby wyłączyć automatyczne sprawdzanie aktualizacji stylów użytkownika, ustaw interwał na 0", "description": "" }, + "installButtonUpdate": { + "message": "Zaktualizuj", + "description": "Label for update button" + }, "backupButtons": { "message": "Kopia zapasowa", "description": "Heading for backup" @@ -822,6 +1031,14 @@ "message": "Edytuj", "description": "Label for the button to go to the edit style page" }, + "installButtonInstalled": { + "message": "Zainstalowany", + "description": "Text displayed when the style is successfully installed" + }, + "author": { + "message": "Autor", + "description": "Label for the style author" + }, "cm_theme": { "message": "Motyw", "description": "Label for the style editor's CSS theme." @@ -830,6 +1047,10 @@ "message": "Otwórz edytor w nowym oknie", "description": "Label for the checkbox controlling 'edit' action behavior in the popup." }, + "appliesRemoveError": { + "message": "Nie można usunąć ostatniego wpisu 'dotyczy'", + "description": "Error displayed when the last 'applies' is going to be removed" + }, "backupMessage": { "message": "Wybierz plik lub przeciągnij i upuść go na tę stronę.", "description": "Message for backup" @@ -849,5 +1070,9 @@ "description": { "message": "Przeprojektuj sieć za pomocą Stylusa – menedżera stylów użytkownika. Stylus umożliwia łatwe instalowanie motywów i skórek dla wielu popularnych stron.", "description": "Extension description" + }, + "confirmClose": { + "message": "Zamknij", + "description": "'Close' button in a confirm dialog" } } \ No newline at end of file diff --git a/_locales/pt_BR/messages.json b/_locales/pt_BR/messages.json index ce98da46..1fd49753 100644 --- a/_locales/pt_BR/messages.json +++ b/_locales/pt_BR/messages.json @@ -8,7 +8,7 @@ "description": "Label for the button to enable a style" }, "styleMissingName": { - "message": "Insira um nome.", + "message": "Insira um nome", "description": "Error displayed when user saves without providing a name" }, "appliesDomainOption": { diff --git a/_locales/pt_PT/messages.json b/_locales/pt_PT/messages.json index d470e6e9..f1b288d8 100644 --- a/_locales/pt_PT/messages.json +++ b/_locales/pt_PT/messages.json @@ -44,7 +44,7 @@ "description": "Label for the button to enable a style" }, "styleMissingName": { - "message": "Insira um nome.", + "message": "Insira um nome", "description": "Error displayed when user saves without providing a name" }, "genericHistoryLabel": { diff --git a/_locales/ru/messages.json b/_locales/ru/messages.json index 557cc6e6..e7165087 100644 --- a/_locales/ru/messages.json +++ b/_locales/ru/messages.json @@ -19,6 +19,10 @@ "message": "Экспорт стилей", "description": "" }, + "manageOnlyUsercss": { + "message": "Только Usercss стили", + "description": "Checkbox to show only Usercss styles" + }, "optionsUpdateInterval": { "message": "Автоматически проверять и устанавливать обновления стилей (интервал в часах)", "description": "" @@ -31,6 +35,14 @@ "message": "Экспорт", "description": "Label for the button to export a style ('edit' page) or all styles ('manage' page)" }, + "installButton": { + "message": "Установить", + "description": "Label for install button" + }, + "styleMetaErrorCheckbox": { + "message": "Ошибочный @var checkbox: значение должно быть 0 или 1", + "description": "Error displayed when the value of @var checkbox is invalid" + }, "linterJSONError": { "message": "Ошибка формата JSON", "description": "Setting linter config with invalid JSON" @@ -52,7 +64,7 @@ "description": "Label for the button to enable a style" }, "styleMissingName": { - "message": "Введите название.", + "message": "Введите название", "description": "Error displayed when user saves without providing a name" }, "genericHistoryLabel": { @@ -75,6 +87,10 @@ "message": "Стиль не был применен из-за некорректного regexp()", "description": "Tooltip in the popup for styles that were not applied at all" }, + "colorpickerSwitchFormatTooltip": { + "message": "Сменить формат: #FFF -> RGB -> HSL.\nКлик с Shift меняет в обратном направлении.\nТакже клавишами PgUp, PgDn (\"Страница вверх\" и \"Страница вниз\").", + "description": "Tooltip for the switch button in the color picker popup in the style editor." + }, "styleRegexpInvalidExplanation": { "message": "Некоторые 'regexp()' выражения не удалось скомпилировать.", "description": "" @@ -83,6 +99,10 @@ "message": "Тёмный интерфейс браузера", "description": "" }, + "styleFromMozillaFormatError": { + "message": "Ошибка импорта формата Mozilla", + "description": "Label for the import error" + }, "importAppendLabel": { "message": "Добавить к стилю", "description": "Label for the button to import a style and append to the existing sections" @@ -123,6 +143,10 @@ "message": "Обесцвечивать", "description": "Label for the checkbox that toggles grayed out mode of applies-to favicons in the new UI on manage page" }, + "versionInvalidOlder": { + "message": "Версия меньше установленной.", + "description": "Displayed when the version of style is older than the installed one" + }, "confirmYes": { "message": "Да", "description": "'Yes' button in a confirm dialog" @@ -175,10 +199,18 @@ "message": "Удалить", "description": "" }, + "confirmDefault": { + "message": "По умолчанию", + "description": "'Set to default' button in a confirm dialog" + }, "confirmCancel": { "message": "Отмена", "description": "" }, + "cm_autoCloseBracketsTooltip": { + "message": "Автоматически вставлять закрывающий символ при наборе открывающего из ()[]{}''\"\"", + "description": "Label for the checkbox in the style editor." + }, "retrieveBckp": { "message": "Импорт стилей", "description": "" @@ -236,6 +268,15 @@ "message": "Только локально созданные стили", "description": "Checkbox to show only locally created styles i.e. non-updatable" }, + "styleMetaErrorPreprocessor": { + "message": "Ошибочный @preprocessor: $preprocessor$", + "description": "Error displayed when the value of @preprocessor is not supported", + "placeholders": { + "preprocessor": { + "content": "$1" + } + } + }, "linterIssuesHelp": { "message": "Проблемы, найденные правилами $link$:", "description": "Help popup message for the selected CSS linter issues block on the style edit page", @@ -245,6 +286,10 @@ } } }, + "parseUsercssError": { + "message": "Stylus не смог распарсить usercss:", + "description": "The error message to show when stylus failed to parse usercss" + }, "searchStyles": { "message": "Искать по содержимому", "description": "Label for the search filter textbox on the Manage styles page" @@ -257,6 +302,14 @@ "message": "Я не менял стили, проверить заново!", "description": "Label for the button to apply all detected updates" }, + "manageOnlyNonUsercss": { + "message": "Спрятать Usercss стили", + "description": "Checkbox to show only non-Usercss (standard) styles" + }, + "liveReloadLabel": { + "message": "Автозагрузка изменений", + "description": "The label of live-reload feature" + }, "unreachableFileHint": { "message": "Доступ к адресам file:// возможен только если включить соответствующую опцию для Stylus на странице chrome://extensions.", "description": "Note in the toolbar popup for file:// URLs" @@ -329,6 +382,10 @@ "message": "Ошибка в регулярном выражении.", "description": "Validation message for a bad regexp in a style" }, + "license": { + "message": "Лицензия", + "description": "Label for the license" + }, "optionsHeading": { "message": "Настройки", "description": "Heading for options section on manage page." @@ -371,6 +428,10 @@ "message": "некорректных пропущено", "description": "Text after the number of styles skipped due to being invalid (not a Stylus/Stylish backup file probably) in the report shown after importing styles" }, + "optionsAdvancedNewStyleAsUsercss": { + "message": "Создавать стили в формате usercss", + "description": "" + }, "genericResetLabel": { "message": "Сброс", "description": "Used in various parts of UI to indicate that something may be reset to its original state" @@ -400,6 +461,10 @@ "message": "Используйте нотацию /re/ для поиска регулярными выражениями", "description": "Label after the search input field in the editor shown on Ctrl-F" }, + "popupBordersTooltip": { + "message": "Полезно для темных тем оформления т.к. новый Chrome не рисует боковые бордюры", + "description": "" + }, "updateCheckManualUpdateHint": { "message": "Форсирование обновления удалит локальные изменения.", "description": "Additional text displayed when an update check skipped updating the style to avoid losing local modifications" @@ -412,6 +477,10 @@ "message": "Удалить содержимое редактируемого стиля и заменить его на импортируемый стиль", "description": "Label for the button to import and overwrite current style" }, + "installUpdateFromLabel": { + "message": "Проверить обновления", + "description": "Label for the checkbox to save current URL for update check" + }, "cm_resizeGripHint": { "message": "Двойной клик = переключить максимальный размер", "description": "Tooltip for the resize grip in style editor" @@ -444,6 +513,10 @@ "message": "Стиль в формате Mozilla", "description": "Title of the popup with the style code in Mozilla format, shown after pressing the Export button on Edit style page" }, + "cm_colorpicker": { + "message": "Раскрашивать цвета в CSS", + "description": "Label for the checkbox controlling colorpicker option for the style editor." + }, "writeStyleFor": { "message": "Создать стиль для:", "description": "Label for toolbar pop-up that precedes the links to write a new style" @@ -545,6 +618,10 @@ "message": "Выключить все стили", "description": "Label for the checkbox that turns all enabled styles off." }, + "appliesLineWidgetLabel": { + "message": "Показать целевые сайты секций", + "description": "Label for the checkbox to display applies-to information in the single editor" + }, "updateCheckSkippedMaybeLocallyEdited": { "message": "Возможно был изменен локально.", "description": "Text that displays when an update check skipped updating the style to avoid losing possible local modifications" @@ -585,6 +662,21 @@ "message": "Используется сторонний сервис https://www.google.com/s2/favicons", "description": "Label for the checkbox that toggles applies-to favicons in the new UI on manage page" }, + "styleInstallOverwrite": { + "message": "'$stylename$' уже установлен. Обновить?\nВерсии: $oldVersion$ -> $newVersion$", + "description": "Confirmation when re-installing a style", + "placeholders": { + "stylename": { + "content": "$1" + }, + "newVersion": { + "content": "$3" + }, + "oldVersion": { + "content": "$2" + } + } + }, "updateCheckSkippedLocallyEdited": { "message": "Стиль был изменен локально.", "description": "Text that displays when an update check skipped updating the style to avoid losing local modifications" @@ -593,6 +685,10 @@ "message": "Открыть полный список правил", "description": "Stylelint or CSSLint rules label added immediately before a link" }, + "styleUpdateDiscardChanges": { + "message": "Стиль был изменен вне редактора. Перезагрузить?", + "description": "Confirmation to update the style in the editor" + }, "optionsResetButton": { "message": "Сброс настроек", "description": "" @@ -601,6 +697,10 @@ "message": "Код", "description": "Label for the code for a section" }, + "externalUsercssDocument": { + "message": "Документация по usercss", + "description": "Label for the external link to usercss documentation" + }, "optionsAdvancedContextDelete": { "message": "Показывать команду \"Удалить\" в контекстном меню редактора", "description": "" @@ -614,6 +714,10 @@ } } }, + "configureStyle": { + "message": "Настроить", + "description": "Label for the button to configure userstyle" + }, "importReportLegendUpdatedBoth": { "message": "обновлены мета-данные и код", "description": "Text after the number of styles updated entirely in the report shown after importing styles" @@ -642,6 +746,32 @@ "message": "Подсказки при наборе кода", "description": "Label for the checkbox in the style editor." }, + "linterCSSLintIncompatible": { + "message": "CSSLint не поддерживает препроцессор $preprocessorname$", + "description": "The label to display when the preprocessor isn't compatible with CSSLint", + "placeholders": { + "preprocessorname": { + "content": "$1" + } + } + }, + "styleMetaErrorSelectValueMismatch": { + "message": "Ошибочный @select: значение не в списке", + "description": "Error displayed when the value of @select is invalid" + }, + "styleMetaErrorColor": { + "message": "$color$ - цвет не распознан", + "description": "Error displayed when the value of @var color is invalid", + "placeholders": { + "color": { + "content": "$1" + } + } + }, + "externalFeedback": { + "message": "Отзывы", + "description": "Label for the external link to send feedback for the style" + }, "manageOnlyDisabled": { "message": "Только неактивные стили", "description": "Checkbox to show only disabled styles" @@ -662,6 +792,10 @@ "message": "Такие адреса не поддерживаются.", "description": "Note in the toolbar pop-up when on a URL Stylus can't affect" }, + "popupBorders": { + "message": "Добавить белый бордюр по бокам", + "description": "" + }, "manageOnlyUpdates": { "message": "Только обновляемые и проблемные", "description": "Checkbox to show only styles that have updates after check-all-styles-for-updates was performed" @@ -670,6 +804,14 @@ "message": "Добавление стиля", "description": "Title of the page for adding styles" }, + "externalLink": { + "message": "Внешняя ссылка", + "description": "Label for external links" + }, + "externalHomepage": { + "message": "Домашняя страницы", + "description": "Label for the external link to style's homepage" + }, "importReplaceLabel": { "message": "Заменить стиль", "description": "Label for the button to import and overwrite current style" @@ -686,6 +828,10 @@ "message": "Другое", "description": "" }, + "alphaChannel": { + "message": "Прозрачность", + "description": "Label of color's opacity" + }, "importAppendTooltip": { "message": "Добавить импортируемый стиль к редактируемому", "description": "Tooltip for the button to import a style and append to the existing sections" @@ -742,18 +888,43 @@ "message": "Настройки", "description": "Go to Options UI" }, + "colorpickerTooltip": { + "message": "Изменить цвет", + "description": "Tooltip for the colored squares shown before CSS colors in the style editor." + }, "optionsCustomizeBadge": { "message": "Бейдж на пиктограмме в тулбаре", "description": "" }, + "installUpdateFrom": { + "message": "Источник обновления стиля: $url$", + "description": "Label to describe where the style gets update", + "placeholders": { + "url": { + "content": "$1" + } + } + }, "importReportLegendIdentical": { "message": "идентичные пропущены", "description": "Text after the number of styles skipped due to being identical to the already installed ones in the report shown after importing styles" }, + "manageNewStyleAsUsercss": { + "message": "в формате Usercss", + "description": "VERY SHORT label for the checkbox next to the 'Write new style' button in the style manager" + }, "optionsPopupWidth": { "message": "Ширина всплывающего окна (в пикселах)", "description": "" }, + "cm_autoCloseBrackets": { + "message": "Закрывать скобки/кавычки при наборе", + "description": "Label for the checkbox in the style editor." + }, + "installButtonReinstall": { + "message": "Переустановить", + "description": "Label for reinstall button" + }, "linterInvalidConfigError": { "message": "Не сохранено из-за неправильных настроек ниже:", "description": "Invalid linter config will show a message followed by a list of invalid entries" @@ -762,6 +933,19 @@ "message": "Нет", "description": "'No' button in a confirm dialog" }, + "styleMissingMeta": { + "message": "Отсутствуют метаданные @$key$", + "description": "Error displayed when a mandatory metadata is missing", + "placeholders": { + "key": { + "content": "$1" + } + } + }, + "appliesLineWidgetWarning": { + "message": "Не работает с минифицированным CSS", + "description": "A warning that applies-to information won't show properly with minified CSS" + }, "undo": { "message": "Отменить", "description": "Button label" @@ -770,6 +954,14 @@ "message": "Раскладка", "description": "Label for the drop-down list controlling the keymap for the style editor." }, + "externalSupport": { + "message": "Поддержка", + "description": "Label for the external link to style's support site" + }, + "confirmSave": { + "message": "Сохранить", + "description": "'Save' button in a confirm dialog" + }, "manageNewUI": { "message": "Новый интерфейс", "description": "Label for the checkbox that toggles the new UI on manage page" @@ -790,6 +982,10 @@ "message": "Заменить на", "description": "Label before the replace-with input field in the editor shown on Ctrl-H etc." }, + "liveReloadError": { + "message": "Ошибка слежения за файлом", + "description": "The label of live-reload error" + }, "deleteStyleLabel": { "message": "Удалить", "description": "Label for the button to delete a style" @@ -798,6 +994,15 @@ "message": "Установить обновление (локальные изменения будут утеряны)", "description": "Additional text displayed when an update check skipped updating the style to avoid losing local modifications" }, + "styleInstallFailed": { + "message": "Ошибка установки стиля!\n$error$", + "description": "Warning when installation failed", + "placeholders": { + "error": { + "content": "$1" + } + } + }, "optionsAdvancedExposeIframes": { "message": "Выявлять iframe путем добавления HTML[stylus-iframe]", "description": "" @@ -810,6 +1015,10 @@ "message": "Для отключения автоматического обновления стилей введите 0 (ноль)", "description": "" }, + "installButtonUpdate": { + "message": "Обновить", + "description": "Label for update button" + }, "backupButtons": { "message": "Резервное копирование", "description": "Heading for backup" @@ -822,6 +1031,14 @@ "message": "Изменить", "description": "Label for the button to go to the edit style page" }, + "installButtonInstalled": { + "message": "Установлен", + "description": "Text displayed when the style is successfully installed" + }, + "author": { + "message": "Автор", + "description": "Label for the style author" + }, "cm_theme": { "message": "Тема", "description": "Label for the style editor's CSS theme." @@ -830,6 +1047,10 @@ "message": "Открывать редактор в новом окне", "description": "Label for the checkbox controlling 'edit' action behavior in the popup." }, + "appliesRemoveError": { + "message": "Нельзя удалить последний элемент", + "description": "Error displayed when the last 'applies' is going to be removed" + }, "backupMessage": { "message": "Нажмите Импорт чтобы выбрать файл или просто перетащите его на эту страницу", "description": "Message for backup" @@ -849,5 +1070,9 @@ "description": { "message": "Настраивайте стили веб-сайтов с помощью менеджера стилей Stylus. Он позволяет легко установить темы и изменить внешний вид сайтов Google, Facebook, YouTube, Orkut и множества других веб-страниц.", "description": "Extension description" + }, + "confirmClose": { + "message": "Закрыть", + "description": "'Close' button in a confirm dialog" } } \ No newline at end of file diff --git a/_locales/sv/messages.json b/_locales/sv/messages.json index b42e3c2c..e432893d 100644 --- a/_locales/sv/messages.json +++ b/_locales/sv/messages.json @@ -12,7 +12,7 @@ "description": "Label for the button to enable a style" }, "styleMissingName": { - "message": "Ange ett namn.", + "message": "Ange ett namn", "description": "Error displayed when user saves without providing a name" }, "appliesDomainOption": { diff --git a/_locales/tr/messages.json b/_locales/tr/messages.json index b9b565d1..51d9907e 100644 --- a/_locales/tr/messages.json +++ b/_locales/tr/messages.json @@ -8,7 +8,7 @@ "description": "Label for the button to enable a style" }, "styleMissingName": { - "message": "Bir ad girin.", + "message": "Bir ad girin", "description": "Error displayed when user saves without providing a name" }, "appliesDomainOption": { diff --git a/_locales/zh/messages.json b/_locales/zh/messages.json index dee83899..ea30b3b7 100644 --- a/_locales/zh/messages.json +++ b/_locales/zh/messages.json @@ -8,7 +8,7 @@ "description": "Label for the button to enable a style" }, "styleMissingName": { - "message": "请输入名称.", + "message": "请输入名称", "description": "Error displayed when user saves without providing a name" }, "appliesDomainOption": { diff --git a/_locales/zh_CN/messages.json b/_locales/zh_CN/messages.json index 9e7d9c25..72841ce5 100644 --- a/_locales/zh_CN/messages.json +++ b/_locales/zh_CN/messages.json @@ -48,7 +48,7 @@ "description": "Label for the button to enable a style" }, "styleMissingName": { - "message": "输入名称。", + "message": "输入名称", "description": "Error displayed when user saves without providing a name" }, "genericHistoryLabel": { diff --git a/_locales/zh_TW/messages.json b/_locales/zh_TW/messages.json index 33a40331..022d830e 100644 --- a/_locales/zh_TW/messages.json +++ b/_locales/zh_TW/messages.json @@ -31,6 +31,14 @@ "message": "導出", "description": "Label for the button to export a style ('edit' page) or all styles ('manage' page)" }, + "installButton": { + "message": "安裝", + "description": "Label for install button" + }, + "styleMetaErrorCheckbox": { + "message": "無效的 @var 勾選框:值必須為 0 或 1", + "description": "Error displayed when the value of @var checkbox is invalid" + }, "linterJSONError": { "message": "無效的 JSON 格式", "description": "Setting linter config with invalid JSON" @@ -52,7 +60,7 @@ "description": "Label for the button to enable a style" }, "styleMissingName": { - "message": "請輸入名稱。", + "message": "輸入名稱", "description": "Error displayed when user saves without providing a name" }, "genericHistoryLabel": { @@ -83,6 +91,10 @@ "message": "暗色瀏覽器主題", "description": "" }, + "styleFromMozillaFormatError": { + "message": "從 Mozilla 格式匯入失敗", + "description": "Label for the import error" + }, "importAppendLabel": { "message": "追加到樣式", "description": "Label for the button to import a style and append to the existing sections" @@ -123,6 +135,10 @@ "message": "灰階淡出", "description": "Label for the checkbox that toggles grayed out mode of applies-to favicons in the new UI on manage page" }, + "versionInvalidOlder": { + "message": "版本舊於已安裝的樣式。", + "description": "Displayed when the version of style is older than the installed one" + }, "confirmYes": { "message": "是", "description": "'Yes' button in a confirm dialog" @@ -175,10 +191,18 @@ "message": "刪除", "description": "" }, + "confirmDefault": { + "message": "使用預設值", + "description": "'Set to default' button in a confirm dialog" + }, "confirmCancel": { "message": "取消", "description": "" }, + "cm_autoCloseBracketsTooltip": { + "message": "當輸入開放的 ()[]{}''\"\" 時自動新增另一邊的標點符號", + "description": "Label for the checkbox in the style editor." + }, "retrieveBckp": { "message": "匯入樣式", "description": "" @@ -236,6 +260,15 @@ "message": "僅本機建立的樣式", "description": "Checkbox to show only locally created styles i.e. non-updatable" }, + "styleMetaErrorPreprocessor": { + "message": "不支援的 @preprocessor:$preprocessor$", + "description": "Error displayed when the value of @preprocessor is not supported", + "placeholders": { + "preprocessor": { + "content": "$1" + } + } + }, "linterIssuesHelp": { "message": "這些問題被 $link$ 找到了:", "description": "Help popup message for the selected CSS linter issues block on the style edit page", @@ -245,6 +278,10 @@ } } }, + "parseUsercssError": { + "message": "Stylus 解析 usercss 失敗:", + "description": "The error message to show when stylus failed to parse usercss" + }, "searchStyles": { "message": "搜索內容", "description": "Label for the search filter textbox on the Manage styles page" @@ -257,6 +294,10 @@ "message": "再次檢查,我沒有編輯任何樣式!", "description": "Label for the button to apply all detected updates" }, + "liveReloadLabel": { + "message": "即時重新整理", + "description": "The label of live-reload feature" + }, "unreachableFileHint": { "message": "Stylus 僅在您於 chrome://extensions 啟用了 Stylus 擴充套件中對應的勾選框時才能存取 file:// 的 URL。", "description": "Note in the toolbar popup for file:// URLs" @@ -329,6 +370,10 @@ "message": "正規表示式無效。", "description": "Validation message for a bad regexp in a style" }, + "license": { + "message": "授權條款", + "description": "Label for the license" + }, "optionsHeading": { "message": "選項", "description": "Heading for options section on manage page." @@ -371,6 +416,10 @@ "message": "已跳過無效的", "description": "Text after the number of styles skipped due to being invalid (not a Stylus/Stylish backup file probably) in the report shown after importing styles" }, + "optionsAdvancedNewStyleAsUsercss": { + "message": "以 usercss 編寫新樣式", + "description": "" + }, "genericResetLabel": { "message": "重設", "description": "Used in various parts of UI to indicate that something may be reset to its original state" @@ -400,6 +449,10 @@ "message": "使用/re/句法正則表達式搜索", "description": "Label after the search input field in the editor shown on Ctrl-F" }, + "popupBordersTooltip": { + "message": "對新 Chrome 中的暗色主題很有用,因為其不再繪製邊框", + "description": "" + }, "updateCheckManualUpdateHint": { "message": "強制更新覆蓋任何本機編輯。", "description": "Additional text displayed when an update check skipped updating the style to avoid losing local modifications" @@ -412,6 +465,10 @@ "message": "棄用當前樣式內容并用導入樣式覆蓋", "description": "Label for the button to import and overwrite current style" }, + "installUpdateFromLabel": { + "message": "檢查更新", + "description": "Label for the checkbox to save current URL for update check" + }, "cm_resizeGripHint": { "message": "雙擊以最大化/復原高度", "description": "Tooltip for the resize grip in style editor" @@ -444,6 +501,10 @@ "message": "Mozilla格式樣式表", "description": "Title of the popup with the style code in Mozilla format, shown after pressing the Export button on Edit style page" }, + "cm_colorpicker": { + "message": "用於 CSS 色彩的顏色挑選器", + "description": "Label for the checkbox controlling colorpicker option for the style editor." + }, "writeStyleFor": { "message": "編寫樣式給:", "description": "Label for toolbar pop-up that precedes the links to write a new style" @@ -545,6 +606,10 @@ "message": "禁用所有樣式", "description": "Label for the checkbox that turns all enabled styles off." }, + "appliesLineWidgetLabel": { + "message": "顯示「套用至」資訊", + "description": "Label for the checkbox to display applies-to information in the single editor" + }, "updateCheckSkippedMaybeLocallyEdited": { "message": "這個樣式可能在本機被編輯過。", "description": "Text that displays when an update check skipped updating the style to avoid losing possible local modifications" @@ -585,6 +650,21 @@ "message": "Stylus 使用外部服務 https://www.google.com/s2/favicons", "description": "Label for the checkbox that toggles applies-to favicons in the new UI on manage page" }, + "styleInstallOverwrite": { + "message": "「$stylename$」已安裝。要覆寫嗎?\n版本:$oldVersion$→$newVersion$", + "description": "Confirmation when re-installing a style", + "placeholders": { + "stylename": { + "content": "$1" + }, + "newVersion": { + "content": "$3" + }, + "oldVersion": { + "content": "$2" + } + } + }, "updateCheckSkippedLocallyEdited": { "message": "這個樣式已在本機編輯。", "description": "Text that displays when an update check skipped updating the style to avoid losing local modifications" @@ -593,6 +673,10 @@ "message": "見完整的規則清單", "description": "Stylelint or CSSLint rules label added immediately before a link" }, + "styleUpdateDiscardChanges": { + "message": "樣式已在編輯器外變更。您想要重新載入樣式嗎?", + "description": "Confirmation to update the style in the editor" + }, "optionsResetButton": { "message": "重設選項", "description": "" @@ -601,6 +685,10 @@ "message": "代碼", "description": "Label for the code for a section" }, + "externalUsercssDocument": { + "message": "Usercss 的文件", + "description": "Label for the external link to usercss documentation" + }, "optionsAdvancedContextDelete": { "message": "在編輯器的右鍵選單中加入「刪除」", "description": "" @@ -614,6 +702,10 @@ } } }, + "configureStyle": { + "message": "設定", + "description": "Label for the button to configure userstyle" + }, "importReportLegendUpdatedBoth": { "message": "後設資訊與程式碼均已更新", "description": "Text after the number of styles updated entirely in the report shown after importing styles" @@ -642,6 +734,32 @@ "message": "在輸入時自動完成", "description": "Label for the checkbox in the style editor." }, + "linterCSSLintIncompatible": { + "message": "CSSLint 不支援 $preprocessorname$ 預處理器", + "description": "The label to display when the preprocessor isn't compatible with CSSLint", + "placeholders": { + "preprocessorname": { + "content": "$1" + } + } + }, + "styleMetaErrorSelectValueMismatch": { + "message": "無效的 @select:值不存在於清單中", + "description": "Error displayed when the value of @select is invalid" + }, + "styleMetaErrorColor": { + "message": "$color$是無效的顏色", + "description": "Error displayed when the value of @var color is invalid", + "placeholders": { + "color": { + "content": "$1" + } + } + }, + "externalFeedback": { + "message": "回饋", + "description": "Label for the external link to send feedback for the style" + }, "manageOnlyDisabled": { "message": "僅已停用的樣式", "description": "Checkbox to show only disabled styles" @@ -666,6 +784,10 @@ "message": "Stylus 不能在諸如此類的網頁上生效。", "description": "Note in the toolbar pop-up when on a URL Stylus can't affect" }, + "popupBorders": { + "message": "在邊邊新增白色邊框", + "description": "" + }, "manageOnlyUpdates": { "message": "僅有更新或是有問題的", "description": "Checkbox to show only styles that have updates after check-all-styles-for-updates was performed" @@ -674,6 +796,14 @@ "message": "添加樣式", "description": "Title of the page for adding styles" }, + "externalLink": { + "message": "外部連結", + "description": "Label for external links" + }, + "externalHomepage": { + "message": "首頁", + "description": "Label for the external link to style's homepage" + }, "importReplaceLabel": { "message": "覆蓋樣式", "description": "Label for the button to import and overwrite current style" @@ -690,6 +820,10 @@ "message": "進階", "description": "" }, + "alphaChannel": { + "message": "不透明度", + "description": "Label of color's opacity" + }, "importAppendTooltip": { "message": "追加導入的樣式到當前樣式", "description": "Tooltip for the button to import a style and append to the existing sections" @@ -742,10 +876,23 @@ "message": "選項介面", "description": "Go to Options UI" }, + "colorpickerTooltip": { + "message": "開啟顏色挑選器", + "description": "Tooltip for the colored squares shown before CSS colors in the style editor." + }, "optionsCustomizeBadge": { "message": "在工具列圖示上的徽章", "description": "" }, + "installUpdateFrom": { + "message": "目前從 $url$ 更新樣式", + "description": "Label to describe where the style gets update", + "placeholders": { + "url": { + "content": "$1" + } + } + }, "importReportLegendIdentical": { "message": "已跳過相同的", "description": "Text after the number of styles skipped due to being identical to the already installed ones in the report shown after importing styles" @@ -754,6 +901,14 @@ "message": "彈出視窗寬度(以像素計)", "description": "" }, + "cm_autoCloseBrackets": { + "message": "自動關閉括號與引號", + "description": "Label for the checkbox in the style editor." + }, + "installButtonReinstall": { + "message": "重新安裝", + "description": "Label for reinstall button" + }, "linterInvalidConfigError": { "message": "因為無效的設定所以未儲存:", "description": "Invalid linter config will show a message followed by a list of invalid entries" @@ -762,6 +917,19 @@ "message": "否", "description": "'No' button in a confirm dialog" }, + "styleMissingMeta": { + "message": "遺失詮釋資料 @ $key$", + "description": "Error displayed when a mandatory metadata is missing", + "placeholders": { + "key": { + "content": "$1" + } + } + }, + "appliesLineWidgetWarning": { + "message": "無法與最小化的 CSS 一起運作", + "description": "A warning that applies-to information won't show properly with minified CSS" + }, "undo": { "message": "撤銷", "description": "Button label" @@ -770,6 +938,14 @@ "message": "鍵盤映射", "description": "Label for the drop-down list controlling the keymap for the style editor." }, + "externalSupport": { + "message": "支援", + "description": "Label for the external link to style's support site" + }, + "confirmSave": { + "message": "儲存", + "description": "'Save' button in a confirm dialog" + }, "manageNewUI": { "message": "新的管理介面佈局", "description": "Label for the checkbox that toggles the new UI on manage page" @@ -790,6 +966,10 @@ "message": "替換為", "description": "Label before the replace-with input field in the editor shown on Ctrl-H etc." }, + "liveReloadError": { + "message": "觀看檔案時發生錯誤", + "description": "The label of live-reload error" + }, "deleteStyleLabel": { "message": "删除", "description": "Label for the button to delete a style" @@ -798,6 +978,15 @@ "message": "安裝更新(本機編輯將會被覆寫)", "description": "Additional text displayed when an update check skipped updating the style to avoid losing local modifications" }, + "styleInstallFailed": { + "message": "安裝使用者樣式失敗!\n$error$", + "description": "Warning when installation failed", + "placeholders": { + "error": { + "content": "$1" + } + } + }, "optionsAdvancedExposeIframes": { "message": "透過 HTML[stylus-iframe] 公開 iframes", "description": "" @@ -810,6 +999,10 @@ "message": "要停用自動化使用者樣式更新檢查,設定間隔為 0", "description": "" }, + "installButtonUpdate": { + "message": "更新", + "description": "Label for update button" + }, "backupButtons": { "message": "備份", "description": "Heading for backup" @@ -822,6 +1015,14 @@ "message": "編輯", "description": "Label for the button to go to the edit style page" }, + "installButtonInstalled": { + "message": "已安裝", + "description": "Text displayed when the style is successfully installed" + }, + "author": { + "message": "作者", + "description": "Label for the style author" + }, "cm_theme": { "message": "主題", "description": "Label for the style editor's CSS theme." @@ -830,6 +1031,10 @@ "message": "在新視窗開啟編輯器", "description": "Label for the checkbox controlling 'edit' action behavior in the popup." }, + "appliesRemoveError": { + "message": "無法移除最後的「套用到」項目", + "description": "Error displayed when the last 'applies' is going to be removed" + }, "backupMessage": { "message": "選取檔案並拖曳到此頁面。", "description": "Message for backup" @@ -849,5 +1054,9 @@ "description": { "message": "用Stylus(一個用戶樣式管理器)重塑網頁。 Stylus 讓你能為诸多主流網站輕鬆的安裝主題和皮膚。", "description": "Extension description" + }, + "confirmClose": { + "message": "關閉", + "description": "'Close' button in a confirm dialog" } } \ No newline at end of file diff --git a/background/background.js b/background/background.js index 60942b61..2dfe2054 100644 --- a/background/background.js +++ b/background/background.js @@ -28,16 +28,33 @@ chrome.runtime.onMessage.addListener(onRuntimeMessage); chrome.webNavigation.onReferenceFragmentUpdated.addListener(data => listener('styleReplaceAll', data)); + + if (FIREFOX) { + // FF applies page CSP even to content scripts, https://bugzil.la/1267027 + chrome.webNavigation.onCommitted.addListener(webNavUsercssInstallerFF, { + url: [ + {urlPrefix: 'https://raw.githubusercontent.com/', urlSuffix: '.user.css'}, + {urlPrefix: 'https://raw.githubusercontent.com/', urlSuffix: '.user.styl'}, + ] + }); + } } -chrome.contextMenus.onClicked.addListener((info, tab) => - contextMenus[info.menuItemId].click(info, tab)); +if (chrome.contextMenus) { + chrome.contextMenus.onClicked.addListener((info, tab) => + contextMenus[info.menuItemId].click(info, tab)); +} -if ('commands' in chrome) { +if (chrome.commands) { // Not available in Firefox - https://bugzilla.mozilla.org/show_bug.cgi?id=1240350 chrome.commands.onCommand.addListener(command => browserCommands[command]()); } +if (!chrome.browserAction || + !['setIcon', 'setBadgeBackgroundColor', 'setBadgeText'].every(name => chrome.browserAction[name])) { + window.updateIcon = () => {}; +} + // ************************************************************************* // set the default icon displayed after a tab is created until webNavigation kicks in prefs.subscribe(['iconset'], () => updateIcon({id: undefined}, {})); @@ -50,9 +67,13 @@ prefs.subscribe(['iconset'], () => updateIcon({id: undefined}, {})); // Open FAQs page once after installation to guide new users. // Do not display it in development mode. if (reason === 'install' && manifest.update_url) { - setTimeout(openURL, 100, { - url: 'http://add0n.com/stylus.html' - }); + // don't hardcode homepage URL, extract it from "Get Help" label translation + // TODO: add a built-in tour page in the extension + const getHelpHtml = chrome.i18n.getMessage('manageText').match(/]+/g); + const url = (getHelpHtml[1] || '').replace(/^.+?=\s*/, '').replace(/^['"]|["']$/g, ''); + if (url) { + setTimeout(openURL, 100, {url}); + } } // reset L10N cache on update if (reason === 'update') { @@ -79,7 +100,7 @@ browserCommands = { // ************************************************************************* // context menus -contextMenus = Object.assign({ +contextMenus = { 'show-badge': { title: 'menuShowBadge', click: info => prefs.set(info.menuItemId, info.checked), @@ -92,22 +113,27 @@ contextMenus = Object.assign({ title: 'openStylesManager', click: browserCommands.openManage, }, -}, !FIREFOX && prefs.get('editor.contextDelete') && { 'editor.contextDelete': { + presentIf: () => !FIREFOX && prefs.get('editor.contextDelete'), title: 'editDeleteText', type: 'normal', contexts: ['editable'], documentUrlPatterns: [URLS.ownOrigin + 'edit*'], click: (info, tab) => { - chrome.tabs.sendMessage(tab.id, {method: 'editDeleteText'}); + sendMessage({tabId: tab.id, method: 'editDeleteText'}); }, } -}); +}; -{ - const createContextMenus = (ids = Object.keys(contextMenus)) => { +if (chrome.contextMenus) { + const createContextMenus = ids => { for (const id of ids) { - const item = Object.assign({id}, contextMenus[id]); + let item = contextMenus[id]; + if (item.presentIf && !item.presentIf()) { + continue; + } + item = Object.assign({id}, item); + delete item.presentIf; const prefValue = prefs.readOnlyValues[id]; item.title = chrome.i18n.getMessage(item.title); if (!item.type && typeof prefValue === 'boolean') { @@ -121,20 +147,20 @@ contextMenus = Object.assign({ chrome.contextMenus.create(item, ignoreChromeError); } }; - createContextMenus(); - const toggleableIds = Object.keys(contextMenus).filter(key => - typeof prefs.readOnlyValues[key] === 'boolean'); - prefs.subscribe(toggleableIds, (id, checked) => { - if (id === 'editor.contextDelete') { - if (checked) { - createContextMenus([id]); - } else { - chrome.contextMenus.remove(id, ignoreChromeError); - } + const toggleCheckmark = (id, checked) => { + chrome.contextMenus.update(id, {checked}, ignoreChromeError); + }; + const togglePresence = (id, checked) => { + if (checked) { + createContextMenus([id]); } else { - chrome.contextMenus.update(id, {checked}, ignoreChromeError); + chrome.contextMenus.remove(id, ignoreChromeError); } - }); + }; + const keys = Object.keys(contextMenus); + prefs.subscribe(keys.filter(id => typeof prefs.readOnlyValues[id] === 'boolean'), toggleCheckmark); + prefs.subscribe(keys.filter(id => contextMenus[id].presentIf), togglePresence); + createContextMenus(keys); } // ************************************************************************* @@ -145,7 +171,6 @@ window.addEventListener('storageReady', function _() { updateIcon({id: undefined}, {}); const NTP = 'chrome://newtab/'; - const PING = {method: 'ping'}; const ALL_URLS = ''; const contentScripts = chrome.runtime.getManifest().content_scripts; // expand * as .*? @@ -168,15 +193,11 @@ window.addEventListener('storageReady', function _() { }; const pingCS = (cs, {id, url}) => { + const maybeInject = pong => !pong && injectCS(cs, id); cs.matches.some(match => { - if ((match === ALL_URLS || url.match(match)) - && (!url.startsWith('chrome') || url === NTP)) { - chrome.tabs.sendMessage(id, PING, pong => { - if (!pong) { - injectCS(cs, id); - } - ignoreChromeError(); - }); + if ((match === ALL_URLS || url.match(match)) && + (!url.startsWith('chrome') || url === NTP)) { + sendMessage({method: 'ping', tabId: id}, maybeInject); return true; } }); @@ -200,13 +221,13 @@ function webNavigationListener(method, {url, tabId, frameId}) { if (method === 'styleApply') { handleCssTransitionBug({tabId, frameId, url, styles}); } - chrome.tabs.sendMessage(tabId, { + sendMessage({ + tabId, + frameId, method, // ping own page so it retrieves the styles directly styles: url.startsWith(URLS.ownOrigin) ? 'DIY' : styles, - }, { - frameId - }, ignoreChromeError); + }); } // main page frame id is 0 if (frameId === 0) { @@ -234,6 +255,21 @@ function webNavigationListenerChrome(method, data) { } +function webNavUsercssInstallerFF(data) { + const {tabId} = data; + Promise.all([ + sendMessage({tabId, method: 'ping'}), + // we need tab index to open the installer next to the original one + // and also to skip the double-invocation in FF which assigns tab url later + getTab(tabId), + ]).then(([pong, tab]) => { + if (pong !== true && tab.url !== 'about:blank') { + usercssHelper.openInstallPage(tab, {direct: true}); + } + }); +} + + function updateIcon(tab, styles) { if (tab.id < 0) { return; @@ -281,20 +317,28 @@ function updateIcon(tab, styles) { } // Vivaldi bug workaround: setBadgeText must follow setBadgeBackgroundColor chrome.browserAction.setBadgeBackgroundColor({color}); - getTab(tab.id).then(realTab => { - // skip pre-rendered tabs - if (realTab.index >= 0) { - chrome.browserAction.setBadgeText({text, tabId: tab.id}); - } + setTimeout(() => { + getTab(tab.id).then(realTab => { + // skip pre-rendered tabs + if (realTab.index >= 0) { + chrome.browserAction.setBadgeText({text, tabId: tab.id}); + } + }); }); }); } } -function onRuntimeMessage(request, sender, sendResponse) { - // prevent browser exception bug on sending a response to a closed tab - sendResponse = (send => data => tryCatch(send, data))(sendResponse); +function onRuntimeMessage(request, sender, sendResponseInternal) { + const sendResponse = data => { + // wrap Error object instance as {__ERROR__: message} - will be unwrapped in sendMessage + if (data instanceof Error) { + data = {__ERROR__: data.message}; + } + // prevent browser exception bug on sending a response to a closed tab + tryCatch(sendResponseInternal, data); + }; switch (request.method) { case 'getStyles': getStyles(request).then(sendResponse); @@ -333,7 +377,11 @@ function onRuntimeMessage(request, sender, sendResponse) { return KEEP_CHANNEL_OPEN; case 'closeTab': - closeTab(sender.tab.id, request).then(sendResponse); + chrome.tabs.remove(request.tabId || sender.tab.id, () => { + if (chrome.runtime.lastError && request.tabId !== sender.tab.id) { + sendResponse(new Error(chrome.runtime.lastError.message)); + } + }); return KEEP_CHANNEL_OPEN; case 'openEditor': @@ -341,22 +389,3 @@ function onRuntimeMessage(request, sender, sendResponse) { return; } } - -function closeTab(tabId, request) { - return new Promise(resolve => { - if (request.tabId) { - tabId = request.tabId; - } - chrome.tabs.remove(tabId, () => { - const {lastError} = chrome.runtime; - if (lastError) { - resolve({ - success: false, - error: lastError.message || String(lastError) - }); - return; - } - resolve({success: true}); - }); - }); -} diff --git a/background/storage.js b/background/storage.js index c34f4bee..eee6a011 100644 --- a/background/storage.js +++ b/background/storage.js @@ -203,12 +203,18 @@ function dbExecChromeStorage(method, data) { case 'getAll': return chromeLocal.get(null).then(storage => { const styles = []; + const leftovers = []; for (const key in storage) { if (key.startsWith(STYLE_KEY_PREFIX) && Number(key.substr(STYLE_KEY_PREFIX.length))) { styles.push(storage[key]); + } else if (key.startsWith('tempUsercssCode')) { + leftovers.push(key); } } + if (leftovers.length) { + chromeLocal.remove(leftovers); + } return {target: {result: styles}}; }); } @@ -389,7 +395,7 @@ function saveStyle(style) { .then(decide); function maybeCalcDigest() { - if (reason === 'update' || reason === 'update-digest') { + if (['install', 'update', 'update-digest'].includes(reason)) { return calcStyleDigest(style).then(digest => { style.originalDigest = digest; }); @@ -418,7 +424,7 @@ function saveStyle(style) { return style; } codeIsUpdated = !existed || 'sections' in style && !styleSectionsEqual(style, oldStyle); - style = Object.assign({}, oldStyle, style); + style = Object.assign({installDate: Date.now()}, oldStyle, style); return write(style, store); }); } else { diff --git a/background/update.js b/background/update.js index 36adcde7..e9018d55 100644 --- a/background/update.js +++ b/background/update.js @@ -127,6 +127,7 @@ var updater = { function maybeSave(json) { json.id = style.id; + json.updateDate = Date.now(); if (styleSectionsEqual(json, style)) { // JSONs may have different order of items even if sections are effectively equal // so we'll update the digest anyway diff --git a/background/usercss-helper.js b/background/usercss-helper.js index 1b4eb71e..4d5a4be9 100644 --- a/background/usercss-helper.js +++ b/background/usercss-helper.js @@ -1,4 +1,4 @@ -/* global usercss saveStyle getStyles */ +/* global usercss saveStyle getStyles chromeLocal */ 'use strict'; // eslint-disable-next-line no-var @@ -22,8 +22,8 @@ var usercssHelper = (() => { } function wrapReject(pending) { - return pending.then(result => ({success: true, result})) - .catch(err => ({success: false, result: err.message || String(err)})); + return pending + .catch(err => new Error(Array.isArray(err) ? err.join('\n') : err.message || String(err))); } // Parse the source and find the duplication @@ -78,16 +78,30 @@ var usercssHelper = (() => { ); } - function openInstallPage(tab, request) { - const url = '/install-usercss.html' + - '?updateUrl=' + encodeURIComponent(request.updateUrl) + - '&tabId=' + tab.id; + function openInstallPage(tab, {url = tab.url, direct} = {}) { + if (direct) { + prefetchCodeForInstallation(tab.id, url); + } return wrapReject(openURL({ - url, + url: '/install-usercss.html' + + '?updateUrl=' + encodeURIComponent(url) + + '&tabId=' + tab.id + + (direct ? '&direct=yes' : ''), index: tab.index + 1, openerTabId: tab.id, })); } + function prefetchCodeForInstallation(tabId, url) { + const key = 'tempUsercssCode' + tabId; + Promise.all([ + download(url), + chromeLocal.setValue(key, {loading: true}), + ]).then(([code]) => { + chromeLocal.setValue(key, code); + setTimeout(() => chromeLocal.remove(key), 60e3); + }); + } + return {build, save, findDup, openInstallPage}; })(); diff --git a/content/apply.js b/content/apply.js index 0d61e475..e2f52124 100644 --- a/content/apply.js +++ b/content/apply.js @@ -1,398 +1,498 @@ /* eslint no-var: 0 */ 'use strict'; -var ID_PREFIX = 'stylus-'; -var ROOT = document.documentElement; -var isOwnPage = location.protocol.endsWith('-extension:'); -var disableAll = false; -var exposeIframes = false; -var styleElements = new Map(); -var disabledElements = new Map(); -var retiredStyleTimers = new Map(); -var docRewriteObserver; -var docRootObserver; +(() => { + var ID_PREFIX = 'stylus-'; + var ROOT = document.documentElement; + var isOwnPage = location.protocol.endsWith('-extension:'); + var disableAll = false; + var exposeIframes = false; + var styleElements = new Map(); + var disabledElements = new Map(); + var retiredStyleTimers = new Map(); + var docRewriteObserver; + var docRootObserver; -requestStyles(); -chrome.runtime.onMessage.addListener(applyOnMessage); + requestStyles(); + chrome.runtime.onMessage.addListener(applyOnMessage); + window.applyOnMessage = applyOnMessage; -if (!isOwnPage) { - window.dispatchEvent(new CustomEvent(chrome.runtime.id)); - window.addEventListener(chrome.runtime.id, orphanCheck, true); -} - -function requestStyles(options, callback = applyStyles) { - if (!chrome.app && document instanceof XMLDocument) { - chrome.runtime.sendMessage({method: 'styleViaAPI', action: 'styleApply'}); - return; - } - var matchUrl = location.href; - if (!matchUrl.match(/^(http|file|chrome|ftp)/)) { - // dynamic about: and javascript: iframes don't have an URL yet - // so we'll try the parent frame which is guaranteed to have a real URL - try { - if (window !== parent) { - matchUrl = parent.location.href; - } - } catch (e) {} - } - const request = Object.assign({ - method: 'getStyles', - matchUrl, - enabled: true, - asHash: true, - }, options); - // On own pages we request the styles directly to minimize delay and flicker - if (typeof getStylesSafe === 'function') { - getStylesSafe(request).then(callback); - } else { - chrome.runtime.sendMessage(request, callback); - } -} - - -function applyOnMessage(request, sender, sendResponse) { - if (request.styles === 'DIY') { - // Do-It-Yourself tells our built-in pages to fetch the styles directly - // which is faster because IPC messaging JSON-ifies everything internally - requestStyles({}, styles => { - request.styles = styles; - applyOnMessage(request); - }); - return; + if (!isOwnPage) { + window.dispatchEvent(new CustomEvent(chrome.runtime.id)); + window.addEventListener(chrome.runtime.id, orphanCheck, true); } - if (!chrome.app && document instanceof XMLDocument && request.method !== 'ping') { - request.action = request.method; - request.method = 'styleViaAPI'; - request.styles = null; - if (request.style) { - request.style.sections = null; + function requestStyles(options, callback = applyStyles) { + if (!chrome.app && document instanceof XMLDocument) { + chrome.runtime.sendMessage({method: 'styleViaAPI', action: 'styleApply'}); + return; + } + var matchUrl = location.href; + if (!matchUrl.match(/^(http|file|chrome|ftp)/)) { + // dynamic about: and javascript: iframes don't have an URL yet + // so we'll try the parent frame which is guaranteed to have a real URL + try { + if (window !== parent) { + matchUrl = parent.location.href; + } + } catch (e) {} + } + const request = Object.assign({ + method: 'getStyles', + matchUrl, + enabled: true, + asHash: true, + }, options); + // On own pages we request the styles directly to minimize delay and flicker + if (typeof getStylesSafe === 'function') { + getStylesSafe(request).then(callback); + } else { + chrome.runtime.sendMessage(request, callback); } - chrome.runtime.sendMessage(request); - return; } - switch (request.method) { - case 'styleDeleted': - removeStyle(request); - break; - case 'styleUpdated': - if (request.codeIsUpdated === false) { - applyStyleState(request.style); + function applyOnMessage(request, sender, sendResponse) { + if (request.styles === 'DIY') { + // Do-It-Yourself tells our built-in pages to fetch the styles directly + // which is faster because IPC messaging JSON-ifies everything internally + requestStyles({}, styles => { + request.styles = styles; + applyOnMessage(request); + }); + return; + } + + if (!chrome.app && document instanceof XMLDocument && request.method !== 'ping') { + request.action = request.method; + request.method = 'styleViaAPI'; + request.styles = null; + if (request.style) { + request.style.sections = null; + } + chrome.runtime.sendMessage(request); + return; + } + + switch (request.method) { + case 'styleDeleted': + removeStyle(request); + break; + + case 'styleUpdated': + if (request.codeIsUpdated === false) { + applyStyleState(request.style); + break; + } + if (request.style.enabled) { + removeStyle({id: request.style.id, retire: true}); + requestStyles({id: request.style.id}); + } else { + removeStyle(request.style); + } + break; + + case 'styleAdded': + if (request.style.enabled) { + requestStyles({id: request.style.id}); + } + break; + + case 'styleApply': + applyStyles(request.styles); + break; + + case 'styleReplaceAll': + replaceAll(request.styles); + break; + + case 'prefChanged': + if ('disableAll' in request.prefs) { + doDisableAll(request.prefs.disableAll); + } + if ('exposeIframes' in request.prefs) { + doExposeIframes(request.prefs.exposeIframes); + } + break; + + case 'ping': + sendResponse(true); + break; + } + } + + + function doDisableAll(disable = disableAll) { + if (!disable === !disableAll) { + return; + } + disableAll = disable; + Array.prototype.forEach.call(document.styleSheets, stylesheet => { + if (stylesheet.ownerNode.matches(`style.stylus[id^="${ID_PREFIX}"]`) + && stylesheet.disabled !== disable) { + stylesheet.disabled = disable; + } + }); + } + + + function doExposeIframes(state = exposeIframes) { + if (state === exposeIframes || window === parent) { + return; + } + exposeIframes = state; + const attr = document.documentElement.getAttribute('stylus-iframe'); + if (state && attr !== '') { + document.documentElement.setAttribute('stylus-iframe', ''); + } else if (!state && attr === '') { + document.documentElement.removeAttribute('stylus-iframe'); + } + } + + + function applyStyleState({id, enabled}) { + const inCache = disabledElements.get(id) || styleElements.get(id); + const inDoc = document.getElementById(ID_PREFIX + id); + if (enabled) { + if (inDoc) { + return; + } else if (inCache) { + addStyleElement(inCache); + disabledElements.delete(id); + } else { + requestStyles({id}); + } + } else { + if (inDoc) { + disabledElements.set(id, inDoc); + docRootObserver.stop(); + inDoc.remove(); + docRootObserver.start(); + } + } + } + + + function removeStyle({id, retire = false}) { + const el = document.getElementById(ID_PREFIX + id); + if (el) { + if (retire) { + // to avoid page flicker when the style is updated + // instead of removing it immediately we rename its ID and queue it + // to be deleted in applyStyles after a new version is fetched and applied + const deadID = 'ghost-' + id; + el.id = ID_PREFIX + deadID; + // in case something went wrong and new style was never applied + retiredStyleTimers.set(deadID, setTimeout(removeStyle, 1000, {id: deadID})); + } else { + el.remove(); + } + } + styleElements.delete(ID_PREFIX + id); + disabledElements.delete(id); + retiredStyleTimers.delete(id); + } + + + function applyStyles(styles) { + if (!styles) { + // Chrome is starting up + requestStyles(); + return; + } + if ('disableAll' in styles) { + doDisableAll(styles.disableAll); + delete styles.disableAll; + } + if ('exposeIframes' in styles) { + doExposeIframes(styles.exposeIframes); + delete styles.exposeIframes; + } + + const gotNewStyles = Object.keys(styles).length || styles.needTransitionPatch; + if (gotNewStyles) { + if (docRootObserver) { + docRootObserver.stop(); + } else { + initDocRootObserver(); + } + } + + if (styles.needTransitionPatch) { + // CSS transition bug workaround: since we insert styles asynchronously, + // the browsers, especially Firefox, may apply all transitions on page load + delete styles.needTransitionPatch; + const className = chrome.runtime.id + '-transition-bug-fix'; + const docId = document.documentElement.id ? '#' + document.documentElement.id : ''; + document.documentElement.classList.add(className); + applySections(0, ` + ${docId}.${className}:root * { + transition: none !important; + } + `); + setTimeout(() => { + removeStyle({id: 0}); + document.documentElement.classList.remove(className); + }); + } + + if (gotNewStyles) { + for (const id in styles) { + applySections(id, styles[id].map(section => section.code).join('\n')); + } + docRootObserver.start({sort: true}); + } + + if (!isOwnPage && !docRewriteObserver && styleElements.size) { + initDocRewriteObserver(); + } + + if (retiredStyleTimers.size) { + setTimeout(() => { + for (const [id, timer] of retiredStyleTimers.entries()) { + removeStyle({id}); + clearTimeout(timer); + } + }); + } + } + + + function applySections(styleId, code) { + const id = ID_PREFIX + styleId; + let el = styleElements.get(id) || document.getElementById(id); + if (!el) { + if (document.documentElement instanceof SVGSVGElement) { + // SVG document style + el = document.createElementNS('http://www.w3.org/2000/svg', 'style'); + } else if (document instanceof XMLDocument) { + // XML document style + el = document.createElementNS('http://www.w3.org/1999/xhtml', 'style'); + } else { + // HTML document style; also works on HTML-embedded SVG + el = document.createElement('style'); + } + Object.assign(el, { + id, + type: 'text/css', + textContent: code, + }); + // SVG className is not a string, but an instance of SVGAnimatedString + el.classList.add('stylus'); + addStyleElement(el); + } + styleElements.set(id, el); + disabledElements.delete(Number(styleId)); + return el; + } + + + function addStyleElement(newElement) { + if (!ROOT) { + return; + } + let next; + const newStyleId = getStyleId(newElement); + for (const el of styleElements.values()) { + if (el.parentNode && !el.id.endsWith('-ghost') && getStyleId(el) > newStyleId) { + next = el.parentNode === ROOT ? el : null; break; } - if (request.style.enabled) { - removeStyle({id: request.style.id, retire: true}); - requestStyles({id: request.style.id}); - } else { - removeStyle(request.style); - } - break; - - case 'styleAdded': - if (request.style.enabled) { - requestStyles({id: request.style.id}); - } - break; - - case 'styleApply': - applyStyles(request.styles); - break; - - case 'styleReplaceAll': - replaceAll(request.styles); - break; - - case 'prefChanged': - if ('disableAll' in request.prefs) { - doDisableAll(request.prefs.disableAll); - } - if ('exposeIframes' in request.prefs) { - doExposeIframes(request.prefs.exposeIframes); - } - break; - - case 'ping': - sendResponse(true); - break; - } -} - - -function doDisableAll(disable = disableAll) { - if (!disable === !disableAll) { - return; - } - disableAll = disable; - Array.prototype.forEach.call(document.styleSheets, stylesheet => { - if (stylesheet.ownerNode.matches(`style.stylus[id^="${ID_PREFIX}"]`) - && stylesheet.disabled !== disable) { - stylesheet.disabled = disable; } - }); -} - - -function doExposeIframes(state = exposeIframes) { - if (state === exposeIframes || window === parent) { - return; - } - exposeIframes = state; - const attr = document.documentElement.getAttribute('stylus-iframe'); - if (state && attr !== '') { - document.documentElement.setAttribute('stylus-iframe', ''); - } else if (!state && attr === '') { - document.documentElement.removeAttribute('stylus-iframe'); - } -} - - -function applyStyleState({id, enabled}) { - const inCache = disabledElements.get(id) || styleElements.get(id); - const inDoc = document.getElementById(ID_PREFIX + id); - if (enabled) { - if (inDoc) { + if (next === newElement.nextElementSibling) { return; - } else if (inCache) { - addStyleElement(inCache); - disabledElements.delete(id); - } else { - requestStyles({id}); } - } else { - if (inDoc) { - disabledElements.set(id, inDoc); - inDoc.remove(); - } - } -} - - -function removeStyle({id, retire = false}) { - const el = document.getElementById(ID_PREFIX + id); - if (el) { - if (retire) { - // to avoid page flicker when the style is updated - // instead of removing it immediately we rename its ID and queue it - // to be deleted in applyStyles after a new version is fetched and applied - const deadID = 'ghost-' + id; - el.id = ID_PREFIX + deadID; - // in case something went wrong and new style was never applied - retiredStyleTimers.set(deadID, setTimeout(removeStyle, 1000, {id: deadID})); - } else { - el.remove(); - } - } - styleElements.delete(ID_PREFIX + id); - disabledElements.delete(id); - retiredStyleTimers.delete(id); -} - - -function applyStyles(styles) { - if (!styles) { - // Chrome is starting up - requestStyles(); - return; - } - if ('disableAll' in styles) { - doDisableAll(styles.disableAll); - delete styles.disableAll; - } - if ('exposeIframes' in styles) { - doExposeIframes(styles.exposeIframes); - delete styles.exposeIframes; - } - if (styles.needTransitionPatch) { - // CSS transition bug workaround: since we insert styles asynchronously, - // the browsers, especially Firefox, may apply all transitions on page load - delete styles.needTransitionPatch; - const className = chrome.runtime.id + '-transition-bug-fix'; - const docId = document.documentElement.id ? '#' + document.documentElement.id : ''; - document.documentElement.classList.add(className); - applySections(0, ` - ${docId}.${className}:root * { - transition: none !important; - } - `); - setTimeout(() => { - removeStyle({id: 0}); - document.documentElement.classList.remove(className); - }); - } - for (const id in styles) { - applySections(id, styles[id].map(section => section.code).join('\n')); - } - initDocRewriteObserver(); - initDocRootObserver(); - if (retiredStyleTimers.size) { - setTimeout(() => { - for (const [id, timer] of retiredStyleTimers.entries()) { - removeStyle({id}); - clearTimeout(timer); - } - }); - } -} - - -function applySections(styleId, code) { - let el = document.getElementById(ID_PREFIX + styleId); - if (el) { - return; - } - if (document.documentElement instanceof SVGSVGElement) { - // SVG document style - el = document.createElementNS('http://www.w3.org/2000/svg', 'style'); - } else if (document instanceof XMLDocument) { - // XML document style - el = document.createElementNS('http://www.w3.org/1999/xhtml', 'style'); - } else { - // HTML document style; also works on HTML-embedded SVG - el = document.createElement('style'); - } - Object.assign(el, { - id: ID_PREFIX + styleId, - type: 'text/css', - textContent: code, - }); - // SVG className is not a string, but an instance of SVGAnimatedString - el.classList.add('stylus'); - addStyleElement(el); - styleElements.set(el.id, el); - disabledElements.delete(Number(styleId)); - return el; -} - - -function addStyleElement(el) { - if (ROOT && !document.getElementById(el.id)) { - ROOT.appendChild(el); + docRootObserver.stop(); + ROOT.insertBefore(newElement, next || null); if (disableAll) { - el.disabled = true; + newElement.disabled = true; } + docRootObserver.start(); } -} -function replaceAll(newStyles) { - const oldStyles = Array.prototype.slice.call( - document.querySelectorAll(`style.stylus[id^="${ID_PREFIX}"]`)); - oldStyles.forEach(el => (el.id += '-ghost')); - styleElements.clear(); - disabledElements.clear(); - [...retiredStyleTimers.values()].forEach(clearTimeout); - retiredStyleTimers.clear(); - applyStyles(newStyles); - oldStyles.forEach(el => el.remove()); -} - - -function initDocRewriteObserver() { - if (isOwnPage || docRewriteObserver || !styleElements.size) { - return; + function replaceAll(newStyles) { + const oldStyles = Array.prototype.slice.call( + document.querySelectorAll(`style.stylus[id^="${ID_PREFIX}"]`)); + oldStyles.forEach(el => (el.id += '-ghost')); + styleElements.clear(); + disabledElements.clear(); + [...retiredStyleTimers.values()].forEach(clearTimeout); + retiredStyleTimers.clear(); + applyStyles(newStyles); + oldStyles.forEach(el => el.remove()); } - // re-add styles if we detect documentElement being recreated - const reinjectStyles = () => { - if (!styleElements) { - return orphanCheck && orphanCheck(); + + + function getStyleId(el) { + return parseInt(el.id.substr(ID_PREFIX.length)); + } + + + function orphanCheck() { + if (chrome.i18n && chrome.i18n.getUILanguage()) { + return true; } - ROOT = document.documentElement; - for (const el of styleElements.values()) { - el.textContent += ' '; // invalidate CSSOM cache - addStyleElement(document.importNode(el, true)); - } - }; - // detect documentElement being rewritten from inside the script - docRewriteObserver = new MutationObserver(mutations => { - for (let m = mutations.length; --m >= 0;) { - const added = mutations[m].addedNodes; - for (let n = added.length; --n >= 0;) { - if (added[n].localName === 'html') { - reinjectStyles(); - return; + // In Chrome content script is orphaned on an extension update/reload + // so we need to detach event listeners + [docRewriteObserver, docRootObserver].forEach(ob => ob && ob.takeRecords() && ob.disconnect()); + window.removeEventListener(chrome.runtime.id, orphanCheck, true); + } + + + function initDocRewriteObserver() { + // detect documentElement being rewritten from inside the script + docRewriteObserver = new MutationObserver(mutations => { + for (let m = mutations.length; --m >= 0;) { + const added = mutations[m].addedNodes; + for (let n = added.length; --n >= 0;) { + if (added[n].localName === 'html') { + reinjectStyles(); + return; + } } } - } - }); - docRewriteObserver.observe(document, {childList: true}); - // detect dynamic iframes rewritten after creation by the embedder i.e. externally - setTimeout(() => { - if (document.documentElement !== ROOT) { - reinjectStyles(); - } - }); -} - - -function initDocRootObserver() { - if (!styleElements.size || document.body || docRootObserver) { - return; - } - // wait for BODY and move all style elements after it - docRootObserver = new MutationObserver(() => { - let expectedPrevSibling = document.body || document.head; - if (!expectedPrevSibling) { - return; - } - docRootObserver.disconnect(); - for (const el of styleElements.values()) { - if (el.previousElementSibling !== expectedPrevSibling) { - ROOT.insertBefore(el, expectedPrevSibling.nextSibling); - if (el.disabled !== disableAll) { - // moving an element resets its 'disabled' state - el.disabled = disableAll; - } + }); + docRewriteObserver.observe(document, {childList: true}); + // detect dynamic iframes rewritten after creation by the embedder i.e. externally + setTimeout(() => { + if (document.documentElement !== ROOT) { + reinjectStyles(); } - expectedPrevSibling = el; + }); + // re-add styles if we detect documentElement being recreated + function reinjectStyles() { + if (!styleElements) { + orphanCheck(); + return; + } + ROOT = document.documentElement; + docRootObserver.stop(); + const imported = []; + for (const [id, el] of styleElements.entries()) { + const copy = document.importNode(el, true); + el.textContent += ' '; // invalidate CSSOM cache + imported.push([id, copy]); + addStyleElement(copy); + } + docRootObserver.start(); + styleElements = new Map(imported); } - if (document.body) { - docRootObserver = null; - } else { - docRootObserver.connect(); - } - }); - docRootObserver.connect = () => { - docRootObserver.observe(ROOT, {childList: true}); - }; - docRootObserver.connect(); -} - - -function orphanCheck() { - const port = chrome.runtime.connect(); - if (port) { - port.disconnect(); - return; } - // we're orphaned due to an extension update - // we can detach the mutation observer - [docRewriteObserver, docRootObserver].forEach(ob => ob && ob.disconnect()); - // we can detach event listeners - window.removeEventListener(chrome.runtime.id, orphanCheck, true); - // we can't detach chrome.runtime.onMessage because it's no longer connected internally - // we can destroy our globals in this context to free up memory - [ // functions - 'addStyleElement', - 'applyOnMessage', - 'applySections', - 'applyStyles', - 'applyStyleState', - 'doDisableAll', - 'initDocRewriteObserver', - 'initDocRootObserver', - 'orphanCheck', - 'removeStyle', - 'replaceAll', - 'requestStyles', - // variables - 'ROOT', - 'disabledElements', - 'retiredStyleTimers', - 'styleElements', - 'docRewriteObserver', - 'docRootObserver', - ].forEach(fn => (window[fn] = null)); -} + + function initDocRootObserver() { + let lastRestorationTime = 0; + let restorationCounter = 0; + let observing = false; + let sorting = false; + // allow any types of elements between ours, except for the following: + const ORDERED_TAGS = ['head', 'body', 'style', 'link']; + + init(); + return; + + function init() { + docRootObserver = new MutationObserver(sortStyleElements); + Object.assign(docRootObserver, {start, stop}); + } + function start({sort = false} = {}) { + if (sort && sortStyleMap()) { + sortStyleElements(); + } + if (!observing && ROOT) { + docRootObserver.observe(ROOT, {childList: true}); + observing = true; + } + } + function stop() { + if (observing) { + docRootObserver.disconnect(); + observing = false; + } + } + function sortStyleMap() { + const list = []; + let prevStyleId = 0; + let needsSorting = false; + for (const entry of styleElements.entries()) { + list.push(entry); + const el = entry[1]; + const styleId = getStyleId(el); + el.styleId = styleId; + needsSorting |= styleId < prevStyleId; + prevStyleId = styleId; + } + if (needsSorting) { + styleElements = new Map(list.sort((a, b) => a[1].styleId - b[1].styleId)); + return true; + } + } + function sortStyleElements() { + let expected = document.body || document.head; + if (!expected || sorting) { + return; + } + for (const el of styleElements.values()) { + if (!isMovable(el)) { + continue; + } + let prev = el.previousElementSibling; + while (prev !== expected) { + if (prev && isSkippable(prev)) { + expected = prev; + prev = prev.nextElementSibling; + } else if (!moveAfter(el, expected)) { + return; + } else { + break; + } + } + expected = el; + } + if (sorting) { + sorting = false; + docRootObserver.takeRecords(); + setTimeout(start); + //docRootObserver.start(); + } + } + function isMovable(el) { + return el.parentNode || !disabledElements.has(getStyleId(el)); + } + function isSkippable(el) { + return !ORDERED_TAGS.includes(el.localName) || + el.id.startsWith(ID_PREFIX) && + el.id.endsWith('-ghost') && + el.localName === 'style' && + el.className === 'stylus'; + } + function moveAfter(el, expected) { + if (!sorting) { + if (restorationLimitExceeded()) { + return false; + } + sorting = true; + docRootObserver.stop(); + } + expected.insertAdjacentElement('afterend', el); + if (el.disabled !== disableAll) { + // moving an element resets its 'disabled' state + el.disabled = disableAll; + } + return true; + } + function restorationLimitExceeded() { + const t = performance.now(); + if (t - lastRestorationTime > 1000) { + restorationCounter = 0; + } + lastRestorationTime = t; + if (++restorationCounter > 100) { + console.error('Stylus stopped restoring userstyle elements after 100 failed attempts.\n' + + 'Please report on https://github.com/openstyles/stylus/issues'); + return true; + } + } + } +})(); diff --git a/content/install-user-css.js b/content/install-hook-usercss.js similarity index 88% rename from content/install-user-css.js rename to content/install-hook-usercss.js index 150199c2..aa3a4d46 100644 --- a/content/install-user-css.js +++ b/content/install-hook-usercss.js @@ -1,4 +1,3 @@ -/* global runtimeSend */ 'use strict'; function createSourceLoader() { @@ -66,10 +65,6 @@ function initUsercssInstall() { let watcher; chrome.runtime.onConnect.addListener(port => { - // FIXME: is this the correct way to reject a connection? - // https://developer.chrome.com/extensions/messaging#connect - console.assert(port.name === 'usercss-install'); - port.onMessage.addListener(msg => { switch (msg.method) { case 'getSourceCode': @@ -95,16 +90,16 @@ function initUsercssInstall() { if (history.length > 1) { history.back(); } else { - runtimeSend({method: 'closeTab'}); + chrome.runtime.sendMessage({method: 'closeTab'}); } break; } }); }); - return runtimeSend({ + chrome.runtime.sendMessage({ method: 'openUsercssInstallPage', - updateUrl: location.href - }).catch(alert); + url: location.href, + }, r => r && r.__ERROR__ && alert(r.__ERROR__)); } function isUsercss() { diff --git a/content/install-hook-userstyles.js b/content/install-hook-userstyles.js new file mode 100644 index 00000000..a7c80dae --- /dev/null +++ b/content/install-hook-userstyles.js @@ -0,0 +1,369 @@ +'use strict'; + +(() => { + const FIREFOX = !chrome.app; + const VIVALDI = chrome.app && /Vivaldi/.test(navigator.userAgent); + const OPERA = chrome.app && /OPR/.test(navigator.userAgent); + + window.dispatchEvent(new CustomEvent(chrome.runtime.id + '-install')); + window.addEventListener(chrome.runtime.id + '-install', orphanCheck, true); + + ['Update', 'Install'].forEach(type => + ['', 'Chrome', 'Opera'].forEach(browser => + document.addEventListener('stylish' + type + browser, onClick))); + + chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { + // orphaned content script check + if (msg.method === 'ping') { + sendResponse(true); + } + }); + + new MutationObserver((mutations, observer) => { + if (document.body) { + observer.disconnect(); + // TODO: remove the following statement when USO pagination title is fixed + document.title = document.title.replace(/^(\d+)&\w+=/, '#$1: '); + chrome.runtime.sendMessage({ + method: 'getStyles', + url: getMeta('stylish-id-url') || location.href + }, checkUpdatability); + } + }).observe(document.documentElement, {childList: true}); + + /* since we are using "stylish-code-chrome" meta key on all browsers and + US.o does not provide "advanced settings" on this url if browser is not Chrome, + we need to fix this URL using "stylish-update-url" meta key + */ + function getStyleURL() { + const textUrl = getMeta('stylish-update-url') || ''; + const jsonUrl = getMeta('stylish-code-chrome') || + textUrl.replace(/styles\/(\d+)\/[^?]*/, 'styles/chrome/$1.json'); + const paramsMissing = !jsonUrl.includes('?') && textUrl.includes('?'); + return jsonUrl + (paramsMissing ? textUrl.replace(/^[^?]+/, '') : ''); + } + + function checkUpdatability([installedStyle]) { + // TODO: remove the following statement when USO is fixed + document.dispatchEvent(new CustomEvent('stylusFixBuggyUSOsettings', { + detail: installedStyle && installedStyle.updateUrl, + })); + if (!installedStyle) { + sendEvent('styleCanBeInstalledChrome'); + return; + } + const md5Url = getMeta('stylish-md5-url'); + if (md5Url && installedStyle.md5Url && installedStyle.originalMd5) { + getResource(md5Url).then(md5 => { + reportUpdatable(md5 !== installedStyle.originalMd5); + }); + } else { + getStyleJson().then(json => { + reportUpdatable(!json || + !styleSectionsEqual(json, installedStyle)); + }); + } + + function reportUpdatable(isUpdatable) { + sendEvent( + isUpdatable + ? 'styleCanBeUpdatedChrome' + : 'styleAlreadyInstalledChrome', + { + updateUrl: installedStyle.updateUrl + } + ); + } + } + + + function sendEvent(type, detail = null) { + if (FIREFOX) { + type = type.replace('Chrome', ''); + } else if (OPERA || VIVALDI) { + type = type.replace('Chrome', 'Opera'); + } + detail = {detail}; + if (typeof cloneInto !== 'undefined') { + // Firefox requires explicit cloning, however USO can't process our messages anyway + // because USO tries to use a global "event" variable deprecated in Firefox + detail = cloneInto(detail, document); // eslint-disable-line no-undef + } + onDOMready().then(() => { + document.dispatchEvent(new CustomEvent(type, detail)); + }); + } + + + function onClick(event) { + if (onClick.processing || !orphanCheck()) { + return; + } + onClick.processing = true; + (event.type.includes('Update') ? onUpdate() : onInstall()) + .then(done, done); + function done() { + setTimeout(() => { + onClick.processing = false; + }); + } + } + + + function onInstall() { + return getResource(getMeta('stylish-description')) + .then(name => saveStyleCode('styleInstall', name)) + .then(() => getResource(getMeta('stylish-install-ping-url-chrome'))); + } + + + function onUpdate() { + return new Promise((resolve, reject) => { + chrome.runtime.sendMessage({ + method: 'getStyles', + url: getMeta('stylish-id-url') || location.href, + }, ([style]) => { + saveStyleCode('styleUpdate', style.name, {id: style.id}) + .then(resolve, reject); + }); + }); + } + + + function saveStyleCode(message, name, addProps) { + return new Promise((resolve, reject) => { + const isNew = message === 'styleInstall'; + const needsConfirmation = isNew || !saveStyleCode.confirmed; + if (needsConfirmation && !confirm(chrome.i18n.getMessage(message, [name]))) { + reject(); + return; + } + saveStyleCode.confirmed = true; + enableUpdateButton(false); + getStyleJson().then(json => { + if (!json) { + prompt(chrome.i18n.getMessage('styleInstallFailed', ''), + 'https://github.com/openstyles/stylus/issues/195'); + return; + } + chrome.runtime.sendMessage( + Object.assign(json, addProps, { + method: 'saveStyle', + reason: isNew ? 'install' : 'update', + }), + style => { + if (!isNew && style.updateUrl.includes('?')) { + enableUpdateButton(true); + } else { + sendEvent('styleInstalledChrome'); + } + } + ); + resolve(); + }); + }); + + function enableUpdateButton(state) { + const important = s => s.replace(/;/g, '!important;'); + const button = document.getElementById('update_style_button'); + if (button) { + button.style.cssText = state ? '' : important('pointer-events: none; opacity: .35;'); + const icon = button.querySelector('img[src*=".svg"]'); + if (icon) { + icon.style.cssText = state ? '' : important('transition: transform 5s; transform: rotate(0);'); + if (state) { + setTimeout(() => (icon.style.cssText += important('transform: rotate(10turn);'))); + } + } + } + } + } + + + function getMeta(name) { + const e = document.querySelector(`link[rel="${name}"]`); + return e ? e.getAttribute('href') : null; + } + + + function getResource(url) { + return new Promise(resolve => { + if (url.startsWith('#')) { + resolve(document.getElementById(url.slice(1)).textContent); + } else { + chrome.runtime.sendMessage({method: 'download', url}, resolve); + } + }); + } + + + function getStyleJson() { + const url = getStyleURL(); + return getResource(url).then(code => { + try { + return JSON.parse(code); + } catch (e) { + return fetch(url).then(r => r.json()).catch(() => null); + } + }); + } + + + function styleSectionsEqual({sections: a}, {sections: b}) { + if (!a || !b) { + return undefined; + } + if (a.length !== b.length) { + return false; + } + // order of sections should be identical to account for the case of multiple + // sections matching the same URL because the order of rules is part of cascading + return a.every((sectionA, index) => propertiesEqual(sectionA, b[index])); + + function propertiesEqual(secA, secB) { + for (const name of ['urlPrefixes', 'urls', 'domains', 'regexps']) { + if (!equalOrEmpty(secA[name], secB[name], 'every', arrayMirrors)) { + return false; + } + } + return equalOrEmpty(secA.code, secB.code, 'substr', (a, b) => a === b); + } + + function equalOrEmpty(a, b, telltale, comparator) { + const typeA = a && typeof a[telltale] === 'function'; + const typeB = b && typeof b[telltale] === 'function'; + return ( + (a === null || a === undefined || (typeA && !a.length)) && + (b === null || b === undefined || (typeB && !b.length)) + ) || typeA && typeB && a.length === b.length && comparator(a, b); + } + + function arrayMirrors(array1, array2) { + return ( + array1.every(el => array2.includes(el)) && + array2.every(el => array1.includes(el)) + ); + } + } + + + function onDOMready() { + if (document.readyState !== 'loading') { + return Promise.resolve(); + } + return new Promise(resolve => { + document.addEventListener('DOMContentLoaded', function _() { + document.removeEventListener('DOMContentLoaded', _); + resolve(); + }); + }); + } + + + function orphanCheck() { + if (chrome.i18n && chrome.i18n.getUILanguage()) { + return true; + } + // In Chrome content script is orphaned on an extension update/reload + // so we need to detach event listeners + window.removeEventListener(chrome.runtime.id + '-install', orphanCheck, true); + ['Update', 'Install'].forEach(type => + ['', 'Chrome', 'Opera'].forEach(browser => + document.addEventListener('stylish' + type + browser, onClick))); + } +})(); + +// TODO: remove the following statement when USO is fixed +document.documentElement.appendChild(document.createElement('script')).text = '(' + + function () { + let settings; + const originalResponseJson = Response.prototype.json; + document.currentScript.remove(); + document.addEventListener('stylusFixBuggyUSOsettings', function _({detail}) { + document.removeEventListener('stylusFixBuggyUSOsettings', _); + // TODO: remove .replace(/^\?/, '') when minimum_chrome_version >= 52 (https://crbug.com/601425) + settings = /\?/.test(detail) && new URLSearchParams(new URL(detail).search.replace(/^\?/, '')); + if (!settings) { + Response.prototype.json = originalResponseJson; + } + }); + Response.prototype.json = function (...args) { + return originalResponseJson.call(this, ...args).then(json => { + if (!settings || typeof ((json || {}).style_settings || {}).every !== 'function') { + return json; + } + Response.prototype.json = originalResponseJson; + const images = new Map(); + for (const jsonSetting of json.style_settings) { + let value = settings.get('ik-' + jsonSetting.install_key); + if (!value + || !jsonSetting.style_setting_options + || !jsonSetting.style_setting_options[0]) { + continue; + } + if (value.startsWith('ik-')) { + value = value.replace(/^ik-/, ''); + const defaultItem = jsonSetting.style_setting_options.find(item => item.default); + if (!defaultItem || defaultItem.install_key !== value) { + if (defaultItem) { + defaultItem.default = false; + } + jsonSetting.style_setting_options.some(item => { + if (item.install_key === value) { + item.default = true; + return true; + } + }); + } + } else if (jsonSetting.setting_type === 'image') { + jsonSetting.style_setting_options.some(item => { + if (item.default) { + item.default = false; + return true; + } + }); + images.set(jsonSetting.install_key, value); + } else { + const item = jsonSetting.style_setting_options[0]; + if (item.value !== value && item.install_key === 'placeholder') { + item.value = value; + } + } + } + if (images.size) { + new MutationObserver((_, observer) => { + if (!document.getElementById('style-settings')) { + return; + } + observer.disconnect(); + for (const [name, url] of images.entries()) { + const elRadio = document.querySelector(`input[name="ik-${name}"][value="user-url"]`); + const elUrl = elRadio && document.getElementById(elRadio.id.replace('url-choice', 'user-url')); + if (elUrl) { + elUrl.value = url; + } + } + }).observe(document, {childList: true, subtree: true}); + } + return json; + }); + }; + } + ')()'; + +// TODO: remove the following statement when USO pagination is fixed +if (location.search.includes('category=')) { + document.addEventListener('DOMContentLoaded', function _() { + document.removeEventListener('DOMContentLoaded', _); + new MutationObserver((_, observer) => { + if (!document.getElementById('pagination')) { + return; + } + observer.disconnect(); + const category = '&' + location.search.match(/category=[^&]+/)[0]; + const links = document.querySelectorAll('#pagination a[href*="page="]:not([href*="category="])'); + for (let i = 0; i < links.length; i++) { + links[i].href += category; + } + }).observe(document, {childList: true, subtree: true}); + }); +} diff --git a/content/install.js b/content/install.js deleted file mode 100644 index 25bbd62b..00000000 --- a/content/install.js +++ /dev/null @@ -1,363 +0,0 @@ -'use strict'; - -const CHROMIUM = chrome.app && /Chromium/.test(navigator.userAgent); // non-Windows Chromium -const FIREFOX = !chrome.app; -const VIVALDI = chrome.app && /Vivaldi/.test(navigator.userAgent); -const OPERA = chrome.app && /OPR/.test(navigator.userAgent); - -document.addEventListener('stylishUpdate', onClick); -document.addEventListener('stylishUpdateChrome', onClick); -document.addEventListener('stylishUpdateOpera', onClick); - -document.addEventListener('stylishInstall', onClick); -document.addEventListener('stylishInstallChrome', onClick); -document.addEventListener('stylishInstallOpera', onClick); - -chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { - // orphaned content script check - if (msg.method === 'ping') { - sendResponse(true); - } -}); - -// TODO: remove the following statement when USO is fixed -document.documentElement.appendChild(document.createElement('script')).text = '(' + - function () { - let settings; - document.addEventListener('stylusFixBuggyUSOsettings', function _({detail}) { - document.removeEventListener('stylusFixBuggyUSOsettings', _); - settings = /\?/.test(detail) && new URLSearchParams(new URL(detail).search); - }); - const originalResponseJson = Response.prototype.json; - Response.prototype.json = function (...args) { - return originalResponseJson.call(this, ...args).then(json => { - Response.prototype.json = originalResponseJson; - if (!settings || typeof ((json || {}).style_settings || {}).every !== 'function') { - return json; - } - const images = new Map(); - for (const jsonSetting of json.style_settings) { - let value = settings.get('ik-' + jsonSetting.install_key); - if (!value - || !jsonSetting.style_setting_options - || !jsonSetting.style_setting_options[0]) { - continue; - } - if (value.startsWith('ik-')) { - value = value.replace(/^ik-/, ''); - const defaultItem = jsonSetting.style_setting_options.find(item => item.default); - if (!defaultItem || defaultItem.install_key !== value) { - if (defaultItem) { - defaultItem.default = false; - } - jsonSetting.style_setting_options.some(item => { - if (item.install_key === value) { - item.default = true; - return true; - } - }); - } - } else if (jsonSetting.setting_type === 'image') { - jsonSetting.style_setting_options.some(item => { - if (item.default) { - item.default = false; - return true; - } - }); - images.set(jsonSetting.install_key, value); - } else { - const item = jsonSetting.style_setting_options[0]; - if (item.value !== value && item.install_key === 'placeholder') { - item.value = value; - } - } - } - if (images.size) { - new MutationObserver((_, observer) => { - if (!document.getElementById('style-settings')) { - return; - } - observer.disconnect(); - for (const [name, url] of images.entries()) { - const elRadio = document.querySelector(`input[name="ik-${name}"][value="user-url"]`); - const elUrl = elRadio && document.getElementById(elRadio.id.replace('url-choice', 'user-url')); - if (elUrl) { - elUrl.value = url; - } - } - }).observe(document, {childList: true, subtree: true}); - } - return json; - }); - }; - } + ')()'; - -// TODO: remove the following statement when USO pagination is fixed -if (location.search.includes('category=')) { - document.addEventListener('DOMContentLoaded', function _() { - document.removeEventListener('DOMContentLoaded', _); - new MutationObserver((_, observer) => { - if (!document.getElementById('pagination')) { - return; - } - observer.disconnect(); - const category = '&' + location.search.match(/category=[^&]+/)[0]; - const links = document.querySelectorAll('#pagination a[href*="page="]:not([href*="category="])'); - for (let i = 0; i < links.length; i++) { - links[i].href += category; - } - }).observe(document, {childList: true, subtree: true}); - }); -} - -new MutationObserver((mutations, observer) => { - if (document.body) { - observer.disconnect(); - // TODO: remove the following statement when USO pagination title is fixed - document.title = document.title.replace(/^(\d+)&\w+=/, '#$1: '); - chrome.runtime.sendMessage({ - method: 'getStyles', - url: getMeta('stylish-id-url') || location.href - }, checkUpdatability); - } -}).observe(document.documentElement, {childList: true}); - -/* since we are using "stylish-code-chrome" meta key on all browsers and - US.o does not provide "advanced settings" on this url if browser is not Chrome, - we need to fix this URL using "stylish-update-url" meta key -*/ -function getStyleURL() { - const url = getMeta('stylish-code-chrome'); - // TODO: remove when USO is fixed - const directUrl = getMeta('stylish-update-url'); - if (directUrl.includes('?') && !url.includes('?')) { - /* get custom settings from the update url */ - return Object.assign(new URL(url), { - search: (new URL(directUrl)).search - }).href; - } - return url; -} - -function checkUpdatability([installedStyle]) { - // TODO: remove the following statement when USO is fixed - document.dispatchEvent(new CustomEvent('stylusFixBuggyUSOsettings', { - detail: installedStyle && installedStyle.updateUrl, - })); - if (!installedStyle) { - sendEvent('styleCanBeInstalledChrome'); - return; - } - const md5Url = getMeta('stylish-md5-url'); - if (md5Url && installedStyle.md5Url && installedStyle.originalMd5) { - getResource(md5Url).then(md5 => { - reportUpdatable(md5 !== installedStyle.originalMd5); - }); - } else { - getResource(getStyleURL()).then(code => { - reportUpdatable(code === null || - !styleSectionsEqual(JSON.parse(code), installedStyle)); - }); - } - - function reportUpdatable(isUpdatable) { - sendEvent( - isUpdatable - ? 'styleCanBeUpdatedChrome' - : 'styleAlreadyInstalledChrome', - { - updateUrl: installedStyle.updateUrl - } - ); - } -} - - -function sendEvent(type, detail = null) { - if (FIREFOX) { - type = type.replace('Chrome', ''); - } else if (OPERA || VIVALDI) { - type = type.replace('Chrome', 'Opera'); - } - detail = {detail}; - if (typeof cloneInto !== 'undefined') { - // Firefox requires explicit cloning, however USO can't process our messages anyway - // because USO tries to use a global "event" variable deprecated in Firefox - detail = cloneInto(detail, document); // eslint-disable-line no-undef - } - onDOMready().then(() => { - document.dispatchEvent(new CustomEvent(type, detail)); - }); -} - - -function onClick(event) { - if (onClick.processing || !orphanCheck || !orphanCheck()) { - return; - } - onClick.processing = true; - (event.type.includes('Update') ? onUpdate() : onInstall()) - .then(done, done); - function done() { - setTimeout(() => { - onClick.processing = false; - }); - } -} - - -function onInstall() { - return getResource(getMeta('stylish-description')) - .then(name => saveStyleCode('styleInstall', name)) - .then(() => getResource(getMeta('stylish-install-ping-url-chrome'))); -} - - -function onUpdate() { - return new Promise((resolve, reject) => { - chrome.runtime.sendMessage({ - method: 'getStyles', - url: getMeta('stylish-id-url') || location.href, - }, ([style]) => { - saveStyleCode('styleUpdate', style.name, {id: style.id}) - .then(resolve, reject); - }); - }); -} - - -function saveStyleCode(message, name, addProps) { - return new Promise((resolve, reject) => { - if (!confirm(chrome.i18n.getMessage(message, [name]))) { - reject(); - return; - } - enableUpdateButton(false); - getResource(getStyleURL()).then(code => { - chrome.runtime.sendMessage( - Object.assign(JSON.parse(code), addProps, { - method: 'saveStyle', - reason: 'update', - }), - style => { - if (message === 'styleUpdate' && style.updateUrl.includes('?')) { - enableUpdateButton(true); - } else { - sendEvent('styleInstalledChrome'); - } - } - ); - resolve(); - }); - }); - - function enableUpdateButton(state) { - const button = document.getElementById('update_style_button'); - if (button) { - button.style.cssText = state ? '' : - 'pointer-events: none !important; opacity: .25 !important;'; - } - } -} - - -function getMeta(name) { - const e = document.querySelector(`link[rel="${name}"]`); - return e ? e.getAttribute('href') : null; -} - - -function getResource(url) { - return new Promise(resolve => { - if (url.startsWith('#')) { - resolve(document.getElementById(url.slice(1)).textContent); - } else { - chrome.runtime.sendMessage({method: 'download', url}, resolve); - } - }); -} - - -function styleSectionsEqual({sections: a}, {sections: b}) { - if (!a || !b) { - return undefined; - } - if (a.length !== b.length) { - return false; - } - // order of sections should be identical to account for the case of multiple - // sections matching the same URL because the order of rules is part of cascading - return a.every((sectionA, index) => propertiesEqual(sectionA, b[index])); - - function propertiesEqual(secA, secB) { - for (const name of ['urlPrefixes', 'urls', 'domains', 'regexps']) { - if (!equalOrEmpty(secA[name], secB[name], 'every', arrayMirrors)) { - return false; - } - } - return equalOrEmpty(secA.code, secB.code, 'substr', (a, b) => a === b); - } - - function equalOrEmpty(a, b, telltale, comparator) { - const typeA = a && typeof a[telltale] === 'function'; - const typeB = b && typeof b[telltale] === 'function'; - return ( - (a === null || a === undefined || (typeA && !a.length)) && - (b === null || b === undefined || (typeB && !b.length)) - ) || typeA && typeB && a.length === b.length && comparator(a, b); - } - - function arrayMirrors(array1, array2) { - return ( - array1.every(el => array2.includes(el)) && - array2.every(el => array1.includes(el)) - ); - } -} - - -function onDOMready() { - if (document.readyState !== 'loading') { - return Promise.resolve(); - } - return new Promise(resolve => { - document.addEventListener('DOMContentLoaded', function _() { - document.removeEventListener('DOMContentLoaded', _); - resolve(); - }); - }); -} - - -function orphanCheck() { - const port = chrome.runtime.connect(); - if (port) { - port.disconnect(); - return true; - } - // we're orphaned due to an extension update - // we can detach event listeners - document.removeEventListener('stylishUpdate', onClick); - document.removeEventListener('stylishUpdateChrome', onClick); - document.removeEventListener('stylishUpdateOpera', onClick); - - document.removeEventListener('stylishInstall', onClick); - document.removeEventListener('stylishInstallChrome', onClick); - document.removeEventListener('stylishInstallOpera', onClick); - - // we can't detach chrome.runtime.onMessage because it's no longer connected internally - // we can destroy global functions in this context to free up memory - [ - 'checkUpdatability', - 'getMeta', - 'getResource', - 'onDOMready', - 'onClick', - 'onInstall', - 'onUpdate', - 'orphanCheck', - 'saveStyleCode', - 'sendEvent', - 'styleSectionsEqual', - ].forEach(fn => (window[fn] = null)); -} diff --git a/content/util.js b/content/util.js deleted file mode 100644 index 34160e87..00000000 --- a/content/util.js +++ /dev/null @@ -1,10 +0,0 @@ -'use strict'; - -function runtimeSend(request) { - return new Promise((resolve, reject) => { - chrome.runtime.sendMessage( - request, - ({success, result}) => (success ? resolve : reject)(result) - ); - }); -} diff --git a/edit.html b/edit.html index 6e20b003..ee6b2fa3 100644 --- a/edit.html +++ b/edit.html @@ -1,6 +1,7 @@ - + + @@ -86,10 +88,8 @@ @@ -138,7 +138,7 @@ @@ -150,7 +150,7 @@ - + @@ -173,13 +173,22 @@ +