Merge branch 'master' of https://github.com/openstyles/stylus into dev-refactor
This commit is contained in:
commit
f736ffa2fb
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
24
.github/CONTRIBUTING.md
vendored
24
.github/CONTRIBUTING.md
vendored
|
@ -4,7 +4,9 @@
|
|||
2. [How to report issues](#how-to-report-issues)
|
||||
3. [Adding translations](#adding-translations)
|
||||
4. [Pull requests](#pull-requests)
|
||||
5. [Contact us](#contact-us)
|
||||
5. [Scripts](#scripts)
|
||||
6. [Updating locale files](#updating-locale-files-admin-only)
|
||||
7. [Contact us](#contact-us)
|
||||
|
||||
## Getting involved
|
||||
|
||||
|
@ -32,6 +34,26 @@ You can help us translate the extension on [Transifex](https://www.transifex.com
|
|||
* Make any changes within a branch of this repository (not the `master` branch).
|
||||
* Submit a pull request and include a reference to the initial issue with the discussion.
|
||||
|
||||
## Scripts
|
||||
|
||||
* `npm run lint` - Run ESLint on all JavaScript files.
|
||||
* `npm run update` - Runs update-node & update-main scripts.
|
||||
* `npm run update-quick` - Updates development dependencies (uses `npm update`; does not include new dependencies).
|
||||
* `npm run update-locales` (admin only)- Updates locale files from Transifex. See the [updating locale files section](#updating-locale-files-admin-only) for more details.
|
||||
* `npm run update-main` - Runs update-versions & update-codemirror.
|
||||
* `npm run update-node` - Update development dependencies, removes & reinstalls `node_modules` folder (slow).
|
||||
* `npm run update-transifex` (admin only) - Upload `en/messages.json` source to Transifex.
|
||||
* `npm run update-vendor` - Update codemirror, codemirror themes & other vendor libraries.
|
||||
* `npm run update-versions` - Update version of `manifest.json` to match `package.json`.
|
||||
* `npm run zip` - Run update-versions, then compress required files into a zip file.
|
||||
|
||||
## Updating locale files (admin only)
|
||||
|
||||
* Make sure you have the Transifex client installed. Follow the instructions on [this page](https://docs.transifex.com/client/installing-the-client).
|
||||
* Contact another admin if you need the `.transifexrc` file in the root folder. It includes the API key to use Transifex's API.
|
||||
* Use `npm run update-locales` in the command line to [update the language files](https://docs.transifex.com/client/pull) in the repo.
|
||||
* Use `npm run update-transifex` in the command line to [upload the source](https://docs.transifex.com/client/push) `en/messages.json` file to Transifex.
|
||||
|
||||
## Contact us
|
||||
|
||||
If you prefer a more informal method of getting in touch or starting a conversation, please [join us on Discord](https://discordapp.com/widget?id=379521691774353408) or leave a comment in the [discussion section](https://add0n.com/stylus.html#reviews). We will monitor any discussions there and join in, and it may be a more appropriate venue for opinions and less urgent suggestions.
|
||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -6,3 +6,4 @@ package-lock.json
|
|||
yarn.lock
|
||||
*.zip
|
||||
.eslintcache
|
||||
.transifexrc
|
||||
|
|
10
.tx/config
Normal file
10
.tx/config
Normal file
|
@ -0,0 +1,10 @@
|
|||
[main]
|
||||
host = https://www.transifex.com
|
||||
|
||||
[Stylus.messages]
|
||||
file_filter = _locales/<lang>/messages.json
|
||||
minimum_perc = 0
|
||||
source_file = _locales/en/messages.json
|
||||
source_lang = en_US
|
||||
type = CHROME
|
||||
|
|
@ -258,11 +258,11 @@
|
|||
"filteredStyles": {
|
||||
"message": "zobrazeno $numShown$ z $numTotal$",
|
||||
"placeholders": {
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
},
|
||||
"numTotal": {
|
||||
"content": "$2"
|
||||
},
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -742,6 +742,9 @@
|
|||
"styleBeautifyIndentConditional": {
|
||||
"message": "Odsadit @media, @supports"
|
||||
},
|
||||
"styleBeautifyPreserveNewlines": {
|
||||
"message": "Zachovat nové řádky"
|
||||
},
|
||||
"styleCancelEditLabel": {
|
||||
"message": "Zpět ke správě"
|
||||
},
|
||||
|
@ -776,14 +779,14 @@
|
|||
"styleInstallOverwrite": {
|
||||
"message": "Styl „$stylename$“ je již nainstalován. Přepsat?\nVerze: $oldVersion$ → $newVersion$",
|
||||
"placeholders": {
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
},
|
||||
"newVersion": {
|
||||
"content": "$3"
|
||||
},
|
||||
"oldVersion": {
|
||||
"content": "$2"
|
||||
},
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -798,6 +801,14 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"styleMetaErrorRangeOrNumber": {
|
||||
"message": "Neplatná @var $type$: hodnota musí být pole obsahující alespoň jedno číslo na nulové pozici",
|
||||
"placeholders": {
|
||||
"type": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"styleMetaErrorPreprocessor": {
|
||||
"message": "Nepodporovaný @preprocessor: $preprocessor$",
|
||||
"placeholders": {
|
||||
|
@ -953,6 +964,9 @@
|
|||
"updatesCurrentlyInstalled": {
|
||||
"message": "Instalované aktualizace:"
|
||||
},
|
||||
"usercssAvoidOverwriting": {
|
||||
"message": "Prosím, změňte hodnotu @name nebo @namespace ať nedojde k přepsání existujícího stylu."
|
||||
},
|
||||
"usercssConfigIncomplete": {
|
||||
"message": "Styl byl aktualizován nebo smazán po zobrazení dialogu konfigurace. Tyto proměnné nebyly uloženy aby se předešlo poškození metadat stylu."
|
||||
},
|
||||
|
|
|
@ -246,11 +246,11 @@
|
|||
"filteredStyles": {
|
||||
"message": "$numShown$ von $numTotal$ gesamt",
|
||||
"placeholders": {
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
},
|
||||
"numTotal": {
|
||||
"content": "$2"
|
||||
},
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -776,14 +776,14 @@
|
|||
"styleInstallOverwrite": {
|
||||
"message": "\"$stylename$\" ist bereits installiert. Überschreiben?\nVersion: $oldVersion$ -> $newVersion$",
|
||||
"placeholders": {
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
},
|
||||
"newVersion": {
|
||||
"content": "$3"
|
||||
},
|
||||
"oldVersion": {
|
||||
"content": "$2"
|
||||
},
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -798,6 +798,14 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"styleMetaErrorRangeOrNumber": {
|
||||
"message": "@var $type$ ungültig: Wert muss ein Array sein, welches mindestens eine Zahl an Index 0 enthält",
|
||||
"placeholders": {
|
||||
"type": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"styleMetaErrorPreprocessor": {
|
||||
"message": "Nicht unterstützter @preprocessor: $preprocessor$",
|
||||
"placeholders": {
|
||||
|
|
|
@ -1430,5 +1430,38 @@
|
|||
"writeStyleForURL": {
|
||||
"message": "this URL",
|
||||
"description": "Text for link in toolbar pop-up to write a new style for the current URL"
|
||||
},
|
||||
"syncDropboxStyles": {
|
||||
"message": "Dropbox Export"
|
||||
},
|
||||
"retrieveDropboxSync": {
|
||||
"message": "Dropbox Import"
|
||||
},
|
||||
"overwriteFileExport": {
|
||||
"message": "Do you want to overwrite an existing file?"
|
||||
},
|
||||
"exportSavedSuccess": {
|
||||
"message": "File saved with success"
|
||||
},
|
||||
"noFileToImport": {
|
||||
"message": "To import your styles, you should export it first."
|
||||
},
|
||||
"connectingDropbox": {
|
||||
"message": "Connecting Dropbox..."
|
||||
},
|
||||
"gettingStyles": {
|
||||
"message": "Getting all styles..."
|
||||
},
|
||||
"zipStyles": {
|
||||
"message": "Zipping styles..."
|
||||
},
|
||||
"unzipStyles": {
|
||||
"message": "Unzipping styles..."
|
||||
},
|
||||
"readingStyles": {
|
||||
"message": "Reading styles..."
|
||||
},
|
||||
"uploadingFile": {
|
||||
"message": "Uploading File..."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -255,11 +255,11 @@
|
|||
"filteredStyles": {
|
||||
"message": "$numShown$ mostrados de $numTotal$ en total",
|
||||
"placeholders": {
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
},
|
||||
"numTotal": {
|
||||
"content": "$2"
|
||||
},
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -791,14 +791,14 @@
|
|||
"styleInstallOverwrite": {
|
||||
"message": "'$stylename$' ya está instalado ¿Sobrescribirlo?\nVersión: $oldVersion$ -> $newVersion$",
|
||||
"placeholders": {
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
},
|
||||
"newVersion": {
|
||||
"content": "$3"
|
||||
},
|
||||
"oldVersion": {
|
||||
"content": "$2"
|
||||
},
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -255,11 +255,11 @@
|
|||
"filteredStyles": {
|
||||
"message": "$numShown$/$numTotal$ kuvatud",
|
||||
"placeholders": {
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
},
|
||||
"numTotal": {
|
||||
"content": "$2"
|
||||
},
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -794,14 +794,14 @@
|
|||
"styleInstallOverwrite": {
|
||||
"message": "'$stylename$' on juba paigaldatud. Kas kirjutada üle?\nVersioon: $oldVersion$ -> $newVersion$",
|
||||
"placeholders": {
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
},
|
||||
"newVersion": {
|
||||
"content": "$3"
|
||||
},
|
||||
"oldVersion": {
|
||||
"content": "$2"
|
||||
},
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -258,11 +258,11 @@
|
|||
"filteredStyles": {
|
||||
"message": "$numShown$ montrés sur $numTotal$ au total",
|
||||
"placeholders": {
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
},
|
||||
"numTotal": {
|
||||
"content": "$2"
|
||||
},
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -785,14 +785,14 @@
|
|||
"styleInstallOverwrite": {
|
||||
"message": "\"$stylename$\" est déjà installé. L'écraser ?\nVersion : $oldVersion$ -> $newVersion$",
|
||||
"placeholders": {
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
},
|
||||
"newVersion": {
|
||||
"content": "$3"
|
||||
},
|
||||
"oldVersion": {
|
||||
"content": "$2"
|
||||
},
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
52
_locales/gl/messages.json
Normal file
52
_locales/gl/messages.json
Normal file
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"addStyleTitle": {
|
||||
"message": "Engadir Estilo"
|
||||
},
|
||||
"alphaChannel": {
|
||||
"message": "Opacidade"
|
||||
},
|
||||
"appliesAdd": {
|
||||
"message": "Engadir"
|
||||
},
|
||||
"appliesDisplay": {
|
||||
"message": "Aplica a: $applies$",
|
||||
"placeholders": {
|
||||
"applies": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"appliesDisplayTruncatedSuffix": {
|
||||
"message": "e mais"
|
||||
},
|
||||
"appliesDomainOption": {
|
||||
"message": "URLs no dominio"
|
||||
},
|
||||
"appliesLabel": {
|
||||
"message": "Aplica para"
|
||||
},
|
||||
"appliesLineWidgetWarning": {
|
||||
"message": "Non funciona con CSS minificado"
|
||||
},
|
||||
"appliesRegexpOption": {
|
||||
"message": "URLs que concorden co regexp"
|
||||
},
|
||||
"appliesRemove": {
|
||||
"message": "Suprimir"
|
||||
},
|
||||
"appliesSpecify": {
|
||||
"message": "Especificar"
|
||||
},
|
||||
"appliesToEverything": {
|
||||
"message": "Todo"
|
||||
},
|
||||
"appliesUrlPrefixOption": {
|
||||
"message": "URLs que comecen por"
|
||||
},
|
||||
"applyAllUpdates": {
|
||||
"message": "Aplicar tódalas actualizacións"
|
||||
},
|
||||
"author": {
|
||||
"message": "Autor"
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@
|
|||
"message": "Hozzáadás"
|
||||
},
|
||||
"appliesDisplay": {
|
||||
"message": "A következőre érvényesül:$applies$",
|
||||
"message": "Érvényes erre:$applies$",
|
||||
"placeholders": {
|
||||
"applies": {
|
||||
"content": "$1"
|
||||
|
@ -23,22 +23,22 @@
|
|||
"message": "és ennél is több"
|
||||
},
|
||||
"appliesDomainOption": {
|
||||
"message": "URL-ek a doménon"
|
||||
"message": "URL-ek a tartományban"
|
||||
},
|
||||
"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!"
|
||||
"message": "Az \"Érvényes erre\" beállítással korlártozható, hogy milyen URL-ekre vonatkozik az itt lévő kód."
|
||||
},
|
||||
"appliesLabel": {
|
||||
"message": "Amire érvényesül"
|
||||
"message": "Érvényes erre"
|
||||
},
|
||||
"appliesLineWidgetLabel": {
|
||||
"message": "Információ megjelenítése arról, hogy mire van alkalmazva"
|
||||
},
|
||||
"appliesLineWidgetWarning": {
|
||||
"message": "Nem működik minimalizált CSS-szel"
|
||||
"message": "Nem működik minimalizált CSS-sel"
|
||||
},
|
||||
"appliesRegexpOption": {
|
||||
"message": "Reguláris kifejezésekre (regexp) illeszkedő URL-ek"
|
||||
"message": "Reguláris kifejezésre (regexp) illeszkedő URL-ek"
|
||||
},
|
||||
"appliesRemove": {
|
||||
"message": "Eltávolítás"
|
||||
|
@ -71,7 +71,7 @@
|
|||
"message": "Stílusok exportálása"
|
||||
},
|
||||
"checkAllUpdates": {
|
||||
"message": "Az összes stílus frissítésének ellenőrzése"
|
||||
"message": "Összes stílus frissítésének ellenőrzése"
|
||||
},
|
||||
"checkAllUpdatesForce": {
|
||||
"message": "Ellenőrizd újra, nem módosítottam egy stílust sem!"
|
||||
|
@ -89,13 +89,13 @@
|
|||
"message": "Zárójelek és idézőjelek automatikus bezárása"
|
||||
},
|
||||
"cm_autoCloseBracketsTooltip": {
|
||||
"message": "Automatikusan legyen hozzáadva záró jelpár a következők gépelésekor: ()[]{}''\"\""
|
||||
"message": "Nyitó '([{'zárójel gépelésekor lezáró ')]}' zárójel automatikus hozzáadása"
|
||||
},
|
||||
"cm_autocompleteOnTyping": {
|
||||
"message": "Automatikus kiegészítés gépeléskor"
|
||||
},
|
||||
"cm_colorpicker": {
|
||||
"message": "Színválasztó CSS színekhez"
|
||||
"message": "Színválasztó CSS-színekhez"
|
||||
},
|
||||
"cm_indentWithTabs": {
|
||||
"message": "Tabulátorok használata intelligens behúzásra"
|
||||
|
@ -107,7 +107,7 @@
|
|||
"message": "Automatikus sortörés"
|
||||
},
|
||||
"cm_matchHighlight": {
|
||||
"message": "Kijelöl"
|
||||
"message": "Kijelölés"
|
||||
},
|
||||
"cm_matchHighlightSelection": {
|
||||
"message": "Csak kiválasztás"
|
||||
|
@ -125,7 +125,7 @@
|
|||
"message": "Példák kifejezésekre: .valami-2 #aabbcc 0.32 !important\nAmikor ki van kapcsolva: a központosítással elválasztott szavak ki lesznek jelölve."
|
||||
},
|
||||
"cm_smartIndent": {
|
||||
"message": "Intelligens behúzás használata"
|
||||
"message": "Intelligens behúzás"
|
||||
},
|
||||
"cm_tabSize": {
|
||||
"message": "Tabulátorméret"
|
||||
|
@ -200,7 +200,7 @@
|
|||
"message": "Tervezd újra a webet a Stylus stíluskezelővel. A Stylus lehetővé teszi a témák és egyéni külsők egyszerű telepítését sok népszerű oldalhoz."
|
||||
},
|
||||
"disableAllStyles": {
|
||||
"message": "Az összes stílus kikapcsolása"
|
||||
"message": "Összes stílus kikapcsolása"
|
||||
},
|
||||
"disableStyleLabel": {
|
||||
"message": "Letiltás"
|
||||
|
@ -255,11 +255,11 @@
|
|||
"filteredStyles": {
|
||||
"message": "$numShown$ mutatva $numTotal$-ból/-ből",
|
||||
"placeholders": {
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
},
|
||||
"numTotal": {
|
||||
"content": "$2"
|
||||
},
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -321,10 +321,10 @@
|
|||
"message": "Írj be egy parancsot"
|
||||
},
|
||||
"helpKeyMapHotkey": {
|
||||
"message": "Gyorsgomb"
|
||||
"message": "Gyorsbillentyű"
|
||||
},
|
||||
"importAppendLabel": {
|
||||
"message": "Hozzáadás stílushoz"
|
||||
"message": "Hozzáfűzés stílushoz"
|
||||
},
|
||||
"importAppendTooltip": {
|
||||
"message": "Az importált stílus hozzáadása a jelenlegi stílushoz"
|
||||
|
@ -357,10 +357,10 @@
|
|||
"message": "metainfó frissítve"
|
||||
},
|
||||
"importReportTitle": {
|
||||
"message": "A stílusok importálása befejeződött"
|
||||
"message": "A stílusok importálása befejeződött."
|
||||
},
|
||||
"importReportUnchanged": {
|
||||
"message": "Semmi sem változott."
|
||||
"message": "Nincs változás."
|
||||
},
|
||||
"importReportUndone": {
|
||||
"message": "stílusok visszavonva"
|
||||
|
@ -384,7 +384,7 @@
|
|||
"message": "Frissítés telepítése"
|
||||
},
|
||||
"installUpdateFrom": {
|
||||
"message": "A stílus most a következő helyről frissül: $url$",
|
||||
"message": "A stílus jelenleg innen frissül: $url$",
|
||||
"placeholders": {
|
||||
"url": {
|
||||
"content": "$1"
|
||||
|
@ -398,7 +398,7 @@
|
|||
"message": "Licenc"
|
||||
},
|
||||
"linkGetHelp": {
|
||||
"message": "Kérj segítséget"
|
||||
"message": "Segítség kérése"
|
||||
},
|
||||
"linkGetStyles": {
|
||||
"message": "Szerezz be stílusokat"
|
||||
|
@ -426,10 +426,10 @@
|
|||
}
|
||||
},
|
||||
"linterConfigTooltip": {
|
||||
"message": "Kattints ennek a linternek a beállításához"
|
||||
"message": "Linter beállítása"
|
||||
},
|
||||
"linterInvalidConfigError": {
|
||||
"message": "Nincs mentve ezek miatt az érvénytelen beállítások miatt:"
|
||||
"message": "Nincs mentve a következő érvénytelen beállítások miatt:"
|
||||
},
|
||||
"linterIssues": {
|
||||
"message": "Problémák"
|
||||
|
@ -443,31 +443,31 @@
|
|||
}
|
||||
},
|
||||
"linterJSONError": {
|
||||
"message": "Érvénytelen JSON formátum"
|
||||
"message": "Érvénytelen JSON-formátum"
|
||||
},
|
||||
"linterResetMessage": {
|
||||
"message": "Egy véletlen visszaállítás visszavonásához nyomj Ctrl-Z-t (vagy Cmd-Z) a szövegdobozon belül)"
|
||||
},
|
||||
"linterRulesLink": {
|
||||
"message": "Lista az összes stílusról"
|
||||
"message": "Összes szabály listája"
|
||||
},
|
||||
"liveReloadError": {
|
||||
"message": "Hiba történt a fájl figyelése közben"
|
||||
},
|
||||
"liveReloadInstallHint": {
|
||||
"message": "A valós idejű újratöltés engedélyezve van, így a telepített stílus automatikusan frissítve lesz kűlső változtatások során amíg ez a fül és a forrásfájlt tartalmazó fül nyitva van."
|
||||
"message": "A valós idejű újratöltés engedélyezve van, így a telepített stílus automatikusan frissül külső változások során, amíg ez a fül és a forrásfájlt tartalmazó fül nyitva van."
|
||||
},
|
||||
"liveReloadLabel": {
|
||||
"message": "Valós idejű újratöltés"
|
||||
},
|
||||
"manageFavicons": {
|
||||
"message": "Faviconok az alkalmazási oszlopban"
|
||||
"message": "Faviconok az 'Érvényes erre' oszlopban"
|
||||
},
|
||||
"manageFaviconsGray": {
|
||||
"message": "Szürke mód"
|
||||
"message": "Megjelenítés szürkítve"
|
||||
},
|
||||
"manageFaviconsHelp": {
|
||||
"message": "A Stylus egy külső szolgáltatást használ (https://www.google.com/s2/favicons)"
|
||||
"message": "A Stylus külső szolgáltatást használ (https://www.google.com/s2/favicons)"
|
||||
},
|
||||
"manageFilters": {
|
||||
"message": "Szűrők"
|
||||
|
@ -476,13 +476,13 @@
|
|||
"message": "Telepített stílusok"
|
||||
},
|
||||
"manageMaxTargets": {
|
||||
"message": "Megjelenítendő célok száma"
|
||||
"message": "'Érvényes erre' elemek kijelzendő száma"
|
||||
},
|
||||
"manageNewStyleAsUsercss": {
|
||||
"message": "Usercss-ként"
|
||||
},
|
||||
"manageNewUI": {
|
||||
"message": "Az új kezelési felületkiosztás"
|
||||
"message": "Új kezelői felület"
|
||||
},
|
||||
"manageOnlyDisabled": {
|
||||
"message": "Csak letiltott stílusok"
|
||||
|
@ -497,13 +497,13 @@
|
|||
"message": "Csak helyileg létrehozott stílusok"
|
||||
},
|
||||
"manageOnlyLocalTooltip": {
|
||||
"message": "(a stílusok nem egy userstyles.org oldalon lettek telepítve)"
|
||||
"message": "(a stílusok nem a userstyles.org egyik oldaláról települtek)"
|
||||
},
|
||||
"manageOnlyNonUsercss": {
|
||||
"message": "Csak nem Usercss stílusok"
|
||||
},
|
||||
"manageOnlyUpdates": {
|
||||
"message": "Csak frissíthetőek vagy problémásak"
|
||||
"message": "Csak a frissíthetők vagy problémásak"
|
||||
},
|
||||
"manageOnlyUsercss": {
|
||||
"message": "Csak Usercss stílusok"
|
||||
|
@ -524,7 +524,7 @@
|
|||
"message": "Beállítások"
|
||||
},
|
||||
"openStylesManager": {
|
||||
"message": "A frissítéskezelő megnyitása"
|
||||
"message": "Stíluskezelő megnyitása"
|
||||
},
|
||||
"optionsActions": {
|
||||
"message": "Műveletek"
|
||||
|
@ -533,13 +533,13 @@
|
|||
"message": "Haladó"
|
||||
},
|
||||
"optionsAdvancedContextDelete": {
|
||||
"message": "Delete hozzáadása a gyorsmenühöz"
|
||||
"message": "'Törlés' parancs a szerkesztő helyi menüjében"
|
||||
},
|
||||
"optionsAdvancedExposeIframes": {
|
||||
"message": "iframe-ek kitevése HTML[stylus-iframe]-en keresztül"
|
||||
},
|
||||
"optionsAdvancedExposeIframesNote": {
|
||||
"message": "Engedélyezi a legfelsőbb szintű domain elérését\nmindegyik iframe-ben. Lehetővé teszi az olyan\niframe-specifikus CSS írását, mint:\nhtml[stylus-iframe$=\"twitter.com\"] h1 { display:none }"
|
||||
"message": "A legfelsőbb szintű tartomány elérésének engedélyezése\nmindegyik iframe-ben. Lehetővé teszi az olyan\niframe-specifikus CSS írását, mint pl.:\nhtml[stylus-iframe$=\"twitter.com\"] h1 { display:none }"
|
||||
},
|
||||
"optionsAdvancedNewStyleAsUsercss": {
|
||||
"message": "Új stílus írása usercss-ként"
|
||||
|
@ -557,13 +557,13 @@
|
|||
"message": "Az összes frissítés ellenőrzése és telepítése"
|
||||
},
|
||||
"optionsCustomizeBadge": {
|
||||
"message": "Jelvény az eszköztárikonon"
|
||||
"message": "Ikon képe az eszköztáron"
|
||||
},
|
||||
"optionsCustomizeIcon": {
|
||||
"message": "Eszköztárikon"
|
||||
},
|
||||
"optionsCustomizePopup": {
|
||||
"message": "Felugró"
|
||||
"message": "Felugró ablak"
|
||||
},
|
||||
"optionsCustomizeUpdate": {
|
||||
"message": "Frissítések"
|
||||
|
@ -587,13 +587,13 @@
|
|||
"message": "Felugró ablak szélessége (pixelben)"
|
||||
},
|
||||
"optionsReset": {
|
||||
"message": "Beállítások visszaállítása alapértelmezett értékekre."
|
||||
"message": "Beállítások visszaállítása alapértelmezett értékre"
|
||||
},
|
||||
"optionsResetButton": {
|
||||
"message": "Beállítások visszaállítása alapra"
|
||||
"message": "Alapértelmezés visszaállítása"
|
||||
},
|
||||
"optionsSubheading": {
|
||||
"message": "Még több beállítás"
|
||||
"message": "További beállítások"
|
||||
},
|
||||
"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!"
|
||||
|
@ -620,19 +620,19 @@
|
|||
"message": "A Stylus nem tudta elemezni a usercss-t"
|
||||
},
|
||||
"popupBorders": {
|
||||
"message": "Fehér szegélyek használata két oldalt"
|
||||
"message": "Fehér szegély az oldalakon"
|
||||
},
|
||||
"popupBordersTooltip": {
|
||||
"message": "Hasznos az új Chromehoz létrehozott sötét témákhoz, mert nem színezi át az oldalszegélyeket"
|
||||
"message": "Hasznos az új Chrome sötét témáinál, mert nem színezi át az oldalszegélyeket"
|
||||
},
|
||||
"popupHotkeysInfo": {
|
||||
"message": "<1>-<9>, <0>, a numpaden is - be-/kikapcsolja az n-nedik stílust (a 0 10-et jelent)\n<A>-<Z> az adott betűvel kezdődő első stílust kapcsolja be/ki \n<Shift> kapcsolgatás helyett megnyitja a szerkesztőt\n<Numpad +> listázott stílusokat engedélyez\n<Numpad –> listázott stílusokat tilt le\n<Numpad *> és <`> (fordított félidézőjel) - kezdeti állapotban engedélyezett stílusokat kapcsol; nem vonatkozik azokra a stílusokra, amiket később engedélyeztél, mialatt a felugró ablakocska nyitva volt, hogy vissza tudd állítani a kezdeti kiválasztást tesztelés után: egyszerűen tilts le mindent, majd pl. <Numpad –> vagy <Numpad *>\nTovábbi információ a wikiben"
|
||||
},
|
||||
"popupHotkeysTooltip": {
|
||||
"message": "Kattints az elérhető gyorsbillentyűk megtekintéséhez"
|
||||
"message": "Elérhető gyorsbillentyűk megtekintése"
|
||||
},
|
||||
"popupManageTooltip": {
|
||||
"message": "Shift-kattintás vagy jobb kattintás megnyitja a stíluskezelőt a jelenlegi oldalra érvényesülő stílusokkal"
|
||||
"message": "Shift+kattintás vagy jobb kattintás: a stíluskezelő megnyitása a jelenlegi oldalra érvényes stílusokkal"
|
||||
},
|
||||
"popupOpenEditInWindow": {
|
||||
"message": "Szerkesztő megnyitása új ablakban"
|
||||
|
@ -641,7 +641,7 @@
|
|||
"message": "A fül a böngésző ablakától történő leválasztásával is engedélyezhető, és letiltható a fül egy másik ablakhoz való hozzácsatolásával."
|
||||
},
|
||||
"popupStylesFirst": {
|
||||
"message": "Parancsok előtti stílusok"
|
||||
"message": "Stílusnevek a parancsok előtt"
|
||||
},
|
||||
"prefShowBadge": {
|
||||
"message": "A jelenlegi oldalon aktív stílusok száma"
|
||||
|
@ -722,28 +722,28 @@
|
|||
"message": "Gyorsbillentyűk megadása"
|
||||
},
|
||||
"sortDateNewestFirst": {
|
||||
"message": "a legújabb elöl"
|
||||
"message": "újabb elöl"
|
||||
},
|
||||
"sortDateOldestFirst": {
|
||||
"message": "a legrégebbi elöl"
|
||||
"message": "régebbi elöl"
|
||||
},
|
||||
"sortLabel": {
|
||||
"message": "Válaszd ki, hogyan szeretnéd sorba rendezni a telepített stílusokat"
|
||||
"message": "Telepített stílusok sorbarendezésének módja"
|
||||
},
|
||||
"sortLabelTitleAsc": {
|
||||
"message": "Cím növekvő sorrendben"
|
||||
"message": "Cím - növekvő sorrend"
|
||||
},
|
||||
"sortLabelTitleDesc": {
|
||||
"message": "Cím csökkenő sorrendben"
|
||||
"message": "Cím - csökkenő sorrend"
|
||||
},
|
||||
"sortStylesHelp": {
|
||||
"message": "A legördülő menüben válaszd ki, hogyan szeretnéd sorba rendezni a telepített bejegyzéseket. Az alapértelmezett beállítás növekvő sorrend (A-tól Z-ig) a bejegyzések címei szerint. A „Cím csökkenő sorrendben” csoportban megadott rendezési módok csökkenő sorrendet (Z-től A-ig) alkalmaznak a címre.\nMás beállítások azt is lehetővé teszik, hogy több szempont alapján rendezd a bejegyzéseket. Elképzelheted ezt úgy, mint egy többoszlopos rendezési táblázatot, amelyben minden egyes (a plusz jelek között) kiválasztott kategória egy oszlopot vagy egy csoportot jelképez.\nPéldául ha az van beállítva, hogy „Engedélyezve (első) + Cím”, az engedélyezett bejegyzések kerülnek a lista tetejére, aztán az engedélyezett és a letiltott bejegyzések címei külön-külön növekvő sorrendbe A-tól Z-ig) vannak rendezve."
|
||||
"message": "A legördülő menüben válaszhatjuk ki, hogyan szeretnénk sorbarendezni a telepített stílusok bejegyzéseit. Az alapértelmezett beállítás a bejegyzések címei szerinti növekvő (A-tól Z-ig) sorrend. A „Cím - csökkenő sorrend” csoportban megadott rendezési módok csökkenő (Z-től A-ig) sorrendben rendezik a címeket.\nEgyéb beállításokkal több szempont alapján is rendezhetők a bejegyzések. Tekintsünk erre úgy, mint egy többoszlopos, rendezhető táblázatra, amelyben minden egyes (a plusz jelek között) kiválasztott kategória egy oszlopot vagy egy csoportot jelképez.\nPéldául, ha az van beállítva, hogy „Engedélyezve (első) + Cím”, az engedélyezett bejegyzések kerülnek a lista tetejére, majd az engedélyezett és a letiltott bejegyzések címei külön-külön, növekvő (A-tól Z-ig) sorrendben jelennek meg."
|
||||
},
|
||||
"sortStylesHelpTitle": {
|
||||
"message": "Tartalom rendezése"
|
||||
},
|
||||
"styleBadRegexp": {
|
||||
"message": "Érvénytelen regexp."
|
||||
"message": "Érvénytelen reguláris kifejezés."
|
||||
},
|
||||
"styleBeautify": {
|
||||
"message": "Csinosít"
|
||||
|
@ -788,14 +788,14 @@
|
|||
"styleInstallOverwrite": {
|
||||
"message": "„$stylename$” már telepítve van. Felülírod?\nVerzió: $oldVersion$ -> $newVersion$",
|
||||
"placeholders": {
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
},
|
||||
"newVersion": {
|
||||
"content": "$3"
|
||||
},
|
||||
"oldVersion": {
|
||||
"content": "$2"
|
||||
},
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -833,28 +833,28 @@
|
|||
"message": "Írj be egy nevet!"
|
||||
},
|
||||
"styleMozillaFormatHeading": {
|
||||
"message": "Mozilla formátum"
|
||||
"message": "Mozilla-formátum"
|
||||
},
|
||||
"styleNotAppliedRegexpProblemTooltip": {
|
||||
"message": "A stílus nem lett alkalmazva a „regexp()” helytelen használata miatt"
|
||||
},
|
||||
"styleRegexpInvalidExplanation": {
|
||||
"message": "Egyes „regexp()” szabályokat nem lehetett lefordítani."
|
||||
"message": "Néhány „regexp()” szabály nem lefordítható."
|
||||
},
|
||||
"styleRegexpPartialExplanation": {
|
||||
"message": "Ez a stílus olyan részlegesen illeszkedő reguláris kifejezéseket használ, melyek sértik a<a href='https://developer.mozilla.org/docs/Web/CSS/@document'>CSS4@dokumentumspecifikációt</a>, 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)."
|
||||
"message": "A stílus olyan részlegesen illeszkedő reguláris kifejezéseket használ, amelyek sértik a<a href='https://developer.mozilla.org/docs/Web/CSS/@document'>CSS4@dokumentumspecifikációt</a>, amely megköveteli az URL teljes illeszkedését. Az érintett CSS-szekciók nem kerültek alkalmazásra az oldalon. A stílus valószínűleg a Stylish-for-Chrome kiegészítőben készült, amely helytelenül ellenőrzi a „regexp()” szabályokat a legelső verziótól fogva (ismert hiba)."
|
||||
},
|
||||
"styleRegexpProblemTooltip": {
|
||||
"message": "A nem alkalmazott szeckiók száma helytelen 'regexp()' használat miatt"
|
||||
},
|
||||
"styleRegexpTestButton": {
|
||||
"message": "RegExp teszt"
|
||||
"message": "RegExp tesztelése"
|
||||
},
|
||||
"styleRegexpTestFull": {
|
||||
"message": "Illeszkedő fülek"
|
||||
},
|
||||
"styleRegexpTestInvalid": {
|
||||
"message": "Kihagyott érvénytelen reguláris kifejezések"
|
||||
"message": "Kihagyott, érvénytelen reguláris kifejezések"
|
||||
},
|
||||
"styleRegexpTestNone": {
|
||||
"message": "Nincs illeszkedő fül"
|
||||
|
|
|
@ -79,6 +79,9 @@
|
|||
"clickToUninstall": {
|
||||
"message": "Clica per disinstallare"
|
||||
},
|
||||
"cm_autoCloseBrackets": {
|
||||
"message": "Chiudi automaticamente parentesi e virgolette"
|
||||
},
|
||||
"cm_autocompleteOnTyping": {
|
||||
"message": "Completamento automatico durante digitazione"
|
||||
},
|
||||
|
@ -86,7 +89,7 @@
|
|||
"message": "Selezionatore colore per colori CSS"
|
||||
},
|
||||
"cm_indentWithTabs": {
|
||||
"message": "Usa schede con indentazione intellingente"
|
||||
"message": "Usa tabulazioni con indentazione intellingente"
|
||||
},
|
||||
"cm_keyMap": {
|
||||
"message": "Mappa caratteri"
|
||||
|
@ -101,7 +104,7 @@
|
|||
"message": "Usa indentazione intelligente"
|
||||
},
|
||||
"cm_tabSize": {
|
||||
"message": "Dimensione scheda"
|
||||
"message": "Dimensione tabulazione"
|
||||
},
|
||||
"cm_theme": {
|
||||
"message": "Tema"
|
||||
|
@ -207,11 +210,11 @@
|
|||
"filteredStyles": {
|
||||
"message": "$numShown$ mostrati di $numTotal$ totali",
|
||||
"placeholders": {
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
},
|
||||
"numTotal": {
|
||||
"content": "$2"
|
||||
},
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -523,6 +526,9 @@
|
|||
"search": {
|
||||
"message": "Cerca"
|
||||
},
|
||||
"searchNumberOfResults": {
|
||||
"message": "Numero di occorrenze"
|
||||
},
|
||||
"searchResultInstallCount": {
|
||||
"message": "Installazioni totali"
|
||||
},
|
||||
|
@ -611,14 +617,14 @@
|
|||
"styleInstallOverwrite": {
|
||||
"message": "'$stylename$' è già installato. Vuoi sovrascriverlo?\nVersione: $oldVersion$ -> $newVersion$",
|
||||
"placeholders": {
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
},
|
||||
"newVersion": {
|
||||
"content": "$3"
|
||||
},
|
||||
"oldVersion": {
|
||||
"content": "$2"
|
||||
},
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -255,11 +255,11 @@
|
|||
"filteredStyles": {
|
||||
"message": "$numTotal$ 件中の $numShown$ 件を表示",
|
||||
"placeholders": {
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
},
|
||||
"numTotal": {
|
||||
"content": "$2"
|
||||
},
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -797,14 +797,14 @@
|
|||
"styleInstallOverwrite": {
|
||||
"message": "「$stylename$」はすでにインストール済みです。上書きしますか?\nバージョン: $oldVersion$ -> $newVersion$",
|
||||
"placeholders": {
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
},
|
||||
"newVersion": {
|
||||
"content": "$3"
|
||||
},
|
||||
"oldVersion": {
|
||||
"content": "$2"
|
||||
},
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -819,6 +819,14 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"styleMetaErrorRangeOrNumber": {
|
||||
"message": "不正な @var $type$: 最低でも1個の数値を持つ配列である必要があります",
|
||||
"placeholders": {
|
||||
"type": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"styleMetaErrorPreprocessor": {
|
||||
"message": "未サポートの @preprocessor: $preprocessor$",
|
||||
"placeholders": {
|
||||
|
|
|
@ -255,11 +255,11 @@
|
|||
"filteredStyles": {
|
||||
"message": "$numShown$ van de $numTotal$ getoond",
|
||||
"placeholders": {
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
},
|
||||
"numTotal": {
|
||||
"content": "$2"
|
||||
},
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -782,14 +782,14 @@
|
|||
"styleInstallOverwrite": {
|
||||
"message": "‘$stylename$’ is al geïnstalleerd. Overschrijven?\nVersie: $oldVersion$ -> $newVersion$",
|
||||
"placeholders": {
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
},
|
||||
"newVersion": {
|
||||
"content": "$3"
|
||||
},
|
||||
"oldVersion": {
|
||||
"content": "$2"
|
||||
},
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -804,6 +804,14 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"styleMetaErrorRangeOrNumber": {
|
||||
"message": "Ongeldige @var $type$: de waarde moet een reeks zijn die minimaal één getal bevat bij index nul",
|
||||
"placeholders": {
|
||||
"type": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"styleMetaErrorPreprocessor": {
|
||||
"message": "Niet-ondersteunde @preprocessor: $preprocessor$",
|
||||
"placeholders": {
|
||||
|
|
|
@ -261,11 +261,11 @@
|
|||
"filteredStyles": {
|
||||
"message": "Pokazano $numShown$ z sumy $numTotal$",
|
||||
"placeholders": {
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
},
|
||||
"numTotal": {
|
||||
"content": "$2"
|
||||
},
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -800,14 +800,14 @@
|
|||
"styleInstallOverwrite": {
|
||||
"message": "'$stylename$' jest już zainstalowany. Zastąpić?\nWersja: $oldVersion$ -> $newVersion$",
|
||||
"placeholders": {
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
},
|
||||
"newVersion": {
|
||||
"content": "$3"
|
||||
},
|
||||
"oldVersion": {
|
||||
"content": "$2"
|
||||
},
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -822,6 +822,14 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"styleMetaErrorRangeOrNumber": {
|
||||
"message": "Nieprawidłowa wartość @var $type$: musi być tablicą zawierającą co najmniej jedną liczbę w punkcie zerowym",
|
||||
"placeholders": {
|
||||
"type": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"styleMetaErrorPreprocessor": {
|
||||
"message": "Nieobsługiwany @preprocessor: $preprocessor$",
|
||||
"placeholders": {
|
||||
|
|
|
@ -249,11 +249,11 @@
|
|||
"filteredStyles": {
|
||||
"message": "$numShown$ apresentado(s) de $numTotal$total",
|
||||
"placeholders": {
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
},
|
||||
"numTotal": {
|
||||
"content": "$2"
|
||||
},
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -782,14 +782,14 @@
|
|||
"styleInstallOverwrite": {
|
||||
"message": "$stylename$já está instalado. Substituir?\nVersão:$oldVersion$-> $newVersion$",
|
||||
"placeholders": {
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
},
|
||||
"newVersion": {
|
||||
"content": "$3"
|
||||
},
|
||||
"oldVersion": {
|
||||
"content": "$2"
|
||||
},
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -222,11 +222,11 @@
|
|||
"filteredStyles": {
|
||||
"message": "$numShown$ vizualizabile din $numTotal$ ",
|
||||
"placeholders": {
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
},
|
||||
"numTotal": {
|
||||
"content": "$2"
|
||||
},
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -725,14 +725,14 @@
|
|||
"styleInstallOverwrite": {
|
||||
"message": "'$stylename$' este deja instalată. Scrieți peste?\nVersiune: $oldVersion$ -> $newVersion$",
|
||||
"placeholders": {
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
},
|
||||
"newVersion": {
|
||||
"content": "$3"
|
||||
},
|
||||
"oldVersion": {
|
||||
"content": "$2"
|
||||
},
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -261,11 +261,11 @@
|
|||
"filteredStyles": {
|
||||
"message": "найдено $numShown$ из $numTotal$всего",
|
||||
"placeholders": {
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
},
|
||||
"numTotal": {
|
||||
"content": "$2"
|
||||
},
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -803,14 +803,14 @@
|
|||
"styleInstallOverwrite": {
|
||||
"message": "'$stylename$' уже установлен. Обновить?\nВерсии: $oldVersion$ -> $newVersion$",
|
||||
"placeholders": {
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
},
|
||||
"newVersion": {
|
||||
"content": "$3"
|
||||
},
|
||||
"oldVersion": {
|
||||
"content": "$2"
|
||||
},
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -255,11 +255,11 @@
|
|||
"filteredStyles": {
|
||||
"message": "已显示 $numShown$ 个,总共 $numTotal$ 个",
|
||||
"placeholders": {
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
},
|
||||
"numTotal": {
|
||||
"content": "$2"
|
||||
},
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -776,14 +776,14 @@
|
|||
"styleInstallOverwrite": {
|
||||
"message": "'$stylename$' 已经安装,要覆盖吗?\n版本: $oldVersion$ -> $newVersion$",
|
||||
"placeholders": {
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
},
|
||||
"newVersion": {
|
||||
"content": "$3"
|
||||
},
|
||||
"oldVersion": {
|
||||
"content": "$2"
|
||||
},
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -206,7 +206,7 @@
|
|||
"message": "用Stylus(一個用戶樣式管理器)重塑網頁。 Stylus 讓你能為诸多主流網站輕鬆的安裝主題和皮膚。"
|
||||
},
|
||||
"disableAllStyles": {
|
||||
"message": "禁用所有樣式"
|
||||
"message": "停用所有樣式"
|
||||
},
|
||||
"disableStyleLabel": {
|
||||
"message": "停用"
|
||||
|
@ -261,11 +261,11 @@
|
|||
"filteredStyles": {
|
||||
"message": "$numShown$ 個已顯示,總共 $numTotal$ 個",
|
||||
"placeholders": {
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
},
|
||||
"numTotal": {
|
||||
"content": "$2"
|
||||
},
|
||||
"numShown": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -800,14 +800,14 @@
|
|||
"styleInstallOverwrite": {
|
||||
"message": "「$stylename$」已安裝。要覆寫嗎?\n版本:$oldVersion$→$newVersion$",
|
||||
"placeholders": {
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
},
|
||||
"newVersion": {
|
||||
"content": "$3"
|
||||
},
|
||||
"oldVersion": {
|
||||
"content": "$2"
|
||||
},
|
||||
"stylename": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -822,6 +822,14 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"styleMetaErrorRangeOrNumber": {
|
||||
"message": "無效的 @var $type$:值必須為在索引零處包含至少一個數字的陣列",
|
||||
"placeholders": {
|
||||
"type": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"styleMetaErrorPreprocessor": {
|
||||
"message": "不支援的 @preprocessor:$preprocessor$",
|
||||
"placeholders": {
|
||||
|
|
32
manage.html
32
manage.html
|
@ -167,6 +167,12 @@
|
|||
<script src="msgbox/msgbox.js"></script>
|
||||
<script src="js/sections-util.js"></script>
|
||||
<script src="js/storage-util.js"></script>
|
||||
|
||||
<script src="sync/vendor/dropbox/dropbox-sdk.js" async></script>
|
||||
<script src="sync/vendor/zipjs/zip.js" defer></script>
|
||||
<script src="sync/compress-text.js" defer></script>
|
||||
<script src="sync/cross-browser-functions.js" defer></script>
|
||||
<script src="sync/import-export-dropbox.js" async></script>
|
||||
</head>
|
||||
|
||||
<body id="stylus-manage" i18n-dragndrop-hint="dragDropMessage">
|
||||
|
@ -366,8 +372,30 @@
|
|||
<summary><h2 id="backup-title" i18n-text="backupButtons"></h2></summary>
|
||||
<span id="backup-message" i18n-text="backupMessage"></span>
|
||||
<div id="backup-buttons">
|
||||
<button id="file-all-styles" i18n-text="bckpInstStyles"></button>
|
||||
<button id="unfile-all-styles" i18n-text="retrieveBckp"></button>
|
||||
<div class="dropdown">
|
||||
<button class="dropbtn">
|
||||
<span>Export</span>
|
||||
<svg class="svg-icon select-arrow"><use xlink:href="#svg-icon-select-arrow"/></svg>
|
||||
</button>
|
||||
|
||||
<div class="dropdown-content">
|
||||
<a href="#" id="file-all-styles" i18n-text="bckpInstStyles"></a>
|
||||
<a href="#" id="sync-dropbox-export" i18n-text="syncDropboxStyles"></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dropdown">
|
||||
<button class="dropbtn">
|
||||
<span>Import</span>
|
||||
<svg class="svg-icon select-arrow"><use xlink:href="#svg-icon-select-arrow"/></svg>
|
||||
</button>
|
||||
|
||||
<div class="dropdown-content">
|
||||
<a href="#" id="unfile-all-styles" i18n-text="retrieveBckp"></a>
|
||||
<a href="#" id="sync-dropbox-import" i18n-text="retrieveDropboxSync"></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</details>
|
||||
|
||||
|
|
|
@ -1047,6 +1047,54 @@ input[id^="manage.newUI"] {
|
|||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/* export/import buttons */
|
||||
#backup-buttons .dropbtn {
|
||||
padding: 3px 7px;
|
||||
cursor: pointer;
|
||||
text-overflow: inherit;
|
||||
}
|
||||
|
||||
#backup-buttons .dropbtn span {
|
||||
display: inline-block;
|
||||
margin-right: 7px;
|
||||
}
|
||||
|
||||
#backup-buttons .dropdown {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#backup-buttons .dropdown-content {
|
||||
display: none;
|
||||
position: absolute;
|
||||
background-color: #f9f9f9;
|
||||
min-width: 160px;
|
||||
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#backup-buttons .dropdown-content a {
|
||||
color: black;
|
||||
padding: 12px 16px;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#backup-buttons .dropdown-content a:hover {
|
||||
/* background-color: #f2f2f2 */
|
||||
background-color: #e9e9e9
|
||||
}
|
||||
|
||||
#backup-buttons .dropdown:hover .dropdown-content {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#backup-buttons .dropdown:hover .dropbtn {
|
||||
background-color: hsl(0, 0%, 95%);
|
||||
border-color: hsl(0, 0%, 52%);
|
||||
/* background-color: #3e8e41; */
|
||||
}
|
||||
|
||||
/* sort font */
|
||||
@font-face {
|
||||
font-family: 'sorticon';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "Stylus",
|
||||
"version": "1.4.22",
|
||||
"version": "1.4.23",
|
||||
"minimum_chrome_version": "49",
|
||||
"description": "__MSG_description__",
|
||||
"homepage_url": "https://add0n.com/stylus.html",
|
||||
|
@ -19,6 +19,7 @@
|
|||
"contextMenus",
|
||||
"storage",
|
||||
"alarms",
|
||||
"identity",
|
||||
"<all_urls>"
|
||||
],
|
||||
"background": {
|
||||
|
|
17
package.json
17
package.json
|
@ -1,14 +1,14 @@
|
|||
{
|
||||
"name": "Stylus",
|
||||
"version": "1.4.22",
|
||||
"version": "1.4.23",
|
||||
"description": "Redesign the web with Stylus, a user styles manager",
|
||||
"license": "GPL-3.0-only",
|
||||
"repository": "openstyles/stylus",
|
||||
"author": "Stylus Team",
|
||||
"devDependencies": {
|
||||
"archiver": "^3.0.0",
|
||||
"codemirror": "^5.40.0",
|
||||
"eslint": "^5.4.0",
|
||||
"codemirror": "^5.41.0",
|
||||
"eslint": "^5.8.0",
|
||||
"fs-extra": "^7.0.0",
|
||||
"jsonlint": "^1.6.3",
|
||||
"less": "^3.8.1",
|
||||
|
@ -17,17 +17,20 @@
|
|||
"semver-bundle": "^0.1.1",
|
||||
"stylelint-bundle": "^8.0.0",
|
||||
"stylus-lang-bundle": "^0.54.5",
|
||||
"updates": "^4.2.1",
|
||||
"updates": "^5.1.2",
|
||||
"web-ext": "^2.9.1",
|
||||
"usercss-meta": "^0.8.1"
|
||||
"usercss-meta": "^0.8.1",
|
||||
"webext-tx-fix": "^0.3.1"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint **/*.js --cache || exit 0",
|
||||
"update": "npm run update-node && npm run update-main",
|
||||
"update-quick": "updates -u && npm update && npm run update-main",
|
||||
"update-main": "npm run update-versions && npm run update-codemirror",
|
||||
"update-locales": "tx pull --all && webext-tx-fix",
|
||||
"update-main": "npm run update-versions && npm run update-vendor",
|
||||
"update-node": "updates -u && node tools/remove-modules.js && npm install",
|
||||
"update-codemirror": "node tools/update-libraries.js && node tools/update-codemirror-themes.js",
|
||||
"update-transifex": "tx push -s",
|
||||
"update-vendor": "node tools/update-libraries.js && node tools/update-codemirror-themes.js",
|
||||
"update-versions": "node tools/update-versions",
|
||||
"zip": "npm run update-versions && node tools/zip.js",
|
||||
"start": "web-ext run"
|
||||
|
|
41
sync/compress-text.js
Normal file
41
sync/compress-text.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
/* global messageBox */
|
||||
/* global zip */
|
||||
'use strict';
|
||||
|
||||
onDOMready().then(() => {
|
||||
zip.workerScriptsPath = '/sync/vendor/zipjs/';
|
||||
});
|
||||
|
||||
/**
|
||||
* @param {String} filename
|
||||
* @param {String} text content of the file as text
|
||||
* @returns {Promise<Blob>} resolves to a blob object representing the zip file
|
||||
*/
|
||||
function createZipFileFromText(filename, text) {
|
||||
return new Promise((resolve, reject) => {
|
||||
zip.createWriter(new zip.BlobWriter('application/zip'), writer => {
|
||||
writer.add(filename, new zip.TextReader(text), function () {
|
||||
writer.close(blob => {
|
||||
resolve(blob);
|
||||
});
|
||||
});
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} blob object of zip file
|
||||
* @returns {Promise<String>} resolves to a string the content of the first file of the zip
|
||||
*/
|
||||
function readZipFileFromBlob(blob) {
|
||||
return new Promise((resolve, reject) => {
|
||||
zip.createReader(new zip.BlobReader(blob), zipReader => {
|
||||
zipReader.getEntries(entries => {
|
||||
entries[0].getData(new zip.BlobWriter('text/plain'), data => {
|
||||
zipReader.close();
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
}, reject);
|
||||
});
|
||||
}
|
24
sync/cross-browser-functions.js
Normal file
24
sync/cross-browser-functions.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* @returns {String} returns a redirect URL to be used in |launchWebAuthFlow|
|
||||
*/
|
||||
function getRedirectUrlAuthFlow() {
|
||||
const browserApi = typeof browser === 'undefined' ? chrome : browser;
|
||||
return browserApi.identity.getRedirectURL();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} details based on chrome api
|
||||
* @param {string} details.url url that initiates the auth flow
|
||||
* @param {boolean} details.interactive if it is true a window will be displayed
|
||||
* @return {Promise} returns the url containing the token for extraction
|
||||
*/
|
||||
function launchWebAuthFlow(details) {
|
||||
if (typeof browser === 'undefined') {
|
||||
return new Promise(resolve => {
|
||||
chrome.identity.launchWebAuthFlow(details, resolve);
|
||||
});
|
||||
}
|
||||
return browser.identity.launchWebAuthFlow(details);
|
||||
}
|
163
sync/import-export-dropbox.js
Normal file
163
sync/import-export-dropbox.js
Normal file
|
@ -0,0 +1,163 @@
|
|||
/* global messageBox Dropbox createZipFileFromText readZipFileFromBlob launchWebAuthFlow getRedirectUrlAuthFlow importFromString resolve */
|
||||
'use strict';
|
||||
|
||||
const DROPBOX_API_KEY = 'zg52vphuapvpng9';
|
||||
const FILENAME_ZIP_FILE = 'stylus.json';
|
||||
const DROPBOX_FILE = 'stylus.zip';
|
||||
const API_ERROR_STATUS_FILE_NOT_FOUND = 409;
|
||||
const HTTP_STATUS_CANCEL = 499;
|
||||
|
||||
function messageProgressBar(data) {
|
||||
return messageBox({
|
||||
title: `${data.title}`,
|
||||
className: 'config-dialog',
|
||||
contents: [
|
||||
$create('p', data.text)
|
||||
],
|
||||
buttons: [{
|
||||
textContent: t('confirmClose'),
|
||||
dataset: {cmd: 'close'},
|
||||
}],
|
||||
}).then(() => {
|
||||
document.body.style.minWidth = '';
|
||||
document.body.style.minHeight = '';
|
||||
});
|
||||
}
|
||||
|
||||
function hasDropboxAccessToken() {
|
||||
return chromeLocal.getValue('dropbox_access_token');
|
||||
}
|
||||
|
||||
function requestDropboxAccessToken() {
|
||||
const client = new Dropbox.Dropbox({clientId: DROPBOX_API_KEY});
|
||||
const authUrl = client.getAuthenticationUrl(getRedirectUrlAuthFlow());
|
||||
return launchWebAuthFlow({url: authUrl, interactive: true})
|
||||
.then(urlReturned => {
|
||||
const params = new URLSearchParams(new URL(urlReturned).hash.replace('#', ''));
|
||||
chromeLocal.setValue('dropbox_access_token', params.get('access_token'));
|
||||
return params.get('access_token');
|
||||
});
|
||||
}
|
||||
|
||||
function uploadFileDropbox(client, stylesText) {
|
||||
return client.filesUpload({path: '/' + DROPBOX_FILE, contents: stylesText});
|
||||
}
|
||||
|
||||
$('#sync-dropbox-export').onclick = () => {
|
||||
const title = t('syncDropboxStyles');
|
||||
messageProgressBar({title: title, text: t('connectingDropbox')});
|
||||
|
||||
hasDropboxAccessToken()
|
||||
.then(token => token || requestDropboxAccessToken())
|
||||
.then(token => {
|
||||
const client = new Dropbox.Dropbox({
|
||||
clientId: DROPBOX_API_KEY,
|
||||
accessToken: token
|
||||
});
|
||||
return client.filesDownload({path: '/' + DROPBOX_FILE})
|
||||
.then(() => messageBox.confirm(t('overwriteFileExport')))
|
||||
.then(ok => {
|
||||
// deletes file if user want to
|
||||
if (!ok) {
|
||||
return Promise.reject({status: HTTP_STATUS_CANCEL});
|
||||
}
|
||||
return client.filesDelete({path: '/' + DROPBOX_FILE});
|
||||
})
|
||||
// file deleted with success, get styles and create a file
|
||||
.then(() => {
|
||||
messageProgressBar({title: title, text: t('gettingStyles')});
|
||||
return API.getStyles().then(styles => JSON.stringify(styles, null, '\t'));
|
||||
})
|
||||
// create zip file
|
||||
.then(stylesText => {
|
||||
messageProgressBar({title: title, text: t('zipStyles')});
|
||||
return createZipFileFromText(FILENAME_ZIP_FILE, stylesText);
|
||||
})
|
||||
// create file dropbox
|
||||
.then(zipedText => {
|
||||
messageProgressBar({title: title, text: t('uploadingFile')});
|
||||
return uploadFileDropbox(client, zipedText);
|
||||
})
|
||||
// gives feedback to user
|
||||
.then(() => messageProgressBar({title: title, text: t('exportSavedSuccess')}))
|
||||
// handle not found cases and cancel action
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
// saving file first time
|
||||
if (error.status === API_ERROR_STATUS_FILE_NOT_FOUND) {
|
||||
API.getStyles()
|
||||
.then(styles => {
|
||||
messageProgressBar({title: title, text: t('gettingStyles')});
|
||||
return JSON.stringify(styles, null, '\t');
|
||||
})
|
||||
.then(stylesText => {
|
||||
messageProgressBar({title: title, text: t('zipStyles')});
|
||||
return createZipFileFromText(FILENAME_ZIP_FILE, stylesText);
|
||||
})
|
||||
.then(zipedText => {
|
||||
messageProgressBar({title: title, text: t('uploadingFile')});
|
||||
return uploadFileDropbox(client, zipedText);
|
||||
})
|
||||
.then(() => messageProgressBar({title: title, text: t('exportSavedSuccess')}))
|
||||
.catch(err => messageBox.alert(err));
|
||||
return;
|
||||
}
|
||||
|
||||
// user cancelled the flow
|
||||
if (error.status === HTTP_STATUS_CANCEL) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.error(error);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$('#sync-dropbox-import').onclick = () => {
|
||||
const title = t('retrieveDropboxSync');
|
||||
messageProgressBar({title: title, text: t('connectingDropbox')});
|
||||
|
||||
hasDropboxAccessToken()
|
||||
.then(token => token || requestDropboxAccessToken())
|
||||
.then(token => {
|
||||
const client = new Dropbox.Dropbox({
|
||||
clientId: DROPBOX_API_KEY,
|
||||
accessToken: token
|
||||
});
|
||||
return client.filesDownload({path: '/' + DROPBOX_FILE})
|
||||
.then(response => {
|
||||
messageProgressBar({title: title, text: t('unzipStyles')});
|
||||
return readZipFileFromBlob(response.fileBlob);
|
||||
})
|
||||
.then(zipedFileBlob => {
|
||||
messageProgressBar({title: title, text: t('readingStyles')});
|
||||
document.body.style.cursor = 'wait';
|
||||
const fReader = new FileReader();
|
||||
fReader.onloadend = event => {
|
||||
const text = event.target.result;
|
||||
const maybeUsercss = !/^[\s\r\n]*\[/.test(text) &&
|
||||
(text.includes('==UserStyle==') || /==UserStyle==/i.test(text));
|
||||
(!maybeUsercss ?
|
||||
importFromString(text) :
|
||||
getOwnTab().then(tab => {
|
||||
tab.url = URL.createObjectURL(new Blob([text], {type: 'text/css'}));
|
||||
return API.installUsercss({direct: true, tab})
|
||||
.then(() => URL.revokeObjectURL(tab.url));
|
||||
})
|
||||
).then(numStyles => {
|
||||
document.body.style.cursor = '';
|
||||
resolve(numStyles);
|
||||
});
|
||||
};
|
||||
fReader.readAsText(zipedFileBlob, 'utf-8');
|
||||
})
|
||||
.catch(error => {
|
||||
// no file
|
||||
if (error.status === API_ERROR_STATUS_FILE_NOT_FOUND) {
|
||||
messageBox.alert(t('noFileToImport'));
|
||||
return;
|
||||
}
|
||||
messageBox.alert(error);
|
||||
});
|
||||
});
|
||||
};
|
20
sync/vendor/dropbox/LICENSE
vendored
Executable file
20
sync/vendor/dropbox/LICENSE
vendored
Executable file
|
@ -0,0 +1,20 @@
|
|||
Copyright (c) 2016 Dropbox Inc., http://www.dropbox.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
5190
sync/vendor/dropbox/dropbox-sdk.js
vendored
Normal file
5190
sync/vendor/dropbox/dropbox-sdk.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
22
sync/vendor/zipjs/LICENSE
vendored
Executable file
22
sync/vendor/zipjs/LICENSE
vendored
Executable file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
Copyright (c) 2013 Gildas Lormeau. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
3. The names of the authors may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
2060
sync/vendor/zipjs/deflate.js
vendored
Executable file
2060
sync/vendor/zipjs/deflate.js
vendored
Executable file
File diff suppressed because it is too large
Load Diff
2155
sync/vendor/zipjs/inflate.js
vendored
Executable file
2155
sync/vendor/zipjs/inflate.js
vendored
Executable file
File diff suppressed because it is too large
Load Diff
153
sync/vendor/zipjs/z-worker.js
vendored
Executable file
153
sync/vendor/zipjs/z-worker.js
vendored
Executable file
|
@ -0,0 +1,153 @@
|
|||
/* jshint worker:true */
|
||||
(function main(global) {
|
||||
"use strict";
|
||||
|
||||
if (global.zWorkerInitialized)
|
||||
throw new Error('z-worker.js should be run only once');
|
||||
global.zWorkerInitialized = true;
|
||||
|
||||
addEventListener("message", function(event) {
|
||||
var message = event.data, type = message.type, sn = message.sn;
|
||||
var handler = handlers[type];
|
||||
if (handler) {
|
||||
try {
|
||||
handler(message);
|
||||
} catch (e) {
|
||||
onError(type, sn, e);
|
||||
}
|
||||
}
|
||||
//for debug
|
||||
//postMessage({type: 'echo', originalType: type, sn: sn});
|
||||
});
|
||||
|
||||
var handlers = {
|
||||
importScripts: doImportScripts,
|
||||
newTask: newTask,
|
||||
append: processData,
|
||||
flush: processData,
|
||||
};
|
||||
|
||||
// deflater/inflater tasks indexed by serial numbers
|
||||
var tasks = {};
|
||||
|
||||
function doImportScripts(msg) {
|
||||
if (msg.scripts && msg.scripts.length > 0)
|
||||
importScripts.apply(undefined, msg.scripts);
|
||||
postMessage({type: 'importScripts'});
|
||||
}
|
||||
|
||||
function newTask(msg) {
|
||||
var CodecClass = global[msg.codecClass];
|
||||
var sn = msg.sn;
|
||||
if (tasks[sn])
|
||||
throw Error('duplicated sn');
|
||||
tasks[sn] = {
|
||||
codec: new CodecClass(msg.options),
|
||||
crcInput: msg.crcType === 'input',
|
||||
crcOutput: msg.crcType === 'output',
|
||||
crc: new Crc32(),
|
||||
};
|
||||
postMessage({type: 'newTask', sn: sn});
|
||||
}
|
||||
|
||||
// performance may not be supported
|
||||
var now = global.performance ? global.performance.now.bind(global.performance) : Date.now;
|
||||
|
||||
function processData(msg) {
|
||||
var sn = msg.sn, type = msg.type, input = msg.data;
|
||||
var task = tasks[sn];
|
||||
// allow creating codec on first append
|
||||
if (!task && msg.codecClass) {
|
||||
newTask(msg);
|
||||
task = tasks[sn];
|
||||
}
|
||||
var isAppend = type === 'append';
|
||||
var start = now();
|
||||
var output;
|
||||
if (isAppend) {
|
||||
try {
|
||||
output = task.codec.append(input, function onprogress(loaded) {
|
||||
postMessage({type: 'progress', sn: sn, loaded: loaded});
|
||||
});
|
||||
} catch (e) {
|
||||
delete tasks[sn];
|
||||
throw e;
|
||||
}
|
||||
} else {
|
||||
delete tasks[sn];
|
||||
output = task.codec.flush();
|
||||
}
|
||||
var codecTime = now() - start;
|
||||
|
||||
start = now();
|
||||
if (input && task.crcInput)
|
||||
task.crc.append(input);
|
||||
if (output && task.crcOutput)
|
||||
task.crc.append(output);
|
||||
var crcTime = now() - start;
|
||||
|
||||
var rmsg = {type: type, sn: sn, codecTime: codecTime, crcTime: crcTime};
|
||||
var transferables = [];
|
||||
if (output) {
|
||||
rmsg.data = output;
|
||||
transferables.push(output.buffer);
|
||||
}
|
||||
if (!isAppend && (task.crcInput || task.crcOutput))
|
||||
rmsg.crc = task.crc.get();
|
||||
|
||||
// posting a message with transferables will fail on IE10
|
||||
try {
|
||||
postMessage(rmsg, transferables);
|
||||
} catch(ex) {
|
||||
postMessage(rmsg); // retry without transferables
|
||||
}
|
||||
}
|
||||
|
||||
function onError(type, sn, e) {
|
||||
var msg = {
|
||||
type: type,
|
||||
sn: sn,
|
||||
error: formatError(e)
|
||||
};
|
||||
postMessage(msg);
|
||||
}
|
||||
|
||||
function formatError(e) {
|
||||
return { message: e.message, stack: e.stack };
|
||||
}
|
||||
|
||||
// Crc32 code copied from file zip.js
|
||||
function Crc32() {
|
||||
this.crc = -1;
|
||||
}
|
||||
Crc32.prototype.append = function append(data) {
|
||||
var crc = this.crc | 0, table = this.table;
|
||||
for (var offset = 0, len = data.length | 0; offset < len; offset++)
|
||||
crc = (crc >>> 8) ^ table[(crc ^ data[offset]) & 0xFF];
|
||||
this.crc = crc;
|
||||
};
|
||||
Crc32.prototype.get = function get() {
|
||||
return ~this.crc;
|
||||
};
|
||||
Crc32.prototype.table = (function() {
|
||||
var i, j, t, table = []; // Uint32Array is actually slower than []
|
||||
for (i = 0; i < 256; i++) {
|
||||
t = i;
|
||||
for (j = 0; j < 8; j++)
|
||||
if (t & 1)
|
||||
t = (t >>> 1) ^ 0xEDB88320;
|
||||
else
|
||||
t = t >>> 1;
|
||||
table[i] = t;
|
||||
}
|
||||
return table;
|
||||
})();
|
||||
|
||||
// "no-op" codec
|
||||
function NOOP() {}
|
||||
global.NOOP = NOOP;
|
||||
NOOP.prototype.append = function append(bytes, onprogress) {
|
||||
return bytes;
|
||||
};
|
||||
NOOP.prototype.flush = function flush() {};
|
||||
})(this);
|
966
sync/vendor/zipjs/zip.js
vendored
Executable file
966
sync/vendor/zipjs/zip.js
vendored
Executable file
|
@ -0,0 +1,966 @@
|
|||
/*
|
||||
Copyright (c) 2013 Gildas Lormeau. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. The names of the authors may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
(function(obj) {
|
||||
"use strict";
|
||||
|
||||
var ERR_BAD_FORMAT = "File format is not recognized.";
|
||||
var ERR_CRC = "CRC failed.";
|
||||
var ERR_ENCRYPTED = "File contains encrypted entry.";
|
||||
var ERR_ZIP64 = "File is using Zip64 (4gb+ file size).";
|
||||
var ERR_READ = "Error while reading zip file.";
|
||||
var ERR_WRITE = "Error while writing zip file.";
|
||||
var ERR_WRITE_DATA = "Error while writing file data.";
|
||||
var ERR_READ_DATA = "Error while reading file data.";
|
||||
var ERR_DUPLICATED_NAME = "File already exists.";
|
||||
var CHUNK_SIZE = 512 * 1024;
|
||||
|
||||
var TEXT_PLAIN = "text/plain";
|
||||
|
||||
var appendABViewSupported;
|
||||
try {
|
||||
appendABViewSupported = new Blob([ new DataView(new ArrayBuffer(0)) ]).size === 0;
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
function Crc32() {
|
||||
this.crc = -1;
|
||||
}
|
||||
Crc32.prototype.append = function append(data) {
|
||||
var crc = this.crc | 0, table = this.table;
|
||||
for (var offset = 0, len = data.length | 0; offset < len; offset++)
|
||||
crc = (crc >>> 8) ^ table[(crc ^ data[offset]) & 0xFF];
|
||||
this.crc = crc;
|
||||
};
|
||||
Crc32.prototype.get = function get() {
|
||||
return ~this.crc;
|
||||
};
|
||||
Crc32.prototype.table = (function() {
|
||||
var i, j, t, table = []; // Uint32Array is actually slower than []
|
||||
for (i = 0; i < 256; i++) {
|
||||
t = i;
|
||||
for (j = 0; j < 8; j++)
|
||||
if (t & 1)
|
||||
t = (t >>> 1) ^ 0xEDB88320;
|
||||
else
|
||||
t = t >>> 1;
|
||||
table[i] = t;
|
||||
}
|
||||
return table;
|
||||
})();
|
||||
|
||||
// "no-op" codec
|
||||
function NOOP() {}
|
||||
NOOP.prototype.append = function append(bytes, onprogress) {
|
||||
return bytes;
|
||||
};
|
||||
NOOP.prototype.flush = function flush() {};
|
||||
|
||||
function blobSlice(blob, index, length) {
|
||||
if (index < 0 || length < 0 || index + length > blob.size)
|
||||
throw new RangeError('offset:' + index + ', length:' + length + ', size:' + blob.size);
|
||||
if (blob.slice)
|
||||
return blob.slice(index, index + length);
|
||||
else if (blob.webkitSlice)
|
||||
return blob.webkitSlice(index, index + length);
|
||||
else if (blob.mozSlice)
|
||||
return blob.mozSlice(index, index + length);
|
||||
else if (blob.msSlice)
|
||||
return blob.msSlice(index, index + length);
|
||||
}
|
||||
|
||||
function getDataHelper(byteLength, bytes) {
|
||||
var dataBuffer, dataArray;
|
||||
dataBuffer = new ArrayBuffer(byteLength);
|
||||
dataArray = new Uint8Array(dataBuffer);
|
||||
if (bytes)
|
||||
dataArray.set(bytes, 0);
|
||||
return {
|
||||
buffer : dataBuffer,
|
||||
array : dataArray,
|
||||
view : new DataView(dataBuffer)
|
||||
};
|
||||
}
|
||||
|
||||
// Readers
|
||||
function Reader() {
|
||||
}
|
||||
|
||||
function TextReader(text) {
|
||||
var that = this, blobReader;
|
||||
|
||||
function init(callback, onerror) {
|
||||
var blob = new Blob([ text ], {
|
||||
type : TEXT_PLAIN
|
||||
});
|
||||
blobReader = new BlobReader(blob);
|
||||
blobReader.init(function() {
|
||||
that.size = blobReader.size;
|
||||
callback();
|
||||
}, onerror);
|
||||
}
|
||||
|
||||
function readUint8Array(index, length, callback, onerror) {
|
||||
blobReader.readUint8Array(index, length, callback, onerror);
|
||||
}
|
||||
|
||||
that.size = 0;
|
||||
that.init = init;
|
||||
that.readUint8Array = readUint8Array;
|
||||
}
|
||||
TextReader.prototype = new Reader();
|
||||
TextReader.prototype.constructor = TextReader;
|
||||
|
||||
function Data64URIReader(dataURI) {
|
||||
var that = this, dataStart;
|
||||
|
||||
function init(callback) {
|
||||
var dataEnd = dataURI.length;
|
||||
while (dataURI.charAt(dataEnd - 1) == "=")
|
||||
dataEnd--;
|
||||
dataStart = dataURI.indexOf(",") + 1;
|
||||
that.size = Math.floor((dataEnd - dataStart) * 0.75);
|
||||
callback();
|
||||
}
|
||||
|
||||
function readUint8Array(index, length, callback) {
|
||||
var i, data = getDataHelper(length);
|
||||
var start = Math.floor(index / 3) * 4;
|
||||
var end = Math.ceil((index + length) / 3) * 4;
|
||||
var bytes = obj.atob(dataURI.substring(start + dataStart, end + dataStart));
|
||||
var delta = index - Math.floor(start / 4) * 3;
|
||||
for (i = delta; i < delta + length; i++)
|
||||
data.array[i - delta] = bytes.charCodeAt(i);
|
||||
callback(data.array);
|
||||
}
|
||||
|
||||
that.size = 0;
|
||||
that.init = init;
|
||||
that.readUint8Array = readUint8Array;
|
||||
}
|
||||
Data64URIReader.prototype = new Reader();
|
||||
Data64URIReader.prototype.constructor = Data64URIReader;
|
||||
|
||||
function BlobReader(blob) {
|
||||
var that = this;
|
||||
|
||||
function init(callback) {
|
||||
that.size = blob.size;
|
||||
callback();
|
||||
}
|
||||
|
||||
function readUint8Array(index, length, callback, onerror) {
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
callback(new Uint8Array(e.target.result));
|
||||
};
|
||||
reader.onerror = onerror;
|
||||
try {
|
||||
reader.readAsArrayBuffer(blobSlice(blob, index, length));
|
||||
} catch (e) {
|
||||
onerror(e);
|
||||
}
|
||||
}
|
||||
|
||||
that.size = 0;
|
||||
that.init = init;
|
||||
that.readUint8Array = readUint8Array;
|
||||
}
|
||||
BlobReader.prototype = new Reader();
|
||||
BlobReader.prototype.constructor = BlobReader;
|
||||
|
||||
// Writers
|
||||
|
||||
function Writer() {
|
||||
}
|
||||
Writer.prototype.getData = function(callback) {
|
||||
callback(this.data);
|
||||
};
|
||||
|
||||
function TextWriter(encoding) {
|
||||
var that = this, blob;
|
||||
|
||||
function init(callback) {
|
||||
blob = new Blob([], {
|
||||
type : TEXT_PLAIN
|
||||
});
|
||||
callback();
|
||||
}
|
||||
|
||||
function writeUint8Array(array, callback) {
|
||||
blob = new Blob([ blob, appendABViewSupported ? array : array.buffer ], {
|
||||
type : TEXT_PLAIN
|
||||
});
|
||||
callback();
|
||||
}
|
||||
|
||||
function getData(callback, onerror) {
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
callback(e.target.result);
|
||||
};
|
||||
reader.onerror = onerror;
|
||||
reader.readAsText(blob, encoding);
|
||||
}
|
||||
|
||||
that.init = init;
|
||||
that.writeUint8Array = writeUint8Array;
|
||||
that.getData = getData;
|
||||
}
|
||||
TextWriter.prototype = new Writer();
|
||||
TextWriter.prototype.constructor = TextWriter;
|
||||
|
||||
function Data64URIWriter(contentType) {
|
||||
var that = this, data = "", pending = "";
|
||||
|
||||
function init(callback) {
|
||||
data += "data:" + (contentType || "") + ";base64,";
|
||||
callback();
|
||||
}
|
||||
|
||||
function writeUint8Array(array, callback) {
|
||||
var i, delta = pending.length, dataString = pending;
|
||||
pending = "";
|
||||
for (i = 0; i < (Math.floor((delta + array.length) / 3) * 3) - delta; i++)
|
||||
dataString += String.fromCharCode(array[i]);
|
||||
for (; i < array.length; i++)
|
||||
pending += String.fromCharCode(array[i]);
|
||||
if (dataString.length > 2)
|
||||
data += obj.btoa(dataString);
|
||||
else
|
||||
pending = dataString;
|
||||
callback();
|
||||
}
|
||||
|
||||
function getData(callback) {
|
||||
callback(data + obj.btoa(pending));
|
||||
}
|
||||
|
||||
that.init = init;
|
||||
that.writeUint8Array = writeUint8Array;
|
||||
that.getData = getData;
|
||||
}
|
||||
Data64URIWriter.prototype = new Writer();
|
||||
Data64URIWriter.prototype.constructor = Data64URIWriter;
|
||||
|
||||
function BlobWriter(contentType) {
|
||||
var blob, that = this;
|
||||
|
||||
function init(callback) {
|
||||
blob = new Blob([], {
|
||||
type : contentType
|
||||
});
|
||||
callback();
|
||||
}
|
||||
|
||||
function writeUint8Array(array, callback) {
|
||||
blob = new Blob([ blob, appendABViewSupported ? array : array.buffer ], {
|
||||
type : contentType
|
||||
});
|
||||
callback();
|
||||
}
|
||||
|
||||
function getData(callback) {
|
||||
callback(blob);
|
||||
}
|
||||
|
||||
that.init = init;
|
||||
that.writeUint8Array = writeUint8Array;
|
||||
that.getData = getData;
|
||||
}
|
||||
BlobWriter.prototype = new Writer();
|
||||
BlobWriter.prototype.constructor = BlobWriter;
|
||||
|
||||
/**
|
||||
* inflate/deflate core functions
|
||||
* @param worker {Worker} web worker for the task.
|
||||
* @param initialMessage {Object} initial message to be sent to the worker. should contain
|
||||
* sn(serial number for distinguishing multiple tasks sent to the worker), and codecClass.
|
||||
* This function may add more properties before sending.
|
||||
*/
|
||||
function launchWorkerProcess(worker, initialMessage, reader, writer, offset, size, onprogress, onend, onreaderror, onwriteerror) {
|
||||
var chunkIndex = 0, index, outputSize, sn = initialMessage.sn, crc;
|
||||
|
||||
function onflush() {
|
||||
worker.removeEventListener('message', onmessage, false);
|
||||
onend(outputSize, crc);
|
||||
}
|
||||
|
||||
function onmessage(event) {
|
||||
var message = event.data, data = message.data, err = message.error;
|
||||
if (err) {
|
||||
err.toString = function () { return 'Error: ' + this.message; };
|
||||
onreaderror(err);
|
||||
return;
|
||||
}
|
||||
if (message.sn !== sn)
|
||||
return;
|
||||
if (typeof message.codecTime === 'number')
|
||||
worker.codecTime += message.codecTime; // should be before onflush()
|
||||
if (typeof message.crcTime === 'number')
|
||||
worker.crcTime += message.crcTime;
|
||||
|
||||
switch (message.type) {
|
||||
case 'append':
|
||||
if (data) {
|
||||
outputSize += data.length;
|
||||
writer.writeUint8Array(data, function() {
|
||||
step();
|
||||
}, onwriteerror);
|
||||
} else
|
||||
step();
|
||||
break;
|
||||
case 'flush':
|
||||
crc = message.crc;
|
||||
if (data) {
|
||||
outputSize += data.length;
|
||||
writer.writeUint8Array(data, function() {
|
||||
onflush();
|
||||
}, onwriteerror);
|
||||
} else
|
||||
onflush();
|
||||
break;
|
||||
case 'progress':
|
||||
if (onprogress)
|
||||
onprogress(index + message.loaded, size);
|
||||
break;
|
||||
case 'importScripts': //no need to handle here
|
||||
case 'newTask':
|
||||
case 'echo':
|
||||
break;
|
||||
default:
|
||||
console.warn('zip.js:launchWorkerProcess: unknown message: ', message);
|
||||
}
|
||||
}
|
||||
|
||||
function step() {
|
||||
index = chunkIndex * CHUNK_SIZE;
|
||||
// use `<=` instead of `<`, because `size` may be 0.
|
||||
if (index <= size) {
|
||||
reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function(array) {
|
||||
if (onprogress)
|
||||
onprogress(index, size);
|
||||
var msg = index === 0 ? initialMessage : {sn : sn};
|
||||
msg.type = 'append';
|
||||
msg.data = array;
|
||||
|
||||
// posting a message with transferables will fail on IE10
|
||||
try {
|
||||
worker.postMessage(msg, [array.buffer]);
|
||||
} catch(ex) {
|
||||
worker.postMessage(msg); // retry without transferables
|
||||
}
|
||||
chunkIndex++;
|
||||
}, onreaderror);
|
||||
} else {
|
||||
worker.postMessage({
|
||||
sn: sn,
|
||||
type: 'flush'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
outputSize = 0;
|
||||
worker.addEventListener('message', onmessage, false);
|
||||
step();
|
||||
}
|
||||
|
||||
function launchProcess(process, reader, writer, offset, size, crcType, onprogress, onend, onreaderror, onwriteerror) {
|
||||
var chunkIndex = 0, index, outputSize = 0,
|
||||
crcInput = crcType === 'input',
|
||||
crcOutput = crcType === 'output',
|
||||
crc = new Crc32();
|
||||
function step() {
|
||||
var outputData;
|
||||
index = chunkIndex * CHUNK_SIZE;
|
||||
if (index < size)
|
||||
reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function(inputData) {
|
||||
var outputData;
|
||||
try {
|
||||
outputData = process.append(inputData, function(loaded) {
|
||||
if (onprogress)
|
||||
onprogress(index + loaded, size);
|
||||
});
|
||||
} catch (e) {
|
||||
onreaderror(e);
|
||||
return;
|
||||
}
|
||||
if (outputData) {
|
||||
outputSize += outputData.length;
|
||||
writer.writeUint8Array(outputData, function() {
|
||||
chunkIndex++;
|
||||
setTimeout(step, 1);
|
||||
}, onwriteerror);
|
||||
if (crcOutput)
|
||||
crc.append(outputData);
|
||||
} else {
|
||||
chunkIndex++;
|
||||
setTimeout(step, 1);
|
||||
}
|
||||
if (crcInput)
|
||||
crc.append(inputData);
|
||||
if (onprogress)
|
||||
onprogress(index, size);
|
||||
}, onreaderror);
|
||||
else {
|
||||
try {
|
||||
outputData = process.flush();
|
||||
} catch (e) {
|
||||
onreaderror(e);
|
||||
return;
|
||||
}
|
||||
if (outputData) {
|
||||
if (crcOutput)
|
||||
crc.append(outputData);
|
||||
outputSize += outputData.length;
|
||||
writer.writeUint8Array(outputData, function() {
|
||||
onend(outputSize, crc.get());
|
||||
}, onwriteerror);
|
||||
} else
|
||||
onend(outputSize, crc.get());
|
||||
}
|
||||
}
|
||||
|
||||
step();
|
||||
}
|
||||
|
||||
function inflate(worker, sn, reader, writer, offset, size, computeCrc32, onend, onprogress, onreaderror, onwriteerror) {
|
||||
var crcType = computeCrc32 ? 'output' : 'none';
|
||||
if (obj.zip.useWebWorkers) {
|
||||
var initialMessage = {
|
||||
sn: sn,
|
||||
codecClass: 'Inflater',
|
||||
crcType: crcType,
|
||||
};
|
||||
launchWorkerProcess(worker, initialMessage, reader, writer, offset, size, onprogress, onend, onreaderror, onwriteerror);
|
||||
} else
|
||||
launchProcess(new obj.zip.Inflater(), reader, writer, offset, size, crcType, onprogress, onend, onreaderror, onwriteerror);
|
||||
}
|
||||
|
||||
function deflate(worker, sn, reader, writer, level, onend, onprogress, onreaderror, onwriteerror) {
|
||||
var crcType = 'input';
|
||||
if (obj.zip.useWebWorkers) {
|
||||
var initialMessage = {
|
||||
sn: sn,
|
||||
options: {level: level},
|
||||
codecClass: 'Deflater',
|
||||
crcType: crcType,
|
||||
};
|
||||
launchWorkerProcess(worker, initialMessage, reader, writer, 0, reader.size, onprogress, onend, onreaderror, onwriteerror);
|
||||
} else
|
||||
launchProcess(new obj.zip.Deflater(), reader, writer, 0, reader.size, crcType, onprogress, onend, onreaderror, onwriteerror);
|
||||
}
|
||||
|
||||
function copy(worker, sn, reader, writer, offset, size, computeCrc32, onend, onprogress, onreaderror, onwriteerror) {
|
||||
var crcType = 'input';
|
||||
if (obj.zip.useWebWorkers && computeCrc32) {
|
||||
var initialMessage = {
|
||||
sn: sn,
|
||||
codecClass: 'NOOP',
|
||||
crcType: crcType,
|
||||
};
|
||||
launchWorkerProcess(worker, initialMessage, reader, writer, offset, size, onprogress, onend, onreaderror, onwriteerror);
|
||||
} else
|
||||
launchProcess(new NOOP(), reader, writer, offset, size, crcType, onprogress, onend, onreaderror, onwriteerror);
|
||||
}
|
||||
|
||||
// ZipReader
|
||||
|
||||
function decodeASCII(str) {
|
||||
var i, out = "", charCode, extendedASCII = [ '\u00C7', '\u00FC', '\u00E9', '\u00E2', '\u00E4', '\u00E0', '\u00E5', '\u00E7', '\u00EA', '\u00EB',
|
||||
'\u00E8', '\u00EF', '\u00EE', '\u00EC', '\u00C4', '\u00C5', '\u00C9', '\u00E6', '\u00C6', '\u00F4', '\u00F6', '\u00F2', '\u00FB', '\u00F9',
|
||||
'\u00FF', '\u00D6', '\u00DC', '\u00F8', '\u00A3', '\u00D8', '\u00D7', '\u0192', '\u00E1', '\u00ED', '\u00F3', '\u00FA', '\u00F1', '\u00D1',
|
||||
'\u00AA', '\u00BA', '\u00BF', '\u00AE', '\u00AC', '\u00BD', '\u00BC', '\u00A1', '\u00AB', '\u00BB', '_', '_', '_', '\u00A6', '\u00A6',
|
||||
'\u00C1', '\u00C2', '\u00C0', '\u00A9', '\u00A6', '\u00A6', '+', '+', '\u00A2', '\u00A5', '+', '+', '-', '-', '+', '-', '+', '\u00E3',
|
||||
'\u00C3', '+', '+', '-', '-', '\u00A6', '-', '+', '\u00A4', '\u00F0', '\u00D0', '\u00CA', '\u00CB', '\u00C8', 'i', '\u00CD', '\u00CE',
|
||||
'\u00CF', '+', '+', '_', '_', '\u00A6', '\u00CC', '_', '\u00D3', '\u00DF', '\u00D4', '\u00D2', '\u00F5', '\u00D5', '\u00B5', '\u00FE',
|
||||
'\u00DE', '\u00DA', '\u00DB', '\u00D9', '\u00FD', '\u00DD', '\u00AF', '\u00B4', '\u00AD', '\u00B1', '_', '\u00BE', '\u00B6', '\u00A7',
|
||||
'\u00F7', '\u00B8', '\u00B0', '\u00A8', '\u00B7', '\u00B9', '\u00B3', '\u00B2', '_', ' ' ];
|
||||
for (i = 0; i < str.length; i++) {
|
||||
charCode = str.charCodeAt(i) & 0xFF;
|
||||
if (charCode > 127)
|
||||
out += extendedASCII[charCode - 128];
|
||||
else
|
||||
out += String.fromCharCode(charCode);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function decodeUTF8(string) {
|
||||
return decodeURIComponent(escape(string));
|
||||
}
|
||||
|
||||
function getString(bytes) {
|
||||
var i, str = "";
|
||||
for (i = 0; i < bytes.length; i++)
|
||||
str += String.fromCharCode(bytes[i]);
|
||||
return str;
|
||||
}
|
||||
|
||||
function getDate(timeRaw) {
|
||||
var date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & 0x0000ffff;
|
||||
try {
|
||||
return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5,
|
||||
(time & 0x001F) * 2, 0);
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
function readCommonHeader(entry, data, index, centralDirectory, onerror) {
|
||||
entry.version = data.view.getUint16(index, true);
|
||||
entry.bitFlag = data.view.getUint16(index + 2, true);
|
||||
entry.compressionMethod = data.view.getUint16(index + 4, true);
|
||||
entry.lastModDateRaw = data.view.getUint32(index + 6, true);
|
||||
entry.lastModDate = getDate(entry.lastModDateRaw);
|
||||
if ((entry.bitFlag & 0x01) === 0x01) {
|
||||
onerror(ERR_ENCRYPTED);
|
||||
return;
|
||||
}
|
||||
if (centralDirectory || (entry.bitFlag & 0x0008) != 0x0008) {
|
||||
entry.crc32 = data.view.getUint32(index + 10, true);
|
||||
entry.compressedSize = data.view.getUint32(index + 14, true);
|
||||
entry.uncompressedSize = data.view.getUint32(index + 18, true);
|
||||
}
|
||||
if (entry.compressedSize === 0xFFFFFFFF || entry.uncompressedSize === 0xFFFFFFFF) {
|
||||
onerror(ERR_ZIP64);
|
||||
return;
|
||||
}
|
||||
entry.filenameLength = data.view.getUint16(index + 22, true);
|
||||
entry.extraFieldLength = data.view.getUint16(index + 24, true);
|
||||
}
|
||||
|
||||
function createZipReader(reader, callback, onerror) {
|
||||
var inflateSN = 0;
|
||||
|
||||
function Entry() {
|
||||
}
|
||||
|
||||
Entry.prototype.getData = function(writer, onend, onprogress, checkCrc32) {
|
||||
var that = this;
|
||||
|
||||
function testCrc32(crc32) {
|
||||
var dataCrc32 = getDataHelper(4);
|
||||
dataCrc32.view.setUint32(0, crc32);
|
||||
return that.crc32 == dataCrc32.view.getUint32(0);
|
||||
}
|
||||
|
||||
function getWriterData(uncompressedSize, crc32) {
|
||||
if (checkCrc32 && !testCrc32(crc32))
|
||||
onerror(ERR_CRC);
|
||||
else
|
||||
writer.getData(function(data) {
|
||||
onend(data);
|
||||
});
|
||||
}
|
||||
|
||||
function onreaderror(err) {
|
||||
onerror(err || ERR_READ_DATA);
|
||||
}
|
||||
|
||||
function onwriteerror(err) {
|
||||
onerror(err || ERR_WRITE_DATA);
|
||||
}
|
||||
|
||||
reader.readUint8Array(that.offset, 30, function(bytes) {
|
||||
var data = getDataHelper(bytes.length, bytes), dataOffset;
|
||||
if (data.view.getUint32(0) != 0x504b0304) {
|
||||
onerror(ERR_BAD_FORMAT);
|
||||
return;
|
||||
}
|
||||
readCommonHeader(that, data, 4, false, onerror);
|
||||
dataOffset = that.offset + 30 + that.filenameLength + that.extraFieldLength;
|
||||
writer.init(function() {
|
||||
if (that.compressionMethod === 0)
|
||||
copy(that._worker, inflateSN++, reader, writer, dataOffset, that.compressedSize, checkCrc32, getWriterData, onprogress, onreaderror, onwriteerror);
|
||||
else
|
||||
inflate(that._worker, inflateSN++, reader, writer, dataOffset, that.compressedSize, checkCrc32, getWriterData, onprogress, onreaderror, onwriteerror);
|
||||
}, onwriteerror);
|
||||
}, onreaderror);
|
||||
};
|
||||
|
||||
function seekEOCDR(eocdrCallback) {
|
||||
// "End of central directory record" is the last part of a zip archive, and is at least 22 bytes long.
|
||||
// Zip file comment is the last part of EOCDR and has max length of 64KB,
|
||||
// so we only have to search the last 64K + 22 bytes of a archive for EOCDR signature (0x06054b50).
|
||||
var EOCDR_MIN = 22;
|
||||
if (reader.size < EOCDR_MIN) {
|
||||
onerror(ERR_BAD_FORMAT);
|
||||
return;
|
||||
}
|
||||
var ZIP_COMMENT_MAX = 256 * 256, EOCDR_MAX = EOCDR_MIN + ZIP_COMMENT_MAX;
|
||||
|
||||
// In most cases, the EOCDR is EOCDR_MIN bytes long
|
||||
doSeek(EOCDR_MIN, function() {
|
||||
// If not found, try within EOCDR_MAX bytes
|
||||
doSeek(Math.min(EOCDR_MAX, reader.size), function() {
|
||||
onerror(ERR_BAD_FORMAT);
|
||||
});
|
||||
});
|
||||
|
||||
// seek last length bytes of file for EOCDR
|
||||
function doSeek(length, eocdrNotFoundCallback) {
|
||||
reader.readUint8Array(reader.size - length, length, function(bytes) {
|
||||
for (var i = bytes.length - EOCDR_MIN; i >= 0; i--) {
|
||||
if (bytes[i] === 0x50 && bytes[i + 1] === 0x4b && bytes[i + 2] === 0x05 && bytes[i + 3] === 0x06) {
|
||||
eocdrCallback(new DataView(bytes.buffer, i, EOCDR_MIN));
|
||||
return;
|
||||
}
|
||||
}
|
||||
eocdrNotFoundCallback();
|
||||
}, function() {
|
||||
onerror(ERR_READ);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var zipReader = {
|
||||
getEntries : function(callback) {
|
||||
var worker = this._worker;
|
||||
// look for End of central directory record
|
||||
seekEOCDR(function(dataView) {
|
||||
var datalength, fileslength;
|
||||
datalength = dataView.getUint32(16, true);
|
||||
fileslength = dataView.getUint16(8, true);
|
||||
if (datalength < 0 || datalength >= reader.size) {
|
||||
onerror(ERR_BAD_FORMAT);
|
||||
return;
|
||||
}
|
||||
reader.readUint8Array(datalength, reader.size - datalength, function(bytes) {
|
||||
var i, index = 0, entries = [], entry, filename, comment, data = getDataHelper(bytes.length, bytes);
|
||||
for (i = 0; i < fileslength; i++) {
|
||||
entry = new Entry();
|
||||
entry._worker = worker;
|
||||
if (data.view.getUint32(index) != 0x504b0102) {
|
||||
onerror(ERR_BAD_FORMAT);
|
||||
return;
|
||||
}
|
||||
readCommonHeader(entry, data, index + 6, true, onerror);
|
||||
entry.commentLength = data.view.getUint16(index + 32, true);
|
||||
entry.directory = ((data.view.getUint8(index + 38) & 0x10) == 0x10);
|
||||
entry.offset = data.view.getUint32(index + 42, true);
|
||||
filename = getString(data.array.subarray(index + 46, index + 46 + entry.filenameLength));
|
||||
entry.filename = ((entry.bitFlag & 0x0800) === 0x0800) ? decodeUTF8(filename) : decodeASCII(filename);
|
||||
if (!entry.directory && entry.filename.charAt(entry.filename.length - 1) == "/")
|
||||
entry.directory = true;
|
||||
comment = getString(data.array.subarray(index + 46 + entry.filenameLength + entry.extraFieldLength, index + 46
|
||||
+ entry.filenameLength + entry.extraFieldLength + entry.commentLength));
|
||||
entry.comment = ((entry.bitFlag & 0x0800) === 0x0800) ? decodeUTF8(comment) : decodeASCII(comment);
|
||||
entries.push(entry);
|
||||
index += 46 + entry.filenameLength + entry.extraFieldLength + entry.commentLength;
|
||||
}
|
||||
callback(entries);
|
||||
}, function() {
|
||||
onerror(ERR_READ);
|
||||
});
|
||||
});
|
||||
},
|
||||
close : function(callback) {
|
||||
if (this._worker) {
|
||||
this._worker.terminate();
|
||||
this._worker = null;
|
||||
}
|
||||
if (callback)
|
||||
callback();
|
||||
},
|
||||
_worker: null
|
||||
};
|
||||
|
||||
if (!obj.zip.useWebWorkers)
|
||||
callback(zipReader);
|
||||
else {
|
||||
createWorker('inflater',
|
||||
function(worker) {
|
||||
zipReader._worker = worker;
|
||||
callback(zipReader);
|
||||
},
|
||||
function(err) {
|
||||
onerror(err);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ZipWriter
|
||||
|
||||
function encodeUTF8(string) {
|
||||
return unescape(encodeURIComponent(string));
|
||||
}
|
||||
|
||||
function getBytes(str) {
|
||||
var i, array = [];
|
||||
for (i = 0; i < str.length; i++)
|
||||
array.push(str.charCodeAt(i));
|
||||
return array;
|
||||
}
|
||||
|
||||
function createZipWriter(writer, callback, onerror, dontDeflate) {
|
||||
var files = {}, filenames = [], datalength = 0;
|
||||
var deflateSN = 0;
|
||||
|
||||
function onwriteerror(err) {
|
||||
onerror(err || ERR_WRITE);
|
||||
}
|
||||
|
||||
function onreaderror(err) {
|
||||
onerror(err || ERR_READ_DATA);
|
||||
}
|
||||
|
||||
var zipWriter = {
|
||||
add : function(name, reader, onend, onprogress, options) {
|
||||
var header, filename, date;
|
||||
var worker = this._worker;
|
||||
|
||||
function writeHeader(callback) {
|
||||
var data;
|
||||
date = options.lastModDate || new Date();
|
||||
header = getDataHelper(26);
|
||||
files[name] = {
|
||||
headerArray : header.array,
|
||||
directory : options.directory,
|
||||
filename : filename,
|
||||
offset : datalength,
|
||||
comment : getBytes(encodeUTF8(options.comment || ""))
|
||||
};
|
||||
header.view.setUint32(0, 0x14000808);
|
||||
if (options.version)
|
||||
header.view.setUint8(0, options.version);
|
||||
if (!dontDeflate && options.level !== 0 && !options.directory)
|
||||
header.view.setUint16(4, 0x0800);
|
||||
header.view.setUint16(6, (((date.getHours() << 6) | date.getMinutes()) << 5) | date.getSeconds() / 2, true);
|
||||
header.view.setUint16(8, ((((date.getFullYear() - 1980) << 4) | (date.getMonth() + 1)) << 5) | date.getDate(), true);
|
||||
header.view.setUint16(22, filename.length, true);
|
||||
data = getDataHelper(30 + filename.length);
|
||||
data.view.setUint32(0, 0x504b0304);
|
||||
data.array.set(header.array, 4);
|
||||
data.array.set(filename, 30);
|
||||
datalength += data.array.length;
|
||||
writer.writeUint8Array(data.array, callback, onwriteerror);
|
||||
}
|
||||
|
||||
function writeFooter(compressedLength, crc32) {
|
||||
var footer = getDataHelper(16);
|
||||
datalength += compressedLength || 0;
|
||||
footer.view.setUint32(0, 0x504b0708);
|
||||
if (typeof crc32 != "undefined") {
|
||||
header.view.setUint32(10, crc32, true);
|
||||
footer.view.setUint32(4, crc32, true);
|
||||
}
|
||||
if (reader) {
|
||||
footer.view.setUint32(8, compressedLength, true);
|
||||
header.view.setUint32(14, compressedLength, true);
|
||||
footer.view.setUint32(12, reader.size, true);
|
||||
header.view.setUint32(18, reader.size, true);
|
||||
}
|
||||
writer.writeUint8Array(footer.array, function() {
|
||||
datalength += 16;
|
||||
onend();
|
||||
}, onwriteerror);
|
||||
}
|
||||
|
||||
function writeFile() {
|
||||
options = options || {};
|
||||
name = name.trim();
|
||||
if (options.directory && name.charAt(name.length - 1) != "/")
|
||||
name += "/";
|
||||
if (files.hasOwnProperty(name)) {
|
||||
onerror(ERR_DUPLICATED_NAME);
|
||||
return;
|
||||
}
|
||||
filename = getBytes(encodeUTF8(name));
|
||||
filenames.push(name);
|
||||
writeHeader(function() {
|
||||
if (reader)
|
||||
if (dontDeflate || options.level === 0)
|
||||
copy(worker, deflateSN++, reader, writer, 0, reader.size, true, writeFooter, onprogress, onreaderror, onwriteerror);
|
||||
else
|
||||
deflate(worker, deflateSN++, reader, writer, options.level, writeFooter, onprogress, onreaderror, onwriteerror);
|
||||
else
|
||||
writeFooter();
|
||||
}, onwriteerror);
|
||||
}
|
||||
|
||||
if (reader)
|
||||
reader.init(writeFile, onreaderror);
|
||||
else
|
||||
writeFile();
|
||||
},
|
||||
close : function(callback) {
|
||||
if (this._worker) {
|
||||
this._worker.terminate();
|
||||
this._worker = null;
|
||||
}
|
||||
|
||||
var data, length = 0, index = 0, indexFilename, file;
|
||||
for (indexFilename = 0; indexFilename < filenames.length; indexFilename++) {
|
||||
file = files[filenames[indexFilename]];
|
||||
length += 46 + file.filename.length + file.comment.length;
|
||||
}
|
||||
data = getDataHelper(length + 22);
|
||||
for (indexFilename = 0; indexFilename < filenames.length; indexFilename++) {
|
||||
file = files[filenames[indexFilename]];
|
||||
data.view.setUint32(index, 0x504b0102);
|
||||
data.view.setUint16(index + 4, 0x1400);
|
||||
data.array.set(file.headerArray, index + 6);
|
||||
data.view.setUint16(index + 32, file.comment.length, true);
|
||||
if (file.directory)
|
||||
data.view.setUint8(index + 38, 0x10);
|
||||
data.view.setUint32(index + 42, file.offset, true);
|
||||
data.array.set(file.filename, index + 46);
|
||||
data.array.set(file.comment, index + 46 + file.filename.length);
|
||||
index += 46 + file.filename.length + file.comment.length;
|
||||
}
|
||||
data.view.setUint32(index, 0x504b0506);
|
||||
data.view.setUint16(index + 8, filenames.length, true);
|
||||
data.view.setUint16(index + 10, filenames.length, true);
|
||||
data.view.setUint32(index + 12, length, true);
|
||||
data.view.setUint32(index + 16, datalength, true);
|
||||
writer.writeUint8Array(data.array, function() {
|
||||
writer.getData(callback);
|
||||
}, onwriteerror);
|
||||
},
|
||||
_worker: null
|
||||
};
|
||||
|
||||
if (!obj.zip.useWebWorkers)
|
||||
callback(zipWriter);
|
||||
else {
|
||||
createWorker('deflater',
|
||||
function(worker) {
|
||||
zipWriter._worker = worker;
|
||||
callback(zipWriter);
|
||||
},
|
||||
function(err) {
|
||||
onerror(err);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function resolveURLs(urls) {
|
||||
var a = document.createElement('a');
|
||||
return urls.map(function(url) {
|
||||
a.href = url;
|
||||
return a.href;
|
||||
});
|
||||
}
|
||||
|
||||
var DEFAULT_WORKER_SCRIPTS = {
|
||||
deflater: ['z-worker.js', 'deflate.js'],
|
||||
inflater: ['z-worker.js', 'inflate.js']
|
||||
};
|
||||
function createWorker(type, callback, onerror) {
|
||||
if (obj.zip.workerScripts !== null && obj.zip.workerScriptsPath !== null) {
|
||||
onerror(new Error('Either zip.workerScripts or zip.workerScriptsPath may be set, not both.'));
|
||||
return;
|
||||
}
|
||||
var scripts;
|
||||
if (obj.zip.workerScripts) {
|
||||
scripts = obj.zip.workerScripts[type];
|
||||
if (!Array.isArray(scripts)) {
|
||||
onerror(new Error('zip.workerScripts.' + type + ' is not an array!'));
|
||||
return;
|
||||
}
|
||||
scripts = resolveURLs(scripts);
|
||||
} else {
|
||||
scripts = DEFAULT_WORKER_SCRIPTS[type].slice(0);
|
||||
scripts[0] = (obj.zip.workerScriptsPath || '') + scripts[0];
|
||||
}
|
||||
var worker = new Worker(scripts[0]);
|
||||
// record total consumed time by inflater/deflater/crc32 in this worker
|
||||
worker.codecTime = worker.crcTime = 0;
|
||||
worker.postMessage({ type: 'importScripts', scripts: scripts.slice(1) });
|
||||
worker.addEventListener('message', onmessage);
|
||||
function onmessage(ev) {
|
||||
var msg = ev.data;
|
||||
if (msg.error) {
|
||||
worker.terminate(); // should before onerror(), because onerror() may throw.
|
||||
onerror(msg.error);
|
||||
return;
|
||||
}
|
||||
if (msg.type === 'importScripts') {
|
||||
worker.removeEventListener('message', onmessage);
|
||||
worker.removeEventListener('error', errorHandler);
|
||||
callback(worker);
|
||||
}
|
||||
}
|
||||
// catch entry script loading error and other unhandled errors
|
||||
worker.addEventListener('error', errorHandler);
|
||||
function errorHandler(err) {
|
||||
worker.terminate();
|
||||
onerror(err);
|
||||
}
|
||||
}
|
||||
|
||||
function onerror_default(error) {
|
||||
console.error(error);
|
||||
}
|
||||
obj.zip = {
|
||||
Reader : Reader,
|
||||
Writer : Writer,
|
||||
BlobReader : BlobReader,
|
||||
Data64URIReader : Data64URIReader,
|
||||
TextReader : TextReader,
|
||||
BlobWriter : BlobWriter,
|
||||
Data64URIWriter : Data64URIWriter,
|
||||
TextWriter : TextWriter,
|
||||
createReader : function(reader, callback, onerror) {
|
||||
onerror = onerror || onerror_default;
|
||||
|
||||
reader.init(function() {
|
||||
createZipReader(reader, callback, onerror);
|
||||
}, onerror);
|
||||
},
|
||||
createWriter : function(writer, callback, onerror, dontDeflate) {
|
||||
onerror = onerror || onerror_default;
|
||||
dontDeflate = !!dontDeflate;
|
||||
|
||||
writer.init(function() {
|
||||
createZipWriter(writer, callback, onerror, dontDeflate);
|
||||
}, onerror);
|
||||
},
|
||||
useWebWorkers : true,
|
||||
/**
|
||||
* Directory containing the default worker scripts (z-worker.js, deflate.js, and inflate.js), relative to current base url.
|
||||
* E.g.: zip.workerScripts = './';
|
||||
*/
|
||||
workerScriptsPath : null,
|
||||
/**
|
||||
* Advanced option to control which scripts are loaded in the Web worker. If this option is specified, then workerScriptsPath must not be set.
|
||||
* workerScripts.deflater/workerScripts.inflater should be arrays of urls to scripts for deflater/inflater, respectively.
|
||||
* Scripts in the array are executed in order, and the first one should be z-worker.js, which is used to start the worker.
|
||||
* All urls are relative to current base url.
|
||||
* E.g.:
|
||||
* zip.workerScripts = {
|
||||
* deflater: ['z-worker.js', 'deflate.js'],
|
||||
* inflater: ['z-worker.js', 'inflate.js']
|
||||
* };
|
||||
*/
|
||||
workerScripts : null,
|
||||
};
|
||||
|
||||
})(this);
|
|
@ -1,45 +0,0 @@
|
|||
# Install transifex-ruby - https://rubygems.org/gems/transifex-ruby
|
||||
#
|
||||
# Create a file called pull_locales_login.rb.
|
||||
# Contents should be:
|
||||
#
|
||||
# Transifex.configure do |config|
|
||||
# config.username = 'transifex.username'
|
||||
# config.password = 'transifex.password'
|
||||
# end
|
||||
#
|
||||
# Update require_relative to point to this file.
|
||||
|
||||
require 'transifex'
|
||||
require 'fileutils'
|
||||
require_relative '../stylish-chrome-bin/pull_locales_login'
|
||||
|
||||
project_slug = 'stylish-for-chrome'
|
||||
|
||||
transifex = Transifex::Client.new
|
||||
project = transifex.project(project_slug)
|
||||
|
||||
project.languages.each do |language|
|
||||
code = language.language_code
|
||||
puts "Getting locale #{code}"
|
||||
dir_name = "../_locales/#{code}"
|
||||
Dir.mkdir(dir_name) if !Dir.exist?(dir_name)
|
||||
has_content = false
|
||||
project.resources.each do |resource|
|
||||
c = resource.translation(code).content
|
||||
file_name = "#{dir_name}/#{resource.name}"
|
||||
begin
|
||||
completed = resource.stats(code).completed
|
||||
rescue Transifex::NotFound
|
||||
puts "#{code} not found."
|
||||
next
|
||||
end
|
||||
has_content ||= completed != "0%"
|
||||
puts "Writing resource #{file_name}, #{completed} complete."
|
||||
File.open(file_name, 'w') { |file| file.write(c) }
|
||||
end
|
||||
if !has_content
|
||||
puts "Locale #{code} has no content, deleting."
|
||||
FileUtils.rm_rf(dir_name)
|
||||
end
|
||||
end
|
|
@ -1,2 +0,0 @@
|
|||
ruby pull_locales.rb
|
||||
python pull_locales_postprocess.py
|
|
@ -1,45 +0,0 @@
|
|||
#! python2
|
||||
import io, os, json, re
|
||||
from collections import OrderedDict
|
||||
|
||||
with io.open('../_locales/en/messages.json', 'r', encoding='utf-8') as f:
|
||||
items = json.load(f).items()
|
||||
english = [(k, v['message']) for k, v in items if 'message' in v]
|
||||
english_placeholders = [(k, v['placeholders']) for k,v in items
|
||||
if 'placeholders' in v]
|
||||
|
||||
for locale_name in os.listdir('../_locales'):
|
||||
if locale_name == 'en':
|
||||
continue
|
||||
if not re.match(r'^\w{2}(_\w{2,3})?$', locale_name):
|
||||
print('Skipped %s: not a locale dir' % locale_name)
|
||||
continue
|
||||
loc_path = '../_locales/' + locale_name + '/messages.json'
|
||||
with io.open(loc_path, 'r+', encoding='utf-8') as f:
|
||||
loc = json.load(f, object_pairs_hook=OrderedDict)
|
||||
|
||||
deduplicated = 0
|
||||
for msgId, message in english:
|
||||
if msgId in loc and loc[msgId].get('message', '') == message:
|
||||
del loc[msgId]
|
||||
deduplicated += 1
|
||||
|
||||
changed = 0
|
||||
for msgId, placeholder in english_placeholders:
|
||||
if msgId in loc and cmp(placeholder, loc[msgId].get('placeholders', None)) != 0:
|
||||
loc[msgId]['placeholders'] = placeholder
|
||||
changed += 1
|
||||
|
||||
if deduplicated > 0 or changed > 0:
|
||||
f.seek(0)
|
||||
json_str = json.dumps(loc, indent=1, ensure_ascii=False,
|
||||
separators=(',', ': '), encoding='utf-8')
|
||||
json_tabs = re.sub(r'^\s+', lambda s: s.group(0).replace(' ', '\t'),
|
||||
json_str, flags=re.MULTILINE)
|
||||
f.write(json_tabs)
|
||||
f.truncate()
|
||||
print('%s: %d deduplicated%s' % (
|
||||
locale_name,
|
||||
deduplicated,
|
||||
', %d placeholder(s) added' % changed if changed else ''
|
||||
))
|
2
vendor/codemirror/README.md
vendored
2
vendor/codemirror/README.md
vendored
|
@ -1,3 +1,3 @@
|
|||
## CodeMirror v5.40.0
|
||||
## CodeMirror v5.41.0
|
||||
|
||||
Only files & folders that exist in the `vendor/codemirror` folder are copied from the `node_modules/codemirror` folder. Except all theme files are copied, in case new themes have been added.
|
||||
|
|
2
vendor/codemirror/addon/fold/brace-fold.js
vendored
2
vendor/codemirror/addon/fold/brace-fold.js
vendored
|
@ -54,7 +54,7 @@ CodeMirror.registerHelper("fold", "brace", function(cm, start) {
|
|||
++pos;
|
||||
}
|
||||
}
|
||||
if (end == null || line == end && endCh == startCh) return;
|
||||
if (end == null || line == end) return;
|
||||
return {from: CodeMirror.Pos(line, startCh),
|
||||
to: CodeMirror.Pos(end, endCh)};
|
||||
});
|
||||
|
|
109
vendor/codemirror/keymap/vim.js
vendored
109
vendor/codemirror/keymap/vim.js
vendored
|
@ -3,7 +3,7 @@
|
|||
|
||||
/**
|
||||
* Supported keybindings:
|
||||
* Too many to list. Refer to defaultKeyMap below.
|
||||
* Too many to list. Refer to defaultKeymap below.
|
||||
*
|
||||
* Supported Ex commands:
|
||||
* Refer to defaultExCommandMap below.
|
||||
|
@ -207,6 +207,7 @@
|
|||
// Ex command
|
||||
{ keys: ':', type: 'ex' }
|
||||
];
|
||||
var defaultKeymapLength = defaultKeymap.length;
|
||||
|
||||
/**
|
||||
* Ex commands
|
||||
|
@ -742,6 +743,78 @@
|
|||
unmap: function(lhs, ctx) {
|
||||
exCommandDispatcher.unmap(lhs, ctx);
|
||||
},
|
||||
// Non-recursive map function.
|
||||
// NOTE: This will not create mappings to key maps that aren't present
|
||||
// in the default key map. See TODO at bottom of function.
|
||||
noremap: function(lhs, rhs, ctx) {
|
||||
function toCtxArray(ctx) {
|
||||
return ctx ? [ctx] : ['normal', 'insert', 'visual'];
|
||||
}
|
||||
var ctxsToMap = toCtxArray(ctx);
|
||||
// Look through all actual defaults to find a map candidate.
|
||||
var actualLength = defaultKeymap.length, origLength = defaultKeymapLength;
|
||||
for (var i = actualLength - origLength;
|
||||
i < actualLength && ctxsToMap.length;
|
||||
i++) {
|
||||
var mapping = defaultKeymap[i];
|
||||
// Omit mappings that operate in the wrong context(s) and those of invalid type.
|
||||
if (mapping.keys == rhs &&
|
||||
(!ctx || !mapping.context || mapping.context === ctx) &&
|
||||
mapping.type.substr(0, 2) !== 'ex' &&
|
||||
mapping.type.substr(0, 3) !== 'key') {
|
||||
// Make a shallow copy of the original keymap entry.
|
||||
var newMapping = {};
|
||||
for (var key in mapping) {
|
||||
newMapping[key] = mapping[key];
|
||||
}
|
||||
// Modify it point to the new mapping with the proper context.
|
||||
newMapping.keys = lhs;
|
||||
if (ctx && !newMapping.context) {
|
||||
newMapping.context = ctx;
|
||||
}
|
||||
// Add it to the keymap with a higher priority than the original.
|
||||
this._mapCommand(newMapping);
|
||||
// Record the mapped contexts as complete.
|
||||
var mappedCtxs = toCtxArray(mapping.context);
|
||||
ctxsToMap = ctxsToMap.filter(function(el) { return mappedCtxs.indexOf(el) === -1; });
|
||||
}
|
||||
}
|
||||
// TODO: Create non-recursive keyToKey mappings for the unmapped contexts once those exist.
|
||||
},
|
||||
// Remove all user-defined mappings for the provided context.
|
||||
mapclear: function(ctx) {
|
||||
// Partition the existing keymap into user-defined and true defaults.
|
||||
var actualLength = defaultKeymap.length,
|
||||
origLength = defaultKeymapLength;
|
||||
var userKeymap = defaultKeymap.slice(0, actualLength - origLength);
|
||||
defaultKeymap = defaultKeymap.slice(actualLength - origLength);
|
||||
if (ctx) {
|
||||
// If a specific context is being cleared, we need to keep mappings
|
||||
// from all other contexts.
|
||||
for (var i = userKeymap.length - 1; i >= 0; i--) {
|
||||
var mapping = userKeymap[i];
|
||||
if (ctx !== mapping.context) {
|
||||
if (mapping.context) {
|
||||
this._mapCommand(mapping);
|
||||
} else {
|
||||
// `mapping` applies to all contexts so create keymap copies
|
||||
// for each context except the one being cleared.
|
||||
var contexts = ['normal', 'insert', 'visual'];
|
||||
for (var j in contexts) {
|
||||
if (contexts[j] !== ctx) {
|
||||
var newMapping = {};
|
||||
for (var key in mapping) {
|
||||
newMapping[key] = mapping[key];
|
||||
}
|
||||
newMapping.context = contexts[j];
|
||||
this._mapCommand(newMapping);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// TODO: Expose setOption and getOption as instance methods. Need to decide how to namespace
|
||||
// them, or somehow make them work with the existing CodeMirror setOption/getOption API.
|
||||
setOption: setOption,
|
||||
|
@ -5040,32 +5113,7 @@
|
|||
var insertModeChangeRegister = vimGlobalState.registerController.getRegister('.');
|
||||
var isPlaying = macroModeState.isPlaying;
|
||||
var lastChange = macroModeState.lastInsertModeChanges;
|
||||
// In case of visual block, the insertModeChanges are not saved as a
|
||||
// single word, so we convert them to a single word
|
||||
// so as to update the ". register as expected in real vim.
|
||||
var text = [];
|
||||
if (!isPlaying) {
|
||||
var selLength = lastChange.inVisualBlock && vim.lastSelection ?
|
||||
vim.lastSelection.visualBlock.height : 1;
|
||||
var changes = lastChange.changes;
|
||||
var text = [];
|
||||
var i = 0;
|
||||
// In case of multiple selections in blockwise visual,
|
||||
// the inserted text, for example: 'f<Backspace>oo', is stored as
|
||||
// 'f', 'f', InsertModeKey 'o', 'o', 'o', 'o'. (if you have a block with 2 lines).
|
||||
// We push the contents of the changes array as per the following:
|
||||
// 1. In case of InsertModeKey, just increment by 1.
|
||||
// 2. In case of a character, jump by selLength (2 in the example).
|
||||
while (i < changes.length) {
|
||||
// This loop will convert 'ff<bs>oooo' to 'f<bs>oo'.
|
||||
text.push(changes[i]);
|
||||
if (changes[i] instanceof InsertModeKey) {
|
||||
i++;
|
||||
} else {
|
||||
i+= selLength;
|
||||
}
|
||||
}
|
||||
lastChange.changes = text;
|
||||
cm.off('change', onChange);
|
||||
CodeMirror.off(cm.getInputField(), 'keydown', onKeyEventTargetKeyDown);
|
||||
}
|
||||
|
@ -5196,19 +5244,26 @@
|
|||
if (!macroModeState.isPlaying) {
|
||||
while(changeObj) {
|
||||
lastChange.expectCursorActivityForChange = true;
|
||||
if (changeObj.origin == '+input' || changeObj.origin == 'paste'
|
||||
if (lastChange.ignoreCount > 1) {
|
||||
lastChange.ignoreCount--;
|
||||
} else if (changeObj.origin == '+input' || changeObj.origin == 'paste'
|
||||
|| changeObj.origin === undefined /* only in testing */) {
|
||||
var selectionCount = cm.listSelections().length;
|
||||
if (selectionCount > 1)
|
||||
lastChange.ignoreCount = selectionCount;
|
||||
var text = changeObj.text.join('\n');
|
||||
if (lastChange.maybeReset) {
|
||||
lastChange.changes = [];
|
||||
lastChange.maybeReset = false;
|
||||
}
|
||||
if (text) {
|
||||
if (cm.state.overwrite && !/\n/.test(text)) {
|
||||
lastChange.changes.push([text]);
|
||||
} else {
|
||||
lastChange.changes.push(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Change objects may be chained with next.
|
||||
changeObj = changeObj.next;
|
||||
}
|
||||
|
|
92
vendor/codemirror/lib/codemirror.js
vendored
92
vendor/codemirror/lib/codemirror.js
vendored
|
@ -193,9 +193,7 @@ var scrollerGap = 30;
|
|||
var Pass = {toString: function(){return "CodeMirror.Pass"}};
|
||||
|
||||
// Reused option objects for setSelection & friends
|
||||
var sel_dontScroll = {scroll: false};
|
||||
var sel_mouse = {origin: "*mouse"};
|
||||
var sel_move = {origin: "+move"};
|
||||
var sel_dontScroll = {scroll: false}, sel_mouse = {origin: "*mouse"}, sel_move = {origin: "+move"};
|
||||
|
||||
// The inverse of countColumn -- find the offset that corresponds to
|
||||
// a particular column.
|
||||
|
@ -523,8 +521,7 @@ function clipPosArray(doc, array) {
|
|||
}
|
||||
|
||||
// Optimize some code when these features are not used.
|
||||
var sawReadOnlySpans = false;
|
||||
var sawCollapsedSpans = false;
|
||||
var sawReadOnlySpans = false, sawCollapsedSpans = false;
|
||||
|
||||
function seeReadOnlySpans() {
|
||||
sawReadOnlySpans = true;
|
||||
|
@ -572,7 +569,8 @@ function markedSpansBefore(old, startCh, isInsert) {
|
|||
var span = old[i], marker = span.marker;
|
||||
var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
|
||||
if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) {
|
||||
var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);(nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to));
|
||||
var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh)
|
||||
;(nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to));
|
||||
}
|
||||
} }
|
||||
return nw
|
||||
|
@ -583,7 +581,8 @@ function markedSpansAfter(old, endCh, isInsert) {
|
|||
var span = old[i], marker = span.marker;
|
||||
var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
|
||||
if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) {
|
||||
var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);(nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh,
|
||||
var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh)
|
||||
;(nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh,
|
||||
span.to == null ? null : span.to - endCh));
|
||||
}
|
||||
} }
|
||||
|
@ -1306,8 +1305,7 @@ function hasBadZoomedRects(measure) {
|
|||
}
|
||||
|
||||
// Known modes, by name and by MIME
|
||||
var modes = {};
|
||||
var mimeModes = {};
|
||||
var modes = {}, mimeModes = {};
|
||||
|
||||
// Extra arguments are stored as the mode's dependencies, which is
|
||||
// used by (legacy) mechanisms like loadmode.js to automatically
|
||||
|
@ -1800,8 +1798,7 @@ function cleanUpLine(line) {
|
|||
// Convert a style as returned by a mode (either null, or a string
|
||||
// containing one or more styles) to a CSS style. This is cached,
|
||||
// and also looks for line-wide styles.
|
||||
var styleToClassCache = {};
|
||||
var styleToClassCacheWithMode = {};
|
||||
var styleToClassCache = {}, styleToClassCacheWithMode = {};
|
||||
function interpretTokenStyle(style, options) {
|
||||
if (!style || /^\s*$/.test(style)) { return null }
|
||||
var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache;
|
||||
|
@ -1822,7 +1819,7 @@ function buildLineContent(cm, lineView) {
|
|||
var builder = {pre: eltP("pre", [content], "CodeMirror-line"), content: content,
|
||||
col: 0, pos: 0, cm: cm,
|
||||
trailingSpace: false,
|
||||
splitSpaces: (ie || webkit) && cm.getOption("lineWrapping")};
|
||||
splitSpaces: cm.getOption("lineWrapping")};
|
||||
lineView.measure = {};
|
||||
|
||||
// Iterate over the logical lines that make up this visual line.
|
||||
|
@ -1943,6 +1940,8 @@ function buildToken(builder, text, style, startStyle, endStyle, title, css) {
|
|||
builder.content.appendChild(content);
|
||||
}
|
||||
|
||||
// Change some spaces to NBSP to prevent the browser from collapsing
|
||||
// trailing spaces at the end of a line when rendering text (issue #1362).
|
||||
function splitSpaces(text, trailingBefore) {
|
||||
if (text.length > 1 && !/ /.test(text)) { return text }
|
||||
var spaceBefore = trailingBefore, result = "";
|
||||
|
@ -3745,11 +3744,11 @@ function startOperation(cm) {
|
|||
// Finish an operation, updating the display and signalling delayed events
|
||||
function endOperation(cm) {
|
||||
var op = cm.curOp;
|
||||
finishOperation(op, function (group) {
|
||||
if (op) { finishOperation(op, function (group) {
|
||||
for (var i = 0; i < group.ops.length; i++)
|
||||
{ group.ops[i].cm.curOp = null; }
|
||||
endOperations(group);
|
||||
});
|
||||
}); }
|
||||
}
|
||||
|
||||
// The DOM updates done when an operation finishes are batched so
|
||||
|
@ -4312,8 +4311,7 @@ function patchDisplay(cm, updateNumbersFrom, dims) {
|
|||
// in display.lineDiv) with the view as we go.
|
||||
for (var i = 0; i < view.length; i++) {
|
||||
var lineView = view[i];
|
||||
if (lineView.hidden) {
|
||||
} else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet
|
||||
if (lineView.hidden) ; else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet
|
||||
var node = buildLineElement(cm, lineView, lineN, dims);
|
||||
container.insertBefore(node, cur);
|
||||
} else { // Already drawn
|
||||
|
@ -4387,8 +4385,7 @@ function setGuttersForLineNumbers(options) {
|
|||
// is that it gives us a chance to update the display before the
|
||||
// actual scrolling happens, reducing flickering.
|
||||
|
||||
var wheelSamples = 0;
|
||||
var wheelPixelsPerUnit = null;
|
||||
var wheelSamples = 0, wheelPixelsPerUnit = null;
|
||||
// Fill in a browser-detected starting value on browsers where we
|
||||
// know one. These don't have to be accurate -- the result of them
|
||||
// being wrong would just be a slight flicker on the first wheel
|
||||
|
@ -4551,13 +4548,15 @@ Range.prototype.empty = function () { return this.head.line == this.anchor.line
|
|||
// Take an unsorted, potentially overlapping set of ranges, and
|
||||
// build a selection out of it. 'Consumes' ranges array (modifying
|
||||
// it).
|
||||
function normalizeSelection(ranges, primIndex) {
|
||||
function normalizeSelection(cm, ranges, primIndex) {
|
||||
var mayTouch = cm && cm.options.selectionsMayTouch;
|
||||
var prim = ranges[primIndex];
|
||||
ranges.sort(function (a, b) { return cmp(a.from(), b.from()); });
|
||||
primIndex = indexOf(ranges, prim);
|
||||
for (var i = 1; i < ranges.length; i++) {
|
||||
var cur = ranges[i], prev = ranges[i - 1];
|
||||
if (cmp(prev.to(), cur.from()) >= 0) {
|
||||
var diff = cmp(prev.to(), cur.from());
|
||||
if (mayTouch && !cur.empty() ? diff > 0 : diff >= 0) {
|
||||
var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to());
|
||||
var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head;
|
||||
if (i <= primIndex) { --primIndex; }
|
||||
|
@ -4597,7 +4596,7 @@ function computeSelAfterChange(doc, change) {
|
|||
out.push(new Range(adjustForChange(range.anchor, change),
|
||||
adjustForChange(range.head, change)));
|
||||
}
|
||||
return normalizeSelection(out, doc.sel.primIndex)
|
||||
return normalizeSelection(doc.cm, out, doc.sel.primIndex)
|
||||
}
|
||||
|
||||
function offsetPos(pos, old, nw) {
|
||||
|
@ -5005,7 +5004,7 @@ function extendSelections(doc, heads, options) {
|
|||
var extend = doc.cm && (doc.cm.display.shift || doc.extend);
|
||||
for (var i = 0; i < doc.sel.ranges.length; i++)
|
||||
{ out[i] = extendRange(doc.sel.ranges[i], heads[i], null, extend); }
|
||||
var newSel = normalizeSelection(out, doc.sel.primIndex);
|
||||
var newSel = normalizeSelection(doc.cm, out, doc.sel.primIndex);
|
||||
setSelection(doc, newSel, options);
|
||||
}
|
||||
|
||||
|
@ -5013,7 +5012,7 @@ function extendSelections(doc, heads, options) {
|
|||
function replaceOneSelection(doc, i, range, options) {
|
||||
var ranges = doc.sel.ranges.slice(0);
|
||||
ranges[i] = range;
|
||||
setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options);
|
||||
setSelection(doc, normalizeSelection(doc.cm, ranges, doc.sel.primIndex), options);
|
||||
}
|
||||
|
||||
// Reset the selection to a single range.
|
||||
|
@ -5038,7 +5037,7 @@ function filterSelectionChange(doc, sel, options) {
|
|||
};
|
||||
signal(doc, "beforeSelectionChange", doc, obj);
|
||||
if (doc.cm) { signal(doc.cm, "beforeSelectionChange", doc.cm, obj); }
|
||||
if (obj.ranges != sel.ranges) { return normalizeSelection(obj.ranges, obj.ranges.length - 1) }
|
||||
if (obj.ranges != sel.ranges) { return normalizeSelection(doc.cm, obj.ranges, obj.ranges.length - 1) }
|
||||
else { return sel }
|
||||
}
|
||||
|
||||
|
@ -5102,7 +5101,7 @@ function skipAtomicInSelection(doc, sel, bias, mayClear) {
|
|||
out[i] = new Range(newAnchor, newHead);
|
||||
}
|
||||
}
|
||||
return out ? normalizeSelection(out, sel.primIndex) : sel
|
||||
return out ? normalizeSelection(doc.cm, out, sel.primIndex) : sel
|
||||
}
|
||||
|
||||
function skipAtomicInner(doc, pos, oldPos, dir, mayClear) {
|
||||
|
@ -5418,9 +5417,10 @@ function makeChangeSingleDocInEditor(cm, change, spans) {
|
|||
}
|
||||
|
||||
function replaceRange(doc, code, from, to, origin) {
|
||||
var assign;
|
||||
|
||||
if (!to) { to = from; }
|
||||
if (cmp(to, from) < 0) { var assign;
|
||||
(assign = [to, from], from = assign[0], to = assign[1]); }
|
||||
if (cmp(to, from) < 0) { (assign = [to, from], from = assign[0], to = assign[1]); }
|
||||
if (typeof code == "string") { code = doc.splitLines(code); }
|
||||
makeChange(doc, {from: from, to: to, text: code, origin: origin});
|
||||
}
|
||||
|
@ -5876,7 +5876,8 @@ TextMarker.prototype.attachLine = function (line) {
|
|||
TextMarker.prototype.detachLine = function (line) {
|
||||
this.lines.splice(indexOf(this.lines, line), 1);
|
||||
if (!this.lines.length && this.doc.cm) {
|
||||
var op = this.doc.cm.curOp;(op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this);
|
||||
var op = this.doc.cm.curOp
|
||||
;(op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this);
|
||||
}
|
||||
};
|
||||
eventMixin(TextMarker);
|
||||
|
@ -6149,12 +6150,12 @@ Doc.prototype = createObj(BranchChunk.prototype, {
|
|||
{ out[i] = new Range(clipPos(this$1, ranges[i].anchor),
|
||||
clipPos(this$1, ranges[i].head)); }
|
||||
if (primary == null) { primary = Math.min(ranges.length - 1, this.sel.primIndex); }
|
||||
setSelection(this, normalizeSelection(out, primary), options);
|
||||
setSelection(this, normalizeSelection(this.cm, out, primary), options);
|
||||
}),
|
||||
addSelection: docMethodOp(function(anchor, head, options) {
|
||||
var ranges = this.sel.ranges.slice(0);
|
||||
ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor)));
|
||||
setSelection(this, normalizeSelection(ranges, ranges.length - 1), options);
|
||||
setSelection(this, normalizeSelection(this.cm, ranges, ranges.length - 1), options);
|
||||
}),
|
||||
|
||||
getSelection: function(lineSep) {
|
||||
|
@ -7216,8 +7217,7 @@ PastClick.prototype.compare = function (time, pos, button) {
|
|||
cmp(pos, this.pos) == 0 && button == this.button
|
||||
};
|
||||
|
||||
var lastClick;
|
||||
var lastDoubleClick;
|
||||
var lastClick, lastDoubleClick;
|
||||
function clickRepeat(pos, button) {
|
||||
var now = +new Date;
|
||||
if (lastDoubleClick && lastDoubleClick.compare(now, pos, button)) {
|
||||
|
@ -7271,7 +7271,7 @@ function onMouseDown(e) {
|
|||
if (pos) { extendSelection(cm.doc, pos); }
|
||||
setTimeout(function () { return display.input.focus(); }, 20);
|
||||
} else if (button == 3) {
|
||||
if (captureRightClick) { onContextMenu(cm, e); }
|
||||
if (captureRightClick) { cm.display.input.onContextMenu(e); }
|
||||
else { delayBlurEvent(cm); }
|
||||
}
|
||||
}
|
||||
|
@ -7409,10 +7409,10 @@ function leftButtonSelect(cm, event, start, behavior) {
|
|||
startSel = doc.sel;
|
||||
} else if (ourIndex == -1) {
|
||||
ourIndex = ranges.length;
|
||||
setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex),
|
||||
setSelection(doc, normalizeSelection(cm, ranges.concat([ourRange]), ourIndex),
|
||||
{scroll: false, origin: "*mouse"});
|
||||
} else if (ranges.length > 1 && ranges[ourIndex].empty() && behavior.unit == "char" && !behavior.extend) {
|
||||
setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0),
|
||||
setSelection(doc, normalizeSelection(cm, ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0),
|
||||
{scroll: false, origin: "*mouse"});
|
||||
startSel = doc.sel;
|
||||
} else {
|
||||
|
@ -7438,7 +7438,7 @@ function leftButtonSelect(cm, event, start, behavior) {
|
|||
{ ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize)))); }
|
||||
}
|
||||
if (!ranges.length) { ranges.push(new Range(start, start)); }
|
||||
setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex),
|
||||
setSelection(doc, normalizeSelection(cm, startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex),
|
||||
{origin: "*mouse", scroll: false});
|
||||
cm.scrollIntoView(pos);
|
||||
} else {
|
||||
|
@ -7454,7 +7454,7 @@ function leftButtonSelect(cm, event, start, behavior) {
|
|||
}
|
||||
var ranges$1 = startSel.ranges.slice(0);
|
||||
ranges$1[ourIndex] = bidiSimplify(cm, new Range(clipPos(doc, anchor), head));
|
||||
setSelection(doc, normalizeSelection(ranges$1, ourIndex), sel_mouse);
|
||||
setSelection(doc, normalizeSelection(cm, ranges$1, ourIndex), sel_mouse);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7583,7 +7583,7 @@ function clickInGutter(cm, e) {
|
|||
function onContextMenu(cm, e) {
|
||||
if (eventInWidget(cm.display, e) || contextMenuInGutter(cm, e)) { return }
|
||||
if (signalDOMEvent(cm, e, "contextmenu")) { return }
|
||||
cm.display.input.onContextMenu(e);
|
||||
if (!captureRightClick) { cm.display.input.onContextMenu(e); }
|
||||
}
|
||||
|
||||
function contextMenuInGutter(cm, e) {
|
||||
|
@ -7702,6 +7702,7 @@ function defineOptions(CodeMirror) {
|
|||
option("resetSelectionOnContextMenu", true);
|
||||
option("lineWiseCopyCut", true);
|
||||
option("pasteLinesPerSelection", true);
|
||||
option("selectionsMayTouch", false);
|
||||
|
||||
option("readOnly", false, function (cm, val) {
|
||||
if (val == "nocursor") {
|
||||
|
@ -7869,7 +7870,7 @@ function registerEventHandlers(cm) {
|
|||
// Some browsers fire contextmenu *after* opening the menu, at
|
||||
// which point we can't mess with it anymore. Context menu is
|
||||
// handled in onMouseDown for these browsers.
|
||||
if (!captureRightClick) { on(d.scroller, "contextmenu", function (e) { return onContextMenu(cm, e); }); }
|
||||
on(d.scroller, "contextmenu", function (e) { return onContextMenu(cm, e); });
|
||||
|
||||
// Used to suppress mouse event handling when a touch happens
|
||||
var touchFinished, prevTouch = {end: 0};
|
||||
|
@ -8064,7 +8065,7 @@ function applyTextInput(cm, inserted, deleted, sel, origin) {
|
|||
{ from = Pos(from.line, from.ch - deleted); }
|
||||
else if (cm.state.overwrite && !paste) // Handle overwrite
|
||||
{ to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length)); }
|
||||
else if (lastCopied && lastCopied.lineWise && lastCopied.text.join("\n") == inserted)
|
||||
else if (paste && lastCopied && lastCopied.lineWise && lastCopied.text.join("\n") == inserted)
|
||||
{ from = to = Pos(from.line, 0); }
|
||||
}
|
||||
updateInput = cm.curOp.updateInput;
|
||||
|
@ -8156,7 +8157,7 @@ function hiddenTextarea() {
|
|||
// CodeMirror.prototype, for backwards compatibility and
|
||||
// convenience.
|
||||
|
||||
var addEditorMethods = function(CodeMirror) {
|
||||
function addEditorMethods(CodeMirror) {
|
||||
var optionHandlers = CodeMirror.optionHandlers;
|
||||
|
||||
var helpers = CodeMirror.helpers = {};
|
||||
|
@ -8593,7 +8594,7 @@ var addEditorMethods = function(CodeMirror) {
|
|||
CodeMirror.registerHelper(type, name, value);
|
||||
helpers[type]._global.push({pred: predicate, val: value});
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// Used for horizontal relative motion. Dir is -1 or 1 (left or
|
||||
// right), unit can be "char", "column" (like char, but doesn't
|
||||
|
@ -9661,13 +9662,8 @@ for (var prop in Doc.prototype) { if (Doc.prototype.hasOwnProperty(prop) && inde
|
|||
})(Doc.prototype[prop]); } }
|
||||
|
||||
eventMixin(Doc);
|
||||
|
||||
// INPUT HANDLING
|
||||
|
||||
CodeMirror.inputStyles = {"textarea": TextareaInput, "contenteditable": ContentEditableInput};
|
||||
|
||||
// MODE DEFINITION AND QUERYING
|
||||
|
||||
// Extra arguments are stored as the mode's dependencies, which is
|
||||
// used by (legacy) mechanisms like loadmode.js to automatically
|
||||
// load a mode. (Preferred mechanism is the require/define calls.)
|
||||
|
@ -9695,7 +9691,7 @@ CodeMirror.fromTextArea = fromTextArea;
|
|||
|
||||
addLegacyProps(CodeMirror);
|
||||
|
||||
CodeMirror.version = "5.40.0";
|
||||
CodeMirror.version = "5.41.0";
|
||||
|
||||
return CodeMirror;
|
||||
|
||||
|
|
2
vendor/codemirror/mode/css/css.js
vendored
2
vendor/codemirror/mode/css/css.js
vendored
|
@ -501,7 +501,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
"margin-bottom", "margin-left", "margin-right", "margin-top",
|
||||
"marks", "marquee-direction", "marquee-loop",
|
||||
"marquee-play-count", "marquee-speed", "marquee-style", "max-height",
|
||||
"max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
|
||||
"max-width", "min-height", "min-width", "mix-blend-mode", "move-to", "nav-down", "nav-index",
|
||||
"nav-left", "nav-right", "nav-up", "object-fit", "object-position",
|
||||
"opacity", "order", "orphans", "outline",
|
||||
"outline-color", "outline-offset", "outline-style", "outline-width",
|
||||
|
|
|
@ -644,7 +644,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|||
if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(pattern) }
|
||||
if (type == "variable") { register(value); return cont(); }
|
||||
if (type == "spread") return cont(pattern);
|
||||
if (type == "[") return contCommasep(pattern, "]");
|
||||
if (type == "[") return contCommasep(eltpattern, "]");
|
||||
if (type == "{") return contCommasep(proppattern, "}");
|
||||
}
|
||||
function proppattern(type, value) {
|
||||
|
@ -657,6 +657,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|||
if (type == "}") return pass();
|
||||
return cont(expect(":"), pattern, maybeAssign);
|
||||
}
|
||||
function eltpattern() {
|
||||
return pass(pattern, maybeAssign)
|
||||
}
|
||||
function maybeAssign(_type, value) {
|
||||
if (value == "=") return cont(expressionNoComma);
|
||||
}
|
||||
|
|
9
vendor/codemirror/theme/gruvbox-dark.css
vendored
9
vendor/codemirror/theme/gruvbox-dark.css
vendored
|
@ -12,7 +12,7 @@
|
|||
.cm-s-gruvbox-dark .CodeMirror-linenumber {color: #7c6f64;}
|
||||
.cm-s-gruvbox-dark .CodeMirror-cursor { border-left: 1px solid #ebdbb2; }
|
||||
.cm-s-gruvbox-dark div.CodeMirror-selected { background: #928374; }
|
||||
.cm-s-gruvbox-dark span.cm-meta { color: #808000; }
|
||||
.cm-s-gruvbox-dark span.cm-meta { color: #83a598; }
|
||||
|
||||
.cm-s-gruvbox-dark span.cm-comment { color: #928374; }
|
||||
.cm-s-gruvbox-dark span.cm-number, span.cm-atom { color: #d3869b; }
|
||||
|
@ -20,15 +20,18 @@
|
|||
|
||||
.cm-s-gruvbox-dark span.cm-variable { color: #ebdbb2; }
|
||||
.cm-s-gruvbox-dark span.cm-variable-2 { color: #ebdbb2; }
|
||||
.cm-s-gruvbox-dark span.cm-variable-3, .cm-s-gruvbox-dark span.cm-type { color: black; }
|
||||
.cm-s-gruvbox-dark span.cm-variable-3, .cm-s-gruvbox-dark span.cm-type { color: #fabd2f; }
|
||||
.cm-s-gruvbox-dark span.cm-operator { color: #ebdbb2; }
|
||||
.cm-s-gruvbox-dark span.cm-callee { color: #ebdbb2; }
|
||||
.cm-s-gruvbox-dark span.cm-def { color: #ebdbb2; }
|
||||
.cm-s-gruvbox-dark span.cm-property { color: #ebdbb2; }
|
||||
.cm-s-gruvbox-dark span.cm-string { color: #b8bb26; }
|
||||
.cm-s-gruvbox-dark span.cm-string-2 { color: #8ec07c; }
|
||||
.cm-s-gruvbox-dark span.cm-qualifier { color: #555; }
|
||||
.cm-s-gruvbox-dark span.cm-qualifier { color: #8ec07c; }
|
||||
.cm-s-gruvbox-dark span.cm-attribute { color: #8ec07c; }
|
||||
|
||||
.cm-s-gruvbox-dark .CodeMirror-activeline-background { background: #3c3836; }
|
||||
.cm-s-gruvbox-dark .CodeMirror-matchingbracket { background: #928374; color:#282828 !important; }
|
||||
|
||||
.cm-s-gruvbox-dark span.cm-builtin { color: #fe8019; }
|
||||
.cm-s-gruvbox-dark span.cm-tag { color: #fe8019; }
|
||||
|
|
Loading…
Reference in New Issue
Block a user