Merge branch 'master' into dev-color-scheme
This commit is contained in:
commit
72488cf099
20
.github/workflows/ci.yml
vendored
Normal file
20
.github/workflows/ci.yml
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
name: ci
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest]
|
||||||
|
node: ['10', '12', '14']
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node }}
|
||||||
|
- run: npm install
|
||||||
|
- run: npm test
|
|
@ -1277,6 +1277,10 @@
|
||||||
"message": "Code formatieren",
|
"message": "Code formatieren",
|
||||||
"description": "Label for the CSS-beautifier button on the edit style page"
|
"description": "Label for the CSS-beautifier button on the edit style page"
|
||||||
},
|
},
|
||||||
|
"styleBeautifyHint": {
|
||||||
|
"message": "Hinweis: Mache einen Rechtsklick auf \"Code formatieren\" oder nutze das weiter unten definierte Tastenkürzel, um den Code zu formatieren ohne dieses Fenster anzuzeigen.",
|
||||||
|
"description": "Hint shown inside the CSS-beautifier panel"
|
||||||
|
},
|
||||||
"styleBeautifyIndentConditional": {
|
"styleBeautifyIndentConditional": {
|
||||||
"message": "Rücke @media / @supports ein",
|
"message": "Rücke @media / @supports ein",
|
||||||
"description": "CSS-beautifier option"
|
"description": "CSS-beautifier option"
|
||||||
|
|
|
@ -1297,6 +1297,10 @@
|
||||||
"message": "Beautify",
|
"message": "Beautify",
|
||||||
"description": "Label for the CSS-beautifier button on the edit style page"
|
"description": "Label for the CSS-beautifier button on the edit style page"
|
||||||
},
|
},
|
||||||
|
"styleBeautifyHint": {
|
||||||
|
"message": "Hint: right-click the “Beautify” button or use the keyboard shortcut defined below to beautify without showing this panel",
|
||||||
|
"description": "Hint shown inside the CSS-beautifier panel"
|
||||||
|
},
|
||||||
"styleBeautifyIndentConditional": {
|
"styleBeautifyIndentConditional": {
|
||||||
"message": "Indent @media, @supports",
|
"message": "Indent @media, @supports",
|
||||||
"description": "CSS-beautifier option"
|
"description": "CSS-beautifier option"
|
||||||
|
|
|
@ -93,7 +93,7 @@
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
"checkAllUpdates": {
|
"checkAllUpdates": {
|
||||||
"message": "Rechercher des mises à jour pour tous les styles",
|
"message": "Rechercher des mises à jour",
|
||||||
"description": "Label for the button to check all styles for updates"
|
"description": "Label for the button to check all styles for updates"
|
||||||
},
|
},
|
||||||
"checkAllUpdatesForce": {
|
"checkAllUpdatesForce": {
|
||||||
|
@ -101,7 +101,7 @@
|
||||||
"description": "Label for the button to apply all detected updates"
|
"description": "Label for the button to apply all detected updates"
|
||||||
},
|
},
|
||||||
"checkForUpdate": {
|
"checkForUpdate": {
|
||||||
"message": "Rechercher des mises à jour",
|
"message": "Rechercher une mise à jour",
|
||||||
"description": "Label for the button to check a single style for an update"
|
"description": "Label for the button to check a single style for an update"
|
||||||
},
|
},
|
||||||
"checkingForUpdate": {
|
"checkingForUpdate": {
|
||||||
|
@ -292,6 +292,10 @@
|
||||||
"message": "Glisser votre fichier de sauvegarde n’importe où sur cette page pour l’importer.",
|
"message": "Glisser votre fichier de sauvegarde n’importe où sur cette page pour l’importer.",
|
||||||
"description": "Drag'n'drop message"
|
"description": "Drag'n'drop message"
|
||||||
},
|
},
|
||||||
|
"dragDropUsercssTabstrip": {
|
||||||
|
"message": "Pour installer le fichier, glisser le fichier sur la barre des onglets (la zone où les titres des onglets sont affichés).",
|
||||||
|
"description": "Message popup shown when erroneously dropping a usercss file into the manager page"
|
||||||
|
},
|
||||||
"editDeleteText": {
|
"editDeleteText": {
|
||||||
"message": "Supprimer",
|
"message": "Supprimer",
|
||||||
"description": "Label for the context menu item in the editor to delete selected text"
|
"description": "Label for the context menu item in the editor to delete selected text"
|
||||||
|
@ -617,6 +621,14 @@
|
||||||
"message": "Une erreur est survenue durant la surveillance du fichier",
|
"message": "Une erreur est survenue durant la surveillance du fichier",
|
||||||
"description": "The label of live-reload error"
|
"description": "The label of live-reload error"
|
||||||
},
|
},
|
||||||
|
"liveReloadInstallHint": {
|
||||||
|
"message": "Gardez cet onglet ouvert pour mettre à jour le style automatiquement basé sur les modifications extérieures.",
|
||||||
|
"description": "The label of live-reload feature"
|
||||||
|
},
|
||||||
|
"liveReloadInstallHintFF": {
|
||||||
|
"message": "Gardez cet onglet ouvert ainsi que l´onglet original pour mettre à jour le style automatiquement basé sur les modifications extérieures.",
|
||||||
|
"description": "The extra hint of live-reload feature shown only for file:// URLs in Firefox"
|
||||||
|
},
|
||||||
"liveReloadLabel": {
|
"liveReloadLabel": {
|
||||||
"message": "Rechargement immédiat",
|
"message": "Rechargement immédiat",
|
||||||
"description": "The label of live-reload feature"
|
"description": "The label of live-reload feature"
|
||||||
|
@ -674,15 +686,15 @@
|
||||||
"description": "Tooltip for the checkbox to show only locally created styles i.e. non-updatable"
|
"description": "Tooltip for the checkbox to show only locally created styles i.e. non-updatable"
|
||||||
},
|
},
|
||||||
"manageOnlyNonUsercss": {
|
"manageOnlyNonUsercss": {
|
||||||
"message": "Uniquement les styles non Usercss",
|
"message": "Styles non Usercss uniquement",
|
||||||
"description": "Checkbox to show only non-Usercss (standard) styles"
|
"description": "Checkbox to show only non-Usercss (standard) styles"
|
||||||
},
|
},
|
||||||
"manageOnlyUpdates": {
|
"manageOnlyUpdates": {
|
||||||
"message": "Uniquement avec mises à jour ou problèmes",
|
"message": "Avec mises à jour ou problèmes uniquement",
|
||||||
"description": "Checkbox to show only styles that have updates after check-all-styles-for-updates was performed"
|
"description": "Checkbox to show only styles that have updates after check-all-styles-for-updates was performed"
|
||||||
},
|
},
|
||||||
"manageOnlyUsercss": {
|
"manageOnlyUsercss": {
|
||||||
"message": "Uniquement les styles Usercss",
|
"message": "Styles Usercss uniquement",
|
||||||
"description": "Checkbox to show only Usercss styles"
|
"description": "Checkbox to show only Usercss styles"
|
||||||
},
|
},
|
||||||
"menuShowBadge": {
|
"menuShowBadge": {
|
||||||
|
@ -1464,7 +1476,7 @@
|
||||||
"description": "Note in the toolbar popup for some file types that cannot be accessed"
|
"description": "Note in the toolbar popup for some file types that cannot be accessed"
|
||||||
},
|
},
|
||||||
"updateAllCheckSucceededNoUpdate": {
|
"updateAllCheckSucceededNoUpdate": {
|
||||||
"message": "All styles are up to date.",
|
"message": "Aucune mise à jour trouvée.",
|
||||||
"description": "Text that displays when an update all check completed and no updates are available"
|
"description": "Text that displays when an update all check completed and no updates are available"
|
||||||
},
|
},
|
||||||
"updateAllCheckSucceededSomeEdited": {
|
"updateAllCheckSucceededSomeEdited": {
|
||||||
|
|
|
@ -1162,7 +1162,7 @@
|
||||||
"description": "Label for the checkbox controlling 'edit' action behavior in the popup."
|
"description": "Label for the checkbox controlling 'edit' action behavior in the popup."
|
||||||
},
|
},
|
||||||
"popupStylesFirst": {
|
"popupStylesFirst": {
|
||||||
"message": "スタイルをコマンドボタンより上に表示",
|
"message": "スタイル一覧をコマンドボタンより上に表示",
|
||||||
"description": "Label for the checkbox controlling section order in the popup."
|
"description": "Label for the checkbox controlling section order in the popup."
|
||||||
},
|
},
|
||||||
"prefShowBadge": {
|
"prefShowBadge": {
|
||||||
|
@ -1305,6 +1305,10 @@
|
||||||
"message": "書式整形",
|
"message": "書式整形",
|
||||||
"description": "Label for the CSS-beautifier button on the edit style page"
|
"description": "Label for the CSS-beautifier button on the edit style page"
|
||||||
},
|
},
|
||||||
|
"styleBeautifyHint": {
|
||||||
|
"message": "ヒント: 書式整形ボタンを右クリックするか、下で設定したキーボードショートカットを使用すると、このパネルを表示せずに書式設定が行えます",
|
||||||
|
"description": "Hint shown inside the CSS-beautifier panel"
|
||||||
|
},
|
||||||
"styleBeautifyIndentConditional": {
|
"styleBeautifyIndentConditional": {
|
||||||
"message": "@media, @supports をインデント",
|
"message": "@media, @supports をインデント",
|
||||||
"description": "CSS-beautifier option"
|
"description": "CSS-beautifier option"
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1285,6 +1285,10 @@
|
||||||
"message": "Mooier maken",
|
"message": "Mooier maken",
|
||||||
"description": "Label for the CSS-beautifier button on the edit style page"
|
"description": "Label for the CSS-beautifier button on the edit style page"
|
||||||
},
|
},
|
||||||
|
"styleBeautifyHint": {
|
||||||
|
"message": "Hint: klik met de rechtermuisknop op de knop ‘Mooier maken’ of gebruik de hieronder gedefinieerde sneltoets om iets mooier te maken zonder dit paneel te tonen",
|
||||||
|
"description": "Hint shown inside the CSS-beautifier panel"
|
||||||
|
},
|
||||||
"styleBeautifyIndentConditional": {
|
"styleBeautifyIndentConditional": {
|
||||||
"message": "@media, @supports inspringen",
|
"message": "@media, @supports inspringen",
|
||||||
"description": "CSS-beautifier option"
|
"description": "CSS-beautifier option"
|
||||||
|
|
|
@ -1309,6 +1309,10 @@
|
||||||
"message": "Upiększ",
|
"message": "Upiększ",
|
||||||
"description": "Label for the CSS-beautifier button on the edit style page"
|
"description": "Label for the CSS-beautifier button on the edit style page"
|
||||||
},
|
},
|
||||||
|
"styleBeautifyHint": {
|
||||||
|
"message": "Wskazówka: kliknij prawym przyciskiem myszy przycisk “Upiększ” lub użyj zdefiniowanego poniżej skrótu klawiaturowego, aby upiększyć bez pokazywania tego panelu",
|
||||||
|
"description": "Hint shown inside the CSS-beautifier panel"
|
||||||
|
},
|
||||||
"styleBeautifyIndentConditional": {
|
"styleBeautifyIndentConditional": {
|
||||||
"message": "Wcięcie @media, @supports",
|
"message": "Wcięcie @media, @supports",
|
||||||
"description": "CSS-beautifier option"
|
"description": "CSS-beautifier option"
|
||||||
|
|
|
@ -244,6 +244,14 @@
|
||||||
"message": "Да",
|
"message": "Да",
|
||||||
"description": "'Yes' button in a confirm dialog"
|
"description": "'Yes' button in a confirm dialog"
|
||||||
},
|
},
|
||||||
|
"copied": {
|
||||||
|
"message": "Скопировано в буфер обмена",
|
||||||
|
"description": "Message shown when content has been copied to the clipboard"
|
||||||
|
},
|
||||||
|
"copy": {
|
||||||
|
"message": "Скопировать в буфер обмена",
|
||||||
|
"description": "Tooltip for elements which can be copied"
|
||||||
|
},
|
||||||
"dateInstalled": {
|
"dateInstalled": {
|
||||||
"message": "Дата установки",
|
"message": "Дата установки",
|
||||||
"description": "Option text for the user to sort the style by install date"
|
"description": "Option text for the user to sort the style by install date"
|
||||||
|
@ -284,6 +292,10 @@
|
||||||
"message": "Перетащите файл с резервной копией стилей в любое место этой страницы, чтобы импортировать его.",
|
"message": "Перетащите файл с резервной копией стилей в любое место этой страницы, чтобы импортировать его.",
|
||||||
"description": "Drag'n'drop message"
|
"description": "Drag'n'drop message"
|
||||||
},
|
},
|
||||||
|
"dragDropUsercssTabstrip": {
|
||||||
|
"message": "Чтобы установить файл, поместите его на вкладку (область, где отображаются заголовки вкладок).",
|
||||||
|
"description": "Message popup shown when erroneously dropping a usercss file into the manager page"
|
||||||
|
},
|
||||||
"editDeleteText": {
|
"editDeleteText": {
|
||||||
"message": "Удалить",
|
"message": "Удалить",
|
||||||
"description": "Label for the context menu item in the editor to delete selected text"
|
"description": "Label for the context menu item in the editor to delete selected text"
|
||||||
|
@ -441,6 +453,10 @@
|
||||||
"message": "Нажмите клавишу",
|
"message": "Нажмите клавишу",
|
||||||
"description": "Placeholder text of inputbox in keymap help popup on the edit style page. Must be very short"
|
"description": "Placeholder text of inputbox in keymap help popup on the edit style page. Must be very short"
|
||||||
},
|
},
|
||||||
|
"hostDisabled": {
|
||||||
|
"message": "Этот хост был отключен из-за ошибки в текущей версии используемого браузера",
|
||||||
|
"description": "Tooltip for cloud host disabled"
|
||||||
|
},
|
||||||
"importAppendLabel": {
|
"importAppendLabel": {
|
||||||
"message": "Добавить к стилю",
|
"message": "Добавить к стилю",
|
||||||
"description": "Label for the button to import a style and append to the existing sections"
|
"description": "Label for the button to import a style and append to the existing sections"
|
||||||
|
@ -613,6 +629,14 @@
|
||||||
"message": "Ошибка слежения за файлом",
|
"message": "Ошибка слежения за файлом",
|
||||||
"description": "The label of live-reload error"
|
"description": "The label of live-reload error"
|
||||||
},
|
},
|
||||||
|
"liveReloadInstallHint": {
|
||||||
|
"message": "Держите эту вкладку открытой, чтобы автоматически обновлять стиль при внешних изменениях.",
|
||||||
|
"description": "The label of live-reload feature"
|
||||||
|
},
|
||||||
|
"liveReloadInstallHintFF": {
|
||||||
|
"message": "Оставьте эту вкладку и исходную вкладку открытой, чтобы автоматически обновлять стиль при внешних изменениях.",
|
||||||
|
"description": "The extra hint of live-reload feature shown only for file:// URLs in Firefox"
|
||||||
|
},
|
||||||
"liveReloadLabel": {
|
"liveReloadLabel": {
|
||||||
"message": "Автозагрузка изменений",
|
"message": "Автозагрузка изменений",
|
||||||
"description": "The label of live-reload feature"
|
"description": "The label of live-reload feature"
|
||||||
|
@ -909,6 +933,10 @@
|
||||||
"message": "Менеджер",
|
"message": "Менеджер",
|
||||||
"description": "Link to open the manage page."
|
"description": "Link to open the manage page."
|
||||||
},
|
},
|
||||||
|
"openOptions": {
|
||||||
|
"message": "Опции",
|
||||||
|
"description": "Go to Options UI"
|
||||||
|
},
|
||||||
"openStylesManager": {
|
"openStylesManager": {
|
||||||
"message": "Менеджер стилей",
|
"message": "Менеджер стилей",
|
||||||
"description": "Label for the style maanger opener in the browser action context menu."
|
"description": "Label for the style maanger opener in the browser action context menu."
|
||||||
|
@ -969,6 +997,10 @@
|
||||||
"message": "Обновления",
|
"message": "Обновления",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"optionsCustomizeSync": {
|
||||||
|
"message": "Синхронизация с облаком",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"optionsHeading": {
|
"optionsHeading": {
|
||||||
"message": "Настройки",
|
"message": "Настройки",
|
||||||
"description": "Heading for options section on manage page."
|
"description": "Heading for options section on manage page."
|
||||||
|
@ -1013,6 +1045,70 @@
|
||||||
"message": "Интервал обновления стилей, в часах (укажите 0 для выключения)",
|
"message": "Интервал обновления стилей, в часах (укажите 0 для выключения)",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"optionsSyncNone": {
|
||||||
|
"message": "Ничего",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"optionsSyncConnect": {
|
||||||
|
"message": "Подключить",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"optionsSyncDisconnect": {
|
||||||
|
"message": "Отсоединить",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"optionsSyncSyncNow": {
|
||||||
|
"message": "Синхронизировать",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"optionsSyncLogin": {
|
||||||
|
"message": "Логин",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"optionsSyncStatusPull": {
|
||||||
|
"message": "Загружено стилей $loaded$ из $total$",
|
||||||
|
"description": "",
|
||||||
|
"placeholders": {
|
||||||
|
"loaded": {
|
||||||
|
"content": "$1"
|
||||||
|
},
|
||||||
|
"total": {
|
||||||
|
"content": "$2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"optionsSyncStatusPush": {
|
||||||
|
"message": "Загружено стилей $loaded$ из $total$",
|
||||||
|
"description": "",
|
||||||
|
"placeholders": {
|
||||||
|
"loaded": {
|
||||||
|
"content": "$1"
|
||||||
|
},
|
||||||
|
"total": {
|
||||||
|
"content": "$2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"optionsSyncStatusSyncing": {
|
||||||
|
"message": "Синхронизация",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"optionsSyncStatusConnecting": {
|
||||||
|
"message": "Подключение…",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"optionsSyncStatusConnected": {
|
||||||
|
"message": "Подключено",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"optionsSyncStatusDisconnecting": {
|
||||||
|
"message": "Отсоединение…",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"optionsSyncStatusDisconnected": {
|
||||||
|
"message": "Отсоединено",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"paginationCurrent": {
|
"paginationCurrent": {
|
||||||
"message": "Текущая страница",
|
"message": "Текущая страница",
|
||||||
"description": "Tooltip for the current page index in search results"
|
"description": "Tooltip for the current page index in search results"
|
||||||
|
@ -1089,6 +1185,10 @@
|
||||||
"message": "Временно применяет стиль пока вы его редактируете.\nСохраните стиль, чтобы сделать изменения постоянными.",
|
"message": "Временно применяет стиль пока вы его редактируете.\nСохраните стиль, чтобы сделать изменения постоянными.",
|
||||||
"description": "Tooltip for the checkbox in style editor to enable live preview while editing."
|
"description": "Tooltip for the checkbox in style editor to enable live preview while editing."
|
||||||
},
|
},
|
||||||
|
"reload": {
|
||||||
|
"message": "Перезагрузить расширение Stylus",
|
||||||
|
"description": "Context menu reload"
|
||||||
|
},
|
||||||
"replace": {
|
"replace": {
|
||||||
"message": "Заменить",
|
"message": "Заменить",
|
||||||
"description": "Label before the replace input field in the editor shown on Ctrl-H"
|
"description": "Label before the replace input field in the editor shown on Ctrl-H"
|
||||||
|
@ -1496,6 +1596,10 @@
|
||||||
"message": "Экспорт Dropbox",
|
"message": "Экспорт Dropbox",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"syncDropboxDeprecated": {
|
||||||
|
"message": "Импорт/экспорт Dropbox заменен более продвинутой синхронизацией стилей на странице параметров.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"retrieveDropboxSync": {
|
"retrieveDropboxSync": {
|
||||||
"message": "Импорт Dropbox",
|
"message": "Импорт Dropbox",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
|
|
@ -40,6 +40,10 @@
|
||||||
"message": "Şuraya uygulanır",
|
"message": "Şuraya uygulanır",
|
||||||
"description": "Label for 'applies to' fields on the edit/add screen"
|
"description": "Label for 'applies to' fields on the edit/add screen"
|
||||||
},
|
},
|
||||||
|
"appliesLineWidgetWarning": {
|
||||||
|
"message": "Küçültülmüş CSS ile çalışmaz",
|
||||||
|
"description": "A warning that applies-to information won't show properly with minified CSS"
|
||||||
|
},
|
||||||
"appliesRegexpOption": {
|
"appliesRegexpOption": {
|
||||||
"message": "regexp ile eşleşen URL'ler",
|
"message": "regexp ile eşleşen URL'ler",
|
||||||
"description": "Option to make the style apply to the entered string as a regular expression"
|
"description": "Option to make the style apply to the entered string as a regular expression"
|
||||||
|
@ -68,6 +72,14 @@
|
||||||
"message": "Yazar",
|
"message": "Yazar",
|
||||||
"description": "Label for the style author"
|
"description": "Label for the style author"
|
||||||
},
|
},
|
||||||
|
"backupButtons": {
|
||||||
|
"message": "Yedek",
|
||||||
|
"description": "Heading for backup"
|
||||||
|
},
|
||||||
|
"backupMessage": {
|
||||||
|
"message": "Bir dosya seçin veya bu sayfaya sürükleyip bırakın.",
|
||||||
|
"description": "Message for backup"
|
||||||
|
},
|
||||||
"bckpInstStyles": {
|
"bckpInstStyles": {
|
||||||
"message": "Dışa aktar",
|
"message": "Dışa aktar",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
@ -76,6 +88,10 @@
|
||||||
"message": "Tüm stiller için güncellemeleri denetle",
|
"message": "Tüm stiller için güncellemeleri denetle",
|
||||||
"description": "Label for the button to check all styles for updates"
|
"description": "Label for the button to check all styles for updates"
|
||||||
},
|
},
|
||||||
|
"checkAllUpdatesForce": {
|
||||||
|
"message": "Tekrar kontrol et, herhangi bir stil düzenlemedim!",
|
||||||
|
"description": "Label for the button to apply all detected updates"
|
||||||
|
},
|
||||||
"checkForUpdate": {
|
"checkForUpdate": {
|
||||||
"message": "Güncellemeleri denetle",
|
"message": "Güncellemeleri denetle",
|
||||||
"description": "Label for the button to check a single style for an update"
|
"description": "Label for the button to check a single style for an update"
|
||||||
|
@ -92,6 +108,10 @@
|
||||||
"message": "Parantezleri ve tırnak işaretlerini otomatik olarak kapat",
|
"message": "Parantezleri ve tırnak işaretlerini otomatik olarak kapat",
|
||||||
"description": "Label for the checkbox in the style editor."
|
"description": "Label for the checkbox in the style editor."
|
||||||
},
|
},
|
||||||
|
"cm_autoCloseBracketsTooltip": {
|
||||||
|
"message": "()[]{}''\"\" Açılışlarından birini yazarken otomatik olarak bir kapanış çifti ekleyin",
|
||||||
|
"description": "Label for the checkbox in the style editor."
|
||||||
|
},
|
||||||
"cm_autocompleteOnTyping": {
|
"cm_autocompleteOnTyping": {
|
||||||
"message": "Yazarken tamamla",
|
"message": "Yazarken tamamla",
|
||||||
"description": "Label for the checkbox in the style editor."
|
"description": "Label for the checkbox in the style editor."
|
||||||
|
@ -104,6 +124,14 @@
|
||||||
"message": "Akıllı girintili tab kullan",
|
"message": "Akıllı girintili tab kullan",
|
||||||
"description": "Label for the checkbox controlling tabs with smart indentation option for the style editor."
|
"description": "Label for the checkbox controlling tabs with smart indentation option for the style editor."
|
||||||
},
|
},
|
||||||
|
"cm_keyMap": {
|
||||||
|
"message": "Tuşeşlem",
|
||||||
|
"description": "Label for the drop-down list controlling the keymap for the style editor."
|
||||||
|
},
|
||||||
|
"cm_lineWrapping": {
|
||||||
|
"message": "Kelime kaydırma",
|
||||||
|
"description": "Label for the checkbox controlling word wrap option for the style editor."
|
||||||
|
},
|
||||||
"cm_matchHighlight": {
|
"cm_matchHighlight": {
|
||||||
"message": "Vurgulama",
|
"message": "Vurgulama",
|
||||||
"description": "Label for the drop-down list controlling the automatic highlighting of current word/selection occurrences in the style editor."
|
"description": "Label for the drop-down list controlling the automatic highlighting of current word/selection occurrences in the style editor."
|
||||||
|
@ -112,6 +140,26 @@
|
||||||
"message": "Yalnızca seçim",
|
"message": "Yalnızca seçim",
|
||||||
"description": "Style editor's 'highglight' drop-down list option: highlight the occurrences of currently selected text"
|
"description": "Style editor's 'highglight' drop-down list option: highlight the occurrences of currently selected text"
|
||||||
},
|
},
|
||||||
|
"cm_matchHighlightToken": {
|
||||||
|
"message": "İmleç altındaki token",
|
||||||
|
"description": "Style editor's 'highglight' drop-down list option: highlight the occurrences of the word/token under cursor even if nothing is selected"
|
||||||
|
},
|
||||||
|
"cm_resizeGripHint": {
|
||||||
|
"message": "Yüksekliği en üst düzeye çıkarmak/geri yüklemek için çift tıklayın",
|
||||||
|
"description": "Tooltip for the resize grip in style editor"
|
||||||
|
},
|
||||||
|
"cm_selectByTokens": {
|
||||||
|
"message": "Çift tıklamak tokenleri seçer",
|
||||||
|
"description": "Label for the checkbox in the editor."
|
||||||
|
},
|
||||||
|
"cm_selectByTokensTooltip": {
|
||||||
|
"message": "Token örnekleri: .foo-bar-2 #aabbcc 0.32 !important\nDevre dışı bırakıldığında: noktalama işareti ile ayrılmış kelimeler seçilir.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"cm_smartIndent": {
|
||||||
|
"message": "Akıllı girinti kullanma",
|
||||||
|
"description": "Label for the checkbox controlling smart indentation option for the style editor."
|
||||||
|
},
|
||||||
"cm_tabSize": {
|
"cm_tabSize": {
|
||||||
"message": "Tab büyüklüğü",
|
"message": "Tab büyüklüğü",
|
||||||
"description": "Label for the text box controlling tab size option for the style editor."
|
"description": "Label for the text box controlling tab size option for the style editor."
|
||||||
|
@ -120,10 +168,30 @@
|
||||||
"message": "Tema",
|
"message": "Tema",
|
||||||
"description": "Label for the style editor's CSS theme."
|
"description": "Label for the style editor's CSS theme."
|
||||||
},
|
},
|
||||||
|
"colorpickerSwitchFormatTooltip": {
|
||||||
|
"message": "Format değişimleri: HEX -> RGB -> HSL.\nYönü ters çevirmek için Shift tuşunu basılı tutup tıklatın.\nAyrıca PgUp (PageUp), PgDn (PageDown) tuşları ile.",
|
||||||
|
"description": "Tooltip for the switch button in the color picker popup in the style editor."
|
||||||
|
},
|
||||||
|
"colorpickerTooltip": {
|
||||||
|
"message": "Renk seçiciyi aç",
|
||||||
|
"description": "Tooltip for the colored squares shown before CSS colors in the style editor."
|
||||||
|
},
|
||||||
"configOnChange": {
|
"configOnChange": {
|
||||||
"message": "değişiklikte",
|
"message": "değişiklikte",
|
||||||
"description": "VERY SHORT label for the checkbox in style config dialog after the save button - when enabled the changes in the dialog are saved and applied automatically without the need to press the Save button"
|
"description": "VERY SHORT label for the checkbox in style config dialog after the save button - when enabled the changes in the dialog are saved and applied automatically without the need to press the Save button"
|
||||||
},
|
},
|
||||||
|
"configOnChangeTooltip": {
|
||||||
|
"message": "Otomatik kaydetme ve değişiklikleri otomatik olarak uygulama",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"configureStyle": {
|
||||||
|
"message": "Yapılandır",
|
||||||
|
"description": "Label for the button to configure usercss userstyle"
|
||||||
|
},
|
||||||
|
"configureStyleOnHomepage": {
|
||||||
|
"message": "Ana sayfada yapılandır",
|
||||||
|
"description": "Label for the button to configure userstyles.org userstyle"
|
||||||
|
},
|
||||||
"confirmCancel": {
|
"confirmCancel": {
|
||||||
"message": "İptal",
|
"message": "İptal",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
@ -180,6 +248,10 @@
|
||||||
"message": "Güncelleme tarihi",
|
"message": "Güncelleme tarihi",
|
||||||
"description": "Option text for the user to sort the style by last update date"
|
"description": "Option text for the user to sort the style by last update date"
|
||||||
},
|
},
|
||||||
|
"dbError": {
|
||||||
|
"message": "Stylus veritabanı kullanılırken bir hata oluştu. Olası çözümler içeren bir web sayfasını ziyaret etmek ister misiniz?",
|
||||||
|
"description": "Prompt when a DB error is encountered"
|
||||||
|
},
|
||||||
"defaultTheme": {
|
"defaultTheme": {
|
||||||
"message": "öntanımlı",
|
"message": "öntanımlı",
|
||||||
"description": "Default CodeMirror CSS theme option on the edit style page"
|
"description": "Default CodeMirror CSS theme option on the edit style page"
|
||||||
|
@ -204,6 +276,14 @@
|
||||||
"message": "Devre dışı bırak",
|
"message": "Devre dışı bırak",
|
||||||
"description": "Label for the button to disable a style"
|
"description": "Label for the button to disable a style"
|
||||||
},
|
},
|
||||||
|
"dragDropMessage": {
|
||||||
|
"message": "İçe aktarmak için yedek dosyanızı bu sayfada herhangi bir yere bırakın.",
|
||||||
|
"description": "Drag'n'drop message"
|
||||||
|
},
|
||||||
|
"dragDropUsercssTabstrip": {
|
||||||
|
"message": "Dosyayı yüklemek için sekme şeridine (sekme başlıklarının gösterildiği alan) bırakın.",
|
||||||
|
"description": "Message popup shown when erroneously dropping a usercss file into the manager page"
|
||||||
|
},
|
||||||
"editDeleteText": {
|
"editDeleteText": {
|
||||||
"message": "Sil",
|
"message": "Sil",
|
||||||
"description": "Label for the context menu item in the editor to delete selected text"
|
"description": "Label for the context menu item in the editor to delete selected text"
|
||||||
|
@ -237,6 +317,14 @@
|
||||||
"message": "Etkinleştir",
|
"message": "Etkinleştir",
|
||||||
"description": "Label for the button to enable a style"
|
"description": "Label for the button to enable a style"
|
||||||
},
|
},
|
||||||
|
"excludeStyleByDomainLabel": {
|
||||||
|
"message": "Mevcut alan adını hariç tut",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"excludeStyleByUrlLabel": {
|
||||||
|
"message": "Mevcut URL'yi hariç tut",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"exportLabel": {
|
"exportLabel": {
|
||||||
"message": "Dışa aktar",
|
"message": "Dışa aktar",
|
||||||
"description": "Label for the button to export a style ('edit' page) or all styles ('manage' page)"
|
"description": "Label for the button to export a style ('edit' page) or all styles ('manage' page)"
|
||||||
|
@ -249,10 +337,34 @@
|
||||||
"message": "Anasayfa",
|
"message": "Anasayfa",
|
||||||
"description": "Label for the external link to style's homepage"
|
"description": "Label for the external link to style's homepage"
|
||||||
},
|
},
|
||||||
|
"externalLink": {
|
||||||
|
"message": "Harici bağlantı",
|
||||||
|
"description": "Label for external links"
|
||||||
|
},
|
||||||
"externalSupport": {
|
"externalSupport": {
|
||||||
"message": "Destek",
|
"message": "Destek",
|
||||||
"description": "Label for the external link to style's support site"
|
"description": "Label for the external link to style's support site"
|
||||||
},
|
},
|
||||||
|
"externalUsercssDocument": {
|
||||||
|
"message": "Usercss belgeleri",
|
||||||
|
"description": "Label for the external link to usercss documentation"
|
||||||
|
},
|
||||||
|
"filteredStyles": {
|
||||||
|
"message": "Toplam $numTotal$ gösterilen $numShown$",
|
||||||
|
"description": "TL note - make this message short",
|
||||||
|
"placeholders": {
|
||||||
|
"numTotal": {
|
||||||
|
"content": "$2"
|
||||||
|
},
|
||||||
|
"numShown": {
|
||||||
|
"content": "$1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filteredStylesAllHidden": {
|
||||||
|
"message": "Şu anda uygulanan filtreler hiçbir stille eşleşmiyor",
|
||||||
|
"description": "Text shown when no styles match currently applied filter in the style manager"
|
||||||
|
},
|
||||||
"findStyles": {
|
"findStyles": {
|
||||||
"message": "Stil bul",
|
"message": "Stil bul",
|
||||||
"description": "Text for a link that gets a list of styles for the current site"
|
"description": "Text for a link that gets a list of styles for the current site"
|
||||||
|
@ -261,10 +373,22 @@
|
||||||
"message": "Bu site için başka stiller bul",
|
"message": "Bu site için başka stiller bul",
|
||||||
"description": "Text for a link that gets a list of styles for the current site"
|
"description": "Text for a link that gets a list of styles for the current site"
|
||||||
},
|
},
|
||||||
|
"findStylesInline": {
|
||||||
|
"message": "Hizada",
|
||||||
|
"description": "Text for a checkbox that opens search results 'inline' (within the Stylus popup window)"
|
||||||
|
},
|
||||||
|
"findStylesInlineTooltip": {
|
||||||
|
"message": "Arama sonuçlarını bu pencerede görüntüleyin.",
|
||||||
|
"description": "Text for a checkbox that displays search results within the Stylus popup."
|
||||||
|
},
|
||||||
"genericAdd": {
|
"genericAdd": {
|
||||||
"message": "Ekle",
|
"message": "Ekle",
|
||||||
"description": "Used in various places for an action that adds something"
|
"description": "Used in various places for an action that adds something"
|
||||||
},
|
},
|
||||||
|
"genericClone": {
|
||||||
|
"message": "Klon",
|
||||||
|
"description": "Used in various places for an action that clones something"
|
||||||
|
},
|
||||||
"genericDisabledLabel": {
|
"genericDisabledLabel": {
|
||||||
"message": "Devre dışı",
|
"message": "Devre dışı",
|
||||||
"description": "Used in various lists/options to indicate that something is disabled"
|
"description": "Used in various lists/options to indicate that something is disabled"
|
||||||
|
@ -289,6 +413,10 @@
|
||||||
"message": "Önceki",
|
"message": "Önceki",
|
||||||
"description": "Used in various places to select/perform the previous step/action"
|
"description": "Used in various places to select/perform the previous step/action"
|
||||||
},
|
},
|
||||||
|
"genericResetLabel": {
|
||||||
|
"message": "Yenile",
|
||||||
|
"description": "Used in various parts of UI to indicate that something may be reset to its original state"
|
||||||
|
},
|
||||||
"genericSavedMessage": {
|
"genericSavedMessage": {
|
||||||
"message": "Kaydedildi",
|
"message": "Kaydedildi",
|
||||||
"description": "Used in various parts of the UI to indicate that something was saved"
|
"description": "Used in various parts of the UI to indicate that something was saved"
|
||||||
|
@ -305,10 +433,26 @@
|
||||||
"message": "Yardım",
|
"message": "Yardım",
|
||||||
"description": "Alternate text for help buttons"
|
"description": "Alternate text for help buttons"
|
||||||
},
|
},
|
||||||
|
"helpKeyMapCommand": {
|
||||||
|
"message": "Bir komut adı yazın",
|
||||||
|
"description": "Placeholder text of inputbox in keymap help popup on the edit style page. Must be very short"
|
||||||
|
},
|
||||||
|
"helpKeyMapHotkey": {
|
||||||
|
"message": "Bir kısayol tuşuna basın",
|
||||||
|
"description": "Placeholder text of inputbox in keymap help popup on the edit style page. Must be very short"
|
||||||
|
},
|
||||||
|
"hostDisabled": {
|
||||||
|
"message": "Bu ana bilgisayar, kullanılan tarayıcının mevcut sürümündeki bir hata nedeniyle devre dışı bırakıldı",
|
||||||
|
"description": "Tooltip for cloud host disabled"
|
||||||
|
},
|
||||||
"importAppendLabel": {
|
"importAppendLabel": {
|
||||||
"message": "Stile ekle",
|
"message": "Stile ekle",
|
||||||
"description": "Label for the button to import a style and append to the existing sections"
|
"description": "Label for the button to import a style and append to the existing sections"
|
||||||
},
|
},
|
||||||
|
"importAppendTooltip": {
|
||||||
|
"message": "İçe aktarılan stili geçerli stile ekleme",
|
||||||
|
"description": "Tooltip for the button to import a style and append to the existing sections"
|
||||||
|
},
|
||||||
"importLabel": {
|
"importLabel": {
|
||||||
"message": "İçe aktar",
|
"message": "İçe aktar",
|
||||||
"description": "Label for the button to import a style ('edit' page) or all styles ('manage' page)"
|
"description": "Label for the button to import a style ('edit' page) or all styles ('manage' page)"
|
||||||
|
@ -317,10 +461,18 @@
|
||||||
"message": "Stilin üzerine yaz",
|
"message": "Stilin üzerine yaz",
|
||||||
"description": "Label for the button to import and overwrite current style"
|
"description": "Label for the button to import and overwrite current style"
|
||||||
},
|
},
|
||||||
|
"importReplaceTooltip": {
|
||||||
|
"message": "Geçerli stilin içeriğini atın ve içe aktarılan stil ile üzerine yazın",
|
||||||
|
"description": "Label for the button to import and overwrite current style"
|
||||||
|
},
|
||||||
"importReportLegendAdded": {
|
"importReportLegendAdded": {
|
||||||
"message": "eklendi",
|
"message": "eklendi",
|
||||||
"description": "Text after the number of styles added in the report shown after importing styles"
|
"description": "Text after the number of styles added in the report shown after importing styles"
|
||||||
},
|
},
|
||||||
|
"importReportLegendUpdatedBoth": {
|
||||||
|
"message": "hem meta bilgi hem de kod güncellendi",
|
||||||
|
"description": "Text after the number of styles updated entirely in the report shown after importing styles"
|
||||||
|
},
|
||||||
"importReportLegendUpdatedCode": {
|
"importReportLegendUpdatedCode": {
|
||||||
"message": "güncellenmiş kod",
|
"message": "güncellenmiş kod",
|
||||||
"description": "Text after the number of styles with updated code (meta info is unchanged) in the report shown after importing styles"
|
"description": "Text after the number of styles with updated code (meta info is unchanged) in the report shown after importing styles"
|
||||||
|
@ -640,6 +792,10 @@
|
||||||
"message": "Güncelleme kontrolü geçmişi",
|
"message": "Güncelleme kontrolü geçmişi",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"updateCheckSkippedMaybeLocallyEdited": {
|
||||||
|
"message": "Bu stil yerel olarak düzenlenmiş olabilir.",
|
||||||
|
"description": "Text that displays when an update check skipped updating the style to avoid losing possible local modifications"
|
||||||
|
},
|
||||||
"updateCheckSucceededNoUpdate": {
|
"updateCheckSucceededNoUpdate": {
|
||||||
"message": "Stil güncel.",
|
"message": "Stil güncel.",
|
||||||
"description": "Text that displays when an update check completed and no update is available"
|
"description": "Text that displays when an update check completed and no update is available"
|
||||||
|
@ -652,6 +808,38 @@
|
||||||
"message": "Kurulan güncellemeler:",
|
"message": "Kurulan güncellemeler:",
|
||||||
"description": "Text that displays when an update is installed on options page. Followed by the number of currently installed updates."
|
"description": "Text that displays when an update is installed on options page. Followed by the number of currently installed updates."
|
||||||
},
|
},
|
||||||
|
"usercssAvoidOverwriting": {
|
||||||
|
"message": "Mevcut bir stilin üzerine yazmaktan kaçınmak için lütfen @name veya @ ad alanının değerini değiştirin.",
|
||||||
|
"description": "Shown in a message box when attempting to save a new Usercss style that would overwrite an existing one."
|
||||||
|
},
|
||||||
|
"usercssConfigIncomplete": {
|
||||||
|
"message": "Stil, yapılandırma iletişim kutusu gösterildikten sonra güncellendi veya silindi. Bu değişkenler, stilin meta verilerini bozmamak için kaydedilmedi:",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"usercssEditorNamePlaceholder": {
|
||||||
|
"message": "Kodda @name belirtin",
|
||||||
|
"description": "Placeholder text for the empty name input field when creating a new Usercss style"
|
||||||
|
},
|
||||||
|
"usercssReplaceTemplateConfirmation": {
|
||||||
|
"message": "Yeni Usercss stilleri için varsayılan şablonu geçerli kodla değiştir?",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"usercssReplaceTemplateName": {
|
||||||
|
"message": "Boş @name, varsayılan şablonun yerini alır",
|
||||||
|
"description": "The text shown after @name when creating a new Usercss style"
|
||||||
|
},
|
||||||
|
"usercssReplaceTemplateSectionBody": {
|
||||||
|
"message": "Kodu buraya ekle...",
|
||||||
|
"description": "The code placeholder comment in a new style created by clicking 'Write style' in the popup"
|
||||||
|
},
|
||||||
|
"versionInvalidOlder": {
|
||||||
|
"message": "Sürüm, kurulu stillerden daha eski.",
|
||||||
|
"description": "Displayed when the version of style is older than the installed one"
|
||||||
|
},
|
||||||
|
"writeStyleFor": {
|
||||||
|
"message": "Şunun için stil yaz:",
|
||||||
|
"description": "Label for toolbar pop-up that precedes the links to write a new style"
|
||||||
|
},
|
||||||
"writeStyleForURL": {
|
"writeStyleForURL": {
|
||||||
"message": "bu URL",
|
"message": "bu URL",
|
||||||
"description": "Text for link in toolbar pop-up to write a new style for the current URL"
|
"description": "Text for link in toolbar pop-up to write a new style for the current URL"
|
||||||
|
@ -660,14 +848,34 @@
|
||||||
"message": "Dropbox'tan aktar",
|
"message": "Dropbox'tan aktar",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"syncDropboxDeprecated": {
|
||||||
|
"message": "Dropbox içe/dışa aktarma, seçenekler sayfasında daha gelişmiş bir stil senkronizasyonu ile değiştirilir.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"retrieveDropboxSync": {
|
"retrieveDropboxSync": {
|
||||||
"message": "Dropbox'a aktar",
|
"message": "Dropbox'a aktar",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"overwriteFileExport": {
|
||||||
|
"message": "Mevcut bir dosyanın üzerine yazmak istiyor musunuz?",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"exportSavedSuccess": {
|
"exportSavedSuccess": {
|
||||||
"message": "Dosya başarıyla kaydedildi",
|
"message": "Dosya başarıyla kaydedildi",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"noFileToImport": {
|
||||||
|
"message": "Stillerinizi içe aktarmak için önce dışa aktarmanız gerekir.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"connectingDropbox": {
|
||||||
|
"message": "Dropbox'a bağlanıyor...",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"connectingDropboxNotAllowed": {
|
||||||
|
"message": "Dropbox'a bağlanmak yalnızca doğrudan web mağazasından yüklenen uygulamalarda kullanılabilir",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"gettingStyles": {
|
"gettingStyles": {
|
||||||
"message": "Tüm stiller alınıyor...",
|
"message": "Tüm stiller alınıyor...",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
@ -676,6 +884,10 @@
|
||||||
"message": "Stiller sıkıştırılıyor...",
|
"message": "Stiller sıkıştırılıyor...",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"unzipStyles": {
|
||||||
|
"message": "Stiller açılıyor...",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"readingStyles": {
|
"readingStyles": {
|
||||||
"message": "Stiller okunuyor...",
|
"message": "Stiller okunuyor...",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
|
|
@ -125,7 +125,7 @@
|
||||||
"description": "Label for the checkbox in the style editor."
|
"description": "Label for the checkbox in the style editor."
|
||||||
},
|
},
|
||||||
"cm_autocompleteOnTyping": {
|
"cm_autocompleteOnTyping": {
|
||||||
"message": "输入时自动完成",
|
"message": "输入时自动补全",
|
||||||
"description": "Label for the checkbox in the style editor."
|
"description": "Label for the checkbox in the style editor."
|
||||||
},
|
},
|
||||||
"cm_colorpicker": {
|
"cm_colorpicker": {
|
||||||
|
@ -133,7 +133,7 @@
|
||||||
"description": "Label for the checkbox controlling colorpicker option for the style editor."
|
"description": "Label for the checkbox controlling colorpicker option for the style editor."
|
||||||
},
|
},
|
||||||
"cm_indentWithTabs": {
|
"cm_indentWithTabs": {
|
||||||
"message": "使用 Tab 智能缩进",
|
"message": "使用Tab智能缩进",
|
||||||
"description": "Label for the checkbox controlling tabs with smart indentation option for the style editor."
|
"description": "Label for the checkbox controlling tabs with smart indentation option for the style editor."
|
||||||
},
|
},
|
||||||
"cm_keyMap": {
|
"cm_keyMap": {
|
||||||
|
@ -153,7 +153,7 @@
|
||||||
"description": "Style editor's 'highglight' drop-down list option: highlight the occurrences of currently selected text"
|
"description": "Style editor's 'highglight' drop-down list option: highlight the occurrences of currently selected text"
|
||||||
},
|
},
|
||||||
"cm_matchHighlightToken": {
|
"cm_matchHighlightToken": {
|
||||||
"message": "光标所在 token 字段",
|
"message": "光标所在token字段",
|
||||||
"description": "Style editor's 'highglight' drop-down list option: highlight the occurrences of the word/token under cursor even if nothing is selected"
|
"description": "Style editor's 'highglight' drop-down list option: highlight the occurrences of the word/token under cursor even if nothing is selected"
|
||||||
},
|
},
|
||||||
"cm_resizeGripHint": {
|
"cm_resizeGripHint": {
|
||||||
|
@ -244,6 +244,14 @@
|
||||||
"message": "是",
|
"message": "是",
|
||||||
"description": "'Yes' button in a confirm dialog"
|
"description": "'Yes' button in a confirm dialog"
|
||||||
},
|
},
|
||||||
|
"copied": {
|
||||||
|
"message": "已复制到粘贴板",
|
||||||
|
"description": "Message shown when content has been copied to the clipboard"
|
||||||
|
},
|
||||||
|
"copy": {
|
||||||
|
"message": "复制到粘贴板",
|
||||||
|
"description": "Tooltip for elements which can be copied"
|
||||||
|
},
|
||||||
"dateInstalled": {
|
"dateInstalled": {
|
||||||
"message": "安装日期",
|
"message": "安装日期",
|
||||||
"description": "Option text for the user to sort the style by install date"
|
"description": "Option text for the user to sort the style by install date"
|
||||||
|
@ -284,6 +292,10 @@
|
||||||
"message": "把 JSON 备份文件拖放到页面的任意位置,即可导入",
|
"message": "把 JSON 备份文件拖放到页面的任意位置,即可导入",
|
||||||
"description": "Drag'n'drop message"
|
"description": "Drag'n'drop message"
|
||||||
},
|
},
|
||||||
|
"dragDropUsercssTabstrip": {
|
||||||
|
"message": "要安装文件,就将其放在选项卡条(显示选项卡标题的区域)上。",
|
||||||
|
"description": "Message popup shown when erroneously dropping a usercss file into the manager page"
|
||||||
|
},
|
||||||
"editDeleteText": {
|
"editDeleteText": {
|
||||||
"message": "删除",
|
"message": "删除",
|
||||||
"description": "Label for the context menu item in the editor to delete selected text"
|
"description": "Label for the context menu item in the editor to delete selected text"
|
||||||
|
@ -441,6 +453,10 @@
|
||||||
"message": "按下热键",
|
"message": "按下热键",
|
||||||
"description": "Placeholder text of inputbox in keymap help popup on the edit style page. Must be very short"
|
"description": "Placeholder text of inputbox in keymap help popup on the edit style page. Must be very short"
|
||||||
},
|
},
|
||||||
|
"hostDisabled": {
|
||||||
|
"message": "由于当前使用的浏览器版本中存在的错误,此主机已被禁用",
|
||||||
|
"description": "Tooltip for cloud host disabled"
|
||||||
|
},
|
||||||
"importAppendLabel": {
|
"importAppendLabel": {
|
||||||
"message": "追加到样式",
|
"message": "追加到样式",
|
||||||
"description": "Label for the button to import a style and append to the existing sections"
|
"description": "Label for the button to import a style and append to the existing sections"
|
||||||
|
@ -609,6 +625,14 @@
|
||||||
"message": "查看文件时发生错误",
|
"message": "查看文件时发生错误",
|
||||||
"description": "The label of live-reload error"
|
"description": "The label of live-reload error"
|
||||||
},
|
},
|
||||||
|
"liveReloadInstallHint": {
|
||||||
|
"message": "保持此选项卡为打开状态,将在外部更改后自动更新样式。",
|
||||||
|
"description": "The label of live-reload feature"
|
||||||
|
},
|
||||||
|
"liveReloadInstallHintFF": {
|
||||||
|
"message": "保持此选项卡和原始选项卡处于打开状态,将在外部更改时自动重新更新样式。",
|
||||||
|
"description": "The extra hint of live-reload feature shown only for file:// URLs in Firefox"
|
||||||
|
},
|
||||||
"liveReloadLabel": {
|
"liveReloadLabel": {
|
||||||
"message": "动态刷新",
|
"message": "动态刷新",
|
||||||
"description": "The label of live-reload feature"
|
"description": "The label of live-reload feature"
|
||||||
|
@ -642,7 +666,7 @@
|
||||||
"description": "VERY SHORT label for the checkbox next to the 'Write new style' button in the style manager"
|
"description": "VERY SHORT label for the checkbox next to the 'Write new style' button in the style manager"
|
||||||
},
|
},
|
||||||
"manageNewUI": {
|
"manageNewUI": {
|
||||||
"message": "新的样式管理界面",
|
"message": "新版管理器",
|
||||||
"description": "Label for the checkbox that toggles the new UI on manage page"
|
"description": "Label for the checkbox that toggles the new UI on manage page"
|
||||||
},
|
},
|
||||||
"manageOnlyDisabled": {
|
"manageOnlyDisabled": {
|
||||||
|
@ -905,6 +929,10 @@
|
||||||
"message": "管理样式",
|
"message": "管理样式",
|
||||||
"description": "Link to open the manage page."
|
"description": "Link to open the manage page."
|
||||||
},
|
},
|
||||||
|
"openOptions": {
|
||||||
|
"message": "选项",
|
||||||
|
"description": "Go to Options UI"
|
||||||
|
},
|
||||||
"openStylesManager": {
|
"openStylesManager": {
|
||||||
"message": "打开样式管理器",
|
"message": "打开样式管理器",
|
||||||
"description": "Label for the style maanger opener in the browser action context menu."
|
"description": "Label for the style maanger opener in the browser action context menu."
|
||||||
|
@ -965,6 +993,10 @@
|
||||||
"message": "检测更新",
|
"message": "检测更新",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"optionsCustomizeSync": {
|
||||||
|
"message": "同步到云端",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"optionsHeading": {
|
"optionsHeading": {
|
||||||
"message": "选项",
|
"message": "选项",
|
||||||
"description": "Heading for options section on manage page."
|
"description": "Heading for options section on manage page."
|
||||||
|
@ -1009,6 +1041,70 @@
|
||||||
"message": "每隔 N 小时,检查所有样式更新(0 为关闭检查)",
|
"message": "每隔 N 小时,检查所有样式更新(0 为关闭检查)",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"optionsSyncNone": {
|
||||||
|
"message": "无",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"optionsSyncConnect": {
|
||||||
|
"message": "连接",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"optionsSyncDisconnect": {
|
||||||
|
"message": "断开连接",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"optionsSyncSyncNow": {
|
||||||
|
"message": "现在同步",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"optionsSyncLogin": {
|
||||||
|
"message": "登录",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"optionsSyncStatusPull": {
|
||||||
|
"message": "正在获取样式 $loaded$ 中的 $total$",
|
||||||
|
"description": "",
|
||||||
|
"placeholders": {
|
||||||
|
"loaded": {
|
||||||
|
"content": "$1"
|
||||||
|
},
|
||||||
|
"total": {
|
||||||
|
"content": "$2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"optionsSyncStatusPush": {
|
||||||
|
"message": "正在上传样式 $loaded$ 中的 $total$",
|
||||||
|
"description": "",
|
||||||
|
"placeholders": {
|
||||||
|
"loaded": {
|
||||||
|
"content": "$1"
|
||||||
|
},
|
||||||
|
"total": {
|
||||||
|
"content": "$2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"optionsSyncStatusSyncing": {
|
||||||
|
"message": "同步中...",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"optionsSyncStatusConnecting": {
|
||||||
|
"message": "连接中...",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"optionsSyncStatusConnected": {
|
||||||
|
"message": "已连接",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"optionsSyncStatusDisconnecting": {
|
||||||
|
"message": "正在断开连接...",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"optionsSyncStatusDisconnected": {
|
||||||
|
"message": "已断开连接",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"paginationCurrent": {
|
"paginationCurrent": {
|
||||||
"message": "当前页数",
|
"message": "当前页数",
|
||||||
"description": "Tooltip for the current page index in search results"
|
"description": "Tooltip for the current page index in search results"
|
||||||
|
@ -1085,6 +1181,10 @@
|
||||||
"message": "无需保存即可临时应用样式预览效果。保存以使更改永久生效。",
|
"message": "无需保存即可临时应用样式预览效果。保存以使更改永久生效。",
|
||||||
"description": "Tooltip for the checkbox in style editor to enable live preview while editing."
|
"description": "Tooltip for the checkbox in style editor to enable live preview while editing."
|
||||||
},
|
},
|
||||||
|
"reload": {
|
||||||
|
"message": "重新加载 Stylus 扩展程序",
|
||||||
|
"description": "Context menu reload"
|
||||||
|
},
|
||||||
"replace": {
|
"replace": {
|
||||||
"message": "替换",
|
"message": "替换",
|
||||||
"description": "Label before the replace input field in the editor shown on Ctrl-H"
|
"description": "Label before the replace input field in the editor shown on Ctrl-H"
|
||||||
|
@ -1209,6 +1309,10 @@
|
||||||
"message": "格式化",
|
"message": "格式化",
|
||||||
"description": "Label for the CSS-beautifier button on the edit style page"
|
"description": "Label for the CSS-beautifier button on the edit style page"
|
||||||
},
|
},
|
||||||
|
"styleBeautifyHint": {
|
||||||
|
"message": "提示: 你可以不显示此面板, 而是用右键“美化”按钮 或用下面定义的快捷键来美化.",
|
||||||
|
"description": "Hint shown inside the CSS-beautifier panel"
|
||||||
|
},
|
||||||
"styleBeautifyIndentConditional": {
|
"styleBeautifyIndentConditional": {
|
||||||
"message": "缩进 @media、@supports",
|
"message": "缩进 @media、@supports",
|
||||||
"description": "CSS-beautifier option"
|
"description": "CSS-beautifier option"
|
||||||
|
@ -1218,7 +1322,7 @@
|
||||||
"description": "CSS-beautifier option"
|
"description": "CSS-beautifier option"
|
||||||
},
|
},
|
||||||
"styleCancelEditLabel": {
|
"styleCancelEditLabel": {
|
||||||
"message": "返回管理页面",
|
"message": "返回管理器",
|
||||||
"description": "Label for cancel button for style editing"
|
"description": "Label for cancel button for style editing"
|
||||||
},
|
},
|
||||||
"styleChangesNotSaved": {
|
"styleChangesNotSaved": {
|
||||||
|
@ -1492,6 +1596,10 @@
|
||||||
"message": "导出至 Dropbox",
|
"message": "导出至 Dropbox",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"syncDropboxDeprecated": {
|
||||||
|
"message": "在选项页面中, Dropbox 导入/导出 已经替换为更高级的样式同步方式。",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"retrieveDropboxSync": {
|
"retrieveDropboxSync": {
|
||||||
"message": "从 Dropbox 导入",
|
"message": "从 Dropbox 导入",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
|
|
@ -1309,6 +1309,10 @@
|
||||||
"message": "美化",
|
"message": "美化",
|
||||||
"description": "Label for the CSS-beautifier button on the edit style page"
|
"description": "Label for the CSS-beautifier button on the edit style page"
|
||||||
},
|
},
|
||||||
|
"styleBeautifyHint": {
|
||||||
|
"message": "提示:右鍵點選「美化」按鈕或使用下面定義的鍵盤快捷鍵來美化而不顯示此面板",
|
||||||
|
"description": "Hint shown inside the CSS-beautifier panel"
|
||||||
|
},
|
||||||
"styleBeautifyIndentConditional": {
|
"styleBeautifyIndentConditional": {
|
||||||
"message": "縮排 @media, @supports",
|
"message": "縮排 @media, @supports",
|
||||||
"description": "CSS-beautifier option"
|
"description": "CSS-beautifier option"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* global download prefs openURL FIREFOX CHROME
|
/* global download prefs openURL FIREFOX CHROME
|
||||||
URLS ignoreChromeError usercssHelper
|
URLS ignoreChromeError usercssHelper
|
||||||
styleManager msg navigatorUtil workerUtil contentScripts sync
|
styleManager msg navigatorUtil workerUtil contentScripts sync
|
||||||
findExistingTab createTab activateTab isTabReplaceable getActiveTab
|
findExistingTab activateTab isTabReplaceable getActiveTab
|
||||||
tabManager colorScheme */
|
tabManager colorScheme */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
@ -10,6 +10,20 @@ var backgroundWorker = workerUtil.createWorker({
|
||||||
url: '/background/background-worker.js'
|
url: '/background/background-worker.js'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-var
|
||||||
|
var browserCommands, contextMenus;
|
||||||
|
|
||||||
|
// *************************************************************************
|
||||||
|
// browser commands
|
||||||
|
browserCommands = {
|
||||||
|
openManage,
|
||||||
|
openOptions: () => openManage({options: true}),
|
||||||
|
styleDisableAll(info) {
|
||||||
|
prefs.set('disableAll', info ? info.checked : !prefs.get('disableAll'));
|
||||||
|
},
|
||||||
|
reload: () => chrome.runtime.reload(),
|
||||||
|
};
|
||||||
|
|
||||||
window.API_METHODS = Object.assign(window.API_METHODS || {}, {
|
window.API_METHODS = Object.assign(window.API_METHODS || {}, {
|
||||||
deleteStyle: styleManager.deleteStyle,
|
deleteStyle: styleManager.deleteStyle,
|
||||||
editSave: styleManager.editSave,
|
editSave: styleManager.editSave,
|
||||||
|
@ -70,8 +84,8 @@ window.API_METHODS = Object.assign(window.API_METHODS || {}, {
|
||||||
},
|
},
|
||||||
|
|
||||||
optionsCustomizeHotkeys() {
|
optionsCustomizeHotkeys() {
|
||||||
return browser.runtime.openOptionsPage()
|
return browserCommands.openOptions()
|
||||||
.then(() => new Promise(resolve => setTimeout(resolve, 100)))
|
.then(() => new Promise(resolve => setTimeout(resolve, 500)))
|
||||||
.then(() => msg.broadcastExtension({method: 'optionsCustomizeHotkeys'}));
|
.then(() => msg.broadcastExtension({method: 'optionsCustomizeHotkeys'}));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -86,9 +100,6 @@ window.API_METHODS = Object.assign(window.API_METHODS || {}, {
|
||||||
openManage
|
openManage
|
||||||
});
|
});
|
||||||
|
|
||||||
// eslint-disable-next-line no-var
|
|
||||||
var browserCommands, contextMenus;
|
|
||||||
|
|
||||||
// *************************************************************************
|
// *************************************************************************
|
||||||
// register all listeners
|
// register all listeners
|
||||||
msg.on(onRuntimeMessage);
|
msg.on(onRuntimeMessage);
|
||||||
|
@ -148,17 +159,6 @@ chrome.runtime.onInstalled.addListener(({reason}) => {
|
||||||
delete localStorage.codeMirrorThemes;
|
delete localStorage.codeMirrorThemes;
|
||||||
});
|
});
|
||||||
|
|
||||||
// *************************************************************************
|
|
||||||
// browser commands
|
|
||||||
browserCommands = {
|
|
||||||
openManage,
|
|
||||||
openOptions: () => openManage({options: true}),
|
|
||||||
styleDisableAll(info) {
|
|
||||||
prefs.set('disableAll', info ? info.checked : !prefs.get('disableAll'));
|
|
||||||
},
|
|
||||||
reload: () => chrome.runtime.reload(),
|
|
||||||
};
|
|
||||||
|
|
||||||
// *************************************************************************
|
// *************************************************************************
|
||||||
// context menus
|
// context menus
|
||||||
contextMenus = {
|
contextMenus = {
|
||||||
|
@ -218,7 +218,7 @@ function createContextMenus(ids) {
|
||||||
|
|
||||||
if (chrome.contextMenus) {
|
if (chrome.contextMenus) {
|
||||||
// circumvent the bug with disabling check marks in Chrome 62-64
|
// circumvent the bug with disabling check marks in Chrome 62-64
|
||||||
const toggleCheckmark = CHROME >= 3172 && CHROME <= 3288 ?
|
const toggleCheckmark = CHROME >= 62 && CHROME <= 64 ?
|
||||||
(id => chrome.contextMenus.remove(id, () => createContextMenus([id]) + ignoreChromeError())) :
|
(id => chrome.contextMenus.remove(id, () => createContextMenus([id]) + ignoreChromeError())) :
|
||||||
((id, checked) => chrome.contextMenus.update(id, {checked}, ignoreChromeError));
|
((id, checked) => chrome.contextMenus.update(id, {checked}, ignoreChromeError));
|
||||||
|
|
||||||
|
@ -337,7 +337,7 @@ function openManage({options = false, search} = {}) {
|
||||||
if (isTabReplaceable(tab, url)) {
|
if (isTabReplaceable(tab, url)) {
|
||||||
return activateTab(tab, {url});
|
return activateTab(tab, {url});
|
||||||
}
|
}
|
||||||
return createTab({url});
|
return browser.tabs.create({url});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* global msg queryTabs ignoreChromeError URLS */
|
/* global msg ignoreChromeError URLS */
|
||||||
/* exported contentScripts */
|
/* exported contentScripts */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ const contentScripts = (() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
function injectToAllTabs() {
|
function injectToAllTabs() {
|
||||||
return queryTabs({}).then(tabs => {
|
return browser.tabs.query({}).then(tabs => {
|
||||||
for (const tab of tabs) {
|
for (const tab of tabs) {
|
||||||
// skip unloaded/discarded/chrome tabs
|
// skip unloaded/discarded/chrome tabs
|
||||||
if (!tab.width || tab.discarded || !URLS.supported(tab.url)) continue;
|
if (!tab.width || tab.discarded || !URLS.supported(tab.url)) continue;
|
||||||
|
|
|
@ -1,46 +1,29 @@
|
||||||
/* global promisify */
|
/* global chromeLocal */
|
||||||
/* exported createChromeStorageDB */
|
/* exported createChromeStorageDB */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
function createChromeStorageDB() {
|
function createChromeStorageDB() {
|
||||||
const get = promisify(chrome.storage.local.get.bind(chrome.storage.local));
|
|
||||||
const set = promisify(chrome.storage.local.set.bind(chrome.storage.local));
|
|
||||||
const remove = promisify(chrome.storage.local.remove.bind(chrome.storage.local));
|
|
||||||
|
|
||||||
let INC;
|
let INC;
|
||||||
|
|
||||||
const PREFIX = 'style-';
|
const PREFIX = 'style-';
|
||||||
const METHODS = {
|
const METHODS = {
|
||||||
// FIXME: we don't use this method at all. Should we remove this?
|
// FIXME: we don't use this method at all. Should we remove this?
|
||||||
get: id => get(PREFIX + id)
|
get: id => chromeLocal.getValue(PREFIX + id),
|
||||||
.then(result => result[PREFIX + id]),
|
put: obj =>
|
||||||
put: obj => Promise.resolve()
|
// FIXME: should we clone the object?
|
||||||
.then(() => {
|
Promise.resolve(!obj.id && prepareInc().then(() => Object.assign(obj, {id: INC++})))
|
||||||
if (!obj.id) {
|
.then(() => chromeLocal.setValue(PREFIX + obj.id, obj))
|
||||||
return prepareInc()
|
.then(() => obj.id),
|
||||||
.then(() => {
|
|
||||||
// FIXME: should we clone the object?
|
|
||||||
obj.id = INC++;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(() => set({[PREFIX + obj.id]: obj}))
|
|
||||||
.then(() => obj.id),
|
|
||||||
putMany: items => prepareInc()
|
putMany: items => prepareInc()
|
||||||
.then(() => {
|
.then(() =>
|
||||||
for (const item of items) {
|
chromeLocal.set(items.reduce((data, item) => {
|
||||||
if (!item.id) {
|
if (!item.id) item.id = INC++;
|
||||||
item.id = INC++;
|
data[PREFIX + item.id] = item;
|
||||||
}
|
return data;
|
||||||
}
|
}, {})))
|
||||||
return set(items.reduce((obj, curr) => {
|
|
||||||
obj[PREFIX + curr.id] = curr;
|
|
||||||
return obj;
|
|
||||||
}, {}));
|
|
||||||
})
|
|
||||||
.then(() => items.map(i => i.id)),
|
.then(() => items.map(i => i.id)),
|
||||||
delete: id => remove(PREFIX + id),
|
delete: id => chromeLocal.remove(PREFIX + id),
|
||||||
getAll: () => get(null)
|
getAll: () => chromeLocal.get()
|
||||||
.then(result => {
|
.then(result => {
|
||||||
const output = [];
|
const output = [];
|
||||||
for (const key in result) {
|
for (const key in result) {
|
||||||
|
@ -69,7 +52,7 @@ function createChromeStorageDB() {
|
||||||
|
|
||||||
function prepareInc() {
|
function prepareInc() {
|
||||||
if (INC) return Promise.resolve();
|
if (INC) return Promise.resolve();
|
||||||
return get(null).then(result => {
|
return chromeLocal.get().then(result => {
|
||||||
INC = 1;
|
INC = 1;
|
||||||
for (const key in result) {
|
for (const key in result) {
|
||||||
if (key.startsWith(PREFIX)) {
|
if (key.startsWith(PREFIX)) {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const iconManager = (() => {
|
const iconManager = (() => {
|
||||||
const ICON_SIZES = FIREFOX || CHROME >= 2883 && !VIVALDI ? [16, 32] : [19, 38];
|
const ICON_SIZES = FIREFOX || CHROME >= 55 && !VIVALDI ? [16, 32] : [19, 38];
|
||||||
const staleBadges = new Set();
|
const staleBadges = new Set();
|
||||||
|
|
||||||
prefs.subscribe([
|
prefs.subscribe([
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* global promisify CHROME URLS */
|
/* global CHROME URLS */
|
||||||
/* exported navigatorUtil */
|
/* exported navigatorUtil */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ const navigatorUtil = (() => {
|
||||||
const handler = {
|
const handler = {
|
||||||
urlChange: null
|
urlChange: null
|
||||||
};
|
};
|
||||||
const tabGet = promisify(chrome.tabs.get.bind(chrome.tabs));
|
|
||||||
return extendNative({onUrlChange});
|
return extendNative({onUrlChange});
|
||||||
|
|
||||||
function onUrlChange(fn) {
|
function onUrlChange(fn) {
|
||||||
|
@ -48,7 +47,7 @@ const navigatorUtil = (() => {
|
||||||
) {
|
) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
return tabGet(data.tabId)
|
return browser.tabs.get(data.tabId)
|
||||||
.then(tab => {
|
.then(tab => {
|
||||||
if (tab.url === 'chrome://newtab/') {
|
if (tab.url === 'chrome://newtab/') {
|
||||||
data.url = tab.url;
|
data.url = tab.url;
|
||||||
|
|
|
@ -192,6 +192,7 @@ const sync = (() => {
|
||||||
.catch(handle401Error)
|
.catch(handle401Error)
|
||||||
.then(() => syncNow()),
|
.then(() => syncNow()),
|
||||||
err => {
|
err => {
|
||||||
|
status.errorMessage = err ? err.message : null;
|
||||||
// FIXME: should we move this logic to options.js?
|
// FIXME: should we move this logic to options.js?
|
||||||
if (err && !fromPref) {
|
if (err && !fromPref) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
/* global chromeLocal promisify FIREFOX */
|
/* global chromeLocal promisifyChrome FIREFOX */
|
||||||
/* exported tokenManager */
|
/* exported tokenManager */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const tokenManager = (() => {
|
const tokenManager = (() => {
|
||||||
const launchWebAuthFlow = promisify(chrome.identity.launchWebAuthFlow.bind(chrome.identity));
|
promisifyChrome({
|
||||||
|
identity: ['launchWebAuthFlow'],
|
||||||
|
});
|
||||||
const AUTH = {
|
const AUTH = {
|
||||||
dropbox: {
|
dropbox: {
|
||||||
flow: 'token',
|
flow: 'token',
|
||||||
|
@ -158,7 +160,7 @@ const tokenManager = (() => {
|
||||||
Object.assign(query, provider.authQuery);
|
Object.assign(query, provider.authQuery);
|
||||||
}
|
}
|
||||||
const url = `${provider.authURL}?${stringifyQuery(query)}`;
|
const url = `${provider.authURL}?${stringifyQuery(query)}`;
|
||||||
return launchWebAuthFlow({
|
return browser.identity.launchWebAuthFlow({
|
||||||
url,
|
url,
|
||||||
interactive
|
interactive
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
/* global API_METHODS usercss styleManager deepCopy openURL download URLS getTab */
|
/* global API_METHODS usercss styleManager deepCopy openURL download URLS */
|
||||||
/* exports usercssHelper */
|
/* exported usercssHelper */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
const usercssHelper = (() => {
|
const usercssHelper = (() => {
|
||||||
const installCodeCache = {};
|
const installCodeCache = {};
|
||||||
const clearInstallCode = url => delete installCodeCache[url];
|
const clearInstallCode = url => delete installCodeCache[url];
|
||||||
|
@ -46,7 +45,7 @@ const usercssHelper = (() => {
|
||||||
openInstallerPage(tabId, url, {code, inTab} = {}) {
|
openInstallerPage(tabId, url, {code, inTab} = {}) {
|
||||||
const newUrl = `${URLS.installUsercss}?updateUrl=${encodeURIComponent(url)}`;
|
const newUrl = `${URLS.installUsercss}?updateUrl=${encodeURIComponent(url)}`;
|
||||||
if (inTab) {
|
if (inTab) {
|
||||||
getTab(tabId).then(tab =>
|
browser.tabs.get(tabId).then(tab =>
|
||||||
openURL({
|
openURL({
|
||||||
url: `${newUrl}&tabId=${tabId}`,
|
url: `${newUrl}&tabId=${tabId}`,
|
||||||
active: tab.active,
|
active: tab.active,
|
||||||
|
|
|
@ -19,90 +19,91 @@ self.createStyleInjector = self.INJECTED === 1 ? self.createStyleInjector : ({
|
||||||
let isTransitionPatched;
|
let isTransitionPatched;
|
||||||
// will store the original method refs because the page can override them
|
// will store the original method refs because the page can override them
|
||||||
let creationDoc, createElement, createElementNS;
|
let creationDoc, createElement, createElementNS;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
apply,
|
|
||||||
clear,
|
|
||||||
clearOrphans,
|
|
||||||
remove,
|
|
||||||
replace,
|
|
||||||
toggle,
|
|
||||||
list,
|
list,
|
||||||
|
|
||||||
|
apply(styleMap) {
|
||||||
|
const styles = _styleMapToArray(styleMap);
|
||||||
|
return (
|
||||||
|
!styles.length ?
|
||||||
|
Promise.resolve([]) :
|
||||||
|
docRootObserver.evade(() => {
|
||||||
|
if (!isTransitionPatched && isEnabled) {
|
||||||
|
_applyTransitionPatch(styles);
|
||||||
|
}
|
||||||
|
return styles.map(_addUpdate);
|
||||||
|
})
|
||||||
|
).then(_emitUpdate);
|
||||||
|
},
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
_addRemoveElements(false);
|
||||||
|
list.length = 0;
|
||||||
|
table.clear();
|
||||||
|
_emitUpdate();
|
||||||
|
},
|
||||||
|
|
||||||
|
clearOrphans() {
|
||||||
|
for (const el of document.querySelectorAll(`style[id^="${PREFIX}"].stylus`)) {
|
||||||
|
const id = el.id.slice(PREFIX.length);
|
||||||
|
if (/^\d+$/.test(id) || id === PATCH_ID) {
|
||||||
|
el.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
remove(id) {
|
||||||
|
_remove(id);
|
||||||
|
_emitUpdate();
|
||||||
|
},
|
||||||
|
|
||||||
|
replace(styleMap) {
|
||||||
|
const styles = _styleMapToArray(styleMap);
|
||||||
|
const added = new Set(styles.map(s => s.id));
|
||||||
|
const removed = [];
|
||||||
|
for (const style of list) {
|
||||||
|
if (!added.has(style.id)) {
|
||||||
|
removed.push(style.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
styles.forEach(_addUpdate);
|
||||||
|
removed.forEach(_remove);
|
||||||
|
_emitUpdate();
|
||||||
|
},
|
||||||
|
|
||||||
|
toggle(enable) {
|
||||||
|
if (isEnabled === enable) return;
|
||||||
|
isEnabled = enable;
|
||||||
|
if (!enable) _toggleObservers(false);
|
||||||
|
_addRemoveElements(enable);
|
||||||
|
if (enable) _toggleObservers(true);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function apply(styleMap) {
|
function _add(style) {
|
||||||
const styles = _styleMapToArray(styleMap);
|
const el = style.el = _createStyle(style.id, style.code);
|
||||||
return !styles.length ?
|
const i = list.findIndex(item => compare(item, style) > 0);
|
||||||
Promise.resolve([]) :
|
table.set(style.id, style);
|
||||||
docRootObserver.evade(() => {
|
if (isEnabled) {
|
||||||
if (!isTransitionPatched) _applyTransitionPatch(styles);
|
document.documentElement.insertBefore(el, i < 0 ? null : list[i].el);
|
||||||
const els = styles.map(_apply);
|
|
||||||
_emitUpdate();
|
|
||||||
return els;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function clear() {
|
|
||||||
for (const style of list) {
|
|
||||||
style.el.remove();
|
|
||||||
}
|
}
|
||||||
list.length = 0;
|
list.splice(i < 0 ? list.length : i, 0, style);
|
||||||
table.clear();
|
return el;
|
||||||
_emitUpdate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearOrphans() {
|
function _addRemoveElements(add) {
|
||||||
for (const el of document.querySelectorAll(`style[id^="${PREFIX}"].stylus`)) {
|
for (const {el} of list) {
|
||||||
const id = el.id.slice(PREFIX.length);
|
if (add) {
|
||||||
if (/^\d+$/.test(id) || id === PATCH_ID) {
|
document.documentElement.appendChild(el);
|
||||||
|
} else {
|
||||||
el.remove();
|
el.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function remove(id) {
|
function _addUpdate(style) {
|
||||||
_remove(id);
|
|
||||||
_emitUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
function replace(styleMap) {
|
|
||||||
const styles = _styleMapToArray(styleMap);
|
|
||||||
const added = new Set(styles.map(s => s.id));
|
|
||||||
const removed = [];
|
|
||||||
for (const style of list) {
|
|
||||||
if (!added.has(style.id)) {
|
|
||||||
removed.push(style.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
styles.forEach(_apply);
|
|
||||||
removed.forEach(_remove);
|
|
||||||
_emitUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggle(_enabled) {
|
|
||||||
if (isEnabled === _enabled) return;
|
|
||||||
isEnabled = _enabled;
|
|
||||||
for (const style of list) {
|
|
||||||
style.el.disabled = !isEnabled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function _add(style) {
|
|
||||||
const el = style.el = _createStyle(style.id, style.code);
|
|
||||||
table.set(style.id, style);
|
|
||||||
const nextIndex = list.findIndex(i => compare(i, style) > 0);
|
|
||||||
if (nextIndex < 0) {
|
|
||||||
document.documentElement.appendChild(el);
|
|
||||||
list.push(style);
|
|
||||||
} else {
|
|
||||||
document.documentElement.insertBefore(el, list[nextIndex].el);
|
|
||||||
list.splice(nextIndex, 0, style);
|
|
||||||
}
|
|
||||||
// moving an element resets its 'disabled' state
|
|
||||||
el.disabled = !isEnabled;
|
|
||||||
return el;
|
|
||||||
}
|
|
||||||
|
|
||||||
function _apply(style) {
|
|
||||||
return table.has(style.id) ? _update(style) : _add(style);
|
return table.has(style.id) ? _update(style) : _add(style);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,15 +152,16 @@ self.createStyleInjector = self.INJECTED === 1 ? self.createStyleInjector : ({
|
||||||
return el;
|
return el;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _emitUpdate() {
|
function _toggleObservers(shouldStart) {
|
||||||
if (!IS_OWN_PAGE && list.length) {
|
const onOff = shouldStart && isEnabled ? 'start' : 'stop';
|
||||||
docRewriteObserver.start();
|
docRewriteObserver[onOff]();
|
||||||
docRootObserver.start();
|
docRootObserver[onOff]();
|
||||||
} else {
|
}
|
||||||
docRewriteObserver.stop();
|
|
||||||
docRootObserver.stop();
|
function _emitUpdate(value) {
|
||||||
}
|
_toggleObservers(!IS_OWN_PAGE && list.length);
|
||||||
onUpdate();
|
onUpdate();
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -193,11 +195,7 @@ self.createStyleInjector = self.INJECTED === 1 ? self.createStyleInjector : ({
|
||||||
function _sort() {
|
function _sort() {
|
||||||
docRootObserver.evade(() => {
|
docRootObserver.evade(() => {
|
||||||
list.sort(compare);
|
list.sort(compare);
|
||||||
for (const style of list) {
|
_addRemoveElements(true);
|
||||||
// moving an element resets its 'disabled' state
|
|
||||||
document.documentElement.appendChild(style.el);
|
|
||||||
style.el.disabled = !isEnabled;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,13 +239,13 @@ self.createStyleInjector = self.INJECTED === 1 ? self.createStyleInjector : ({
|
||||||
if (isChromePre65) {
|
if (isChromePre65) {
|
||||||
const oldEl = style.el;
|
const oldEl = style.el;
|
||||||
style.el = _createStyle(id, code);
|
style.el = _createStyle(id, code);
|
||||||
oldEl.parentNode.insertBefore(style.el, oldEl.nextSibling);
|
if (isEnabled) {
|
||||||
oldEl.remove();
|
oldEl.parentNode.insertBefore(style.el, oldEl.nextSibling);
|
||||||
|
oldEl.remove();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
style.el.textContent = code;
|
style.el.textContent = code;
|
||||||
}
|
}
|
||||||
// https://github.com/openstyles/stylus/issues/693
|
|
||||||
style.el.disabled = !isEnabled;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function RewriteObserver(onChange) {
|
function RewriteObserver(onChange) {
|
||||||
|
|
|
@ -64,7 +64,6 @@
|
||||||
<script src="vendor-overwrites/codemirror-addon/match-highlighter.js"></script>
|
<script src="vendor-overwrites/codemirror-addon/match-highlighter.js"></script>
|
||||||
|
|
||||||
<script src="js/polyfill.js"></script>
|
<script src="js/polyfill.js"></script>
|
||||||
<script src="js/promisify.js"></script>
|
|
||||||
<script src="js/dom.js"></script>
|
<script src="js/dom.js"></script>
|
||||||
<script src="js/messaging.js"></script>
|
<script src="js/messaging.js"></script>
|
||||||
<script src="js/prefs.js"></script>
|
<script src="js/prefs.js"></script>
|
||||||
|
|
109
edit/beautify.js
109
edit/beautify.js
|
@ -1,8 +1,49 @@
|
||||||
/* global loadScript css_beautify showHelp prefs t $ $create */
|
/* global loadScript css_beautify showHelp prefs t $ $create */
|
||||||
/* exported beautify */
|
/* global editor createHotkeyInput moveFocus CodeMirror */
|
||||||
|
/* exported initBeautifyButton */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
function beautify(scope) {
|
const HOTKEY_ID = 'editor.beautify.hotkey';
|
||||||
|
|
||||||
|
prefs.initializing.then(() => {
|
||||||
|
CodeMirror.defaults.extraKeys[prefs.get(HOTKEY_ID) || ''] = 'beautify';
|
||||||
|
CodeMirror.commands.beautify = cm => {
|
||||||
|
// using per-section mode when code editor or applies-to block is focused
|
||||||
|
const isPerSection = cm.display.wrapper.parentElement.contains(document.activeElement);
|
||||||
|
beautify(isPerSection ? [cm] : editor.getEditors(), false);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
prefs.subscribe([HOTKEY_ID], (key, value) => {
|
||||||
|
const {extraKeys} = CodeMirror.defaults;
|
||||||
|
for (const [key, cmd] of Object.entries(extraKeys)) {
|
||||||
|
if (cmd === 'beautify') {
|
||||||
|
delete extraKeys[key];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (value) {
|
||||||
|
extraKeys[value] = 'beautify';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {HTMLElement} btn - the button element shown in the UI
|
||||||
|
* @param {function():CodeMirror[]} getScope
|
||||||
|
*/
|
||||||
|
function initBeautifyButton(btn, getScope) {
|
||||||
|
btn.addEventListener('click', () => beautify(getScope()));
|
||||||
|
btn.addEventListener('contextmenu', e => {
|
||||||
|
e.preventDefault();
|
||||||
|
beautify(getScope(), false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {CodeMirror[]} scope
|
||||||
|
* @param {?boolean} ui
|
||||||
|
*/
|
||||||
|
function beautify(scope, ui = true) {
|
||||||
loadScript('/vendor-overwrites/beautify/beautify-css-mod.js')
|
loadScript('/vendor-overwrites/beautify/beautify-css-mod.js')
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if (!window.css_beautify && window.exports) {
|
if (!window.css_beautify && window.exports) {
|
||||||
|
@ -19,7 +60,41 @@ function beautify(scope) {
|
||||||
}
|
}
|
||||||
options.indent_size = tabs ? 1 : prefs.get('editor.tabSize');
|
options.indent_size = tabs ? 1 : prefs.get('editor.tabSize');
|
||||||
options.indent_char = tabs ? '\t' : ' ';
|
options.indent_char = tabs ? '\t' : ' ';
|
||||||
|
if (ui) {
|
||||||
|
createBeautifyUI(scope, options);
|
||||||
|
}
|
||||||
|
for (const cm of scope) {
|
||||||
|
setTimeout(doBeautifyEditor, 0, cm, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function doBeautifyEditor(cm, options) {
|
||||||
|
const pos = options.translate_positions =
|
||||||
|
[].concat.apply([], cm.doc.sel.ranges.map(r =>
|
||||||
|
[Object.assign({}, r.anchor), Object.assign({}, r.head)]));
|
||||||
|
const text = cm.getValue();
|
||||||
|
const newText = css_beautify(text, options);
|
||||||
|
if (newText !== text) {
|
||||||
|
if (!cm.beautifyChange || !cm.beautifyChange[cm.changeGeneration()]) {
|
||||||
|
// clear the list if last change wasn't a css-beautify
|
||||||
|
cm.beautifyChange = {};
|
||||||
|
}
|
||||||
|
cm.setValue(newText);
|
||||||
|
const selections = [];
|
||||||
|
for (let i = 0; i < pos.length; i += 2) {
|
||||||
|
selections.push({anchor: pos[i], head: pos[i + 1]});
|
||||||
|
}
|
||||||
|
const {scrollX, scrollY} = window;
|
||||||
|
cm.setSelections(selections);
|
||||||
|
window.scrollTo(scrollX, scrollY);
|
||||||
|
cm.beautifyChange[cm.changeGeneration()] = true;
|
||||||
|
if (ui) {
|
||||||
|
$('#help-popup button[role="close"]').disabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createBeautifyUI(scope, options) {
|
||||||
showHelp(t('styleBeautify'),
|
showHelp(t('styleBeautify'),
|
||||||
$create([
|
$create([
|
||||||
$create('.beautify-options', [
|
$create('.beautify-options', [
|
||||||
|
@ -32,6 +107,10 @@ function beautify(scope) {
|
||||||
$createLabeledCheckbox('preserve_newlines', 'styleBeautifyPreserveNewlines'),
|
$createLabeledCheckbox('preserve_newlines', 'styleBeautifyPreserveNewlines'),
|
||||||
$createLabeledCheckbox('indent_conditional', 'styleBeautifyIndentConditional'),
|
$createLabeledCheckbox('indent_conditional', 'styleBeautifyIndentConditional'),
|
||||||
]),
|
]),
|
||||||
|
$create('p.beautify-hint', [
|
||||||
|
$create('span', t('styleBeautifyHint') + '\u00A0'),
|
||||||
|
createHotkeyInput(HOTKEY_ID, () => moveFocus($('#help-popup'), 1)),
|
||||||
|
]),
|
||||||
$create('.buttons', [
|
$create('.buttons', [
|
||||||
$create('button', {
|
$create('button', {
|
||||||
attributes: {role: 'close'},
|
attributes: {role: 'close'},
|
||||||
|
@ -60,32 +139,6 @@ function beautify(scope) {
|
||||||
|
|
||||||
$('#help-popup').className = 'wide';
|
$('#help-popup').className = 'wide';
|
||||||
|
|
||||||
scope.forEach(cm => {
|
|
||||||
setTimeout(() => {
|
|
||||||
const pos = options.translate_positions =
|
|
||||||
[].concat.apply([], cm.doc.sel.ranges.map(r =>
|
|
||||||
[Object.assign({}, r.anchor), Object.assign({}, r.head)]));
|
|
||||||
const text = cm.getValue();
|
|
||||||
const newText = css_beautify(text, options);
|
|
||||||
if (newText !== text) {
|
|
||||||
if (!cm.beautifyChange || !cm.beautifyChange[cm.changeGeneration()]) {
|
|
||||||
// clear the list if last change wasn't a css-beautify
|
|
||||||
cm.beautifyChange = {};
|
|
||||||
}
|
|
||||||
cm.setValue(newText);
|
|
||||||
const selections = [];
|
|
||||||
for (let i = 0; i < pos.length; i += 2) {
|
|
||||||
selections.push({anchor: pos[i], head: pos[i + 1]});
|
|
||||||
}
|
|
||||||
const {scrollX, scrollY} = window;
|
|
||||||
cm.setSelections(selections);
|
|
||||||
window.scrollTo(scrollX, scrollY);
|
|
||||||
cm.beautifyChange[cm.changeGeneration()] = true;
|
|
||||||
$('#help-popup button[role="close"]').disabled = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.beautify-options').onchange = ({target}) => {
|
$('.beautify-options').onchange = ({target}) => {
|
||||||
const value = target.type === 'checkbox' ? target.checked : target.selectedIndex > 0;
|
const value = target.type === 'checkbox' ? target.checked : target.selectedIndex > 0;
|
||||||
prefs.set('editor.beautify', Object.assign(options, {[target.dataset.option]: value}));
|
prefs.set('editor.beautify', Object.assign(options, {[target.dataset.option]: value}));
|
||||||
|
|
|
@ -18,6 +18,12 @@
|
||||||
outline: -webkit-focus-ring-color auto 5px;
|
outline: -webkit-focus-ring-color auto 5px;
|
||||||
outline-offset: -2px;
|
outline-offset: -2px;
|
||||||
}
|
}
|
||||||
|
.CodeMirror-bookmark {
|
||||||
|
background: linear-gradient(to right, currentColor, transparent);
|
||||||
|
position: absolute;
|
||||||
|
width: 2em;
|
||||||
|
opacity: .5;
|
||||||
|
}
|
||||||
@supports (-moz-appearance:none) {
|
@supports (-moz-appearance:none) {
|
||||||
/* restrict to FF */
|
/* restrict to FF */
|
||||||
.CodeMirror-focused {
|
.CodeMirror-focused {
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
prefs.reset('editor.keyMap');
|
prefs.reset('editor.keyMap');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CM_BOOKMARK = 'CodeMirror-bookmark';
|
||||||
|
const CM_BOOKMARK_GUTTER = CM_BOOKMARK + 'gutter';
|
||||||
const defaults = {
|
const defaults = {
|
||||||
autoCloseBrackets: prefs.get('editor.autoCloseBrackets'),
|
autoCloseBrackets: prefs.get('editor.autoCloseBrackets'),
|
||||||
mode: 'css',
|
mode: 'css',
|
||||||
|
@ -15,6 +17,7 @@
|
||||||
lineWrapping: prefs.get('editor.lineWrapping'),
|
lineWrapping: prefs.get('editor.lineWrapping'),
|
||||||
foldGutter: true,
|
foldGutter: true,
|
||||||
gutters: [
|
gutters: [
|
||||||
|
CM_BOOKMARK_GUTTER,
|
||||||
'CodeMirror-linenumbers',
|
'CodeMirror-linenumbers',
|
||||||
'CodeMirror-foldgutter',
|
'CodeMirror-foldgutter',
|
||||||
...(prefs.get('editor.linter') ? ['CodeMirror-lint-markers'] : []),
|
...(prefs.get('editor.linter') ? ['CodeMirror-lint-markers'] : []),
|
||||||
|
@ -102,92 +105,19 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.assign(CodeMirror.mimeModes['text/css'].propertyKeywords, {
|
Object.assign(CodeMirror.mimeModes['text/css'].propertyKeywords, {
|
||||||
// CSS Backgrounds and Borders Module L4
|
|
||||||
'background-position-x': true,
|
'background-position-x': true,
|
||||||
'background-position-y': true,
|
'background-position-y': true,
|
||||||
|
|
||||||
// CSS Logical Properties and Values L1
|
|
||||||
'block-size': true,
|
|
||||||
'border-block-color': true,
|
|
||||||
'border-block-end': true,
|
|
||||||
'border-block-end-color': true,
|
|
||||||
'border-block-end-style': true,
|
|
||||||
'border-block-end-width': true,
|
|
||||||
'border-block-start': true,
|
|
||||||
'border-block-start-color': true,
|
|
||||||
'border-block-start-style': true,
|
|
||||||
'border-block-start-width': true,
|
|
||||||
'border-block-style': true,
|
|
||||||
'border-block-width': true,
|
|
||||||
'border-inline-color': true,
|
|
||||||
'border-inline-end': true,
|
|
||||||
'border-inline-end-color': true,
|
|
||||||
'border-inline-end-style': true,
|
|
||||||
'border-inline-end-width': true,
|
|
||||||
'border-inline-start': true,
|
|
||||||
'border-inline-start-color': true,
|
|
||||||
'border-inline-start-style': true,
|
|
||||||
'border-inline-start-width': true,
|
|
||||||
'border-inline-style': true,
|
|
||||||
'border-inline-width': true,
|
|
||||||
'inline-size': true,
|
|
||||||
'inset': true,
|
|
||||||
'inset-block': true,
|
|
||||||
'inset-block-end': true,
|
|
||||||
'inset-block-start': true,
|
|
||||||
'inset-inline': true,
|
|
||||||
'inset-inline-end': true,
|
|
||||||
'inset-inline-start': true,
|
|
||||||
'margin-block': true,
|
|
||||||
'margin-block-end': true,
|
|
||||||
'margin-block-start': true,
|
|
||||||
'margin-inline': true,
|
|
||||||
'margin-inline-end': true,
|
|
||||||
'margin-inline-start': true,
|
|
||||||
'max-block-size': true,
|
|
||||||
'max-inline-size': true,
|
|
||||||
'min-block-size': true,
|
|
||||||
'min-inline-size': true,
|
|
||||||
'padding-block': true,
|
|
||||||
'padding-block-end': true,
|
|
||||||
'padding-block-start': true,
|
|
||||||
'padding-inline': true,
|
|
||||||
'padding-inline-end': true,
|
|
||||||
'padding-inline-start': true,
|
|
||||||
'text-align-all': true,
|
|
||||||
|
|
||||||
'contain': true,
|
'contain': true,
|
||||||
'mask-image': true,
|
'mask-image': true,
|
||||||
'mix-blend-mode': true,
|
'mix-blend-mode': true,
|
||||||
|
'overscroll-behavior': true,
|
||||||
'rotate': true,
|
'rotate': true,
|
||||||
'isolation': true,
|
'isolation': true,
|
||||||
'zoom': true,
|
|
||||||
|
|
||||||
// https://www.w3.org/TR/css-round-display-1/
|
|
||||||
'border-boundary': true,
|
|
||||||
'shape': true,
|
|
||||||
'shape-inside': true,
|
|
||||||
'viewport-fit': true,
|
|
||||||
|
|
||||||
// nonstandard https://compat.spec.whatwg.org/
|
|
||||||
'box-reflect': true,
|
|
||||||
'text-fill-color': true,
|
|
||||||
'text-stroke': true,
|
|
||||||
'text-stroke-color': true,
|
|
||||||
'text-stroke-width': true,
|
|
||||||
// end
|
|
||||||
});
|
|
||||||
Object.assign(CodeMirror.mimeModes['text/css'].valueKeywords, {
|
|
||||||
'isolate': true,
|
|
||||||
'rect': true,
|
|
||||||
'recto': true,
|
|
||||||
'verso': true,
|
|
||||||
});
|
});
|
||||||
Object.assign(CodeMirror.mimeModes['text/css'].colorKeywords, {
|
Object.assign(CodeMirror.mimeModes['text/css'].colorKeywords, {
|
||||||
'darkgrey': true,
|
'darkgrey': true,
|
||||||
'darkslategrey': true,
|
'darkslategrey': true,
|
||||||
'dimgrey': true,
|
'dimgrey': true,
|
||||||
'grey': true,
|
|
||||||
'lightgrey': true,
|
'lightgrey': true,
|
||||||
'lightslategrey': true,
|
'lightslategrey': true,
|
||||||
'slategrey': true,
|
'slategrey': true,
|
||||||
|
@ -242,22 +172,27 @@
|
||||||
CodeMirror.commands[name] = (...args) => editor[name](...args);
|
CodeMirror.commands[name] = (...args) => editor[name](...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
// speedup: reuse the old folding marks
|
const elBookmark = document.createElement('div');
|
||||||
// TODO: remove when https://github.com/codemirror/CodeMirror/pull/6010 is shipped in /vendor
|
elBookmark.className = CM_BOOKMARK;
|
||||||
const {setGutterMarker} = CodeMirror.prototype;
|
elBookmark.textContent = '\u00A0';
|
||||||
CodeMirror.prototype.setGutterMarker = function (line, gutterID, value) {
|
const clearMarker = function () {
|
||||||
const o = this.state.foldGutter.options;
|
const line = this.lines[0];
|
||||||
if (typeof o.indicatorOpen === 'string' ||
|
CodeMirror.TextMarker.prototype.clear.apply(this);
|
||||||
typeof o.indicatorFolded === 'string') {
|
if (!line.markedSpans.some(span => span.marker.sublimeBookmark)) {
|
||||||
const old = line.gutterMarkers && line.gutterMarkers[gutterID];
|
this.doc.setGutterMarker(line, CM_BOOKMARK_GUTTER, null);
|
||||||
// old className can contain other names set by CodeMirror so we'll use classList
|
|
||||||
if (old && value && old.classList.contains(value.className) ||
|
|
||||||
!old && !value) {
|
|
||||||
return line;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return setGutterMarker.apply(this, arguments);
|
|
||||||
};
|
};
|
||||||
|
const {markText} = CodeMirror.prototype;
|
||||||
|
Object.assign(CodeMirror.prototype, {
|
||||||
|
markText() {
|
||||||
|
const marker = markText.apply(this, arguments);
|
||||||
|
if (marker.sublimeBookmark) {
|
||||||
|
this.doc.setGutterMarker(marker.lines[0], CM_BOOKMARK_GUTTER, elBookmark.cloneNode(true));
|
||||||
|
marker.clear = clearMarker;
|
||||||
|
}
|
||||||
|
return marker;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// CodeMirror convenience commands
|
// CodeMirror convenience commands
|
||||||
Object.assign(CodeMirror.commands, {
|
Object.assign(CodeMirror.commands, {
|
||||||
|
@ -307,6 +242,7 @@ CodeMirror.hint && (() => {
|
||||||
const RX_IMPORTANT = /(i(m(p(o(r(t(a(nt?)?)?)?)?)?)?)?)?(?=\b|\W|$)/iy;
|
const RX_IMPORTANT = /(i(m(p(o(r(t(a(nt?)?)?)?)?)?)?)?)?(?=\b|\W|$)/iy;
|
||||||
const RX_VAR_KEYWORD = /(^|[^-\w\u0080-\uFFFF])var\(/iy;
|
const RX_VAR_KEYWORD = /(^|[^-\w\u0080-\uFFFF])var\(/iy;
|
||||||
const RX_END_OF_VAR = /[\s,)]|$/g;
|
const RX_END_OF_VAR = /[\s,)]|$/g;
|
||||||
|
const RX_CONSUME_PROP = /[-\w]*\s*:\s?|$/y;
|
||||||
|
|
||||||
const originalHelper = CodeMirror.hint.css || (() => {});
|
const originalHelper = CodeMirror.hint.css || (() => {});
|
||||||
const helper = cm => {
|
const helper = cm => {
|
||||||
|
@ -372,7 +308,15 @@ CodeMirror.hint && (() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!editor || !style || !style.includes(USO_VAR)) {
|
if (!editor || !style || !style.includes(USO_VAR)) {
|
||||||
return originalHelper(cm);
|
// add ":" after a property name
|
||||||
|
const res = originalHelper(cm);
|
||||||
|
const state = res && cm.getTokenAt(pos).state.state;
|
||||||
|
if (state === 'block' || state === 'maybeprop') {
|
||||||
|
res.list = res.list.map(str => str + ': ');
|
||||||
|
RX_CONSUME_PROP.lastIndex = res.to.ch;
|
||||||
|
res.to.ch += RX_CONSUME_PROP.exec(text)[0].length;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// USO vars in usercss mode editor
|
// USO vars in usercss mode editor
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* global CodeMirror showHelp cmFactory onDOMready $ $create prefs t */
|
/* global CodeMirror showHelp cmFactory onDOMready $ prefs t createHotkeyInput */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
(() => {
|
(() => {
|
||||||
|
@ -62,46 +62,8 @@
|
||||||
|
|
||||||
function configureColorpicker(event) {
|
function configureColorpicker(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const input = $create('input', {
|
const input = createHotkeyInput('editor.colorpicker.hotkey', () => {
|
||||||
type: 'search',
|
$('#help-popup .dismiss').onclick();
|
||||||
spellcheck: false,
|
|
||||||
value: prefs.get('editor.colorpicker.hotkey'),
|
|
||||||
onkeydown(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
const key = CodeMirror.keyName(event);
|
|
||||||
switch (key) {
|
|
||||||
case 'Enter':
|
|
||||||
if (this.checkValidity()) {
|
|
||||||
$('#help-popup .dismiss').onclick();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case 'Esc':
|
|
||||||
$('#help-popup .dismiss').onclick();
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
// disallow: [Shift?] characters, modifiers-only, [modifiers?] + Esc, Tab, nav keys
|
|
||||||
if (!key || new RegExp('^(' + [
|
|
||||||
'(Back)?Space',
|
|
||||||
'(Shift-)?.', // a single character
|
|
||||||
'(Shift-?|Ctrl-?|Alt-?|Cmd-?){0,2}(|Esc|Tab|(Page)?(Up|Down)|Left|Right|Home|End|Insert|Delete)',
|
|
||||||
].join('|') + ')$', 'i').test(key)) {
|
|
||||||
this.value = key || this.value;
|
|
||||||
this.setCustomValidity('Not allowed');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.value = key;
|
|
||||||
this.setCustomValidity('');
|
|
||||||
prefs.set('editor.colorpicker.hotkey', key);
|
|
||||||
},
|
|
||||||
oninput() {
|
|
||||||
// fired on pressing "x" to clear the field
|
|
||||||
prefs.set('editor.colorpicker.hotkey', '');
|
|
||||||
},
|
|
||||||
onpaste(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
const popup = showHelp(t('helpKeyMapHotkey'), input);
|
const popup = showHelp(t('helpKeyMapHotkey'), input);
|
||||||
if (this instanceof Element) {
|
if (this instanceof Element) {
|
||||||
|
|
|
@ -267,6 +267,10 @@ input:invalid {
|
||||||
margin-top: 4em;
|
margin-top: 4em;
|
||||||
}
|
}
|
||||||
/************ section editor ***********/
|
/************ section editor ***********/
|
||||||
|
.CodeMirror-vscrollbar,
|
||||||
|
.CodeMirror-hscrollbar {
|
||||||
|
pointer-events: auto !important; /* FF bug */
|
||||||
|
}
|
||||||
.section-editor .section {
|
.section-editor .section {
|
||||||
margin: 0 0.7rem;
|
margin: 0 0.7rem;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
|
@ -775,6 +779,11 @@ body:not(.find-open) [data-match-highlight-count="1"] .CodeMirror-selection-high
|
||||||
padding-left: 4px;
|
padding-left: 4px;
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
}
|
}
|
||||||
|
.beautify-hint {
|
||||||
|
width: 0;
|
||||||
|
min-width: 100%;
|
||||||
|
font-size: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
/************ single editor **************/
|
/************ single editor **************/
|
||||||
.usercss body {
|
.usercss body {
|
||||||
|
|
23
edit/edit.js
23
edit/edit.js
|
@ -1,7 +1,7 @@
|
||||||
/* global CodeMirror onDOMready prefs setupLivePrefs $ $$ $create t tHTML
|
/* global CodeMirror onDOMready prefs setupLivePrefs $ $$ $create t tHTML
|
||||||
createSourceEditor queryTabs sessionStorageHash getOwnTab FIREFOX API tryCatch
|
createSourceEditor sessionStorageHash getOwnTab FIREFOX API tryCatch
|
||||||
closeCurrentTab messageBox debounce workerUtil
|
closeCurrentTab messageBox debounce workerUtil
|
||||||
beautify ignoreChromeError
|
initBeautifyButton ignoreChromeError
|
||||||
moveFocus msg createSectionsEditor rerouteHotkeys CODEMIRROR_THEMES */
|
moveFocus msg createSectionsEditor rerouteHotkeys CODEMIRROR_THEMES */
|
||||||
/* exported showCodeMirrorPopup editorWorker toggleContextMenuDelete */
|
/* exported showCodeMirrorPopup editorWorker toggleContextMenuDelete */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
@ -170,12 +170,21 @@ preinit();
|
||||||
$('#heading').textContent = t(style.id ? 'editStyleHeading' : 'addStyleTitle');
|
$('#heading').textContent = t(style.id ? 'editStyleHeading' : 'addStyleTitle');
|
||||||
$('#name').placeholder = t(usercss ? 'usercssEditorNamePlaceholder' : 'styleMissingName');
|
$('#name').placeholder = t(usercss ? 'usercssEditorNamePlaceholder' : 'styleMissingName');
|
||||||
$('#name').title = usercss ? t('usercssReplaceTemplateName') : '';
|
$('#name').title = usercss ? t('usercssReplaceTemplateName') : '';
|
||||||
|
|
||||||
$('#preview-label').classList.toggle('hidden', !style.id);
|
$('#preview-label').classList.toggle('hidden', !style.id);
|
||||||
|
initBeautifyButton($('#beautify'), () => editor.getEditors());
|
||||||
$('#beautify').onclick = () => beautify(editor.getEditors());
|
const {onBoundsChanged} = chrome.windows || {};
|
||||||
|
if (onBoundsChanged) {
|
||||||
|
// * movement is reported even if the window wasn't resized
|
||||||
|
// * fired just once when done so debounce is not needed
|
||||||
|
onBoundsChanged.addListener(wnd => {
|
||||||
|
// getting the current window id as it may change if the user attached/detached the tab
|
||||||
|
chrome.windows.getCurrent(ownWnd => {
|
||||||
|
if (wnd.id === ownWnd.id) rememberWindowSize();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
window.addEventListener('resize', () => {
|
window.addEventListener('resize', () => {
|
||||||
debounce(rememberWindowSize, 100);
|
if (!onBoundsChanged) debounce(rememberWindowSize, 100);
|
||||||
detectLayout();
|
detectLayout();
|
||||||
});
|
});
|
||||||
detectLayout();
|
detectLayout();
|
||||||
|
@ -217,7 +226,7 @@ function preinit() {
|
||||||
}).observe(document, {subtree: true, childList: true});
|
}).observe(document, {subtree: true, childList: true});
|
||||||
|
|
||||||
if (chrome.windows) {
|
if (chrome.windows) {
|
||||||
queryTabs({currentWindow: true}).then(tabs => {
|
browser.tabs.query({currentWindow: true}).then(tabs => {
|
||||||
const windowId = tabs[0].windowId;
|
const windowId = tabs[0].windowId;
|
||||||
if (prefs.get('openEditInWindow')) {
|
if (prefs.get('openEditInWindow')) {
|
||||||
if (
|
if (
|
||||||
|
|
|
@ -61,7 +61,7 @@
|
||||||
border: none;
|
border: none;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
white-space: nowrap;
|
white-space: pre; /* issue #1000 */
|
||||||
color: currentColor; /* use the current theme's color instead of UserAgent's CSS */
|
color: currentColor; /* use the current theme's color instead of UserAgent's CSS */
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* global CodeMirror focusAccessibility colorMimicry editor
|
/* global CodeMirror focusAccessibility colorMimicry editor chromeLocal
|
||||||
onDOMready $ $$ $create t debounce tryRegExp stringAsRegExp template */
|
onDOMready $ $$ $create t debounce tryRegExp stringAsRegExp template */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
@ -915,7 +915,7 @@ onDOMready().then(() => {
|
||||||
|
|
||||||
|
|
||||||
function readStorage() {
|
function readStorage() {
|
||||||
chrome.storage.local.get('editor', ({editor = {}}) => {
|
chromeLocal.getValue('editor').then((editor = {}) => {
|
||||||
state.find = editor.find || '';
|
state.find = editor.find || '';
|
||||||
state.replace = editor.replace || '';
|
state.replace = editor.replace || '';
|
||||||
state.icase = editor.icase || state.icase;
|
state.icase = editor.icase || state.icase;
|
||||||
|
@ -924,14 +924,12 @@ onDOMready().then(() => {
|
||||||
|
|
||||||
|
|
||||||
function writeStorage() {
|
function writeStorage() {
|
||||||
chrome.storage.local.get('editor', ({editor}) =>
|
chromeLocal.getValue('editor').then((editor = {}) =>
|
||||||
chrome.storage.local.set({
|
chromeLocal.setValue('editor', Object.assign(editor, {
|
||||||
editor: Object.assign(editor || {}, {
|
find: state.find,
|
||||||
find: state.find,
|
replace: state.replace,
|
||||||
replace: state.replace,
|
icase: state.icase,
|
||||||
icase: state.icase,
|
})));
|
||||||
})
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* global showHelp $ $create tryRegExp queryTabs URLS t template openURL */
|
/* global showHelp $ $create tryRegExp URLS t template openURL */
|
||||||
/* exported regExpTester */
|
/* exported regExpTester */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ const regExpTester = (() => {
|
||||||
return rxData;
|
return rxData;
|
||||||
});
|
});
|
||||||
const getMatchInfo = m => m && {text: m[0], pos: m.index};
|
const getMatchInfo = m => m && {text: m[0], pos: m.index};
|
||||||
queryTabs({}).then(tabs => {
|
browser.tabs.query({}).then(tabs => {
|
||||||
const supported = tabs.map(tab => tab.url)
|
const supported = tabs.map(tab => tab.url)
|
||||||
.filter(url => URLS.supported(url));
|
.filter(url => URLS.supported(url));
|
||||||
const unique = [...new Set(supported).values()];
|
const unique = [...new Set(supported).values()];
|
||||||
|
|
|
@ -12,6 +12,7 @@ const rerouteHotkeys = (() => {
|
||||||
'toggleEditorFocus',
|
'toggleEditorFocus',
|
||||||
'find', 'findNext', 'findPrev', 'replace', 'replaceAll',
|
'find', 'findNext', 'findPrev', 'replace', 'replaceAll',
|
||||||
'colorpicker',
|
'colorpicker',
|
||||||
|
'beautify',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return rerouteHotkeys;
|
return rerouteHotkeys;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* global template cmFactory $ propertyToCss CssToProperty linter regExpTester
|
/* global template cmFactory $ propertyToCss CssToProperty linter regExpTester
|
||||||
FIREFOX toggleContextMenuDelete beautify showHelp t tryRegExp */
|
FIREFOX toggleContextMenuDelete initBeautifyButton showHelp t tryRegExp */
|
||||||
/* exported createSection */
|
/* exported createSection */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
@ -94,6 +94,7 @@ function createSection({
|
||||||
const cm = cmFactory.create(wrapper => {
|
const cm = cmFactory.create(wrapper => {
|
||||||
el.insertBefore(wrapper, $('.code-label', el).nextSibling);
|
el.insertBefore(wrapper, $('.code-label', el).nextSibling);
|
||||||
}, {value: originalSection.code});
|
}, {value: originalSection.code});
|
||||||
|
el.CodeMirror = cm; // used by getAssociatedEditor
|
||||||
|
|
||||||
const changeListeners = new Set();
|
const changeListeners = new Set();
|
||||||
|
|
||||||
|
@ -196,12 +197,12 @@ function createSection({
|
||||||
$('.clone-section', el).addEventListener('click', () => insertSectionAfter(getModel(), section));
|
$('.clone-section', el).addEventListener('click', () => insertSectionAfter(getModel(), section));
|
||||||
$('.move-section-up', el).addEventListener('click', () => moveSectionUp(section));
|
$('.move-section-up', el).addEventListener('click', () => moveSectionUp(section));
|
||||||
$('.move-section-down', el).addEventListener('click', () => moveSectionDown(section));
|
$('.move-section-down', el).addEventListener('click', () => moveSectionDown(section));
|
||||||
$('.beautify-section', el).addEventListener('click', () => beautify([cm]));
|
|
||||||
$('.restore-section', el).addEventListener('click', () => restoreSection(section));
|
$('.restore-section', el).addEventListener('click', () => restoreSection(section));
|
||||||
$('.test-regexp', el).addEventListener('click', () => {
|
$('.test-regexp', el).addEventListener('click', () => {
|
||||||
regExpTester.toggle();
|
regExpTester.toggle();
|
||||||
updateRegexpTester();
|
updateRegexpTester();
|
||||||
});
|
});
|
||||||
|
initBeautifyButton($('.beautify-section', el), () => [cm]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleKeydown(cm, event) {
|
function handleKeydown(cm, event) {
|
||||||
|
|
|
@ -34,7 +34,8 @@ function createSectionsEditor({style, onTitleChanged}) {
|
||||||
$('#from-mozilla').addEventListener('click', () => showMozillaFormatImport());
|
$('#from-mozilla').addEventListener('click', () => showMozillaFormatImport());
|
||||||
$('#save-button').addEventListener('click', saveStyle);
|
$('#save-button').addEventListener('click', saveStyle);
|
||||||
|
|
||||||
document.addEventListener('wheel', scrollEntirePageOnCtrlShift);
|
document.addEventListener('wheel', scrollEntirePageOnCtrlShift, {passive: false});
|
||||||
|
CodeMirror.defaults.extraKeys['Shift-Ctrl-Wheel'] = 'scrollWindow';
|
||||||
|
|
||||||
if (!FIREFOX) {
|
if (!FIREFOX) {
|
||||||
$$([
|
$$([
|
||||||
|
@ -154,9 +155,7 @@ function createSectionsEditor({style, onTitleChanged}) {
|
||||||
function closestVisible(nearbyElement) {
|
function closestVisible(nearbyElement) {
|
||||||
const cm =
|
const cm =
|
||||||
nearbyElement instanceof CodeMirror ? nearbyElement :
|
nearbyElement instanceof CodeMirror ? nearbyElement :
|
||||||
nearbyElement instanceof Node &&
|
nearbyElement instanceof Node && getAssociatedEditor(nearbyElement) || getLastActivatedEditor();
|
||||||
(nearbyElement.closest('#sections > .section') || {}).CodeMirror ||
|
|
||||||
getLastActivatedEditor();
|
|
||||||
if (nearbyElement instanceof Node && cm) {
|
if (nearbyElement instanceof Node && cm) {
|
||||||
const {left, top} = nearbyElement.getBoundingClientRect();
|
const {left, top} = nearbyElement.getBoundingClientRect();
|
||||||
const bounds = cm.display.wrapper.getBoundingClientRect();
|
const bounds = cm.display.wrapper.getBoundingClientRect();
|
||||||
|
@ -228,6 +227,15 @@ function createSectionsEditor({style, onTitleChanged}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getAssociatedEditor(nearbyElement) {
|
||||||
|
for (let el = nearbyElement; el; el = el.parentElement) {
|
||||||
|
// added by createSection
|
||||||
|
if (el.CodeMirror) {
|
||||||
|
return el.CodeMirror;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getEditors() {
|
function getEditors() {
|
||||||
return sections.filter(s => !s.isRemoved()).map(s => s.cm);
|
return sections.filter(s => !s.isRemoved()).map(s => s.cm);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ function showKeyMapHelp() {
|
||||||
const keyMap = mergeKeyMaps({}, prefs.get('editor.keyMap'), CodeMirror.defaults.extraKeys);
|
const keyMap = mergeKeyMaps({}, prefs.get('editor.keyMap'), CodeMirror.defaults.extraKeys);
|
||||||
const keyMapSorted = Object.keys(keyMap)
|
const keyMapSorted = Object.keys(keyMap)
|
||||||
.map(key => ({key, cmd: keyMap[key]}))
|
.map(key => ({key, cmd: keyMap[key]}))
|
||||||
.concat([{key: 'Shift-Ctrl-Wheel', cmd: 'scrollWindow'}])
|
|
||||||
.sort((a, b) => (a.cmd < b.cmd || (a.cmd === b.cmd && a.key < b.key) ? -1 : 1));
|
.sort((a, b) => (a.cmd < b.cmd || (a.cmd === b.cmd && a.key < b.key) ? -1 : 1));
|
||||||
const table = template.keymapHelp.cloneNode(true);
|
const table = template.keymapHelp.cloneNode(true);
|
||||||
const tBody = table.tBodies[0];
|
const tBody = table.tBodies[0];
|
||||||
|
|
52
edit/util.js
52
edit/util.js
|
@ -1,4 +1,5 @@
|
||||||
/* exported dirtyReporter memoize clipString sectionsToMozFormat */
|
/* global CodeMirror $create prefs */
|
||||||
|
/* exported dirtyReporter memoize clipString sectionsToMozFormat createHotkeyInput */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
function dirtyReporter() {
|
function dirtyReporter() {
|
||||||
|
@ -135,3 +136,52 @@ function memoize(fn) {
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!string} prefId
|
||||||
|
* @param {?function(isEnter:boolean)} onDone
|
||||||
|
*/
|
||||||
|
function createHotkeyInput(prefId, onDone = () => {}) {
|
||||||
|
return $create('input', {
|
||||||
|
type: 'search',
|
||||||
|
spellcheck: false,
|
||||||
|
value: prefs.get(prefId),
|
||||||
|
onkeydown(event) {
|
||||||
|
const key = CodeMirror.keyName(event);
|
||||||
|
if (key === 'Tab' || key === 'Shift-Tab') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
switch (key) {
|
||||||
|
case 'Enter':
|
||||||
|
if (this.checkValidity()) onDone(true);
|
||||||
|
return;
|
||||||
|
case 'Esc':
|
||||||
|
onDone(false);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
// disallow: [Shift?] characters, modifiers-only, [modifiers?] + Esc, Tab, nav keys
|
||||||
|
if (!key || new RegExp('^(' + [
|
||||||
|
'(Back)?Space',
|
||||||
|
'(Shift-)?.', // a single character
|
||||||
|
'(Shift-?|Ctrl-?|Alt-?|Cmd-?){0,2}(|Esc|Tab|(Page)?(Up|Down)|Left|Right|Home|End|Insert|Delete)',
|
||||||
|
].join('|') + ')$', 'i').test(key)) {
|
||||||
|
this.value = key || this.value;
|
||||||
|
this.setCustomValidity('Not allowed');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.value = key;
|
||||||
|
this.setCustomValidity('');
|
||||||
|
prefs.set(prefId, key);
|
||||||
|
},
|
||||||
|
oninput() {
|
||||||
|
// fired on pressing "x" to clear the field
|
||||||
|
prefs.set(prefId, '');
|
||||||
|
},
|
||||||
|
onpaste(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
<link href="install-usercss/install-usercss.css" rel="stylesheet">
|
<link href="install-usercss/install-usercss.css" rel="stylesheet">
|
||||||
|
|
||||||
<script src="js/polyfill.js"></script>
|
<script src="js/polyfill.js"></script>
|
||||||
<script src="js/promisify.js"></script>
|
|
||||||
<script src="js/msg.js"></script>
|
<script src="js/msg.js"></script>
|
||||||
<script src="js/messaging.js"></script>
|
<script src="js/messaging.js"></script>
|
||||||
<script src="js/prefs.js"></script>
|
<script src="js/prefs.js"></script>
|
||||||
|
|
|
@ -405,13 +405,9 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
port.onDisconnect.addListener(() => {
|
port.onDisconnect.addListener(() => {
|
||||||
chrome.tabs.get(tabId, tab => {
|
browser.tabs.get(tabId)
|
||||||
if (chrome.runtime.lastError) {
|
.then(tab => tab.url === initialUrl && location.reload())
|
||||||
closeCurrentTab();
|
.catch(closeCurrentTab);
|
||||||
} else if (tab.url === initialUrl) {
|
|
||||||
location.reload();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
return ({timer = true} = {}) => new Promise((resolve, reject) => {
|
return ({timer = true} = {}) => new Promise((resolve, reject) => {
|
||||||
const id = performance.now();
|
const id = performance.now();
|
||||||
|
|
21
js/dom.js
21
js/dom.js
|
@ -85,6 +85,27 @@ onDOMready().then(() => {
|
||||||
|
|
||||||
// set language for CSS :lang and [FF-only] hyphenation
|
// set language for CSS :lang and [FF-only] hyphenation
|
||||||
document.documentElement.setAttribute('lang', chrome.i18n.getUILanguage());
|
document.documentElement.setAttribute('lang', chrome.i18n.getUILanguage());
|
||||||
|
// avoid adding # to the page URL when clicking dummy links
|
||||||
|
document.addEventListener('click', e => {
|
||||||
|
if (e.target.closest('a[href="#"]')) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// update inputs on mousewheel when focused
|
||||||
|
document.addEventListener('wheel', event => {
|
||||||
|
const el = document.activeElement;
|
||||||
|
if (!el || el !== event.target && !el.contains(event.target)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (el.tagName === 'SELECT') {
|
||||||
|
el.selectedIndex = Math.max(0, Math.min(el.length - 1, el.selectedIndex + Math.sign(event.deltaY)));
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
event.stopImmediatePropagation();
|
||||||
|
}, {
|
||||||
|
capture: true,
|
||||||
|
passive: false,
|
||||||
|
});
|
||||||
|
|
||||||
function onDOMready() {
|
function onDOMready() {
|
||||||
if (document.readyState !== 'loading') {
|
if (document.readyState !== 'loading') {
|
||||||
|
|
|
@ -1,18 +1,16 @@
|
||||||
/* exported getTab getActiveTab onTabReady stringAsRegExp openURL ignoreChromeError
|
/* exported getTab getActiveTab onTabReady stringAsRegExp openURL ignoreChromeError
|
||||||
getStyleWithNoCode tryRegExp sessionStorageHash download deepEqual
|
getStyleWithNoCode tryRegExp sessionStorageHash download deepEqual
|
||||||
closeCurrentTab capitalize CHROME_HAS_BORDER_BUG */
|
closeCurrentTab capitalize CHROME_HAS_BORDER_BUG */
|
||||||
/* global promisify */
|
/* global promisifyChrome */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const CHROME = Boolean(chrome.app) && parseInt(navigator.userAgent.match(/Chrom\w+\/(?:\d+\.){2}(\d+)|$/)[1]);
|
const CHROME = Boolean(chrome.app) && parseInt(navigator.userAgent.match(/Chrom\w+\/(\d+)|$/)[1]);
|
||||||
const OPERA = Boolean(chrome.app) && parseFloat(navigator.userAgent.match(/\bOPR\/(\d+\.\d+)|$/)[1]);
|
const OPERA = Boolean(chrome.app) && parseFloat(navigator.userAgent.match(/\bOPR\/(\d+\.\d+)|$/)[1]);
|
||||||
const VIVALDI = Boolean(chrome.app) && navigator.userAgent.includes('Vivaldi');
|
const VIVALDI = Boolean(chrome.app) && navigator.userAgent.includes('Vivaldi');
|
||||||
// FIXME: who use this?
|
|
||||||
// const ANDROID = !chrome.windows;
|
|
||||||
let FIREFOX = !chrome.app && parseFloat(navigator.userAgent.match(/\bFirefox\/(\d+\.\d+)|$/)[1]);
|
let FIREFOX = !chrome.app && parseFloat(navigator.userAgent.match(/\bFirefox\/(\d+\.\d+)|$/)[1]);
|
||||||
|
|
||||||
// see PR #781
|
// see PR #781
|
||||||
const CHROME_HAS_BORDER_BUG = CHROME >= 3167 && CHROME <= 3704;
|
const CHROME_HAS_BORDER_BUG = CHROME >= 62 && CHROME <= 74;
|
||||||
|
|
||||||
if (!CHROME && !chrome.browserAction.openPopup) {
|
if (!CHROME && !chrome.browserAction.openPopup) {
|
||||||
// in FF pre-57 legacy addons can override useragent so we assume the worst
|
// in FF pre-57 legacy addons can override useragent so we assume the worst
|
||||||
|
@ -62,7 +60,7 @@ const URLS = {
|
||||||
|
|
||||||
// Chrome 61.0.3161+ doesn't run content scripts on NTP https://crrev.com/2978953002/
|
// Chrome 61.0.3161+ doesn't run content scripts on NTP https://crrev.com/2978953002/
|
||||||
// TODO: remove when "minimum_chrome_version": "61" or higher
|
// TODO: remove when "minimum_chrome_version": "61" or higher
|
||||||
chromeProtectsNTP: CHROME >= 3161,
|
chromeProtectsNTP: CHROME >= 61,
|
||||||
|
|
||||||
userstylesOrgJson: 'https://userstyles.org/styles/chrome/',
|
userstylesOrgJson: 'https://userstyles.org/styles/chrome/',
|
||||||
|
|
||||||
|
@ -95,33 +93,20 @@ if (IS_BG) {
|
||||||
// Object.defineProperty(window, 'localStorage', {value: {}});
|
// Object.defineProperty(window, 'localStorage', {value: {}});
|
||||||
// Object.defineProperty(window, 'sessionStorage', {value: {}});
|
// Object.defineProperty(window, 'sessionStorage', {value: {}});
|
||||||
|
|
||||||
const createTab = promisify(chrome.tabs.create.bind(chrome.tabs));
|
promisifyChrome({
|
||||||
const queryTabs = promisify(chrome.tabs.query.bind(chrome.tabs));
|
tabs: ['create', 'get', 'getCurrent', 'move', 'query', 'update'],
|
||||||
const updateTab = promisify(chrome.tabs.update.bind(chrome.tabs));
|
windows: ['create', 'update'], // Android doesn't have chrome.windows
|
||||||
const moveTabs = promisify(chrome.tabs.move.bind(chrome.tabs));
|
});
|
||||||
|
|
||||||
// Android doesn't have chrome.windows
|
|
||||||
const updateWindow = chrome.windows && promisify(chrome.windows.update.bind(chrome.windows));
|
|
||||||
const createWindow = chrome.windows && promisify(chrome.windows.create.bind(chrome.windows));
|
|
||||||
// FF57+ supports openerTabId, but not in Android
|
// FF57+ supports openerTabId, but not in Android
|
||||||
// (detecting FF57 by the feature it added, not navigator.ua which may be spoofed in about:config)
|
// (detecting FF57 by the feature it added, not navigator.ua which may be spoofed in about:config)
|
||||||
const openerTabIdSupported = (!FIREFOX || window.AbortController) && chrome.windows != null;
|
const openerTabIdSupported = (!FIREFOX || window.AbortController) && chrome.windows != null;
|
||||||
|
|
||||||
function getTab(id) {
|
|
||||||
return new Promise(resolve =>
|
|
||||||
chrome.tabs.get(id, tab =>
|
|
||||||
!chrome.runtime.lastError && resolve(tab)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function getOwnTab() {
|
function getOwnTab() {
|
||||||
return new Promise(resolve =>
|
return browser.tabs.getCurrent();
|
||||||
chrome.tabs.getCurrent(tab => resolve(tab)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function getActiveTab() {
|
function getActiveTab() {
|
||||||
return queryTabs({currentWindow: true, active: true})
|
return browser.tabs.query({currentWindow: true, active: true})
|
||||||
.then(tabs => tabs[0]);
|
.then(tabs => tabs[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +127,7 @@ function urlToMatchPattern(url, ignoreSearch) {
|
||||||
|
|
||||||
function findExistingTab({url, currentWindow, ignoreHash = true, ignoreSearch = false}) {
|
function findExistingTab({url, currentWindow, ignoreHash = true, ignoreSearch = false}) {
|
||||||
url = new URL(url);
|
url = new URL(url);
|
||||||
return queryTabs({url: urlToMatchPattern(url, ignoreSearch), currentWindow})
|
return browser.tabs.query({url: urlToMatchPattern(url, ignoreSearch), currentWindow})
|
||||||
// FIXME: is tab.url always normalized?
|
// FIXME: is tab.url always normalized?
|
||||||
.then(tabs => tabs.find(matchTab));
|
.then(tabs => tabs.find(matchTab));
|
||||||
|
|
||||||
|
@ -193,8 +178,8 @@ function openURL({
|
||||||
url: url !== tab.url && url.includes('#') ? url : undefined,
|
url: url !== tab.url && url.includes('#') ? url : undefined,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (newWindow && createWindow) {
|
if (newWindow && browser.windows) {
|
||||||
return createWindow(Object.assign({url}, windowPosition))
|
return browser.windows.create(Object.assign({url}, windowPosition))
|
||||||
.then(wnd => wnd.tabs[0]);
|
.then(wnd => wnd.tabs[0]);
|
||||||
}
|
}
|
||||||
return getActiveTab().then((activeTab = {url: ''}) =>
|
return getActiveTab().then((activeTab = {url: ''}) =>
|
||||||
|
@ -207,7 +192,7 @@ function openURL({
|
||||||
if (id != null && !openerTab.incognito && openerTabIdSupported) {
|
if (id != null && !openerTab.incognito && openerTabIdSupported) {
|
||||||
options.openerTabId = id;
|
options.openerTabId = id;
|
||||||
}
|
}
|
||||||
return createTab(options);
|
return browser.tabs.create(options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,9 +219,9 @@ function activateTab(tab, {url, index, openerTabId} = {}) {
|
||||||
options.openerTabId = openerTabId;
|
options.openerTabId = openerTabId;
|
||||||
}
|
}
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
updateTab(tab.id, options),
|
browser.tabs.update(tab.id, options),
|
||||||
updateWindow && updateWindow(tab.windowId, {focused: true}),
|
browser.windows && browser.windows.update(tab.windowId, {focused: true}),
|
||||||
index != null && moveTabs(tab.id, {index})
|
index != null && browser.tabs.move(tab.id, {index})
|
||||||
])
|
])
|
||||||
.then(() => tab);
|
.then(() => tab);
|
||||||
}
|
}
|
||||||
|
@ -381,7 +366,8 @@ function download(url, {
|
||||||
body,
|
body,
|
||||||
responseType = 'text',
|
responseType = 'text',
|
||||||
requiredStatusCode = 200,
|
requiredStatusCode = 200,
|
||||||
timeout = 10e3,
|
timeout = 10e3, // connection timeout
|
||||||
|
loadTimeout = 2 * 60e3, // data transfer timeout (counted from the first remote response)
|
||||||
headers = {
|
headers = {
|
||||||
'Content-type': 'application/x-www-form-urlencoded',
|
'Content-type': 'application/x-www-form-urlencoded',
|
||||||
},
|
},
|
||||||
|
@ -398,23 +384,41 @@ function download(url, {
|
||||||
const usoVars = [];
|
const usoVars = [];
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
let xhr;
|
||||||
const u = new URL(collapseUsoVars(url));
|
const u = new URL(collapseUsoVars(url));
|
||||||
if (u.protocol === 'file:' && FIREFOX) {
|
const onTimeout = () => {
|
||||||
|
if (xhr) xhr.abort();
|
||||||
|
reject(new Error('Timeout fetching ' + u.href));
|
||||||
|
};
|
||||||
|
let timer = setTimeout(onTimeout, timeout);
|
||||||
|
const switchTimer = () => {
|
||||||
|
clearTimeout(timer);
|
||||||
|
timer = loadTimeout && setTimeout(onTimeout, loadTimeout);
|
||||||
|
};
|
||||||
|
if (u.protocol === 'file:' && FIREFOX) { // TODO: maybe remove this since FF68+ can't do it anymore
|
||||||
// https://stackoverflow.com/questions/42108782/firefox-webextensions-get-local-files-content-by-path
|
// https://stackoverflow.com/questions/42108782/firefox-webextensions-get-local-files-content-by-path
|
||||||
// FIXME: add FetchController when it is available.
|
// FIXME: add FetchController when it is available.
|
||||||
const timer = setTimeout(reject, timeout, new Error('Timeout fetching ' + u.href));
|
|
||||||
fetch(u.href, {mode: 'same-origin'})
|
fetch(u.href, {mode: 'same-origin'})
|
||||||
.then(r => {
|
.then(r => {
|
||||||
clearTimeout(timer);
|
switchTimer();
|
||||||
return r.status === 200 ? r.text() : Promise.reject(r.status);
|
return r.status === 200 ? r.text() : Promise.reject(r.status);
|
||||||
})
|
})
|
||||||
.catch(reject)
|
.catch(reject)
|
||||||
.then(resolve);
|
.then(text => {
|
||||||
|
clearTimeout(timer);
|
||||||
|
resolve(text);
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const xhr = new XMLHttpRequest();
|
xhr = new XMLHttpRequest();
|
||||||
xhr.timeout = timeout;
|
xhr.onreadystatechange = () => {
|
||||||
|
if (xhr.readyState >= XMLHttpRequest.HEADERS_RECEIVED) {
|
||||||
|
xhr.onreadystatechange = null;
|
||||||
|
switchTimer();
|
||||||
|
}
|
||||||
|
};
|
||||||
xhr.onloadend = event => {
|
xhr.onloadend = event => {
|
||||||
|
clearTimeout(timer);
|
||||||
if (event.type !== 'error' && (
|
if (event.type !== 'error' && (
|
||||||
xhr.status === requiredStatusCode || !requiredStatusCode ||
|
xhr.status === requiredStatusCode || !requiredStatusCode ||
|
||||||
u.protocol === 'file:')) {
|
u.protocol === 'file:')) {
|
||||||
|
|
24
js/msg.js
24
js/msg.js
|
@ -1,12 +1,12 @@
|
||||||
/* global promisify deepCopy */
|
/* global promisifyChrome deepCopy */
|
||||||
// deepCopy is only used if the script is executed in extension pages.
|
// deepCopy is only used if the script is executed in extension pages.
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
self.msg = self.INJECTED === 1 ? self.msg : (() => {
|
self.msg = self.INJECTED === 1 ? self.msg : (() => {
|
||||||
const runtimeSend = promisify(chrome.runtime.sendMessage.bind(chrome.runtime));
|
promisifyChrome({
|
||||||
const tabSend = chrome.tabs && promisify(chrome.tabs.sendMessage.bind(chrome.tabs));
|
runtime: ['sendMessage'],
|
||||||
const tabQuery = chrome.tabs && promisify(chrome.tabs.query.bind(chrome.tabs));
|
tabs: ['sendMessage', 'query'],
|
||||||
|
});
|
||||||
const isBg = chrome.extension.getBackgroundPage && chrome.extension.getBackgroundPage() === window;
|
const isBg = chrome.extension.getBackgroundPage && chrome.extension.getBackgroundPage() === window;
|
||||||
if (isBg) {
|
if (isBg) {
|
||||||
window._msg = {
|
window._msg = {
|
||||||
|
@ -49,19 +49,21 @@ self.msg = self.INJECTED === 1 ? self.msg : (() => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (chrome.runtime.getBackgroundPage) {
|
if (chrome.runtime.getBackgroundPage) {
|
||||||
return promisify(chrome.runtime.getBackgroundPage.bind(chrome.runtime))()
|
promisifyChrome({
|
||||||
.catch(() => null);
|
runtime: ['getBackgroundPage'],
|
||||||
|
});
|
||||||
|
return browser.runtime.getBackgroundPage().catch(() => null);
|
||||||
}
|
}
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
function send(data, target = 'extension') {
|
function send(data, target = 'extension') {
|
||||||
const message = {data, target};
|
const message = {data, target};
|
||||||
return runtimeSend(message).then(unwrapData);
|
return browser.runtime.sendMessage(message).then(unwrapData);
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendTab(tabId, data, options, target = 'tab') {
|
function sendTab(tabId, data, options, target = 'tab') {
|
||||||
return tabSend(tabId, {data, target}, options)
|
return browser.tabs.sendMessage(tabId, {data, target}, options)
|
||||||
.then(unwrapData);
|
.then(unwrapData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +101,7 @@ self.msg = self.INJECTED === 1 ? self.msg : (() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
function broadcastTab(data, filter, options, ignoreExtension = false, target = 'tab') {
|
function broadcastTab(data, filter, options, ignoreExtension = false, target = 'tab') {
|
||||||
return tabQuery({})
|
return browser.tabs.query({})
|
||||||
// TODO: send to activated tabs first?
|
// TODO: send to activated tabs first?
|
||||||
.then(tabs => {
|
.then(tabs => {
|
||||||
const requests = [];
|
const requests = [];
|
||||||
|
@ -123,7 +125,7 @@ self.msg = self.INJECTED === 1 ? self.msg : (() => {
|
||||||
const message = {data: dataObj, target};
|
const message = {data: dataObj, target};
|
||||||
if (tab && tab.id) {
|
if (tab && tab.id) {
|
||||||
requests.push(
|
requests.push(
|
||||||
tabSend(tab.id, message, options)
|
browser.tabs.sendMessage(tab.id, message, options)
|
||||||
.then(unwrapData)
|
.then(unwrapData)
|
||||||
.catch(ignoreError)
|
.catch(ignoreError)
|
||||||
);
|
);
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
// eslint-disable-next-line no-unused-expressions
|
// eslint-disable-next-line no-unused-expressions
|
||||||
self.INJECTED !== 1 && (() => {
|
self.INJECTED !== 1 && (() => {
|
||||||
|
|
||||||
|
// this part runs in workers, content scripts, our extension pages
|
||||||
|
|
||||||
if (!Object.entries) {
|
if (!Object.entries) {
|
||||||
Object.entries = obj => Object.keys(obj).map(k => [k, obj[k]]);
|
Object.entries = obj => Object.keys(obj).map(k => [k, obj[k]]);
|
||||||
}
|
}
|
||||||
|
@ -10,9 +12,38 @@ self.INJECTED !== 1 && (() => {
|
||||||
Object.values = obj => Object.keys(obj).map(k => obj[k]);
|
Object.values = obj => Object.keys(obj).map(k => obj[k]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// the above was shared by content scripts and workers,
|
// don't use self.chrome. It is undefined in Firefox
|
||||||
// the rest is only needed for our extension pages
|
if (typeof chrome !== 'object') return;
|
||||||
if (!self.chrome || !self.chrome.tabs) return;
|
// the rest is for content scripts and our extension pages
|
||||||
|
|
||||||
|
self.browser = polyfillBrowser();
|
||||||
|
|
||||||
|
/* Promisifies the specified `chrome` methods into `browser`.
|
||||||
|
The definitions is an object like this: {
|
||||||
|
'storage.sync': ['get', 'set'], // if deeper than one level, combine the path via `.`
|
||||||
|
windows: ['create', 'update'], // items and sub-objects will only be created if present in `chrome`
|
||||||
|
} */
|
||||||
|
self.promisifyChrome = definitions => {
|
||||||
|
for (const [scopeName, methods] of Object.entries(definitions)) {
|
||||||
|
const path = scopeName.split('.');
|
||||||
|
const src = path.reduce((obj, p) => obj && obj[p], chrome);
|
||||||
|
if (!src) continue;
|
||||||
|
const dst = path.reduce((obj, p) => obj[p] || (obj[p] = {}), browser);
|
||||||
|
for (const name of methods) {
|
||||||
|
const fn = src[name];
|
||||||
|
if (!fn || dst[name] && !dst[name].isTrap) continue;
|
||||||
|
dst[name] = (...args) => new Promise((resolve, reject) =>
|
||||||
|
fn.call(src, ...args, (...results) =>
|
||||||
|
chrome.runtime.lastError ?
|
||||||
|
reject(chrome.runtime.lastError) :
|
||||||
|
resolve(results.length <= 1 ? results[0] : results)));
|
||||||
|
// a couple of callbacks have 2 parameters (we don't use those methods, but just in case)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!chrome.tabs) return;
|
||||||
|
// the rest is for our extension pages
|
||||||
|
|
||||||
if (typeof document === 'object') {
|
if (typeof document === 'object') {
|
||||||
const ELEMENT_METH = {
|
const ELEMENT_METH = {
|
||||||
|
@ -75,4 +106,27 @@ self.INJECTED !== 1 && (() => {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Object.defineProperty(self, 'sessionStorage', {value: {}});
|
Object.defineProperty(self, 'sessionStorage', {value: {}});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function polyfillBrowser() {
|
||||||
|
if (typeof browser === 'object' && browser.runtime) {
|
||||||
|
return browser;
|
||||||
|
}
|
||||||
|
return createTrap(chrome, null);
|
||||||
|
|
||||||
|
function createTrap(base, parent) {
|
||||||
|
const target = typeof base === 'function' ? () => {} : {};
|
||||||
|
target.isTrap = true;
|
||||||
|
return new Proxy(target, {
|
||||||
|
get: (target, prop) => {
|
||||||
|
if (target[prop]) return target[prop];
|
||||||
|
if (base[prop] && (typeof base[prop] === 'object' || typeof base[prop] === 'function')) {
|
||||||
|
target[prop] = createTrap(base[prop], base);
|
||||||
|
return target[prop];
|
||||||
|
}
|
||||||
|
return base[prop];
|
||||||
|
},
|
||||||
|
apply: (target, thisArg, args) => base.apply(parent, args)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
|
|
12
js/prefs.js
12
js/prefs.js
|
@ -1,4 +1,4 @@
|
||||||
/* global promisify */
|
/* global promisifyChrome */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
self.prefs = self.INJECTED === 1 ? self.prefs : (() => {
|
self.prefs = self.INJECTED === 1 ? self.prefs : (() => {
|
||||||
|
@ -63,6 +63,7 @@ self.prefs = self.INJECTED === 1 ? self.prefs : (() => {
|
||||||
end_with_newline: false,
|
end_with_newline: false,
|
||||||
indent_conditional: true,
|
indent_conditional: true,
|
||||||
},
|
},
|
||||||
|
'editor.beautify.hotkey': '',
|
||||||
'editor.lintDelay': 300, // lint gutter marker update delay, ms
|
'editor.lintDelay': 300, // lint gutter marker update delay, ms
|
||||||
'editor.linter': 'csslint', // 'csslint' or 'stylelint' or ''
|
'editor.linter': 'csslint', // 'csslint' or 'stylelint' or ''
|
||||||
'editor.lintReportDelay': 500, // lint report update delay, ms
|
'editor.lintReportDelay': 500, // lint report update delay, ms
|
||||||
|
@ -110,10 +111,11 @@ self.prefs = self.INJECTED === 1 ? self.prefs : (() => {
|
||||||
specific: new Map(),
|
specific: new Map(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const syncSet = promisify(chrome.storage.sync.set.bind(chrome.storage.sync));
|
promisifyChrome({
|
||||||
const syncGet = promisify(chrome.storage.sync.get.bind(chrome.storage.sync));
|
'storage.sync': ['get', 'set'],
|
||||||
|
});
|
||||||
|
|
||||||
const initializing = syncGet('settings')
|
const initializing = browser.storage.sync.get('settings')
|
||||||
.then(result => {
|
.then(result => {
|
||||||
if (result.settings) {
|
if (result.settings) {
|
||||||
setAll(result.settings, true);
|
setAll(result.settings, true);
|
||||||
|
@ -240,7 +242,7 @@ self.prefs = self.INJECTED === 1 ? self.prefs : (() => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
timer = null;
|
timer = null;
|
||||||
syncSet({settings: values})
|
browser.storage.sync.set({settings: values})
|
||||||
.then(resolve, reject);
|
.then(resolve, reject);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
'use strict';
|
|
||||||
/*
|
|
||||||
Convert chrome APIs into promises. Example:
|
|
||||||
|
|
||||||
const storageSyncGet = promisify(chrome.storage.sync.get.bind(chrome.storage.sync));
|
|
||||||
storageSyncGet(['key']).then(result => {...});
|
|
||||||
|
|
||||||
*/
|
|
||||||
self.promisify = self.INJECTED === 1 ? self.promisify : fn =>
|
|
||||||
(...args) =>
|
|
||||||
new Promise((resolve, reject) => {
|
|
||||||
fn(...args, (...result) => {
|
|
||||||
if (chrome.runtime.lastError) {
|
|
||||||
reject(chrome.runtime.lastError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resolve(
|
|
||||||
result.length === 0 ? undefined :
|
|
||||||
result.length === 1 ? result[0] : result
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,7 +1,12 @@
|
||||||
/* global loadScript tryJSONparse */
|
/* global loadScript tryJSONparse promisifyChrome */
|
||||||
/* exported chromeLocal chromeSync */
|
/* exported chromeLocal chromeSync */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
promisifyChrome({
|
||||||
|
'storage.local': ['get', 'remove', 'set'],
|
||||||
|
'storage.sync': ['get', 'remove', 'set'],
|
||||||
|
});
|
||||||
|
|
||||||
const [chromeLocal, chromeSync] = (() => {
|
const [chromeLocal, chromeSync] = (() => {
|
||||||
return [
|
return [
|
||||||
createWrapper('local'),
|
createWrapper('local'),
|
||||||
|
@ -9,11 +14,11 @@ const [chromeLocal, chromeSync] = (() => {
|
||||||
];
|
];
|
||||||
|
|
||||||
function createWrapper(name) {
|
function createWrapper(name) {
|
||||||
const storage = chrome.storage[name];
|
const storage = browser.storage[name];
|
||||||
const wrapper = {
|
const wrapper = {
|
||||||
get: data => new Promise(resolve => storage.get(data, resolve)),
|
get: storage.get.bind(storage),
|
||||||
set: data => new Promise(resolve => storage.set(data, () => resolve(data))),
|
set: data => storage.set(data).then(() => data),
|
||||||
remove: data => new Promise(resolve => storage.remove(data, resolve)),
|
remove: storage.remove.bind(storage),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {String} key
|
* @param {String} key
|
||||||
|
|
|
@ -6,7 +6,7 @@ const workerUtil = (() => {
|
||||||
const loadedScripts = new Set();
|
const loadedScripts = new Set();
|
||||||
return {createWorker, createAPI, loadScript, cloneError};
|
return {createWorker, createAPI, loadScript, cloneError};
|
||||||
|
|
||||||
function createWorker({url, lifeTime = 30}) {
|
function createWorker({url, lifeTime = 300}) {
|
||||||
let worker;
|
let worker;
|
||||||
let id;
|
let id;
|
||||||
let timer;
|
let timer;
|
||||||
|
|
|
@ -147,7 +147,6 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script src="js/polyfill.js"></script>
|
<script src="js/polyfill.js"></script>
|
||||||
<script src="js/promisify.js"></script>
|
|
||||||
<script src="js/dom.js"></script>
|
<script src="js/dom.js"></script>
|
||||||
<script src="js/messaging.js"></script>
|
<script src="js/messaging.js"></script>
|
||||||
<script src="js/prefs.js"></script>
|
<script src="js/prefs.js"></script>
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
/* global messageBox styleSectionsEqual API onDOMready
|
/* global messageBox styleSectionsEqual API onDOMready
|
||||||
tryJSONparse scrollElementIntoView $ $$ API $create t animateElement
|
tryJSONparse scrollElementIntoView $ $$ API $create t animateElement
|
||||||
styleJSONseemsValid */
|
styleJSONseemsValid */
|
||||||
|
/* exported bulkChangeQueue bulkChangeTime */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const STYLISH_DUMP_FILE_EXT = '.txt';
|
const STYLISH_DUMP_FILE_EXT = '.txt';
|
||||||
const STYLUS_BACKUP_FILE_EXT = '.json';
|
const STYLUS_BACKUP_FILE_EXT = '.json';
|
||||||
|
|
||||||
|
let bulkChangeQueue = [];
|
||||||
|
let bulkChangeTime = 0;
|
||||||
|
|
||||||
onDOMready().then(() => {
|
onDOMready().then(() => {
|
||||||
$('#file-all-styles').onclick = event => {
|
$('#file-all-styles').onclick = event => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
@ -136,6 +140,8 @@ function importFromString(jsonString) {
|
||||||
items.push({info, item});
|
items.push({info, item});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
bulkChangeQueue.length = 0;
|
||||||
|
bulkChangeTime = performance.now();
|
||||||
return API.importManyStyles(items.map(i => i.item))
|
return API.importManyStyles(items.map(i => i.item))
|
||||||
.then(styles => {
|
.then(styles => {
|
||||||
for (let i = 0; i < styles.length; i++) {
|
for (let i = 0; i < styles.length; i++) {
|
||||||
|
|
|
@ -73,18 +73,22 @@ onDOMready().then(() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
function maybeRefocus(event) {
|
function maybeRefocus(event) {
|
||||||
if (event.altKey || event.ctrlKey || event.metaKey ||
|
if (event.altKey || event.metaKey || $('#message-box')) {
|
||||||
event.target.matches('[type="text"], [type="search"], [type="number"]') ||
|
|
||||||
$('#message-box')) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const inTextInput = event.target.matches('[type=text], [type=search], [type=number]');
|
||||||
const {which: k, key} = event;
|
const {which: k, key} = event;
|
||||||
// focus search field on "/" key
|
// focus search field on "/" or Ctrl-F key
|
||||||
if (key === '/' || !key && k === 191 && !event.shiftKey) {
|
if (event.ctrlKey
|
||||||
|
? (event.code === 'KeyF' || !event.code && k === 70) && !event.shiftKey
|
||||||
|
: (key === '/' || !key && k === 191 && !event.shiftKey) && !inTextInput) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
$('#search').focus();
|
$('#search').focus();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (event.ctrlKey || inTextInput) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const time = performance.now();
|
const time = performance.now();
|
||||||
if (
|
if (
|
||||||
// 0-9
|
// 0-9
|
||||||
|
|
|
@ -8,6 +8,7 @@ global messageBox getStyleWithNoCode
|
||||||
URLS enforceInputRange t tWordBreak formatDate
|
URLS enforceInputRange t tWordBreak formatDate
|
||||||
getOwnTab getActiveTab openURL animateElement sessionStorageHash debounce
|
getOwnTab getActiveTab openURL animateElement sessionStorageHash debounce
|
||||||
scrollElementIntoView CHROME VIVALDI FIREFOX router
|
scrollElementIntoView CHROME VIVALDI FIREFOX router
|
||||||
|
bulkChangeTime:true bulkChangeQueue
|
||||||
*/
|
*/
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
@ -16,6 +17,8 @@ let installed;
|
||||||
const ENTRY_ID_PREFIX_RAW = 'style-';
|
const ENTRY_ID_PREFIX_RAW = 'style-';
|
||||||
const ENTRY_ID_PREFIX = '#' + ENTRY_ID_PREFIX_RAW;
|
const ENTRY_ID_PREFIX = '#' + ENTRY_ID_PREFIX_RAW;
|
||||||
|
|
||||||
|
const BULK_THROTTLE_MS = 100;
|
||||||
|
|
||||||
const newUI = {
|
const newUI = {
|
||||||
enabled: prefs.get('manage.newUI'),
|
enabled: prefs.get('manage.newUI'),
|
||||||
favicons: prefs.get('manage.newUI.favicons'),
|
favicons: prefs.get('manage.newUI.favicons'),
|
||||||
|
@ -62,11 +65,13 @@ function onRuntimeMessage(msg) {
|
||||||
switch (msg.method) {
|
switch (msg.method) {
|
||||||
case 'styleUpdated':
|
case 'styleUpdated':
|
||||||
case 'styleAdded':
|
case 'styleAdded':
|
||||||
API.getStyle(msg.style.id, true)
|
|
||||||
.then(style => handleUpdate(style, msg));
|
|
||||||
break;
|
|
||||||
case 'styleDeleted':
|
case 'styleDeleted':
|
||||||
handleDelete(msg.style.id);
|
bulkChangeQueue.push(msg);
|
||||||
|
if (performance.now() - bulkChangeTime < BULK_THROTTLE_MS) {
|
||||||
|
debounce(handleBulkChange, BULK_THROTTLE_MS);
|
||||||
|
} else {
|
||||||
|
handleBulkChange();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'styleApply':
|
case 'styleApply':
|
||||||
case 'styleReplaceAll':
|
case 'styleReplaceAll':
|
||||||
|
@ -449,6 +454,8 @@ Object.assign(handleEvent, {
|
||||||
API.deleteStyle(id);
|
API.deleteStyle(id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
const deleteButton = $('#message-box-buttons > button');
|
||||||
|
if (deleteButton) deleteButton.removeAttribute('data-focused-via-click');
|
||||||
},
|
},
|
||||||
|
|
||||||
external(event) {
|
external(event) {
|
||||||
|
@ -529,6 +536,26 @@ Object.assign(handleEvent, {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function handleBulkChange() {
|
||||||
|
for (const msg of bulkChangeQueue) {
|
||||||
|
const {id} = msg.style;
|
||||||
|
if (msg.method === 'styleDeleted') {
|
||||||
|
handleDelete(id);
|
||||||
|
bulkChangeTime = performance.now();
|
||||||
|
} else {
|
||||||
|
handleUpdateForId(id, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bulkChangeQueue.length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleUpdateForId(id, opts) {
|
||||||
|
return API.getStyle(id, true).then(style => {
|
||||||
|
handleUpdate(style, opts);
|
||||||
|
bulkChangeTime = performance.now();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function handleUpdate(style, {reason, method} = {}) {
|
function handleUpdate(style, {reason, method} = {}) {
|
||||||
if (reason === 'editPreview' || reason === 'editPreviewEnd') return;
|
if (reason === 'editPreview' || reason === 'editPreviewEnd') return;
|
||||||
let entry;
|
let entry;
|
||||||
|
@ -548,7 +575,7 @@ function handleUpdate(style, {reason, method} = {}) {
|
||||||
handleUpdateInstalled(entry, reason);
|
handleUpdateInstalled(entry, reason);
|
||||||
}
|
}
|
||||||
filterAndAppend({entry}).then(sorter.update);
|
filterAndAppend({entry}).then(sorter.update);
|
||||||
if (!entry.matches('.hidden') && reason !== 'import') {
|
if (!entry.matches('.hidden') && reason !== 'import' && reason !== 'sync') {
|
||||||
animateElement(entry);
|
animateElement(entry);
|
||||||
requestAnimationFrame(() => scrollElementIntoView(entry));
|
requestAnimationFrame(() => scrollElementIntoView(entry));
|
||||||
}
|
}
|
||||||
|
@ -625,7 +652,7 @@ function switchUI({styleOnly} = {}) {
|
||||||
filter: none;
|
filter: none;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
`) + (CHROME >= 3004 ? `
|
`) + (CHROME >= 58 ? `
|
||||||
.newUI .entry {
|
.newUI .entry {
|
||||||
contain: strict;
|
contain: strict;
|
||||||
}
|
}
|
||||||
|
@ -677,15 +704,14 @@ function onVisibilityChange() {
|
||||||
// page restored without reloading via history navigation (currently only in FF)
|
// page restored without reloading via history navigation (currently only in FF)
|
||||||
// the catch here is that DOM may be outdated so we'll at least refresh the just edited style
|
// the catch here is that DOM may be outdated so we'll at least refresh the just edited style
|
||||||
// assuming other changes aren't important enough to justify making a complicated DOM sync
|
// assuming other changes aren't important enough to justify making a complicated DOM sync
|
||||||
case 'visible':
|
case 'visible': {
|
||||||
if (sessionStorage.justEditedStyleId) {
|
const id = sessionStorage.justEditedStyleId;
|
||||||
API.getStyle(Number(sessionStorage.justEditedStyleId), true)
|
if (id) {
|
||||||
.then(style => {
|
handleUpdateForId(Number(id), {method: 'styleUpdated'});
|
||||||
handleUpdate(style, {method: 'styleUpdated'});
|
|
||||||
});
|
|
||||||
delete sessionStorage.justEditedStyleId;
|
delete sessionStorage.justEditedStyleId;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
// going away
|
// going away
|
||||||
case 'hidden':
|
case 'hidden':
|
||||||
history.replaceState({scrollY: window.scrollY}, document.title);
|
history.replaceState({scrollY: window.scrollY}, document.title);
|
||||||
|
|
|
@ -32,7 +32,7 @@ const sorter = (() => {
|
||||||
},
|
},
|
||||||
dateUpdated: {
|
dateUpdated: {
|
||||||
text: t('dateUpdated'),
|
text: t('dateUpdated'),
|
||||||
parse: ({style}) => style.updateDate,
|
parse: ({style}) => style.updateDate || style.installDate,
|
||||||
sorter: sorterType.number
|
sorter: sorterType.number
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
{
|
{
|
||||||
"name": "Stylus",
|
"name": "Stylus",
|
||||||
"version": "1.5.10",
|
"version": "1.5.13",
|
||||||
"minimum_chrome_version": "49",
|
"minimum_chrome_version": "49",
|
||||||
"description": "__MSG_description__",
|
"description": "__MSG_description__",
|
||||||
"homepage_url": "https://add0n.com/stylus.html",
|
"homepage_url": "https://add0n.com/stylus.html",
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"icons": {
|
"icons": {
|
||||||
"16": "/images/icon/16.png",
|
"16": "images/icon/16.png",
|
||||||
"32": "/images/icon/32.png",
|
"32": "images/icon/32.png",
|
||||||
"48": "/images/icon/48.png",
|
"48": "images/icon/48.png",
|
||||||
"128": "/images/icon/128.png"
|
"128": "images/icon/128.png"
|
||||||
},
|
},
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"tabs",
|
"tabs",
|
||||||
|
@ -18,6 +18,7 @@
|
||||||
"webRequestBlocking",
|
"webRequestBlocking",
|
||||||
"contextMenus",
|
"contextMenus",
|
||||||
"storage",
|
"storage",
|
||||||
|
"unlimitedStorage",
|
||||||
"alarms",
|
"alarms",
|
||||||
"identity",
|
"identity",
|
||||||
"<all_urls>"
|
"<all_urls>"
|
||||||
|
@ -25,7 +26,6 @@
|
||||||
"background": {
|
"background": {
|
||||||
"scripts": [
|
"scripts": [
|
||||||
"js/polyfill.js",
|
"js/polyfill.js",
|
||||||
"js/promisify.js",
|
|
||||||
"js/messaging.js",
|
"js/messaging.js",
|
||||||
"js/msg.js",
|
"js/msg.js",
|
||||||
"js/storage-util.js",
|
"js/storage-util.js",
|
||||||
|
@ -77,7 +77,6 @@
|
||||||
"match_about_blank": true,
|
"match_about_blank": true,
|
||||||
"js": [
|
"js": [
|
||||||
"js/polyfill.js",
|
"js/polyfill.js",
|
||||||
"js/promisify.js",
|
|
||||||
"js/msg.js",
|
"js/msg.js",
|
||||||
"js/prefs.js",
|
"js/prefs.js",
|
||||||
"content/style-injector.js",
|
"content/style-injector.js",
|
||||||
|
@ -99,10 +98,10 @@
|
||||||
],
|
],
|
||||||
"browser_action": {
|
"browser_action": {
|
||||||
"default_icon": {
|
"default_icon": {
|
||||||
"16": "/images/icon/16w.png",
|
"16": "images/icon/16w.png",
|
||||||
"32": "/images/icon/32w.png",
|
"32": "images/icon/32w.png",
|
||||||
"19": "/images/icon/19w.png",
|
"19": "images/icon/19w.png",
|
||||||
"38": "/images/icon/38w.png"
|
"38": "images/icon/38w.png"
|
||||||
},
|
},
|
||||||
"default_title": "Stylus",
|
"default_title": "Stylus",
|
||||||
"default_popup": "popup.html"
|
"default_popup": "popup.html"
|
||||||
|
|
|
@ -134,6 +134,15 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.danger #message-box-buttons > button:not([data-focused-via-click]):first-child:focus {
|
||||||
|
outline: red auto 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FF ignores color with 'auto' */
|
||||||
|
.firefox .danger #message-box-buttons > button:not([data-focused-via-click]):first-child:focus {
|
||||||
|
outline: red solid 1px;
|
||||||
|
}
|
||||||
|
|
||||||
.non-windows #message-box-buttons {
|
.non-windows #message-box-buttons {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
direction: rtl;
|
direction: rtl;
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
|
|
||||||
<script src="js/polyfill.js"></script>
|
<script src="js/polyfill.js"></script>
|
||||||
<script src="js/dom.js"></script>
|
<script src="js/dom.js"></script>
|
||||||
<script src="js/promisify.js"></script>
|
|
||||||
<script src="js/messaging.js"></script>
|
<script src="js/messaging.js"></script>
|
||||||
<script src="js/msg.js"></script>
|
<script src="js/msg.js"></script>
|
||||||
<script src="js/localization.js"></script>
|
<script src="js/localization.js"></script>
|
||||||
|
|
|
@ -8,8 +8,8 @@ setupLivePrefs();
|
||||||
enforceInputRange($('#popupWidth'));
|
enforceInputRange($('#popupWidth'));
|
||||||
setTimeout(splitLongTooltips);
|
setTimeout(splitLongTooltips);
|
||||||
|
|
||||||
// TODO: add max version to re-enable once crbug.com/996859 is resolved
|
// https://github.com/openstyles/stylus/issues/822
|
||||||
if (!FIREFOX && CHROME >= 3809) {
|
if (!FIREFOX && CHROME >= 76 && CHROME <= 81) {
|
||||||
const dropboxOption = $('option[value="dropbox"]');
|
const dropboxOption = $('option[value="dropbox"]');
|
||||||
dropboxOption.disabled = true;
|
dropboxOption.disabled = true;
|
||||||
dropboxOption.setAttribute('title', t('hostDisabled'));
|
dropboxOption.setAttribute('title', t('hostDisabled'));
|
||||||
|
@ -23,7 +23,7 @@ if (CHROME_HAS_BORDER_BUG) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// collapse #advanced block in Chrome pre-66 (classic chrome://extensions UI)
|
// collapse #advanced block in Chrome pre-66 (classic chrome://extensions UI)
|
||||||
if (!FIREFOX && !OPERA && CHROME < 3343) {
|
if (!FIREFOX && !OPERA && CHROME < 66) {
|
||||||
const block = $('#advanced');
|
const block = $('#advanced');
|
||||||
$('h1', block).onclick = event => {
|
$('h1', block).onclick = event => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
2789
package-lock.json
generated
2789
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
26
package.json
26
package.json
|
@ -1,30 +1,32 @@
|
||||||
{
|
{
|
||||||
"name": "Stylus",
|
"name": "Stylus",
|
||||||
"version": "1.5.10",
|
"version": "1.5.13",
|
||||||
"description": "Redesign the web with Stylus, a user styles manager",
|
"description": "Redesign the web with Stylus, a user styles manager",
|
||||||
"license": "GPL-3.0-only",
|
"license": "GPL-3.0-only",
|
||||||
"repository": "openstyles/stylus",
|
"repository": "openstyles/stylus",
|
||||||
"author": "Stylus Team",
|
"author": "Stylus Team",
|
||||||
"devDependencies": {
|
"dependencies": {
|
||||||
"archiver": "^3.1.1",
|
"codemirror": "^5.56.0",
|
||||||
"codemirror": "^5.51.0",
|
|
||||||
"db-to-cloud": "^0.4.5",
|
"db-to-cloud": "^0.4.5",
|
||||||
"endent": "^1.4.0",
|
|
||||||
"eslint": "^6.8.0",
|
|
||||||
"fs-extra": "^8.1.0",
|
|
||||||
"jsonlint": "^1.6.3",
|
"jsonlint": "^1.6.3",
|
||||||
"less-bundle": "github:openstyles/less-bundle#v0.1.0",
|
"less-bundle": "github:openstyles/less-bundle#v0.1.0",
|
||||||
"lz-string-unsafe": "^1.4.4-fork-1",
|
"lz-string-unsafe": "^1.4.4-fork-1",
|
||||||
"make-fetch-happen": "^7.1.1",
|
|
||||||
"semver-bundle": "^0.1.1",
|
"semver-bundle": "^0.1.1",
|
||||||
"shx": "^0.3.2",
|
|
||||||
"stylelint-bundle": "^8.0.0",
|
"stylelint-bundle": "^8.0.0",
|
||||||
"stylus-lang-bundle": "^0.54.5",
|
"stylus-lang-bundle": "^0.54.5",
|
||||||
|
"usercss-meta": "^0.9.0",
|
||||||
|
"uuid": "^8.1.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"archiver": "^4.0.1",
|
||||||
|
"endent": "^1.4.0",
|
||||||
|
"eslint": "^7.1.0",
|
||||||
|
"fs-extra": "^9.0.0",
|
||||||
|
"make-fetch-happen": "^8.0.7",
|
||||||
|
"shx": "^0.3.2",
|
||||||
"sync-version": "^1.0.1",
|
"sync-version": "^1.0.1",
|
||||||
"tiny-glob": "^0.2.6",
|
"tiny-glob": "^0.2.6",
|
||||||
"usercss-meta": "^0.9.0",
|
"web-ext": "^4.2.0",
|
||||||
"uuid": "^7.0.0-beta.0",
|
|
||||||
"web-ext": "^4.1.0",
|
|
||||||
"webext-tx-fix": "^0.3.3"
|
"webext-tx-fix": "^0.3.3"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
@ -179,7 +179,6 @@
|
||||||
<script src="manage/config-dialog.js"></script>
|
<script src="manage/config-dialog.js"></script>
|
||||||
|
|
||||||
<script src="js/polyfill.js"></script>
|
<script src="js/polyfill.js"></script>
|
||||||
<script src="js/promisify.js"></script>
|
|
||||||
<script src="js/dom.js"></script>
|
<script src="js/dom.js"></script>
|
||||||
<script src="js/messaging.js"></script>
|
<script src="js/messaging.js"></script>
|
||||||
<script src="js/localization.js"></script>
|
<script src="js/localization.js"></script>
|
||||||
|
|
|
@ -341,6 +341,13 @@ a.configure[target="_blank"] .svg-icon.config {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
#confirm button[data-cmd="ok"]:not([data-focused-via-click]):focus {
|
||||||
|
outline: red auto 1px;
|
||||||
|
}
|
||||||
|
/* FF ignores color with 'auto' */
|
||||||
|
.firefox #confirm button[data-cmd="ok"]:not([data-focused-via-click]):focus {
|
||||||
|
outline: red solid 1px;
|
||||||
|
}
|
||||||
.menu-items-wrapper {
|
.menu-items-wrapper {
|
||||||
width: 80%;
|
width: 80%;
|
||||||
max-height: 80%;
|
max-height: 80%;
|
||||||
|
|
|
@ -15,7 +15,7 @@ const ABOUT_BLANK = 'about:blank';
|
||||||
const ENTRY_ID_PREFIX_RAW = 'style-';
|
const ENTRY_ID_PREFIX_RAW = 'style-';
|
||||||
const ENTRY_ID_PREFIX = '#' + ENTRY_ID_PREFIX_RAW;
|
const ENTRY_ID_PREFIX = '#' + ENTRY_ID_PREFIX_RAW;
|
||||||
|
|
||||||
if (CHROME >= 3345 && CHROME < 3533) { // Chrome 66-69 adds a gap, https://crbug.com/821143
|
if (CHROME >= 66 && CHROME <= 69) { // Chrome 66-69 adds a gap, https://crbug.com/821143
|
||||||
document.head.appendChild($create('style', 'html { overflow: overlay }'));
|
document.head.appendChild($create('style', 'html { overflow: overlay }'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* global tabURL handleEvent $ $$ prefs template FIREFOX chromeLocal debounce
|
/* global tabURL handleEvent $ $$ prefs template FIREFOX chromeLocal debounce
|
||||||
$create t API tWordBreak formatDate tryCatch tryJSONparse LZString
|
$create t API tWordBreak formatDate tryCatch tryJSONparse LZString
|
||||||
ignoreChromeError download */
|
promisifyChrome download */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
window.addEventListener('showStyles:done', function _() {
|
window.addEventListener('showStyles:done', function _() {
|
||||||
|
@ -88,6 +88,9 @@ window.addEventListener('showStyles:done', function _() {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
|
promisifyChrome({
|
||||||
|
'storage.local': ['getBytesInUse'], // FF doesn't implement it
|
||||||
|
});
|
||||||
setTimeout(() => document.body.classList.add(BODY_CLASS));
|
setTimeout(() => document.body.classList.add(BODY_CLASS));
|
||||||
|
|
||||||
$('#find-styles-inline-group').classList.add('hidden');
|
$('#find-styles-inline-group').classList.add('hidden');
|
||||||
|
@ -711,7 +714,7 @@ window.addEventListener('showStyles:done', function _() {
|
||||||
return chromeLocal.loadLZStringScript().then(() =>
|
return chromeLocal.loadLZStringScript().then(() =>
|
||||||
tryJSONparse(LZString.decompressFromUTF16(item.payload)));
|
tryJSONparse(LZString.decompressFromUTF16(item.payload)));
|
||||||
} else if (item) {
|
} else if (item) {
|
||||||
chrome.storage.local.remove(key);
|
chromeLocal.remove(key);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -742,16 +745,8 @@ window.addEventListener('showStyles:done', function _() {
|
||||||
|
|
||||||
function cleanupCache() {
|
function cleanupCache() {
|
||||||
chromeLocal.remove(CACHE_CLEANUP_NEEDED);
|
chromeLocal.remove(CACHE_CLEANUP_NEEDED);
|
||||||
if (chrome.storage.local.getBytesInUse) {
|
Promise.resolve(!browser.storage.local.getBytesInUse ? 1e99 : browser.storage.local.getBytesInUse())
|
||||||
chrome.storage.local.getBytesInUse(null, size => {
|
.then(size => size > CACHE_SIZE && chromeLocal.get().then(cleanupCacheInternal));
|
||||||
if (size > CACHE_SIZE) {
|
|
||||||
chrome.storage.local.get(null, cleanupCacheInternal);
|
|
||||||
}
|
|
||||||
ignoreChromeError();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
chrome.storage.local.get(null, cleanupCacheInternal);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function cleanupCacheInternal(storage) {
|
function cleanupCacheInternal(storage) {
|
||||||
|
@ -764,9 +759,8 @@ window.addEventListener('showStyles:done', function _() {
|
||||||
sortedByTime.slice(0, sortedByTime.length / 2);
|
sortedByTime.slice(0, sortedByTime.length / 2);
|
||||||
const toRemove = expired.length ? expired : sortedByTime;
|
const toRemove = expired.length ? expired : sortedByTime;
|
||||||
if (toRemove.length) {
|
if (toRemove.length) {
|
||||||
chrome.storage.local.remove(toRemove.map(item => item.key), ignoreChromeError);
|
chromeLocal.remove(toRemove.map(item => item.key));
|
||||||
}
|
}
|
||||||
ignoreChromeError();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
@ -779,6 +773,7 @@ window.addEventListener('showStyles:done', function _() {
|
||||||
return download(url, {
|
return download(url, {
|
||||||
body: null,
|
body: null,
|
||||||
responseType: 'json',
|
responseType: 'json',
|
||||||
|
timeout: 60e3,
|
||||||
headers: {
|
headers: {
|
||||||
'Referrer-Policy': 'origin-when-cross-origin',
|
'Referrer-Policy': 'origin-when-cross-origin',
|
||||||
[xhrSpoofTelltale]: requestId,
|
[xhrSpoofTelltale]: requestId,
|
||||||
|
|
|
@ -106,7 +106,7 @@ const colorConverter = (() => {
|
||||||
if (!type) return;
|
if (!type) return;
|
||||||
|
|
||||||
const comma = value.includes(',') && !value.includes('/');
|
const comma = value.includes(',') && !value.includes('/');
|
||||||
const num = value.split(comma ? /\s*,\s*/ : /\s+(?!\/)|\s*\/\s*/);
|
const num = value.trim().split(comma ? /\s*,\s*/ : /\s+(?!\/)|\s*\/\s*/);
|
||||||
if (num.length < 3 || num.length > 4) return;
|
if (num.length < 3 || num.length > 4) return;
|
||||||
if (num[3] && !validateAlpha(num[3])) return null;
|
if (num[3] && !validateAlpha(num[3])) return null;
|
||||||
|
|
||||||
|
|
|
@ -182,12 +182,13 @@
|
||||||
|
|
||||||
if (viewFrom > 0 || viewTo < cm.doc.size) {
|
if (viewFrom > 0 || viewTo < cm.doc.size) {
|
||||||
clearTimeout(state.colorizeTimer);
|
clearTimeout(state.colorizeTimer);
|
||||||
state.colorizeTimer = setTimeout(colorizeInvisible, 100, state, viewFrom, viewTo, 0);
|
state.line = 0;
|
||||||
|
state.colorizeTimer = setTimeout(colorizeInvisible, 100, state, viewFrom, viewTo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function colorizeInvisible(state, viewFrom, viewTo, line) {
|
function colorizeInvisible(state, viewFrom, viewTo) {
|
||||||
const {cm} = state;
|
const {cm} = state;
|
||||||
const {curOp} = cm;
|
const {curOp} = cm;
|
||||||
if (!curOp) cm.startOperation();
|
if (!curOp) cm.startOperation();
|
||||||
|
@ -197,22 +198,19 @@
|
||||||
state.stopped = null;
|
state.stopped = null;
|
||||||
|
|
||||||
// before the visible range
|
// before the visible range
|
||||||
if (viewFrom) {
|
cm.eachLine(state.line, viewFrom, lineHandle => colorizeLine(state, lineHandle));
|
||||||
state.line = line;
|
|
||||||
cm.doc.iter(line, viewFrom, lineHandle => colorizeLine(state, lineHandle));
|
|
||||||
}
|
|
||||||
|
|
||||||
// after the visible range
|
// after the visible range
|
||||||
if (!state.stopped && viewTo < cm.doc.size) {
|
if (!state.stopped && viewTo < cm.doc.size) {
|
||||||
state.line = viewTo;
|
state.line = Math.max(viewTo, state.line);
|
||||||
cm.doc.iter(viewTo, cm.doc.size, lineHandle => colorizeLine(state, lineHandle));
|
cm.eachLine(state.line, cm.doc.size, lineHandle => colorizeLine(state, lineHandle));
|
||||||
}
|
}
|
||||||
|
|
||||||
updateMarkers(state);
|
updateMarkers(state);
|
||||||
if (!curOp) cm.endOperation();
|
if (!curOp) cm.endOperation();
|
||||||
|
|
||||||
if (state.stopped) {
|
if (state.stopped) {
|
||||||
state.colorizeTimer = setTimeout(colorizeInvisible, 0, state, viewFrom, viewFrom, state.line);
|
state.colorizeTimer = setTimeout(colorizeInvisible, 0, state, viewFrom, viewTo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -229,30 +229,33 @@ var CSSLint = (() => {
|
||||||
|
|
||||||
// Example 1:
|
// Example 1:
|
||||||
|
|
||||||
/* csslint ignore:start */
|
/* csslint ignore:start */
|
||||||
// the chunk of code where errors won't be reported
|
/*
|
||||||
// the chunk's start is hardwired to the line of the opening comment
|
the chunk of code where errors won't be reported
|
||||||
// the chunk's end is hardwired to the line of the closing comment
|
the chunk's start is hardwired to the line of the opening comment
|
||||||
/* csslint ignore:end */
|
the chunk's end is hardwired to the line of the closing comment
|
||||||
|
*/
|
||||||
|
/* csslint ignore:end */
|
||||||
|
|
||||||
// Example 2:
|
// Example 2:
|
||||||
|
// allow rule violations on the current line:
|
||||||
|
|
||||||
/* csslint allow:rulename1,rulename2,... */
|
// foo: bar; /* csslint allow:rulename1,rulename2,... */
|
||||||
// allows to break the specified rules on the next single line of code
|
/* csslint allow:rulename1,rulename2,... */ // foo: bar;
|
||||||
|
|
||||||
// Example 3:
|
// Example 3:
|
||||||
|
|
||||||
/* csslint rulename1 */
|
/* csslint rulename1 */
|
||||||
/* csslint rulename2:N */
|
/* csslint rulename2:N */
|
||||||
/* csslint rulename3:N, rulename4:N */
|
/* csslint rulename3:N, rulename4:N */
|
||||||
|
|
||||||
// entire code is affected;
|
/* entire code is affected;
|
||||||
// comments futher down the code extend/override previous comments of this kind
|
* comments futher down the code extend/override previous comments of this kind
|
||||||
// values for N:
|
* values for N (without the backquotes):
|
||||||
// "2" or "true" means "error"
|
`2` or `true` means "error"
|
||||||
// "1" or nothing means "warning" - note in this case ":" can also be omitted
|
`1` or omitted means "warning" (when omitting, the colon can be omitted too)
|
||||||
// "0" or "false" means "ignore"
|
`0` or `false` means "ignore"
|
||||||
// (the quotes are added here for convenience, don't put them in the actual comments)
|
*/
|
||||||
|
|
||||||
function applyEmbeddedOverrides(text, ruleset, allow, ignore) {
|
function applyEmbeddedOverrides(text, ruleset, allow, ignore) {
|
||||||
let ignoreStart = null;
|
let ignoreStart = null;
|
||||||
|
@ -282,7 +285,7 @@ var CSSLint = (() => {
|
||||||
allowRuleset[allowRule.trim()] = true;
|
allowRuleset[allowRule.trim()] = true;
|
||||||
num++;
|
num++;
|
||||||
});
|
});
|
||||||
if (num) allow[lineno + 1] = allowRuleset;
|
if (num) allow[lineno] = allowRuleset;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -319,7 +319,7 @@ self.parserlib = (() => {
|
||||||
'drop-initial-before-align': 'caps-height | baseline | use-script | before-edge | text-before-edge | ' +
|
'drop-initial-before-align': 'caps-height | baseline | use-script | before-edge | text-before-edge | ' +
|
||||||
'after-edge | text-after-edge | central | middle | ideographic | alphabetic | ' +
|
'after-edge | text-after-edge | central | middle | ideographic | alphabetic | ' +
|
||||||
'hanging | mathematical',
|
'hanging | mathematical',
|
||||||
'drop-initial-size': 'auto | line | <length> | <percentage>',
|
'drop-initial-size': 'auto | line | <length-percentage>',
|
||||||
'drop-initial-value': '<integer>',
|
'drop-initial-value': '<integer>',
|
||||||
|
|
||||||
// E
|
// E
|
||||||
|
@ -347,19 +347,28 @@ self.parserlib = (() => {
|
||||||
'flood-opacity': '<opacity-value>',
|
'flood-opacity': '<opacity-value>',
|
||||||
'font': '<font-shorthand> | caption | icon | menu | message-box | small-caption | status-bar',
|
'font': '<font-shorthand> | caption | icon | menu | message-box | small-caption | status-bar',
|
||||||
'font-family': '<font-family>',
|
'font-family': '<font-family>',
|
||||||
'font-feature-settings': '<feature-tag-value> | normal',
|
'font-feature-settings': '<feature-tag-value># | normal',
|
||||||
'font-kerning': 'auto | normal | none',
|
'font-kerning': 'auto | normal | none',
|
||||||
|
'font-language-override': 'normal | <string>',
|
||||||
|
'font-optical-sizing': 'auto | none',
|
||||||
|
'font-palette': 'none | normal | light | dark | <ident>',
|
||||||
'font-size': '<font-size>',
|
'font-size': '<font-size>',
|
||||||
'font-size-adjust': '<number> | none',
|
'font-size-adjust': '<number> | none',
|
||||||
'font-stretch': '<font-stretch>',
|
'font-stretch': '<font-stretch>',
|
||||||
'font-style': '<font-style>',
|
'font-style': '<font-style>',
|
||||||
|
'font-synthesis': 'none | [ weight || style ]',
|
||||||
|
'font-synthesis-style': 'auto | none',
|
||||||
|
'font-synthesis-weight': 'auto | none',
|
||||||
|
'font-synthesis-small-caps': 'auto | none',
|
||||||
'font-variant': '<font-variant> | normal | none',
|
'font-variant': '<font-variant> | normal | none',
|
||||||
'font-variant-alternates': '<font-variant-alternates> | normal',
|
'font-variant-alternates': '<font-variant-alternates> | normal',
|
||||||
'font-variant-caps': '<font-variant-caps> | normal',
|
'font-variant-caps': '<font-variant-caps> | normal',
|
||||||
'font-variant-east-asian': '<font-variant-east-asian> | normal',
|
'font-variant-east-asian': '<font-variant-east-asian> | normal',
|
||||||
|
'font-variant-emoji': 'auto | text | emoji | unicode',
|
||||||
'font-variant-ligatures': '<font-variant-ligatures> | normal | none',
|
'font-variant-ligatures': '<font-variant-ligatures> | normal | none',
|
||||||
'font-variant-numeric': '<font-variant-numeric> | normal',
|
'font-variant-numeric': '<font-variant-numeric> | normal',
|
||||||
'font-variant-position': 'normal | sub | super',
|
'font-variant-position': 'normal | sub | super',
|
||||||
|
'font-variation-settings': 'normal | [ <string> <number>]#',
|
||||||
'font-weight': '<font-weight>',
|
'font-weight': '<font-weight>',
|
||||||
'-ms-flex-align': 'start | end | center | stretch | baseline',
|
'-ms-flex-align': 'start | end | center | stretch | baseline',
|
||||||
'-ms-flex-order': '<number>',
|
'-ms-flex-order': '<number>',
|
||||||
|
@ -392,7 +401,7 @@ self.parserlib = (() => {
|
||||||
'grid-gap': '<row-gap> <column-gap>?',
|
'grid-gap': '<row-gap> <column-gap>?',
|
||||||
|
|
||||||
// H
|
// H
|
||||||
'hanging-punctuation': 1,
|
'hanging-punctuation': 'none | [ first || [ force-end | allow-end ] || last ]',
|
||||||
'height': 'auto | <width-height>',
|
'height': 'auto | <width-height>',
|
||||||
'hyphenate-after': '<integer> | auto',
|
'hyphenate-after': '<integer> | auto',
|
||||||
'hyphenate-before': '<integer> | auto',
|
'hyphenate-before': '<integer> | auto',
|
||||||
|
@ -431,7 +440,7 @@ self.parserlib = (() => {
|
||||||
'left': '<width>',
|
'left': '<width>',
|
||||||
'letter-spacing': '<length> | normal',
|
'letter-spacing': '<length> | normal',
|
||||||
'line-height': '<line-height>',
|
'line-height': '<line-height>',
|
||||||
'line-break': 'auto | loose | normal | strict',
|
'line-break': 'auto | loose | normal | strict | anywhere',
|
||||||
'line-stacking': 1,
|
'line-stacking': 1,
|
||||||
'line-stacking-ruby': 'exclude-ruby | include-ruby',
|
'line-stacking-ruby': 'exclude-ruby | include-ruby',
|
||||||
'line-stacking-shift': 'consider-shifts | disregard-shifts',
|
'line-stacking-shift': 'consider-shifts | disregard-shifts',
|
||||||
|
@ -502,9 +511,14 @@ self.parserlib = (() => {
|
||||||
'overflow-block': '<overflow>',
|
'overflow-block': '<overflow>',
|
||||||
'overflow-inline': '<overflow>',
|
'overflow-inline': '<overflow>',
|
||||||
'overflow-style': 1,
|
'overflow-style': 1,
|
||||||
'overflow-wrap': 'normal | break-word',
|
'overflow-wrap': 'normal | break-word | anywhere',
|
||||||
'overflow-x': '<overflow>',
|
'overflow-x': '<overflow>',
|
||||||
'overflow-y': '<overflow>',
|
'overflow-y': '<overflow>',
|
||||||
|
'overscroll-behavior': '<overscroll>{1,2}',
|
||||||
|
'overscroll-behavior-block': '<overscroll>',
|
||||||
|
'overscroll-behavior-inline': '<overscroll>',
|
||||||
|
'overscroll-behavior-x': '<overscroll>',
|
||||||
|
'overscroll-behavior-y': '<overscroll>',
|
||||||
|
|
||||||
// P
|
// P
|
||||||
'padding': '<padding-width>{1,4}',
|
'padding': '<padding-width>{1,4}',
|
||||||
|
@ -564,6 +578,8 @@ self.parserlib = (() => {
|
||||||
|
|
||||||
// S
|
// S
|
||||||
'scale': 'none | <number>{1,3}',
|
'scale': 'none | <number>{1,3}',
|
||||||
|
'scrollbar-color': 'auto | dark | light | <color>{2}',
|
||||||
|
'scrollbar-width': 'auto | thin | none',
|
||||||
'shape-inside': 'auto | outside-shape | [ <basic-shape> || shape-box ] | <image> | display',
|
'shape-inside': 'auto | outside-shape | [ <basic-shape> || shape-box ] | <image> | display',
|
||||||
'shape-rendering': 'auto | optimizeSpeed | crispEdges | geometricPrecision',
|
'shape-rendering': 'auto | optimizeSpeed | crispEdges | geometricPrecision',
|
||||||
'size': 1,
|
'size': 1,
|
||||||
|
@ -588,14 +604,14 @@ self.parserlib = (() => {
|
||||||
|
|
||||||
// T
|
// T
|
||||||
'table-layout': 'auto | fixed',
|
'table-layout': 'auto | fixed',
|
||||||
'tab-size': '<integer> | <length>',
|
'tab-size': '<number> | <length>',
|
||||||
'target': 1,
|
'target': 1,
|
||||||
'target-name': 1,
|
'target-name': 1,
|
||||||
'target-new': 1,
|
'target-new': 1,
|
||||||
'target-position': 1,
|
'target-position': 1,
|
||||||
'text-align': 'start | end | left | right | center | justify | match-parent | justify-all',
|
'text-align': '<text-align> | justify-all',
|
||||||
'text-align-all': 'start | end | left | right | center | justify | match-parent',
|
'text-align-all': '<text-align>',
|
||||||
'text-align-last': 'auto | start | end | left | right | center | justify',
|
'text-align-last': '<text-align> | auto',
|
||||||
'text-anchor': 'start | middle | end',
|
'text-anchor': 'start | middle | end',
|
||||||
'text-decoration': '<text-decoration-line> || <text-decoration-style> || <color>',
|
'text-decoration': '<text-decoration-line> || <text-decoration-style> || <color>',
|
||||||
'text-decoration-color': '<color>',
|
'text-decoration-color': '<color>',
|
||||||
|
@ -607,13 +623,13 @@ self.parserlib = (() => {
|
||||||
'text-emphasis-style': '<text-emphasis-style>',
|
'text-emphasis-style': '<text-emphasis-style>',
|
||||||
'text-emphasis-position': '[ over | under ] && [ right | left ]?',
|
'text-emphasis-position': '[ over | under ] && [ right | left ]?',
|
||||||
'text-height': 1,
|
'text-height': 1,
|
||||||
'text-indent': '<length> | <percentage>',
|
'text-indent': '<length-percentage> && hanging? && each-line?',
|
||||||
'text-justify': 'auto | none | inter-word | inter-ideograph | inter-cluster | distribute | kashida',
|
'text-justify': 'auto | none | inter-word | inter-character',
|
||||||
'text-outline': 1,
|
'text-outline': 1,
|
||||||
'text-overflow': 'clip | ellipsis',
|
'text-overflow': 'clip | ellipsis',
|
||||||
'text-rendering': 'auto | optimizeSpeed | optimizeLegibility | geometricPrecision',
|
'text-rendering': 'auto | optimizeSpeed | optimizeLegibility | geometricPrecision',
|
||||||
'text-shadow': 'none | [ <color>? && <length>{2,3} ]#',
|
'text-shadow': 'none | [ <color>? && <length>{2,3} ]#',
|
||||||
'text-transform': 'capitalize | uppercase | lowercase | none',
|
'text-transform': 'none | [ capitalize | uppercase | lowercase ] || full-width || full-size-kana',
|
||||||
'text-underline-position': 'auto | [ under || [ left | right ] ]',
|
'text-underline-position': 'auto | [ under || [ left | right ] ]',
|
||||||
'text-wrap': 'normal | none | avoid',
|
'text-wrap': 'normal | none | avoid',
|
||||||
'top': '<width>',
|
'top': '<width>',
|
||||||
|
@ -650,15 +666,14 @@ self.parserlib = (() => {
|
||||||
'volume': 1,
|
'volume': 1,
|
||||||
|
|
||||||
// W
|
// W
|
||||||
'white-space': 'normal | pre | nowrap | pre-wrap | pre-line | -pre-wrap |' +
|
'white-space': 'normal | pre | nowrap | pre-wrap | break-spaces | pre-line',
|
||||||
' -o-pre-wrap | -moz-pre-wrap | -hp-pre-wrap',
|
|
||||||
'white-space-collapse': 1,
|
'white-space-collapse': 1,
|
||||||
'widows': '<integer>',
|
'widows': '<integer>',
|
||||||
'width': 'auto | <width-height>',
|
'width': 'auto | <width-height>',
|
||||||
'will-change': '<will-change>',
|
'will-change': '<will-change>',
|
||||||
'word-break': 'normal | keep-all | break-all',
|
'word-break': 'normal | keep-all | break-all | break-word',
|
||||||
'word-spacing': '<length> | normal',
|
'word-spacing': '<length> | normal',
|
||||||
'word-wrap': 'normal | break-word',
|
'word-wrap': 'normal | break-word | anywhere',
|
||||||
'writing-mode': 'horizontal-tb | vertical-rl | vertical-lr | lr-tb | rl-tb | tb-rl | ' +
|
'writing-mode': 'horizontal-tb | vertical-rl | vertical-lr | lr-tb | rl-tb | tb-rl | ' +
|
||||||
'bt-rl | tb-lr | bt-lr | lr-bt | rl-bt | lr | rl | tb',
|
'bt-rl | tb-lr | bt-lr | lr-bt | rl-bt | lr | rl | tb',
|
||||||
|
|
||||||
|
@ -711,7 +726,7 @@ self.parserlib = (() => {
|
||||||
|
|
||||||
'<clip-source>': '<uri>',
|
'<clip-source>': '<uri>',
|
||||||
|
|
||||||
'<column-gap>': 'normal | <length> | <percentage>',
|
'<column-gap>': 'normal | <length-percentage>',
|
||||||
|
|
||||||
'<content-distribution>': 'space-between | space-around | space-evenly | stretch',
|
'<content-distribution>': 'space-between | space-around | space-evenly | stretch',
|
||||||
'<content-position>': 'center | start | end | flex-start | flex-end',
|
'<content-position>': 'center | start | end | flex-start | flex-end',
|
||||||
|
@ -747,17 +762,17 @@ self.parserlib = (() => {
|
||||||
'<flex-shrink>': '<number>',
|
'<flex-shrink>': '<number>',
|
||||||
'<flex-wrap>': 'nowrap | wrap | wrap-reverse',
|
'<flex-wrap>': 'nowrap | wrap | wrap-reverse',
|
||||||
|
|
||||||
'<font-size>': '<absolute-size> | <relative-size> | <length> | <percentage>',
|
'<font-size>': '<absolute-size> | <relative-size> | <length-percentage>',
|
||||||
'<font-stretch>': 'normal | ultra-condensed | extra-condensed | condensed | semi-condensed | ' +
|
'<font-stretch>': 'normal | <percentage> | ultra-condensed | extra-condensed | condensed | semi-condensed | ' +
|
||||||
'semi-expanded | expanded | extra-expanded | ultra-expanded',
|
'semi-expanded | expanded | extra-expanded | ultra-expanded',
|
||||||
'<font-style>': 'normal | italic | oblique',
|
'<font-style>': 'normal | italic | oblique <angle>?',
|
||||||
'<font-variant-caps>': 'small-caps | all-small-caps | petite-caps | all-petite-caps | ' +
|
'<font-variant-caps>': 'small-caps | all-small-caps | petite-caps | all-petite-caps | ' +
|
||||||
'unicase | titling-caps',
|
'unicase | titling-caps',
|
||||||
'<font-variant-css21>': 'normal | small-caps',
|
'<font-variant-css21>': 'normal | small-caps',
|
||||||
'<font-weight>': 'normal | bold | bolder | lighter | ' +
|
'<font-weight>': 'normal | bold | bolder | lighter | <number>',
|
||||||
'100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900',
|
|
||||||
|
|
||||||
'<generic-family>': 'serif | sans-serif | cursive | fantasy | monospace',
|
'<generic-family>': 'serif | sans-serif | cursive | fantasy | monospace | system-ui | emoji | ' +
|
||||||
|
'math | fangsong | ui-serif | ui-sans-serif | ui-monospace | ui-rounded',
|
||||||
|
|
||||||
'<geometry-box>': '<shape-box> | fill-box | stroke-box | view-box',
|
'<geometry-box>': '<shape-box> | fill-box | stroke-box | view-box',
|
||||||
|
|
||||||
|
@ -798,7 +813,7 @@ self.parserlib = (() => {
|
||||||
|
|
||||||
'<line>': part => part.type === 'integer',
|
'<line>': part => part.type === 'integer',
|
||||||
|
|
||||||
'<line-height>': '<number> | <length> | <percentage> | normal',
|
'<line-height>': '<number> | <length-percentage> | normal',
|
||||||
|
|
||||||
'<line-names>': function (part) {
|
'<line-names>': function (part) {
|
||||||
// eslint-disable-next-line no-use-before-define
|
// eslint-disable-next-line no-use-before-define
|
||||||
|
@ -868,6 +883,8 @@ self.parserlib = (() => {
|
||||||
|
|
||||||
'<string>': part => part.type === 'string',
|
'<string>': part => part.type === 'string',
|
||||||
|
|
||||||
|
'<text-align>': 'start | end | left | right | center | justify | match-parent',
|
||||||
|
|
||||||
'<text-decoration-style>': 'solid | double | dotted | dashed | wavy',
|
'<text-decoration-style>': 'solid | double | dotted | dashed | wavy',
|
||||||
|
|
||||||
'<time>': part => part.type === 'time',
|
'<time>': part => part.type === 'time',
|
||||||
|
@ -901,7 +918,7 @@ self.parserlib = (() => {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
'<width>': '<length> | <percentage> | auto',
|
'<width>': '<length-percentage> | auto',
|
||||||
},
|
},
|
||||||
|
|
||||||
complex: {
|
complex: {
|
||||||
|
@ -929,7 +946,7 @@ self.parserlib = (() => {
|
||||||
'[ left | center | right | <length-percentage> ] [ top | center | bottom | <length-percentage> ] | ' +
|
'[ left | center | right | <length-percentage> ] [ top | center | bottom | <length-percentage> ] | ' +
|
||||||
'[ left | center | right | top | bottom | <length-percentage> ]',
|
'[ left | center | right | top | bottom | <length-percentage> ]',
|
||||||
|
|
||||||
'<bg-size>': '[ <length> | <percentage> | auto ]{1,2} | cover | contain',
|
'<bg-size>': '[ <length-percentage> | auto ]{1,2} | cover | contain',
|
||||||
|
|
||||||
'<border-image-outset>': '[ <length> | <number> ]{1,4}',
|
'<border-image-outset>': '[ <length> | <number> ]{1,4}',
|
||||||
'<border-image-repeat>': '[ stretch | repeat | round | space ]{1,2}',
|
'<border-image-repeat>': '[ stretch | repeat | round | space ]{1,2}',
|
||||||
|
@ -943,7 +960,7 @@ self.parserlib = (() => {
|
||||||
Matcher.cast('<nonnegative-number-or-percentage>'),
|
Matcher.cast('<nonnegative-number-or-percentage>'),
|
||||||
Matcher.cast('<nonnegative-number-or-percentage>'),
|
Matcher.cast('<nonnegative-number-or-percentage>'),
|
||||||
'fill'),
|
'fill'),
|
||||||
'<border-image-width>': '[ <length> | <percentage> | <number> | auto ]{1,4}',
|
'<border-image-width>': '[ <length-percentage> | <number> | auto ]{1,4}',
|
||||||
'<border-radius>': '<nonnegative-length-or-percentage>{1,4} [ / <nonnegative-length-or-percentage>{1,4} ]?',
|
'<border-radius>': '<nonnegative-length-or-percentage>{1,4} [ / <nonnegative-length-or-percentage>{1,4} ]?',
|
||||||
'<border-shorthand>': '<border-width> || <border-style> || <color>',
|
'<border-shorthand>': '<border-width> || <border-style> || <color>',
|
||||||
|
|
||||||
|
@ -1050,6 +1067,8 @@ self.parserlib = (() => {
|
||||||
'<hsl-color>': '[ <number> | <angle> ] <percentage>{2} [ / <nonnegative-number-or-percentage> ]? | ' +
|
'<hsl-color>': '[ <number> | <angle> ] <percentage>{2} [ / <nonnegative-number-or-percentage> ]? | ' +
|
||||||
'[ <number> | <angle> ] , <percentage>#{2} [ , <nonnegative-number-or-percentage> ]?',
|
'[ <number> | <angle> ] , <percentage>#{2} [ , <nonnegative-number-or-percentage> ]?',
|
||||||
|
|
||||||
|
'<overscroll>': 'contain | none | auto',
|
||||||
|
|
||||||
'<shadow>': 'inset? && [ <length>{2,4} && <color>? ]',
|
'<shadow>': 'inset? && [ <length>{2,4} && <color>? ]',
|
||||||
|
|
||||||
'<single-timing-function>': 'linear | <cubic-bezier-timing-function> | <step-timing-function> | frames()',
|
'<single-timing-function>': 'linear | <cubic-bezier-timing-function> | <step-timing-function> | frames()',
|
||||||
|
@ -1076,7 +1095,7 @@ self.parserlib = (() => {
|
||||||
|
|
||||||
'<will-change>': 'auto | <animateable-feature>#',
|
'<will-change>': 'auto | <animateable-feature>#',
|
||||||
|
|
||||||
'<x-one-radius>': '[ <length> | <percentage> ]{1,2}',
|
'<x-one-radius>': '<length-percentage>{1,2}',
|
||||||
},
|
},
|
||||||
|
|
||||||
functions: {
|
functions: {
|
||||||
|
@ -1345,165 +1364,154 @@ self.parserlib = (() => {
|
||||||
* The following token names are defined in CSS3 Grammar:
|
* The following token names are defined in CSS3 Grammar:
|
||||||
* https://www.w3.org/TR/css3-syntax/#lexical
|
* https://www.w3.org/TR/css3-syntax/#lexical
|
||||||
*/
|
*/
|
||||||
const Tokens = [
|
const Tokens = Object.assign([], {
|
||||||
|
EOF: {}, // must be the first token
|
||||||
|
}, {
|
||||||
// HTML-style comments
|
// HTML-style comments
|
||||||
{name: 'CDO'},
|
CDO: {},
|
||||||
{name: 'CDC'},
|
CDC: {},
|
||||||
|
|
||||||
// ignorables
|
// ignorables
|
||||||
{name: 'S', whitespace: true},
|
S: {whitespace: true},
|
||||||
{name: 'COMMENT', whitespace: true, comment: true, hide: true},
|
COMMENT: {whitespace: true, comment: true, hide: true},
|
||||||
|
|
||||||
// attribute equality
|
// attribute equality
|
||||||
{name: 'INCLUDES', text: '~='},
|
INCLUDES: {text: '~='},
|
||||||
{name: 'DASHMATCH', text: '|='},
|
DASHMATCH: {text: '|='},
|
||||||
{name: 'PREFIXMATCH', text: '^='},
|
PREFIXMATCH: {text: '^='},
|
||||||
{name: 'SUFFIXMATCH', text: '$='},
|
SUFFIXMATCH: {text: '$='},
|
||||||
{name: 'SUBSTRINGMATCH', text: '*='},
|
SUBSTRINGMATCH: {text: '*='},
|
||||||
|
|
||||||
// identifier types
|
// identifier types
|
||||||
{name: 'STRING'},
|
STRING: {},
|
||||||
{name: 'IDENT'},
|
IDENT: {},
|
||||||
{name: 'HASH'},
|
HASH: {},
|
||||||
|
|
||||||
// at-keywords
|
// at-keywords
|
||||||
{name: 'IMPORT_SYM', text: '@import'},
|
IMPORT_SYM: {text: '@import'},
|
||||||
{name: 'PAGE_SYM', text: '@page'},
|
PAGE_SYM: {text: '@page'},
|
||||||
{name: 'MEDIA_SYM', text: '@media'},
|
MEDIA_SYM: {text: '@media'},
|
||||||
{name: 'FONT_FACE_SYM', text: '@font-face'},
|
FONT_FACE_SYM: {text: '@font-face'},
|
||||||
{name: 'CHARSET_SYM', text: '@charset'},
|
CHARSET_SYM: {text: '@charset'},
|
||||||
{name: 'NAMESPACE_SYM', text: '@namespace'},
|
NAMESPACE_SYM: {text: '@namespace'},
|
||||||
{name: 'SUPPORTS_SYM', text: '@supports'},
|
SUPPORTS_SYM: {text: '@supports'},
|
||||||
{name: 'VIEWPORT_SYM', text: ['@viewport', '@-ms-viewport', '@-o-viewport']},
|
VIEWPORT_SYM: {text: ['@viewport', '@-ms-viewport', '@-o-viewport']},
|
||||||
{name: 'DOCUMENT_SYM', text: ['@document', '@-moz-document']},
|
DOCUMENT_SYM: {text: ['@document', '@-moz-document']},
|
||||||
{name: 'UNKNOWN_SYM'}, //{ name: "ATKEYWORD"},
|
UNKNOWN_SYM: {}, //{ name: "ATKEYWORD"},
|
||||||
|
|
||||||
// CSS3 animations
|
// CSS3 animations
|
||||||
{name: 'KEYFRAMES_SYM', text: ['@keyframes', '@-webkit-keyframes', '@-moz-keyframes', '@-o-keyframes']},
|
KEYFRAMES_SYM: {text: ['@keyframes', '@-webkit-keyframes', '@-moz-keyframes', '@-o-keyframes']},
|
||||||
|
|
||||||
// important symbol
|
// important symbol
|
||||||
{name: 'IMPORTANT_SYM'},
|
IMPORTANT_SYM: {},
|
||||||
|
|
||||||
// measurements
|
// measurements
|
||||||
{name: 'LENGTH'},
|
LENGTH: {},
|
||||||
{name: 'ANGLE'},
|
ANGLE: {},
|
||||||
{name: 'TIME'},
|
TIME: {},
|
||||||
{name: 'FREQ'},
|
FREQ: {},
|
||||||
{name: 'DIMENSION'},
|
DIMENSION: {},
|
||||||
{name: 'PERCENTAGE'},
|
PERCENTAGE: {},
|
||||||
{name: 'NUMBER'},
|
NUMBER: {},
|
||||||
|
|
||||||
// functions
|
// functions
|
||||||
{name: 'URI'},
|
URI: {},
|
||||||
{name: 'FUNCTION'},
|
FUNCTION: {},
|
||||||
|
|
||||||
// Unicode ranges
|
// Unicode ranges
|
||||||
{name: 'UNICODE_RANGE'},
|
UNICODE_RANGE: {},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following token names are defined in CSS3 Selectors: https://www.w3.org/TR/css3-selectors/#selector-syntax
|
* The following token names are defined in CSS3 Selectors: https://www.w3.org/TR/css3-selectors/#selector-syntax
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// invalid string
|
// invalid string
|
||||||
{name: 'INVALID'},
|
INVALID: {},
|
||||||
|
|
||||||
// combinators
|
// combinators
|
||||||
{name: 'PLUS', text: '+'},
|
PLUS: {text: '+'},
|
||||||
{name: 'GREATER', text: '>'},
|
GREATER: {text: '>'},
|
||||||
{name: 'COMMA', text: ','},
|
COMMA: {text: ','},
|
||||||
{name: 'TILDE', text: '~'},
|
TILDE: {text: '~'},
|
||||||
|
COLUMN: {text: '||'},
|
||||||
|
|
||||||
// modifier
|
// modifier
|
||||||
{name: 'NOT'},
|
NOT: {},
|
||||||
{name: 'ANY', text: ['any', '-webkit-any', '-moz-any']},
|
ANY: {text: ['any', '-webkit-any', '-moz-any']},
|
||||||
{name: 'MATCHES'},
|
IS: {},
|
||||||
{name: 'IS'},
|
WHERE: {},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Defined in CSS3 Paged Media
|
* Defined in CSS3 Paged Media
|
||||||
*/
|
*/
|
||||||
{name: 'TOPLEFTCORNER_SYM', text: '@top-left-corner'},
|
TOPLEFTCORNER_SYM: {text: '@top-left-corner'},
|
||||||
{name: 'TOPLEFT_SYM', text: '@top-left'},
|
TOPLEFT_SYM: {text: '@top-left'},
|
||||||
{name: 'TOPCENTER_SYM', text: '@top-center'},
|
TOPCENTER_SYM: {text: '@top-center'},
|
||||||
{name: 'TOPRIGHT_SYM', text: '@top-right'},
|
TOPRIGHT_SYM: {text: '@top-right'},
|
||||||
{name: 'TOPRIGHTCORNER_SYM', text: '@top-right-corner'},
|
TOPRIGHTCORNER_SYM: {text: '@top-right-corner'},
|
||||||
{name: 'BOTTOMLEFTCORNER_SYM', text: '@bottom-left-corner'},
|
BOTTOMLEFTCORNER_SYM: {text: '@bottom-left-corner'},
|
||||||
{name: 'BOTTOMLEFT_SYM', text: '@bottom-left'},
|
BOTTOMLEFT_SYM: {text: '@bottom-left'},
|
||||||
{name: 'BOTTOMCENTER_SYM', text: '@bottom-center'},
|
BOTTOMCENTER_SYM: {text: '@bottom-center'},
|
||||||
{name: 'BOTTOMRIGHT_SYM', text: '@bottom-right'},
|
BOTTOMRIGHT_SYM: {text: '@bottom-right'},
|
||||||
{name: 'BOTTOMRIGHTCORNER_SYM', text: '@bottom-right-corner'},
|
BOTTOMRIGHTCORNER_SYM: {text: '@bottom-right-corner'},
|
||||||
{name: 'LEFTTOP_SYM', text: '@left-top'},
|
LEFTTOP_SYM: {text: '@left-top'},
|
||||||
{name: 'LEFTMIDDLE_SYM', text: '@left-middle'},
|
LEFTMIDDLE_SYM: {text: '@left-middle'},
|
||||||
{name: 'LEFTBOTTOM_SYM', text: '@left-bottom'},
|
LEFTBOTTOM_SYM: {text: '@left-bottom'},
|
||||||
{name: 'RIGHTTOP_SYM', text: '@right-top'},
|
RIGHTTOP_SYM: {text: '@right-top'},
|
||||||
{name: 'RIGHTMIDDLE_SYM', text: '@right-middle'},
|
RIGHTMIDDLE_SYM: {text: '@right-middle'},
|
||||||
{name: 'RIGHTBOTTOM_SYM', text: '@right-bottom'},
|
RIGHTBOTTOM_SYM: {text: '@right-bottom'},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following token names are defined in CSS3 Media Queries: https://www.w3.org/TR/css3-mediaqueries/#syntax
|
* The following token names are defined in CSS3 Media Queries: https://www.w3.org/TR/css3-mediaqueries/#syntax
|
||||||
*/
|
*/
|
||||||
{name: 'RESOLUTION', state: 'media'},
|
RESOLUTION: {state: 'media'},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following token names are not defined in any CSS specification but are used by the lexer.
|
* The following token names are not defined in any CSS specification but are used by the lexer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// not a real token, but useful for stupid IE filters
|
// not a real token, but useful for stupid IE filters
|
||||||
{name: 'IE_FUNCTION'},
|
IE_FUNCTION: {},
|
||||||
|
|
||||||
// part of CSS3 grammar but not the Flex code
|
// part of CSS3 grammar but not the Flex code
|
||||||
{name: 'CHAR'},
|
CHAR: {},
|
||||||
|
|
||||||
// TODO: Needed?
|
|
||||||
// Not defined as tokens, but might as well be
|
// Not defined as tokens, but might as well be
|
||||||
{name: 'PIPE', text: '|'},
|
PIPE: {text: '|'},
|
||||||
{name: 'SLASH', text: '/'},
|
SLASH: {text: '/'},
|
||||||
{name: 'MINUS', text: '-'},
|
MINUS: {text: '-'},
|
||||||
{name: 'STAR', text: '*'},
|
STAR: {text: '*'},
|
||||||
|
|
||||||
{name: 'LBRACE', text: '{', endChar: '}'},
|
LBRACE: {text: '{', endChar: '}'},
|
||||||
{name: 'RBRACE', text: '}'},
|
RBRACE: {text: '}'},
|
||||||
{name: 'LBRACKET', text: '[', endChar: ']'},
|
LBRACKET: {text: '[', endChar: ']'},
|
||||||
{name: 'RBRACKET', text: ']'},
|
RBRACKET: {text: ']'},
|
||||||
{name: 'EQUALS', text: '='},
|
EQUALS: {text: '='},
|
||||||
{name: 'COLON', text: ':'},
|
COLON: {text: ':'},
|
||||||
{name: 'SEMICOLON', text: ';'},
|
SEMICOLON: {text: ';'},
|
||||||
{name: 'LPAREN', text: '(', endChar: ')'},
|
LPAREN: {text: '(', endChar: ')'},
|
||||||
{name: 'RPAREN', text: ')'},
|
RPAREN: {text: ')'},
|
||||||
{name: 'DOT', text: '.'},
|
DOT: {text: '.'},
|
||||||
|
|
||||||
{name: 'USO_VAR', comment: true},
|
USO_VAR: {comment: true},
|
||||||
{name: 'CUSTOM_PROP'},
|
CUSTOM_PROP: {},
|
||||||
];
|
});
|
||||||
|
// make Tokens an array of tokens, store the index in original prop, add 'name' to each token
|
||||||
{
|
const typeMap = new Map();
|
||||||
Tokens.UNKNOWN = -1;
|
for (const [k, val] of Object.entries(Tokens)) {
|
||||||
Tokens.unshift({name: 'EOF'});
|
const index = Tokens[k] = Tokens.length;
|
||||||
|
val.name = k;
|
||||||
const nameMap = [];
|
Tokens.push(val);
|
||||||
const typeMap = new Map();
|
const {text} = val;
|
||||||
for (let i = 0, len = Tokens.length; i < len; i++) {
|
if (text) {
|
||||||
nameMap.push(Tokens[i].name);
|
for (const item of Array.isArray(text) ? text : [text]) {
|
||||||
Tokens[Tokens[i].name] = i;
|
typeMap.set(item, index);
|
||||||
if (Tokens[i].text) {
|
|
||||||
if (Tokens[i].text instanceof Array) {
|
|
||||||
for (let j = 0; j < Tokens[i].text.length; j++) {
|
|
||||||
typeMap.set(Tokens[i].text[j], i);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
typeMap.set(Tokens[i].text, i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Tokens.name = function (tt) {
|
|
||||||
return nameMap[tt];
|
|
||||||
};
|
|
||||||
|
|
||||||
Tokens.type = function (c) {
|
|
||||||
return typeMap.get(c) || -1;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
Tokens.UNKNOWN = -1;
|
||||||
|
Tokens.name = index => (Tokens[index] || {}).name;
|
||||||
|
Tokens.type = text => typeMap.get(text) || -1;
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
//region lowerCase helper
|
//region lowerCase helper
|
||||||
|
@ -2204,6 +2212,7 @@ self.parserlib = (() => {
|
||||||
value === '>' ? 'child' :
|
value === '>' ? 'child' :
|
||||||
value === '+' ? 'adjacent-sibling' :
|
value === '+' ? 'adjacent-sibling' :
|
||||||
value === '~' ? 'sibling' :
|
value === '~' ? 'sibling' :
|
||||||
|
value === '||' ? 'column' :
|
||||||
!value.trim() ? 'descendant' :
|
!value.trim() ? 'descendant' :
|
||||||
'unknown';
|
'unknown';
|
||||||
}
|
}
|
||||||
|
@ -2603,9 +2612,11 @@ self.parserlib = (() => {
|
||||||
if (expression._i < expression._parts.length - 1) {
|
if (expression._i < expression._parts.length - 1) {
|
||||||
expression.mark();
|
expression.mark();
|
||||||
expression._i++;
|
expression._i++;
|
||||||
result = ValidationTypes.isType(expression, type);
|
if (ValidationTypes.isType(expression, type)) {
|
||||||
expression.restore();
|
expression.drop();
|
||||||
expression._i += result ? 1 : 0;
|
} else {
|
||||||
|
expression.restore();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result = true;
|
result = true;
|
||||||
|
|
||||||
|
@ -2940,6 +2951,7 @@ self.parserlib = (() => {
|
||||||
* - PREFIXMATCH
|
* - PREFIXMATCH
|
||||||
* - SUFFIXMATCH
|
* - SUFFIXMATCH
|
||||||
* - SUBSTRINGMATCH
|
* - SUBSTRINGMATCH
|
||||||
|
* - COLUMN
|
||||||
* - CHAR
|
* - CHAR
|
||||||
*/
|
*/
|
||||||
case '|':
|
case '|':
|
||||||
|
@ -2947,10 +2959,13 @@ self.parserlib = (() => {
|
||||||
case '^':
|
case '^':
|
||||||
case '$':
|
case '$':
|
||||||
case '*':
|
case '*':
|
||||||
return reader.peek() === '=' ?
|
return (
|
||||||
this.comparisonToken(c, pos) :
|
reader.peek() === '=' ?
|
||||||
this.charToken(c, pos);
|
this.comparisonToken(c, pos) :
|
||||||
|
c === '|' && reader.readMatch('|') ?
|
||||||
|
this.createToken(Tokens.COLUMN, '||', pos) :
|
||||||
|
this.charToken(c, pos)
|
||||||
|
);
|
||||||
/*
|
/*
|
||||||
* Potential tokens:
|
* Potential tokens:
|
||||||
* - STRING
|
* - STRING
|
||||||
|
@ -3040,8 +3055,8 @@ self.parserlib = (() => {
|
||||||
* Potential tokens:
|
* Potential tokens:
|
||||||
* - ANY
|
* - ANY
|
||||||
* - IS
|
* - IS
|
||||||
* - MATCHES
|
|
||||||
* - NOT
|
* - NOT
|
||||||
|
* - WHERE
|
||||||
* - CHAR
|
* - CHAR
|
||||||
*/
|
*/
|
||||||
case ':':
|
case ':':
|
||||||
|
@ -3255,18 +3270,18 @@ self.parserlib = (() => {
|
||||||
// NOT
|
// NOT
|
||||||
// IS
|
// IS
|
||||||
// ANY
|
// ANY
|
||||||
// MATCHES
|
|
||||||
// CHAR
|
// CHAR
|
||||||
notOrIsToken(first, pos) {
|
notOrIsToken(first, pos) {
|
||||||
// first is always ':'
|
// first is always ':'
|
||||||
const reader = this._reader;
|
const reader = this._reader;
|
||||||
const func = reader.readMatch(/(not|is|(-(moz|webkit)-)?(any|matches))\(/iy);
|
const func = reader.readMatch(/(not|is|where|(-(moz|webkit)-)?any)\(/iy);
|
||||||
if (func) {
|
if (func) {
|
||||||
const lcase = func[0].toLowerCase();
|
const lcase = func[0].toLowerCase();
|
||||||
const type =
|
const type =
|
||||||
lcase === 'n' ? Tokens.NOT :
|
lcase === 'n' ? Tokens.NOT :
|
||||||
lcase === 'i' ? Tokens.IS :
|
lcase === 'i' ? Tokens.IS :
|
||||||
lcase === 'm' ? Tokens.MATCHES : Tokens.ANY;
|
lcase === 'w' ? Tokens.WHERE :
|
||||||
|
Tokens.ANY;
|
||||||
return this.createToken(type, first + func, pos);
|
return this.createToken(type, first + func, pos);
|
||||||
}
|
}
|
||||||
return this.charToken(first, pos);
|
return this.charToken(first, pos);
|
||||||
|
@ -4017,7 +4032,7 @@ self.parserlib = (() => {
|
||||||
const stream = this._tokenStream;
|
const stream = this._tokenStream;
|
||||||
if (stream.match(Tokens.LPAREN)) {
|
if (stream.match(Tokens.LPAREN)) {
|
||||||
this._ws();
|
this._ws();
|
||||||
if (stream.match(Tokens.IDENT)) {
|
if (stream.match([Tokens.IDENT, Tokens.CUSTOM_PROP])) {
|
||||||
// look ahead for not keyword,
|
// look ahead for not keyword,
|
||||||
// if not given, continue with declaration condition.
|
// if not given, continue with declaration condition.
|
||||||
const ident = lower(stream._token.value);
|
const ident = lower(stream._token.value);
|
||||||
|
@ -4366,7 +4381,7 @@ self.parserlib = (() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
_combinator() {
|
_combinator() {
|
||||||
if (this._tokenStream.match([Tokens.PLUS, Tokens.GREATER, Tokens.TILDE])) {
|
if (this._tokenStream.match([Tokens.PLUS, Tokens.GREATER, Tokens.TILDE, Tokens.COLUMN])) {
|
||||||
const value = new Combinator(this._tokenStream._token);
|
const value = new Combinator(this._tokenStream._token);
|
||||||
this._ws();
|
this._ws();
|
||||||
return value;
|
return value;
|
||||||
|
@ -4630,7 +4645,8 @@ self.parserlib = (() => {
|
||||||
this._ws();
|
this._ws();
|
||||||
|
|
||||||
if (stream.match([Tokens.IDENT])) {
|
if (stream.match([Tokens.IDENT])) {
|
||||||
if (lower(stream._token.value) === 'i') {
|
const caseMod = lower(stream._token.value);
|
||||||
|
if (caseMod === 'i' || caseMod === 's') {
|
||||||
value += stream._token.value +
|
value += stream._token.value +
|
||||||
this._ws();
|
this._ws();
|
||||||
} else {
|
} else {
|
||||||
|
@ -4710,7 +4726,7 @@ self.parserlib = (() => {
|
||||||
|
|
||||||
_is() {
|
_is() {
|
||||||
const stream = this._tokenStream;
|
const stream = this._tokenStream;
|
||||||
if (!stream.match([Tokens.IS, Tokens.ANY, Tokens.MATCHES])) return null;
|
if (!stream.match([Tokens.IS, Tokens.ANY, Tokens.WHERE])) return null;
|
||||||
|
|
||||||
let arg;
|
let arg;
|
||||||
const start = stream._token;
|
const start = stream._token;
|
||||||
|
@ -5421,6 +5437,7 @@ self.parserlib = (() => {
|
||||||
]),
|
]),
|
||||||
|
|
||||||
supports: new Map([
|
supports: new Map([
|
||||||
|
[Tokens.KEYFRAMES_SYM, Parser.prototype._keyframes],
|
||||||
[Tokens.MEDIA_SYM, Parser.prototype._media],
|
[Tokens.MEDIA_SYM, Parser.prototype._media],
|
||||||
[Tokens.SUPPORTS_SYM, Parser.prototype._supports],
|
[Tokens.SUPPORTS_SYM, Parser.prototype._supports],
|
||||||
[Tokens.DOCUMENT_SYM, Parser.prototype._documentMisplaced],
|
[Tokens.DOCUMENT_SYM, Parser.prototype._documentMisplaced],
|
||||||
|
@ -5428,6 +5445,7 @@ self.parserlib = (() => {
|
||||||
]),
|
]),
|
||||||
|
|
||||||
media: new Map([
|
media: new Map([
|
||||||
|
[Tokens.KEYFRAMES_SYM, Parser.prototype._keyframes],
|
||||||
[Tokens.MEDIA_SYM, Parser.prototype._media],
|
[Tokens.MEDIA_SYM, Parser.prototype._media],
|
||||||
[Tokens.DOCUMENT_SYM, Parser.prototype._documentMisplaced],
|
[Tokens.DOCUMENT_SYM, Parser.prototype._documentMisplaced],
|
||||||
[Tokens.SUPPORTS_SYM, Parser.prototype._supports],
|
[Tokens.SUPPORTS_SYM, Parser.prototype._supports],
|
||||||
|
@ -5443,7 +5461,7 @@ self.parserlib = (() => {
|
||||||
[Tokens.COLON, Parser.prototype._pseudo],
|
[Tokens.COLON, Parser.prototype._pseudo],
|
||||||
[Tokens.IS, Parser.prototype._is],
|
[Tokens.IS, Parser.prototype._is],
|
||||||
[Tokens.ANY, Parser.prototype._is],
|
[Tokens.ANY, Parser.prototype._is],
|
||||||
[Tokens.MATCHES, Parser.prototype._is],
|
[Tokens.WHERE, Parser.prototype._is],
|
||||||
[Tokens.NOT, Parser.prototype._negation],
|
[Tokens.NOT, Parser.prototype._negation],
|
||||||
]),
|
]),
|
||||||
};
|
};
|
||||||
|
|
2
vendor/codemirror/README.md
vendored
2
vendor/codemirror/README.md
vendored
|
@ -1,4 +1,4 @@
|
||||||
## codemirror v5.51.0
|
## codemirror v5.56.0
|
||||||
|
|
||||||
Following files are copied from npm (node_modules):
|
Following files are copied from npm (node_modules):
|
||||||
|
|
||||||
|
|
4
vendor/codemirror/addon/dialog/dialog.js
vendored
4
vendor/codemirror/addon/dialog/dialog.js
vendored
|
@ -82,7 +82,9 @@
|
||||||
if (e.keyCode == 13) callback(inp.value, e);
|
if (e.keyCode == 13) callback(inp.value, e);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (options.closeOnBlur !== false) CodeMirror.on(inp, "blur", close);
|
if (options.closeOnBlur !== false) CodeMirror.on(dialog, "focusout", function (evt) {
|
||||||
|
if (evt.relatedTarget !== null) close();
|
||||||
|
});
|
||||||
} else if (button = dialog.getElementsByTagName("button")[0]) {
|
} else if (button = dialog.getElementsByTagName("button")[0]) {
|
||||||
CodeMirror.on(button, "click", function() {
|
CodeMirror.on(button, "click", function() {
|
||||||
close();
|
close();
|
||||||
|
|
12
vendor/codemirror/addon/edit/matchbrackets.js
vendored
12
vendor/codemirror/addon/edit/matchbrackets.js
vendored
|
@ -118,16 +118,24 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) {
|
CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) {
|
||||||
if (old && old != CodeMirror.Init) {
|
function clear(cm) {
|
||||||
cm.off("cursorActivity", doMatchBrackets);
|
|
||||||
if (cm.state.matchBrackets && cm.state.matchBrackets.currentlyHighlighted) {
|
if (cm.state.matchBrackets && cm.state.matchBrackets.currentlyHighlighted) {
|
||||||
cm.state.matchBrackets.currentlyHighlighted();
|
cm.state.matchBrackets.currentlyHighlighted();
|
||||||
cm.state.matchBrackets.currentlyHighlighted = null;
|
cm.state.matchBrackets.currentlyHighlighted = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (old && old != CodeMirror.Init) {
|
||||||
|
cm.off("cursorActivity", doMatchBrackets);
|
||||||
|
cm.off("focus", doMatchBrackets)
|
||||||
|
cm.off("blur", clear)
|
||||||
|
clear(cm);
|
||||||
|
}
|
||||||
if (val) {
|
if (val) {
|
||||||
cm.state.matchBrackets = typeof val == "object" ? val : {};
|
cm.state.matchBrackets = typeof val == "object" ? val : {};
|
||||||
cm.on("cursorActivity", doMatchBrackets);
|
cm.on("cursorActivity", doMatchBrackets);
|
||||||
|
cm.on("focus", doMatchBrackets)
|
||||||
|
cm.on("blur", clear)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
35
vendor/codemirror/addon/hint/show-hint.js
vendored
35
vendor/codemirror/addon/hint/show-hint.js
vendored
|
@ -85,11 +85,16 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
pick: function(data, i) {
|
pick: function(data, i) {
|
||||||
var completion = data.list[i];
|
var completion = data.list[i], self = this;
|
||||||
if (completion.hint) completion.hint(this.cm, data, completion);
|
this.cm.operation(function() {
|
||||||
else this.cm.replaceRange(getText(completion), completion.from || data.from,
|
if (completion.hint)
|
||||||
completion.to || data.to, "complete");
|
completion.hint(self.cm, data, completion);
|
||||||
CodeMirror.signal(data, "pick", completion);
|
else
|
||||||
|
self.cm.replaceRange(getText(completion), completion.from || data.from,
|
||||||
|
completion.to || data.to, "complete");
|
||||||
|
CodeMirror.signal(data, "pick", completion);
|
||||||
|
self.cm.scrollIntoView();
|
||||||
|
})
|
||||||
this.close();
|
this.close();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -99,9 +104,14 @@
|
||||||
this.debounce = 0;
|
this.debounce = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var identStart = this.startPos;
|
||||||
|
if(this.data) {
|
||||||
|
identStart = this.data.from;
|
||||||
|
}
|
||||||
|
|
||||||
var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line);
|
var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line);
|
||||||
if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch ||
|
if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch ||
|
||||||
pos.ch < this.startPos.ch || this.cm.somethingSelected() ||
|
pos.ch < identStart.ch || this.cm.somethingSelected() ||
|
||||||
(!pos.ch || this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
|
(!pos.ch || this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
|
||||||
this.close();
|
this.close();
|
||||||
} else {
|
} else {
|
||||||
|
@ -369,11 +379,14 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
scrollToActive: function() {
|
scrollToActive: function() {
|
||||||
var node = this.hints.childNodes[this.selectedHint]
|
var margin = this.completion.options.scrollMargin || 0;
|
||||||
if (node.offsetTop < this.hints.scrollTop)
|
var node1 = this.hints.childNodes[Math.max(0, this.selectedHint - margin)];
|
||||||
this.hints.scrollTop = node.offsetTop - 3;
|
var node2 = this.hints.childNodes[Math.min(this.data.list.length - 1, this.selectedHint + margin)];
|
||||||
else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
|
var firstNode = this.hints.firstChild;
|
||||||
this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3;
|
if (node1.offsetTop < this.hints.scrollTop)
|
||||||
|
this.hints.scrollTop = node1.offsetTop - firstNode.offsetTop;
|
||||||
|
else if (node2.offsetTop + node2.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
|
||||||
|
this.hints.scrollTop = node2.offsetTop + node2.offsetHeight - this.hints.clientHeight + firstNode.offsetTop;
|
||||||
},
|
},
|
||||||
|
|
||||||
screenAmount: function() {
|
screenAmount: function() {
|
||||||
|
|
29
vendor/codemirror/addon/lint/lint.js
vendored
29
vendor/codemirror/addon/lint/lint.js
vendored
|
@ -12,11 +12,14 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
var GUTTER_ID = "CodeMirror-lint-markers";
|
var GUTTER_ID = "CodeMirror-lint-markers";
|
||||||
|
|
||||||
function showTooltip(e, content) {
|
function showTooltip(cm, e, content) {
|
||||||
var tt = document.createElement("div");
|
var tt = document.createElement("div");
|
||||||
tt.className = "CodeMirror-lint-tooltip";
|
tt.className = "CodeMirror-lint-tooltip cm-s-" + cm.options.theme;
|
||||||
tt.appendChild(content.cloneNode(true));
|
tt.appendChild(content.cloneNode(true));
|
||||||
document.body.appendChild(tt);
|
if (cm.state.lint.options.selfContain)
|
||||||
|
cm.getWrapperElement().appendChild(tt);
|
||||||
|
else
|
||||||
|
document.body.appendChild(tt);
|
||||||
|
|
||||||
function position(e) {
|
function position(e) {
|
||||||
if (!tt.parentNode) return CodeMirror.off(document, "mousemove", position);
|
if (!tt.parentNode) return CodeMirror.off(document, "mousemove", position);
|
||||||
|
@ -38,8 +41,8 @@
|
||||||
setTimeout(function() { rm(tt); }, 600);
|
setTimeout(function() { rm(tt); }, 600);
|
||||||
}
|
}
|
||||||
|
|
||||||
function showTooltipFor(e, content, node) {
|
function showTooltipFor(cm, e, content, node) {
|
||||||
var tooltip = showTooltip(e, content);
|
var tooltip = showTooltip(cm, e, content);
|
||||||
function hide() {
|
function hide() {
|
||||||
CodeMirror.off(node, "mouseout", hide);
|
CodeMirror.off(node, "mouseout", hide);
|
||||||
if (tooltip) { hideTooltip(tooltip); tooltip = null; }
|
if (tooltip) { hideTooltip(tooltip); tooltip = null; }
|
||||||
|
@ -78,7 +81,7 @@
|
||||||
state.marked.length = 0;
|
state.marked.length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeMarker(labels, severity, multiple, tooltips) {
|
function makeMarker(cm, labels, severity, multiple, tooltips) {
|
||||||
var marker = document.createElement("div"), inner = marker;
|
var marker = document.createElement("div"), inner = marker;
|
||||||
marker.className = "CodeMirror-lint-marker-" + severity;
|
marker.className = "CodeMirror-lint-marker-" + severity;
|
||||||
if (multiple) {
|
if (multiple) {
|
||||||
|
@ -87,7 +90,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tooltips != false) CodeMirror.on(inner, "mouseover", function(e) {
|
if (tooltips != false) CodeMirror.on(inner, "mouseover", function(e) {
|
||||||
showTooltipFor(e, labels, inner);
|
showTooltipFor(cm, e, labels, inner);
|
||||||
});
|
});
|
||||||
|
|
||||||
return marker;
|
return marker;
|
||||||
|
@ -113,9 +116,9 @@
|
||||||
var tip = document.createElement("div");
|
var tip = document.createElement("div");
|
||||||
tip.className = "CodeMirror-lint-message-" + severity;
|
tip.className = "CodeMirror-lint-message-" + severity;
|
||||||
if (typeof ann.messageHTML != 'undefined') {
|
if (typeof ann.messageHTML != 'undefined') {
|
||||||
tip.innerHTML = ann.messageHTML;
|
tip.innerHTML = ann.messageHTML;
|
||||||
} else {
|
} else {
|
||||||
tip.appendChild(document.createTextNode(ann.message));
|
tip.appendChild(document.createTextNode(ann.message));
|
||||||
}
|
}
|
||||||
return tip;
|
return tip;
|
||||||
}
|
}
|
||||||
|
@ -186,7 +189,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.hasGutter)
|
if (state.hasGutter)
|
||||||
cm.setGutterMarker(line, GUTTER_ID, makeMarker(tipLabel, maxSeverity, anns.length > 1,
|
cm.setGutterMarker(line, GUTTER_ID, makeMarker(cm, tipLabel, maxSeverity, anns.length > 1,
|
||||||
state.options.tooltips));
|
state.options.tooltips));
|
||||||
}
|
}
|
||||||
if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm);
|
if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm);
|
||||||
|
@ -199,14 +202,14 @@
|
||||||
state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500);
|
state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
function popupTooltips(annotations, e) {
|
function popupTooltips(cm, annotations, e) {
|
||||||
var target = e.target || e.srcElement;
|
var target = e.target || e.srcElement;
|
||||||
var tooltip = document.createDocumentFragment();
|
var tooltip = document.createDocumentFragment();
|
||||||
for (var i = 0; i < annotations.length; i++) {
|
for (var i = 0; i < annotations.length; i++) {
|
||||||
var ann = annotations[i];
|
var ann = annotations[i];
|
||||||
tooltip.appendChild(annotationTooltip(ann));
|
tooltip.appendChild(annotationTooltip(ann));
|
||||||
}
|
}
|
||||||
showTooltipFor(e, tooltip, target);
|
showTooltipFor(cm, e, tooltip, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onMouseOver(cm, e) {
|
function onMouseOver(cm, e) {
|
||||||
|
@ -220,7 +223,7 @@
|
||||||
var ann = spans[i].__annotation;
|
var ann = spans[i].__annotation;
|
||||||
if (ann) annotations.push(ann);
|
if (ann) annotations.push(ann);
|
||||||
}
|
}
|
||||||
if (annotations.length) popupTooltips(annotations, e);
|
if (annotations.length) popupTooltips(cm, annotations, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeMirror.defineOption("lint", false, function(cm, val, old) {
|
CodeMirror.defineOption("lint", false, function(cm, val, old) {
|
||||||
|
|
|
@ -240,7 +240,7 @@
|
||||||
var result = this.matches(reverse, this.doc.clipPos(reverse ? this.pos.from : this.pos.to))
|
var result = this.matches(reverse, this.doc.clipPos(reverse ? this.pos.from : this.pos.to))
|
||||||
|
|
||||||
// Implements weird auto-growing behavior on null-matches for
|
// Implements weird auto-growing behavior on null-matches for
|
||||||
// backwards-compatiblity with the vim code (unfortunately)
|
// backwards-compatibility with the vim code (unfortunately)
|
||||||
while (result && CodeMirror.cmpPos(result.from, result.to) == 0) {
|
while (result && CodeMirror.cmpPos(result.from, result.to) == 0) {
|
||||||
if (reverse) {
|
if (reverse) {
|
||||||
if (result.from.ch) result.from = Pos(result.from.line, result.from.ch - 1)
|
if (result.from.ch) result.from = Pos(result.from.line, result.from.ch - 1)
|
||||||
|
|
3
vendor/codemirror/keymap/emacs.js
vendored
3
vendor/codemirror/keymap/emacs.js
vendored
|
@ -404,7 +404,8 @@
|
||||||
"Ctrl-X H": "selectAll",
|
"Ctrl-X H": "selectAll",
|
||||||
|
|
||||||
"Ctrl-Q Tab": repeated("insertTab"),
|
"Ctrl-Q Tab": repeated("insertTab"),
|
||||||
"Ctrl-U": addPrefixMap
|
"Ctrl-U": addPrefixMap,
|
||||||
|
"fallthrough": "default"
|
||||||
});
|
});
|
||||||
|
|
||||||
var prefixMap = {"Ctrl-G": clearPrefix};
|
var prefixMap = {"Ctrl-G": clearPrefix};
|
||||||
|
|
2
vendor/codemirror/keymap/sublime.js
vendored
2
vendor/codemirror/keymap/sublime.js
vendored
|
@ -628,6 +628,7 @@
|
||||||
"Cmd-K Cmd-C": "showInCenter",
|
"Cmd-K Cmd-C": "showInCenter",
|
||||||
"Cmd-K Cmd-G": "clearBookmarks",
|
"Cmd-K Cmd-G": "clearBookmarks",
|
||||||
"Cmd-K Cmd-Backspace": "delLineLeft",
|
"Cmd-K Cmd-Backspace": "delLineLeft",
|
||||||
|
"Cmd-K Cmd-1": "foldAll",
|
||||||
"Cmd-K Cmd-0": "unfoldAll",
|
"Cmd-K Cmd-0": "unfoldAll",
|
||||||
"Cmd-K Cmd-J": "unfoldAll",
|
"Cmd-K Cmd-J": "unfoldAll",
|
||||||
"Ctrl-Shift-Up": "addCursorToPrevLine",
|
"Ctrl-Shift-Up": "addCursorToPrevLine",
|
||||||
|
@ -689,6 +690,7 @@
|
||||||
"Ctrl-K Ctrl-C": "showInCenter",
|
"Ctrl-K Ctrl-C": "showInCenter",
|
||||||
"Ctrl-K Ctrl-G": "clearBookmarks",
|
"Ctrl-K Ctrl-G": "clearBookmarks",
|
||||||
"Ctrl-K Ctrl-Backspace": "delLineLeft",
|
"Ctrl-K Ctrl-Backspace": "delLineLeft",
|
||||||
|
"Ctrl-K Ctrl-1": "foldAll",
|
||||||
"Ctrl-K Ctrl-0": "unfoldAll",
|
"Ctrl-K Ctrl-0": "unfoldAll",
|
||||||
"Ctrl-K Ctrl-J": "unfoldAll",
|
"Ctrl-K Ctrl-J": "unfoldAll",
|
||||||
"Ctrl-Alt-Up": "addCursorToPrevLine",
|
"Ctrl-Alt-Up": "addCursorToPrevLine",
|
||||||
|
|
65
vendor/codemirror/keymap/vim.js
vendored
65
vendor/codemirror/keymap/vim.js
vendored
|
@ -234,7 +234,6 @@
|
||||||
{ name: 'undo', shortName: 'u' },
|
{ name: 'undo', shortName: 'u' },
|
||||||
{ name: 'redo', shortName: 'red' },
|
{ name: 'redo', shortName: 'red' },
|
||||||
{ name: 'set', shortName: 'se' },
|
{ name: 'set', shortName: 'se' },
|
||||||
{ name: 'set', shortName: 'se' },
|
|
||||||
{ name: 'setlocal', shortName: 'setl' },
|
{ name: 'setlocal', shortName: 'setl' },
|
||||||
{ name: 'setglobal', shortName: 'setg' },
|
{ name: 'setglobal', shortName: 'setg' },
|
||||||
{ name: 'sort', shortName: 'sor' },
|
{ name: 'sort', shortName: 'sor' },
|
||||||
|
@ -295,16 +294,16 @@
|
||||||
clearFatCursorMark(cm);
|
clearFatCursorMark(cm);
|
||||||
var ranges = cm.listSelections(), result = []
|
var ranges = cm.listSelections(), result = []
|
||||||
for (var i = 0; i < ranges.length; i++) {
|
for (var i = 0; i < ranges.length; i++) {
|
||||||
var range = ranges[i]
|
var range = ranges[i];
|
||||||
if (range.empty()) {
|
if (range.empty()) {
|
||||||
if (range.anchor.ch < cm.getLine(range.anchor.line).length) {
|
var lineLength = cm.getLine(range.anchor.line).length;
|
||||||
|
if (range.anchor.ch < lineLength) {
|
||||||
result.push(cm.markText(range.anchor, Pos(range.anchor.line, range.anchor.ch + 1),
|
result.push(cm.markText(range.anchor, Pos(range.anchor.line, range.anchor.ch + 1),
|
||||||
{className: "cm-fat-cursor-mark"}))
|
{className: "cm-fat-cursor-mark"}));
|
||||||
} else {
|
} else {
|
||||||
var widget = document.createElement("span")
|
result.push(cm.markText(Pos(range.anchor.line, lineLength - 1),
|
||||||
widget.textContent = "\u00a0"
|
Pos(range.anchor.line, lineLength),
|
||||||
widget.className = "cm-fat-cursor-mark"
|
{className: "cm-fat-cursor-mark"}));
|
||||||
result.push(cm.setBookmark(range.anchor, {widget: widget}))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1603,10 +1602,10 @@
|
||||||
}
|
}
|
||||||
if (vim.visualMode) {
|
if (vim.visualMode) {
|
||||||
if (!(vim.visualBlock && newHead.ch === Infinity)) {
|
if (!(vim.visualBlock && newHead.ch === Infinity)) {
|
||||||
newHead = clipCursorToContent(cm, newHead, vim.visualBlock);
|
newHead = clipCursorToContent(cm, newHead);
|
||||||
}
|
}
|
||||||
if (newAnchor) {
|
if (newAnchor) {
|
||||||
newAnchor = clipCursorToContent(cm, newAnchor, true);
|
newAnchor = clipCursorToContent(cm, newAnchor);
|
||||||
}
|
}
|
||||||
newAnchor = newAnchor || oldAnchor;
|
newAnchor = newAnchor || oldAnchor;
|
||||||
sel.anchor = newAnchor;
|
sel.anchor = newAnchor;
|
||||||
|
@ -2200,8 +2199,7 @@
|
||||||
vimGlobalState.registerController.pushText(
|
vimGlobalState.registerController.pushText(
|
||||||
args.registerName, 'delete', text,
|
args.registerName, 'delete', text,
|
||||||
args.linewise, vim.visualBlock);
|
args.linewise, vim.visualBlock);
|
||||||
var includeLineBreak = vim.insertMode
|
return clipCursorToContent(cm, finalHead);
|
||||||
return clipCursorToContent(cm, finalHead, includeLineBreak);
|
|
||||||
},
|
},
|
||||||
indent: function(cm, args, ranges) {
|
indent: function(cm, args, ranges) {
|
||||||
var vim = cm.state.vim;
|
var vim = cm.state.vim;
|
||||||
|
@ -2460,8 +2458,7 @@
|
||||||
vim.visualLine = !!actionArgs.linewise;
|
vim.visualLine = !!actionArgs.linewise;
|
||||||
vim.visualBlock = !!actionArgs.blockwise;
|
vim.visualBlock = !!actionArgs.blockwise;
|
||||||
head = clipCursorToContent(
|
head = clipCursorToContent(
|
||||||
cm, Pos(anchor.line, anchor.ch + repeat - 1),
|
cm, Pos(anchor.line, anchor.ch + repeat - 1));
|
||||||
true /** includeLineBreak */);
|
|
||||||
vim.sel = {
|
vim.sel = {
|
||||||
anchor: anchor,
|
anchor: anchor,
|
||||||
head: head
|
head: head
|
||||||
|
@ -2837,10 +2834,11 @@
|
||||||
* Clips cursor to ensure that line is within the buffer's range
|
* Clips cursor to ensure that line is within the buffer's range
|
||||||
* If includeLineBreak is true, then allow cur.ch == lineLength.
|
* If includeLineBreak is true, then allow cur.ch == lineLength.
|
||||||
*/
|
*/
|
||||||
function clipCursorToContent(cm, cur, includeLineBreak) {
|
function clipCursorToContent(cm, cur) {
|
||||||
|
var vim = cm.state.vim;
|
||||||
|
var includeLineBreak = vim.insertMode || vim.visualMode;
|
||||||
var line = Math.min(Math.max(cm.firstLine(), cur.line), cm.lastLine() );
|
var line = Math.min(Math.max(cm.firstLine(), cur.line), cm.lastLine() );
|
||||||
var maxCh = lineLength(cm, line) - 1;
|
var maxCh = lineLength(cm, line) - 1 + !!includeLineBreak;
|
||||||
maxCh = (includeLineBreak) ? maxCh + 1 : maxCh;
|
|
||||||
var ch = Math.min(Math.max(0, cur.ch), maxCh);
|
var ch = Math.min(Math.max(0, cur.ch), maxCh);
|
||||||
return Pos(line, ch);
|
return Pos(line, ch);
|
||||||
}
|
}
|
||||||
|
@ -3205,10 +3203,8 @@
|
||||||
vim.visualMode = false;
|
vim.visualMode = false;
|
||||||
vim.visualLine = false;
|
vim.visualLine = false;
|
||||||
vim.visualBlock = false;
|
vim.visualBlock = false;
|
||||||
CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"});
|
if (!vim.insertMode) CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"});
|
||||||
if (vim.fakeCursor) {
|
clearFakeCursor(vim);
|
||||||
vim.fakeCursor.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove any trailing newlines from the selection. For
|
// Remove any trailing newlines from the selection. For
|
||||||
|
@ -4186,7 +4182,8 @@
|
||||||
}
|
}
|
||||||
function makePrompt(prefix, desc) {
|
function makePrompt(prefix, desc) {
|
||||||
var raw = '<span style="font-family: monospace; white-space: pre">' +
|
var raw = '<span style="font-family: monospace; white-space: pre">' +
|
||||||
(prefix || "") + '<input type="text"></span>';
|
(prefix || "") + '<input type="text" autocorrect="off" ' +
|
||||||
|
'autocapitalize="off" spellcheck="false"></span>';
|
||||||
if (desc)
|
if (desc)
|
||||||
raw += ' <span style="color: #888">' + desc + '</span>';
|
raw += ' <span style="color: #888">' + desc + '</span>';
|
||||||
return raw;
|
return raw;
|
||||||
|
@ -4459,7 +4456,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse command name.
|
// Parse command name.
|
||||||
var commandMatch = inputStream.match(/^(\w+)/);
|
var commandMatch = inputStream.match(/^(\w+|!!|@@|[!#&*<=>@~])/);
|
||||||
if (commandMatch) {
|
if (commandMatch) {
|
||||||
result.commandName = commandMatch[1];
|
result.commandName = commandMatch[1];
|
||||||
} else {
|
} else {
|
||||||
|
@ -5357,14 +5354,34 @@
|
||||||
updateFakeCursor(cm);
|
updateFakeCursor(cm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Keeps track of a fake cursor to support visual mode cursor behavior.
|
||||||
|
*/
|
||||||
function updateFakeCursor(cm) {
|
function updateFakeCursor(cm) {
|
||||||
|
var className = 'cm-animate-fat-cursor';
|
||||||
var vim = cm.state.vim;
|
var vim = cm.state.vim;
|
||||||
var from = clipCursorToContent(cm, copyCursor(vim.sel.head));
|
var from = clipCursorToContent(cm, copyCursor(vim.sel.head));
|
||||||
var to = offsetCursor(from, 0, 1);
|
var to = offsetCursor(from, 0, 1);
|
||||||
|
clearFakeCursor(vim);
|
||||||
|
// In visual mode, the cursor may be positioned over EOL.
|
||||||
|
if (from.ch == cm.getLine(from.line).length) {
|
||||||
|
var widget = document.createElement("span");
|
||||||
|
widget.textContent = "\u00a0";
|
||||||
|
widget.className = className;
|
||||||
|
vim.fakeCursorBookmark = cm.setBookmark(from, {widget: widget});
|
||||||
|
} else {
|
||||||
|
vim.fakeCursor = cm.markText(from, to, {className: className});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function clearFakeCursor(vim) {
|
||||||
if (vim.fakeCursor) {
|
if (vim.fakeCursor) {
|
||||||
vim.fakeCursor.clear();
|
vim.fakeCursor.clear();
|
||||||
|
vim.fakeCursor = null;
|
||||||
|
}
|
||||||
|
if (vim.fakeCursorBookmark) {
|
||||||
|
vim.fakeCursorBookmark.clear();
|
||||||
|
vim.fakeCursorBookmark = null;
|
||||||
}
|
}
|
||||||
vim.fakeCursor = cm.markText(from, to, {className: 'cm-animate-fat-cursor'});
|
|
||||||
}
|
}
|
||||||
function handleExternalSelection(cm, vim) {
|
function handleExternalSelection(cm, vim) {
|
||||||
var anchor = cm.getCursor('anchor');
|
var anchor = cm.getCursor('anchor');
|
||||||
|
|
10
vendor/codemirror/lib/codemirror.css
vendored
10
vendor/codemirror/lib/codemirror.css
vendored
|
@ -164,17 +164,17 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
|
||||||
|
|
||||||
.CodeMirror-scroll {
|
.CodeMirror-scroll {
|
||||||
overflow: scroll !important; /* Things will break if this is overridden */
|
overflow: scroll !important; /* Things will break if this is overridden */
|
||||||
/* 30px is the magic margin used to hide the element's real scrollbars */
|
/* 50px is the magic margin used to hide the element's real scrollbars */
|
||||||
/* See overflow: hidden in .CodeMirror */
|
/* See overflow: hidden in .CodeMirror */
|
||||||
margin-bottom: -30px; margin-right: -30px;
|
margin-bottom: -50px; margin-right: -50px;
|
||||||
padding-bottom: 30px;
|
padding-bottom: 50px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
outline: none; /* Prevent dragging from highlighting the element */
|
outline: none; /* Prevent dragging from highlighting the element */
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
.CodeMirror-sizer {
|
.CodeMirror-sizer {
|
||||||
position: relative;
|
position: relative;
|
||||||
border-right: 30px solid transparent;
|
border-right: 50px solid transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The fake, visible scrollbars. Used to force redraw during scrolling
|
/* The fake, visible scrollbars. Used to force redraw during scrolling
|
||||||
|
@ -212,7 +212,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
margin-bottom: -30px;
|
margin-bottom: -50px;
|
||||||
}
|
}
|
||||||
.CodeMirror-gutter-wrapper {
|
.CodeMirror-gutter-wrapper {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
86
vendor/codemirror/lib/codemirror.js
vendored
86
vendor/codemirror/lib/codemirror.js
vendored
|
@ -204,7 +204,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Number of pixels added to scroller and sizer to hide scrollbar
|
// Number of pixels added to scroller and sizer to hide scrollbar
|
||||||
var scrollerGap = 30;
|
var scrollerGap = 50;
|
||||||
|
|
||||||
// Returned or thrown by various protocols to signal 'I'm not
|
// Returned or thrown by various protocols to signal 'I'm not
|
||||||
// handling this'.
|
// handling this'.
|
||||||
|
@ -485,14 +485,15 @@
|
||||||
for (++i$7; i$7 < len && countsAsLeft.test(types[i$7]); ++i$7) {}
|
for (++i$7; i$7 < len && countsAsLeft.test(types[i$7]); ++i$7) {}
|
||||||
order.push(new BidiSpan(0, start, i$7));
|
order.push(new BidiSpan(0, start, i$7));
|
||||||
} else {
|
} else {
|
||||||
var pos = i$7, at = order.length;
|
var pos = i$7, at = order.length, isRTL = direction == "rtl" ? 1 : 0;
|
||||||
for (++i$7; i$7 < len && types[i$7] != "L"; ++i$7) {}
|
for (++i$7; i$7 < len && types[i$7] != "L"; ++i$7) {}
|
||||||
for (var j$2 = pos; j$2 < i$7;) {
|
for (var j$2 = pos; j$2 < i$7;) {
|
||||||
if (countsAsNum.test(types[j$2])) {
|
if (countsAsNum.test(types[j$2])) {
|
||||||
if (pos < j$2) { order.splice(at, 0, new BidiSpan(1, pos, j$2)); }
|
if (pos < j$2) { order.splice(at, 0, new BidiSpan(1, pos, j$2)); at += isRTL; }
|
||||||
var nstart = j$2;
|
var nstart = j$2;
|
||||||
for (++j$2; j$2 < i$7 && countsAsNum.test(types[j$2]); ++j$2) {}
|
for (++j$2; j$2 < i$7 && countsAsNum.test(types[j$2]); ++j$2) {}
|
||||||
order.splice(at, 0, new BidiSpan(2, nstart, j$2));
|
order.splice(at, 0, new BidiSpan(2, nstart, j$2));
|
||||||
|
at += isRTL;
|
||||||
pos = j$2;
|
pos = j$2;
|
||||||
} else { ++j$2; }
|
} else { ++j$2; }
|
||||||
}
|
}
|
||||||
|
@ -1200,7 +1201,7 @@
|
||||||
var prop = lineClass[1] ? "bgClass" : "textClass";
|
var prop = lineClass[1] ? "bgClass" : "textClass";
|
||||||
if (output[prop] == null)
|
if (output[prop] == null)
|
||||||
{ output[prop] = lineClass[2]; }
|
{ output[prop] = lineClass[2]; }
|
||||||
else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop]))
|
else if (!(new RegExp("(?:^|\\s)" + lineClass[2] + "(?:$|\\s)")).test(output[prop]))
|
||||||
{ output[prop] += " " + lineClass[2]; }
|
{ output[prop] += " " + lineClass[2]; }
|
||||||
} }
|
} }
|
||||||
return type
|
return type
|
||||||
|
@ -2959,7 +2960,7 @@
|
||||||
var x, y, space = display.lineSpace.getBoundingClientRect();
|
var x, y, space = display.lineSpace.getBoundingClientRect();
|
||||||
// Fails unpredictably on IE[67] when mouse is dragged around quickly.
|
// Fails unpredictably on IE[67] when mouse is dragged around quickly.
|
||||||
try { x = e.clientX - space.left; y = e.clientY - space.top; }
|
try { x = e.clientX - space.left; y = e.clientY - space.top; }
|
||||||
catch (e) { return null }
|
catch (e$1) { return null }
|
||||||
var coords = coordsChar(cm, x, y), line;
|
var coords = coordsChar(cm, x, y), line;
|
||||||
if (forRect && coords.xRel > 0 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) {
|
if (forRect && coords.xRel > 0 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) {
|
||||||
var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length;
|
var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length;
|
||||||
|
@ -3550,7 +3551,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function setScrollTop(cm, val, forceScroll) {
|
function setScrollTop(cm, val, forceScroll) {
|
||||||
val = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight, val);
|
val = Math.max(0, Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight, val));
|
||||||
if (cm.display.scroller.scrollTop == val && !forceScroll) { return }
|
if (cm.display.scroller.scrollTop == val && !forceScroll) { return }
|
||||||
cm.doc.scrollTop = val;
|
cm.doc.scrollTop = val;
|
||||||
cm.display.scrollbars.setScrollTop(val);
|
cm.display.scrollbars.setScrollTop(val);
|
||||||
|
@ -3560,7 +3561,7 @@
|
||||||
// Sync scroller and scrollbar, ensure the gutter elements are
|
// Sync scroller and scrollbar, ensure the gutter elements are
|
||||||
// aligned.
|
// aligned.
|
||||||
function setScrollLeft(cm, val, isScroller, forceScroll) {
|
function setScrollLeft(cm, val, isScroller, forceScroll) {
|
||||||
val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
|
val = Math.max(0, Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth));
|
||||||
if ((isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) && !forceScroll) { return }
|
if ((isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) && !forceScroll) { return }
|
||||||
cm.doc.scrollLeft = val;
|
cm.doc.scrollLeft = val;
|
||||||
alignHorizontally(cm);
|
alignHorizontally(cm);
|
||||||
|
@ -4049,7 +4050,8 @@
|
||||||
function restoreSelection(snapshot) {
|
function restoreSelection(snapshot) {
|
||||||
if (!snapshot || !snapshot.activeElt || snapshot.activeElt == activeElt()) { return }
|
if (!snapshot || !snapshot.activeElt || snapshot.activeElt == activeElt()) { return }
|
||||||
snapshot.activeElt.focus();
|
snapshot.activeElt.focus();
|
||||||
if (snapshot.anchorNode && contains(document.body, snapshot.anchorNode) && contains(document.body, snapshot.focusNode)) {
|
if (!/^(INPUT|TEXTAREA)$/.test(snapshot.activeElt.nodeName) &&
|
||||||
|
snapshot.anchorNode && contains(document.body, snapshot.anchorNode) && contains(document.body, snapshot.focusNode)) {
|
||||||
var sel = window.getSelection(), range = document.createRange();
|
var sel = window.getSelection(), range = document.createRange();
|
||||||
range.setEnd(snapshot.anchorNode, snapshot.anchorOffset);
|
range.setEnd(snapshot.anchorNode, snapshot.anchorOffset);
|
||||||
range.collapse(false);
|
range.collapse(false);
|
||||||
|
@ -4147,6 +4149,8 @@
|
||||||
update.visible = visibleLines(cm.display, cm.doc, viewport);
|
update.visible = visibleLines(cm.display, cm.doc, viewport);
|
||||||
if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo)
|
if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo)
|
||||||
{ break }
|
{ break }
|
||||||
|
} else if (first) {
|
||||||
|
update.visible = visibleLines(cm.display, cm.doc, viewport);
|
||||||
}
|
}
|
||||||
if (!updateDisplayIfNeeded(cm, update)) { break }
|
if (!updateDisplayIfNeeded(cm, update)) { break }
|
||||||
updateHeightsInViewport(cm);
|
updateHeightsInViewport(cm);
|
||||||
|
@ -6496,7 +6500,7 @@
|
||||||
text.filter(function (t) { return t != null; }).join(cm.doc.lineSeparator())),
|
text.filter(function (t) { return t != null; }).join(cm.doc.lineSeparator())),
|
||||||
origin: "paste"};
|
origin: "paste"};
|
||||||
makeChange(cm.doc, change);
|
makeChange(cm.doc, change);
|
||||||
setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change)));
|
setSelectionReplaceHistory(cm.doc, simpleSelection(clipPos(cm.doc, pos), clipPos(cm.doc, changeEnd(change))));
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -6541,7 +6545,7 @@
|
||||||
cm.display.input.focus();
|
cm.display.input.focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(e){}
|
catch(e$1){}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6829,7 +6833,7 @@
|
||||||
|
|
||||||
function endOfLine(visually, cm, lineObj, lineNo, dir) {
|
function endOfLine(visually, cm, lineObj, lineNo, dir) {
|
||||||
if (visually) {
|
if (visually) {
|
||||||
if (cm.getOption("direction") == "rtl") { dir = -dir; }
|
if (cm.doc.direction == "rtl") { dir = -dir; }
|
||||||
var order = getOrder(lineObj, cm.doc.direction);
|
var order = getOrder(lineObj, cm.doc.direction);
|
||||||
if (order) {
|
if (order) {
|
||||||
var part = dir < 0 ? lst(order) : order[0];
|
var part = dir < 0 ? lst(order) : order[0];
|
||||||
|
@ -7084,7 +7088,7 @@
|
||||||
var line = getLine(cm.doc, start.line);
|
var line = getLine(cm.doc, start.line);
|
||||||
var order = getOrder(line, cm.doc.direction);
|
var order = getOrder(line, cm.doc.direction);
|
||||||
if (!order || order[0].level == 0) {
|
if (!order || order[0].level == 0) {
|
||||||
var firstNonWS = Math.max(0, line.text.search(/\S/));
|
var firstNonWS = Math.max(start.ch, line.text.search(/\S/));
|
||||||
var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch;
|
var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch;
|
||||||
return Pos(start.line, inWS ? 0 : firstNonWS, start.sticky)
|
return Pos(start.line, inWS ? 0 : firstNonWS, start.sticky)
|
||||||
}
|
}
|
||||||
|
@ -7187,6 +7191,7 @@
|
||||||
var lastStoppedKey = null;
|
var lastStoppedKey = null;
|
||||||
function onKeyDown(e) {
|
function onKeyDown(e) {
|
||||||
var cm = this;
|
var cm = this;
|
||||||
|
if (e.target && e.target != cm.display.input.getField()) { return }
|
||||||
cm.curOp.focus = activeElt();
|
cm.curOp.focus = activeElt();
|
||||||
if (signalDOMEvent(cm, e)) { return }
|
if (signalDOMEvent(cm, e)) { return }
|
||||||
// IE does strange things with escape.
|
// IE does strange things with escape.
|
||||||
|
@ -7230,6 +7235,7 @@
|
||||||
|
|
||||||
function onKeyPress(e) {
|
function onKeyPress(e) {
|
||||||
var cm = this;
|
var cm = this;
|
||||||
|
if (e.target && e.target != cm.display.input.getField()) { return }
|
||||||
if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) { return }
|
if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) { return }
|
||||||
var keyCode = e.keyCode, charCode = e.charCode;
|
var keyCode = e.keyCode, charCode = e.charCode;
|
||||||
if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return}
|
if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return}
|
||||||
|
@ -7378,8 +7384,8 @@
|
||||||
if (!behavior.addNew)
|
if (!behavior.addNew)
|
||||||
{ extendSelection(cm.doc, pos, null, null, behavior.extend); }
|
{ extendSelection(cm.doc, pos, null, null, behavior.extend); }
|
||||||
// Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081)
|
// Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081)
|
||||||
if (webkit || ie && ie_version == 9)
|
if ((webkit && !safari) || ie && ie_version == 9)
|
||||||
{ setTimeout(function () {display.wrapper.ownerDocument.body.focus(); display.input.focus();}, 20); }
|
{ setTimeout(function () {display.wrapper.ownerDocument.body.focus({preventScroll: true}); display.input.focus();}, 20); }
|
||||||
else
|
else
|
||||||
{ display.input.focus(); }
|
{ display.input.focus(); }
|
||||||
}
|
}
|
||||||
|
@ -7591,7 +7597,7 @@
|
||||||
mY = e.touches[0].clientY;
|
mY = e.touches[0].clientY;
|
||||||
} else {
|
} else {
|
||||||
try { mX = e.clientX; mY = e.clientY; }
|
try { mX = e.clientX; mY = e.clientY; }
|
||||||
catch(e) { return false }
|
catch(e$1) { return false }
|
||||||
}
|
}
|
||||||
if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) { return false }
|
if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) { return false }
|
||||||
if (prevent) { e_preventDefault(e); }
|
if (prevent) { e_preventDefault(e); }
|
||||||
|
@ -7691,7 +7697,7 @@
|
||||||
for (var i = newBreaks.length - 1; i >= 0; i--)
|
for (var i = newBreaks.length - 1; i >= 0; i--)
|
||||||
{ replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length)); }
|
{ replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length)); }
|
||||||
});
|
});
|
||||||
option("specialChars", /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200f\u2028\u2029\ufeff\ufff9-\ufffc]/g, function (cm, val, old) {
|
option("specialChars", /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200c\u200e\u200f\u2028\u2029\ufeff\ufff9-\ufffc]/g, function (cm, val, old) {
|
||||||
cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g");
|
cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g");
|
||||||
if (old != Init) { cm.refresh(); }
|
if (old != Init) { cm.refresh(); }
|
||||||
});
|
});
|
||||||
|
@ -7755,6 +7761,12 @@
|
||||||
}
|
}
|
||||||
cm.display.input.readOnlyChanged(val);
|
cm.display.input.readOnlyChanged(val);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
option("screenReaderLabel", null, function (cm, val) {
|
||||||
|
val = (val === '') ? null : val;
|
||||||
|
cm.display.input.screenReaderLabelChanged(val);
|
||||||
|
});
|
||||||
|
|
||||||
option("disableInput", false, function (cm, val) {if (!val) { cm.display.input.reset(); }}, true);
|
option("disableInput", false, function (cm, val) {if (!val) { cm.display.input.reset(); }}, true);
|
||||||
option("dragDrop", true, dragDropChanged);
|
option("dragDrop", true, dragDropChanged);
|
||||||
option("allowDropFileTypes", null);
|
option("allowDropFileTypes", null);
|
||||||
|
@ -8105,7 +8117,7 @@
|
||||||
{ from = Pos(from.line, from.ch - deleted); }
|
{ from = Pos(from.line, from.ch - deleted); }
|
||||||
else if (cm.state.overwrite && !paste) // Handle overwrite
|
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)); }
|
{ to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length)); }
|
||||||
else if (paste && lastCopied && lastCopied.lineWise && lastCopied.text.join("\n") == inserted)
|
else if (paste && lastCopied && lastCopied.lineWise && lastCopied.text.join("\n") == textLines.join("\n"))
|
||||||
{ from = to = Pos(from.line, 0); }
|
{ from = to = Pos(from.line, 0); }
|
||||||
}
|
}
|
||||||
var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i$1 % multiPaste.length] : textLines,
|
var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i$1 % multiPaste.length] : textLines,
|
||||||
|
@ -8586,7 +8598,7 @@
|
||||||
clearCaches(this);
|
clearCaches(this);
|
||||||
scrollToCoords(this, this.doc.scrollLeft, this.doc.scrollTop);
|
scrollToCoords(this, this.doc.scrollLeft, this.doc.scrollTop);
|
||||||
updateGutterSpace(this.display);
|
updateGutterSpace(this.display);
|
||||||
if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5)
|
if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5 || this.options.lineWrapping)
|
||||||
{ estimateLineHeights(this); }
|
{ estimateLineHeights(this); }
|
||||||
signal(this, "refresh", this);
|
signal(this, "refresh", this);
|
||||||
}),
|
}),
|
||||||
|
@ -8640,7 +8652,7 @@
|
||||||
var oldPos = pos;
|
var oldPos = pos;
|
||||||
var origDir = dir;
|
var origDir = dir;
|
||||||
var lineObj = getLine(doc, pos.line);
|
var lineObj = getLine(doc, pos.line);
|
||||||
var lineDir = visually && doc.cm && doc.cm.getOption("direction") == "rtl" ? -dir : dir;
|
var lineDir = visually && doc.direction == "rtl" ? -dir : dir;
|
||||||
function findNextLine() {
|
function findNextLine() {
|
||||||
var l = pos.line + lineDir;
|
var l = pos.line + lineDir;
|
||||||
if (l < doc.first || l >= doc.first + doc.size) { return false }
|
if (l < doc.first || l >= doc.first + doc.size) { return false }
|
||||||
|
@ -8735,8 +8747,16 @@
|
||||||
var div = input.div = display.lineDiv;
|
var div = input.div = display.lineDiv;
|
||||||
disableBrowserMagic(div, cm.options.spellcheck, cm.options.autocorrect, cm.options.autocapitalize);
|
disableBrowserMagic(div, cm.options.spellcheck, cm.options.autocorrect, cm.options.autocapitalize);
|
||||||
|
|
||||||
|
function belongsToInput(e) {
|
||||||
|
for (var t = e.target; t; t = t.parentNode) {
|
||||||
|
if (t == div) { return true }
|
||||||
|
if (/\bCodeMirror-(?:line)?widget\b/.test(t.className)) { break }
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
on(div, "paste", function (e) {
|
on(div, "paste", function (e) {
|
||||||
if (signalDOMEvent(cm, e) || handlePaste(e, cm)) { return }
|
if (!belongsToInput(e) || signalDOMEvent(cm, e) || handlePaste(e, cm)) { return }
|
||||||
// IE doesn't fire input events, so we schedule a read for the pasted content in this way
|
// IE doesn't fire input events, so we schedule a read for the pasted content in this way
|
||||||
if (ie_version <= 11) { setTimeout(operation(cm, function () { return this$1.updateFromDOM(); }), 20); }
|
if (ie_version <= 11) { setTimeout(operation(cm, function () { return this$1.updateFromDOM(); }), 20); }
|
||||||
});
|
});
|
||||||
|
@ -8761,7 +8781,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
function onCopyCut(e) {
|
function onCopyCut(e) {
|
||||||
if (signalDOMEvent(cm, e)) { return }
|
if (!belongsToInput(e) || signalDOMEvent(cm, e)) { return }
|
||||||
if (cm.somethingSelected()) {
|
if (cm.somethingSelected()) {
|
||||||
setLastCopied({lineWise: false, text: cm.getSelections()});
|
setLastCopied({lineWise: false, text: cm.getSelections()});
|
||||||
if (e.type == "cut") { cm.replaceSelection("", null, "cut"); }
|
if (e.type == "cut") { cm.replaceSelection("", null, "cut"); }
|
||||||
|
@ -8803,9 +8823,18 @@
|
||||||
on(div, "cut", onCopyCut);
|
on(div, "cut", onCopyCut);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ContentEditableInput.prototype.screenReaderLabelChanged = function (label) {
|
||||||
|
// Label for screenreaders, accessibility
|
||||||
|
if(label) {
|
||||||
|
this.div.setAttribute('aria-label', label);
|
||||||
|
} else {
|
||||||
|
this.div.removeAttribute('aria-label');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
ContentEditableInput.prototype.prepareSelection = function () {
|
ContentEditableInput.prototype.prepareSelection = function () {
|
||||||
var result = prepareSelection(this.cm, false);
|
var result = prepareSelection(this.cm, false);
|
||||||
result.focus = this.cm.state.focused;
|
result.focus = document.activeElement == this.div;
|
||||||
return result
|
return result
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8901,7 +8930,7 @@
|
||||||
|
|
||||||
ContentEditableInput.prototype.focus = function () {
|
ContentEditableInput.prototype.focus = function () {
|
||||||
if (this.cm.options.readOnly != "nocursor") {
|
if (this.cm.options.readOnly != "nocursor") {
|
||||||
if (!this.selectionInEditor())
|
if (!this.selectionInEditor() || document.activeElement != this.div)
|
||||||
{ this.showSelection(this.prepareSelection(), true); }
|
{ this.showSelection(this.prepareSelection(), true); }
|
||||||
this.div.focus();
|
this.div.focus();
|
||||||
}
|
}
|
||||||
|
@ -9343,6 +9372,15 @@
|
||||||
this.textarea = this.wrapper.firstChild;
|
this.textarea = this.wrapper.firstChild;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TextareaInput.prototype.screenReaderLabelChanged = function (label) {
|
||||||
|
// Label for screenreaders, accessibility
|
||||||
|
if(label) {
|
||||||
|
this.textarea.setAttribute('aria-label', label);
|
||||||
|
} else {
|
||||||
|
this.textarea.removeAttribute('aria-label');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
TextareaInput.prototype.prepareSelection = function () {
|
TextareaInput.prototype.prepareSelection = function () {
|
||||||
// Redraw the selection and/or cursor
|
// Redraw the selection and/or cursor
|
||||||
var cm = this.cm, display = cm.display, doc = cm.doc;
|
var cm = this.cm, display = cm.display, doc = cm.doc;
|
||||||
|
@ -9733,7 +9771,7 @@
|
||||||
|
|
||||||
addLegacyProps(CodeMirror);
|
addLegacyProps(CodeMirror);
|
||||||
|
|
||||||
CodeMirror.version = "5.51.0";
|
CodeMirror.version = "5.56.0";
|
||||||
|
|
||||||
return CodeMirror;
|
return CodeMirror;
|
||||||
|
|
||||||
|
|
181
vendor/codemirror/mode/css/css.js
vendored
181
vendor/codemirror/mode/css/css.js
vendored
|
@ -455,81 +455,98 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||||
"alignment-baseline", "anchor-point", "animation", "animation-delay",
|
"alignment-baseline", "anchor-point", "animation", "animation-delay",
|
||||||
"animation-direction", "animation-duration", "animation-fill-mode",
|
"animation-direction", "animation-duration", "animation-fill-mode",
|
||||||
"animation-iteration-count", "animation-name", "animation-play-state",
|
"animation-iteration-count", "animation-name", "animation-play-state",
|
||||||
"animation-timing-function", "appearance", "azimuth", "backface-visibility",
|
"animation-timing-function", "appearance", "azimuth", "backdrop-filter",
|
||||||
"background", "background-attachment", "background-blend-mode", "background-clip",
|
"backface-visibility", "background", "background-attachment",
|
||||||
"background-color", "background-image", "background-origin", "background-position",
|
"background-blend-mode", "background-clip", "background-color",
|
||||||
"background-repeat", "background-size", "baseline-shift", "binding",
|
"background-image", "background-origin", "background-position",
|
||||||
"bleed", "bookmark-label", "bookmark-level", "bookmark-state",
|
"background-position-x", "background-position-y", "background-repeat",
|
||||||
"bookmark-target", "border", "border-bottom", "border-bottom-color",
|
"background-size", "baseline-shift", "binding", "bleed", "block-size",
|
||||||
"border-bottom-left-radius", "border-bottom-right-radius",
|
"bookmark-label", "bookmark-level", "bookmark-state", "bookmark-target",
|
||||||
"border-bottom-style", "border-bottom-width", "border-collapse",
|
"border", "border-bottom", "border-bottom-color", "border-bottom-left-radius",
|
||||||
"border-color", "border-image", "border-image-outset",
|
"border-bottom-right-radius", "border-bottom-style", "border-bottom-width",
|
||||||
|
"border-collapse", "border-color", "border-image", "border-image-outset",
|
||||||
"border-image-repeat", "border-image-slice", "border-image-source",
|
"border-image-repeat", "border-image-slice", "border-image-source",
|
||||||
"border-image-width", "border-left", "border-left-color",
|
"border-image-width", "border-left", "border-left-color", "border-left-style",
|
||||||
"border-left-style", "border-left-width", "border-radius", "border-right",
|
"border-left-width", "border-radius", "border-right", "border-right-color",
|
||||||
"border-right-color", "border-right-style", "border-right-width",
|
"border-right-style", "border-right-width", "border-spacing", "border-style",
|
||||||
"border-spacing", "border-style", "border-top", "border-top-color",
|
"border-top", "border-top-color", "border-top-left-radius",
|
||||||
"border-top-left-radius", "border-top-right-radius", "border-top-style",
|
"border-top-right-radius", "border-top-style", "border-top-width",
|
||||||
"border-top-width", "border-width", "bottom", "box-decoration-break",
|
"border-width", "bottom", "box-decoration-break", "box-shadow", "box-sizing",
|
||||||
"box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
|
"break-after", "break-before", "break-inside", "caption-side", "caret-color",
|
||||||
"caption-side", "caret-color", "clear", "clip", "color", "color-profile", "column-count",
|
"clear", "clip", "color", "color-profile", "column-count", "column-fill",
|
||||||
"column-fill", "column-gap", "column-rule", "column-rule-color",
|
"column-gap", "column-rule", "column-rule-color", "column-rule-style",
|
||||||
"column-rule-style", "column-rule-width", "column-span", "column-width",
|
"column-rule-width", "column-span", "column-width", "columns", "contain",
|
||||||
"columns", "content", "counter-increment", "counter-reset", "crop", "cue",
|
"content", "counter-increment", "counter-reset", "crop", "cue", "cue-after",
|
||||||
"cue-after", "cue-before", "cursor", "direction", "display",
|
"cue-before", "cursor", "direction", "display", "dominant-baseline",
|
||||||
"dominant-baseline", "drop-initial-after-adjust",
|
"drop-initial-after-adjust", "drop-initial-after-align",
|
||||||
"drop-initial-after-align", "drop-initial-before-adjust",
|
"drop-initial-before-adjust", "drop-initial-before-align", "drop-initial-size",
|
||||||
"drop-initial-before-align", "drop-initial-size", "drop-initial-value",
|
"drop-initial-value", "elevation", "empty-cells", "fit", "fit-position",
|
||||||
"elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
|
"flex", "flex-basis", "flex-direction", "flex-flow", "flex-grow",
|
||||||
"flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
|
"flex-shrink", "flex-wrap", "float", "float-offset", "flow-from", "flow-into",
|
||||||
"float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings",
|
"font", "font-family", "font-feature-settings", "font-kerning",
|
||||||
"font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust",
|
"font-language-override", "font-optical-sizing", "font-size",
|
||||||
"font-stretch", "font-style", "font-synthesis", "font-variant",
|
"font-size-adjust", "font-stretch", "font-style", "font-synthesis",
|
||||||
"font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
|
"font-variant", "font-variant-alternates", "font-variant-caps",
|
||||||
"font-variant-ligatures", "font-variant-numeric", "font-variant-position",
|
"font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric",
|
||||||
"font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow",
|
"font-variant-position", "font-variation-settings", "font-weight", "gap",
|
||||||
"grid-auto-rows", "grid-column", "grid-column-end", "grid-column-gap",
|
"grid", "grid-area", "grid-auto-columns", "grid-auto-flow", "grid-auto-rows",
|
||||||
"grid-column-start", "grid-gap", "grid-row", "grid-row-end", "grid-row-gap",
|
"grid-column", "grid-column-end", "grid-column-gap", "grid-column-start",
|
||||||
"grid-row-start", "grid-template", "grid-template-areas", "grid-template-columns",
|
"grid-gap", "grid-row", "grid-row-end", "grid-row-gap", "grid-row-start",
|
||||||
"grid-template-rows", "hanging-punctuation", "height", "hyphens",
|
"grid-template", "grid-template-areas", "grid-template-columns",
|
||||||
"icon", "image-orientation", "image-rendering", "image-resolution",
|
"grid-template-rows", "hanging-punctuation", "height", "hyphens", "icon",
|
||||||
"inline-box-align", "justify-content", "justify-items", "justify-self", "left", "letter-spacing",
|
"image-orientation", "image-rendering", "image-resolution", "inline-box-align",
|
||||||
"line-break", "line-height", "line-stacking", "line-stacking-ruby",
|
"inset", "inset-block", "inset-block-end", "inset-block-start", "inset-inline",
|
||||||
|
"inset-inline-end", "inset-inline-start", "isolation", "justify-content",
|
||||||
|
"justify-items", "justify-self", "left", "letter-spacing", "line-break",
|
||||||
|
"line-height", "line-height-step", "line-stacking", "line-stacking-ruby",
|
||||||
"line-stacking-shift", "line-stacking-strategy", "list-style",
|
"line-stacking-shift", "line-stacking-strategy", "list-style",
|
||||||
"list-style-image", "list-style-position", "list-style-type", "margin",
|
"list-style-image", "list-style-position", "list-style-type", "margin",
|
||||||
"margin-bottom", "margin-left", "margin-right", "margin-top",
|
"margin-bottom", "margin-left", "margin-right", "margin-top", "marks",
|
||||||
"marks", "marquee-direction", "marquee-loop",
|
"marquee-direction", "marquee-loop", "marquee-play-count", "marquee-speed",
|
||||||
"marquee-play-count", "marquee-speed", "marquee-style", "max-height",
|
"marquee-style", "max-block-size", "max-height", "max-inline-size",
|
||||||
"max-width", "min-height", "min-width", "mix-blend-mode", "move-to", "nav-down", "nav-index",
|
"max-width", "min-block-size", "min-height", "min-inline-size", "min-width",
|
||||||
"nav-left", "nav-right", "nav-up", "object-fit", "object-position",
|
"mix-blend-mode", "move-to", "nav-down", "nav-index", "nav-left", "nav-right",
|
||||||
"opacity", "order", "orphans", "outline",
|
"nav-up", "object-fit", "object-position", "offset", "offset-anchor",
|
||||||
"outline-color", "outline-offset", "outline-style", "outline-width",
|
"offset-distance", "offset-path", "offset-position", "offset-rotate",
|
||||||
"overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
|
"opacity", "order", "orphans", "outline", "outline-color", "outline-offset",
|
||||||
"padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
|
"outline-style", "outline-width", "overflow", "overflow-style",
|
||||||
"page", "page-break-after", "page-break-before", "page-break-inside",
|
"overflow-wrap", "overflow-x", "overflow-y", "padding", "padding-bottom",
|
||||||
"page-policy", "pause", "pause-after", "pause-before", "perspective",
|
"padding-left", "padding-right", "padding-top", "page", "page-break-after",
|
||||||
"perspective-origin", "pitch", "pitch-range", "place-content", "place-items", "place-self", "play-during", "position",
|
"page-break-before", "page-break-inside", "page-policy", "pause",
|
||||||
"presentation-level", "punctuation-trim", "quotes", "region-break-after",
|
"pause-after", "pause-before", "perspective", "perspective-origin", "pitch",
|
||||||
"region-break-before", "region-break-inside", "region-fragment",
|
"pitch-range", "place-content", "place-items", "place-self", "play-during",
|
||||||
"rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
|
"position", "presentation-level", "punctuation-trim", "quotes",
|
||||||
"right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
|
"region-break-after", "region-break-before", "region-break-inside",
|
||||||
"ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin",
|
"region-fragment", "rendering-intent", "resize", "rest", "rest-after",
|
||||||
"shape-outside", "size", "speak", "speak-as", "speak-header",
|
"rest-before", "richness", "right", "rotate", "rotation", "rotation-point",
|
||||||
"speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
|
"row-gap", "ruby-align", "ruby-overhang", "ruby-position", "ruby-span",
|
||||||
"tab-size", "table-layout", "target", "target-name", "target-new",
|
"scale", "scroll-behavior", "scroll-margin", "scroll-margin-block",
|
||||||
"target-position", "text-align", "text-align-last", "text-decoration",
|
"scroll-margin-block-end", "scroll-margin-block-start", "scroll-margin-bottom",
|
||||||
|
"scroll-margin-inline", "scroll-margin-inline-end",
|
||||||
|
"scroll-margin-inline-start", "scroll-margin-left", "scroll-margin-right",
|
||||||
|
"scroll-margin-top", "scroll-padding", "scroll-padding-block",
|
||||||
|
"scroll-padding-block-end", "scroll-padding-block-start",
|
||||||
|
"scroll-padding-bottom", "scroll-padding-inline", "scroll-padding-inline-end",
|
||||||
|
"scroll-padding-inline-start", "scroll-padding-left", "scroll-padding-right",
|
||||||
|
"scroll-padding-top", "scroll-snap-align", "scroll-snap-type",
|
||||||
|
"shape-image-threshold", "shape-inside", "shape-margin", "shape-outside",
|
||||||
|
"size", "speak", "speak-as", "speak-header", "speak-numeral",
|
||||||
|
"speak-punctuation", "speech-rate", "stress", "string-set", "tab-size",
|
||||||
|
"table-layout", "target", "target-name", "target-new", "target-position",
|
||||||
|
"text-align", "text-align-last", "text-combine-upright", "text-decoration",
|
||||||
"text-decoration-color", "text-decoration-line", "text-decoration-skip",
|
"text-decoration-color", "text-decoration-line", "text-decoration-skip",
|
||||||
"text-decoration-style", "text-emphasis", "text-emphasis-color",
|
"text-decoration-skip-ink", "text-decoration-style", "text-emphasis",
|
||||||
"text-emphasis-position", "text-emphasis-style", "text-height",
|
"text-emphasis-color", "text-emphasis-position", "text-emphasis-style",
|
||||||
"text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
|
"text-height", "text-indent", "text-justify", "text-orientation",
|
||||||
"text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
|
"text-outline", "text-overflow", "text-rendering", "text-shadow",
|
||||||
"text-wrap", "top", "transform", "transform-origin", "transform-style",
|
"text-size-adjust", "text-space-collapse", "text-transform",
|
||||||
"transition", "transition-delay", "transition-duration",
|
"text-underline-position", "text-wrap", "top", "transform", "transform-origin",
|
||||||
"transition-property", "transition-timing-function", "unicode-bidi",
|
"transform-style", "transition", "transition-delay", "transition-duration",
|
||||||
"user-select", "vertical-align", "visibility", "voice-balance", "voice-duration",
|
"transition-property", "transition-timing-function", "translate",
|
||||||
"voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
|
"unicode-bidi", "user-select", "vertical-align", "visibility", "voice-balance",
|
||||||
"voice-volume", "volume", "white-space", "widows", "width", "will-change", "word-break",
|
"voice-duration", "voice-family", "voice-pitch", "voice-range", "voice-rate",
|
||||||
"word-spacing", "word-wrap", "z-index",
|
"voice-stress", "voice-volume", "volume", "white-space", "widows", "width",
|
||||||
|
"will-change", "word-break", "word-spacing", "word-wrap", "writing-mode", "z-index",
|
||||||
// SVG-specific
|
// SVG-specific
|
||||||
"clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
|
"clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
|
||||||
"flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
|
"flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
|
||||||
|
@ -543,16 +560,28 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||||
], propertyKeywords = keySet(propertyKeywords_);
|
], propertyKeywords = keySet(propertyKeywords_);
|
||||||
|
|
||||||
var nonStandardPropertyKeywords_ = [
|
var nonStandardPropertyKeywords_ = [
|
||||||
|
"border-block", "border-block-color", "border-block-end",
|
||||||
|
"border-block-end-color", "border-block-end-style", "border-block-end-width",
|
||||||
|
"border-block-start", "border-block-start-color", "border-block-start-style",
|
||||||
|
"border-block-start-width", "border-block-style", "border-block-width",
|
||||||
|
"border-inline", "border-inline-color", "border-inline-end",
|
||||||
|
"border-inline-end-color", "border-inline-end-style",
|
||||||
|
"border-inline-end-width", "border-inline-start", "border-inline-start-color",
|
||||||
|
"border-inline-start-style", "border-inline-start-width",
|
||||||
|
"border-inline-style", "border-inline-width", "margin-block",
|
||||||
|
"margin-block-end", "margin-block-start", "margin-inline", "margin-inline-end",
|
||||||
|
"margin-inline-start", "padding-block", "padding-block-end",
|
||||||
|
"padding-block-start", "padding-inline", "padding-inline-end",
|
||||||
|
"padding-inline-start", "scroll-snap-stop", "scrollbar-3d-light-color",
|
||||||
"scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
|
"scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
|
||||||
"scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
|
"scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
|
||||||
"scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside",
|
"scrollbar-track-color", "searchfield-cancel-button", "searchfield-decoration",
|
||||||
"searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
|
"searchfield-results-button", "searchfield-results-decoration", "shape-inside", "zoom"
|
||||||
"searchfield-results-decoration", "zoom"
|
|
||||||
], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
|
], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
|
||||||
|
|
||||||
var fontProperties_ = [
|
var fontProperties_ = [
|
||||||
"font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
|
"font-display", "font-family", "src", "unicode-range", "font-variant",
|
||||||
"font-stretch", "font-weight", "font-style"
|
"font-feature-settings", "font-stretch", "font-weight", "font-style"
|
||||||
], fontProperties = keySet(fontProperties_);
|
], fontProperties = keySet(fontProperties_);
|
||||||
|
|
||||||
var counterDescriptors_ = [
|
var counterDescriptors_ = [
|
||||||
|
|
22
vendor/codemirror/mode/javascript/javascript.js
vendored
22
vendor/codemirror/mode/javascript/javascript.js
vendored
|
@ -98,10 +98,13 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||||
} else if (ch == "`") {
|
} else if (ch == "`") {
|
||||||
state.tokenize = tokenQuasi;
|
state.tokenize = tokenQuasi;
|
||||||
return tokenQuasi(stream, state);
|
return tokenQuasi(stream, state);
|
||||||
} else if (ch == "#") {
|
} else if (ch == "#" && stream.peek() == "!") {
|
||||||
stream.skipToEnd();
|
stream.skipToEnd();
|
||||||
return ret("error", "error");
|
return ret("meta", "meta");
|
||||||
} else if (ch == "<" && stream.match("!--") || ch == "-" && stream.match("->")) {
|
} else if (ch == "#" && stream.eatWhile(wordRE)) {
|
||||||
|
return ret("variable", "property")
|
||||||
|
} else if (ch == "<" && stream.match("!--") ||
|
||||||
|
(ch == "-" && stream.match("->") && !/\S/.test(stream.string.slice(0, stream.start)))) {
|
||||||
stream.skipToEnd()
|
stream.skipToEnd()
|
||||||
return ret("comment", "comment")
|
return ret("comment", "comment")
|
||||||
} else if (isOperatorChar.test(ch)) {
|
} else if (isOperatorChar.test(ch)) {
|
||||||
|
@ -113,6 +116,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||||
if (ch == ">") stream.eat(ch)
|
if (ch == ">") stream.eat(ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ch == "?" && stream.eat(".")) return ret(".")
|
||||||
return ret("operator", "operator", stream.current());
|
return ret("operator", "operator", stream.current());
|
||||||
} else if (wordRE.test(ch)) {
|
} else if (wordRE.test(ch)) {
|
||||||
stream.eatWhile(wordRE);
|
stream.eatWhile(wordRE);
|
||||||
|
@ -417,7 +421,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||||
}
|
}
|
||||||
function parenExpr(type) {
|
function parenExpr(type) {
|
||||||
if (type != "(") return pass()
|
if (type != "(") return pass()
|
||||||
return cont(pushlex(")"), expression, expect(")"), poplex)
|
return cont(pushlex(")"), maybeexpression, expect(")"), poplex)
|
||||||
}
|
}
|
||||||
function expressionInner(type, value, noComma) {
|
function expressionInner(type, value, noComma) {
|
||||||
if (cx.state.fatArrowAt == cx.stream.start) {
|
if (cx.state.fatArrowAt == cx.stream.start) {
|
||||||
|
@ -446,7 +450,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function maybeoperatorComma(type, value) {
|
function maybeoperatorComma(type, value) {
|
||||||
if (type == ",") return cont(expression);
|
if (type == ",") return cont(maybeexpression);
|
||||||
return maybeoperatorNoComma(type, value, false);
|
return maybeoperatorNoComma(type, value, false);
|
||||||
}
|
}
|
||||||
function maybeoperatorNoComma(type, value, noComma) {
|
function maybeoperatorNoComma(type, value, noComma) {
|
||||||
|
@ -455,7 +459,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||||
if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
|
if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
|
||||||
if (type == "operator") {
|
if (type == "operator") {
|
||||||
if (/\+\+|--/.test(value) || isTS && value == "!") return cont(me);
|
if (/\+\+|--/.test(value) || isTS && value == "!") return cont(me);
|
||||||
if (isTS && value == "<" && cx.stream.match(/^([^>]|<.*?>)*>\s*\(/, false))
|
if (isTS && value == "<" && cx.stream.match(/^([^<>]|<[^<>]*>)*>\s*\(/, false))
|
||||||
return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, me);
|
return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, me);
|
||||||
if (value == "?") return cont(expression, expect(":"), expr);
|
if (value == "?") return cont(expression, expect(":"), expr);
|
||||||
return cont(expr);
|
return cont(expr);
|
||||||
|
@ -757,11 +761,11 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||||
}
|
}
|
||||||
if (type == "variable" || cx.style == "keyword") {
|
if (type == "variable" || cx.style == "keyword") {
|
||||||
cx.marked = "property";
|
cx.marked = "property";
|
||||||
return cont(isTS ? classfield : functiondef, classBody);
|
return cont(classfield, classBody);
|
||||||
}
|
}
|
||||||
if (type == "number" || type == "string") return cont(isTS ? classfield : functiondef, classBody);
|
if (type == "number" || type == "string") return cont(classfield, classBody);
|
||||||
if (type == "[")
|
if (type == "[")
|
||||||
return cont(expression, maybetype, expect("]"), isTS ? classfield : functiondef, classBody)
|
return cont(expression, maybetype, expect("]"), classfield, classBody)
|
||||||
if (value == "*") {
|
if (value == "*") {
|
||||||
cx.marked = "keyword";
|
cx.marked = "keyword";
|
||||||
return cont(classBody);
|
return cont(classBody);
|
||||||
|
|
2
vendor/codemirror/mode/stylus/stylus.js
vendored
2
vendor/codemirror/mode/stylus/stylus.js
vendored
|
@ -76,7 +76,7 @@
|
||||||
if (ch == "#") {
|
if (ch == "#") {
|
||||||
stream.next();
|
stream.next();
|
||||||
// Hex color
|
// Hex color
|
||||||
if (stream.match(/^[0-9a-f]{3}([0-9a-f]([0-9a-f]{2}){0,2})?\b/i)) {
|
if (stream.match(/^[0-9a-f]{3}([0-9a-f]([0-9a-f]{2}){0,2})?\b(?!-)/i)) {
|
||||||
return ["atom", "atom"];
|
return ["atom", "atom"];
|
||||||
}
|
}
|
||||||
// ID selector
|
// ID selector
|
||||||
|
|
2
vendor/codemirror/theme/zenburn.css
vendored
2
vendor/codemirror/theme/zenburn.css
vendored
|
@ -11,7 +11,7 @@
|
||||||
.cm-s-zenburn .CodeMirror-gutters { background: #3f3f3f !important; }
|
.cm-s-zenburn .CodeMirror-gutters { background: #3f3f3f !important; }
|
||||||
.cm-s-zenburn .CodeMirror-foldgutter-open, .CodeMirror-foldgutter-folded { color: #999; }
|
.cm-s-zenburn .CodeMirror-foldgutter-open, .CodeMirror-foldgutter-folded { color: #999; }
|
||||||
.cm-s-zenburn .CodeMirror-cursor { border-left: 1px solid white; }
|
.cm-s-zenburn .CodeMirror-cursor { border-left: 1px solid white; }
|
||||||
.cm-s-zenburn { background-color: #3f3f3f; color: #dcdccc; }
|
.cm-s-zenburn.CodeMirror { background-color: #3f3f3f; color: #dcdccc; }
|
||||||
.cm-s-zenburn span.cm-builtin { color: #dcdccc; font-weight: bold; }
|
.cm-s-zenburn span.cm-builtin { color: #dcdccc; font-weight: bold; }
|
||||||
.cm-s-zenburn span.cm-comment { color: #7f9f7f; }
|
.cm-s-zenburn span.cm-comment { color: #7f9f7f; }
|
||||||
.cm-s-zenburn span.cm-keyword { color: #f0dfaf; font-weight: bold; }
|
.cm-s-zenburn span.cm-keyword { color: #f0dfaf; font-weight: bold; }
|
||||||
|
|
2
vendor/uuid/LICENSE
vendored
2
vendor/uuid/LICENSE
vendored
|
@ -1,6 +1,6 @@
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2010-2016 Robert Kieffer and other contributors
|
Copyright (c) 2010-2020 Robert Kieffer and other contributors
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
2
vendor/uuid/README.md
vendored
2
vendor/uuid/README.md
vendored
|
@ -1,4 +1,4 @@
|
||||||
## uuid v7.0.0-beta.0
|
## uuid v8.1.0
|
||||||
|
|
||||||
Following files are copied from npm (node_modules):
|
Following files are copied from npm (node_modules):
|
||||||
|
|
||||||
|
|
2
vendor/uuid/uuid.min.js
vendored
2
vendor/uuid/uuid.min.js
vendored
|
@ -1 +1 @@
|
||||||
!function(o,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(o=o||self).uuidv4=e()}(this,(function(){"use strict";var o="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof window.msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto),e=new Uint8Array(16);function r(){if(!o)throw new Error("uuid: This browser does not seem to support crypto.getRandomValues(). If you need to support this browser, please provide a custom random number generator through options.rng.");return o(e)}for(var n=[],t=0;t<256;++t)n[t]=(t+256).toString(16).substr(1);return function(o,e,t){var u=e&&t||0;"string"==typeof o&&(e="binary"===o?new Array(16):null,o=null);var i=(o=o||{}).random||(o.rng||r)();if(i[6]=15&i[6]|64,i[8]=63&i[8]|128,e)for(var s=0;s<16;++s)e[u+s]=i[s];return e||function(o,e){var r=e||0,t=n;return[t[o[r++]],t[o[r++]],t[o[r++]],t[o[r++]],"-",t[o[r++]],t[o[r++]],"-",t[o[r++]],t[o[r++]],"-",t[o[r++]],t[o[r++]],"-",t[o[r++]],t[o[r++]],t[o[r++]],t[o[r++]],t[o[r++]],t[o[r++]]].join("")}(i)}}));
|
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).uuidv4=e()}(this,(function(){"use strict";var t="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto),e=new Uint8Array(16);function n(){if(!t)throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return t(e)}for(var o=[],r=0;r<256;++r)o.push((r+256).toString(16).substr(1));return function(t,e,r){"string"==typeof t&&(e="binary"===t?new Uint8Array(16):null,t=null);var u=(t=t||{}).random||(t.rng||n)();if(u[6]=15&u[6]|64,u[8]=63&u[8]|128,e){for(var i=r||0,d=0;d<16;++d)e[i+d]=u[d];return e}return function(t,e){var n=e||0,r=o;return(r[t[n+0]]+r[t[n+1]]+r[t[n+2]]+r[t[n+3]]+"-"+r[t[n+4]]+r[t[n+5]]+"-"+r[t[n+6]]+r[t[n+7]]+"-"+r[t[n+8]]+r[t[n+9]]+"-"+r[t[n+10]]+r[t[n+11]]+r[t[n+12]]+r[t[n+13]]+r[t[n+14]]+r[t[n+15]]).toLowerCase()}(u)}}));
|
Loading…
Reference in New Issue
Block a user