Compare commits

..

242 Commits

Author SHA1 Message Date
tophf
fc39f0d5a6 parserlib: dot-separated layer names 2022-10-19 22:47:19 +03:00
tophf
1725c0ecb9 show installed styles in popup finder
fixes #1488
2022-10-12 20:04:45 +03:00
tophf
79dff2775b add upDownKeyJumps option, remove left/right 2022-10-08 13:07:57 +03:00
tophf
b22bbaaec0 make <iframe> more evident 2022-10-08 13:05:40 +03:00
tophf
fff59ee12f use a self-explanatory "..." in #write-for-frames 2022-09-17 21:42:39 +03:00
tophf
540e2af62c micro-optimize colorConverter.parse
#hex, named colors: 15x faster
rgb() and other functions: 1.6x faster
2022-09-17 20:10:18 +03:00
tophf
0128489bbb unbork rgb colors with % 2022-09-17 01:29:11 +03:00
dependabot[bot]
a5b11ac687
Bump node-forge and web-ext (#1474) 2022-09-16 16:24:27 +03:00
Rob Garrison
5d3a9dccf3 1.5.28 2022-09-16 08:11:25 -05:00
tophf
09691a6362 add a comment for USO devs 2022-09-16 15:33:11 +03:00
tophf
62987fe5f8 update locales 2022-09-16 12:47:55 +03:00
tophf
405a93f9e5 no need for fse dep here 2022-09-16 12:47:37 +03:00
tophf
da4bdc6821 API should return something 2022-09-16 12:40:14 +03:00
tophf
d1f5468a81 fix USO install button 2022-09-16 12:39:46 +03:00
tophf
efc6d09d49 properly show "no styles found" 2022-09-15 17:14:13 +03:00
tophf
0bb0d32c29 simplify fitNameColumn
as it wasn't using average and an average is too small anyway
2022-09-15 13:05:00 +03:00
tophf
f5397b8aec simplify hover highlight to an underline 2022-09-15 12:57:01 +03:00
tophf
1594b4dcd8 help auto-hyphenation at word boundaries 2022-09-15 12:54:26 +03:00
tophf
527d7c0fbc add fake header before linking to USW 2022-09-11 20:44:19 +03:00
tophf
cda606e7cc tall applies-to toggle + simplify CSS 2022-09-08 00:20:25 +03:00
tophf
5cb30c8b69 simplify oldUI CSS 2022-09-07 23:57:19 +03:00
tophf
1b914a397e simplify hover animation: 50% less CPU 2022-09-06 21:25:13 +03:00
tophf
7b64deeb37 create templates on demand 2022-09-06 18:41:22 +03:00
tophf
9398857d93 clear searchMode along with search 2022-09-06 01:07:14 +03:00
tophf
b45825c015 preserve current URL params in openManage 2022-09-06 00:54:52 +03:00
tophf
3aae3f181a linkify numbers in option labels 2022-09-05 23:08:03 +03:00
tophf
48d90544f6 reuse setInputValue 2022-09-05 22:41:17 +03:00
tophf
ef998e423e add multi-column mode option 2022-09-04 22:50:27 +03:00
tophf
6979958908 use localization cache 2022-09-04 22:50:26 +03:00
tophf
4236eb4e29 shorten highlight animation
...because it was invisible 90% of time anyway
2022-09-04 22:50:26 +03:00
tophf
c351413c3f show Size column + simplify sorter 2022-09-03 20:08:24 +03:00
tophf
d91cf11366 parserlib: update forced-color-adjust 2022-09-02 09:12:32 +03:00
tophf
e49644f1c8 CodeMirror 5.65.8 2022-09-01 11:35:37 +03:00
tophf
15b59ae207 update locales 2022-09-01 11:35:37 +03:00
tophf
ad43560016 fix and simplify applyScrollInfo 2022-09-01 11:35:24 +03:00
tophf
c423025c5d postpone lazyScripts more 2022-09-01 10:37:29 +03:00
tophf
030621462c error.stack has no message in FF 2022-09-01 10:30:46 +03:00
tophf
bf3dd0318d don't apply global section to Stylus pages
unless it was intentionally targeted via url(),  url-prefix(), or regexp(). The regexp must contain the word "extension" without quotes.
2022-08-31 16:27:31 +03:00
tophf
3489b513c9 [autocomplete] find LESS vars 2022-08-30 10:31:21 +03:00
Rob Garrison
984fa6e425 1.5.27 2022-08-29 17:07:09 -05:00
tophf
6110cbee68 use /* */ for line comments in less/stylus 2022-08-28 22:48:49 +03:00
tophf
40ec2c000f [autocomplete] use parserlib's list of CSS props 2022-08-27 21:58:29 +03:00
tophf
9022f6b318 [autocomplete] add ":" to LESS props 2022-08-27 21:58:28 +03:00
tophf
c5667b0352 hide lint errors for LESS vars 2022-08-27 21:58:27 +03:00
tophf
5379f62c90
add year selector in popup search (#1411) 2022-08-27 21:57:14 +03:00
Rob Garrison
9d3fa1c5f9 1.5.26 2022-08-06 17:48:47 -05:00
tophf
906a5ca960 use license from stylelint-bundle 2022-08-06 23:35:32 +03:00
tophf
e1e351d956 report network failures in build-vendor 2022-08-06 23:35:01 +03:00
tophf
7a5569e9d5 stylelint 14.9.1 2022-08-06 23:20:29 +03:00
tophf
2d21bb1dd6 generate separate zip for FF with options_ui 2022-08-05 18:35:16 +03:00
tophf
8302c50d54 remove the unused identity permission 2022-08-05 18:34:38 +03:00
dependabot[bot]
27a878aed8
Bump moment from 2.29.2 to 2.29.4 (#1463) 2022-08-05 17:56:52 +03:00
tophf
f9e6df116f update deps 2022-08-05 17:50:31 +03:00
tophf
a832b51d9c update locales 2022-08-05 17:41:08 +03:00
tophf
b88a978843 improve orphan check + cosmetics 2022-08-03 23:58:55 +03:00
tophf
685bf1fa3e
fix USO site installation (#1461) 2022-08-03 22:37:04 +03:00
tophf
6995483ec0 parserlib: cosmetics/simplifications 2022-08-03 22:35:01 +03:00
tophf
6ff5f17140 assume bg is ready if messaging succeeded 2022-08-03 22:20:41 +03:00
tophf
7a1045b45a keep valid url path chars intact 2022-07-30 20:48:43 +03:00
tophf
079e7e50f1 retry API on browser startup automatically 2022-07-25 19:28:25 +03:00
tophf
00b732177f speed up regex for block comments 2022-07-23 23:54:24 +03:00
tophf
484ff24950 parserlib: container query 2022-07-17 12:38:07 +03:00
tophf
31177f1017 parserlib: fix custom-ident and use it more 2022-07-17 12:38:07 +03:00
tophf
e406e2b5dc fetch all indexes before showing "not found" 2022-07-07 17:17:33 +03:00
tophf
bd2b435781 parserlib: simplify/flatten _keyframe 2022-07-01 10:29:43 +03:00
tophf
b742ed2c65 parserlib: forbid default in custom-ident 2022-07-01 10:26:46 +03:00
tophf
d68433c867 fix usage of chrome.windows in android 2022-07-01 07:55:11 +03:00
tophf
a10003ee80 parserlib: has() selector 2022-06-30 13:40:39 +03:00
tophf
3fcd4f8027 code cosmetics 2022-06-27 12:42:27 +03:00
tophf
9364ef585f
fix nextcloud WebDAV csrf error (#1448) 2022-06-27 12:41:39 +03:00
tophf
6e0cfb7d0f fix infinite loop in readUnknownSym 2022-06-26 18:13:13 +03:00
tophf
91501cce19 parserlib: simplified media query L4 2022-06-24 21:09:14 +03:00
tophf
95a4514f15 parserlib: object-overflow, object-view-box 2022-06-24 08:25:33 +03:00
tophf
3d6b55e53e error may be an object 2022-06-23 21:29:52 +03:00
tophf
88a0a3858c update locales 2022-06-23 21:21:56 +03:00
tophf
685ee625ee update codemirror 5.65.6 2022-06-23 21:21:56 +03:00
tophf
944a7f23ef update stylus-lang-bundle 0.58.1 2022-06-23 21:16:02 +03:00
tophf
d78329d295
add transifex languages info 2022-06-07 21:08:39 +03:00
tophf
b5fd8b63dc new Vivaldi uses vivExtData 2022-06-04 19:20:20 +03:00
tophf
a77996df60 window type may be 'app' 2022-06-04 18:02:41 +03:00
tophf
2e1961bdf7 messageBox.element is nulled in close() 2022-06-03 18:41:25 +03:00
tophf
cd88aff733 hide undefined label in colorpicker in FF 2022-06-02 21:52:49 +03:00
Rob Garrison
0f3ba30066 1.5.25 2022-05-31 12:11:33 -05:00
tophf
cda6e4fb9e recreate idb with missing stores 2022-05-31 16:08:03 +03:00
tophf
97520be9b2 create missing idb store 2022-05-31 15:32:01 +03:00
Rob Garrison
30af48a69a 1.5.24 2022-05-30 09:24:45 -05:00
Rob Garrison
b33b5ba624 Update locales 2022-05-30 09:11:47 -05:00
tophf
ad5c90e240 actually set INJECTED 2022-04-24 00:21:25 +03:00
tophf
3522a53ad4 limit section's height to viewport 2022-04-11 14:05:02 +03:00
tophf
79ada00a01 don't show reset-name on local classic styles 2022-04-11 09:57:38 +03:00
tophf
a34fe5f400 parserlib: add webkit-optimize-contrast 2022-04-09 09:00:08 +03:00
dependabot[bot]
ffb72cc656
Bump moment from 2.29.1 to 2.29.2 (#1424) 2022-04-09 08:59:30 +03:00
tophf
a74ae5ac4f extract popup search + show error + CtrlF 2022-04-05 13:49:48 +03:00
tophf
3907116328 getEventKeyName: uppercase for single letters 2022-04-05 13:46:37 +03:00
tophf
fd42f2d365 update icon on bfcache navigation 2022-04-04 10:11:41 +03:00
tophf
537372dffa colorpicker: add hwb colors 2022-04-04 09:52:01 +03:00
tophf
f54d145bf5 parserlib: add font-palette, hwb 2022-04-04 09:52:00 +03:00
tophf
2efb6c5cd1 strip source mapping from vendor js 2022-03-31 14:00:12 +03:00
tophf
ea388ea9a7 add [x] as usercss to write-style in popup 2022-03-31 12:27:11 +03:00
tophf
24aaf2fdb8
improve power-off switch (#1412)
* show it in manager/editor when active
* reflect the state in the label when active
2022-03-31 12:25:37 +03:00
tophf
963e58f237 unbork 57a7939b 2022-03-27 22:42:35 +03:00
tophf
57a7939b5e show livepreview error in compact mode 2022-03-27 18:47:52 +03:00
tophf
ec5a685ee2 limit details width in compact mode 2022-03-27 18:47:52 +03:00
dependabot[bot]
b21497c1b2
Bump minimist from 1.2.5 to 1.2.6 (#1420) 2022-03-26 09:12:05 +03:00
tophf
ba1f10b865 fix/simplify editor loader
fixes #1419
2022-03-24 17:52:26 +03:00
Rob Garrison
7ab95cce33 1.5.23 2022-03-19 17:15:43 -05:00
dependabot[bot]
0a84d802d3
Bump node-fetch from 2.6.6 to 2.6.7 (#1415) 2022-03-17 09:21:29 +03:00
dependabot[bot]
2c42f40acb
Bump nanoid from 3.1.30 to 3.3.1 (#1416) 2022-03-17 09:21:17 +03:00
tophf
ee0826e538 update CodeMirror 5.65.2 2022-03-17 09:18:59 +03:00
tophf
411d7f7b95 update locales 2022-03-17 09:18:04 +03:00
tophf
614dce0e8c transition patch is redundant in Chrome 93+ 2022-03-08 23:38:51 +03:00
tophf
619f771b4a strip www for greasyfork search 2022-03-07 01:49:14 +03:00
tophf
9ed550c882 fix popup find error 2022-03-06 03:02:41 +03:00
tophf
6d721fe7a5 actually hide invisible "?" favicons 2022-03-05 22:37:31 +03:00
tophf
d9ad0fec3c parserlib: new values for mix-blend-mode 2022-03-04 19:07:52 +03:00
tophf
d623aa679f properly update hash when closing UI, part 2
for the history log
2022-03-04 08:10:46 +03:00
tophf
9e009726c5 properly update hash when closing UI 2022-03-03 05:23:34 +03:00
tophf
bcc98d913b fix/simplify dom::collapsible
now it observes the `open` attribute as the `click` was too fragile due to dependency on timing
2022-03-02 02:54:25 +03:00
tophf
2e31cae71e instant match hl same as other editors
also enable it when the find dialog is open because selection may be different
2022-02-28 10:18:15 +03:00
tophf
b80c3e2f73 enable activeline highlight with selection 2022-02-28 10:15:11 +03:00
tophf
37baf8a2c6 reuse deepCopy 2022-02-26 10:32:58 +03:00
tophf
b4f10cb296 fix popup buttons in styles-last mode 2022-02-25 03:12:43 +03:00
tophf
8fc6c8bcde cosmetics 2022-02-25 01:26:50 +03:00
tophf
29cafd619c extract initBadFavs 2022-02-25 00:43:21 +03:00
tophf
bd9d51308a simplify context menu + shorten titles 2022-02-24 07:53:14 +03:00
tophf
d2a99b5be1 simplify getProxy 2022-02-24 07:29:11 +03:00
tophf
e567b6d56d use the public defaults 2022-02-24 07:29:11 +03:00
tophf
329d0caac1 avoid flicker/delay when opening manager 2022-02-23 09:07:30 +03:00
tophf
51e9b09f52 load favicons earlier + show bads as ? 2022-02-23 06:11:28 +03:00
tophf
f5b2fe2fc6 properly show another split-btn + tiny popup 2022-02-23 00:17:14 +03:00
tophf
38ac974d8a remember and skip bad favicons 2022-02-22 01:39:03 +03:00
tophf
5ff664f9b9 simplify/generalize close-on-esc 2022-02-21 23:45:42 +03:00
tophf
b75e2cb56b add @-moz-document indent to beautifier 2022-02-21 23:35:49 +03:00
tophf
d162928fb9 right-click to expand all applies-to targets 2022-02-21 07:12:11 +03:00
tophf
ce7137c54d preload nearby favicons 2022-02-21 07:11:09 +03:00
tophf
62974751ff limit disable-all area to its text 2022-02-21 03:18:12 +03:00
tophf
e0c9c13856 explicitly hyphenate domains in popup 2022-02-21 02:36:03 +03:00
tophf
6ff68aaa74 simplify conditional css in popup 2022-02-21 02:24:34 +03:00
tophf
bd0e8273c1 add USA/USW/US/GF splitter to Find styles 2022-02-21 02:01:50 +03:00
tophf
268c7b758b give history log a navigatable #hash 2022-02-20 19:57:11 +03:00
tophf
38ddf5d79d simplify and speed up init in manage/edit 2022-02-20 19:26:26 +03:00
tophf
90a71c0afc deflicker name element in new usercss 2022-02-20 18:34:51 +03:00
tophf
dd1f30e6aa fix popup regression on blocked page 2022-02-19 17:20:32 +03:00
tophf
b804e39de6 workaround for crbug.com/1288447 2022-02-19 17:20:26 +03:00
tophf
16f7e19915 attenuate dark scrollbar colors 2022-02-19 17:08:05 +03:00
tophf
ad969fca6a
simplify css/html in popup (#1408)
+ reuse global checkbox-wrapper more
2022-02-19 11:18:14 +03:00
tophf
9d64e9ba54 wait for real prefs on bg startup
+ convert msg.sendXXX to async
2022-02-19 10:05:47 +03:00
tophf
cc3c85be58 fix update when using embedded meta 2022-02-19 06:48:55 +03:00
tophf
f7bbfd6ead fix mozdoc widget when duplicating section 2022-02-18 22:29:02 +03:00
tophf
dff0c133b4 hide 'manage site styles' if blocked 2022-02-18 08:02:47 +03:00
tophf
1364d3a8ba add colorScheme.isDark() 2022-02-18 06:03:52 +03:00
tophf
bef70f6db3 fix light mode in dark system, properly 2022-02-18 04:40:23 +03:00
tophf
77562ecd8d fix light mode in dark system 2022-02-18 04:35:36 +03:00
tophf
9fbf641571 fix some colors in dark theme 2022-02-18 03:59:00 +03:00
tophf
a58af7f816 speed up and simplify i18n 2022-02-18 03:49:16 +03:00
tophf
8d3e01e05a
shuffle and tidy up options (#1406)
* move updates/sync to the top, theme to the bottom
* remove font override
* replace 'Back to manage' with 'Close'
* add a note for the built-in shortcuts UI in FF
- update button
+ confirm reset
* one button to connect/disconnect
* shorten ids
* simplify/extract sync js
* reuse :invalid style
2022-02-18 03:47:22 +03:00
tophf
c9b8593830 fix setupLivePrefs regression 2022-02-17 19:51:58 +03:00
tophf
6fb2727f6b restore button's svg color in light mode 2022-02-17 03:35:51 +03:00
tophf
1721bad7d8 reuse radio-wrapper for visual uniformity 2022-02-17 03:26:20 +03:00
tophf
944c44ffb8 use default sorter pref for resiliency 2022-02-17 03:12:11 +03:00
tophf
adef93c3ed speed up setupLivePrefs 2022-02-17 03:12:11 +03:00
tophf
b7cfbe6e66
use color palette and enable a simple dark theme (#1405)
* add 'auto' iconset and use it by default
* expose `data-ui-theme` on html

Co-authored-by: narcolepticinsomniac <therealdoctorgonzo@gmail.com>
2022-02-17 03:10:59 +03:00
tophf
dd38856eda
scrollable details + sticky header (#1400)
* shorten section labels in lint report
* `sectioned` class on html for sectioned editor
* fix scrollElementIntoView
2022-02-14 22:19:20 +03:00
tophf
225a2cec31 unbork installer, regressed in 81a5acfd 2022-02-13 16:19:58 +03:00
tophf
2e021f6ac9 preserve style element name during livePreview
also strip _ from methods as we don't use such convention
2022-02-13 04:36:33 +03:00
tophf
fcad0ee523 avoid double handling of keyboard event in rerouter
...and thus fix the bug with restoring keyboard focus to codemirror when closing color picker
2022-02-12 21:31:35 +03:00
tophf
f9a2b9de35 fix/simplify i18n in templates
fix: double-translation, regressed in cc7eba9
2022-02-12 01:44:52 +03:00
tophf
648b295ef2 parserlib: handle layer statements anywhere 2022-02-12 01:18:03 +03:00
tophf
81a5acfda3 .user.css in virtual style urls
benefits:
* styles are listed directly under `Stylus` in devtools source file tree
* easy to differentiate from site's css
2022-02-11 00:08:20 +03:00
tophf
10de02f04d
expose style name (#1403) 2022-02-10 21:28:47 +03:00
tophf
b86cb6a36c reuse standard style of applies-to in usercss
+ shorten the Test button label
2022-02-10 21:25:09 +03:00
tophf
290a0f99d2 keep internal tooltips in js 2022-02-10 21:09:49 +03:00
tophf
ae6f7024ce identify by UUID when importing 2022-02-10 09:53:02 +03:00
tophf
de5eb32d2d update locales 2022-02-09 05:03:47 +03:00
tophf
c29048c366 parserlib: units L4, scrollbar-gutter 2022-02-08 15:13:35 +03:00
tophf
6b87f7840f parserlib: text-emphasis-color 2022-02-04 13:26:47 +03:00
tophf
421526d60b parserlib: cascade layers
+ simplify Parser.ACTIONS
2022-02-04 02:28:29 +03:00
tophf
9b0db09b6c
use hardcoded redirect_uri fallback (#1399) 2022-02-03 13:06:29 +03:00
tophf
bab1ba17a9 use standard web cursor for controls in options
+ increase clickable area of (i) notes
2022-02-02 13:46:55 +03:00
tophf
50da5f1966 intercept click on a note properly
regressed in cc7eba97
2022-02-02 13:38:05 +03:00
tophf
2e2c6765b5
keep router buffer on tab reload (#1393) 2022-01-31 17:27:58 +03:00
tophf
b2bc18c3d5 restore usercss section numbering and applies-to gaps
regressed in f9e11f58
2022-01-31 01:27:30 +03:00
tophf
84f4262176 fix rmDir deprecation warning 2022-01-30 14:23:02 +03:00
tophf
799423629a use standard cursor for svg inside buttons 2022-01-30 05:51:09 +03:00
tophf
f282623ef7
fix split-btn with popup.stylesFirst (#1394) 2022-01-30 05:50:13 +03:00
tophf
513ced6d57 lazy-load favicons 2022-01-29 18:53:49 +03:00
tophf
d048c480c3 require FF >= 55 2022-01-29 18:19:21 +03:00
tophf
f966b2ef96 allow non-object values in db 2022-01-29 16:39:30 +03:00
tophf
c597303692 skip deleted styles in order 2022-01-29 03:41:47 +03:00
tophf
26b75e77b3
separate storage for order + important styles (#1390)
* use Proxy for `db`
* don't merge arrays in deepMerge by default
* extract sync and cache from styleMan
2022-01-29 02:54:56 +03:00
tophf
46785b0550 use pageshow/pagehide events
...to avoid DOM update/scroll on switching tabs
2022-01-29 02:46:12 +03:00
tophf
554d121c45 remove duplicate toggleDataset call 2022-01-29 00:32:11 +03:00
tophf
f9e11f5806
align 'Applies-to' and actions (#1392) 2022-01-28 15:52:55 +03:00
tophf
5529cbec2b fix and simplify editDeleteText context menu
* enable it on inputs added by the user later
* enable it in all of our pages
2022-01-28 03:11:25 +03:00
tophf
5253c863b9 remove the unused collapsible from options 2022-01-27 15:27:10 +03:00
tophf
60834f7bd6 check userAgentData when available 2022-01-27 15:21:02 +03:00
tophf
8afab0eaeb fix first click on regexp tester 2022-01-27 06:03:37 +03:00
tophf
4c4a319b33 use duckduckgo favicons 2022-01-27 05:10:17 +03:00
tophf
ea7c26ce71 toLoad is always an array 2022-01-26 14:53:17 +03:00
tophf
f740686cb5 fix icon when opening an unstyled Options frame
...and the containing page is styled
2022-01-24 22:49:27 +03:00
tophf
e54178a43c
draft recovery in editor (#1388)
+ use toolbox::clamp() more
2022-01-23 12:44:25 +03:00
tophf
60f59e9f06 fix split button [re]activation 2022-01-22 22:21:14 +03:00
tophf
0e31557748 show a button to reset the template 2022-01-22 12:29:35 +03:00
tophf
45eeedbe97 strip only dummy sections from the template 2022-01-22 12:06:57 +03:00
tophf
b4b135826c use css borders for split button triangle 2022-01-22 12:06:29 +03:00
tophf
ce9e74e2a0 add per-style setting for autoupdate checks 2022-01-21 19:45:56 +03:00
tophf
f041f2265a fix $ for detached nodes 2022-01-21 19:45:56 +03:00
tophf
98da86f816 update CodeMirror, stylelint, deps 2022-01-20 17:43:31 +03:00
tophf
4c696fefbc show search results for the faster index first
+ refresh after the slower index is downloaded
+ use an existing `f` instead of `isUsw`
2022-01-20 00:45:51 +03:00
tophf
6a07ad0f56 split button for manage::export, popup::manage 2022-01-19 16:13:53 +03:00
tophf
b692cf9608 show source code in build error when updating
fixes #891
2022-01-19 14:46:09 +03:00
tophf
be43bf3f23 force no-cache in update checker 2022-01-19 14:46:08 +03:00
tophf
cc7eba979e
save-as-template button in editor (#1385)
+ keep i18n attributes to use them as CSS selectors
+ reduce flicker when creating a new style
+ split button
2022-01-19 14:45:45 +03:00
tophf
594ca3520c
actually use the global font everywhere (#1384) 2022-01-19 00:25:11 +03:00
tophf
42d6e2f2af parserlib: reimplement d9a80623 properly 2022-01-18 20:24:41 +03:00
tophf
f7729eac15 remove unused files 2022-01-18 17:23:51 +03:00
tophf
0705392fb2
fix/deduplicate/simplify installer html/css/js (#1383) 2022-01-18 16:39:33 +03:00
tophf
936f5b40d2 pixel-align (i) icon 2022-01-18 01:10:45 +03:00
tophf
9136631bc6 manager: trivial alignments
* removed `Filters` left shift
* removed inadvertent extra padding in compact mode
* fixed `Backup` label in verbose languages
* flexible width of header blocks in compact mode
2022-01-18 01:10:45 +03:00
tophf
14e0a418bf create URL fallback only when necessary 2022-01-18 01:10:45 +03:00
tophf
12eb243610 replace installer if another file is drag'n'dropped 2022-01-16 20:22:42 +03:00
tophf
956b60e1ef fix header width when maximizing initially small window 2022-01-16 15:45:55 +03:00
tophf
0c20ef5d17 refactor a complex ternary 2022-01-14 18:47:09 +03:00
eight
ddc09f3511
Add: a draggable list to customize injection order (#1364)
+ implement messageBox.close()
+ fix require() with root urls in /dir/page.html
+ limit messageBox focus shift to config-dialog
+ flatten vendor dirs and simplify build-vendor:
  + replace the unicode symbol with ASCII `->`
  + flatten dirs by default to simplify writing the rules and improve their readability
  + rename and sort functions in the order they run
  + use `node-fetch` instead of the gargantuan `make-fetch-happen`
  + use `glob` which is already installed by other deps

Co-authored-by: tophf <tophf@gmx.com>
2022-01-14 15:44:48 +03:00
tophf
8ddeef221b
resizable header panel (#1378) 2022-01-13 12:47:37 +03:00
tophf
cce483dd22 update locales 2022-01-12 01:30:46 +03:00
tophf
d9a80623e1 parserlib: fix endless loop on incomplete tokens
regressed in 048c2672
fixes #1381
2022-01-11 21:18:37 +03:00
tophf
ca5402136d removed an unused string 2022-01-11 12:21:44 +03:00
tophf
5791ae7b05 removed an unused duplicate string 2022-01-11 11:46:20 +03:00
tophf
68dc584749 deduplicate editor.useSavedStyle
...and call it when saving in sectioned editor (regressed in ba9d904c)
2022-01-10 21:31:15 +03:00
tophf
6e4fc3236e confirm reload in sectioned editor 2022-01-10 19:12:29 +03:00
tophf
ba9d904ccc don't rebuild editor DOM on save, fixes #1380 2022-01-10 17:57:46 +03:00
tophf
51e56110e8 parserlib: color-scheme, scrollbar-gutter, transforms 2022-01-10 07:32:02 +03:00
tophf
906508832b
show style settings in a dialog (#1374)
+ simplify css/html
+ save button and autosave checkbox just like in config-dialog
+ generalize can-close-on-esc
+ add `props` parameter to helpPopup.show
+ deduplicate usage of #help-popup id
+ uniform padding in popups
+ disambiguate style settings from editor options
2021-12-29 22:57:22 +03:00
tophf
8128100cef ensure editor window is visible
fixes #1375
2021-12-26 19:35:13 +03:00
tophf
6afb4dc634 fix toggling of newline in beautifier dialog 2021-12-25 22:17:35 +03:00
tophf
440395db9f export in compat mode on shift-click/right-click 2021-12-25 18:05:29 +03:00
tophf
3cdf526fa3
don't export redundant values (#1373)
+ implement proper check for same code in usercss so unchanged styles won't be unnecessarily imported
2021-12-25 13:08:38 +03:00
tophf
6b9cdf2bc2 extend drop zone to viewport in Chrome too 2021-12-22 20:05:42 +03:00
tophf
249196d414 don't add _usw to all styles 2021-12-22 19:49:21 +03:00
tophf
0ac01d2e22
add a callstack to errors in browser and msg (#1369) 2021-12-16 20:21:02 +03:00
eight
9d2854c272
Fix: compatibility with kiwi (#1368) 2021-12-16 16:04:22 +03:00
370 changed files with 20403 additions and 23674 deletions

View File

@ -1,22 +0,0 @@
[
"node_modules/codemirror/addon/comment/comment.js",
"node_modules/codemirror/addon/dialog/dialog.js",
"node_modules/codemirror/addon/edit/closebrackets.js",
"node_modules/codemirror/addon/edit/matchbrackets.js",
"node_modules/codemirror/addon/fold/brace-fold.js",
"node_modules/codemirror/addon/fold/comment-fold.js",
"node_modules/codemirror/addon/fold/foldcode.js",
"node_modules/codemirror/addon/fold/foldgutter.js",
"node_modules/codemirror/addon/fold/indent-fold.js",
"node_modules/codemirror/addon/hint/css-hint.js",
"node_modules/codemirror/addon/hint/show-hint.js",
"node_modules/codemirror/addon/lint/lint.js",
"node_modules/codemirror/addon/scroll/annotatescrollbar.js",
"node_modules/codemirror/addon/search/matchesonscrollbar.js",
"node_modules/codemirror/addon/search/searchcursor.js",
"node_modules/codemirror/addon/selection/active-line.js",
"node_modules/codemirror/keymap/sublime.js",
"node_modules/codemirror/lib/codemirror.js",
"node_modules/codemirror/mode/css/css.js",
"node_modules/codemirror/mode/stylus/stylus.js"
]

2
.eslintignore Normal file
View File

@ -0,0 +1,2 @@
vendor/
vendor-overwrites/

View File

@ -238,7 +238,3 @@ overrides:
- files: ["**/*worker*.js"]
env:
worker: true
- files: ["**/*.mjs"]
parserOptions:
sourceType: module

View File

@ -24,6 +24,9 @@ If not, then provide details describing which page the feature will effect, e.g.
## Adding translations
You can help us translate the extension on [Transifex](https://www.transifex.com/github-7/Stylus).
Only the languages supported by the web store are allowed:
https://developer.chrome.com/docs/webstore/i18n/#localeTable
## Pull requests

12
.gitignore vendored
View File

@ -1,10 +1,8 @@
.DS_Store
pull_locales_login.rb
.vscode
node_modules/
yarn.lock
*.zip
*.log
*.swp
.DS_Store
.eslintcache
.transifexrc
.vscode
desktop.ini
node_modules/
yarn.lock

View File

@ -2,9 +2,9 @@
host = https://www.transifex.com
[Stylus.messages]
file_filter = dist/_locales/<lang>/messages.json
file_filter = _locales/<lang>/messages.json
minimum_perc = 0
source_file = dist/_locales/en/messages.json
source_file = _locales/en/messages.json
source_lang = en_US
type = CHROME

View File

@ -50,7 +50,7 @@ Copyright &copy; 2005-2014 [Jason Barnabe](jason.barnabe@gmail.com)
Current Stylus:
Copyright &copy; 2017-2019 [Stylus Team](https://github.com/openstyles/stylus/graphs/contributors)
Copyright &copy; 2017-2022 [Stylus Team](https://github.com/openstyles/stylus/graphs/contributors)
**[GNU GPLv3](./LICENSE)**

View File

@ -58,6 +58,12 @@
"checkingForUpdate": {
"message": "جارٍ البحث..."
},
"confirmDelete": {
"message": "حذف"
},
"confirmSave": {
"message": "حفظ"
},
"deleteStyleConfirm": {
"message": "هل تريد بالتأكيد حذف هذا النمط؟"
},
@ -70,6 +76,9 @@
"disableStyleLabel": {
"message": "تعطيل"
},
"editDeleteText": {
"message": "حذف"
},
"editStyleHeading": {
"message": "تعديل النمط"
},
@ -87,8 +96,11 @@
"enableStyleLabel": {
"message": "تمكين"
},
"findStylesForSite": {
"message": "البحث عن المزيد من الأنماط لموقع الويب هذا"
"genericAdd": {
"message": "إضافة"
},
"genericEnabledLabel": {
"message": "ممكّن"
},
"helpAlt": {
"message": "مساعدة"
@ -105,6 +117,9 @@
"openManage": {
"message": "إدارة الأنماط المثبتة"
},
"optionsSyncUrl": {
"message": "عنوان URL"
},
"sectionAdd": {
"message": "إضافة قسم آخر"
},
@ -114,6 +129,9 @@
"sectionRemove": {
"message": "إزالة القسم"
},
"sections": {
"message": "الأقسام"
},
"styleCancelEditLabel": {
"message": "رجوع للإدارة"
},

View File

@ -52,9 +52,6 @@
"backupButtons": {
"message": "Резервни копия"
},
"backupMessage": {
"message": "Изберете файл или го влачете до страницата."
},
"bckpInstStyles": {
"message": "Изнасяне на стилове"
},
@ -115,6 +112,9 @@
"confirmOK": {
"message": "Добре"
},
"confirmSave": {
"message": "Запазване"
},
"confirmStop": {
"message": "Спиране"
},
@ -171,12 +171,15 @@
"exportLabel": {
"message": "Изнасяне"
},
"findStylesForSite": {
"message": "Още стилове за този сайт"
"genericAdd": {
"message": "Добавяне"
},
"genericDisabledLabel": {
"message": "Изключено"
},
"genericEnabledLabel": {
"message": "Включено"
},
"genericHistoryLabel": {
"message": "Хронология"
},
@ -260,9 +263,6 @@
"manageFaviconsGray": {
"message": "Сиви"
},
"manageFaviconsHelp": {
"message": "Разширението използва външна услуга https://www.google.com/s2/favicons"
},
"manageFilters": {
"message": "Филтри"
},
@ -299,6 +299,9 @@
"openManage": {
"message": "Управление"
},
"openOptions": {
"message": "Настройки"
},
"openStylesManager": {
"message": "Управление на стиловете"
},
@ -365,6 +368,9 @@
"optionsSubheading": {
"message": "Още настройки"
},
"optionsSyncUrl": {
"message": "Адрес"
},
"optionsUpdateImportNote": {
"message": "При внасянето на резервни копия от стари версии или от Стайлиш направете ръчна проверка за обновления, за да сте сигурни, че стиловете са актуални."
},
@ -401,6 +407,9 @@
"sectionRemove": {
"message": "Премахване на отдела"
},
"sections": {
"message": "Отдели"
},
"shortcuts": {
"message": "Клавишни комбинации"
},
@ -454,9 +463,6 @@
"styleRegexpProblemTooltip": {
"message": "Брой на неприложените отдели поради неправилно използване на регулярни изрази"
},
"styleRegexpTestButton": {
"message": "Тест на регулярния израз"
},
"styleRegexpTestFull": {
"message": "Съвпадащи подпрозорци"
},

View File

@ -67,9 +67,6 @@
"backupButtons": {
"message": "Zálohovat"
},
"backupMessage": {
"message": "Vyberte soubor nebo ho přetáhněte na tuto stránku."
},
"bckpInstStyles": {
"message": "Exportovat styly"
},
@ -275,15 +272,6 @@
"findStyles": {
"message": "Najít styly"
},
"findStylesForSite": {
"message": "Najít styly pro tento web"
},
"findStylesInline": {
"message": "Zobrazit zde"
},
"findStylesInlineTooltip": {
"message": "Zobrazit výsledky vyhledávání v tomto okně."
},
"genericAdd": {
"message": "Přidat"
},
@ -473,7 +461,7 @@
"message": "Zešednutí"
},
"manageFaviconsHelp": {
"message": "Stylus používá externí službu https://www.google.com/s2/favicons"
"message": "Stylus používá externí službu https://icons.duckduckgo.com"
},
"manageFilters": {
"message": "Filtry"
@ -517,6 +505,9 @@
"menuShowBadge": {
"message": "Zobrazit počet aktivních stylů"
},
"meta_invalidCheckboxDefault": {
"message": "Neplatný @var checkbox: hodnota musí být 0 nebo 1"
},
"meta_invalidNumber": {
"message": "Očekáváno číslo"
},
@ -562,6 +553,9 @@
"openManage": {
"message": "Spravovat"
},
"openOptions": {
"message": "Možnosti"
},
"openStylesManager": {
"message": "Otevřít správce stylů"
},
@ -631,6 +625,9 @@
"optionsSubheading": {
"message": "Další možnosti"
},
"optionsSyncUrl": {
"message": "URL adresa"
},
"optionsUpdateImportNote": {
"message": "Importujete-li zálohy stylů ze starší verze nebo z rozšíření Stylish, proveďte jednorázovou ruční kontrolu aktualizací ve správci stylů, aby byly všechny styly aktuální."
},
@ -745,6 +742,9 @@
"sectionRestore": {
"message": "Obnovit odstraněnou sekci"
},
"sections": {
"message": "Sekce"
},
"shortcuts": {
"message": "Zkratky"
},
@ -844,9 +844,6 @@
"styleRegexpProblemTooltip": {
"message": "Počet sekcí nepoužitých kvůli nesprávnému použití „regexp()“"
},
"styleRegexpTestButton": {
"message": "Otestovat RegExp"
},
"styleRegexpTestFull": {
"message": "Odpovídající listy"
},
@ -915,6 +912,9 @@
"unreachableFileHint": {
"message": "Stylus může přistupovat k file:// URL pouze při povolení odpovídající možnosti pro rozšíření Stylus ve správci chrome://extensions."
},
"unreachableMozSiteHintOldFF": {
"message": "Pouze Firefox 59 a novější může být nakonfigurován tak, aby rozšíření typu WebExtensions mohla přidávat styly na stránky chráněné CSP (Content Security Policy) jako je tato."
},
"unzipStyles": {
"message": "Rozbalování stylů…"
},
@ -974,9 +974,6 @@
"usercssReplaceTemplateConfirmation": {
"message": "Nahradit výchozí šablonu pro nové Usercss styly aktuálním kódem?"
},
"usercssReplaceTemplateName": {
"message": "Prázdné @name nahrazuje výchozí šablonu"
},
"usercssReplaceTemplateSectionBody": {
"message": "Sem vložte kód…"
},

View File

@ -58,9 +58,6 @@
"author": {
"message": "Forfatter"
},
"backupMessage": {
"message": "Vælg en fil eller træk og slip til denne side."
},
"bckpInstStyles": {
"message": "Eksportér stil"
},
@ -96,5 +93,8 @@
},
"cm_keyMap": {
"message": "Tastegenveje"
},
"genericAdd": {
"message": "Tilføj"
}
}

View File

@ -68,7 +68,7 @@
"message": "Datensicherung"
},
"backupMessage": {
"message": "Wähle eine Datei aus oder ziehe die Datei auf diese Seite. (Drag and Drop)"
"message": "Um die Backupdatei zu importieren, ziehe sie in diese Seite oder klicke auf die Import-Schaltfläche.\n\nZum Exportieren einer mit Stylus 1.5.18 (und älter) kompatiblen Backupdatei, rechtsklicke oder Shift-klicke auf die Export-Schaltfläche."
},
"bckpInstStyles": {
"message": "Styles exportieren"
@ -223,9 +223,23 @@
"disableAllStyles": {
"message": "Alle Styles deaktivieren"
},
"disableAllStylesOff": {
"message": "Styles sind ausgeschaltet"
},
"disableStyleLabel": {
"message": "Deaktivieren"
},
"draftAction": {
"message": "Wähle \"Ja\", um diesen Entwurf zu laden oder \"Nein\", um ihn zu verwerfen."
},
"draftTitle": {
"message": "Wiederherstellung ungespeicherter Entwürfe, erstellt vor $date$",
"placeholders": {
"date": {
"content": "$1"
}
}
},
"dragDropMessage": {
"message": "Ziehe die Backup Datei zum importieren an irgendeinen Ort auf dieser Seite."
},
@ -252,6 +266,9 @@
}
}
},
"editorSettings": {
"message": "Editor Einstellungen"
},
"enableStyleLabel": {
"message": "Aktivieren"
},
@ -261,6 +278,9 @@
"excludeStyleByUrlLabel": {
"message": "Aktuelle URL ausschließen"
},
"exportCompatible": {
"message": "Exportieren (Kompatibilitätsmodus)"
},
"exportLabel": {
"message": "Exportieren"
},
@ -293,15 +313,6 @@
"findStyles": {
"message": "Styles finden"
},
"findStylesForSite": {
"message": "Weitere Styles für diese Seite finden"
},
"findStylesInline": {
"message": "Ergebnisse hier anzeigen"
},
"findStylesInlineTooltip": {
"message": "Suchergebnisse in diesem Fenster anzeigen."
},
"genericAdd": {
"message": "Hinzufügen"
},
@ -335,6 +346,9 @@
"genericSavedMessage": {
"message": "Gespeichert"
},
"genericSize": {
"message": "Größe"
},
"genericTitle": {
"message": "Name"
},
@ -344,6 +358,9 @@
"gettingStyles": {
"message": "Empfange alle Styles..."
},
"headerResizerHint": {
"message": "Halte Shift gedrückt, um nur diese Art der Benutzeroberfläche (z.B. Editor, Manager, Installer) zu verändern"
},
"helpAlt": {
"message": "Hilfe"
},
@ -518,7 +535,7 @@
"message": "Ausgegraut"
},
"manageFaviconsHelp": {
"message": "Stylus nutzt hierzu den externen Dienst https://www.google.com/s2/favicons"
"message": "Stylus nutzt hierzu den externen Dienst https://icons.duckduckgo.com"
},
"manageFilters": {
"message": "Filter"
@ -529,6 +546,9 @@
"manageMaxTargets": {
"message": "Anzahl der \"Gilt für\" Elemente"
},
"manageMinColumnWidth": {
"message": "Minimale Spaltenbreite (in Pixeln. 9999 deaktiviert den Mehrspalten-Modus)"
},
"manageNewStyleAsUsercss": {
"message": "als UserCSS"
},
@ -778,6 +798,15 @@
"optionsAdvanced": {
"message": "Erweitert"
},
"optionsAdvancedAutoSwitchSchemeBySystem": {
"message": "Nach Systemeinstellung"
},
"optionsAdvancedAutoSwitchSchemeByTime": {
"message": "Bei Nacht:"
},
"optionsAdvancedAutoSwitchSchemeNever": {
"message": "Deaktiviert. Die hell / dunkel Einstellung in Styles wird ignoriert."
},
"optionsAdvancedContextDelete": {
"message": "\"Löschen\" im Editor-Kontextmenü hinzufügen"
},
@ -787,11 +816,17 @@
"optionsAdvancedExposeIframesNote": {
"message": "Style wirkt sich auch auf iframes der anvisierten (obersten) Domain aus.\nIframe-spezifisches CSS ist dann wie folgt möglich:\nhtml[stylus-iframe$$=\"twitter.com\"] h1 { display:none }"
},
"optionsAdvancedExposeStyleName": {
"message": "Stylename anzeigen"
},
"optionsAdvancedExposeStyleNameNote": {
"message": "Zeigt den Stylenamen auf der Seite an, um das Debuggen von Styles in den Devtools zu erleichtern. Bitte lade die Tabs neu, um die neue Einstellung zu übernehmen."
},
"optionsAdvancedNewStyleAsUsercss": {
"message": "Schreibe neuen Style als UserCSS"
},
"optionsAdvancedPatchCsp": {
"message": "<code>CSP</code>abändern, um externe Ressourcen zu erlauben"
"message": "<code>CSP</code> abändern, um externe Ressourcen zu erlauben"
},
"optionsAdvancedPatchCspNote": {
"message": "Aktivieren, wenn Styles Bilder oder Schriftarten enthalten, die aufgrund strenger <code>CSP</code> (<code>Content-Security-Policy</code>) Regeln mancher Seiten nicht laden.\n\nDas Aktivieren wird <code>CSP</code>Beschränkungen lockern, um für den Style erforderliche Ressourcen zu laden. Diese Option ist für fortgeschrittene Benutzer gedacht, die sich den möglichen Sicherheitsrisiken bewusst sind und die die Verantwortung dafür tragen, die nachgeladenen Inhalte selbst zu überwachen. Informiere dich über \"CSS-basierte Angriffe\" um mehr zu erfahren.\n\nBeachte außerdem, dass diese Option nicht garantiert funktioniert, falls eine andere installierte Erweiterung die Netzwerkantwort (CSP-header) zuerst abändert."
@ -826,6 +861,9 @@
"optionsHeading": {
"message": "Optionen"
},
"optionsIconAuto": {
"message": "An Hell- / Dunkelmodus angleichen"
},
"optionsIconDark": {
"message": "Dunkle Browser-Themes"
},
@ -848,7 +886,7 @@
"message": "Optionen zurücksetzen"
},
"optionsStylusThemes": {
"message": "Stylus UI-Theme suchen"
"message": "Klicke auf einer beliebigen Stylus Seite auf das Stylus-Symbol in der Werkzeugleiste des Browsers, dann klicke auf \"Styles finden\""
},
"optionsSubheading": {
"message": "Mehr Optionen"
@ -865,6 +903,9 @@
"optionsSyncNone": {
"message": "Nichts"
},
"optionsSyncPassword": {
"message": "Passwort"
},
"optionsSyncStatusConnected": {
"message": "Verbunden"
},
@ -908,6 +949,9 @@
"optionsSyncSyncNow": {
"message": "Jetzt synchronisieren"
},
"optionsSyncUsername": {
"message": "Benutzername"
},
"optionsUpdateImportNote": {
"message": "Nach dem Importieren von Styles aus einer alten Version oder von Stylish ist eine einmalige manuelle Updatesuche in der Verwaltung nötig. Dies stellt sicher, dass alle Styles auf dem aktuellsten Stand sind."
},
@ -950,6 +994,9 @@
"popupHotkeysTooltip": {
"message": "Klicke, um Tastenkürzel zu sehen"
},
"popupManageSiteStyles": {
"message": "Styles dieser Seite verwalten"
},
"popupManageTooltip": {
"message": "Shift+Klick oder Rechtsklick öffnet den Stylemanager mit Filter für Styles der aktuellen Seite"
},
@ -971,6 +1018,21 @@
"prefShowBadge": {
"message": "Anzahl der aktiven Styles auf der aktuellen Seite"
},
"preferScheme": {
"message": "Hell- / Dunkelmodus Vorrang"
},
"preferSchemeAlways": {
"message": "Derzeit ignoriert (Style wird immer angewendet), weil der allgemeine Hell- / Dunkelmodus nicht aktiv ist"
},
"preferSchemeDark": {
"message": "Dunkel"
},
"preferSchemeLight": {
"message": "Hell"
},
"preferSchemeNone": {
"message": "Keines (immer aktiv)"
},
"previewLabel": {
"message": "Echtzeitvorschau"
},
@ -999,7 +1061,7 @@
"message": "Lese Styles..."
},
"reload": {
"message": "Stylus Addon neu laden"
"message": "Neu laden"
},
"replace": {
"message": "Ersetzen"
@ -1010,9 +1072,15 @@
"replaceWith": {
"message": "Ersetzen durch"
},
"restoreTemplate": {
"message": "Standard-Template wiederherstellen.\n\n(Die gerade geöffneten Editorseiten werden nicht verändert.)"
},
"retrieveBckp": {
"message": "Styles importieren"
},
"saveAsTemplate": {
"message": "Als Template speichern"
},
"search": {
"message": "Suche"
},
@ -1053,7 +1121,7 @@
"message": "Wöchentliche Installationen"
},
"searchStyleQueryHint": {
"message": "Stylenamen ohne Beachtung der Groß-/Kleinschreibung suchen:\nMehrere Suchworte - alle Wörter in beliebiger Reihenfolge\n\"Bestimmte Phrase\" - genau diese Phrase ohne Anführungszeichen\n2020 - zeigt auch Styles, die 2020 aktualisiert wurden"
"message": "Stylenamen durchsuchen (Groß-Kleinschreibung wird beachtet, sobald ein Großbuchstabe benutzt wird):\nHaus Baum Sonne - sucht nach allen Wörtern in beliebiger Reihenfolge\n\"Baum Haus\" - sucht exakt diesen Ausdruck (ohne Anführungszeichen)\n/foo.*bar/i - Regulärer Ausdruck ohne Leerzeichen (nutze stattdessen \\s)"
},
"searchStylesAll": {
"message": "Alles"
@ -1082,12 +1150,18 @@
"sections": {
"message": "Bereiche"
},
"settings": {
"message": "Einstellungen"
},
"shortcuts": {
"message": "Tastenkürzel"
},
"shortcutsNote": {
"message": "Eine Tastenkombination definieren"
},
"shortcutsNoteFF": {
"message": "In Firefox 66+ kannst du die eingebaute Tastenkürzelverwaltung selbst öffnen:\n1) Rechtsklicke das Stylus-Symbol in der Werkzeugleiste und wähle \"Erweiterung verwalten\". Alternativ kannst du about:addons über das Hauptmenü oder per Tastenkürzel Strg-Umschalt-A öffnen.\n2) Klicke auf der geöffneten Seite (about:addons) auf das Zahnrad oben rechts.\n3) Wähle \"Tastenkombinationen von Erweiterungen verwalten\".\n\nHier kannst du alle Tastenkürzel individuell anpassen."
},
"sortDateNewestFirst": {
"message": "neueste zuerst"
},
@ -1133,12 +1207,30 @@
"styleEnabledLabel": {
"message": "Aktiviert"
},
"styleExcludeLabel": {
"message": "Benutzerdefinierte ausgeschlossene URLs"
},
"styleFromMozillaFormatError": {
"message": "Import vom Mozilla Format fehlgeschlagen"
},
"styleFromMozillaFormatPrompt": {
"message": "Mozilla-Format Code einfügen"
},
"styleIncludeLabel": {
"message": "Benutzerdefinierte Ziel-URLs"
},
"styleInjectionImportance": {
"message": "Style als wichtig markieren"
},
"styleInjectionOrder": {
"message": "Applikationsreihenfolge der Styles"
},
"styleInjectionOrderHint": {
"message": "Ziehe den Style mit der Maus an die gewünschte Stelle, um die Applikationsreihenfolge zu ändern. Styles weiter unten können die oberen überschreiben."
},
"styleInjectionOrderHint_prio": {
"message": "Die unten als wichtig gekennzeichneten Styles werden immer zuletzt angewendet, sodass sie auch neu installierte Styles überschreiben können. Klicke auf das Zeichen des Styles, um die Wichtigkeit umzuschalten."
},
"styleInstall": {
"message": "\"$stylename$\" mit Stylus installieren?",
"placeholders": {
@ -1178,6 +1270,15 @@
"styleNotAppliedRegexpProblemTooltip": {
"message": "Der Style wurde aufgrund ungültiger RegExp nicht angewandt."
},
"styleNotAppliedSchemeDark": {
"message": "Der Style wird nur im dunklen Modus angewendet"
},
"styleNotAppliedSchemeLight": {
"message": "Der Style wird nur im hellen Modus angewendet"
},
"stylePreferSchemeLabel": {
"message": "Dunkler/Heller Modus"
},
"styleRegexpInvalidExplanation": {
"message": "Einige RegExp konnten nicht kompiliert werden."
},
@ -1187,9 +1288,6 @@
"styleRegexpProblemTooltip": {
"message": "Anzahl der Bereiche, welche aufgrund nicht korrekt verwendeter RegExp nicht angewendet wurden"
},
"styleRegexpTestButton": {
"message": "RegExp testen"
},
"styleRegexpTestFull": {
"message": "Zutreffende Tabs"
},
@ -1211,6 +1309,9 @@
"styleSaveLabel": {
"message": "Speichern"
},
"styleSettings": {
"message": "Style Einstellungen"
},
"styleToMozillaFormatHelp": {
"message": "Das Mozilla-Format des Codes kann mit Stylish für Firefox verwendet werden und bei userstyles.org eingereicht werden."
},
@ -1232,7 +1333,7 @@
"message": "Stylus funktioniert nicht auf Seiten wie diesen."
},
"stylusUnavailableForURLdetails": {
"message": "Als Sicherheitsvorkehrung verbietet der Browser es Erweiterungen, seine eingebauten Seiten (wie chrome://version, dem neuen Standard-Tab ab Chrome 61, about:addons, usw.), sowie Seiten anderer Erweiterungen zu beeinflussen. Jeder Browser beschränkt auch den Zugriff auf seine eigene Erweiterungsgalerie (wie Chrome Web Store oder addons.mozilla.org)."
"message": "Als Sicherheitsvorkehrung verbietet der Browser es Erweiterungen, seine eigenen Seiten (wie z.B. chrome://version oder about:addons) und eigene Seiten anderer Erweiterungen zu verändern. Auch die jeweils browser-eigene Erweiterungsgalerie (wie Chrome Web Store oder addons.mozilla.org) kann nicht verändert werden."
},
"syncDropboxDeprecated": {
"message": "Dropbox Import / Export wurde durch einen fortschrittlicheren Mechanismus auf der Optionsseite ersetzt."
@ -1240,8 +1341,16 @@
"syncError": {
"message": "Synchronisation fehlgeschlagen"
},
"syncErrorLock": {
"message": "Die Datenbank wird bereits verwendet. Die Sperre wird um $TIME$ aufgehoben.",
"placeholders": {
"time": {
"content": "$1"
}
}
},
"syncErrorRelogin": {
"message": "Synchronisation fehlgeschlagen.\nVersuche, dich in den Optionen neu einzuloggen:\nKlicke erst \"Trennen\", dann \"Verbinden\"."
"message": "Synchronisation erfolglos. Du wurdest ausgeloggt.\nVersuche, dich in den Stylus Einstellungen wieder einzuloggen."
},
"syncStorageErrorSaving": {
"message": "Der Wert kann nicht gespeichert werden. Versuche, die Textmenge zu reduzieren."
@ -1332,9 +1441,6 @@
"usercssReplaceTemplateConfirmation": {
"message": "Ersetze das vorgegebene Template für neue UserCSS styles mit dem vorliegenden Code?"
},
"usercssReplaceTemplateName": {
"message": "Ein leeres @name ersetzt das vorgegebene Template"
},
"usercssReplaceTemplateSectionBody": {
"message": "Quelltext hier eingeben..."
},

View File

@ -64,9 +64,6 @@
"backupButtons": {
"message": "Δημιουργήστε αντίγραφο ασφαλείας"
},
"backupMessage": {
"message": "Επιλέξτε ένα αρχείο ή σύρετέ το σε αυτήν τη σελίδα"
},
"bckpInstStyles": {
"message": "Εξαγωγή στυλ"
},
@ -301,9 +298,6 @@
"findStyles": {
"message": "Εύρεση στυλ"
},
"findStylesForSite": {
"message": "Αναζήτηση περισσότερων στυλ για αυτή την ιστοσελίδα"
},
"genericAdd": {
"message": "Προσθήκη"
},
@ -415,9 +409,6 @@
"linterResetMessage": {
"message": "Για αναίρεση μιας κατά λάθος επαναφοράς, πατήστε Ctrl-Z (ή Cmd-Z) στο πλαίσιο κειμένου"
},
"manageFaviconsHelp": {
"message": "Το Stylus χρησιμοποιεί μία εξωτερική υπηρεσία https://www.google.com/s2/favicons"
},
"manageFilters": {
"message": "Φίλτρα"
},
@ -538,6 +529,9 @@
"optionsSyncSyncNow": {
"message": "Συγχρονισμός τώρα"
},
"optionsSyncUrl": {
"message": "διεύθυνση URL"
},
"optionsUpdateInterval": {
"message": "Διάστημα αυτόματης ενημέρωσης των στυλ σε ώρες (0 για απενεργοποίηση)"
},
@ -610,6 +604,9 @@
"sectionRemove": {
"message": "Αφαίρεση ενότητας"
},
"sections": {
"message": "Ενότητες"
},
"shortcuts": {
"message": "Συντομεύσεις"
},
@ -680,9 +677,6 @@
"syncError": {
"message": "Ο συγχρονισμός απέτυχε"
},
"syncErrorRelogin": {
"message": "Ο συγχρονισμός απέτυχε.\nΠροσπαθήστε να συνδεθείτε ξανά στις επιλογές Stylus:\nκάντε κλικ στο 'αποσύνδεση' πρώτα και μετά στο 'σύνδεση'."
},
"toggleStyle": {
"message": "Αλλαγή στυλ"
},

View File

@ -93,8 +93,8 @@
"description": "Heading for backup"
},
"backupMessage": {
"message": "Select a file or drag and drop to this page.",
"description": "Message for backup"
"message": "To import the backup file, drag'n'drop it into this page or click the Import button.\n\nTo export a compatible backup for Stylus older than 1.5.18, right-click or shift-click the Export button.",
"description": "Text for Backup section's (i) in the manager"
},
"bckpInstStyles": {
"message": "Export styles"
@ -186,6 +186,10 @@
"message": "Theme",
"description": "Label for the style editor's CSS theme."
},
"cm_arrowKeysTraverse": {
"message": "Arrow keys ↑↓ traverse sections",
"description": "Label for the option in the editor."
},
"colorpickerPaletteHint": {
"message": "Right-click a swatch to cycle through its source lines"
},
@ -336,12 +340,29 @@
},
"disableAllStyles": {
"message": "Turn all styles off",
"description": "Label for the checkbox that turns all enabled styles off."
"description": "Label for the checkbox that turns all styles off."
},
"disableAllStylesOff": {
"message": "Styles are turned off",
"description": "Label for the checkbox that turns all styles off when it's checked."
},
"disableStyleLabel": {
"message": "Disable",
"description": "Label for the button to disable a style"
},
"draftTitle": {
"message": "Draft recovery, created $date$",
"placeholders": {
"date": {
"content": "$1"
}
},
"description": "Title of the modal displayed in the editor when an unsaved draft is found, the $date$ looks like '1 hour ago' in user's current UI language"
},
"draftAction": {
"message": "Choose 'Yes' to load this draft or 'No' to discard it.",
"description": "Displayed in the editor after the browser/extension crashed"
},
"dragDropMessage": {
"message": "Drop your backup file anywhere on this page to import.",
"description": "Drag'n'drop message"
@ -375,11 +396,8 @@
},
"description": "Title of the page for editing styles"
},
"editorCodeLabel": {
"message": "Code"
},
"editorSettingLabel": {
"message": "Settings"
"editorSettings": {
"message": "Editor settings"
},
"enableStyleLabel": {
"message": "Enable",
@ -395,6 +413,9 @@
"message": "Export",
"description": "Label for the button to export a style ('edit' page) or all styles ('manage' page)"
},
"exportCompatible": {
"message": "Export (compatible mode)"
},
"exportSavedSuccess": {
"message": "File saved with success"
},
@ -438,18 +459,6 @@
"message": "Find styles",
"description": "Text for a link that gets a list of styles for the current site"
},
"findStylesForSite": {
"message": "Find more styles for this site",
"description": "Text for a link that gets a list of styles for the current site"
},
"findStylesInline": {
"message": "Inline",
"description": "Text for a checkbox that opens search results 'inline' (within the Stylus popup window)"
},
"findStylesInlineTooltip": {
"message": "Display search results inside this window.",
"description": "Text for a checkbox that displays search results within the Stylus popup."
},
"genericAdd": {
"message": "Add",
"description": "Used in various places for an action that adds something"
@ -493,6 +502,13 @@
"message": "Saved",
"description": "Used in various parts of the UI to indicate that something was saved"
},
"genericSize": {
"message": "Size"
},
"genericTest": {
"message": "Test",
"description": "Label for the action that runs some test e.g. opens the regexp tester panel in the editor"
},
"genericTitle": {
"message": "Title",
"description": "Used in various parts of the UI to indicate the title of something"
@ -504,6 +520,10 @@
"gettingStyles": {
"message": "Getting all styles..."
},
"headerResizerHint": {
"message": "Hold Shift to resize only in this type of UI, i.e. editor, manager, installer",
"description": "Tooltip for the header panel resizer"
},
"helpAlt": {
"message": "Help",
"description": "Alternate text for help buttons"
@ -602,18 +622,6 @@
"message": "Update style",
"description": "Label for update button"
},
"installPreferSchemeLabel": {
"message": "The style should be applied:"
},
"installPreferSchemeNone": {
"message": "Always"
},
"installPreferSchemeDark": {
"message": "In Dark Mode"
},
"installPreferSchemeLight": {
"message": "In Light Mode"
},
"installUpdate": {
"message": "Install update",
"description": "Label for the button to install an update for a single style"
@ -743,7 +751,7 @@
"description": "Label for the checkbox that toggles grayed out mode of applies-to favicons in the new UI on manage page"
},
"manageFaviconsHelp": {
"message": "Stylus uses an external service https://www.google.com/s2/favicons",
"message": "Stylus uses an external service https://icons.duckduckgo.com",
"description": "Label for the checkbox that toggles applies-to favicons in the new UI on manage page"
},
"manageFilters": {
@ -758,6 +766,9 @@
"message": "Number of applies-to items",
"description": "Label for the numeric input box to limit max number of applies-to targets in the new UI on manage page"
},
"manageMinColumnWidth": {
"message": "Minimum column width (in pixels; 9999 disables multi-column mode)"
},
"manageNewStyleAsUsercss": {
"message": "as Usercss",
"description": "VERY SHORT label for the checkbox next to the 'Write new style' button in the style manager"
@ -1068,14 +1079,17 @@
"message": "Exposes the top site domain in each iframe.\nEnables writing iframe-specific CSS like this:\nhtml[stylus-iframe$$=\"twitter.com\"] h1 { display:none }",
"description": "Add attribute to iframe; make sure to include the double $$ in the css example, or the `$=` will be omitted in the displayed text."
},
"optionsAdvancedExposeStyleName": {
"message": "Expose style name"
},
"optionsAdvancedExposeStyleNameNote": {
"message": "Exposes the style name in the page to facilitate debugging of styles in devtools. Please reload the tab(s) to apply the new setting."
},
"optionsAdvancedNewStyleAsUsercss": {
"message": "Write new style as usercss"
},
"optionsAdvancedAutoSwitchScheme": {
"message": "Toggle Light/Dark Mode styles automatically"
},
"optionsAdvancedAutoSwitchSchemeNever": {
"message": "Never"
"message": "Disabled. The dark/light setting in styles is ignored."
},
"optionsAdvancedAutoSwitchSchemeBySystem": {
"message": "By system preference"
@ -1126,6 +1140,9 @@
"message": "Options",
"description": "Heading for options section on manage page."
},
"optionsIconAuto": {
"message": "Match the Dark/Light mode"
},
"optionsIconDark": {
"message": "Dark browser themes"
},
@ -1148,7 +1165,7 @@
"message": "Reset options"
},
"optionsStylusThemes": {
"message": "Find a Stylus UI theme"
"message": "Click Stylus icon in the browser toolbar on any Stylus page including this one, then click 'Find styles'"
},
"optionsSubheading": {
"message": "More Options",
@ -1268,6 +1285,10 @@
"message": "Click to see available hotkeys",
"description": "Tooltip displayed when hovering the right edge of the extension popup"
},
"popupManageSiteStyles": {
"message": "Manage site styles",
"description": "Item in the dropdown menu for the 'Manage' button in the popup that opens manager with styles applicable for current site."
},
"popupManageTooltip": {
"message": "Shift-click or right-click opens manager with styles applicable for current site",
"description": "Tooltip for the 'Manage' button in the popup."
@ -1292,6 +1313,21 @@
"message": "Styles before commands",
"description": "Label for the checkbox controlling section order in the popup."
},
"preferScheme": {
"message": "Dark/Light mode preference"
},
"preferSchemeAlways": {
"message": "Currently ignored (the style always applies) because the global Dark/Light mode is disabled"
},
"preferSchemeDark": {
"message": "Dark"
},
"preferSchemeLight": {
"message": "Light"
},
"preferSchemeNone": {
"message": "None (always applied)"
},
"prefShowBadge": {
"message": "Number of styles active for the current site",
"description": "Label for the checkbox controlling toolbar badge text."
@ -1330,8 +1366,8 @@
"message": "Reading styles..."
},
"reload": {
"message": "Reload Stylus extension",
"description": "Context menu reload"
"message": "Reload",
"description": "Context menu to reload the extension when installed in developer mode"
},
"replace": {
"message": "Replace",
@ -1345,12 +1381,18 @@
"message": "Replace with",
"description": "Label before the replace-with input field in the editor shown on Ctrl-H etc."
},
"restoreTemplate": {
"message": "Restore the default template.\n\n(The currently open editor pages won't change.)"
},
"retrieveBckp": {
"message": "Import styles"
},
"retrieveDropboxSync": {
"message": "Dropbox Import"
},
"saveAsTemplate": {
"message": "Save as template"
},
"search": {
"message": "Search",
"description": "Label before the search input field in the editor shown on Ctrl-F"
@ -1402,7 +1444,7 @@
"description": "Text for label that shows the number of times a search result was installed during last week"
},
"searchStyleQueryHint": {
"message": "Search style names case-insensitively:\nsome words - all words in any order\n\"some phrase\" - this exact phrase without quotes\n2020 - a year like this also shows styles updated in 2020",
"message": "Search style names (case-sensitively if an uppercase letter is used):\nsome words - all these words in any order\n\"some phrase\" - this exact phrase without quotes\n/foo.*bar/i - regular expression without spaces (use \\s instead)",
"description": "Tooltip shown for the text input in the popup's inline style finder"
},
"searchStylesAll": {
@ -1449,6 +1491,10 @@
"message": "Sections",
"description": "Header for the table of contents block listing style section names in the left panel of the classic editor"
},
"settings": {
"message": "Settings",
"description": "Generic label/title for settings"
},
"shortcuts": {
"message": "Shortcuts",
"description": "Go to shortcut configuration"
@ -1456,6 +1502,9 @@
"shortcutsNote": {
"message": "Define keyboard shortcuts"
},
"shortcutsNoteFF": {
"message": "In Firefox 66+ you can open the built-in shortcuts UI manually:\n1) right-click Stylus icon in the toolbar and choose 'Manage'\n(alternatively, open about:addons via the main menu or Ctrl-Shift-A),\n2) in the page that opens click the cog wheel icon in the top right corner,\n3) choose 'Manage extension shortcuts'.\n\nYou can also customize the shortcuts here."
},
"sortDateNewestFirst": {
"message": "newest first",
"description": "Text added to indicate that sorting a date would add the newest entries at the top"
@ -1588,10 +1637,6 @@
"message": "Number of sections not applied due to incorrect usage of 'regexp()'",
"description": "Tooltip in the popup for styles that were applied only partially"
},
"styleRegexpTestButton": {
"message": "RegExp test",
"description": "RegExp test button label in the editor shown when applies-to list has a regexp value"
},
"styleRegexpTestFull": {
"message": "Matching tabs",
"description": "RegExp test report: label for the fully matching expressions"
@ -1620,6 +1665,10 @@
"message": "Save",
"description": "Label for save button for style editing"
},
"styleSettings": {
"message": "Style settings",
"description": "Label/title for style settings dialog"
},
"styleToMozillaFormatHelp": {
"message": "The Mozilla format of the code can be submitted to userstyles.org and used with the classic Stylish for Firefox",
"description": "Help info for the Mozilla format header section that converts the code to/from Mozilla format"
@ -1649,9 +1698,6 @@
"message": "As a security precaution, the browser prohibits extensions from affecting its built-in pages (like chrome://version, the standard new tab page as of Chrome 61, about:addons, and so on) as well as other extensions' pages. Each browser also restricts access to its own extensions gallery (like Chrome Web Store or AMO).",
"description": "Sub-note in the toolbar pop-up when on a URL Stylus can't affect"
},
"styleOriginLabel": {
"message": "Style origin"
},
"styleUpdateUrlLabel": {
"message": "Update URL"
},
@ -1661,6 +1707,21 @@
"styleIncludeLabel": {
"message": "Custom included sites"
},
"styleInjectionImportance": {
"message": "Toggle style's importance"
},
"styleInjectionOrder": {
"message": "Style injection order",
"description": "Tooltip for the button in the manager to open the dialog and also the title of this dialog"
},
"styleInjectionOrderHint": {
"message": "Drag'n'drop a style to change its position. Styles are injected sequentially in the order shown below so a style further down the list can override the earlier styles.",
"description": "Hint in the injection order dialog in the manager"
},
"styleInjectionOrderHint_prio": {
"message": "Important styles listed below are always injected last so they can override any newly installed styles. Click the style's mark to toggle its importance.",
"description": "Hint at the bottom of the injection order dialog in the manager"
},
"styleExcludeLabel": {
"message": "Custom excluded sites"
},
@ -1798,10 +1859,6 @@
"usercssReplaceTemplateConfirmation": {
"message": "Replace the default template for new Usercss styles with the current code?"
},
"usercssReplaceTemplateName": {
"message": "Empty @name replaces the default template",
"description": "The text shown after @name when creating a new Usercss style"
},
"usercssReplaceTemplateSectionBody": {
"message": "Insert code here...",
"description": "The code placeholder comment in a new style created by clicking 'Write style' in the popup"

1494
_locales/es/messages.json Normal file

File diff suppressed because it is too large Load Diff

View File

@ -67,9 +67,6 @@
"backupButtons": {
"message": "Respaldo"
},
"backupMessage": {
"message": "Al exportar hará una copia de respaldo de TODOS los estilos instalados. Para restaurar una copia de respaldo, importe el archivo o arrástrelo a esta página."
},
"bckpInstStyles": {
"message": "Exportar estilos"
},
@ -313,15 +310,6 @@
"findStyles": {
"message": "Buscar estilos"
},
"findStylesForSite": {
"message": "Buscar más estilos para este sitio"
},
"findStylesInline": {
"message": "Dentro"
},
"findStylesInlineTooltip": {
"message": "Muestra los resultados de búsqueda dentro de esta ventana."
},
"genericAdd": {
"message": "Añadir"
},
@ -526,7 +514,7 @@
"message": "Atenuado"
},
"manageFaviconsHelp": {
"message": "Stylus usa un servicio externo https://www.google.com/s2/favicons"
"message": "Stylus usa un servicio externo https://icons.duckduckgo.com"
},
"manageFilters": {
"message": "Filtros"
@ -861,9 +849,6 @@
"optionsResetButton": {
"message": "Restablecer opciones"
},
"optionsStylusThemes": {
"message": "Buscar un tema de Stylus"
},
"optionsSubheading": {
"message": "Más opciones"
},
@ -1012,9 +997,6 @@
"readingStyles": {
"message": "Leyendo los estilos..."
},
"reload": {
"message": "Recargar extensión Stylus"
},
"replace": {
"message": "Reemplazar"
},
@ -1069,9 +1051,6 @@
"searchResultWeeklyCount": {
"message": "Instalaciones semanales"
},
"searchStyleQueryHint": {
"message": "La búsqueda de nombres de estilo no distingue mayúsculas de minúsculas:\nalgunas palabras: todas las palabras en cualquier orden\n\"una frase\": esta frase exacta (sin comillas)\n2020: al escribir un año, se muestran estilos que se actualizaron ese año"
},
"searchStylesAll": {
"message": "Todos"
},
@ -1154,7 +1133,7 @@
"message": "Has realizado cambios en este estilo sin guardarlos."
},
"styleEnabledLabel": {
"message": "Activado"
"message": "Habilitado"
},
"styleFromMozillaFormatError": {
"message": "No se pudo importar desde el formato Mozilla"
@ -1213,9 +1192,6 @@
"styleRegexpProblemTooltip": {
"message": "Número de secciones no aplicadas debido a un uso incorrecto de 'regexp()'"
},
"styleRegexpTestButton": {
"message": "Probar regexp"
},
"styleRegexpTestFull": {
"message": "Pestañas coincidentes"
},
@ -1269,9 +1245,6 @@
"syncError": {
"message": "No se pudo sincronizar"
},
"syncErrorRelogin": {
"message": "No se pudo sincronizar.\nIntenta volver a iniciar sesión en las opciones de Stylus:\nprimero haz clic en 'desconectar', y luego en 'conectar'."
},
"syncStorageErrorSaving": {
"message": "El valor no se puede guardar. Trate de reducir la longitud del texto."
},
@ -1361,9 +1334,6 @@
"usercssReplaceTemplateConfirmation": {
"message": "¿Reemplazar con el código actual la plantilla predeterminada para nuevos estilos UserCSS?"
},
"usercssReplaceTemplateName": {
"message": "@name vacío reemplaza la plantilla predeterminada"
},
"usercssReplaceTemplateSectionBody": {
"message": "Inserte el código aquí..."
},

View File

@ -67,9 +67,6 @@
"backupButtons": {
"message": "Varunda"
},
"backupMessage": {
"message": "Vali fail või lohista see siia lehele."
},
"bckpInstStyles": {
"message": "Ekspordi stiilid"
},
@ -293,15 +290,6 @@
"findStyles": {
"message": "Leia stiile"
},
"findStylesForSite": {
"message": "Leia sellele saidile veel stiile"
},
"findStylesInline": {
"message": "Aknasisene"
},
"findStylesInlineTooltip": {
"message": "Näita otsingu tulemusi selles aknas."
},
"genericAdd": {
"message": "Lisa"
},
@ -497,7 +485,7 @@
"message": "Tee halliks"
},
"manageFaviconsHelp": {
"message": "Stylus kasutab välist teenust https://www.google.com/s2/favicons"
"message": "Stylus kasutab välist teenust https://icons.duckduckgo.com"
},
"manageFilters": {
"message": "Filtrid"
@ -877,6 +865,9 @@
"sectionRestore": {
"message": "Taasta eemaldatud jaotis"
},
"sections": {
"message": "Jaotised"
},
"shortcuts": {
"message": "Otseteed"
},
@ -979,9 +970,6 @@
"styleRegexpProblemTooltip": {
"message": "\"regexp()\" vale kasutuse tõttu rakendamata jaotiste arv"
},
"styleRegexpTestButton": {
"message": "Regulaaravaldise katsetus"
},
"styleRegexpTestFull": {
"message": "Vastavad kaardid"
},
@ -1056,6 +1044,9 @@
"unreachableFileHint": {
"message": "Stylus saab ligi pääseda file:// URLidele ainult siis, kui märgistad vastava kasti Stylus laiendusel chrome://extensions lehel"
},
"unreachableMozSiteHintOldFF": {
"message": "Ainult Firefox 59 ja uuem on võimalik seadistada lubama WebExtensionsil lisada stiilielemente CSP-kaitstud saitidele nagu see."
},
"unzipStyles": {
"message": "Stiilide lahtipakkimine..."
},
@ -1115,9 +1106,6 @@
"usercssReplaceTemplateConfirmation": {
"message": "Asendad vaikimisi malli uutes kasutajacss stiilides praeguse koodiga?"
},
"usercssReplaceTemplateName": {
"message": "Tühi @name asendab vaikimisi malli"
},
"usercssReplaceTemplateSectionBody": {
"message": "Sisesta kood siia..."
},

View File

@ -52,6 +52,12 @@
"checkingForUpdate": {
"message": "Tarkistetaan..."
},
"confirmDelete": {
"message": "Poista"
},
"confirmSave": {
"message": "Tallenna"
},
"deleteStyleConfirm": {
"message": "Oletko varma että haluat poistaa tämän tyylin?"
},
@ -64,6 +70,9 @@
"disableStyleLabel": {
"message": "Poista Käytöstä"
},
"editDeleteText": {
"message": "Poista"
},
"editStyleHeading": {
"message": "Muokkaa Tyyliä"
},
@ -81,8 +90,11 @@
"enableStyleLabel": {
"message": "Aktivoi"
},
"findStylesForSite": {
"message": "Hae lisää tyylejä tälle sivustolle"
"genericAdd": {
"message": "Lisää"
},
"genericEnabledLabel": {
"message": "Aktivoitu"
},
"helpAlt": {
"message": "Apu"
@ -117,6 +129,9 @@
"sectionRemove": {
"message": "Poista osio"
},
"sections": {
"message": "Osiot"
},
"styleBadRegexp": {
"message": "Regexp ei kelpaa."
},

View File

@ -68,7 +68,7 @@
"message": "Sauvegarde"
},
"backupMessage": {
"message": "Sélectionner un fichier ou le glisser-déposer sur cette page"
"message": "Pour importer le fichier de sauvegarder, glissez-déposez-le sur dans page ou cliquez sur le bouton Importer.\n\nPour export une sauvegarde compatible avec une version de Stylus plus ancienne que 1.5.18, effectuez un clic droit ou un appuie sur la touche Maj + clic sur le bouton Exporter."
},
"bckpInstStyles": {
"message": "Exporter des styles"
@ -199,6 +199,28 @@
"copy": {
"message": "Copier dans le presse-papier"
},
"customNameHint": {
"message": "Entrez un nom personnalisé ici pour renommer le style dans l'IU sans casser les mises à jour"
},
"customNameResetHint": {
"message": "Arrête d'utiliser le nom personnalisé, change vers le propre nom du style"
},
"dateAbbrDay": {
"message": "$value$j",
"placeholders": {
"value": {
"content": "$1"
}
}
},
"dateAbbrYear": {
"message": "$value$a",
"placeholders": {
"value": {
"content": "$1"
}
}
},
"dateInstalled": {
"message": "Date d'installation"
},
@ -223,9 +245,23 @@
"disableAllStyles": {
"message": "Désactiver tous les styles"
},
"disableAllStylesOff": {
"message": "Les styles sont désactivés"
},
"disableStyleLabel": {
"message": "Désactiver"
},
"draftAction": {
"message": "Choisissez « Oui » pour charger ce brouillon ou « Non » pour l'abandonner."
},
"draftTitle": {
"message": "Sauvegarde du brouillon, créée $date$",
"placeholders": {
"date": {
"content": "$1"
}
}
},
"dragDropMessage": {
"message": "Glisser votre fichier de sauvegarde nimporte où sur cette page pour limporter."
},
@ -252,6 +288,9 @@
}
}
},
"editorSettings": {
"message": "Paramètres de léditeur"
},
"enableStyleLabel": {
"message": "Activer"
},
@ -261,6 +300,9 @@
"excludeStyleByUrlLabel": {
"message": "Exclure lURL actuelle"
},
"exportCompatible": {
"message": "Export (mode de compatibilité)"
},
"exportLabel": {
"message": "Exporter"
},
@ -296,15 +338,6 @@
"findStyles": {
"message": "Trouver des styles"
},
"findStylesForSite": {
"message": "Rechercher d'autres styles pour ce site"
},
"findStylesInline": {
"message": "Dans la popup"
},
"findStylesInlineTooltip": {
"message": "Affiche les résultats de recherche dans cette fenêtre"
},
"genericAdd": {
"message": "Ajouter"
},
@ -344,6 +377,9 @@
"gettingStyles": {
"message": "Récupération de tous les styles…"
},
"headerResizerHint": {
"message": "Maintenir la touche Maj pour redimensionner uniquement dans ce type d'interface, par exemple, éditeur, gestionnaire, installateur"
},
"helpAlt": {
"message": "Aide"
},
@ -365,6 +401,12 @@
"importLabel": {
"message": "Importer"
},
"importPreprocessor": {
"message": "Les styles avec un <code>@preprocessor</code> ne fonctionnera pas en mode classique. Vous pouvez changer l'éditeur en mode Usercss : 1) Ouvrez le gestionnaire de styles, 2) Activer l'option \"en tant que Usercss\", 3) Cliquez \"écrire un nouveau style\"\n\nImporter de toute façon ?"
},
"importPreprocessorTitle": {
"message": "Problème potentiel à cause de @preprocessor"
},
"importReplaceLabel": {
"message": "Remplacer le style"
},
@ -433,9 +475,18 @@
"linkGetHelp": {
"message": "Consulter l'aide"
},
"linkGetShareStyles": {
"message": "Obtenir et partager les styles"
},
"linkGetShareStylesInfo": {
"message": "Le nouveau userstyles.world géré par la communauté est créé par les auteurs d'userstyles dans le but de remplacer userstyles.org, qui a été tellement lent et inconscient durant l'année dernière que beaucoup d'auteurs ont arrêté de mettre à jour leurs styles."
},
"linkGetStyles": {
"message": "Obtenir des styles"
},
"linkGetStylesInfo": {
"message": "Ce site d'archive à été créé par un membre de la communauté userstyle pour archiver le lent et inconscient site userstyles.org. Cette archive est mise à jour approximativement chaque jour."
},
"linkTranslate": {
"message": "Traduire"
},
@ -503,7 +554,7 @@
"message": "Grisés"
},
"manageFaviconsHelp": {
"message": "Stylus utilise le service externe https://www.google.com/s2/favicons"
"message": "Stylus utilise le service externe https://icons.duckduckgo.com"
},
"manageFilters": {
"message": "Filtres"
@ -709,6 +760,17 @@
}
}
},
"meta_unknownMetaTypo": {
"message": "Peut-être @$keyOk$? Métadonnée inconnue: @$keyErr$",
"placeholders": {
"keyErr": {
"content": "$1"
},
"keyOk": {
"content": "$2"
}
}
},
"meta_unknownPreprocessor": {
"message": "@preprocessor inconnu: $preprocessor$",
"placeholders": {
@ -734,6 +796,9 @@
"noStylesForSite": {
"message": "Aucun style n'est installé pour ce site."
},
"numberedLine": {
"message": "Ligne :"
},
"openManage": {
"message": "Gestion"
},
@ -743,6 +808,15 @@
"optionsAdvanced": {
"message": "Avancé"
},
"optionsAdvancedAutoSwitchSchemeBySystem": {
"message": "Par préférence système"
},
"optionsAdvancedAutoSwitchSchemeByTime": {
"message": "Par horaire nocturne :"
},
"optionsAdvancedAutoSwitchSchemeNever": {
"message": "Désactivé. Le paramètre clair/obscur dans les styles est ignoré."
},
"optionsAdvancedContextDelete": {
"message": "Ajouter « Supprimer » dans le menu contextuel de lextension"
},
@ -752,9 +826,24 @@
"optionsAdvancedExposeIframesNote": {
"message": "Expose le domaine principal dans chaque iframe.\nPermet décrire du CSS spécifique aux iframe tel que :\nhtml[stylus-iframe$$=\"twitter.com\"] h1 { display:none }"
},
"optionsAdvancedExposeStyleName": {
"message": "Afficher le nom du style"
},
"optionsAdvancedExposeStyleNameNote": {
"message": "Afficher le nom du style dans la page pour faciliter le débogage des styles dans les outils de développement. Veuillez recharger le ou les onglets pour appliquer ce nouveau paramètre."
},
"optionsAdvancedNewStyleAsUsercss": {
"message": "Écrire un nouveau style en tant que usercss"
},
"optionsAdvancedPatchCsp": {
"message": "Corrige <code>CSP</code> pour permettre les ressources de style"
},
"optionsAdvancedPatchCspNote": {
"message": "Activez cela si les styles comportent des images ou des polices qui échoue à charger sur les sites avec une politique de sécurité de contenus stricte <code>CSP</code> (<code>Content-Security-Policy</code>).\n\nActiver cette option permettra d'alléger les restrictions du <code>CSP</code>, permettant les styles essentiels de charger. Cette option n'est entendue que pour les utilisateurs expérimentés qui comprennent les potentielles implications de sécurité que cela introduit, et accepte la responsabilité de surveiller le contenu qu'ils autorisent. Veuillez lire les attaques basé sur le CSS pour plus dinformation.\n\nAussi sachez, que cette option en particulier n'est pas garanti de fonctionner si une autre extension modifie la réponse réseau avant."
},
"optionsAdvancedStyleViaXhr": {
"message": "Mode d'injection instantanée"
},
"optionsBadgeDisabled": {
"message": "Couleur d'arrière plan si désactivé"
},
@ -815,6 +904,9 @@
"optionsSyncNone": {
"message": "Aucun"
},
"optionsSyncPassword": {
"message": "Mot de passe"
},
"optionsSyncStatusConnected": {
"message": "Connecté"
},
@ -849,12 +941,18 @@
}
}
},
"optionsSyncStatusRelogin": {
"message": "Session expirée, veuillez vous reconnecter à nouveau."
},
"optionsSyncStatusSyncing": {
"message": "Synchronisation..."
},
"optionsSyncSyncNow": {
"message": "Synchroniser maintenant"
},
"optionsSyncUsername": {
"message": "Nom dutilisateur"
},
"optionsUpdateImportNote": {
"message": "Quand vous importez des sauvegardes de style dune ancienne version ou de Stylish, faites une vérification manuellement pour vous assurez que tous les styles sont à jour."
},
@ -903,6 +1001,9 @@
"popupMenuButtonTooltip": {
"message": "Actions"
},
"popupOpenEditInPopup": {
"message": "Utiliser une simple fenêtre (pas d'omnibox)"
},
"popupOpenEditInWindow": {
"message": "Ouvrir l'éditeur dans une nouvelle fenêtre"
},
@ -915,17 +1016,41 @@
"prefShowBadge": {
"message": "Afficher le nombre de styles actifs pour le site actuel sur le boutton Stylus"
},
"preferSchemeDark": {
"message": "Obscur"
},
"preferSchemeLight": {
"message": "Clair"
},
"preferSchemeNone": {
"message": "Aucun (quand appliqué)"
},
"previewLabel": {
"message": "Prévisualiser en direct"
},
"previewTooltip": {
"message": "Applique temporairement les changements sans sauvegarder.\nSauvegarde le style pour rendre les changements permanents."
},
"publish": {
"message": "Publier"
},
"publishPush": {
"message": "Pousser la mise à jour"
},
"publishReconnect": {
"message": "Essayez de vous déconnecter et de publier à nouveau"
},
"publishStyle": {
"message": "Publier le style"
},
"publishUsw": {
"message": "Utiliser <userstyles.world>"
},
"readingStyles": {
"message": "Lecture des styles…"
},
"reload": {
"message": "Recharger l´extension Stylus"
"message": "Recharger"
},
"replace": {
"message": "Remplacer"
@ -942,12 +1067,18 @@
"retrieveDropboxSync": {
"message": "Importer depuis Dropbox"
},
"saveAsTemplate": {
"message": "Sauvegarder comme modèle"
},
"search": {
"message": "Rechercher"
},
"searchCaseSensitive": {
"message": "Sensible à la casse"
},
"searchGlobalStyles": {
"message": "Chercher aussi des styles globaux."
},
"searchNumberOfResults": {
"message": "Nombre de correspondances"
},
@ -963,6 +1094,12 @@
"searchResultNoneFound": {
"message": "Aucun style trouvé pour ce site"
},
"searchResultNotMatching": {
"message": "Ce style est installé mais il ne s'applique pas au lien du site actuel."
},
"searchResultNotMatchingNote": {
"message": "Essaye de demander lauteur pour ajouter le lien l'URL.\n\nVous pouvez aussi ouvrir le style dans le gestionnaire et l'éditer soit-même,\nmais soyez avertis que cela désactive les mises à jour automatiques pour ce style."
},
"searchResultRating": {
"message": "Note"
},
@ -972,6 +1109,21 @@
"searchResultWeeklyCount": {
"message": "Installations hebdomadaires"
},
"searchStylesAll": {
"message": "Tout"
},
"searchStylesCode": {
"message": "Code CSS"
},
"searchStylesMatchUrl": {
"message": "Par lien"
},
"searchStylesMeta": {
"message": "Meta-données"
},
"searchStylesName": {
"message": "Nom"
},
"sectionAdd": {
"message": "Ajouter une section"
},
@ -981,6 +1133,9 @@
"sectionRestore": {
"message": "Restaurer la section supprimée"
},
"settings": {
"message": "Paramètres"
},
"shortcuts": {
"message": "Raccourcis"
},
@ -1014,6 +1169,9 @@
"styleBeautify": {
"message": "Embellir "
},
"styleBeautifyHint": {
"message": "Astuce : Cliquez-droit le bouton \"Beautify\" ou utilisez le raccourci clavier définit ci-dessous pour beautify sans montrer le panneau."
},
"styleBeautifyIndentConditional": {
"message": "Indenter @media, @supports"
},
@ -1029,6 +1187,9 @@
"styleEnabledLabel": {
"message": "Activé"
},
"styleExcludeLabel": {
"message": "Personnalisation des sites exclus"
},
"styleFromMozillaFormatError": {
"message": "Échec de l'importation depuis le format Mozilla"
},
@ -1071,9 +1232,21 @@
"styleMozillaFormatHeading": {
"message": "Format Mozilla"
},
"styleName": {
"message": "Nom du style"
},
"styleNotAppliedRegexpProblemTooltip": {
"message": "Le style n'a pu s'appliquer en raison d'une utilisation erronée de 'regexp()'"
},
"styleNotAppliedSchemeDark": {
"message": "Ce style est uniquement appliqué en mode sombre"
},
"styleNotAppliedSchemeLight": {
"message": "Ce style est uniquement appliqué en mode clair"
},
"stylePreferSchemeLabel": {
"message": "Mode clair/sombre"
},
"styleRegexpInvalidExplanation": {
"message": "Quelques règles 'regexp()' qui nont pas pu être compilées"
},
@ -1083,9 +1256,6 @@
"styleRegexpProblemTooltip": {
"message": "Nombre de sections non appliquées à cause dune utilisation incorrecte de 'regexp()'"
},
"styleRegexpTestButton": {
"message": "Test dexpression rationnelle"
},
"styleRegexpTestFull": {
"message": "Onglets correspondants"
},
@ -1107,6 +1277,9 @@
"styleSaveLabel": {
"message": "Enregistrer"
},
"styleSettings": {
"message": "Paramètres du style"
},
"styleToMozillaFormatHelp": {
"message": "Le code au format Mozilla peut être utilisé dans Stylish for Firefox et envoyé à userstyles.org."
},
@ -1124,6 +1297,9 @@
"styleUpdateDiscardChanges": {
"message": "Le style a été changé en dehors de léditeur. Voulez-vous recharger le style ?"
},
"styleUpdateUrlLabel": {
"message": "URL de mise à jour"
},
"stylusUnavailableForURL": {
"message": "Stylus ne fonctionne pas sur les pages de ce genre"
},
@ -1136,6 +1312,17 @@
"syncDropboxStyles": {
"message": "Exporter vers Dropbox"
},
"syncError": {
"message": "Synchronisation échouée"
},
"syncErrorLock": {
"message": "Cette base de données est déjà utilisée. Le verrouillage expirera le $TIME$",
"placeholders": {
"time": {
"content": "$1"
}
}
},
"syncStorageErrorSaving": {
"message": "La valeur ne peut pas être sauvegardée. Essayez de réduire la quantité de texte."
},
@ -1160,6 +1347,12 @@
"unreachableFileHint": {
"message": "Stylus peut accéder aux URL file:// uniquement si vous cochez la case correspondante pour lextension Stylus sur la page chrome://extensions."
},
"unreachableMozSiteHint": {
"message": "Dans Firefox 60 et plus récent vous devez retirer ce domaine de <extensions.webextensions.restrictedDomains> dans <about:config>."
},
"unreachableMozSiteHintOldFF": {
"message": "Seulement dans Firefox 59 et plus récent que les extensions-web peuvent être configurés pour autoriser de rajouter des éléments de style sur les sites protégés CSP comme celui-ci."
},
"unzipStyles": {
"message": "Décompression des styles…"
},
@ -1219,9 +1412,6 @@
"usercssReplaceTemplateConfirmation": {
"message": "Remplacer le modèle par défaut pour les nouveaux styles Usercss par le code actuel ?"
},
"usercssReplaceTemplateName": {
"message": "Un @name vide remplace le modèle par défaut"
},
"usercssReplaceTemplateSectionBody": {
"message": "Insérer le code ici..."
},

View File

@ -67,9 +67,6 @@
"backupButtons": {
"message": "גיבוי"
},
"backupMessage": {
"message": "בחר קובץ או גרור ושחרר אותו בדף זה."
},
"bckpInstStyles": {
"message": "ייצא עיצובים"
},
@ -296,15 +293,6 @@
"findStyles": {
"message": "מצא עיצובים"
},
"findStylesForSite": {
"message": "מצא סגנונות נוספים לאתר זה"
},
"findStylesInline": {
"message": "מוטבע"
},
"findStylesInlineTooltip": {
"message": "הצג תוצאות חיפוש בחלון זה."
},
"genericAdd": {
"message": "הוספה"
},
@ -496,9 +484,6 @@
"manageFaviconsGray": {
"message": "האפרת האייקונים"
},
"manageFaviconsHelp": {
"message": "Stylus משתמש בשירות חיצוני https://www.google.com/s2/favicons"
},
"manageFilters": {
"message": "מסננים"
},
@ -703,6 +688,9 @@
"optionsSyncSyncNow": {
"message": "סנכרן כעת"
},
"optionsSyncUrl": {
"message": "כתובת אתר"
},
"optionsUpdateImportNote": {
"message": "בעת ייבוא גיבויים לסגנון מגרסה ישנה או מ־Stylish, בדוק באופן חד פעמי אם יש עדכונים באופן ידני במנהל הסגנונות כדי לוודא שכל הסגנונות מעודכנים."
},
@ -766,9 +754,6 @@
"readingStyles": {
"message": "קורא עיצובים..."
},
"reload": {
"message": "טען מחדש את Stylus"
},
"replace": {
"message": "החלף"
},
@ -826,6 +811,9 @@
"sectionRestore": {
"message": "שחזר סעיף שהוסר"
},
"sections": {
"message": "סעיפים"
},
"shortcuts": {
"message": "קיצורי מקשים"
},
@ -919,9 +907,6 @@
"styleRegexpProblemTooltip": {
"message": "מספר המקטעים שלא הוחלו עקב שימוש שגוי ב־'regexp()'"
},
"styleRegexpTestButton": {
"message": "בדוק RegExp"
},
"styleRegexpTestFull": {
"message": "כרטיסיות תואמות"
},

View File

@ -67,9 +67,6 @@
"backupButtons": {
"message": "Biztonsági mentés"
},
"backupMessage": {
"message": "Válassz ki egy fájlt vagy húzd erre az oldalra!"
},
"bckpInstStyles": {
"message": "Stílusok exportálása"
},
@ -290,15 +287,6 @@
"findStyles": {
"message": "Stílusok keresése"
},
"findStylesForSite": {
"message": "További stílusok keresése ehhez az oldalhoz"
},
"findStylesInline": {
"message": "Helyben"
},
"findStylesInlineTooltip": {
"message": "Keresési eredmények megjelenítése ebben az ablakban."
},
"genericAdd": {
"message": "Hozzáadás"
},
@ -488,7 +476,7 @@
"message": "Megjelenítés szürkítve"
},
"manageFaviconsHelp": {
"message": "A Stylus külső szolgáltatást használ (https://www.google.com/s2/favicons)"
"message": "A Stylus külső szolgáltatást használ (https://icons.duckduckgo.com)"
},
"manageFilters": {
"message": "Szűrők"
@ -722,6 +710,9 @@
"openManage": {
"message": "Kezelés"
},
"openOptions": {
"message": "Beállítások"
},
"openStylesManager": {
"message": "Stíluskezelő megnyitása"
},
@ -975,6 +966,9 @@
"sectionRestore": {
"message": "Eltávolított szekció visszaállítása"
},
"sections": {
"message": "Szekciók"
},
"shortcuts": {
"message": "Gyorsbillentyűk"
},
@ -1077,9 +1071,6 @@
"styleRegexpProblemTooltip": {
"message": "A nem alkalmazott szeckiók száma helytelen 'regexp()' használat miatt"
},
"styleRegexpTestButton": {
"message": "RegExp tesztelése"
},
"styleRegexpTestFull": {
"message": "Illeszkedő fülek"
},
@ -1151,6 +1142,9 @@
"unreachableFileHint": {
"message": "A Stylus csak akkor képes hozzáférni a file:// URL-ekhez, ha engedélyezed az erre vonatkozó beállítást a Stylus kiegészítőre a chrome://extensions oldalon."
},
"unreachableMozSiteHintOldFF": {
"message": "Csak a Firefox 59 vagy annál újabb állítható be az ilyen CSP-védett oldalak stílusának átszabása WebExtensions kiegészítőkön keresztül."
},
"unzipStyles": {
"message": "Stílusok kibontása..."
},
@ -1210,9 +1204,6 @@
"usercssReplaceTemplateConfirmation": {
"message": "Le legyen cserélve az alapértelmezett sablon az új Usercss stílusokhoz a jelenlegi kóddal?"
},
"usercssReplaceTemplateName": {
"message": "Az üres @name lecseréli az alapértelmezett sablont"
},
"usercssReplaceTemplateSectionBody": {
"message": "Írj kódot ide…"
},

View File

@ -1,6 +1,9 @@
{
"InaccessibleFileHint": {
"message": "Stylus non può accedere ad alcuni tipi di file (ad es. pdf & JSON)"
},
"addStyleLabel": {
"message": "Scrivi nuovo stile"
"message": "Scrivi un nuovo stile"
},
"addStyleTitle": {
"message": "Aggiungi stili"
@ -59,7 +62,7 @@
"message": "Autore"
},
"backupMessage": {
"message": "Seleziona un file o trascinalo in questa pagina."
"message": "Per importare il file di backup, selezionalo e rilascialo in questa pagina oppure utilizza il bottone Importa\n\nPer esportare un backup compatibile con Stylus versione 1.5.18 e oltre, selezionalo col tasto destro oppure shift-click il pulsante Esporta"
},
"bckpInstStyles": {
"message": "Esporta stili"
@ -124,6 +127,9 @@
"cm_theme": {
"message": "Tema"
},
"colorpickerSwitchFormatTooltip": {
"message": "Cambia formato: HEX -> RGB -> HSL.\nShift-click per invertire la direzione.\nAnche con i tasti PgUp (PaginaSu), PgDn (PaginaGiù)."
},
"colorpickerTooltip": {
"message": "Apri selettore colore"
},
@ -160,6 +166,18 @@
"confirmYes": {
"message": "Si"
},
"connectingDropboxNotAllowed": {
"message": "La connessione a Dropbox è disponibile soltanto nelle app installate direttamente dal webstore"
},
"copied": {
"message": "Copiato negli appunti"
},
"copy": {
"message": "Copia negli appunti"
},
"customNameHint": {
"message": "Inserisci qui un nome personalizzato per rinominare lo stile nell'interfaccia utente (UI) senza rompere i suoi aggiornamenti"
},
"dateInstalled": {
"message": "Data installazione"
},
@ -239,12 +257,6 @@
"findStyles": {
"message": "Trova stili"
},
"findStylesForSite": {
"message": "Trova più stili per questo sito"
},
"findStylesInlineTooltip": {
"message": "Visualizza risultati in questa finestra."
},
"genericAdd": {
"message": "Aggiungi"
},
@ -399,9 +411,6 @@
"liveReloadLabel": {
"message": "Ricaricamento live"
},
"manageFaviconsHelp": {
"message": "Stylus utilizza un servizio esterno https://www.google.com/s2/favicons"
},
"manageFilters": {
"message": "Filtri"
},
@ -488,6 +497,9 @@
"openManage": {
"message": "Gestisci gli stili installati"
},
"openOptions": {
"message": "Opzioni"
},
"openStylesManager": {
"message": "Apri gestore stili"
},
@ -626,6 +638,9 @@
"sectionRemove": {
"message": "Rimuovi sezione"
},
"sections": {
"message": "Sezioni"
},
"shortcuts": {
"message": "Scorciatoie"
},
@ -713,9 +728,6 @@
"styleRegexpProblemTooltip": {
"message": "Numero di sezioni non applicato a causa dell'uso errato di 'regexp()'"
},
"styleRegexpTestButton": {
"message": "Test RegExp"
},
"styleRegexpTestInvalid": {
"message": "Regexp invalida ignorata"
},
@ -754,6 +766,9 @@
"unreachableContentScript": {
"message": "Impossibile comunicare con la pagina. Prova a ricaricare la scheda."
},
"unreachableMozSiteHintOldFF": {
"message": "Solo Firefox 59 e successivi possono essere configurati per consentire alle WebExtensions di aggiungere elementi degli stili su siti CSP-protected come questo."
},
"updateAllCheckSucceededNoUpdate": {
"message": "Nessun aggiornamento trovato"
},

View File

@ -68,7 +68,7 @@
"message": "バックアップ"
},
"backupMessage": {
"message": "ファイルを選択するか、このページにドラッグ&ドロップしてください。"
"message": "バックアップファイルをインポートする場合、このページにドラッグ&ドロップするか、インポートボタンをクリックしてください。\nまた、Stylus 1.5.18 より古い形式でバックアップしたい場合は、エクスポートボタンを 右クリック もしくは shift-クリック してください。"
},
"bckpInstStyles": {
"message": "スタイルをエクスポート"
@ -226,9 +226,23 @@
"disableAllStyles": {
"message": "すべてのスタイルをオフにする"
},
"disableAllStylesOff": {
"message": "全スタイルをOFFにする"
},
"disableStyleLabel": {
"message": "無効化"
},
"draftAction": {
"message": "このデータをロードするならば「はい」を、破棄するならば「いいえ」を選択してください。"
},
"draftTitle": {
"message": "$date$に作成されたデータ",
"placeholders": {
"date": {
"content": "$1"
}
}
},
"dragDropMessage": {
"message": "このページの任意の場所にバックアップファイルをドロップしてインポートします。"
},
@ -255,6 +269,9 @@
}
}
},
"editorSettings": {
"message": "エディタ設定"
},
"enableStyleLabel": {
"message": "有効化"
},
@ -264,6 +281,9 @@
"excludeStyleByUrlLabel": {
"message": "現在のURLを除外"
},
"exportCompatible": {
"message": "エクスポート(互換モード)"
},
"exportLabel": {
"message": "エクスポート"
},
@ -302,15 +322,6 @@
"findStyles": {
"message": "スタイルを検索"
},
"findStylesForSite": {
"message": "このサイト用のスタイルを検索"
},
"findStylesInline": {
"message": "結果を下に表示"
},
"findStylesInlineTooltip": {
"message": "検索結果をこのウィンドウに表示"
},
"genericAdd": {
"message": "追加"
},
@ -344,6 +355,12 @@
"genericSavedMessage": {
"message": "保存しました"
},
"genericSize": {
"message": "サイズ"
},
"genericTest": {
"message": "テスト"
},
"genericTitle": {
"message": "タイトル"
},
@ -353,6 +370,9 @@
"gettingStyles": {
"message": "全スタイルを取得中..."
},
"headerResizerHint": {
"message": "この種のUIエディタ、管理、インストーラの中では、Shiftを押しながらリサイズしてください"
},
"helpAlt": {
"message": "ヘルプ"
},
@ -530,7 +550,7 @@
"message": "ファビコンをグレー表示"
},
"manageFaviconsHelp": {
"message": "Stylusは外部サービスを使用します https://www.google.com/s2/favicons"
"message": "Stylusは外部サービスを使用します https://icons.duckduckgo.com"
},
"manageFilters": {
"message": "フィルター"
@ -541,6 +561,9 @@
"manageMaxTargets": {
"message": "適用先欄の表示件数"
},
"manageMinColumnWidth": {
"message": "最小カラム幅 (ピクセル単位。9999にすると、マルチカラムモードを無効にします)"
},
"manageNewStyleAsUsercss": {
"message": "Usercssとして"
},
@ -790,6 +813,15 @@
"optionsAdvanced": {
"message": "上級者向け"
},
"optionsAdvancedAutoSwitchSchemeBySystem": {
"message": "システム設定による"
},
"optionsAdvancedAutoSwitchSchemeByTime": {
"message": "夜間時間による"
},
"optionsAdvancedAutoSwitchSchemeNever": {
"message": "無効。スタイルの暗い/明るい設定は無視されます。"
},
"optionsAdvancedContextDelete": {
"message": "エディタのコンテキストメニューに「削除」を追加する"
},
@ -799,6 +831,12 @@
"optionsAdvancedExposeIframesNote": {
"message": "各iframeにトップサイトドメインを公開します。\n次のようにiframe用のCSSを書くことができるようになります:\nhtml[stylus-iframe$$=\"twitter.com\"] h1 { display:none }"
},
"optionsAdvancedExposeStyleName": {
"message": "スタイル名を公開"
},
"optionsAdvancedExposeStyleNameNote": {
"message": "開発ツールでスタイルのデバッグを容易にするため、ページ内にスタイル名を公開します。タブをリロードして新しい設定を適用してください。"
},
"optionsAdvancedNewStyleAsUsercss": {
"message": "新しいスタイルを usercss として作成します"
},
@ -844,6 +882,9 @@
"optionsHeading": {
"message": "オプション"
},
"optionsIconAuto": {
"message": "暗い/明るいモード設定に合わせます"
},
"optionsIconDark": {
"message": "暗いブラウザのテーマ"
},
@ -866,7 +907,7 @@
"message": "オプションをリセット"
},
"optionsStylusThemes": {
"message": "StylusのUIテーマを見つける"
"message": "このページを含む任意のStylusのページで、ブラウザのツールバー内のStylusアイコンをクリックして、「スタイルを見つける」をクリックします"
},
"optionsSubheading": {
"message": "その他のオプション"
@ -883,6 +924,9 @@
"optionsSyncNone": {
"message": "未選択"
},
"optionsSyncPassword": {
"message": "パスワード"
},
"optionsSyncStatusConnected": {
"message": "接続状態"
},
@ -926,6 +970,9 @@
"optionsSyncSyncNow": {
"message": "すぐに同期"
},
"optionsSyncUsername": {
"message": "ユーザ名"
},
"optionsUpdateImportNote": {
"message": "旧バージョンまたはStylishからスタイルのバックアップをインポートする場合は、スタイルマネージャで一度手動で更新チェックを行い、すべてのスタイルが確実に更新されるようにしてください。"
},
@ -968,6 +1015,9 @@
"popupHotkeysTooltip": {
"message": "クリックすると使用可能なホットキーを表示します"
},
"popupManageSiteStyles": {
"message": "サイトのスタイルを管理"
},
"popupManageTooltip": {
"message": "シフトを押しながらクリック または 右クリック で、現在のサイトに適用可能なスタイルの管理画面を開きます"
},
@ -989,6 +1039,21 @@
"prefShowBadge": {
"message": "現在のサイトで有効なスタイルの数を表示"
},
"preferScheme": {
"message": "暗い/明るいモード設定"
},
"preferSchemeAlways": {
"message": "グローバルな暗い/明るいモード設定が無効になっているため、現在は無視されます(スタイルは常に適用されます)"
},
"preferSchemeDark": {
"message": "暗い"
},
"preferSchemeLight": {
"message": "明るい"
},
"preferSchemeNone": {
"message": "なし(常に適用)"
},
"previewLabel": {
"message": "自動プレビュー"
},
@ -1017,7 +1082,7 @@
"message": "スタイルを読み込み中..."
},
"reload": {
"message": "Stylus拡張をリロードする"
"message": "リロード"
},
"replace": {
"message": "置換"
@ -1028,12 +1093,18 @@
"replaceWith": {
"message": "次に置換"
},
"restoreTemplate": {
"message": "デフォルトのテンプレートに戻す。\n\n現在エディタで開いているものは変化しません。"
},
"retrieveBckp": {
"message": "スタイルをインポート"
},
"retrieveDropboxSync": {
"message": "Dropboxからインポート"
},
"saveAsTemplate": {
"message": "テンプレートとして保存"
},
"search": {
"message": "検索"
},
@ -1074,7 +1145,7 @@
"message": "週間インストール数"
},
"searchStyleQueryHint": {
"message": "スタイル名を大文字小文字の区別なく検索します:\n複数の単語 - 全単語を順番の区別なく検索します\n\"複数の単語からなるフレーズ\" - 正確なフレーズを (引用符は除いて) 検索します\n2020 - このように数値 (年) を指定すると、2020年に更新されたスタイルも結果に表示します"
"message": "スタイル名を検索します (大文字を使用すると、大文字小文字を区別して検索します) :\n複数の単語 - すべての単語を (順不同で) 含む\n\"複数の単語からなるフレーズ\" - 正確なフレーズを (引用符は除いて) 探す\n/foo.*bar/i - 正規表現 (空白は使用不可。空白を使いたい場合は、代わりに \\s を使ってください)"
},
"searchStylesAll": {
"message": "すべて"
@ -1109,12 +1180,18 @@
"sections": {
"message": "セクション"
},
"settings": {
"message": "設定"
},
"shortcuts": {
"message": "ショートカット"
},
"shortcutsNote": {
"message": "キーボードショートカットを定義する"
},
"shortcutsNoteFF": {
"message": "Firefox 66+ では、ビルトインのショートカットUIを手動で開けます。\n1ツールバーのStylusアイコンを右クリックして、「管理」を選択します。\nもしくは、メインメニューでabout:addonsを開くかCtrl-Shift-Aを押します\n2開いたページの右上隅にある歯車のアイコンをクリックします。\n3「拡張機能のショートカットの管理」を選択します。\n\nまた、ショートカットをここで設定することもできます。"
},
"sortDateNewestFirst": {
"message": "新しい順"
},
@ -1160,12 +1237,30 @@
"styleEnabledLabel": {
"message": "有効"
},
"styleExcludeLabel": {
"message": "含めないサイトを設定"
},
"styleFromMozillaFormatError": {
"message": "Mozilla形式のインポートに失敗しました"
},
"styleFromMozillaFormatPrompt": {
"message": "Mozilla形式のコードを貼り付ける"
},
"styleIncludeLabel": {
"message": "含めるサイトを設定"
},
"styleInjectionImportance": {
"message": "スタイルの重要度を設定/解除する"
},
"styleInjectionOrder": {
"message": "スタイルの適用順"
},
"styleInjectionOrderHint": {
"message": "ドラッグ&ドロップでスタイルの位置を変更できます。スタイルは表示の順番に適用されるため、リストのより下にあるスタイルは、上のものを上書きできます。"
},
"styleInjectionOrderHint_prio": {
"message": "以下に表示される重要なスタイルは、常に最後に挿入されるため、新しくインストールしたスタイルを上書きできます。スタイルをクリックして重要度を設定/解除してください。"
},
"styleInstall": {
"message": "「$stylename$」を Stylus にインストールしますか?",
"placeholders": {
@ -1205,6 +1300,15 @@
"styleNotAppliedRegexpProblemTooltip": {
"message": "'regexp()' の誤った使用のためスタイルを適用できませんでした"
},
"styleNotAppliedSchemeDark": {
"message": "スタイルはダークモード時のみ適用されます"
},
"styleNotAppliedSchemeLight": {
"message": "スタイルはライトモード時のみ適用されます"
},
"stylePreferSchemeLabel": {
"message": "暗い/明るい モード"
},
"styleRegexpInvalidExplanation": {
"message": "いくつかの 'regexp()' のルールはコンパイルできませんでした"
},
@ -1214,9 +1318,6 @@
"styleRegexpProblemTooltip": {
"message": "'regexp()' の誤った使用のためいくつかのセクションを適用できませんでした"
},
"styleRegexpTestButton": {
"message": "正規表現をテスト"
},
"styleRegexpTestFull": {
"message": "一致するタブ"
},
@ -1238,6 +1339,9 @@
"styleSaveLabel": {
"message": "保存"
},
"styleSettings": {
"message": "スタイル設定"
},
"styleToMozillaFormatHelp": {
"message": "Mozilla形式のコードは、userstyles.org に投稿することができ、また従来の Stylish for Firefox でも使用できます"
},
@ -1255,6 +1359,9 @@
"styleUpdateDiscardChanges": {
"message": "このスタイルはエディタの外部で変更されました。このスタイルをリロードしますか?"
},
"styleUpdateUrlLabel": {
"message": "更新URL"
},
"stylusUnavailableForURL": {
"message": "このページではStylusは動作しません。"
},
@ -1270,8 +1377,16 @@
"syncError": {
"message": "同期に失敗"
},
"syncErrorLock": {
"message": "データベースが使用中です。\nロック状態は$TIME$に解除されます。",
"placeholders": {
"time": {
"content": "$1"
}
}
},
"syncErrorRelogin": {
"message": "同期に失敗しました。\nStylusのオプション画面で、再ログインしてください :\n「切断」をクリック後、「接続」をクリック"
"message": "同期に失敗しました。ログアウトした可能性があります。\nStylusのオプション画面で再ログインしてください。"
},
"syncStorageErrorSaving": {
"message": "値を保存できません。テキストの量を減らしてください。"
@ -1362,9 +1477,6 @@
"usercssReplaceTemplateConfirmation": {
"message": "現在のコードで、新しいUsercssスタイルのデフォルト・テンプレートを置き換えますか"
},
"usercssReplaceTemplateName": {
"message": "@name が指定されていません"
},
"usercssReplaceTemplateSectionBody": {
"message": "ここにコードを挿入..."
},

View File

@ -67,9 +67,6 @@
"backupButtons": {
"message": "백업"
},
"backupMessage": {
"message": "파일을 선택하거나, 이 페이지로 파일을 드래그앤드롭하세요."
},
"bckpInstStyles": {
"message": "스타일 내보내기"
},
@ -136,6 +133,9 @@
"cm_theme": {
"message": "테마"
},
"colorpickerPaletteHint": {
"message": "견본을 우클릭하여 소스 코드와 번갈아 가며 확인"
},
"colorpickerSwitchFormatTooltip": {
"message": "16 진수-> RGB -> HSL 순서로 형식을 변환합니다.\nShift+클릭을 이용해 역순으로 변환할 수 있습니다.\nPgUp(PageUp), PgDn(PageDown) 키도 사용 가능합니다."
},
@ -302,21 +302,15 @@
"findStyles": {
"message": "스타일 찾기"
},
"findStylesForSite": {
"message": "현재 사이트에 맞는 스타일 찾기"
},
"findStylesInline": {
"message": "팝업창 내에서"
},
"findStylesInlineTooltip": {
"message": "이 창에서 검색 결과 표시"
},
"genericAdd": {
"message": "추가"
},
"genericClone": {
"message": "복제"
},
"genericDescription": {
"message": "설명"
},
"genericDisabledLabel": {
"message": "비활성화됨"
},
@ -445,9 +439,18 @@
"linkGetHelp": {
"message": "도움말"
},
"linkGetShareStyles": {
"message": "스타일 주고받기"
},
"linkGetShareStylesInfo": {
"message": "커뮤니티에 의해 새롭게 운영되는 userstyles.world 사이트는 userstyle 투고자들이 userstyle.org를 대체하기 위해 만들었습니다. userstyle.org는 지난 몇 년간 많은 투고자들이 스타일을 업데이트하는 것을 멈춰서 느리고 둔감해졌습니다."
},
"linkGetStyles": {
"message": "스타일 찾기"
},
"linkGetStylesInfo": {
"message": "본 아카이브 사이트는 느리고 응답이 늦는 userstyles.org를 백업하기 위해 Userstyle 커뮤니티 회원에 의해 제작되었습니다. 하루에 약 한 번 아카이브 내 콘텐츠가 갱신됩니다."
},
"linkStylusWiki": {
"message": "위키"
},
@ -518,7 +521,7 @@
"message": "회색으로 표시"
},
"manageFaviconsHelp": {
"message": "Stylus는 https://www.google.com/s2/favicons 외부 서비스를 이용합니다"
"message": "Stylus는 https://icons.duckduckgo.com 외부 서비스를 이용합니다"
},
"manageFilters": {
"message": "필터"
@ -724,6 +727,17 @@
}
}
},
"meta_unknownMetaTypo": {
"message": "혹시 @$keyOk$입니까? 알 수 없는 메타데이터: @$keyErr$",
"placeholders": {
"keyErr": {
"content": "$1"
},
"keyOk": {
"content": "$2"
}
}
},
"meta_unknownPreprocessor": {
"message": "알 수 없는 @preprocessor $preprocessor$",
"placeholders": {
@ -782,9 +796,15 @@
"optionsAdvancedPatchCsp": {
"message": "스타일 자원을 허용하도록 <code>CSP</code>패치하기"
},
"optionsAdvancedPatchCspNote": {
"message": "엄격한 <code>콘텐츠 보안 정책</code>(<code>Content-Security-Policy; CSP</code>)이 적용된 사이트에서 사진이나 글꼴이 포함된 스타일을 불러올 수 없는 경우 이 설정을 켜십시오.\n\n설정을 켜면 <code>CSP</code> 제한이 풀려, 필수적인 스타일 콘텐츠를 불러올 수 있도록 합니다. 이 설정은 잠재적인 보안 영향을 이해하고, 콘텐츠 모니터링 허용 시 발생하는 문제에 대한 책임을 질 수 있는 사용자에게만 권장됩니다. 자세한 정보를 알고 싶다면 CSS 기반 공격에 대해 알아 보십시오.\n\n또, 이 설정은 설치된 다른 확장 프로그램이 네트워크 응답을 먼저 수정하는 경우 작동하지 않을 수도 있으므로 이 점에 유의하십시오."
},
"optionsAdvancedStyleViaXhr": {
"message": "즉시 주입 모드"
},
"optionsAdvancedStyleViaXhrNote": {
"message": "만약 브라우징 도중 스타일이 적용되지 않은 콘텐츠가 깜빡거리며 나오는 경우(FOUC), 특히 다크 테마를 사용하는 중 눈에 두드러지게 깜빡이는 경우 이 설정을 켜십시오.\n\n기술적으로 Chrome/Chromium이 확장 프로그램과의 비동기 통신을 미루기 때문에 발생하는 문제이며, 페이지를 더 빨리 불러오려는 시도이지만 보통은 무의미하고 스타일이 늦게 적용되도록 하는 요인으로 작용합니다. 확장 프로그램에는 이를 회피하기 위한 동기형 API가 제공되지 않으므로, Stylus는 \"비권장\" 상태인 동기형 XMLHttpRquest 웹 API를 사용하여 스타일을 가져오는 설정을 제공합니다. 페이지를 서버에서 내려받는 몇 밀리초 내에 이런 과정이 끝나므로 로드 속도에는 악영향이 없습니다.\n\n그럼에도 불구하고 Chromium 브라우저에서는 개발자 도구의 콘솔에 경고를 출력할 것입니다. 경고를 우클릭하여 숨기면 이후에는 경고가 표시되지 않습니다."
},
"optionsBadgeDisabled": {
"message": "비활성화 시의 배경 색"
},
@ -836,9 +856,6 @@
"optionsResetButton": {
"message": "설정 초기화"
},
"optionsStylusThemes": {
"message": "스타일러스 UI 테마 찾기"
},
"optionsSubheading": {
"message": "추가 옵션"
},
@ -966,12 +983,27 @@
"previewTooltip": {
"message": "변경 사항은 저장되지 않고 일시적으로 적용됩니다.\n영구적으로 변경하려면 스타일을 저장하세요."
},
"publish": {
"message": "배포"
},
"publishPush": {
"message": "업데이트 푸시"
},
"publishReconnect": {
"message": "연결을 해제한 뒤 배포를 다시 시도해보세요"
},
"publishRetry": {
"message": "Stylus에서는 계속 이 스타일을 배포하려고 하고 있습니다. 하지만 인증 창이 뜨지 않는 경우 다시 시도할 수 있습니다. 지금 다시 시도하시겠습니까?"
},
"publishStyle": {
"message": "스타일 배포"
},
"publishUsw": {
"message": "<userstyles.world> 사용"
},
"readingStyles": {
"message": "스타일 읽어들이는 중..."
},
"reload": {
"message": "Stylus 확장 프로그램 리로드"
},
"replace": {
"message": "바꾸기"
},
@ -1032,6 +1064,9 @@
"searchStylesCode": {
"message": "CSS 코드"
},
"searchStylesHelp": {
"message": "</> 또는 <Ctrl-F> 키를 누르면 검색창에 포커스합니다.\nDefault mode is plain text search for all space-separated terms in any order.\n정확한 단어 검색: 검색어를 큰따옴표로 감쌉니다. 예: <\".header ~ div\">\n정규표현식: 빗금 및 플래그 문자를 포함합니다. 예: </body.*?\\ba\\b/i>\nURL로 찾기: 완전히 특정된 URL에 적용되는 스타일을 검색합니다. 예: https://www.example.org/\n메타데이터로 찾기: 이름, \"적용 대상\" 지정자, 설치 URL, 업데이트 URL 등 usercss 스타일의 모든 메타데이터 블록을 기반으로 검색합니다."
},
"searchStylesMatchUrl": {
"message": "URL별"
},
@ -1146,6 +1181,9 @@
"styleMozillaFormatHeading": {
"message": "Mozilla 형식"
},
"styleName": {
"message": "스타일 이름"
},
"styleNotAppliedRegexpProblemTooltip": {
"message": "잘못된 'regexp()'의 사용으로 인해 스타일을 적용할 수 없습니다"
},
@ -1158,9 +1196,6 @@
"styleRegexpProblemTooltip": {
"message": "잘못된 'regexp()' 사용으로 인해 몇몇 섹션을 적용할 수 없습니다."
},
"styleRegexpTestButton": {
"message": "정규 표현식 테스트"
},
"styleRegexpTestFull": {
"message": "일치하는 탭 목록"
},
@ -1238,6 +1273,12 @@
"unreachableFileHint": {
"message": "Stylus가 file:// URL에 접근할 수 있도록 하려면 chrome://extensions 페이지에서 파일 URL에 대한 액세스를 허용해야 합니다."
},
"unreachableMozSiteHint": {
"message": "Firefox 60 이후의 버전에서는 <about:config> 내의 <extensions.webextensions.restrictedDomains>에서 이 도메인을 제거해야 합니다. "
},
"unreachableMozSiteHintOldFF": {
"message": "Firefox 59 버전 이상에서만 이처럼 CSP 보호 정책이 적용된 사이트에 웹 확장 기능으로 스타일 요소를 추가할 수 있도록 설정 가능합니다."
},
"unzipStyles": {
"message": "스타일 압축 푸는 중..."
},
@ -1297,9 +1338,6 @@
"usercssReplaceTemplateConfirmation": {
"message": "현재 코드로 새 Usercss 스타일의 기본 템플릿을 대체하시겠습니까?"
},
"usercssReplaceTemplateName": {
"message": "@name을 비우면 기본 템플릿이 대체됩니다."
},
"usercssReplaceTemplateSectionBody": {
"message": "코드를 여기 입력하세요"
},

View File

@ -62,13 +62,13 @@
"message": "Alle updates toepassen"
},
"author": {
"message": "Auteur"
"message": "Maker"
},
"backupButtons": {
"message": "Back-up"
},
"backupMessage": {
"message": "Selecteer een bestand of sleep het naar deze pagina."
"message": "Sleep het back-upbestand naar deze pagina of klik op de knop Importeren om het te importeren.\n\nRechtsklik of shift-klik op de knop Exporteren om een compatibele back-up voor Stylus ouder dan 1.5.18 te exporteren."
},
"bckpInstStyles": {
"message": "Stijlen exporteren"
@ -98,7 +98,7 @@
"message": "Automatisch aanvullen tijdens typen"
},
"cm_colorpicker": {
"message": "Kleurkiezer voor CSS-kleuren"
"message": "Kleurkiezers voor CSS-kleuren"
},
"cm_indentWithTabs": {
"message": "Tabs met slimme inspringing gebruiken"
@ -245,9 +245,23 @@
"disableAllStyles": {
"message": "Alle stijlen uitschakelen"
},
"disableAllStylesOff": {
"message": "Stijlen zijn uitgeschakeld"
},
"disableStyleLabel": {
"message": "Uitschakelen"
},
"draftAction": {
"message": "Klik op Ja om dit concept te laden, of op Nee om het te verwerpen."
},
"draftTitle": {
"message": "Conceptherstel; gemaakt: $date$",
"placeholders": {
"date": {
"content": "$1"
}
}
},
"dragDropMessage": {
"message": "Sleep uw back-upbestand naar deze pagina om het te importeren."
},
@ -274,6 +288,9 @@
}
}
},
"editorSettings": {
"message": "Editor-instellingen"
},
"enableStyleLabel": {
"message": "Inschakelen"
},
@ -283,6 +300,9 @@
"excludeStyleByUrlLabel": {
"message": "De huidige URL uitsluiten"
},
"exportCompatible": {
"message": "Exporteren (compatibele modus)"
},
"exportLabel": {
"message": "Exporteren"
},
@ -318,12 +338,6 @@
"findStyles": {
"message": "Stijlen zoeken"
},
"findStylesForSite": {
"message": "Meer stijlen voor deze website zoeken"
},
"findStylesInlineTooltip": {
"message": "Zoekresultaten binnen dit venster weergeven"
},
"genericAdd": {
"message": "Toevoegen"
},
@ -357,6 +371,12 @@
"genericSavedMessage": {
"message": "Opgeslagen"
},
"genericSize": {
"message": "Grootte"
},
"genericTest": {
"message": "Testen"
},
"genericTitle": {
"message": "Titel"
},
@ -366,6 +386,9 @@
"gettingStyles": {
"message": "Alle stijlen ophalen..."
},
"headerResizerHint": {
"message": "Houd Shift ingedrukt om alleen in dit type UI de grootte te wijzigen, m.a.w. editor, beheerder, installer"
},
"helpAlt": {
"message": "Hulp"
},
@ -540,7 +563,7 @@
"message": "Niet beschikbaar"
},
"manageFaviconsHelp": {
"message": "Stylus gebruikt een externe dienst: https://www.google.com/s2/favicons"
"message": "Stylus gebruikt een externe dienst: https://icons.duckduckgo.com"
},
"manageHeading": {
"message": "Geïnstalleerde stijlen"
@ -548,6 +571,9 @@
"manageMaxTargets": {
"message": "Aantal Van toepassing op-items"
},
"manageMinColumnWidth": {
"message": "Minimale kolombreedte (in pixels; 9999 schakelt de modus met meerdere kolommen uit)"
},
"manageNewStyleAsUsercss": {
"message": "als Usercss"
},
@ -797,6 +823,15 @@
"optionsAdvanced": {
"message": "Geavanceerd"
},
"optionsAdvancedAutoSwitchSchemeBySystem": {
"message": "Systeemvoorkeur volgen"
},
"optionsAdvancedAutoSwitchSchemeByTime": {
"message": "Door nachttijd:"
},
"optionsAdvancedAutoSwitchSchemeNever": {
"message": "Uitgeschakeld. De instelling voor donker/licht in stijlen wordt genegeerd."
},
"optionsAdvancedContextDelete": {
"message": "Verwijderen toevoegen in contextmenu van editor"
},
@ -806,6 +841,12 @@
"optionsAdvancedExposeIframesNote": {
"message": "Legt het bovenliggende domein van de website bloot in elk iframe.\nSchakelt schrijven in voor iframe-specifieke CSS, zoals:\nhtml[stylus-iframe$$=\"twitter.com\"] h1 { display:none }"
},
"optionsAdvancedExposeStyleName": {
"message": "Stijlnaam tonen"
},
"optionsAdvancedExposeStyleNameNote": {
"message": "Toont de stijlnaam in de pagina om het opsporen van stijlfouten in devtools mogelijk te maken. Vernieuw de tabbladen om de nieuwe instelling toe te passen."
},
"optionsAdvancedNewStyleAsUsercss": {
"message": "Nieuwe stijl schrijven als usercss"
},
@ -848,6 +889,9 @@
"optionsHeading": {
"message": "Opties"
},
"optionsIconAuto": {
"message": "Volgens de Donkere/Lichte modus"
},
"optionsIconDark": {
"message": "Donkere browserthemas"
},
@ -870,7 +914,7 @@
"message": "Standaardwaarden"
},
"optionsStylusThemes": {
"message": "Een UI-thema voor Stylus zoeken"
"message": "Klik op een willekeurige Stylus-pagina (waaronder deze) op het Stylus-pictogram in de browserwerkbalk, en klik daarna op Stijlen zoeken."
},
"optionsSubheading": {
"message": "Meer opties"
@ -887,6 +931,9 @@
"optionsSyncNone": {
"message": "Geen"
},
"optionsSyncPassword": {
"message": "Wachtwoord"
},
"optionsSyncStatusConnected": {
"message": "Gekoppeld"
},
@ -930,6 +977,9 @@
"optionsSyncSyncNow": {
"message": "Nu synchroniseren"
},
"optionsSyncUsername": {
"message": "Gebruikersnaam"
},
"optionsUpdateImportNote": {
"message": "Als u stijlen vanuit een oudere versie of vanuit Stylish importeert, controleer dan eenmalig op updates in de stijlbeheerder om er zeker van te zijn dat alle stijlen zijn bijgewerkt."
},
@ -972,6 +1022,9 @@
"popupHotkeysTooltip": {
"message": "Klik om beschikbare sneltoetsen te tonen"
},
"popupManageSiteStyles": {
"message": "Websitestijlen beheren"
},
"popupManageTooltip": {
"message": "Shift-klik of rechtsklik opent de beheerder met stijlen die op de huidige website van toepassing zijn"
},
@ -993,6 +1046,21 @@
"prefShowBadge": {
"message": "Aantal actieve stijlen voor de huidige website"
},
"preferScheme": {
"message": "Voorkeur voor Donkere/Lichte modus"
},
"preferSchemeAlways": {
"message": "Momenteel genegeerd (de stijl is altijd van toepassing), omdat de globale Donkere/Lichte modus is uitgeschakeld"
},
"preferSchemeDark": {
"message": "Donker"
},
"preferSchemeLight": {
"message": "Licht"
},
"preferSchemeNone": {
"message": "Geen (altijd toegepast)"
},
"previewLabel": {
"message": "Live-voorbeeld"
},
@ -1021,7 +1089,7 @@
"message": "Stijlen lezen..."
},
"reload": {
"message": "Stylus-extensie herladen"
"message": "Opnieuw laden"
},
"replace": {
"message": "Vervangen"
@ -1032,12 +1100,18 @@
"replaceWith": {
"message": "Vervangen door"
},
"restoreTemplate": {
"message": "De standaardsjabloon herstellen.\n\n(De momenteel geopende editorpaginas worden niet gewijzigd.)"
},
"retrieveBckp": {
"message": "Stijlen importeren"
},
"retrieveDropboxSync": {
"message": "Dropbox - Importeren"
},
"saveAsTemplate": {
"message": "Opslaan als sjabloon"
},
"search": {
"message": "Zoeken"
},
@ -1078,7 +1152,7 @@
"message": "Wekelijks aantal installaties"
},
"searchStyleQueryHint": {
"message": "Stijlnamen niet hoofdlettergevoelig doorzoeken:\nbepaalde woorden - alle woorden in willekeurige volgorde\n\"bepaalde woordgroep\" - deze exacte woordgroep zonder aanhalingstekens\n2020 - een jaar als dit toont ook stijlen die in 2020 zijn bijgewerkt"
"message": "Stijlnamen doorzoeken (hoofdlettergevoelig als een hoofdletter wordt gebruikt):\nenkele woorden - al deze woorden in willekeurige volgorde\n\"bepaalde woordgroep\" - deze exacte woordgroep zonder aanhalingstekens\n/foo.*bar/i - reguliere expressie zonder spaties (gebruik in plaats daarvan \\s)"
},
"searchStylesAll": {
"message": "Alles"
@ -1110,12 +1184,18 @@
"sections": {
"message": "Secties"
},
"settings": {
"message": "Instellingen"
},
"shortcuts": {
"message": "Sneltoetsen"
},
"shortcutsNote": {
"message": "Sneltoetsen definiëren"
},
"shortcutsNoteFF": {
"message": "In Firefox 66+ kunt u de ingebouwde UI voor sneltoetsen handmatig openen:\n1) klik met rechts op het Stylus-pictogram in de werkbalk en kies Extensie beheren\n(als alternatief kunt u about:addons openen via het hoofdmenu of Ctrl-Shift-A),\n2) klik in de pagina die wordt geopend op het tandwielpictogram in de rechterbovenhoek,\n3) kies Extensiesneltoetsen beheren.\n\nHier kunt u ook de sneltoetsen aanpassen."
},
"sortDateNewestFirst": {
"message": "nieuwste eerst"
},
@ -1161,12 +1241,30 @@
"styleEnabledLabel": {
"message": "Ingeschakeld"
},
"styleExcludeLabel": {
"message": "Eigen uitgesloten websites"
},
"styleFromMozillaFormatError": {
"message": "Importeren vanuit Mozilla-opmaak mislukt"
},
"styleFromMozillaFormatPrompt": {
"message": "Plak de code in Mozilla-opmaak"
},
"styleIncludeLabel": {
"message": "Eigen opgenomen websites"
},
"styleInjectionImportance": {
"message": "Urgentie van stijl bepalen"
},
"styleInjectionOrder": {
"message": "Stijlinjectievolgorde"
},
"styleInjectionOrderHint": {
"message": "Versleep een stijl om de positie ervan te wijzigen. Stijlen worden geïnjecteerd op basis van de onderstaande volgorde, dus een stijl die lager op de lijst staat, kan de eerdere stijlen vervangen."
},
"styleInjectionOrderHint_prio": {
"message": "Belangrijke stijlen hieronder worden altijd als laatste geïnjecteerd, zodat ze eventuele pas geïnstalleerde stijlen kunnen vervangen. Klik op het sterpictogram van een stijl om de urgentie ervan te bepalen."
},
"styleInstall": {
"message": "$stylename$ installeren in Stylus?",
"placeholders": {
@ -1209,6 +1307,15 @@
"styleNotAppliedRegexpProblemTooltip": {
"message": "Stijl is niet toegepast vanwege onjuist gebruik van regexp()"
},
"styleNotAppliedSchemeDark": {
"message": "Deze stijl wordt alleen in Donkere modus toegepast"
},
"styleNotAppliedSchemeLight": {
"message": "Deze stijl wordt alleen in Lichte modus toegepast"
},
"stylePreferSchemeLabel": {
"message": "Donkere/Lichte modus"
},
"styleRegexpInvalidExplanation": {
"message": "Sommige regexp()-regels konden niet worden gecompileerd."
},
@ -1218,9 +1325,6 @@
"styleRegexpProblemTooltip": {
"message": "Aantal secties dat niet wordt toegepast vanwege onjuist gebruik van regexp()"
},
"styleRegexpTestButton": {
"message": "RegExp-test"
},
"styleRegexpTestFull": {
"message": "Overeenkomende tabbladen"
},
@ -1237,11 +1341,14 @@
"message": "Niet volledig overeenkomend, dus overgeslagen"
},
"styleRegexpTestTitle": {
"message": "Lijst van overeenkomende geopende tabbladen (klik op de URL om de focus op het tabblad te leggen)"
"message": "Lijst met overeenkomende geopende tabbladen (klik op de URL om de focus op het tabblad te leggen)"
},
"styleSaveLabel": {
"message": "Opslaan"
},
"styleSettings": {
"message": "Stijlinstellingen"
},
"styleToMozillaFormatHelp": {
"message": "De Mozilla-opmaak van de code kan bij userstyles.org worden ingediend en met het klassieke Stylish voor Firefox worden gebruikt."
},
@ -1259,6 +1366,9 @@
"styleUpdateDiscardChanges": {
"message": "Deze stijl is buiten de editor om gewijzigd. Wilt u de stijl opnieuw laden?"
},
"styleUpdateUrlLabel": {
"message": "Update-URL"
},
"stylusUnavailableForURL": {
"message": "Stylus werkt niet op paginas als deze."
},
@ -1274,8 +1384,16 @@
"syncError": {
"message": "Synchronisatie mislukt"
},
"syncErrorLock": {
"message": "De database is al in gebruik. De vergrendeling vervalt om $TIME$.",
"placeholders": {
"time": {
"content": "$1"
}
}
},
"syncErrorRelogin": {
"message": "Synchronisatie mislukt.\nProbeer u opnieuw aan te melden in de Stylus-opties:\nklik eerst op ontkoppelen, daarna op koppelen."
"message": "Synchronisatie mislukt. U bent afgemeld.\nProbeer u opnieuw aan te melden in de Stylus-opties."
},
"syncStorageErrorSaving": {
"message": "De waarde kan niet worden opgeslagen. Probeer de hoeveelheid tekst te verminderen."
@ -1366,9 +1484,6 @@
"usercssReplaceTemplateConfirmation": {
"message": "Wilt u de standaardsjabloon voor nieuwe Usercss-stijlen vervangen door de huidige code?"
},
"usercssReplaceTemplateName": {
"message": "Lege @name vervangt de standaardsjabloon"
},
"usercssReplaceTemplateSectionBody": {
"message": "Voer hier code in..."
},

View File

@ -71,7 +71,7 @@
"message": "Kopia zapasowa"
},
"backupMessage": {
"message": "Wybierz plik lub przeciągnij i upuść go na tę stronę."
"message": "Aby zaimportować plik kopii zapasowej, przeciągnij go i upuść na tej stronie lub kliknij przycisk Importuj.\n\nAby wyeksportować kompatybilną kopię zapasową Stylusa w wersji starszej niż 1.5.18, kliknij prawym przyciskiem myszy lub kliknij z wciśniętym klawiszem Shift przycisk Eksportuj."
},
"bckpInstStyles": {
"message": "Eksportuj style"
@ -264,9 +264,23 @@
"disableAllStyles": {
"message": "Wyłącz wszystkie style"
},
"disableAllStylesOff": {
"message": "Style są wyłączone"
},
"disableStyleLabel": {
"message": "Wyłącz"
},
"draftAction": {
"message": "Wybierz 'Tak', aby załadować tę wersję roboczą lub 'Nie', aby ją odrzucić."
},
"draftTitle": {
"message": "Odzyskiwanie wersji roboczej, utworzonej $date$",
"placeholders": {
"date": {
"content": "$1"
}
}
},
"dragDropMessage": {
"message": "Upuść twój plik kopii zapasowej gdziekolwiek na tej stronie, aby zaimportować."
},
@ -293,6 +307,9 @@
}
}
},
"editorSettings": {
"message": "Ustawienia edytora"
},
"enableStyleLabel": {
"message": "Włącz"
},
@ -302,6 +319,9 @@
"excludeStyleByUrlLabel": {
"message": "Wyklucz bieżący adres URL"
},
"exportCompatible": {
"message": "Eksportuj (tryb kompatybilny)"
},
"exportLabel": {
"message": "Eksportuj"
},
@ -340,15 +360,6 @@
"findStyles": {
"message": "Znajdź style"
},
"findStylesForSite": {
"message": "Znajdź więcej stylów dla tej strony"
},
"findStylesInline": {
"message": "Wstawka"
},
"findStylesInlineTooltip": {
"message": "Wyświetlaj wyniki wyszukiwania w tym oknie."
},
"genericAdd": {
"message": "Dodaj"
},
@ -382,6 +393,12 @@
"genericSavedMessage": {
"message": "Zapisano"
},
"genericSize": {
"message": "Rozmiar"
},
"genericTest": {
"message": "Testuj"
},
"genericTitle": {
"message": "Tytuł"
},
@ -391,6 +408,9 @@
"gettingStyles": {
"message": "Uzyskiwanie wszystkich stylów..."
},
"headerResizerHint": {
"message": "Przytrzymaj Shift, aby zmienić rozmiar tylko w tego typu interfejsie, tj. edytorze, menedżerze, instalatorze"
},
"helpAlt": {
"message": "Pomoc"
},
@ -565,7 +585,7 @@
"message": "Wyszarzone"
},
"manageFaviconsHelp": {
"message": "Stylus korzysta z usługi zewnętrznej https://www.google.com/s2/favicons"
"message": "Stylus korzysta z usługi zewnętrznej https://icons.duckduckgo.com"
},
"manageFilters": {
"message": "Filtry"
@ -576,6 +596,9 @@
"manageMaxTargets": {
"message": "Liczba dotyczących elementów "
},
"manageMinColumnWidth": {
"message": "Minimalna szerokość kolumny (w pikselach; 9999 wyłącza tryb wielokolumnowy)"
},
"manageNewStyleAsUsercss": {
"message": "jako Usercss"
},
@ -825,6 +848,15 @@
"optionsAdvanced": {
"message": "Zaawansowane"
},
"optionsAdvancedAutoSwitchSchemeBySystem": {
"message": "Według preferencji systemowych"
},
"optionsAdvancedAutoSwitchSchemeByTime": {
"message": "W nocy:"
},
"optionsAdvancedAutoSwitchSchemeNever": {
"message": "Wyłączone. Ustawienie ciemny/jasny w stylach jest ignorowane."
},
"optionsAdvancedContextDelete": {
"message": "Dodaj 'Usuń' do menu kontekstowego edytora"
},
@ -834,6 +866,12 @@
"optionsAdvancedExposeIframesNote": {
"message": "Odsłania domenę najwyższego poziomu w każdym elemencie iframe.\nWłącza pisanie CSS specyficznych dla iframe w taki sposób:\nhtml[stylus-iframe$$=\"twitter.com\"] h1 { display:none }"
},
"optionsAdvancedExposeStyleName": {
"message": "Eksponuj nazwę stylu"
},
"optionsAdvancedExposeStyleNameNote": {
"message": "Eksponuje nazwę stylu na stronie, aby ułatwić debugowanie stylów w narzędziach dla twórców witryn. Załaduj ponownie kartę(-y), aby zastosować nowe ustawienie."
},
"optionsAdvancedNewStyleAsUsercss": {
"message": "Napisz nowy styl jako usercss"
},
@ -879,6 +917,9 @@
"optionsHeading": {
"message": "Opcje"
},
"optionsIconAuto": {
"message": "Dopasuj tryb ciemny/jasny"
},
"optionsIconDark": {
"message": "Ciemne motywy przeglądarki"
},
@ -901,7 +942,7 @@
"message": "Resetuj opcje"
},
"optionsStylusThemes": {
"message": "Znajdź motyw interfejsu Stylusa"
"message": "Kliknij ikonę Stylusa na pasku narzędzi przeglądarki na dowolnej stronie Stylusa, w tym tej, a następnie kliknij 'Znajdź style'"
},
"optionsSubheading": {
"message": "Więcej opcji"
@ -918,6 +959,9 @@
"optionsSyncNone": {
"message": "Brak"
},
"optionsSyncPassword": {
"message": "Hasło"
},
"optionsSyncStatusConnected": {
"message": "Połączono"
},
@ -961,6 +1005,12 @@
"optionsSyncSyncNow": {
"message": "Synchronizuj teraz"
},
"optionsSyncUrl": {
"message": "Adres URL"
},
"optionsSyncUsername": {
"message": "Nazwa użytkownika"
},
"optionsUpdateImportNote": {
"message": "Podczas importowania kopii zapasowych stylu ze starej wersji lub ze Stylish jednorazowo sprawdź aktualizacje ręcznie w menedżerze stylów, aby upewnić się, że wszystkie style są zaktualizowane."
},
@ -1003,6 +1053,9 @@
"popupHotkeysTooltip": {
"message": "Kliknij, aby zobaczyć dostępne skróty klawiszowe"
},
"popupManageSiteStyles": {
"message": "Zarządzaj stylami witryny"
},
"popupManageTooltip": {
"message": "Shift + kliknięcie lub kliknięcie prawym przyciskiem otwiera menedżera ze stylami obowiązującymi dla bieżącej witryny"
},
@ -1024,6 +1077,21 @@
"prefShowBadge": {
"message": "Liczba aktywnych stylów dla bieżącej witryny"
},
"preferScheme": {
"message": "Preferencje trybu ciemnego/jasnego"
},
"preferSchemeAlways": {
"message": "Obecnie ignorowane (styl zawsze obowiązuje), ponieważ globalny tryb ciemny/jasny jest wyłączony"
},
"preferSchemeDark": {
"message": "Ciemny"
},
"preferSchemeLight": {
"message": "Jasny"
},
"preferSchemeNone": {
"message": "Brak (zawsze stosowane)"
},
"previewLabel": {
"message": "Podgląd na żywo"
},
@ -1052,7 +1120,7 @@
"message": "Odczytywanie stylów..."
},
"reload": {
"message": "Przeładuj rozszerzenie Stylus"
"message": "Przeładuj"
},
"replace": {
"message": "Zamień"
@ -1063,12 +1131,18 @@
"replaceWith": {
"message": "Zamień na"
},
"restoreTemplate": {
"message": "Przywróć szablon domyślny.\n\n(Aktualnie otwarte strony edytora nie ulegną zmianie.)"
},
"retrieveBckp": {
"message": "Importuj style"
},
"retrieveDropboxSync": {
"message": "Importuj z Dropboksa"
},
"saveAsTemplate": {
"message": "Zapisz jako szablon"
},
"search": {
"message": "Szukaj"
},
@ -1109,7 +1183,7 @@
"message": "Tygodniowa liczba instalacji"
},
"searchStyleQueryHint": {
"message": "Szukaj nazw stylów bez rozróżniania wielkości liter:\njakieś słowa - wszystkie słowa w dowolnej kolejności\n\"jakieś zdanie\" - dokładnie to zdanie bez cudzysłowów\n2020 - rok jak ten pokazuje również style zaktualizowane w 2020"
"message": "Szukaj nazwy stylów (z uwzględnieniem wielkości liter, jeśli używana jest wielka litera):\njakieś słowa wszystkie te słowa w dowolnej kolejności\n\"jakaś fraza\" ta fraza bez cudzysłowów\n/foo.*bar/i wyrażenie regularne bez spacji (zamiast tego użyj \\s)"
},
"searchStylesAll": {
"message": "Wszystkie"
@ -1144,12 +1218,18 @@
"sections": {
"message": "Sekcje"
},
"settings": {
"message": "Ustawienia"
},
"shortcuts": {
"message": "Skróty"
},
"shortcutsNote": {
"message": "Zdefiniuj skróty klawiaturowe"
},
"shortcutsNoteFF": {
"message": "W przeglądarce Firefox 66+ możesz ręcznie otworzyć interfejs wbudowanych skrótów:\n1) kliknij prawym przyciskiem myszy ikonę Stylusa na pasku narzędzi i wybierz 'Zarządzaj'\n(alternatywnie otwórz about:addon z menu głównego lub Ctrl-Shift-A),\n2) na stronie, która się otworzy, kliknij ikonę koła zębatego w prawym górnym rogu,\n3) wybierz 'Zarządzaj skrótami rozszerzeń'.\n\nMożesz także dostosować skróty tutaj."
},
"sortDateNewestFirst": {
"message": "najpierw najnowsze"
},
@ -1195,12 +1275,30 @@
"styleEnabledLabel": {
"message": "Włączony"
},
"styleExcludeLabel": {
"message": "Niestandardowe wykluczone witryny"
},
"styleFromMozillaFormatError": {
"message": "Nie udało się zaimportować z formatu Mozilla"
},
"styleFromMozillaFormatPrompt": {
"message": "Wprowadź kod w formacie Mozilla"
},
"styleIncludeLabel": {
"message": "Niestandardowe uwzględnione witryny"
},
"styleInjectionImportance": {
"message": "Przełącz ważność stylu"
},
"styleInjectionOrder": {
"message": "Kolejność wstrzykiwania stylów"
},
"styleInjectionOrderHint": {
"message": "Przeciągnij i upuść styl, aby zmienić jego pozycję. Style są wstrzykiwane sekwencyjnie w kolejności pokazanej poniżej, dzięki czemu styl znajdujący się dalej na liście może zastąpić wcześniejsze style."
},
"styleInjectionOrderHint_prio": {
"message": "Ważne style wymienione poniżej są zawsze wstrzykiwane jako ostatnie, dzięki czemu mogą zastąpić nowo zainstalowane style. Kliknij oznaczenie stylu, aby zmienić jego ważność."
},
"styleInstall": {
"message": "Zainstalować '$stylename$' do Stylusa?",
"placeholders": {
@ -1243,6 +1341,15 @@
"styleNotAppliedRegexpProblemTooltip": {
"message": "Styl nie został zastosowany z powodu nieprawidłowego użycia 'regexp()'"
},
"styleNotAppliedSchemeDark": {
"message": "Ten styl jest stosowany tylko w trybie ciemnym"
},
"styleNotAppliedSchemeLight": {
"message": "Ten styl jest stosowany tylko w trybie jasnym"
},
"stylePreferSchemeLabel": {
"message": "Tryb ciemny/jasny"
},
"styleRegexpInvalidExplanation": {
"message": "Niektóre reguły 'regexp()', których nie można było w ogóle skompilować."
},
@ -1252,9 +1359,6 @@
"styleRegexpProblemTooltip": {
"message": "Liczba sekcji, które nie zostały zastosowane z powodu nieprawidłowego użycia 'regexp()'"
},
"styleRegexpTestButton": {
"message": "Test RegExp"
},
"styleRegexpTestFull": {
"message": "Dopasowane karty"
},
@ -1276,6 +1380,9 @@
"styleSaveLabel": {
"message": "Zapisz"
},
"styleSettings": {
"message": "Ustawienia stylu"
},
"styleToMozillaFormatHelp": {
"message": "Kod w formacie Mozilla może być przesłany do userstyles.org i użyty z klasycznym dodatkiem Stylish dla Firefoksa"
},
@ -1293,6 +1400,9 @@
"styleUpdateDiscardChanges": {
"message": "Styl zmieniono poza edytorem. Czy chcesz przeładować styl?"
},
"styleUpdateUrlLabel": {
"message": "Adres URL aktualizacji"
},
"stylusUnavailableForURL": {
"message": "Stylus nie działa na takich stronach."
},
@ -1308,8 +1418,16 @@
"syncError": {
"message": "Synchronizacja nie powiodła się"
},
"syncErrorLock": {
"message": "Baza danych jest już w użyciu. Blokada wygaśnie o $TIME$",
"placeholders": {
"time": {
"content": "$1"
}
}
},
"syncErrorRelogin": {
"message": "Synchronizacja nie powiodła się.\nSpróbuj ponownie zalogować się w opcjach Stylusa:\nkliknij najpierw 'rozłącz' , następnie 'połącz'."
"message": "Synchronizacja nie powiodła się. Wylogowano.\nSpróbuj ponownie zalogować się w opcjach Stylusa."
},
"syncStorageErrorSaving": {
"message": "Nie można zapisać wartości. Spróbuj zmniejszyć ilość tekstu."
@ -1400,9 +1518,6 @@
"usercssReplaceTemplateConfirmation": {
"message": "Zastąpić domyślny szablon dla nowych stylów Usercss aktualnym kodem?"
},
"usercssReplaceTemplateName": {
"message": "Puste @name zastępuje szablon domyślny"
},
"usercssReplaceTemplateSectionBody": {
"message": "Wstaw kod tutaj..."
},

View File

@ -64,9 +64,6 @@
"author": {
"message": "Autor"
},
"backupMessage": {
"message": "Selecione um arquivo ou arraste e solte nessa página."
},
"bckpInstStyles": {
"message": "Exportar estilos"
},
@ -124,6 +121,9 @@
"cm_selectByTokens": {
"message": "Clicar duas vezes seleciona tokens"
},
"cm_selectByTokensTooltip": {
"message": "Exemplos de tokens: .foo-bar-2 #aabbcc 0.32 !Important\nQuando desativado: as palavras delimitadas por pontuação são selecionadas."
},
"cm_smartIndent": {
"message": "Usar indentação inteligente"
},
@ -231,6 +231,9 @@
"disableAllStyles": {
"message": "Desativar todos os estilos"
},
"disableAllStylesOff": {
"message": "Estilos estão desligados"
},
"disableStyleLabel": {
"message": "Desativar"
},
@ -307,21 +310,15 @@
"findStyles": {
"message": "Encontrar estilos"
},
"findStylesForSite": {
"message": "Procurar mais estilos para este site"
},
"findStylesInline": {
"message": "Em linha"
},
"findStylesInlineTooltip": {
"message": "Mostrar resultados dentro dessa janela"
},
"genericAdd": {
"message": "Adicionar"
},
"genericClone": {
"message": "Clonar"
},
"genericDescription": {
"message": "Descrição"
},
"genericDisabledLabel": {
"message": "Desativado"
},
@ -510,27 +507,63 @@
"liveReloadInstallHintFF": {
"message": "Mantenha juntamente esta guia e a guia original abertas para atualizar automaticamente o estilo sob mudanças externas."
},
"liveReloadLabel": {
"message": "Recarregamento dinâmico"
},
"manageFavicons": {
"message": "Favicons em colunas de aplica-se a"
},
"manageFaviconsGray": {
"message": "Acinzentado(s)"
},
"manageFaviconsHelp": {
"message": "O Stylus usa um serviço externo https://icons.duckduckgo.com"
},
"manageFilters": {
"message": "Filtros"
},
"manageHeading": {
"message": "Estilos instalados"
},
"manageMaxTargets": {
"message": "Número de aplica-se a itens"
},
"manageNewStyleAsUsercss": {
"message": "como UserCSS"
},
"manageNewUI": {
"message": "Nova interface do gestor"
},
"manageOnlyDisabled": {
"message": "Somente estilos desativados"
},
"manageOnlyEnabled": {
"message": "Apenas estilos habilitados"
},
"manageOnlyExternal": {
"message": "Apenas estilos externos"
},
"manageOnlyLocal": {
"message": "Apenas estilos criados localmente"
},
"manageOnlyLocalTooltip": {
"message": "(os estilos não instalados através de uma página userstyles.org)"
},
"manageOnlyNonUsercss": {
"message": "Apenas estilos sem UserCSS"
},
"manageOnlyUpdates": {
"message": "Apenas com atualizações ou problemas"
},
"manageOnlyUsercss": {
"message": "Apenas estilos com UserCSS"
},
"menuShowBadge": {
"message": "Mostrar a contagem de estilos ativados"
},
"meta_invalidCheckboxDefault": {
"message": "Inválida @var checkbox: o valor deve ser 0 ou 1"
},
"meta_invalidNumber": {
"message": "Espera-se um número"
},
@ -601,6 +634,15 @@
"optionsActions": {
"message": "Ações"
},
"optionsAdvanced": {
"message": "Avançadas"
},
"optionsAdvancedContextDelete": {
"message": "Adicionar 'Eliminar' no menu de contexto do editor"
},
"optionsAdvancedExposeIframes": {
"message": "Expor iframes via HTML[stylus-iframe]"
},
"optionsAdvancedNewStyleAsUsercss": {
"message": "Escrever novo estilo como UserCSS"
},
@ -616,6 +658,12 @@
"optionsCheckUpdate": {
"message": "Verifique e instale todas as atualizações disponíveis"
},
"optionsCustomizeBadge": {
"message": "Distintivo no ícone da barra de ferramentas"
},
"optionsCustomizeIcon": {
"message": "Ícone da barra de ferramentas"
},
"optionsCustomizeSync": {
"message": "Sincronizar para a nuvem"
},
@ -625,6 +673,12 @@
"optionsHeading": {
"message": "Opções"
},
"optionsIconDark": {
"message": "Temas escuros do browser"
},
"optionsIconLight": {
"message": "Temas claros do browser"
},
"optionsOpen": {
"message": "Abrir"
},
@ -634,6 +688,12 @@
"optionsPopupWidth": {
"message": "Largura do popup (em pixels)"
},
"optionsReset": {
"message": "Restabelecer as opções aos valores predefinidos"
},
"optionsResetButton": {
"message": "Restabelecer opções"
},
"optionsSubheading": {
"message": "Mais Opções"
},
@ -646,6 +706,9 @@
"optionsSyncNone": {
"message": "Nenhum"
},
"optionsSyncPassword": {
"message": "Senha"
},
"optionsSyncStatusConnected": {
"message": "Conectado"
},
@ -664,20 +727,86 @@
"optionsSyncSyncNow": {
"message": "Sincronizar agora"
},
"optionsUpdateImportNote": {
"message": "Ao importar uma cópia de segurança de estilo da versão antiga ou do Stylish, faça uma verificação única de atualizações manualmente no gestor de estilos para garantir que todos os estilos sejam atualizados."
},
"optionsUpdateInterval": {
"message": "Intervalo de atualização automática do estilo de usuário em horas (especifique 0 para desativar)"
},
"overwriteFileExport": {
"message": "Você gostaria de substituir um arquivo existente?"
},
"paginationCurrent": {
"message": "Pagina atual"
},
"paginationEstimated": {
"message": "Número estimado de páginas"
},
"paginationNext": {
"message": "Próxima página"
},
"paginationPrevious": {
"message": "Pagina anterior"
},
"paginationTotal": {
"message": "Páginas totais"
},
"parseUsercssError": {
"message": "Não foi possível analisar o UserCSS:"
},
"popupBorders": {
"message": "Adicionar margens laterais brancas "
},
"popupBordersTooltip": {
"message": "Útil para temas escuros no novo Chrome, já que não pinta mais as margens laterais"
},
"popupHotkeysInfo": {
"message": "<1>- <9>,<0>, também no teclado numérico - alterna o Nth estilo (0 é 10)\n<A>- <Z>alterna o primeiro estilo com um nome que começa com a letra\n<Shift>abre o editor em vez de alternar\n<Numpad +>ativa estilos listados\n<Numpad >desativa estilos listados\n<Numpad *>e <`> (backtick) - alterna os estilos inicialmente ativados; não se aplica a estilos habilitados subsequentemente enquanto o popup está aberto, para que você possa restaurar a seleção inicial depois de testar o material: basta desabilitar todos e, em seguida, alternar, i.e. <Numpad ><Numpad *>\nMais informações no wiki"
},
"popupHotkeysTooltip": {
"message": "Clique para ver as teclas de atalho disponíveis"
},
"popupManageTooltip": {
"message": "Shift-clique ou clique com o botão direito abre o gestor com estilos aplicáveis ao site atual"
},
"popupOpenEditInWindow": {
"message": "Abra o editor em uma nova janela"
},
"popupOpenEditInWindowTooltip": {
"message": "Também ativado ao desanexar o separador do editor de uma janela do browser, e desativado por anexar um separador único do editor a outra janela."
},
"popupStylesFirst": {
"message": "Estilos antes de comandos"
},
"prefShowBadge": {
"message": "Número de estilos ativos para o site atual"
},
"preferSchemeDark": {
"message": "Escuro"
},
"preferSchemeLight": {
"message": "Claro"
},
"preferSchemeNone": {
"message": "Nenhum (sempre aplicado)"
},
"previewLabel": {
"message": "Pré-visualização dinâmica"
},
"previewTooltip": {
"message": "Temporariamente aplica as alterações sem guardar.\nGuarde o estilo para tornar as alterações permanentes."
},
"publish": {
"message": "Publicar"
},
"publishStyle": {
"message": "Publicar estilo"
},
"readingStyles": {
"message": "Lendo estilos..."
},
"reload": {
"message": "Recarregar a extensão do Stylus"
"message": "Recarregar"
},
"replace": {
"message": "Substituir"
@ -697,9 +826,39 @@
"search": {
"message": "Buscar"
},
"searchCaseSensitive": {
"message": "Sensível a maiúsculas e minúsculas"
},
"searchGlobalStyles": {
"message": "Também buscar estilos globais"
},
"searchNumberOfResults": {
"message": "Número de correspondências"
},
"searchNumberOfResults2": {
"message": "Número de correspondências no código e aplica-se a valores"
},
"searchRegexp": {
"message": "Use a sintaxe /re/ para busca por regexp"
},
"searchResultInstallCount": {
"message": "Instalações totais"
},
"searchResultNoneFound": {
"message": "Nenhum estilo encontrado para este site."
},
"searchResultRating": {
"message": "Classificação"
},
"searchResultUpdated": {
"message": "Atualizado"
},
"searchResultWeeklyCount": {
"message": "Instalações semanais"
},
"searchStylesCode": {
"message": "Código CSS"
},
"sectionAdd": {
"message": "Adicionar outra seção"
},
@ -709,9 +868,39 @@
"sectionRemove": {
"message": "Remover seção"
},
"sectionRestore": {
"message": "Restaurar secção removida"
},
"sections": {
"message": "Seções"
},
"shortcuts": {
"message": "Atalhos"
},
"shortcutsNote": {
"message": "Definir atalhos de teclado"
},
"sortDateNewestFirst": {
"message": "mais recente primeiro"
},
"sortDateOldestFirst": {
"message": "mais antigos primeiro"
},
"sortLabel": {
"message": "Selecione uma ordenação para aplicar aos estilos instalados"
},
"sortLabelTitleAsc": {
"message": "Título Ascendente"
},
"sortLabelTitleDesc": {
"message": "Título Descendente"
},
"sortStylesHelp": {
"message": "Escolha o tipo de ordenação a ser aplicado às entradas instaladas na lista suspensa de ordenação. A configuração predefinida aplica uma ordem crescente (A a Z) aos títulos de entrada. As ordenações dentro do grupo \"Título Decrescente\" aplicarão uma classificação decrescente (Z a A) ao título. Existem outras predefinições que permitirão classificar as entradas por vários critérios. Pense sobre isso como ordenar uma tabela com várias colunas e cada categoria em cada seleção (entre os sinais de mais) representa uma coluna ou grupo. Por exemplo, se a configuração for \"Ativado (primeiro) + Título\", as entradas serão ordenadas de modo que todas as entradas ativadas sejam classificadas no topo da lista, então uma classificação crescente de título de entrada (A a Z) será aplicada a ambas as entradas ativadas e desativadas separadamente."
},
"sortStylesHelpTitle": {
"message": "Ordenar conteúdos"
},
"styleBadRegexp": {
"message": "Expressão regular é inválida"
},
@ -721,6 +910,12 @@
"styleBeautifyHint": {
"message": "Dica: clique com o botão direito no botão \"Embelezar\" ou use o atalho de teclado definido para embelezar sem mostrar esse painel"
},
"styleBeautifyIndentConditional": {
"message": "Indentar @media, @supports"
},
"styleBeautifyPreserveNewlines": {
"message": "Preserve novas linhas"
},
"styleCancelEditLabel": {
"message": "Voltar ao gerenciamento"
},
@ -730,6 +925,12 @@
"styleEnabledLabel": {
"message": "Ativado"
},
"styleFromMozillaFormatError": {
"message": "Falha ao importar do formato Mozilla"
},
"styleFromMozillaFormatPrompt": {
"message": "Colar o código formato-Mozilla"
},
"styleInstall": {
"message": "Instalar \"$stylename$\" no Stylus?",
"placeholders": {
@ -738,18 +939,79 @@
}
}
},
"styleInstallFailed": {
"message": "Falha ao instalar o estilo de usuário!\n$error$",
"placeholders": {
"error": {
"content": "$1"
}
}
},
"styleInstallOverwrite": {
"message": "$stylename$já está instalado. Substituir?\nVersão:$oldVersion$-> $newVersion$",
"placeholders": {
"newVersion": {
"content": "$3"
},
"oldVersion": {
"content": "$2"
},
"stylename": {
"content": "$1"
}
}
},
"styleMissingName": {
"message": "Insira um nome"
},
"styleMozillaFormatHeading": {
"message": "Formato Mozilla"
},
"styleName": {
"message": "Nome do estilo"
},
"styleNotAppliedRegexpProblemTooltip": {
"message": "O estilo não foi aplicado devido ao uso incorreto de 'regexp ()'"
},
"stylePreferSchemeLabel": {
"message": "Modo Escuro/Claro"
},
"styleRegexpInvalidExplanation": {
"message": "Algumas regras de 'regexp()' que não puderam ser compiladas."
},
"styleRegexpPartialExplanation": {
"message": "Este estilo usa regexps parcialmente correspondentes em violação da <a href='https://developer.mozilla.org/docs/Web/CSS/@document'>CSS4 @document specification</a> que requer um URL correspondente inteiro. As secções de CSS afetadas não foram aplicadas nesta página. Este estilo foi provavelmente criado no Stylish-for-Chrome o qual verifica incorretamente as regras 'regexp()' desde a primeira versão (bug conhecido)."
},
"styleRegexpProblemTooltip": {
"message": "Número de secções não aplicadas devido ao uso incorreto de 'regexp ()'"
},
"styleRegexpTestFull": {
"message": "Separadores correspondentes"
},
"styleRegexpTestInvalid": {
"message": "Regexps inválidos ignorados"
},
"styleRegexpTestNone": {
"message": "Nenhum separador correspondente"
},
"styleRegexpTestNote": {
"message": "Nota: use um único \\ para escapar no campo de entrada regexp, que será automaticamente convertido para \\\\ no código de estilo conforme especificação para strings entre aspas em CSS."
},
"styleRegexpTestPartial": {
"message": "Não corresponde totalmente, portanto ignorado"
},
"styleRegexpTestTitle": {
"message": "Lista de separadores correspondentes abertos (clique no URL para focar no separador)"
},
"styleSaveLabel": {
"message": "Salvar"
},
"styleToMozillaFormatHelp": {
"message": "O formato Mozilla do código pode ser usado com o Stylish para Firefox e pode ser enviado para userstyles.org."
},
"styleToMozillaFormatTitle": {
"message": "Estilo no formato Mozilla"
},
"styleUpdate": {
"message": "Você tem certeza que quer atualizar '$stylename$'?",
"placeholders": {
@ -758,21 +1020,57 @@
}
}
},
"styleUpdateDiscardChanges": {
"message": "O estilo é alterado fora do editor. Gostaria de recarregar o estilo?"
},
"styleUpdateUrlLabel": {
"message": "Atualizar URL"
},
"stylusUnavailableForURL": {
"message": "O Stylus não funciona em páginas como esta."
},
"stylusUnavailableForURLdetails": {
"message": "Como precaução de segurança, o browser proíbe extensões de afetar as páginas embutidas (como chrome://version, a página de novo separador predefinido no Chrome 61, about:addons, e assim sucessivamente) tal como páginas de outras extensões. Cada browser também restringe acesso à sua própria galeria de extensões (como Chrome Web Store ou AMO)"
},
"syncDropboxStyles": {
"message": "Exportar para Dropbox"
},
"syncStorageErrorSaving": {
"message": "O valor não pode ser guardado. Tente reduzir a quantidade de texto."
},
"toggleStyle": {
"message": "Alternar estilo"
},
"undo": {
"message": "Desfazer"
},
"undoGlobal": {
"message": "Desfazer todas as seções"
},
"unreachableAMO": {
"message": "O Firefox proíbe o acesso ao site."
},
"unreachableAMOHint": {
"message": "Para permitir o acesso abra<about:config>,clique com o botão direito na lista, clique em \"Novo\", depois em \"Booleano\", cole <privacy.resistFingerprinting.block_mozAddonManager> e clique em OK,<true>,OK, recarregue a página <addons.mozilla.org>."
},
"unreachableContentScript": {
"message": "Não foi possível comunicar com a página. Tente recarregar o separador."
},
"unreachableFileHint": {
"message": "O Stylus pode aceder URLs file:// apenas se ativar a checkbox correspondente para a extensão Stylus na página chrome://extensions"
},
"unreachableMozSiteHintOldFF": {
"message": "Somente o Firefox 59 e o mais recente podem ser configurados para permitir que WebExtensions incluam elementos de estilo em sites protegidos por CSP como este."
},
"unzipStyles": {
"message": "Descompactando estilos..."
},
"updateAllCheckSucceededNoUpdate": {
"message": "Nenhuma atualização encontrada."
},
"updateAllCheckSucceededSomeEdited": {
"message": "Alguns estilos que podem ser atualizados não foram verificados para evitar perder possíveis edições locais. As atualizações podem ser forçadas ao verificar individualmente, ou fazendo outra verificação para todos os estilos (edições locais vão ser sobrescrevidas)"
},
"updateCheckFailBadResponseCode": {
"message": "A atualização falhou: o servidor respondeu com código $code$.",
"placeholders": {
@ -784,6 +1082,12 @@
"updateCheckFailServerUnreachable": {
"message": "A atualização falhou: servidor inacessível."
},
"updateCheckHistory": {
"message": "Histórico de verificação de atualizações"
},
"updateCheckManualUpdateForce": {
"message": "Instalar atualização (edições locais vão ser sobrescritas)"
},
"updateCheckManualUpdateHint": {
"message": "Forçar uma atualização irá sobrescrever qualquer alteração local."
},
@ -805,12 +1109,18 @@
"uploadingFile": {
"message": "Enviando arquivo..."
},
"usercssAvoidOverwriting": {
"message": "Por favor modifique o valor de @name ou @namespace para evitar sobrescrever um estilo existente."
},
"usercssConfigIncomplete": {
"message": "O estilo foi atualizado ou eliminado após a exibição do diálogo de configuração. Essas variáveis não foram guardadas para evitar corromper os metadados do estilo:"
},
"usercssEditorNamePlaceholder": {
"message": "Especificar @name no código"
},
"usercssReplaceTemplateConfirmation": {
"message": "Substituir o template padrão por novos estilos com UserCSS com o código atual?"
},
"usercssReplaceTemplateName": {
"message": "@nome vazio substitui o template padrão"
},
"usercssReplaceTemplateSectionBody": {
"message": "Insira o código aqui..."
},

View File

@ -1,4 +1,7 @@
{
"InaccessibleFileHint": {
"message": "Stylus não pode acessar alguns tipos de arquivos (ex: arquivos pdf e json)."
},
"addStyleLabel": {
"message": "Escrever novo estilo"
},
@ -64,9 +67,6 @@
"backupButtons": {
"message": "Cópia de segurança"
},
"backupMessage": {
"message": "Selecione um ficheiro ou arraste e solte-o nesta página."
},
"bckpInstStyles": {
"message": "Exportar estilos"
},
@ -133,6 +133,9 @@
"cm_theme": {
"message": "Tema"
},
"colorpickerPaletteHint": {
"message": "Clique com o botão direito em uma amostra para percorrer suas linhas de código"
},
"colorpickerSwitchFormatTooltip": {
"message": "Mudar formatos: HEX -> RGB -> HSL.\nShift-clique para inverter a direção.\nTambém através das teclas PgUp (PageUp), PgDn (PageDown)."
},
@ -178,6 +181,32 @@
"confirmYes": {
"message": "Sim"
},
"connectingDropbox": {
"message": "Conectando ao Dropbox..."
},
"connectingDropboxNotAllowed": {
"message": "Conectar ao Dropbox somente é disponível em apps instalados diretamente da loja web"
},
"copied": {
"message": "Copiado para a área de transferência"
},
"copy": {
"message": "Copiar para a área de transferência"
},
"customNameHint": {
"message": "Digite um nome personalizado para renomear o estilo na UI sem quebrar suas atualizações"
},
"customNameResetHint": {
"message": "Deixar de usar o nome personalizado, usar o próprio nome do estilo"
},
"dateAbbrYear": {
"message": "$value$a",
"placeholders": {
"value": {
"content": "$1"
}
}
},
"dateInstalled": {
"message": "Data de instalação"
},
@ -208,6 +237,9 @@
"dragDropMessage": {
"message": "Solte o ficheiro da sua cópia de segurança em qualquer sítio nesta página para importar."
},
"dragDropUsercssTabstrip": {
"message": "Para instalar o arquivo, solte-o na linha das abas (a área onde os títulos das abas são mostrados)."
},
"editDeleteText": {
"message": "Eliminar"
},
@ -231,9 +263,18 @@
"enableStyleLabel": {
"message": "Ativar"
},
"excludeStyleByDomainLabel": {
"message": "Excluir o domínio atual"
},
"excludeStyleByUrlLabel": {
"message": "Excluir a URL atual"
},
"exportLabel": {
"message": "Exportar"
},
"exportSavedSuccess": {
"message": "Arquivo salvo com sucesso"
},
"externalLink": {
"message": "Hiperligação externa"
},
@ -260,15 +301,6 @@
"findStyles": {
"message": "Localizar estilos"
},
"findStylesForSite": {
"message": "Encontrar mais estilos para este site"
},
"findStylesInline": {
"message": "inline"
},
"findStylesInlineTooltip": {
"message": "Exibir os resultados da pesquisa dentro desta janela."
},
"genericAdd": {
"message": "Adicionar"
},
@ -302,6 +334,9 @@
"genericUnknown": {
"message": "Desconhecido"
},
"gettingStyles": {
"message": "Obtendo todos os estilos..."
},
"helpAlt": {
"message": "Ajuda"
},
@ -311,6 +346,9 @@
"helpKeyMapHotkey": {
"message": "Prima uma tecla de atalho"
},
"hostDisabled": {
"message": "Este hospedeiro foi desabilitado devido a um bug na versão atual que o navegador utilizado se encontra"
},
"importAppendLabel": {
"message": "Acrescentar ao estilo"
},
@ -320,6 +358,12 @@
"importLabel": {
"message": "Importar"
},
"importPreprocessor": {
"message": "Estilos com <code>@preprocessor</code> não irão funcionar no modo clássico. Você pode trocar o editor para o modo UserCSS: 1) abre o gerenciador de estilos, 2) ative a caixa \"como UserCSS\", 3) clique \"Escrever novo estilo\"\n\nDeseja importar mesmo assim?"
},
"importPreprocessorTitle": {
"message": "Possível problema causado pelo @preprocessor"
},
"importReplaceLabel": {
"message": "Sobrescrever estilo"
},
@ -442,6 +486,12 @@
"liveReloadError": {
"message": "Ocorreu um erro ao vigiar o arquivo"
},
"liveReloadInstallHint": {
"message": "Mantenha esta guia aberta para atualizar automaticamente o estilo sob mudanças externas."
},
"liveReloadInstallHintFF": {
"message": "Mantenha juntamente esta guia e a guia original abertas para atualizar automaticamente o estilo sob mudanças externas."
},
"liveReloadLabel": {
"message": "Recarregamento dinâmico"
},
@ -452,7 +502,7 @@
"message": "Acinzentado(s)"
},
"manageFaviconsHelp": {
"message": "O Stylus usa um serviço externo https://www.google.com/s2/favicons"
"message": "O Stylus usa um serviço externo https://icons.duckduckgo.com"
},
"manageFilters": {
"message": "Filtros"
@ -496,12 +546,73 @@
"menuShowBadge": {
"message": "Mostrar a contagem de estilos ativados"
},
"meta_invalidCheckboxDefault": {
"message": "Inválida @var checkbox: o valor deve ser 0 ou 1"
},
"meta_invalidNumber": {
"message": "Espera-se um número"
},
"meta_invalidRange": {
"message": "@var inválido $type$: valor deve ser um número ou um vetor",
"placeholders": {
"type": {
"content": "$1"
}
}
},
"meta_invalidString": {
"message": "Espera-se um texto entre aspas"
},
"meta_invalidWord": {
"message": "Espera-se uma palavra"
},
"meta_missingChar": {
"message": "Caracteres esperados: $chars$",
"placeholders": {
"chars": {
"content": "$1"
}
}
},
"meta_missingMandatory": {
"message": "Metadata obrigatório não encontrado: $keys$",
"placeholders": {
"keys": {
"content": "$1"
}
}
},
"meta_unknownMeta": {
"message": "Metadata desconhecido: $key$",
"placeholders": {
"key": {
"content": "$1"
}
}
},
"meta_unknownVarType": {
"message": "Tipo desconhecido da variável @$varkey$: $vartype$",
"placeholders": {
"varkey": {
"content": "$1"
},
"vartype": {
"content": "$2"
}
}
},
"noFileToImport": {
"message": "Para importar seus estilos, você deve exportar primeiro."
},
"noStylesForSite": {
"message": "Nenhum estilo instalado para este site."
},
"openManage": {
"message": "Gerir"
},
"openOptions": {
"message": "Opções"
},
"openStylesManager": {
"message": "Abrir gestor de estilos"
},
@ -538,6 +649,9 @@
"optionsCustomizeIcon": {
"message": "Ícone da barra de ferramentas"
},
"optionsCustomizeSync": {
"message": "Sincronizar para a nuvem"
},
"optionsCustomizeUpdate": {
"message": "Atualizações"
},
@ -568,12 +682,42 @@
"optionsSubheading": {
"message": "Mais Opções"
},
"optionsSyncConnect": {
"message": "Conectar"
},
"optionsSyncDisconnect": {
"message": "Desconectar"
},
"optionsSyncNone": {
"message": "Nenhum"
},
"optionsSyncStatusConnected": {
"message": "Conectado"
},
"optionsSyncStatusConnecting": {
"message": "Conectando..."
},
"optionsSyncStatusDisconnected": {
"message": "Desconectado"
},
"optionsSyncStatusDisconnecting": {
"message": "Desconectando..."
},
"optionsSyncStatusSyncing": {
"message": "Sincronizando..."
},
"optionsSyncSyncNow": {
"message": "Sincronizar agora"
},
"optionsUpdateImportNote": {
"message": "Ao importar uma cópia de segurança de estilo da versão antiga ou do Stylish, faça uma verificação única de atualizações manualmente no gestor de estilos para garantir que todos os estilos sejam atualizados."
},
"optionsUpdateInterval": {
"message": "Intervalo de atualização automática do estilo de usuário em horas (especifique 0 para desativar)"
},
"overwriteFileExport": {
"message": "Você gostaria de substituir um arquivo existente?"
},
"paginationCurrent": {
"message": "Pagina atual"
},
@ -625,6 +769,9 @@
"previewTooltip": {
"message": "Temporariamente aplica as alterações sem guardar.\nGuarde o estilo para tornar as alterações permanentes."
},
"readingStyles": {
"message": "Lendo estilos..."
},
"replace": {
"message": "Substituir"
},
@ -637,6 +784,9 @@
"retrieveBckp": {
"message": "Importar estilos"
},
"retrieveDropboxSync": {
"message": "Importar do Dropbox"
},
"search": {
"message": "Pesquisar"
},
@ -679,6 +829,9 @@
"sectionRestore": {
"message": "Restaurar secção removida"
},
"sections": {
"message": "Secções"
},
"shortcuts": {
"message": "Atalhos"
},
@ -712,6 +865,9 @@
"styleBeautify": {
"message": "Embelezar"
},
"styleBeautifyHint": {
"message": "Dica: clique com o botão direito no botão \"Embelezar\" ou use o atalho de teclado definido para embelezar sem mostrar esse painel"
},
"styleBeautifyIndentConditional": {
"message": "Indentar @media, @supports"
},
@ -781,9 +937,6 @@
"styleRegexpProblemTooltip": {
"message": "Número de secções não aplicadas devido ao uso incorreto de 'regexp ()'"
},
"styleRegexpTestButton": {
"message": "Testar RegExp"
},
"styleRegexpTestFull": {
"message": "Separadores correspondentes"
},
@ -828,6 +981,9 @@
"stylusUnavailableForURLdetails": {
"message": "Como precaução de segurança, o browser proíbe extensões de afetar as páginas embutidas (como chrome://version, a página de novo separador predefinido no Chrome 61, about:addons, e assim sucessivamente) tal como páginas de outras extensões. Cada browser também restringe acesso à sua própria galeria de extensões (como Chrome Web Store ou AMO)"
},
"syncDropboxStyles": {
"message": "Exportar para Dropbox"
},
"syncStorageErrorSaving": {
"message": "O valor não pode ser guardado. Tente reduzir a quantidade de texto."
},
@ -852,6 +1008,12 @@
"unreachableFileHint": {
"message": "O Stylus pode aceder URLs file:// apenas se ativar a checkbox correspondente para a extensão Stylus na página chrome://extensions"
},
"unreachableMozSiteHintOldFF": {
"message": "Somente o Firefox 59 e o mais recente podem ser configurados para permitir que WebExtensions incluam elementos de estilo em sites protegidos por CSP como este."
},
"unzipStyles": {
"message": "Descompactando estilos..."
},
"updateAllCheckSucceededNoUpdate": {
"message": "Nenhuma atualização encontrada."
},
@ -893,6 +1055,9 @@
"updatesCurrentlyInstalled": {
"message": "Atualizações instaladas:"
},
"uploadingFile": {
"message": "Enviando arquivo..."
},
"usercssAvoidOverwriting": {
"message": "Por favor modifique o valor de @name ou @namespace para evitar sobrescrever um estilo existente."
},
@ -905,9 +1070,6 @@
"usercssReplaceTemplateConfirmation": {
"message": "Substituir o modelo predefinido para novos estilos de Usercss com o código atual?"
},
"usercssReplaceTemplateName": {
"message": "@name vazio substitui o modelo predefinido"
},
"usercssReplaceTemplateSectionBody": {
"message": "Insira o código aqui..."
},
@ -919,5 +1081,8 @@
},
"writeStyleForURL": {
"message": "este URL"
},
"zipStyles": {
"message": "Compactando estilos..."
}
}

View File

@ -61,9 +61,6 @@
"author": {
"message": "Autor"
},
"backupMessage": {
"message": "Selectați un fișier sau drag-and-drop aici"
},
"bckpInstStyles": {
"message": "Exportați teme"
},
@ -233,12 +230,6 @@
"findStyles": {
"message": "Găsiți teme"
},
"findStylesForSite": {
"message": "Gasiți mai multe teme pentru acest site."
},
"findStylesInlineTooltip": {
"message": "Arătați rezultatele căutării în această pagină."
},
"genericAdd": {
"message": "Adaugă"
},
@ -413,7 +404,7 @@
"message": "Hașurat"
},
"manageFaviconsHelp": {
"message": "Stylus folosește un serviciu extern https://www.google.com/s2/favicons"
"message": "Stylus folosește un serviciu extern https://icons.duckduckgo.com"
},
"manageFilters": {
"message": "Filtre"
@ -454,12 +445,18 @@
"menuShowBadge": {
"message": "Afișați numărul temelor active"
},
"meta_invalidCheckboxDefault": {
"message": "@var checkbox invalidă: valuarea trebuie să fie 0 sau 1"
},
"noStylesForSite": {
"message": "Nicio temă instalată pentru acest site."
},
"openManage": {
"message": "Managerul"
},
"openOptions": {
"message": "Opțiuni"
},
"openStylesManager": {
"message": "Deschideți managerul de teme"
},
@ -625,6 +622,9 @@
"sectionRestore": {
"message": "Restaurează o secțiune ștearsă"
},
"sections": {
"message": "Secțiuni"
},
"shortcutsNote": {
"message": "Creeați keyboard shortcuts"
},
@ -789,6 +789,9 @@
"unreachableFileHint": {
"message": "Stylus poate accesa file:// URLs doar când este activată opțiunea respectivă din pagina cu setări chrome://extensions"
},
"unreachableMozSiteHintOldFF": {
"message": "Doar Firefox 59 sau mai nou poate fi configurat să permită WebExtension-urilor să adauge elemente la site-uri CSP-protected precum acesta."
},
"updateAllCheckSucceededNoUpdate": {
"message": "Niciun update găsit."
},
@ -842,9 +845,6 @@
"usercssReplaceTemplateConfirmation": {
"message": "Înlocuiți tema de bază a formatului Usercss cu acest cod?"
},
"usercssReplaceTemplateName": {
"message": "@name este gol și înlocuiețte valoarea de bază"
},
"usercssReplaceTemplateSectionBody": {
"message": "Introduce cod aici..."
},

View File

@ -68,7 +68,7 @@
"message": "Резервное копирование"
},
"backupMessage": {
"message": "Нажмите «Импорт», чтобы выбрать файл или просто перетащите его на эту страницу"
"message": "Чтобы импортировать архив стилей, перетащите файл в эту страницу или нажмите кнопку Импорт.\n\nЧтобы экспортировать совместимый архив для старого Stylus ранее чем 1.5.18, кликните на кнопку Экспорт правой кнопкой мыши или с нажатой клавишей Shift."
},
"bckpInstStyles": {
"message": "Экспорт стилей"
@ -267,6 +267,17 @@
"disableStyleLabel": {
"message": "Отключить"
},
"draftAction": {
"message": "Выберите «Да» для загрузки черновика или «Нет», чтобы выкинуть его."
},
"draftTitle": {
"message": "Восстановление черновика, созданного $date$",
"placeholders": {
"date": {
"content": "$1"
}
}
},
"dragDropMessage": {
"message": "Перетащите файл с резервной копией стилей в любое место этой страницы, чтобы импортировать его."
},
@ -293,6 +304,9 @@
}
}
},
"editorSettings": {
"message": "Настройки редактирования"
},
"enableStyleLabel": {
"message": "Включить"
},
@ -302,6 +316,9 @@
"excludeStyleByUrlLabel": {
"message": "Исключить текущий URL"
},
"exportCompatible": {
"message": "Экспорт (режим совместимости)"
},
"exportLabel": {
"message": "Экспорт"
},
@ -340,15 +357,6 @@
"findStyles": {
"message": "Найти стили"
},
"findStylesForSite": {
"message": "Найти ещё стили для этого веб-сайта"
},
"findStylesInline": {
"message": "и показать здесь"
},
"findStylesInlineTooltip": {
"message": "Показывать найденные стили в этом окне."
},
"genericAdd": {
"message": "Добавить"
},
@ -382,6 +390,9 @@
"genericSavedMessage": {
"message": "Сохранено"
},
"genericTest": {
"message": "Тест"
},
"genericTitle": {
"message": "Имя"
},
@ -391,6 +402,9 @@
"gettingStyles": {
"message": "Получение всех стилей..."
},
"headerResizerHint": {
"message": "С клавишей Shift размер меняется только для такого же типа страниц, т.е. редактор, менеджер, установщик"
},
"helpAlt": {
"message": "Справка"
},
@ -486,9 +500,18 @@
"linkGetHelp": {
"message": "Помощь"
},
"linkGetShareStyles": {
"message": "Поиск/публикация стилей"
},
"linkGetShareStylesInfo": {
"message": "Новый сайт userstyles.world, созданный и развиваемый сообществом энтузиастов и авторов пользовательских стилей с целью заменить userstyles.org, который стал таким медленным и зависающим за последний год, что многие авторы перестали обновлять свои стили."
},
"linkGetStyles": {
"message": "Скачать стили"
},
"linkGetStylesInfo": {
"message": "Архивный сайт от одного энтузиаста и автора пользовательских стилей, зеркальная копия userstyles.org, ныне медленного и зависающего. Архив обновляется примерно раз в день."
},
"linkStylusWiki": {
"message": "Вики"
},
@ -559,7 +582,7 @@
"message": "Обесцвечивать"
},
"manageFaviconsHelp": {
"message": "Используется сторонний сервис https://www.google.com/s2/favicons"
"message": "Используется сторонний сервис https://icons.duckduckgo.com"
},
"manageFilters": {
"message": "Фильтры"
@ -819,6 +842,15 @@
"optionsAdvanced": {
"message": "Другое"
},
"optionsAdvancedAutoSwitchSchemeBySystem": {
"message": "По настройке операционной системы"
},
"optionsAdvancedAutoSwitchSchemeByTime": {
"message": "В ночное время:"
},
"optionsAdvancedAutoSwitchSchemeNever": {
"message": "Отключен. Настройка режима в стилях игнорируется."
},
"optionsAdvancedContextDelete": {
"message": "Показывать команду \"Удалить\" в контекстном меню редактора"
},
@ -828,6 +860,12 @@
"optionsAdvancedExposeIframesNote": {
"message": "Выставляет верхний домен сайта в каждом iframe.\nПозволяет писать iframe-specific CSS следующим образом:\nhtml[stylus-iframe$$=\"twitter.com\"] h1 { display:none }"
},
"optionsAdvancedExposeStyleName": {
"message": "Проставлять имя стиля"
},
"optionsAdvancedExposeStyleNameNote": {
"message": "Проставляет имя стиля внутри страницы чтобы облегчить отладку стилей в инструментах разработчика (devtools). Чтобы применить новую настройку пожалуйста обновите вкладку со страницей."
},
"optionsAdvancedNewStyleAsUsercss": {
"message": "Создавать стили в формате usercss"
},
@ -873,6 +911,9 @@
"optionsHeading": {
"message": "Настройки"
},
"optionsIconAuto": {
"message": "В соответствии с ночным/дневным режимом"
},
"optionsIconDark": {
"message": "Тёмный интерфейс браузера"
},
@ -895,7 +936,7 @@
"message": "Сброс настроек"
},
"optionsStylusThemes": {
"message": "Найти тему интерфейса Stylus"
"message": "Нажмите иконку Stylus в верхней панели браузера на любой странице Stylus, в том числе и этой, затем нажмите «Найти стили»"
},
"optionsSubheading": {
"message": "Дополнительно"
@ -912,6 +953,9 @@
"optionsSyncNone": {
"message": "Ничего"
},
"optionsSyncPassword": {
"message": "Пароль"
},
"optionsSyncStatusConnected": {
"message": "Подключено"
},
@ -955,6 +999,12 @@
"optionsSyncSyncNow": {
"message": "Синхронизировать"
},
"optionsSyncUrl": {
"message": "URL адрес"
},
"optionsSyncUsername": {
"message": "Имя"
},
"optionsUpdateImportNote": {
"message": "После импорта базы стилей из старой версии или из Stylish запустите проверку на обновления из менеджера стилей, чтобы удостовериться в обновлении всех стилей."
},
@ -997,6 +1047,9 @@
"popupHotkeysTooltip": {
"message": "Показать горячие клавиши"
},
"popupManageSiteStyles": {
"message": "Управлять стилями сайта"
},
"popupManageTooltip": {
"message": "Shift-ЛКМ или ПКМ откроет менеджер с стилями только для этого сайта."
},
@ -1018,6 +1071,21 @@
"prefShowBadge": {
"message": "Показывать количество активных стилей для открытого сайта"
},
"preferScheme": {
"message": "Ночной/дневной режим"
},
"preferSchemeAlways": {
"message": "Пока что игнорируется (стиль всегда включен), т.к. общий режим ночи/дня отключен"
},
"preferSchemeDark": {
"message": "Ночной"
},
"preferSchemeLight": {
"message": "Дневной"
},
"preferSchemeNone": {
"message": "Нет (всегда включен)"
},
"previewLabel": {
"message": "Предпросмотр"
},
@ -1045,9 +1113,6 @@
"readingStyles": {
"message": "Чтение стилей..."
},
"reload": {
"message": "Перезагрузить расширение Stylus"
},
"replace": {
"message": "Заменить"
},
@ -1057,12 +1122,18 @@
"replaceWith": {
"message": "Заменить на"
},
"restoreTemplate": {
"message": "Восстановить шаблон по-умолчанию.\n\n(Не влияет на уже открытые страницы редактирования)"
},
"retrieveBckp": {
"message": "Импорт стилей"
},
"retrieveDropboxSync": {
"message": "Импорт Dropbox"
},
"saveAsTemplate": {
"message": "Сохранить как шаблон"
},
"search": {
"message": "Поиск"
},
@ -1102,9 +1173,6 @@
"searchResultWeeklyCount": {
"message": "Загрузок за неделю"
},
"searchStyleQueryHint": {
"message": "Поиск стилистических имён по падежам:\nнекоторые слова - все слова в любом порядке\n\"какая-то фраза\" - именно эта фраза без кавычек\n2020 - такой год также показывает стили, обновлённые в 2020 году"
},
"searchStylesAll": {
"message": "Все"
},
@ -1138,12 +1206,18 @@
"sections": {
"message": "Разделы"
},
"settings": {
"message": "Настройки"
},
"shortcuts": {
"message": "Клавиши"
},
"shortcutsNote": {
"message": "Назначить клавишу"
},
"shortcutsNoteFF": {
"message": "В Firefox 66+ вы можете открыть интерфейс клавиатурных сочетаний самостоятельно:\n1) правой кнопкой мыши на иконке Stylus в панели браузера, затем «Менеджер»\n(либо откройте about:addons из главного меню или нажмите Ctrl-Shift-A),\n2) на странице, которая откроется, нажмите иконку шестеренки в правом верхнем углу,\n3) выберите «Управление горячими клавишами расширений».\n\nТакже настроить клавиши можно и здесь."
},
"sortDateNewestFirst": {
"message": "новые сверху"
},
@ -1189,12 +1263,30 @@
"styleEnabledLabel": {
"message": "Включено"
},
"styleExcludeLabel": {
"message": "Личный список исключенных сайтов"
},
"styleFromMozillaFormatError": {
"message": "Ошибка импорта формата Mozilla"
},
"styleFromMozillaFormatPrompt": {
"message": "Вставьте содержимое стиля в формате Mozilla"
},
"styleIncludeLabel": {
"message": "Личный список включенных сайтов"
},
"styleInjectionImportance": {
"message": "Переключить важность стиля"
},
"styleInjectionOrder": {
"message": "Порядок применения стилей"
},
"styleInjectionOrderHint": {
"message": "Перетащите стиль для изменения его позиции. Стили применяются последовательно в нижеуказанном порядке, так что последующий стиль может изменить эффект предыдущих."
},
"styleInjectionOrderHint_prio": {
"message": "Важные стили всегда применяются после новоустановленных стилей, чтобы иметь «последнее слово». Для изменения важности стиля нажмите на его значок."
},
"styleInstall": {
"message": "Установить \"$stylename$\" в Stylus?",
"placeholders": {
@ -1237,6 +1329,15 @@
"styleNotAppliedRegexpProblemTooltip": {
"message": "Стиль не был применён из-за некорректного regexp()"
},
"styleNotAppliedSchemeDark": {
"message": "Стиль активен только в ночном режиме"
},
"styleNotAppliedSchemeLight": {
"message": "Стиль активен только в дневном режиме"
},
"stylePreferSchemeLabel": {
"message": "Ночной/дневной режим"
},
"styleRegexpInvalidExplanation": {
"message": "Некоторые 'regexp()' выражения не удалось скомпилировать."
},
@ -1246,9 +1347,6 @@
"styleRegexpProblemTooltip": {
"message": "Кол-во пропущенных разделов из-за неправильного regexp()"
},
"styleRegexpTestButton": {
"message": "Тест регулярки"
},
"styleRegexpTestFull": {
"message": "Соответствующие вкладки"
},
@ -1270,6 +1368,9 @@
"styleSaveLabel": {
"message": "Сохранить"
},
"styleSettings": {
"message": "Настройки стиля"
},
"styleToMozillaFormatHelp": {
"message": "Формат кода Mozilla можно отправлять на сайт userstyles.org и использовать в дополнении Stylish для Firefox."
},
@ -1287,6 +1388,9 @@
"styleUpdateDiscardChanges": {
"message": "Стиль был изменён вне редактора. Перезагрузить?"
},
"styleUpdateUrlLabel": {
"message": "URL адрес обновлений"
},
"stylusUnavailableForURL": {
"message": "Такие адреса не поддерживаются."
},
@ -1302,8 +1406,16 @@
"syncError": {
"message": "Сбой синхронизации"
},
"syncErrorLock": {
"message": "Хранилище данных уже занято. Доступ закрыт до $TIME$",
"placeholders": {
"time": {
"content": "$1"
}
}
},
"syncErrorRelogin": {
"message": "Синхронизация не удалась.\nПопробуйте повторно войти в систему в опциях Stylus:\nсначала нажмите \"отсоединить\", затем \"подключить\"."
"message": "Ошибка синхронизации. Произведен выход из учетной записи.\n\nПопробуйте подключиться еще раз в настройках Stylus."
},
"syncStorageErrorSaving": {
"message": "Ошибка сохранения. Попробуйте уменьшить количество текста."
@ -1394,9 +1506,6 @@
"usercssReplaceTemplateConfirmation": {
"message": "Заменить шаблон по умолчанию для нового стиля в формате Usercss текущим кодом?"
},
"usercssReplaceTemplateName": {
"message": "Пустой @name заменяет шаблон по умолчанию"
},
"usercssReplaceTemplateSectionBody": {
"message": "Место для CSS кода..."
},

View File

@ -76,9 +76,15 @@
"cm_theme": {
"message": "Тема"
},
"confirmDelete": {
"message": "Избриши"
},
"confirmNo": {
"message": "Не"
},
"confirmSave": {
"message": "Сачувај"
},
"confirmStop": {
"message": "Заустави"
},
@ -106,6 +112,9 @@
"disableStyleLabel": {
"message": "Онемогући"
},
"editDeleteText": {
"message": "Избриши"
},
"editGotoLine": {
"message": "Иди на ред (или line:col)"
},
@ -129,8 +138,11 @@
"exportLabel": {
"message": "Извези"
},
"findStylesForSite": {
"message": "Пронађи још стилова за овај сајт"
"genericAdd": {
"message": "Додај"
},
"genericEnabledLabel": {
"message": "Омогућено"
},
"helpAlt": {
"message": "Помоћ"
@ -194,9 +206,15 @@
"openManage": {
"message": "Управљај инсталираним стиловима"
},
"openOptions": {
"message": "Опције"
},
"optionsHeading": {
"message": "Опције"
},
"optionsSyncUrl": {
"message": "УРЛ"
},
"popupStylesFirst": {
"message": "Излистај стилове пре команди у менију дугмета на алатној траци"
},
@ -227,6 +245,9 @@
"sectionRemove": {
"message": "Уклони одељак"
},
"sections": {
"message": "Одељци"
},
"styleBadRegexp": {
"message": "Регуларни израз је неисправан."
},

View File

@ -70,9 +70,6 @@
"backupButtons": {
"message": "Säkerhetskopiera"
},
"backupMessage": {
"message": "Välj en fil eller dra och släpp till den här sidan."
},
"bckpInstStyles": {
"message": "Exportera stilar"
},
@ -290,12 +287,6 @@
"findStyles": {
"message": "Hitta stilar"
},
"findStylesForSite": {
"message": "Hitta fler stilar för denna webbplats"
},
"findStylesInlineTooltip": {
"message": "Visa sökresultat i det här fönstret."
},
"genericAdd": {
"message": "Lägg till"
},
@ -482,7 +473,7 @@
"message": "Nedtonade"
},
"manageFaviconsHelp": {
"message": "Stylus använder en extern tjänst https://www.google.com/s2/favicons"
"message": "Stylus använder en extern tjänst https://icons.duckduckgo.com"
},
"manageFilters": {
"message": "Filter"
@ -824,6 +815,9 @@
"optionsSyncSyncNow": {
"message": "Synkronisera nu"
},
"optionsSyncUrl": {
"message": "Webbadress"
},
"optionsUpdateImportNote": {
"message": "När du importerar säkerhetskopior av stilar från gammal version eller från Stylish, gör en engångskontroll för uppdateringar manuellt i stilhanteraren för att säkerställa att alla stilar uppdateras."
},
@ -962,6 +956,9 @@
"sectionRestore": {
"message": "Återställ borttagen sektion"
},
"sections": {
"message": "Sektioner"
},
"shortcuts": {
"message": "Genvägar"
},
@ -1061,9 +1058,6 @@
"styleRegexpProblemTooltip": {
"message": "Antal avsnitt som inte tillämpas på grund av felaktig användning av \"regexp()\""
},
"styleRegexpTestButton": {
"message": "RegExp-test"
},
"styleRegexpTestFull": {
"message": "Matchande flikar"
},
@ -1135,6 +1129,9 @@
"unreachableFileHint": {
"message": "Stylus kan endast komma åt fil:// webbadresser om du aktiverar motsvarande kryssruta för Stylus-tillägg på chrome://extensions-sidan."
},
"unreachableMozSiteHintOldFF": {
"message": "Endast Firefox 59 och nyare kan konfigureras för att tillåta WebExtensions att lägga till stilelement på CSP-skyddade webbplatser som den här."
},
"unzipStyles": {
"message": "Packar upp stilar..."
},
@ -1194,9 +1191,6 @@
"usercssReplaceTemplateConfirmation": {
"message": "Ersätt standardmallen för nya Usercss-stilar med den aktuella koden?"
},
"usercssReplaceTemplateName": {
"message": "Tom @name ersätter standardmallen"
},
"usercssReplaceTemplateSectionBody": {
"message": "Lägg in kod här..."
},

View File

@ -22,6 +22,12 @@
"appliesToEverything": {
"message": "అన్నిటికీ"
},
"confirmDelete": {
"message": "తొలగించు"
},
"confirmSave": {
"message": "భద్రపరచు"
},
"deleteStyleConfirm": {
"message": "మీరు నజంగానే ఈ శైలిని తొలగించాలనుకుంటున్నారా?"
},
@ -31,12 +37,18 @@
"disableStyleLabel": {
"message": "అచేతనించు"
},
"editDeleteText": {
"message": "తొలగించు"
},
"editStyleLabel": {
"message": "మార్చు"
},
"enableStyleLabel": {
"message": "చేతనించు"
},
"genericAdd": {
"message": "చేర్చు"
},
"helpAlt": {
"message": "సహాయం"
},
@ -46,6 +58,9 @@
"manageTitle": {
"message": "స్టైలిష్"
},
"sections": {
"message": "విభాగాలు"
},
"styleSaveLabel": {
"message": "భద్రపరచు"
}

View File

@ -58,9 +58,6 @@
"backupButtons": {
"message": "Yedek"
},
"backupMessage": {
"message": "Bir dosya seçin veya bu sayfaya sürükleyip bırakın."
},
"bckpInstStyles": {
"message": "Dışa aktar"
},
@ -287,15 +284,6 @@
"findStyles": {
"message": "Stil bul"
},
"findStylesForSite": {
"message": "Bu site için başka stiller bul"
},
"findStylesInline": {
"message": "Hizada"
},
"findStylesInlineTooltip": {
"message": "Arama sonuçlarını bu pencerede görüntüleyin."
},
"genericAdd": {
"message": "Ekle"
},
@ -426,7 +414,7 @@
"message": "Gri renkte"
},
"manageFaviconsHelp": {
"message": "Stylus harici bir servis kullanır https://www.google.com/s2/favicons"
"message": "Stylus harici bir servis kullanır https://icons.duckduckgo.com"
},
"manageFilters": {
"message": "Filtreler"
@ -464,6 +452,9 @@
"openManage": {
"message": "Yüklü stilleri yönet"
},
"openOptions": {
"message": "Seçenekler"
},
"openStylesManager": {
"message": "Stil yöneticisini aç"
},
@ -611,6 +602,9 @@
"sectionRemove": {
"message": "Bölümü kaldır"
},
"sections": {
"message": "Bölümler"
},
"shortcuts": {
"message": "Kısayollar"
},
@ -664,9 +658,6 @@
"styleRegexpProblemTooltip": {
"message": "'Regexp ()' yanlış kullanımı nedeniyle uygulanmayan bölüm sayısı"
},
"styleRegexpTestButton": {
"message": "RegExp testi"
},
"styleRegexpTestFull": {
"message": "Eşleşen sekmeler"
},
@ -782,9 +773,6 @@
"usercssReplaceTemplateConfirmation": {
"message": "Yeni Usercss stilleri için varsayılan şablonu geçerli kodla değiştir?"
},
"usercssReplaceTemplateName": {
"message": "Boş @name, varsayılan şablonun yerini alır"
},
"usercssReplaceTemplateSectionBody": {
"message": "Kodu buraya ekle..."
},

View File

@ -61,9 +61,6 @@
"backupButtons": {
"message": "Резервне копіювання"
},
"backupMessage": {
"message": "Виберіть файл або перетягніть на цю сторінку."
},
"bckpInstStyles": {
"message": "Експорт стилів"
},
@ -100,18 +97,12 @@
"disableStyleLabel": {
"message": "Вимкнути"
},
"editDeleteText": {
"message": "Видалити"
},
"findStyles": {
"message": "Знайти стилі"
},
"findStylesForSite": {
"message": "Знайти більше стилів для цього сайту"
},
"findStylesInline": {
"message": "і показати тут"
},
"findStylesInlineTooltip": {
"message": "Показувати знайдені стилі в цьому вікні."
},
"genericAdd": {
"message": "Додати"
},
@ -178,11 +169,20 @@
"importReportTitle": {
"message": "Імпорт стилів закінчено"
},
"installUpdate": {
"message": "Встановити оновлення"
},
"manageFavicons": {
"message": "Піктограми для цільових сайтів"
},
"manageFilters": {
"message": "Фільтри"
},
"manageHeading": {
"message": "Встановити Styles"
},
"manageNewUI": {
"message": "Новий інтерфейс"
"message": "Новий макет інтерфейсу управління користувача"
},
"meta_unknownJSONLiteral": {
"message": "Невірний JSON: $literal$не є дійсним літералом JSON",
@ -193,7 +193,13 @@
}
},
"openManage": {
"message": "Менеджер"
"message": "Керування"
},
"openOptions": {
"message": "Налаштування"
},
"optionsHeading": {
"message": "Налаштування"
},
"optionsReset": {
"message": "Скидання налаштувань до значень за замовчуванням"
@ -207,9 +213,39 @@
"optionsSyncLogin": {
"message": "Логін"
},
"optionsSyncStatusRelogin": {
"message": "Сеанс закінчився, будь ласка, увійдіть ще раз."
},
"paginationNext": {
"message": "Наступна сторінка"
},
"paginationPrevious": {
"message": "Попередня сторінка"
},
"replace": {
"message": "Замінити"
},
"replaceAll": {
"message": "Замінити все"
},
"retrieveBckp": {
"message": "Імпорт стилів"
},
"search": {
"message": "Пошук"
},
"searchStylesAll": {
"message": "Усі"
},
"searchStylesCode": {
"message": "CSS код"
},
"searchStylesHelp": {
"message": "</> або <Ctrl-F>клавіша фокусує поле пошуку.\nРежим за замовчуванням — це пошук у звичайному тексті для всіх термінів, розділених пробілами, у будь-якому порядку.\nТочні слова: оберніть запит у подвійні лапки, напр. <.header ~ div\">\nРегулярні вирази: включають косі риски та прапорці, напр.</body.*?\\ba\\b/i>\n«By URL» в селекторі області: знаходить стилі, які застосовуються до повністю вказаної URL-адреси, напр. https://www.example.org/\n\"Metadata\" в селектрі області: шукає в іменах, \"applies to\" специфікаторів, URL-адреси встановлення, URL-адресі оновлення та всьому блоку метаданих для стилів CSS користувача."
},
"searchStylesName": {
"message": "Назва"
},
"sectionCode": {
"message": "Код"
},
@ -220,14 +256,29 @@
"message": "Облагородити"
},
"styleCancelEditLabel": {
"message": "Всі стилі"
"message": "Повернутися до керування"
},
"styleEnabledLabel": {
"message": "Увімкнено"
},
"stylePreferSchemeLabel": {
"message": "Темна/Світла тема"
},
"styleSaveLabel": {
"message": "Зберегти"
},
"syncErrorRelogin": {
"message": "Помилка синхронізації.\nСпробуйте повторно ввійти в налаштування Stylus:\nнатисніть спочатку «від’єднати», а потім «підключити». "
"message": "Помилка синхронізації. Ви вийшли із системи. \nСпробуйте повторно увійти до системи в налаштуваннях Stylus."
},
"toggleStyle": {
"message": "Включити/виключити стиль"
},
"writeStyleFor": {
"message": "Створити стиль для:"
},
"writeStyleForURL": {
"message": "цей URL"
},
"zipStyles": {
"message": "Запаковування стилів ... "
}

379
_locales/vi/messages.json Normal file
View File

@ -0,0 +1,379 @@
{
"InaccessibleFileHint": {
"message": "Stylus không thể truy cập một số kiểu tập tin (chẳng hạn như PDF và JSON)."
},
"addStyleLabel": {
"message": "Viết bảng định kiểu mới"
},
"addStyleTitle": {
"message": "Thêm bảng định kiểu"
},
"alphaChannel": {
"message": "Độ mờ"
},
"appliesAdd": {
"message": "Thêm"
},
"appliesDisplay": {
"message": "Áp dụng với: $applies$",
"placeholders": {
"applies": {
"content": "$1"
}
}
},
"appliesDisplayTruncatedSuffix": {
"message": "và một số khác"
},
"appliesDomainOption": {
"message": "Các địa chỉ thuộc tên miền này"
},
"appliesHelp": {
"message": "Dùng tuỳ chọn \"Áp dụng với\" để giới hạn các địa chỉ cho đoạn mã này"
},
"appliesLabel": {
"message": "Áp dụng với"
},
"appliesLineWidgetLabel": {
"message": "Hiển thị thông tin \"Áp dụng với\""
},
"appliesLineWidgetWarning": {
"message": "Không hoạt động với CSS tối giản"
},
"appliesRegexpOption": {
"message": "URL khớp với biểu thức chính quy"
},
"appliesRemove": {
"message": "Xoá"
},
"appliesRemoveError": {
"message": "Không thể xoá mục \"Áp dụng với\" cuối cùng"
},
"appliesSpecify": {
"message": "Chỉ định"
},
"appliesToEverything": {
"message": "Tất cả"
},
"appliesUrlPrefixOption": {
"message": "URL bắt đầu bằng"
},
"author": {
"message": "Tác giả"
},
"backupButtons": {
"message": "Sao lưu"
},
"backupMessage": {
"message": "Để nhập tập tin sao lưu, kéo và thả nó vào trang này hoặc nhấp vào nút Nhập.\n\nĐể xuất một bản sao lưu tương thích với Stylus trước phiên bản 1.5.18, nhấp chuột phải hoặc nhấn giữ Shift khi nhấp chuột trái vào nút Xuất."
},
"bckpInstStyles": {
"message": "Xuất bảng định kiểu"
},
"checkForUpdate": {
"message": "Kiểm tra bản cập nhật mới"
},
"checkingForUpdate": {
"message": "Đang kiểm tra..."
},
"clickToUninstall": {
"message": "Nhấp để huỷ kích hoạt"
},
"cm_autoCloseBrackets": {
"message": "Tự động đóng ngoặc và nháy"
},
"cm_autoCloseBracketsTooltip": {
"message": "Tự động thêm dấu đóng tương ứng khi nhập một trong các dấu (, [, {, ' và \"."
},
"cm_autocompleteOnTyping": {
"message": "Tự động hoàn thành"
},
"cm_colorpicker": {
"message": "Bộ chọn màu cho màu CSS"
},
"cm_indentWithTabs": {
"message": "Lùi đầu dòng thông minh bằng tab"
},
"cm_lineWrapping": {
"message": "Gập dòng dài"
},
"cm_linter": {
"message": "Trình phân tích cú pháp"
},
"cm_matchHighlight": {
"message": "Làm nổi"
},
"cm_matchHighlightSelection": {
"message": "Chỉ vùng được chọn"
},
"cm_matchHighlightToken": {
"message": "Token nằm dưới con trỏ văn bản"
},
"cm_selectByTokens": {
"message": "Nhấp đúp để chọn token"
},
"cm_selectByTokensTooltip": {
"message": "Ví dụ về token: .foo-bar-2 #aabbcc 0.32 !important\nKhi tắt: Chọn từ (phân tách bằng dấu câu)."
},
"cm_smartIndent": {
"message": "Lùi đầu dòng thông minh"
},
"cm_tabSize": {
"message": "Chiều rộng tab"
},
"cm_theme": {
"message": "Chủ đề"
},
"colorpickerSwitchFormatTooltip": {
"message": "Đổi định dạng: HEX → RGB → HSL.\nNhấn giữ phím Shift khi nhấp để đảo thứ tự.\nPhím tắt: PgUp và PgDn."
},
"colorpickerTooltip": {
"message": "Mở bộ chọn màu"
},
"configOnChange": {
"message": "khi thay đổi"
},
"configOnChangeTooltip": {
"message": "Tự động lưu và áp dụng"
},
"configureStyle": {
"message": "Thiết lập"
},
"configureStyleOnHomepage": {
"message": "Thiết lập trên trang chủ"
},
"confirmCancel": {
"message": "Huỷ"
},
"confirmClose": {
"message": "Đóng"
},
"confirmDefault": {
"message": "Dùng mặc định"
},
"confirmDelete": {
"message": "Xoá"
},
"confirmDiscardChanges": {
"message": "Huỷ thay đổi?"
},
"confirmNo": {
"message": "Không"
},
"confirmSave": {
"message": "Lưu"
},
"confirmStop": {
"message": "Dừng"
},
"confirmYes": {
"message": "Có"
},
"connectingDropbox": {
"message": "Đang kết nối với Dropbox..."
},
"connectingDropboxNotAllowed": {
"message": "Tính năng kết nối với Dropbox chỉ khả dụng khi cài ứng dụng trực tiếp từ cửa hàng web"
},
"copied": {
"message": "Đã chép vào khay nhớ tạm"
},
"copy": {
"message": "Chép vào khay nhớ tạm"
},
"dateAbbrDay": {
"message": "$value$ ngày",
"placeholders": {
"value": {
"content": "$1"
}
}
},
"dateAbbrHour": {
"message": "$value$ giờ",
"placeholders": {
"value": {
"content": "$1"
}
}
},
"dateAbbrMonth": {
"message": "$value$ tháng",
"placeholders": {
"value": {
"content": "$1"
}
}
},
"dateAbbrYear": {
"message": "$value$ năm",
"placeholders": {
"value": {
"content": "$1"
}
}
},
"dateInstalled": {
"message": "Ngày cài đặt"
},
"dateUpdated": {
"message": "Ngày cập nhật"
},
"defaultTheme": {
"message": "mặc định"
},
"deleteStyleConfirm": {
"message": "Bạn có chắc chắn muốn xoá bảng định kiểu này không?"
},
"deleteStyleLabel": {
"message": "Xoá"
},
"disableAllStyles": {
"message": "Tắt tất cả bảng định kiểu"
},
"disableAllStylesOff": {
"message": "Bật tất cả bảng định kiểu"
},
"disableStyleLabel": {
"message": "Vô hiệu hoá"
},
"draftAction": {
"message": "Chọn \"Có\" để tải bản nháp hoặc \"Không\" để xoá nó đi."
},
"editDeleteText": {
"message": "Xoá"
},
"editGotoLine": {
"message": "Đi đến dòng (hoặc dòng:cột)"
},
"editStyleHeading": {
"message": "Sửa bảng định kiểu"
},
"editStyleLabel": {
"message": "Sửa"
},
"editStyleTitle": {
"message": "Sửa bảng định kiểu $stylename$",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"editorSettings": {
"message": "Cài đặt trình soạn thảo"
},
"enableStyleLabel": {
"message": "Kích hoạt"
},
"exportCompatible": {
"message": "Xuất (chế độ tương thích)"
},
"exportLabel": {
"message": "Xuất"
},
"exportSavedSuccess": {
"message": "Lưu thành công"
},
"externalFeedback": {
"message": "Phản hồi"
},
"externalHomepage": {
"message": "Trang chủ"
},
"externalLink": {
"message": "Liên kết ngoài"
},
"externalSupport": {
"message": "Ủng hộ"
},
"genericAdd": {
"message": "Thêm"
},
"genericDescription": {
"message": "Mô tả"
},
"genericDisabledLabel": {
"message": "Vô hiệu hoá"
},
"genericEnabledLabel": {
"message": "Kích hoạt"
},
"genericError": {
"message": "Lỗi"
},
"genericHistoryLabel": {
"message": "Lịch sử"
},
"genericNext": {
"message": "Sau"
},
"genericPrevious": {
"message": "Trước"
},
"genericResetLabel": {
"message": "Đặt lại"
},
"genericSavedMessage": {
"message": "Đã lưu"
},
"genericTest": {
"message": "Thứ"
},
"genericTitle": {
"message": "Tiêu đề"
},
"genericUnknown": {
"message": "Không xác định"
},
"helpAlt": {
"message": "Trợ giúp"
},
"importLabel": {
"message": "Nhập"
},
"importReportLegendAdded": {
"message": "đã thêm"
},
"importReportLegendIdentical": {
"message": "Đã bỏ qua các tệp trùng lặp"
},
"importReportLegendInvalid": {
"message": "Đã bỏ qua các tệp không hợp lệ"
},
"importReportLegendUpdatedBoth": {
"message": "đã cập nhật siêu thông tin và mã"
},
"importReportLegendUpdatedCode": {
"message": "đã cập nhật mã"
},
"importReportLegendUpdatedMeta": {
"message": "đã cập nhật siêu thông tin"
},
"importReportTitle": {
"message": "Đã nhập xong"
},
"installUpdateFromLabel": {
"message": "Kiểm tra bản cập nhật mới"
},
"license": {
"message": "Giấy phép"
},
"linterCSSLintIncompatible": {
"message": "CSSLint không hỗ trợ bộ tiền xử lý $preprocessorname$",
"placeholders": {
"preprocessorname": {
"content": "$1"
}
}
},
"linterJSONError": {
"message": "Định dạng JSON không hợp lệ"
},
"styleEnabledLabel": {
"message": "Kích hoạt"
},
"styleSaveLabel": {
"message": "Lưu"
}
}

View File

@ -71,7 +71,7 @@
"message": "备份"
},
"backupMessage": {
"message": "拖拽JSON备份文件到本页面也可导入。"
"message": "选择/拖拽 JSON 备份文件到本页面来导入备份。\n\n若要导出 Stylus V1.5.18 之前的兼容备份请右击或Shift+左击「导出」按钮。"
},
"bckpInstStyles": {
"message": "导出所有样式"
@ -270,6 +270,17 @@
"disableStyleLabel": {
"message": "禁用"
},
"draftAction": {
"message": "选择“是”以加载此草稿,或“否”以丢弃它。"
},
"draftTitle": {
"message": "恢复 $date$ 个小时前的草稿",
"placeholders": {
"date": {
"content": "$1"
}
}
},
"dragDropMessage": {
"message": "拖放JSON备份文件到管理器页面即可导入!"
},
@ -296,6 +307,9 @@
}
}
},
"editorSettings": {
"message": "编辑器设置"
},
"enableStyleLabel": {
"message": "启用"
},
@ -305,6 +319,9 @@
"excludeStyleByUrlLabel": {
"message": "排除当前链接"
},
"exportCompatible": {
"message": "导出(兼容模式)"
},
"exportLabel": {
"message": "导出"
},
@ -343,21 +360,15 @@
"findStyles": {
"message": "查找样式"
},
"findStylesForSite": {
"message": "查找该域名的在线样式"
},
"findStylesInline": {
"message": "嵌入此页"
},
"findStylesInlineTooltip": {
"message": "将搜索结果嵌入到此页面显示"
},
"genericAdd": {
"message": "添加"
},
"genericClone": {
"message": "创建副本"
},
"genericDescription": {
"message": "描述"
},
"genericDisabledLabel": {
"message": "禁用"
},
@ -382,6 +393,9 @@
"genericSavedMessage": {
"message": "已保存"
},
"genericTest": {
"message": "测试"
},
"genericTitle": {
"message": "标题"
},
@ -391,6 +405,9 @@
"gettingStyles": {
"message": "正在获取所有样式..."
},
"headerResizerHint": {
"message": "仅在此类 编辑器/管理器/安装器 UI , 按住 Shift 可调整大小"
},
"helpAlt": {
"message": "帮助"
},
@ -486,9 +503,18 @@
"linkGetHelp": {
"message": "帮助"
},
"linkGetShareStyles": {
"message": "获取|分享 样式"
},
"linkGetShareStylesInfo": {
"message": "由社区驱动的新站点 userstyles.world 是由 userstyle 作者创建的,目的是取代 userstyles.org该站点在过去一年中缓慢且反应迟钝以至于许多作者停止更新他们的样式。"
},
"linkGetStyles": {
"message": "获取样式"
},
"linkGetStylesInfo": {
"message": "该存档站点由 userstyle 社区成员创建,约每天更新一次其内容,用于备份缓慢且无响应的 userstyles.org。 "
},
"linkTranslate": {
"message": "翻译"
},
@ -556,7 +582,7 @@
"message": "显示为灰色图标"
},
"manageFaviconsHelp": {
"message": "Stylus 使用外部服务 https://www.google.com/s2/favicons 来获取图标"
"message": "Stylus 使用外部服务 https://icons.duckduckgo.com 来获取图标"
},
"manageFilters": {
"message": "过滤器"
@ -597,9 +623,6 @@
"manageOnlyUsercss": {
"message": "只显示 UserCSS"
},
"manageTitle": {
"message": "Stylus管理器"
},
"menuShowBadge": {
"message": "计数器角标"
},
@ -765,6 +788,17 @@
}
}
},
"meta_unknownMetaTypo": {
"message": "可能的 @$keyOk$ ? 未知元数据 @$keyErr$",
"placeholders": {
"keyErr": {
"content": "$1"
},
"keyOk": {
"content": "$2"
}
}
},
"meta_unknownPreprocessor": {
"message": "未知的预处理器 @preprocessor$preprocessor$",
"placeholders": {
@ -808,6 +842,15 @@
"optionsAdvanced": {
"message": "高级设置"
},
"optionsAdvancedAutoSwitchSchemeBySystem": {
"message": "按系统偏好设置"
},
"optionsAdvancedAutoSwitchSchemeByTime": {
"message": "按夜间时间"
},
"optionsAdvancedAutoSwitchSchemeNever": {
"message": "已停用。樣式中的深色/淺色設定會被忽略。"
},
"optionsAdvancedContextDelete": {
"message": "向编辑器右键菜单添加“删除”"
},
@ -817,6 +860,12 @@
"optionsAdvancedExposeIframesNote": {
"message": "给每个iframe内嵌框架的html注入 stylus-iframe=\"父域名hostname\" 属性(值)\n\n用途: 用作iframe选择器来一键确定 iframe 父窗(window.top) 页面 的唯一选择器.\n\n示例 html[stylus-iframe] 或 html[stylus-iframe$=\"twitter.com\"] h1 {...}\n\n详见源码github.com/openstyles/stylus/blob/master/content/apply.js#L270"
},
"optionsAdvancedExposeStyleName": {
"message": "暴露样式名称"
},
"optionsAdvancedExposeStyleNameNote": {
"message": "在页面中暴露样式名称以方便在 DevTools 中调试样式。请重新加载标签页以应用新设置。"
},
"optionsAdvancedNewStyleAsUsercss": {
"message": "将新样式的格式设为UserCSS"
},
@ -862,6 +911,9 @@
"optionsHeading": {
"message": "选项"
},
"optionsIconAuto": {
"message": "符合深色/淺色模式"
},
"optionsIconDark": {
"message": "高对比度暗色图标"
},
@ -884,7 +936,7 @@
"message": "恢复默认值"
},
"optionsStylusThemes": {
"message": "查找 Stylus UI 主题ᐝ"
"message": "點擊任何 Stylus 頁面(包含這個)的瀏覽器工具列中的 Stylus 圖示,然後點擊「尋找樣式」"
},
"optionsSubheading": {
"message": "附加选项"
@ -901,6 +953,9 @@
"optionsSyncNone": {
"message": "无"
},
"optionsSyncPassword": {
"message": "密码"
},
"optionsSyncStatusConnected": {
"message": "已连接"
},
@ -935,12 +990,21 @@
}
}
},
"optionsSyncStatusRelogin": {
"message": "工作階段已過期,請再次登入。"
},
"optionsSyncStatusSyncing": {
"message": "同步中..."
},
"optionsSyncSyncNow": {
"message": "现在同步"
},
"optionsSyncUrl": {
"message": "URL "
},
"optionsSyncUsername": {
"message": "用户名"
},
"optionsUpdateImportNote": {
"message": "从旧版的 Stylus 或 Stylish 中导入备份样式时,\n请手动检测升级一次以确保所有样式都可更新到最新版本。"
},
@ -983,6 +1047,9 @@
"popupHotkeysTooltip": {
"message": "查看Popup列表快捷键"
},
"popupManageSiteStyles": {
"message": "管理网站样式"
},
"popupManageTooltip": {
"message": "右击 || Shift+左击: 打开管理器且筛选当前URL(不含iframe)"
},
@ -1004,17 +1071,50 @@
"prefShowBadge": {
"message": "计数器角标 (或图标右键)"
},
"preferScheme": {
"message": "深色/淺色模式偏好設定"
},
"preferSchemeAlways": {
"message": "目前被忽略(樣式一律套用),因為全域深色/淺色模式已被停用"
},
"preferSchemeDark": {
"message": "深色"
},
"preferSchemeLight": {
"message": "淺色"
},
"preferSchemeNone": {
"message": "無(一律套用)"
},
"previewLabel": {
"message": "实时预览"
},
"previewTooltip": {
"message": "无需保存即可临时预览样式效果"
},
"publish": {
"message": "发布"
},
"publishPush": {
"message": "发布更新"
},
"publishReconnect": {
"message": "尝试断开连接然后再次发布"
},
"publishRetry": {
"message": "Stylus 仍在尝试发布此样式,但如果您没有看到身份验证活动或弹出窗口,您可以重试, 现在重试 "
},
"publishStyle": {
"message": "发布样式"
},
"publishUsw": {
"message": "使用 <userstyles.world>"
},
"readingStyles": {
"message": "正在读取样式..."
},
"reload": {
"message": "重启 Stylus"
"message": "重启"
},
"replace": {
"message": "替换"
@ -1025,12 +1125,18 @@
"replaceWith": {
"message": "替换为"
},
"restoreTemplate": {
"message": "還原預設範本。\n\n不會變更目前開啟的編輯器頁面。"
},
"retrieveBckp": {
"message": "导入所有样式"
},
"retrieveDropboxSync": {
"message": "从 Dropbox 导入"
},
"saveAsTemplate": {
"message": "另存为模板"
},
"search": {
"message": "搜索"
},
@ -1055,6 +1161,12 @@
"searchResultNoneFound": {
"message": "没有找到与此页面相关的样式。"
},
"searchResultNotMatching": {
"message": "样式已安装但不适于当前 URL"
},
"searchResultNotMatchingNote": {
"message": "尝试请求该用户样式的作者添加 URL。\n\n您也可以在管理器中打开样式自己编辑\n但请注意这会禁用此样式的自动更新。"
},
"searchResultRating": {
"message": "评价"
},
@ -1100,12 +1212,18 @@
"sections": {
"message": "章节"
},
"settings": {
"message": "设置"
},
"shortcuts": {
"message": "快捷键"
},
"shortcutsNote": {
"message": "设置快捷键"
},
"shortcutsNoteFF": {
"message": "在 Firefox 66 或更新的版本中,您可以手動開啟內建的快捷鍵使用者介面:\n1) 右鍵點擊工具列中的 Stylus 圖示並選擇「管理」\n或是透過主選單或 Ctrl-Shift-A 開啟 about:addons\n2) 在開啟的頁面中點擊右上角的齒輪圖示,\n3) 選擇「管理擴充套件快捷鍵」。\n\n您也可以在此自訂快捷鍵。"
},
"sortDateNewestFirst": {
"message": "最新的优先"
},
@ -1151,12 +1269,30 @@
"styleEnabledLabel": {
"message": "启用"
},
"styleExcludeLabel": {
"message": "自定义排除网站"
},
"styleFromMozillaFormatError": {
"message": "导入 Mozilla 格式失败"
},
"styleFromMozillaFormatPrompt": {
"message": "粘贴 Mozilla 格式代码"
},
"styleIncludeLabel": {
"message": "自定义包括网站"
},
"styleInjectionImportance": {
"message": "切换样式的优先级"
},
"styleInjectionOrder": {
"message": "樣式注入順序"
},
"styleInjectionOrderHint": {
"message": "拖曳樣式可變更其位置。樣式按下列順序注入,所以清單下方的樣式可覆寫較早樣式。"
},
"styleInjectionOrderHint_prio": {
"message": "下面列出的重要样式始终是最后注入的,因此它们可以覆盖任何新安装的样式。单击样式的标记以切换其重要性。"
},
"styleInstall": {
"message": "要将“$stylename$”安装到 Stylus 中吗?",
"placeholders": {
@ -1193,9 +1329,21 @@
"styleMozillaFormatHeading": {
"message": "Mozilla 格式"
},
"styleName": {
"message": "樣式名稱"
},
"styleNotAppliedRegexpProblemTooltip": {
"message": "正则表达式错误,样式无法正常运行"
},
"styleNotAppliedSchemeDark": {
"message": "此样式仅在深色模式下应用"
},
"styleNotAppliedSchemeLight": {
"message": "此样式仅在浅色模式下应用"
},
"stylePreferSchemeLabel": {
"message": "深色/浅色模式"
},
"styleRegexpInvalidExplanation": {
"message": "部分正则表达式无法生效。"
},
@ -1205,9 +1353,6 @@
"styleRegexpProblemTooltip": {
"message": "多个部分代码无法正常处理正则表达式"
},
"styleRegexpTestButton": {
"message": "正则测试"
},
"styleRegexpTestFull": {
"message": "匹配到标签页的正则"
},
@ -1229,6 +1374,9 @@
"styleSaveLabel": {
"message": "保存"
},
"styleSettings": {
"message": "样式设置"
},
"styleToMozillaFormatHelp": {
"message": "导入 FireFox 格式即 @-moz-document ...的 CSS 代码后,会自动转换成 Stylus 使用的分段式 CSS 代码。\n反过来分段式的 CSS 也可以导出为 FireFox 格式。\n需要注意的是如果你要向 userstyles.org 提交你的代码,则必须使用 FireFox 格式。\n\n导入快捷键: 剪贴板含有 @-moz-document ....代码,则可以直接在编辑器里 Ctrl+V 会自动弹出导入对话框"
},
@ -1246,6 +1394,9 @@
"styleUpdateDiscardChanges": {
"message": "样式已经在编辑器外被修改。需要重新加载样式吗?"
},
"styleUpdateUrlLabel": {
"message": "更新 URL"
},
"stylusUnavailableForURL": {
"message": "Stylus 无法介入到此类页面"
},
@ -1258,6 +1409,20 @@
"syncDropboxStyles": {
"message": "导出至 Dropbox"
},
"syncError": {
"message": "同步失敗"
},
"syncErrorLock": {
"message": "数据库已在使用中。锁定将在 $TIME$ 过期",
"placeholders": {
"time": {
"content": "$1"
}
}
},
"syncErrorRelogin": {
"message": "同步失敗。您已被登出。\n嘗試在 Stylus 選項中重新登入。"
},
"syncStorageErrorSaving": {
"message": "不能保存该值,请尝试减少文本数量。"
},
@ -1282,6 +1447,12 @@
"unreachableFileHint": {
"message": "! Stylus 无法介入到官方商店页面 !\n若是文件页面 或 小号无痕页面 请检查:\n1) 右键 - Stylus图标 并点击-\"管理扩展程序\"\n2) 勾选 - \"允许访问文件网址\" 以在 file:// 工作\n3) 勾选 - \"在无痕模式下启用\" 以在无痕页面和小号标签页工作 (有的浏览器带有小号功能、如CentBrowser)"
},
"unreachableMozSiteHint": {
"message": "在 Firefox ⩾60 版本里, 你需要在 <about:config> 里移除 extensions.webextensions.restrictedDomains"
},
"unreachableMozSiteHintOldFF": {
"message": "仅 Firefox 59 或更新的版本才能让你设置 WebExtensions 在例如这样一个有 CSP 保护的页面上新增样式。"
},
"unzipStyles": {
"message": "正在解压样式..."
},
@ -1341,9 +1512,6 @@
"usercssReplaceTemplateConfirmation": {
"message": "使用当前的 UserStyle 替换为新的UserCSS默认模板 ?"
},
"usercssReplaceTemplateName": {
"message": "该赋值为空的保存可设置默认模板"
},
"usercssReplaceTemplateSectionBody": {
"message": "在此插入代码..."
},

View File

@ -12,7 +12,7 @@
"message": "透明度"
},
"appliesAdd": {
"message": "添加部分"
"message": "添加"
},
"appliesDisplay": {
"message": "应用于:$applies$",
@ -35,7 +35,7 @@
"message": "应用于:"
},
"appliesLineWidgetLabel": {
"message": "显示应用于部件"
"message": "显示「应用于」信息"
},
"appliesLineWidgetWarning": {
"message": "对经过压缩的 CSS 无效"
@ -71,7 +71,7 @@
"message": "备份"
},
"backupMessage": {
"message": "选择备份文件,或将 JSON 备份文件拖放到本页面,即可导入备份。"
"message": "选择/拖拽 JSON 备份文件到本页面来导入备份。\n\n若要导出 Stylus V1.5.18 之前的兼容备份请右击或Shift+左击「导出」按钮。"
},
"bckpInstStyles": {
"message": "导出所有样式"
@ -259,19 +259,33 @@
"message": "删除"
},
"description": {
"message": "Stylus 是一个调整网页外观的用户样式管理器。它可让您轻松为许多热门网站网站安装主题和皮肤。"
"message": "Stylus 是一个调整网页外观的用户样式管理器。它可让您轻松为许多热门网站安装主题和皮肤。"
},
"disableAllStyles": {
"message": "禁用所有样式"
},
"disableAllStylesOff": {
"message": "已禁用样式"
},
"disableStyleLabel": {
"message": "禁用"
},
"draftAction": {
"message": "选择“是”以加载此草稿,或“否”以丢弃它。"
},
"draftTitle": {
"message": "恢复 $date$ 个小时前的草稿",
"placeholders": {
"date": {
"content": "$1"
}
}
},
"dragDropMessage": {
"message": "把 JSON 备份文件拖放到该页面任意位置即可导入"
},
"dragDropUsercssTabstrip": {
"message": "要安装文件,就将其放在选项卡条(显示选项卡标题的区域)上。"
"message": "要安装文件,就将其放在标签页条(显示标签页标题的区域)上。"
},
"editDeleteText": {
"message": "删除"
@ -293,6 +307,9 @@
}
}
},
"editorSettings": {
"message": "编辑器设置"
},
"enableStyleLabel": {
"message": "启用"
},
@ -302,6 +319,9 @@
"excludeStyleByUrlLabel": {
"message": "排除当前链接"
},
"exportCompatible": {
"message": "导出(兼容模式)"
},
"exportLabel": {
"message": "导出"
},
@ -324,7 +344,7 @@
"message": "UserCSS 文档"
},
"filteredStyles": {
"message": "共 $numTotal$ 个,已显示 $numShown$ 个",
"message": "已显示 $numShown$ 个,共 $numTotal$ 个",
"placeholders": {
"numShown": {
"content": "$1"
@ -340,15 +360,6 @@
"findStyles": {
"message": "查找更多样式"
},
"findStylesForSite": {
"message": "查找适合此网站的更多样式"
},
"findStylesInline": {
"message": "嵌入到此页面"
},
"findStylesInlineTooltip": {
"message": "在此弹窗内显示搜索结果。"
},
"genericAdd": {
"message": "添加"
},
@ -382,6 +393,12 @@
"genericSavedMessage": {
"message": "已保存"
},
"genericSize": {
"message": "大小"
},
"genericTest": {
"message": "测试"
},
"genericTitle": {
"message": "标题"
},
@ -391,6 +408,9 @@
"gettingStyles": {
"message": "正在获取所有样式..."
},
"headerResizerHint": {
"message": "仅在此类 编辑器/管理器/安装器 UI , 按住 Shift 可调整大小"
},
"helpAlt": {
"message": "帮助"
},
@ -490,13 +510,13 @@
"message": "获取|分享 样式"
},
"linkGetShareStylesInfo": {
"message": "由社区驱动的新站点 userstyles.world 是由 userstyle 作者创建的,目的是取代 userstyles.org该站点在过去一年中缓慢且反应迟钝以至于许多作者停止更新他们的样式。"
"message": "由社区驱动的新站点 userstyles.world 是用户样式的作者们创建的,目的是取代 userstyles.org。userstyles.org 在过去一年中运行缓慢且反应迟钝,以至于许多作者都不再更新他们的样式。"
},
"linkGetStyles": {
"message": "获取样式"
},
"linkGetStylesInfo": {
"message": "该存档站点由 userstyle 社区成员创建,约每天更新一次其内容,用于备份缓慢且无响应的 userstyles.org。 "
"message": "该存档站点是一位用户样式社区的成员创建的,约每天更新一次其内容,用于备份运行缓慢且反应迟钝的 userstyles.org。"
},
"linkTranslate": {
"message": "翻译"
@ -550,22 +570,22 @@
"message": "查看文件时发生错误"
},
"liveReloadInstallHint": {
"message": "保持此选项卡为打开状态,将在外部更改后自动更新样式。"
"message": "保持此标签页为打开状态,以便在外部更改时自动更新样式。"
},
"liveReloadInstallHintFF": {
"message": "保持此选项卡和原始选项卡处于打开状态,将在外部更改时自动重新更新样式。"
"message": "保持此标签页和原始标签页处于打开状态,以便在外部更改时自动更新样式。"
},
"liveReloadLabel": {
"message": "动态刷新"
},
"manageFavicons": {
"message": "显示 \"应用于\" 的favicon图标"
"message": "显示「应用于」列的网站图标favicon"
},
"manageFaviconsGray": {
"message": "显示为灰色图标"
},
"manageFaviconsHelp": {
"message": "Stylus 使用外部服务 https://www.google.com/s2/favicons 来获取图标"
"message": "Stylus 使用外部服务 https://icons.duckduckgo.com 来获取图标"
},
"manageFilters": {
"message": "过滤器"
@ -825,6 +845,15 @@
"optionsAdvanced": {
"message": "高级设置"
},
"optionsAdvancedAutoSwitchSchemeBySystem": {
"message": "按系统偏好设置"
},
"optionsAdvancedAutoSwitchSchemeByTime": {
"message": "按夜间时间"
},
"optionsAdvancedAutoSwitchSchemeNever": {
"message": "停用。忽略样式的深色/浅色模式设置。"
},
"optionsAdvancedContextDelete": {
"message": "向编辑器右键菜单添加“删除”"
},
@ -834,6 +863,12 @@
"optionsAdvancedExposeIframesNote": {
"message": "给每个iframe框架的html注入window.top父域名的内联属性(值)\n即 html[stylus-iframe=\"hostname\"] \n\n用途: 确定或排除 iframe选择器以避免伤及无辜.\nhtml:not([stylus-iframe]) {...}\nhtml[stylus-iframe] 或 html[stylus-iframe$=\"twitter.com\"] h1 {...}\n\ngithub.com/openstyles/stylus/blob/master/content/apply.js#L270"
},
"optionsAdvancedExposeStyleName": {
"message": "暴露样式名称"
},
"optionsAdvancedExposeStyleNameNote": {
"message": "在页面中暴露样式名称以方便在 DevTools 中调试样式。请重新加载标签页以应用新设置。"
},
"optionsAdvancedNewStyleAsUsercss": {
"message": "将新样式的格式设为 UserCSS"
},
@ -867,9 +902,6 @@
"optionsCustomizeIcon": {
"message": "工具栏图标风格"
},
"optionsCustomizePopup": {
"message": "Popup "
},
"optionsCustomizeSync": {
"message": "同步到云端"
},
@ -879,11 +911,14 @@
"optionsHeading": {
"message": "选项"
},
"optionsIconAuto": {
"message": "跟随深色/浅色模式"
},
"optionsIconDark": {
"message": "高对比度暗色图标"
"message": "深色浏览器主题"
},
"optionsIconLight": {
"message": "低对比度亮色图标"
"message": "浅色浏览器主题"
},
"optionsOpen": {
"message": "打开"
@ -901,7 +936,7 @@
"message": "恢复默认值"
},
"optionsStylusThemes": {
"message": "查找 Stylus UI 主题ᐝ"
"message": "在任意 Stylus 页面(包括这个)点击浏览器工具栏的 Stylus 图标,然后点击「寻找样式」"
},
"optionsSubheading": {
"message": "附加选项"
@ -918,6 +953,9 @@
"optionsSyncNone": {
"message": "无"
},
"optionsSyncPassword": {
"message": "密码"
},
"optionsSyncStatusConnected": {
"message": "已连接"
},
@ -931,7 +969,7 @@
"message": "正在断开连接..."
},
"optionsSyncStatusPull": {
"message": "正在获取样式 $loaded$ 中的 $total$",
"message": "正在拉取样式 $loaded$ / $total$",
"placeholders": {
"loaded": {
"content": "$1"
@ -942,7 +980,7 @@
}
},
"optionsSyncStatusPush": {
"message": "正在上传样式 $loaded$ 中的 $total$",
"message": "正在推送样式 $loaded$ / $total$",
"placeholders": {
"loaded": {
"content": "$1"
@ -961,6 +999,9 @@
"optionsSyncSyncNow": {
"message": "现在同步"
},
"optionsSyncUsername": {
"message": "用户名"
},
"optionsUpdateImportNote": {
"message": "从旧版本的 Stylus 或 Stylish 中导入样式备份时,请在样式管理器中手动检测升级一次,以确保所有样式都可更新到最新版本。"
},
@ -998,11 +1039,14 @@
"message": "对于新 Chrome 中的暗色主题很有用,因为它不再绘制边框"
},
"popupHotkeysInfo": {
"message": "<1>-<9>, <0> 按第1 - 10个列表 来ON/OFF\n<A>-<Z> 按英文首字母 来ON/OFF\n附加<Shift>: 打开对应列表的编辑器\n<Numpad +> ON 全部列表\n<Numpad > OFF 全部列表\n<Numpad *> 或 <`> 仅针对Popup弹出时的初始ON列表, 它只会ON/OFF初始ON列表, 故:\n <Numpad > <Numpad *> 能快速恢复初始状态.\n 更多信息见Wiki"
"message": "<1>-<9>, <0> 开启/关闭第 N 个样式0 就是 10\n<A>-<Z> 开启/关闭相应英文首字母的首个样式\n附加 <Shift> 打开编辑器而不是开启/关闭\n<Numpad +> 启用列出的样式\n<Numpad > 禁用列出的样式\n<Numpad *> 或 <`>(反引号)- 开启/关闭已启用的首个样式,当弹出菜单开启时不应用后来启用的样式,因此你可以在测试完成后恢复初始状态:简单地禁用所有样式,然后切换如 <Numpad > <Numpad *>\n更多信息见 Wiki"
},
"popupHotkeysTooltip": {
"message": "查看 Popup 快捷键"
},
"popupManageSiteStyles": {
"message": "管理网站样式"
},
"popupManageTooltip": {
"message": "右键单击或 Shift + 左键单击可打开管理器并显示适用于当前网站的样式"
},
@ -1024,6 +1068,21 @@
"prefShowBadge": {
"message": "在当前网站生效的样式数量"
},
"preferScheme": {
"message": "深色/浅色模式偏好设置"
},
"preferSchemeAlways": {
"message": "目前已忽略(总是应用的样式),因为已停用全局深色/浅色模式。"
},
"preferSchemeDark": {
"message": "深色"
},
"preferSchemeLight": {
"message": "浅色"
},
"preferSchemeNone": {
"message": "无(总是应用)"
},
"previewLabel": {
"message": "实时预览"
},
@ -1034,7 +1093,7 @@
"message": "发布"
},
"publishPush": {
"message": "发布更新"
"message": "推送更新"
},
"publishReconnect": {
"message": "尝试断开连接然后再次发布"
@ -1052,7 +1111,7 @@
"message": "正在读取样式..."
},
"reload": {
"message": "重启 Stylus"
"message": "重启"
},
"replace": {
"message": "替换"
@ -1063,12 +1122,18 @@
"replaceWith": {
"message": "替换为"
},
"restoreTemplate": {
"message": "恢复默认模板。\n\n不会改变当前打开的编辑器页面"
},
"retrieveBckp": {
"message": "导入所有样式"
},
"retrieveDropboxSync": {
"message": "从 Dropbox 导入"
},
"saveAsTemplate": {
"message": "另存为模板"
},
"search": {
"message": "搜索"
},
@ -1088,7 +1153,7 @@
"message": "/regex/ 用 / 包裹语法来正则搜索"
},
"searchResultInstallCount": {
"message": "总安装次数"
"message": "总安装次数"
},
"searchResultNoneFound": {
"message": "没有找到与此页面相关的样式。"
@ -1108,9 +1173,6 @@
"searchResultWeeklyCount": {
"message": "本周安装次数"
},
"searchStyleQueryHint": {
"message": "空格多词 -- 同时精确匹配(无需双引号)\n2020 -- 也含更新日期的匹配结果\n大小写不敏感"
},
"searchStylesAll": {
"message": "全部"
},
@ -1144,12 +1206,18 @@
"sections": {
"message": "章节"
},
"settings": {
"message": "设置"
},
"shortcuts": {
"message": "快捷键"
},
"shortcutsNote": {
"message": "设置快捷键"
},
"shortcutsNoteFF": {
"message": "在 Firefox 66 及之后更新的版本中:\n1) 右键单击工具栏的的 Stylus 图标,选择「管理」\n也可以通过主菜单或 Ctrl-Shift-A 打开 about:addons\n2) 在打开的页面点击右上角的齿轮图标;\n3) 选择「管理扩展快捷键」。\n\n您也可以在这自定义快捷键。"
},
"sortDateNewestFirst": {
"message": "最新的优先"
},
@ -1195,12 +1263,30 @@
"styleEnabledLabel": {
"message": "启用"
},
"styleExcludeLabel": {
"message": "自定义排除网站"
},
"styleFromMozillaFormatError": {
"message": "导入 Mozilla 格式失败"
},
"styleFromMozillaFormatPrompt": {
"message": "粘贴 Mozilla 格式代码"
},
"styleIncludeLabel": {
"message": "自定义包括网站"
},
"styleInjectionImportance": {
"message": "切换样式的优先级"
},
"styleInjectionOrder": {
"message": "样式注入顺序"
},
"styleInjectionOrderHint": {
"message": "拖拽样式可更改排序。样式会按如下顺序注入,所以在列表更下方样式可覆盖较前面的样式。"
},
"styleInjectionOrderHint_prio": {
"message": "下面列出的重要样式始终是最后注入的,因此它们可以覆盖任何新安装的样式。单击样式的标记以切换其重要性。"
},
"styleInstall": {
"message": "要将“$stylename$”安装到 Stylus 中吗?",
"placeholders": {
@ -1243,6 +1329,15 @@
"styleNotAppliedRegexpProblemTooltip": {
"message": "正则表达式错误,样式无法正常运行"
},
"styleNotAppliedSchemeDark": {
"message": "此样式仅在深色模式下应用"
},
"styleNotAppliedSchemeLight": {
"message": "此样式仅在浅色模式下应用"
},
"stylePreferSchemeLabel": {
"message": "深色/浅色模式"
},
"styleRegexpInvalidExplanation": {
"message": "部分正则表达式无法生效。"
},
@ -1252,9 +1347,6 @@
"styleRegexpProblemTooltip": {
"message": "多个部分代码无法正常处理正则表达式"
},
"styleRegexpTestButton": {
"message": "正则测试"
},
"styleRegexpTestFull": {
"message": "匹配到标签页的正则"
},
@ -1276,6 +1368,9 @@
"styleSaveLabel": {
"message": "保存"
},
"styleSettings": {
"message": "样式设置"
},
"styleToMozillaFormatHelp": {
"message": "导入 FireFox 格式即 @-moz-document ...的 CSS 代码后,会自动转换成 Stylus 使用的分段式 CSS 代码。\n反过来分段式的 CSS 也可以导出为 FireFox 格式。\n需要注意的是如果你要向 userstyles.org 提交你的代码,则必须使用 FireFox 格式。\n\n导入快捷键: 剪贴板含有 @-moz-document ....代码,则可以直接在编辑器里 Ctrl+V 会自动弹出导入对话框"
},
@ -1293,8 +1388,11 @@
"styleUpdateDiscardChanges": {
"message": "样式已经在编辑器外被修改。需要重新加载样式吗?"
},
"styleUpdateUrlLabel": {
"message": "更新 URL"
},
"stylusUnavailableForURL": {
"message": "Stylus 无法介入到此类页面"
"message": "Stylus 不能在此类页面上工作"
},
"stylusUnavailableForURLdetails": {
"message": "出于安全考虑,浏览器禁止扩展程序影响其内置页面(例如 chrome://versionChrome 61 后的标准新标签页about:addons 等等)以及其他扩展程序的页面。每个浏览器也限制了对于自己扩展程序库的介入〔例如 Chrome 网上应用店、Firefox 附加组件addons.mozilla.org。"
@ -1308,8 +1406,16 @@
"syncError": {
"message": "同步失败"
},
"syncErrorLock": {
"message": "数据库已在使用中。锁定将在 $TIME$ 过期",
"placeholders": {
"time": {
"content": "$1"
}
}
},
"syncErrorRelogin": {
"message": "同步失败\n请尝试在 Stylus 选项里重新登录\n先点击「断开连接」再点击「连接」。"
"message": "同步失败。你已退出登录。\n请尝试在 Stylus 选项里重新登录。"
},
"syncStorageErrorSaving": {
"message": "不能保存该值,请尝试减少文本数量。"
@ -1400,9 +1506,6 @@
"usercssReplaceTemplateConfirmation": {
"message": "使用当前 UserStyle 代码替换为新的默认模板吗 ?"
},
"usercssReplaceTemplateName": {
"message": "@name 为空值 可设置新的默认模板"
},
"usercssReplaceTemplateSectionBody": {
"message": "在此插入代码..."
},

View File

@ -71,7 +71,7 @@
"message": "備份"
},
"backupMessage": {
"message": "選取檔案並拖曳到此頁面。"
"message": "要匯入備份檔案,請將其拖曳至此頁面或點擊匯入按鈕。\n\n要匯出相容於比 1.5.18 還舊的 Stylus 版本的備份,請右鍵點擊或按住 Shift 然後點擊匯出按鈕。"
},
"bckpInstStyles": {
"message": "匯出樣式"
@ -264,9 +264,23 @@
"disableAllStyles": {
"message": "停用所有樣式"
},
"disableAllStylesOff": {
"message": "樣式已關閉"
},
"disableStyleLabel": {
"message": "停用"
},
"draftAction": {
"message": "選擇「是」以載入此草稿,或「否」以放棄"
},
"draftTitle": {
"message": "還原草稿,已建立 $date$",
"placeholders": {
"date": {
"content": "$1"
}
}
},
"dragDropMessage": {
"message": "將您的備份檔拖曳到此頁面的任何地方以匯入。"
},
@ -293,6 +307,9 @@
}
}
},
"editorSettings": {
"message": "編輯器設定"
},
"enableStyleLabel": {
"message": "啟用"
},
@ -302,6 +319,9 @@
"excludeStyleByUrlLabel": {
"message": "排除目前的 URL"
},
"exportCompatible": {
"message": "匯出(相容模式)"
},
"exportLabel": {
"message": "匯出"
},
@ -340,15 +360,6 @@
"findStyles": {
"message": "尋找樣式"
},
"findStylesForSite": {
"message": "查找更多適合此網站的樣式"
},
"findStylesInline": {
"message": "嵌入"
},
"findStylesInlineTooltip": {
"message": "在此視窗中顯示搜尋結果。"
},
"genericAdd": {
"message": "新增"
},
@ -382,6 +393,12 @@
"genericSavedMessage": {
"message": "已儲存"
},
"genericSize": {
"message": "大小"
},
"genericTest": {
"message": "測試"
},
"genericTitle": {
"message": "標題"
},
@ -391,6 +408,9 @@
"gettingStyles": {
"message": "正在取得所有樣式……"
},
"headerResizerHint": {
"message": "按住 Shift 以僅在此類型的 UI 中調整大小,例如編輯器、管理程式、安裝程式等"
},
"helpAlt": {
"message": "說明"
},
@ -565,7 +585,7 @@
"message": "灰階淡出"
},
"manageFaviconsHelp": {
"message": "Stylus 使用外部服務 https://www.google.com/s2/favicons"
"message": "Stylus 使用外部服務 https://icons.duckduckgo.com"
},
"manageFilters": {
"message": "過濾器"
@ -576,6 +596,9 @@
"manageMaxTargets": {
"message": "已套用項目的數量"
},
"manageMinColumnWidth": {
"message": "最小欄位寬度以像素為單位9999 停用多欄模式)"
},
"manageNewStyleAsUsercss": {
"message": "做為 Usercss"
},
@ -825,6 +848,15 @@
"optionsAdvanced": {
"message": "進階"
},
"optionsAdvancedAutoSwitchSchemeBySystem": {
"message": "按系統偏好設定"
},
"optionsAdvancedAutoSwitchSchemeByTime": {
"message": "到夜間:"
},
"optionsAdvancedAutoSwitchSchemeNever": {
"message": "已停用。樣式中的深色/淺色設定會被忽略。"
},
"optionsAdvancedContextDelete": {
"message": "在編輯器的右鍵選單中加入「刪除」"
},
@ -834,6 +866,12 @@
"optionsAdvancedExposeIframesNote": {
"message": "公開每個 iframe 中的頂級頁面網域。\n啟用編寫特別用於 iframe 的 CSS如這個\nhtml[stylus-iframe$$=\"twitter.com\"] h1 { display:none }"
},
"optionsAdvancedExposeStyleName": {
"message": "發佈樣式名稱"
},
"optionsAdvancedExposeStyleNameNote": {
"message": "在頁面中發佈樣式名稱以方便在 devtools 中對樣式進行除錯。請重新載入分頁以套用新設定。"
},
"optionsAdvancedNewStyleAsUsercss": {
"message": "以 usercss 編寫新樣式"
},
@ -879,6 +917,9 @@
"optionsHeading": {
"message": "選項"
},
"optionsIconAuto": {
"message": "符合深色/淺色模式"
},
"optionsIconDark": {
"message": "暗色瀏覽器主題"
},
@ -901,7 +942,7 @@
"message": "重設選項"
},
"optionsStylusThemes": {
"message": "尋找 Sytlus UI 佈景主題"
"message": "點擊任何 Stylus 頁面(包含這個)的瀏覽器工具列中的 Stylus 圖示,然後點擊「尋找樣式」"
},
"optionsSubheading": {
"message": "更多選項"
@ -918,6 +959,9 @@
"optionsSyncNone": {
"message": "無"
},
"optionsSyncPassword": {
"message": "密碼"
},
"optionsSyncStatusConnected": {
"message": "已連線"
},
@ -961,6 +1005,9 @@
"optionsSyncSyncNow": {
"message": "立刻同步"
},
"optionsSyncUsername": {
"message": "使用者名稱"
},
"optionsUpdateImportNote": {
"message": "當從舊版本或是從 Stylish 匯入樣式備份時,在樣式管理員中手動進行一次更新檢查,以確保所有樣式都被更新。"
},
@ -1003,6 +1050,9 @@
"popupHotkeysTooltip": {
"message": "點選以檢視可用的快速鍵"
},
"popupManageSiteStyles": {
"message": "管理網站樣式"
},
"popupManageTooltip": {
"message": "Shift + 點選或右鍵 + 點選以在管理員中開啟目前頁面可用的樣式"
},
@ -1024,6 +1074,21 @@
"prefShowBadge": {
"message": "在工具欄按鈕上顯示當前網站已生效的樣式表數目。"
},
"preferScheme": {
"message": "深色/淺色模式偏好設定"
},
"preferSchemeAlways": {
"message": "目前被忽略(樣式一律套用),因為全域深色/淺色模式已被停用"
},
"preferSchemeDark": {
"message": "深色"
},
"preferSchemeLight": {
"message": "淺色"
},
"preferSchemeNone": {
"message": "無(一律套用)"
},
"previewLabel": {
"message": "即時預覽"
},
@ -1052,7 +1117,7 @@
"message": "正在讀取樣式……"
},
"reload": {
"message": "重新載入 Stylus 附加元件"
"message": "重"
},
"replace": {
"message": "取代"
@ -1063,12 +1128,18 @@
"replaceWith": {
"message": "取代為"
},
"restoreTemplate": {
"message": "還原預設範本。\n\n不會變更目前開啟的編輯器頁面。"
},
"retrieveBckp": {
"message": "匯入樣式"
},
"retrieveDropboxSync": {
"message": "Dropbox 匯入"
},
"saveAsTemplate": {
"message": "另存為範本"
},
"search": {
"message": "搜尋"
},
@ -1109,7 +1180,7 @@
"message": "每週安裝"
},
"searchStyleQueryHint": {
"message": "搜尋樣式名稱時是區分大小寫的:\nsome words - 以任意順序搜尋所有文字\n\"some phrase\" - 精確符合引號內的詞語\n2020 - 如此年份顯示在2020年更新的樣式"
"message": "搜尋樣式名稱(若使用大寫字母,則區分大小寫):\n一些字 - 以任何順序符合所有字\n\"一些詞\" - 精確符合引號內的詞\n/foo.*bar/i - 沒有空格的正規表示式(使用 \\s 代替)"
},
"searchStylesAll": {
"message": "全部"
@ -1144,12 +1215,18 @@
"sections": {
"message": "樣式段"
},
"settings": {
"message": "設定"
},
"shortcuts": {
"message": "快速鍵"
},
"shortcutsNote": {
"message": "自訂鍵盤快速鍵"
},
"shortcutsNoteFF": {
"message": "在 Firefox 66 或更新的版本中,您可以手動開啟內建的快捷鍵使用者介面:\n1) 右鍵點擊工具列中的 Stylus 圖示並選擇「管理」\n或是透過主選單或 Ctrl-Shift-A 開啟 about:addons\n2) 在開啟的頁面中點擊右上角的齒輪圖示,\n3) 選擇「管理擴充套件快捷鍵」。\n\n您也可以在此自訂快捷鍵。"
},
"sortDateNewestFirst": {
"message": "最新的優先"
},
@ -1195,12 +1272,30 @@
"styleEnabledLabel": {
"message": "已啟用"
},
"styleExcludeLabel": {
"message": "自訂排除網站"
},
"styleFromMozillaFormatError": {
"message": "從 Mozilla 格式匯入失敗"
},
"styleFromMozillaFormatPrompt": {
"message": "貼上 Mozilla 格式代碼"
},
"styleIncludeLabel": {
"message": "自訂包含網站"
},
"styleInjectionImportance": {
"message": "切換樣式重要程度"
},
"styleInjectionOrder": {
"message": "樣式注入順序"
},
"styleInjectionOrderHint": {
"message": "拖曳樣式可變更其位置。樣式按下列順序注入,所以清單下方的樣式可覆寫較早樣式。"
},
"styleInjectionOrderHint_prio": {
"message": "下方列出的重要樣式一律最後注入,因此它們會覆寫新安裝的樣式。點擊樣式的標記以切換其重要程度。"
},
"styleInstall": {
"message": "安裝 '$stylename$' 到 Stylus ",
"placeholders": {
@ -1243,6 +1338,15 @@
"styleNotAppliedRegexpProblemTooltip": {
"message": "因為不正確的 'regexp()' 使用導致未套用"
},
"styleNotAppliedSchemeDark": {
"message": "此樣式僅於深色模式中套用"
},
"styleNotAppliedSchemeLight": {
"message": "此樣式僅於淺色模式中套用"
},
"stylePreferSchemeLabel": {
"message": "深色/淺色模式"
},
"styleRegexpInvalidExplanation": {
"message": "部份 'regexp()' 規則可能不再能被編譯。"
},
@ -1252,9 +1356,6 @@
"styleRegexpProblemTooltip": {
"message": "因為不正確的 'regexp()' 使用導致未套用的樣式段數量"
},
"styleRegexpTestButton": {
"message": "正規表示式測試"
},
"styleRegexpTestFull": {
"message": "符合的分頁"
},
@ -1276,6 +1377,9 @@
"styleSaveLabel": {
"message": "儲存"
},
"styleSettings": {
"message": "樣式設定"
},
"styleToMozillaFormatHelp": {
"message": "Mozilla格式的樣式代碼能在火狐版Stylus使用也可以提交至 userstyles.org 。"
},
@ -1293,6 +1397,9 @@
"styleUpdateDiscardChanges": {
"message": "樣式已在編輯器外變更。您想要重新載入樣式嗎?"
},
"styleUpdateUrlLabel": {
"message": "更新 URL"
},
"stylusUnavailableForURL": {
"message": "Stylus 不能在諸如此類的網頁上生效。"
},
@ -1308,8 +1415,16 @@
"syncError": {
"message": "同步失敗"
},
"syncErrorLock": {
"message": "資料庫已在使用中。鎖將於 $TIME$ 過期",
"placeholders": {
"time": {
"content": "$1"
}
}
},
"syncErrorRelogin": {
"message": "同步失敗。\n重是在 Stylus 選項重新登入:\n先點擊「斷線」然後「連線」。"
"message": "同步失敗。您已被登出。\n嘗試在 Stylus 選項中重新登入。"
},
"syncStorageErrorSaving": {
"message": "無法儲存值。嘗試減少文字量。"
@ -1400,9 +1515,6 @@
"usercssReplaceTemplateConfirmation": {
"message": "為新的 Usercss 樣式取代預設的範本為目前的程式碼?"
},
"usercssReplaceTemplateName": {
"message": "清空 @name 取代目前範本"
},
"usercssReplaceTemplateSectionBody": {
"message": "在此插入程式碼……"
},

View File

@ -6,15 +6,9 @@
/* global syncMan */
/* global updateMan */
/* global usercssMan */
/* global usoApi */
/* global uswApi */
/* global
FIREFOX
URLS
activateTab
download
findExistingTab
openURL
*/ // toolbox.js
/* global FIREFOX UA activateTab openURL */ // toolbox.js
/* global colorScheme */ // color-scheme.js
'use strict';
@ -41,17 +35,12 @@ addAPI(/** @namespace API */ {
sync: syncMan,
updater: updateMan,
usercss: usercssMan,
uso: usoApi,
usw: uswApi,
colorScheme,
/** @type {BackgroundWorker} */
worker: createWorker({url: '/background/background-worker'}),
download(url, opts) {
return typeof url === 'string' && url.startsWith(URLS.uso) &&
this.sender.url.startsWith(URLS.uso) &&
download(url, opts || {});
},
/** @returns {string} */
getTabUrlPrefix() {
return this.sender.tab.url.match(/^([\w-]+:\/+[^/#]+)/)[1];
@ -69,10 +58,24 @@ addAPI(/** @namespace API */ {
async openEditor(params) {
const u = new URL(chrome.runtime.getURL('edit.html'));
u.search = new URLSearchParams(params);
const wnd = prefs.get('openEditInWindow');
const wnd = chrome.windows && prefs.get('openEditInWindow');
const wndPos = wnd && prefs.get('windowPosition');
const wndBase = wnd && prefs.get('openEditInWindow.popup') ? {type: 'popup'} : {};
const ffBug = wnd && FIREFOX; // https://bugzil.la/1271047
if (wndPos) {
const {left, top, width, height} = wndPos;
const r = left + width;
const b = top + height;
const peek = 32;
if (isNaN(r) || r < peek || left > screen.availWidth - peek || width < 100) {
delete wndPos.left;
delete wndPos.width;
}
if (isNaN(b) || b < peek || top > screen.availHeight - peek || height < 100) {
delete wndPos.top;
delete wndPos.height;
}
}
const tab = await openURL({
url: `${u}`,
currentWindow: null,
@ -84,27 +87,25 @@ addAPI(/** @namespace API */ {
/** @returns {Promise<chrome.tabs.Tab>} */
async openManage({options = false, search, searchMode} = {}) {
let url = chrome.runtime.getURL('manage.html');
if (search) {
url += `?search=${encodeURIComponent(search)}&searchMode=${searchMode}`;
const setUrlParams = url => {
const u = new URL(url);
if (search) u.searchParams.set('search', search);
if (searchMode) u.searchParams.set('searchMode', searchMode);
if (options) u.hash = '#stylus-options';
return u.href;
};
const base = chrome.runtime.getURL('manage.html');
const url = setUrlParams(base);
const tabs = await browser.tabs.query({url: base + '*'});
const same = tabs.find(t => t.url === url);
let tab = same || tabs[0];
if (!tab) {
API.prefsDb.get('badFavs'); // prime the cache to avoid flicker/delay when opening the page
tab = await openURL({url, newTab: true});
} else if (!same) {
msg.sendTab(tab.id, {method: 'pushState', url: setUrlParams(tab.url)});
}
if (options) {
url += '#stylus-options';
}
const tab = await findExistingTab({
url,
currentWindow: null,
ignoreHash: true,
ignoreSearch: true,
});
if (tab) {
await activateTab(tab);
if (url !== (tab.pendingUrl || tab.url)) {
await msg.sendTab(tab.id, {method: 'pushState', url}).catch(console.error);
}
return tab;
}
return openURL({url, ignoreExisting: true}).then(activateTab); // activateTab unminimizes the window
return activateTab(tab); // activateTab unminimizes the window
},
/**
@ -157,10 +158,25 @@ if (chrome.commands) {
}
chrome.runtime.onInstalled.addListener(({reason, previousVersion}) => {
if (reason === 'update') {
const [a, b, c] = (previousVersion || '').split('.');
if (a <= 1 && b <= 5 && c <= 13) { // 1.5.13
require(['/background/remove-unused-storage']);
if (reason === 'install') {
if (UA.mobile) prefs.set('manage.newUI', false);
if (UA.windows) prefs.set('editor.keyMap', 'sublime');
}
// TODO: remove this before 1.5.23 as it's only for a few users who installed git 26b75e77
if (reason === 'update' && previousVersion === '1.5.22') {
for (const dbName of ['drafts', prefs.STORAGE_KEY]) {
try {
indexedDB.open(dbName).onsuccess = async e => {
const idb = /** @type IDBDatabase */ e.target.result;
const ta = idb.objectStoreNames[0] === 'data' && idb.transaction(['data']);
if (ta && ta.objectStore('data').autoIncrement) {
ta.abort();
idb.close();
await new Promise(setTimeout);
indexedDB.deleteDatabase(dbName);
}
};
} catch (e) {}
}
}
});
@ -192,6 +208,6 @@ Promise.all([
require(['/background/context-menus']),
]).then(() => {
bgReady._resolveAll();
msg.isBgReady = true;
msg.ready = true;
msg.broadcast({method: 'backgroundReady'});
});

View File

@ -0,0 +1,91 @@
/* global prefs */
/* exported colorScheme */
'use strict';
const colorScheme = (() => {
const changeListeners = new Set();
const kSTATE = 'schemeSwitcher.enabled';
const kSTART = 'schemeSwitcher.nightStart';
const kEND = 'schemeSwitcher.nightEnd';
const SCHEMES = ['dark', 'light'];
const isDark = {
never: null,
dark: true,
light: false,
system: false,
time: false,
};
let isDarkNow = false;
prefs.subscribe(kSTATE, () => update());
prefs.subscribe([kSTART, kEND], (key, value) => {
updateTimePreferDark();
createAlarm(key, value);
}, {runNow: true});
chrome.alarms.onAlarm.addListener(({name}) => {
if (name === kSTART || name === kEND) {
updateTimePreferDark();
}
});
return {
SCHEMES,
onChange(listener) {
changeListeners.add(listener);
},
isDark: () => isDarkNow,
/** @param {StyleObj} _ */
shouldIncludeStyle({preferScheme: ps}) {
return prefs.get(kSTATE) === 'never' ||
!SCHEMES.includes(ps) ||
isDarkNow === (ps === 'dark');
},
updateSystemPreferDark(val) {
update('system', val);
return true;
},
};
function calcTime(key) {
const [h, m] = prefs.get(key).split(':');
return (h * 3600 + m * 60) * 1000;
}
function createAlarm(key, value) {
const date = new Date();
const [h, m] = value.split(':');
date.setHours(h, m, 0, 0);
if (date.getTime() < Date.now()) {
date.setDate(date.getDate() + 1);
}
chrome.alarms.create(key, {
when: date.getTime(),
periodInMinutes: 24 * 60,
});
}
function updateTimePreferDark() {
const now = Date.now() - new Date().setHours(0, 0, 0, 0);
const start = calcTime(kSTART);
const end = calcTime(kEND);
const val = start > end ?
now >= start || now < end :
now >= start && now < end;
update('time', val);
}
function update(type, val) {
if (type) {
if (isDark[type] === val) return;
isDark[type] = val;
}
val = isDark[prefs.get(kSTATE)];
if (isDarkNow !== val) {
isDarkNow = val;
for (const listener of changeListeners) {
listener(isDarkNow);
}
}
}
})();

92
background/common.js Normal file
View File

@ -0,0 +1,92 @@
/* global API */// msg.js
'use strict';
/**
* Common stuff that's loaded first so it's immediately available to all background scripts
*/
window.bgReady = {}; /* global bgReady */
bgReady.styles = new Promise(r => (bgReady._resolveStyles = r));
bgReady.all = new Promise(r => (bgReady._resolveAll = r));
const uuidIndex = Object.assign(new Map(), {
custom: {},
/** `obj` must have a unique `id`, a UUIDv4 `_id`, and Date.now() for `_rev`. */
addCustomId(obj, {get = () => obj, set}) {
Object.defineProperty(uuidIndex.custom, obj.id, {get, set});
},
});
/* exported addAPI */
function addAPI(methods) {
for (const [key, val] of Object.entries(methods)) {
const old = API[key];
if (old && Object.prototype.toString.call(old) === '[object Object]') {
Object.assign(old, val);
} else {
API[key] = val;
}
}
}
/* exported createCache */
/** Creates a FIFO limit-size map. */
function createCache({size = 1000, onDeleted} = {}) {
const map = new Map();
const buffer = Array(size);
let index = 0;
let lastIndex = 0;
return {
get(id) {
const item = map.get(id);
return item && item.data;
},
set(id, data) {
if (map.size === size) {
// full
map.delete(buffer[lastIndex].id);
if (onDeleted) {
onDeleted(buffer[lastIndex].id, buffer[lastIndex].data);
}
lastIndex = (lastIndex + 1) % size;
}
const item = {id, data, index};
map.set(id, item);
buffer[index] = item;
index = (index + 1) % size;
},
delete(id) {
const item = map.get(id);
if (!item) {
return false;
}
map.delete(item.id);
const lastItem = buffer[lastIndex];
lastItem.index = item.index;
buffer[item.index] = lastItem;
lastIndex = (lastIndex + 1) % size;
if (onDeleted) {
onDeleted(item.id, item.data);
}
return true;
},
clear() {
map.clear();
index = lastIndex = 0;
},
has: id => map.has(id),
*entries() {
for (const [id, item] of map) {
yield [id, item.data];
}
},
*values() {
for (const item of map.values()) {
yield item.data;
}
},
get size() {
return map.size;
},
};
}

View File

@ -0,0 +1,87 @@
/* global browserCommands */// background.js
/* global msg */
/* global prefs */
/* global CHROME URLS ignoreChromeError */// toolbox.js
'use strict';
chrome.management.getSelf(ext => {
const contextMenus = Object.assign({
'show-badge': {
title: 'menuShowBadge',
click: togglePref,
},
'disableAll': {
title: 'disableAllStyles',
click: browserCommands.styleDisableAll,
},
'open-manager': {
title: 'optionsOpenManager',
click: browserCommands.openManage,
},
'open-options': {
title: 'openOptions',
click: browserCommands.openOptions,
},
}, ext.installType === 'development' && {
'reload': {
title: 'reload',
click: browserCommands.reload,
},
}, CHROME && {
'editor.contextDelete': {
title: 'editDeleteText',
type: 'normal',
contexts: ['editable'],
documentUrlPatterns: [URLS.ownOrigin + '*'],
click: (info, tab) => {
msg.sendTab(tab.id, {method: 'editDeleteText'}, undefined, 'extension')
.catch(msg.ignoreError);
},
},
});
createContextMenus(Object.keys(contextMenus));
chrome.contextMenus.onClicked.addListener((info, tab) =>
contextMenus[info.menuItemId].click(info, tab));
function createContextMenus(ids) {
for (const id of ids) {
const item = Object.assign({id, contexts: ['browser_action']}, contextMenus[id]);
item.title = chrome.i18n.getMessage(item.title);
if (typeof prefs.defaults[id] === 'boolean') {
if (item.type) {
prefs.subscribe(id, togglePresence);
} else {
item.type = 'checkbox';
item.checked = prefs.get(id);
prefs.subscribe(id, CHROME >= 62 && CHROME <= 64 ? toggleCheckmarkBugged : toggleCheckmark);
}
}
delete item.click;
chrome.contextMenus.create(item, ignoreChromeError);
}
}
function toggleCheckmark(id, checked) {
chrome.contextMenus.update(id, {checked}, ignoreChromeError);
}
/** Circumvents the bug with disabling check marks in Chrome 62-64 */
async function toggleCheckmarkBugged(id) {
await browser.contextMenus.remove(id).catch(ignoreChromeError);
createContextMenus([id]);
}
/** @param {chrome.contextMenus.OnClickData} info */
function togglePref(info) {
prefs.set(info.menuItemId, info.checked);
}
function togglePresence(id, checked) {
if (checked) {
createContextMenus([id]);
} else {
chrome.contextMenus.remove(id, ignoreChromeError);
}
}
});

View File

@ -2,17 +2,17 @@
'use strict';
/* exported createChromeStorageDB */
function createChromeStorageDB() {
function createChromeStorageDB(PREFIX) {
let INC;
const isMain = !PREFIX;
if (!PREFIX) PREFIX = 'style-';
const PREFIX = 'style-';
const METHODS = {
return {
delete(id) {
return chromeLocal.remove(PREFIX + id);
},
// FIXME: we don't use this method at all. Should we remove this?
get(id) {
return chromeLocal.getValue(PREFIX + id);
},
@ -21,7 +21,9 @@ function createChromeStorageDB() {
const all = await chromeLocal.get();
if (!INC) prepareInc(all);
return Object.entries(all)
.map(([key, val]) => key.startsWith(PREFIX) && Number(key.slice(PREFIX.length)) && val)
.map(([key, val]) => key.startsWith(PREFIX) &&
(!isMain || Number(key.slice(PREFIX.length))) &&
val)
.filter(Boolean);
},
@ -59,8 +61,4 @@ function createChromeStorageDB() {
}
}
}
return function dbExecChromeStorage(method, ...args) {
return METHODS[method](...args);
};
}

150
background/db.js Normal file
View File

@ -0,0 +1,150 @@
/* global addAPI */// common.js
/* global chromeLocal */// storage-util.js
/* global cloneError */// worker-util.js
/* global deepCopy */// toolbox.js
/* global prefs */
'use strict';
/*
Initialize a database. There are some problems using IndexedDB in Firefox:
https://www.reddit.com/r/firefox/comments/74wttb/note_to_firefox_webextension_developers_who_use/
Some of them are fixed in FF59:
https://www.reddit.com/r/firefox/comments/7ijuaq/firefox_59_webextensions_can_use_indexeddb_when/
*/
/* exported db */
const db = (() => {
let exec = async (...args) => (
exec = await tryUsingIndexedDB().catch(useChromeStorage)
)(...args);
const DB = 'stylish';
const FALLBACK = 'dbInChromeStorage';
const ID_AS_KEY = {[DB]: true};
const getStoreName = dbName => dbName === DB ? 'styles' : 'data';
const cache = {};
const proxies = {};
const proxyHandler = {
get: ({dbName}, cmd) =>
(...args) =>
(dbName === DB ? exec : cachedExec)(dbName, cmd, ...args),
};
/**
* @param {string} dbName
* @return {IDBObjectStore | {putMany: function(items:?[]):Promise<?[]>}}
*/
const getProxy = dbName => proxies[dbName] || (
(proxies[dbName] = new Proxy({dbName}, proxyHandler))
);
addAPI(/** @namespace API */ {
drafts: getProxy('drafts'),
/** Storage for big items that may exceed 8kB limit of chrome.storage.sync.
* To make an item syncable register it with uuidIndex.addCustomId. */
prefsDb: getProxy(prefs.STORAGE_KEY),
});
return {
styles: getProxy(DB),
};
async function cachedExec(dbName, cmd, a, b) {
const hub = cache[dbName] || (cache[dbName] = {});
const res = cmd === 'get' && a in hub ? hub[a] : await exec(...arguments);
if (cmd === 'get') {
hub[a] = deepCopy(res);
} else if (cmd === 'put') {
hub[ID_AS_KEY[dbName] ? a.id : b] = deepCopy(a);
} else if (cmd === 'delete') {
delete hub[a];
}
return res;
}
async function tryUsingIndexedDB() {
// we use chrome.storage.local fallback if IndexedDB doesn't save data,
// which, once detected on the first run, is remembered in chrome.storage.local
// note that accessing indexedDB may throw, https://github.com/openstyles/stylus/issues/615
if (typeof indexedDB === 'undefined') {
throw new Error('indexedDB is undefined');
}
switch (await chromeLocal.getValue(FALLBACK)) {
case true: throw null;
case false: break;
default: await testDB();
}
chromeLocal.setValue(FALLBACK, false);
return dbExecIndexedDB;
}
async function testDB() {
const id = `${performance.now()}.${Math.random()}.${Date.now()}`;
await dbExecIndexedDB(DB, 'put', {id});
const e = await dbExecIndexedDB(DB, 'get', id);
await dbExecIndexedDB(DB, 'delete', e.id); // throws if `e` or id is null
}
async function useChromeStorage(err) {
chromeLocal.setValue(FALLBACK, true);
if (err) {
chromeLocal.setValue(FALLBACK + 'Reason', cloneError(err));
console.warn('Failed to access indexedDB. Switched to storage API.', err);
}
await require(['/background/db-chrome-storage']); /* global createChromeStorageDB */
const BASES = {};
return (dbName, method, ...args) => (
BASES[dbName] || (
BASES[dbName] = createChromeStorageDB(dbName !== DB && `${dbName}-`)
)
)[method](...args);
}
async function dbExecIndexedDB(dbName, method, ...args) {
const mode = method.startsWith('get') ? 'readonly' : 'readwrite';
const storeName = getStoreName(dbName);
const store = (await open(dbName)).transaction([storeName], mode).objectStore(storeName);
const fn = method === 'putMany' ? putMany : storeRequest;
return fn(store, method, ...args);
}
function storeRequest(store, method, ...args) {
return new Promise((resolve, reject) => {
/** @type {IDBRequest} */
const request = store[method](...args);
request.onsuccess = () => resolve(request.result);
request.onerror = reject;
});
}
function putMany(store, _method, items) {
return Promise.all(items.map(item => storeRequest(store, 'put', item)));
}
function open(name) {
return new Promise((resolve, reject) => {
const request = indexedDB.open(name, 2);
request.onsuccess = e => resolve(create(e));
request.onerror = reject;
request.onupgradeneeded = create;
});
}
function create(event) {
/** @type IDBDatabase */
const idb = event.target.result;
const dbName = idb.name;
const sn = getStoreName(dbName);
if (!idb.objectStoreNames.contains(sn)) {
if (event.type === 'success') {
idb.close();
return new Promise(resolve => {
indexedDB.deleteDatabase(dbName).onsuccess = () => {
resolve(open(dbName));
};
});
}
idb.createObjectStore(sn, ID_AS_KEY[dbName] ? {
keyPath: 'id',
autoIncrement: true,
} : undefined);
}
return idb;
}
})();

View File

@ -1,19 +1,20 @@
/* global API */// msg.js
/* global addAPI bgReady */// common.js
/* global colorScheme */
/* global prefs */
/* global tabMan */
/* global CHROME FIREFOX VIVALDI debounce ignoreChromeError */// toolbox.js
/* global CHROME FIREFOX UA debounce ignoreChromeError */// toolbox.js
'use strict';
/* exported iconMan */
const iconMan = (() => {
const ICON_SIZES = FIREFOX || CHROME >= 55 && !VIVALDI ? [16, 32] : [19, 38];
const ICON_SIZES = FIREFOX || CHROME && !UA.vivaldi ? [16, 32] : [19, 38];
const staleBadges = new Set();
const imageDataCache = new Map();
const badgeOvr = {color: '', text: ''};
// https://github.com/openstyles/stylus/issues/1287 Fenix can't use custom ImageData
const FIREFOX_ANDROID = FIREFOX && navigator.userAgent.includes('Android');
const FIREFOX_ANDROID = FIREFOX && UA.mobile;
let isDark;
// https://github.com/openstyles/stylus/issues/335
let hasCanvas = FIREFOX_ANDROID ? false : loadImage(`/images/icon/${ICON_SIZES[0]}.png`)
.then(({data}) => (hasCanvas = data.some(b => b !== 255)));
@ -37,13 +38,17 @@ const iconMan = (() => {
chrome.webNavigation.onCommitted.addListener(({tabId, frameId}) => {
if (!frameId) tabMan.set(tabId, 'styleIds', undefined);
});
chrome.runtime.onConnect.addListener(port => {
if (port.name === 'iframe') {
port.onDisconnect.addListener(onPortDisconnected);
}
});
colorScheme.onChange(val => {
isDark = val;
if (prefs.get('iconset') === -1) {
debounce(refreshAllIcons);
}
});
bgReady.all.then(() => {
prefs.subscribe([
'disableAll',
@ -95,9 +100,10 @@ const iconMan = (() => {
}
function getIconName(hasStyles = false) {
const iconset = prefs.get('iconset') === 1 ? 'light/' : '';
const i = prefs.get('iconset');
const prefix = i === 0 || i === -1 && isDark ? '' : 'light/';
const postfix = prefs.get('disableAll') ? 'x' : !hasStyles ? 'w' : '';
return `${iconset}$SIZE$${postfix}`;
return `${prefix}$SIZE$${postfix}`;
}
function refreshIcon(tabId, force = false) {

View File

@ -1,7 +1,7 @@
/* global API msg */// msg.js
/* global CHROME URLS isEmptyObj stringAsRegExp tryRegExp tryURL */// toolbox.js
/* global bgReady compareRevision */// common.js
/* global calcStyleDigest styleCodeEmpty styleSectionGlobal */// sections-util.js
/* global CHROME URLS deepEqual isEmptyObj mapObj stringAsRegExp tryRegExp tryURL */// toolbox.js
/* global bgReady createCache uuidIndex */// common.js
/* global calcStyleDigest styleCodeEmpty */// sections-util.js
/* global db */
/* global prefs */
/* global tabMan */
@ -18,18 +18,26 @@ The live preview feature relies on `runtime.connect` and `port.onDisconnect`
to cleanup the temporary code. See livePreview in /edit.
*/
const styleUtil = {};
/* exported styleMan */
const styleMan = (() => {
Object.assign(styleUtil, {
id2style,
handleSave,
uuid2style,
});
//#region Declarations
/** @typedef {{
style: StyleObj
preview?: StyleObj
appliesTo: Set<string>
style: StyleObj,
preview?: StyleObj,
appliesTo: Set<string>,
}} StyleMapData */
/** @type {Map<number,StyleMapData>} */
const dataMap = new Map();
const uuidIndex = new Map();
/** @typedef {Object<styleId,{id: number, code: string[]}>} StyleSectionsToApply */
/** @type {Map<string,{maybeMatch: Set<styleId>, sections: StyleSectionsToApply}>} */
const cachedStyleForUrl = createCache({
@ -55,18 +63,55 @@ const styleMan = (() => {
name: style => `ID: ${style.id}`,
_id: () => uuidv4(),
_rev: () => Date.now(),
_usw: () => ({}),
};
const DELETE_IF_NULL = ['id', 'customName', 'md5Url', 'originalMd5'];
/** @type {Promise|boolean} will be `true` to avoid wasting a microtask tick on each `await` */
let ready = init();
const INJ_ORDER = 'injectionOrder';
const order = {main: {}, prio: {}};
const orderWrap = {
id: INJ_ORDER,
value: mapObj(order, () => []),
_id: `${chrome.runtime.id}-${INJ_ORDER}`,
_rev: 0,
};
uuidIndex.addCustomId(orderWrap, {set: setOrder});
chrome.runtime.onConnect.addListener(handleLivePreview);
// function handleColorScheme() {
colorScheme.onChange(() => {
for (const {style: data} of dataMap.values()) {
if (data.preferScheme === 'dark' || data.preferScheme === 'light') {
broadcastStyleUpdated(data, 'colorScheme', undefined, false);
class MatchQuery {
constructor(url) {
this.url = url;
}
get urlWithoutHash() {
return this._set('urlWithoutHash', this.url.split('#', 1)[0]);
}
get urlWithoutParams() {
return this._set('urlWithoutParams', this.url.split(/[?#]/, 1)[0]);
}
get domain() {
return this._set('domain', tryURL(this.url).hostname);
}
get isOwnPage() {
return this._set('isOwnPage', this.url.startsWith(URLS.ownOrigin));
}
_set(name, value) {
Object.defineProperty(this, name, {value});
return value;
}
}
/** @type {Promise|boolean} will be `true` to avoid wasting a microtask tick on each `await` */
let ready = Promise.all([init(), prefs.ready]);
chrome.runtime.onConnect.addListener(port => {
if (port.name === 'livePreview') {
handleLivePreview(port);
} else if (port.name.startsWith('draft:')) {
handleDraft(port);
}
});
colorScheme.onChange(value => {
msg.broadcastExtension({method: 'colorScheme', value});
for (const {style} of dataMap.values()) {
if (colorScheme.SCHEMES.includes(style.preferScheme)) {
broadcastStyleUpdated(style, 'colorScheme');
}
}
});
@ -79,22 +124,28 @@ const styleMan = (() => {
/** @returns {Promise<number>} style id */
async delete(id, reason) {
if (ready.then) await ready;
const data = id2data(id);
const {style, appliesTo} = data;
await db.exec('delete', id);
if (reason !== 'sync') {
API.sync.delete(style._id, Date.now());
}
const {style, appliesTo} = dataMap.get(id);
const sync = reason !== 'sync';
const uuid = style._id;
db.styles.delete(id);
if (sync) API.sync.delete(uuid, Date.now());
for (const url of appliesTo) {
const cache = cachedStyleForUrl.get(url);
if (cache) delete cache.sections[id];
}
dataMap.delete(id);
uuidIndex.delete(style._id);
uuidIndex.delete(uuid);
mapObj(orderWrap.value, (group, type) => {
delete order[type][id];
const i = group.indexOf(uuid);
if (i >= 0) group.splice(i, 1);
});
setOrder(orderWrap, {calc: false});
if (style._usw && style._usw.token) {
// Must be called after the style is deleted from dataMap
API.usw.revoke(id);
}
API.drafts.delete(id);
await msg.broadcast({
method: 'styleDeleted',
style: {id},
@ -102,17 +153,6 @@ const styleMan = (() => {
return id;
},
/** @returns {Promise<number>} style id */
async deleteByUUID(_id, rev) {
if (ready.then) await ready;
const id = uuidIndex.get(_id);
const oldDoc = id && id2style(id);
if (oldDoc && compareRevision(oldDoc._rev, rev) <= 0) {
// FIXME: does it make sense to set reason to 'sync' in deleteByUUID?
return styleMan.delete(id, 'sync');
}
},
/** @returns {Promise<StyleObj>} */
async editSave(style) {
if (ready.then) await ready;
@ -122,12 +162,14 @@ const styleMan = (() => {
},
/** @returns {Promise<?StyleObj>} */
async find(filter) {
async find(...filters) {
if (ready.then) await ready;
const filterEntries = Object.entries(filter);
for (const {style} of dataMap.values()) {
if (filterEntries.every(([key, val]) => style[key] === val)) {
return style;
for (const filter of filters) {
const filterEntries = Object.entries(filter);
for (const {style} of dataMap.values()) {
if (filterEntries.every(([key, val]) => style[key] === val)) {
return style;
}
}
}
return null;
@ -136,21 +178,51 @@ const styleMan = (() => {
/** @returns {Promise<StyleObj[]>} */
async getAll() {
if (ready.then) await ready;
return Array.from(dataMap.values(), data2style);
return getAllAsArray();
},
/** @returns {Promise<StyleObj>} */
async getByUUID(uuid) {
/** @returns {Promise<Object<string,StyleObj[]>>}>} */
async getAllOrdered(keys) {
if (ready.then) await ready;
return id2style(uuidIndex.get(uuid));
const res = mapObj(orderWrap.value, group => group.map(uuid2style).filter(Boolean));
if (res.main.length + res.prio.length < dataMap.size) {
for (const {style} of dataMap.values()) {
if (!(style.id in order.main) && !(style.id in order.prio)) {
res.main.push(style);
}
}
}
return keys
? mapObj(res, group => group.map(style => mapObj(style, null, keys)))
: res;
},
getOrder: () => orderWrap.value,
/** @returns {Promise<string | {[remoteId:string]: styleId}>}>} */
async getRemoteInfo(id) {
if (ready.then) await ready;
if (id) return calcRemoteId(id2style(id));
const res = {};
for (const {style} of dataMap.values()) {
const [rid, vars] = calcRemoteId(style);
if (rid) res[rid] = [style.id, vars];
}
return res;
},
/** @returns {Promise<StyleSectionsToApply>} */
async getSectionsByUrl(url, id, isInitialApply) {
if (ready.then) await ready;
if (isInitialApply && prefs.get('disableAll')) {
return {disableAll: true};
return {
cfg: {
disableAll: true,
},
};
}
// TODO: enable in FF when it supports sourceURL comment in style elements (also options.html)
const {exposeStyleName} = CHROME && prefs.__values;
const sender = CHROME && this && this.sender || {};
if (sender.frameId === 0) {
/* Chrome hides text frament from location.href of the page e.g. #:~:text=foo
@ -169,9 +241,9 @@ const styleMan = (() => {
} else if (cache.maybeMatch.size) {
buildCache(cache, url, Array.from(cache.maybeMatch, id2data).filter(Boolean));
}
return id
? cache.sections[id] ? {[id]: cache.sections[id]} : {}
: cache.sections;
return Object.assign({cfg: {exposeStyleName, order}},
id ? mapObj(cache.sections, null, [id])
: cache.sections);
},
/** @returns {Promise<StyleObj>} */
@ -188,8 +260,8 @@ const styleMan = (() => {
const result = [];
const styles = id
? [id2style(id)].filter(Boolean)
: Array.from(dataMap.values(), data2style);
const query = createMatchQuery(url);
: getAllAsArray();
const query = new MatchQuery(url);
for (const style of styles) {
let excluded = false;
let excludedScheme = false;
@ -211,10 +283,7 @@ const styleMan = (() => {
excludedScheme = true;
}
for (const section of style.sections) {
if (styleSectionGlobal(section) && styleCodeEmpty(section.code)) {
continue;
}
const match = urlMatchSection(query, section);
const match = urlMatchSection(query, section, true);
if (match) {
if (match === 'sloppy') {
sloppy = true;
@ -240,11 +309,10 @@ const styleMan = (() => {
await usercssMan.buildCode(style);
}
}
const events = await db.exec('putMany', items);
return Promise.all(items.map((item, i) => {
afterSave(item, events[i]);
return handleSave(item, {reason: 'import'});
}));
const events = await db.styles.putMany(items);
return Promise.all(items.map((item, i) =>
handleSave(item, {reason: 'import'}, events[i])
));
},
/** @returns {Promise<StyleObj>} */
@ -257,33 +325,13 @@ const styleMan = (() => {
return saveStyle(style, {reason});
},
/** @returns {Promise<?StyleObj>} */
async putByUUID(doc) {
if (ready.then) await ready;
const id = uuidIndex.get(doc._id);
if (id) {
doc.id = id;
} else {
delete doc.id;
}
const oldDoc = id && id2style(id);
let diff = -1;
if (oldDoc) {
diff = compareRevision(oldDoc._rev, doc._rev);
if (diff > 0) {
API.sync.put(oldDoc._id, oldDoc._rev);
return;
}
}
if (diff < 0) {
doc.id = await db.exec('put', doc);
uuidIndex.set(doc._id, doc.id);
return handleSave(doc, {reason: 'sync'});
}
},
save: saveStyle,
async setOrder(value) {
if (ready.then) await ready;
return setOrder({value}, {broadcast: true, sync: true});
},
/** @returns {Promise<number>} style id */
async toggle(id, enabled) {
if (ready.then) await ready;
@ -306,7 +354,8 @@ const styleMan = (() => {
async config(id, prop, value) {
if (ready.then) await ready;
const style = Object.assign({}, id2style(id));
style[prop] = value;
const {preview = {}} = dataMap.get(id);
style[prop] = preview[prop] = value;
return saveStyle(style, {reason: 'config'});
},
};
@ -321,12 +370,23 @@ const styleMan = (() => {
/** @returns {?StyleObj} */
function id2style(id) {
return (dataMap.get(id) || {}).style;
return (dataMap.get(Number(id)) || {}).style;
}
/** @returns {?StyleObj} */
function data2style(data) {
return data && data.style;
function uuid2style(uuid) {
return id2style(uuidIndex.get(uuid));
}
function calcRemoteId({md5Url, updateUrl, usercssData: ucd} = {}) {
let id;
id = (id = /\d+/.test(md5Url) || URLS.extractUsoArchiveId(updateUrl)) && `uso-${id}`
|| (id = URLS.extractUSwId(updateUrl)) && `usw-${id}`
|| '';
return id && [
id,
ucd && !isEmptyObj(ucd.vars),
];
}
/** @returns {StyleObj} */
@ -347,6 +407,7 @@ const styleMan = (() => {
style,
appliesTo: new Set(),
});
uuidIndex.set(style._id, style.id);
}
/** @returns {StyleObj} */
@ -356,10 +417,12 @@ const styleMan = (() => {
style);
}
function handleDraft(port) {
const id = port.name.split(':').pop();
port.onDisconnect.addListener(() => API.drafts.delete(Number(id) || id));
}
function handleLivePreview(port) {
if (port.name !== 'livePreview') {
return;
}
let id;
port.onMessage.addListener(style => {
if (!id) id = style.id;
@ -411,10 +474,10 @@ const styleMan = (() => {
cache.maybeMatch.add(id);
continue;
}
const code = getAppliedCode(createMatchQuery(url), style);
const code = getAppliedCode(new MatchQuery(url), style);
if (code) {
updated.add(url);
cache.sections[id] = {id, code};
buildCacheEntry(cache, style, code);
} else {
excluded.add(url);
delete cache.sections[id];
@ -448,29 +511,24 @@ const styleMan = (() => {
fixKnownProblems(style);
}
function afterSave(style, newId) {
if (style.id == null) {
style.id = newId;
}
uuidIndex.set(style._id, style.id);
API.sync.put(style._id, style._rev);
}
async function saveStyle(style, handlingOptions) {
beforeSave(style);
const newId = await db.exec('put', style);
afterSave(style, newId);
return handleSave(style, handlingOptions);
const newId = await db.styles.put(style);
return handleSave(style, handlingOptions, newId);
}
function handleSave(style, {reason, broadcast = true}) {
const data = id2data(style.id);
function handleSave(style, {reason, broadcast = true}, id = style.id) {
if (style.id == null) style.id = id;
const data = id2data(id);
const method = data ? 'styleUpdated' : 'styleAdded';
if (!data) {
storeInMap(style);
} else {
data.style = style;
}
if (reason !== 'sync') {
API.sync.putDoc(style);
}
if (broadcast) broadcastStyleUpdated(style, reason, method);
return style;
}
@ -495,15 +553,14 @@ const styleMan = (() => {
}
async function init() {
const styles = await db.exec('getAll') || [];
const orderPromise = API.prefsDb.get(orderWrap.id);
const styles = await db.styles.getAll() || [];
const updated = await Promise.all(styles.map(fixKnownProblems).filter(Boolean));
if (updated.length) {
await db.exec('putMany', updated);
}
for (const style of styles) {
storeInMap(style);
uuidIndex.set(style._id, style.id);
await db.styles.putMany(updated);
}
setOrder(await orderPromise, {store: false});
styles.forEach(storeInMap);
ready = true;
bgReady._resolveStyles();
}
@ -587,40 +644,56 @@ const styleMan = (() => {
return true;
}
function urlMatchSection(query, section) {
function urlMatchSection(query, section, skipEmptyGlobal) {
let dd, ddL, pp, ppL, rr, rrL, uu, uuL;
if (
section.domains &&
section.domains.some(d => d === query.domain || query.domain.endsWith(`.${d}`))
(dd = section.domains) && (ddL = dd.length) && dd.some(urlMatchDomain, query) ||
(pp = section.urlPrefixes) && (ppL = pp.length) && pp.some(urlMatchPrefix, query) ||
/* Per the specification the fragment portion is ignored in @-moz-document:
https://www.w3.org/TR/2012/WD-css3-conditional-20120911/#url-of-doc
but the spec is outdated and doesn't account for SPA sites,
so we only respect it for `url()` function */
(uu = section.urls) && (uuL = uu.length) && (
uu.includes(query.url) ||
uu.includes(query.urlWithoutHash)
) ||
(rr = section.regexps) && (rrL = rr.length) && rr.some(urlMatchRegexp, query)
) {
return true;
}
if (section.urlPrefixes && section.urlPrefixes.some(p => p && query.url.startsWith(p))) {
return true;
}
// as per spec the fragment portion is ignored in @-moz-document:
// https://www.w3.org/TR/2012/WD-css3-conditional-20120911/#url-of-doc
// but the spec is outdated and doesn't account for SPA sites
// so we only respect it for `url()` function
if (section.urls && (
section.urls.includes(query.url) ||
section.urls.includes(query.urlWithoutHash)
)) {
return true;
}
if (section.regexps && section.regexps.some(r => compileRe(r).test(query.url))) {
return true;
}
/*
According to CSS4 @document specification the entire URL must match.
Stylish-for-Chrome implemented it incorrectly since the very beginning.
We'll detect styles that abuse the bug by finding the sections that
would have been applied by Stylish but not by us as we follow the spec.
*/
if (section.regexps && section.regexps.some(r => compileSloppyRe(r).test(query.url))) {
if (rrL && rr.some(urlMatchRegexpSloppy, query)) {
return 'sloppy';
}
// TODO: check for invalid regexps?
return styleSectionGlobal(section);
return !rrL && !ppL && !uuL && !ddL &&
!query.isOwnPage && // We allow only intentionally targeted sections for own pages
(!skipEmptyGlobal || !styleCodeEmpty(section.code));
}
/** @this {MatchQuery} */
function urlMatchDomain(d) {
const _d = this.domain;
return d === _d ||
_d[_d.length - d.length - 1] === '.' && _d.endsWith(d);
}
/** @this {MatchQuery} */
function urlMatchPrefix(p) {
return p && this.url.startsWith(p);
}
/** @this {MatchQuery} */
function urlMatchRegexp(r) {
return (!this.isOwnPage || /\bextension\b/.test(r)) &&
compileRe(r).test(this.url);
}
/** @this {MatchQuery} */
function urlMatchRegexpSloppy(r) {
return (!this.isOwnPage || /\bextension\b/.test(r)) &&
compileSloppyRe(r).test(this.url);
}
function createCompiler(compile) {
@ -660,112 +733,59 @@ const styleMan = (() => {
'$';
}
function createMatchQuery(url) {
let urlWithoutHash;
let urlWithoutParams;
let domain;
return {
url,
get urlWithoutHash() {
if (!urlWithoutHash) {
urlWithoutHash = url.split('#')[0];
}
return urlWithoutHash;
},
get urlWithoutParams() {
if (!urlWithoutParams) {
const u = tryURL(url);
urlWithoutParams = u.origin + u.pathname;
}
return urlWithoutParams;
},
get domain() {
if (!domain) {
const u = tryURL(url);
domain = u.hostname;
}
return domain;
},
};
}
function buildCache(cache, url, styleList) {
const query = createMatchQuery(url);
const query = new MatchQuery(url);
for (const {style, appliesTo, preview} of styleList) {
const code = getAppliedCode(query, preview || style);
if (code) {
const id = style.id;
cache.sections[id] = {id, code};
buildCacheEntry(cache, style, code);
appliesTo.add(url);
}
}
}
function buildCacheEntry(cache, style, code = style.code) {
cache.sections[style.id] = {
code,
id: style.id,
name: style.customName || style.name,
};
}
/** @returns {StyleObj[]} */
function getAllAsArray() {
return Array.from(dataMap.values(), v => v.style);
}
/** uuidv4 helper: converts to a 4-digit hex string and adds "-" at required positions */
function hex4dashed(num, i) {
return (num + 0x10000).toString(16).slice(-4) + (i >= 1 && i <= 4 ? '-' : '');
}
async function setOrder(data, {broadcast, calc = true, store = true, sync} = {}) {
if (!data || !data.value || deepEqual(data.value, orderWrap.value)) {
return;
}
Object.assign(orderWrap, data, sync && {_rev: Date.now()});
if (calc) {
for (const [type, group] of Object.entries(data.value)) {
const dst = order[type] = {};
group.forEach((uuid, i) => {
const id = uuidIndex.get(uuid);
if (id) dst[id] = i;
});
}
}
if (broadcast) {
msg.broadcast({method: 'styleSort', order});
}
if (store) {
await API.prefsDb.put(orderWrap, orderWrap.id);
}
if (sync) {
API.sync.putDoc(orderWrap);
}
}
//#endregion
})();
/** Creates a FIFO limit-size map. */
function createCache({size = 1000, onDeleted} = {}) {
const map = new Map();
const buffer = Array(size);
let index = 0;
let lastIndex = 0;
return {
get(id) {
const item = map.get(id);
return item && item.data;
},
set(id, data) {
if (map.size === size) {
// full
map.delete(buffer[lastIndex].id);
if (onDeleted) {
onDeleted(buffer[lastIndex].id, buffer[lastIndex].data);
}
lastIndex = (lastIndex + 1) % size;
}
const item = {id, data, index};
map.set(id, item);
buffer[index] = item;
index = (index + 1) % size;
},
delete(id) {
const item = map.get(id);
if (!item) {
return false;
}
map.delete(item.id);
const lastItem = buffer[lastIndex];
lastItem.index = item.index;
buffer[item.index] = lastItem;
lastIndex = (lastIndex + 1) % size;
if (onDeleted) {
onDeleted(item.id, item.data);
}
return true;
},
clear() {
map.clear();
index = lastIndex = 0;
},
has: id => map.has(id),
*entries() {
for (const [id, item] of map) {
yield [id, item.data];
}
},
*values() {
for (const item of map.values()) {
yield item.data;
}
},
get size() {
return map.size;
},
};
}

View File

@ -56,6 +56,7 @@
return NOP;
}
return API.styles.getSectionsByUrl(url, id).then(sections => {
delete sections.cfg;
const tasks = [];
for (const section of Object.values(sections)) {
const styleId = section.id;

View File

@ -1,5 +1,5 @@
/* global API */// msg.js
/* global CHROME ignoreChromeError */// toolbox.js
/* global CHROME URLS ignoreChromeError */// toolbox.js
/* global prefs */
'use strict';
@ -49,6 +49,12 @@
if (CHROME && !off) {
chrome.webNavigation.onCommitted.addListener(injectData, {url: [{urlPrefix: 'http'}]});
}
if (CHROME) {
chrome.webRequest.onBeforeRequest.addListener(openNamedStyle, {
urls: [URLS.ownOrigin + '*.user.css'],
types: ['main_frame'],
}, ['blocking']);
}
state.csp = csp;
state.off = off;
state.xhr = xhr;
@ -146,6 +152,14 @@
}
}
/** @param {chrome.webRequest.WebRequestBodyDetails} req */
function openNamedStyle(req) {
if (!req.url.includes('?')) { // skipping our usercss installer
chrome.tabs.update(req.tabId, {url: 'edit.html?id=' + req.url.split('#')[1]});
return {cancel: true};
}
}
function req2key(req) {
return req.tabId + ':' + req.frameId;
}

View File

@ -1,8 +1,10 @@
/* global API msg */// msg.js
/* global bgReady uuidIndex */// common.js
/* global chromeLocal chromeSync */// storage-util.js
/* global compareRevision */// common.js
/* global db */
/* global iconMan */
/* global prefs */
/* global styleUtil */
/* global tokenMan */
'use strict';
@ -28,11 +30,12 @@ const syncMan = (() => {
errorMessage: null,
login: false,
};
const compareRevision = (rev1, rev2) => rev1 - rev2;
let lastError = null;
let ctrl;
let currentDrive;
/** @type {Promise|boolean} will be `true` to avoid wasting a microtask tick on each `await` */
let ready = prefs.ready.then(() => {
let ready = bgReady.styles.then(() => {
ready = true;
prefs.subscribe('sync.enabled',
(_, val) => val === 'none'
@ -79,11 +82,11 @@ const syncMan = (() => {
}
},
async put(...args) {
async putDoc({_id, _rev}) {
if (ready.then) await ready;
if (!currentDrive) return;
schedule();
return ctrl.put(...args);
return ctrl.put(_id, _rev);
},
async setDriveOptions(driveName, options) {
@ -176,19 +179,35 @@ const syncMan = (() => {
//#region Utils
async function initController() {
await require(['/vendor/db-to-cloud/db-to-cloud.min']); /* global dbToCloud */
await require(['/vendor/db-to-cloud/db-to-cloud']); /* global dbToCloud */
ctrl = dbToCloud.dbToCloud({
onGet(id) {
return API.styles.getByUUID(id);
onGet: styleUtil.uuid2style,
async onPut(doc) {
const id = uuidIndex.get(doc._id);
const oldCust = uuidIndex.custom[id];
const oldDoc = oldCust || styleUtil.id2style(id);
const diff = oldDoc ? compareRevision(oldDoc._rev, doc._rev) : -1;
if (!diff) return;
if (diff > 0) {
syncMan.putDoc(oldDoc);
} else if (oldCust) {
uuidIndex.custom[id] = doc;
} else {
delete doc.id;
if (id) doc.id = id;
doc.id = await db.styles.put(doc);
await styleUtil.handleSave(doc, {reason: 'sync'});
}
},
onPut(doc) {
return API.styles.putByUUID(doc);
},
onDelete(id, rev) {
return API.styles.deleteByUUID(id, rev);
onDelete(_id, rev) {
const id = uuidIndex.get(_id);
const oldDoc = styleUtil.id2style(id);
return oldDoc &&
compareRevision(oldDoc._rev, rev) <= 0 &&
API.styles.delete(id, 'sync');
},
async onFirstSync() {
for (const i of await API.styles.getAll()) {
for (const i of Object.values(uuidIndex.custom).concat(await API.styles.getAll())) {
ctrl.put(i._id, i._rev);
}
},
@ -255,11 +274,21 @@ const syncMan = (() => {
if (name === 'dropbox' || name === 'google' || name === 'onedrive' || name === 'webdav') {
const options = await syncMan.getDriveOptions(name);
options.getAccessToken = () => tokenMan.getToken(name);
options.fetch = name === 'webdav' ? fetchWebDAV.bind(options) : fetch;
return dbToCloud.drive[name](options);
}
throw new Error(`unknown cloud name: ${name}`);
}
/** @this {Object} DriveOptions */
function fetchWebDAV(url, init = {}) {
init.credentials = 'omit'; // circumventing nextcloud CSRF token error
init.headers = Object.assign({}, init.headers, {
Authorization: `Basic ${btoa(`${this.username || ''}:${this.password || ''}`)}`,
});
return fetch(url, init);
}
function schedule(delay = SYNC_DELAY) {
chrome.alarms.create('syncNow', {
delayInMinutes: delay, // fractional values are supported

View File

@ -44,9 +44,6 @@ const tokenMan = (() => {
clientSecret: '9Pj=TpsrStq8K@1BiwB9PIWLppM:@s=w',
authURL: 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize',
tokenURL: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
redirect_uri: FIREFOX ?
'https://clngdbkpkpeebahjckkjfobafhncgmne.chromiumapp.org/' :
'https://' + location.hostname + '.chromiumapp.org/',
scopes: ['Files.ReadWrite.AppFolder', 'offline_access'],
},
userstylesworld: {
@ -60,8 +57,9 @@ const tokenMan = (() => {
},
};
const NETWORK_LATENCY = 30; // seconds
const DEFAULT_REDIRECT_URI = 'https://clngdbkpkpeebahjckkjfobafhncgmne.chromiumapp.org/';
let alwaysUseTab = FIREFOX ? false : null;
let alwaysUseTab = !chrome.windows || (FIREFOX ? false : null);
class TokenError extends Error {
constructor(provider, message) {
@ -146,14 +144,14 @@ const tokenMan = (() => {
}
async function authUser(keys, name, interactive = false, hooks = null) {
await require(['/vendor/webext-launch-web-auth-flow/webext-launch-web-auth-flow.min']);
await require(['/vendor/webext-launch-web-auth-flow/webext-launch-web-auth-flow']);
/* global webextLaunchWebAuthFlow */
const provider = AUTH[name];
const state = Math.random().toFixed(8).slice(2);
const query = {
response_type: provider.flow,
client_id: provider.clientId,
redirect_uri: provider.redirect_uri || chrome.identity.getRedirectURL(),
redirect_uri: provider.redirect_uri || DEFAULT_REDIRECT_URI,
state,
};
if (provider.scopes) {
@ -169,13 +167,13 @@ const tokenMan = (() => {
const url = `${provider.authURL}?${new URLSearchParams(query)}`;
const width = Math.min(screen.availWidth - 100, 800);
const height = Math.min(screen.availHeight - 100, 800);
const wnd = await browser.windows.getLastFocused();
const wnd = !alwaysUseTab && await browser.windows.getLastFocused();
const finalUrl = await webextLaunchWebAuthFlow({
url,
alwaysUseTab,
interactive,
redirect_uri: query.redirect_uri,
windowOptions: Object.assign({
windowOptions: wnd && Object.assign({
state: 'normal',
width,
height,
@ -250,7 +248,7 @@ const tokenMan = (() => {
// Workaround for https://github.com/openstyles/stylus/issues/1182
// Note that modern Vivaldi isn't exposed in `navigator.userAgent` but it adds `extData` to tabs
const anyTab = await getActiveTab() || (await browser.tabs.query({}))[0];
if (anyTab && !anyTab.extData) {
if (anyTab && !(anyTab.extData || anyTab.vivExtData)) {
return false;
}
let bugged = true;

View File

@ -1,6 +1,6 @@
/* global API */// msg.js
/* global RX_META URLS debounce download ignoreChromeError */// toolbox.js
/* global calcStyleDigest styleJSONseemsValid styleSectionsEqual */ // sections-util.js
/* global RX_META URLS debounce deepMerge download ignoreChromeError */// toolbox.js
/* global calcStyleDigest styleSectionsEqual */ // sections-util.js
/* global chromeLocal */// storage-util.js
/* global compareVersion */// cmpver.js
/* global db */
@ -23,6 +23,7 @@ const updateMan = (() => {
ERROR_JSON: 'error: JSON is invalid',
ERROR_VERSION: 'error: version is older than installed style',
};
const USO_STYLES_API = `${URLS.uso}api/v1/styles/`;
const RH_ETAG = {responseHeaders: ['etag']}; // a hashsum of file contents
const RX_DATE2VER = new RegExp([
/^(\d{4})/,
@ -37,6 +38,7 @@ const updateMan = (() => {
503, // service unavailable
429, // too many requests
];
let usoReferers = 0;
let lastUpdateTime;
let checkingAll = false;
let logQueue = [];
@ -63,7 +65,7 @@ const updateMan = (() => {
checkingAll = true;
const port = observe && chrome.runtime.connect({name: 'updater'});
const styles = (await API.styles.getAll())
.filter(style => style.updateUrl);
.filter(style => style.updateUrl && style.updatable !== false);
if (port) port.postMessage({count: styles.length});
log('');
log(`${save ? 'Scheduled' : 'Manual'} update check for ${styles.length} styles`);
@ -78,17 +80,17 @@ const updateMan = (() => {
/**
* @param {{
id?: number
style?: StyleObj
port?: chrome.runtime.Port
save?: boolean = true
ignoreDigest?: boolean
id?: number,
style?: StyleObj,
port?: chrome.runtime.Port,
save?: boolean,
ignoreDigest?: boolean,
}} opts
* @returns {{
style: StyleObj
updated?: boolean
error?: any
STATES: UpdaterStates
style: StyleObj,
updated?: boolean,
error?: any,
STATES: UpdaterStates,
}}
Original style digests are calculated in these cases:
@ -113,12 +115,13 @@ const updateMan = (() => {
save,
} = opts;
if (!id) id = style.id;
const ucd = style.usercssData;
const {md5Url} = style;
let {usercssData: ucd, updateUrl} = style;
let res, state;
try {
await checkIfEdited();
res = {
style: await (ucd ? updateUsercss : updateUSO)().then(maybeSave),
style: await (ucd && !md5Url ? updateUsercss : updateUSO)().then(maybeSave),
updated: true,
};
state = STATES.UPDATED;
@ -127,7 +130,7 @@ const updateMan = (() => {
err && err.message ||
err;
res = {error, style, STATES};
state = `${STATES.SKIPPED} (${error})`;
state = `${STATES.SKIPPED} (${Array.isArray(err) ? err[0].message : error})`;
}
log(`${state} #${id} ${style.customName || style.name}`);
if (port) port.postMessage(res);
@ -142,76 +145,45 @@ const updateMan = (() => {
}
async function updateUSO() {
const url = URLS.makeUsoArchiveCodeUrl(style.md5Url.match(/\d+/)[0]);
const req = await tryDownload(url, RH_ETAG).catch(() => null);
if (req) {
return updateToUSOArchive(url, req);
}
const md5 = await tryDownload(style.md5Url);
const md5 = await tryDownload(md5Url);
if (!md5 || md5.length !== 32) {
return Promise.reject(STATES.ERROR_MD5);
}
if (md5 === style.originalMd5 && style.originalDigest && !ignoreDigest) {
return Promise.reject(STATES.SAME_MD5);
}
const json = await tryDownload(style.updateUrl, {responseType: 'json'});
if (!styleJSONseemsValid(json)) {
return Promise.reject(STATES.ERROR_JSON);
let varsUrl = '';
if (!ucd) {
ucd = {};
varsUrl = updateUrl;
updateUrl = style.updateUrl = `${USO_STYLES_API}${md5Url.match(/\/(\d+)/)[1]}`;
}
usoSpooferStart();
let json;
try {
json = await tryDownload(style.updateUrl, {responseType: 'json'});
json = await updateUsercss(json.css) ||
(await API.uso.toUsercss(json)).style;
if (varsUrl) await API.uso.useVarsUrl(json, varsUrl);
} finally {
usoSpooferStop();
}
// USO may not provide a correctly updated originalMd5 (#555)
json.originalMd5 = md5;
return json;
}
async function updateToUSOArchive(url, req) {
const m2 = getUsoEmbeddedMeta(req.response);
if (m2) {
url = (await m2).updateUrl;
req = await tryDownload(url, RH_ETAG);
}
const json = await API.usercss.buildMeta({
id,
etag: req.headers.etag,
md5Url: null,
originalMd5: null,
sourceCode: req.response,
updateUrl: url,
url: URLS.extractUsoArchiveInstallUrl(url),
});
const varUrlValues = style.updateUrl.split('?')[1];
const varData = json.usercssData.vars;
if (varUrlValues && varData) {
const IK = 'ik-';
const IK_LEN = IK.length;
for (let [key, val] of new URLSearchParams(varUrlValues)) {
if (!key.startsWith(IK)) continue;
key = key.slice(IK_LEN);
const varDef = varData[key];
if (!varDef) continue;
if (varDef.options) {
let sel = val.startsWith(IK) && getVarOptByName(varDef, val.slice(IK_LEN));
if (!sel) {
key += '-custom';
sel = getVarOptByName(varDef, key + '-dropdown');
if (sel) varData[key].value = val;
}
if (sel) varDef.value = sel.name;
} else {
varDef.value = val;
}
}
}
return API.usercss.buildCode(json);
}
async function updateUsercss() {
async function updateUsercss(css) {
let oldVer = ucd.version;
let {etag: oldEtag, updateUrl} = style;
let m2 = URLS.extractUsoArchiveId(updateUrl) && getUsoEmbeddedMeta();
if (m2 && (m2 = await m2).updateUrl) {
const m2 = (css || URLS.extractUsoArchiveId(updateUrl)) &&
await getUsoEmbeddedMeta(css);
if (m2 && m2.updateUrl) {
updateUrl = m2.updateUrl;
oldVer = m2.usercssData.version || '0';
oldEtag = '';
} else if (css) {
return;
}
if (oldEtag && oldEtag === await downloadEtag()) {
return Promise.reject(STATES.SAME_CODE);
@ -234,7 +206,7 @@ const updateMan = (() => {
if (err && etag && !style.etag) {
// first check of ETAG, gonna write it directly to DB as it's too trivial to sync or announce
style.etag = etag;
await db.exec('put', style);
await db.styles.put(style);
}
return err
? Promise.reject(err)
@ -264,6 +236,7 @@ const updateMan = (() => {
let {retryDelay = 1000} = opts;
while (true) {
try {
params = deepMerge(params || {}, {headers: {'Cache-Control': 'no-cache'}});
return await download(url, params);
} catch (code) {
if (!RETRY_ERRORS.includes(code) ||
@ -283,8 +256,7 @@ const updateMan = (() => {
}
function getDateFromVer(style) {
const m = URLS.extractUsoArchiveId(style.updateUrl) &&
style.usercssData.version.match(RX_DATE2VER);
const m = RX_DATE2VER.exec((style.usercssData || {}).version);
if (m) {
m[2]--; // month is 0-based in `Date` constructor
return new Date(...m.slice(1)).getTime();
@ -293,13 +265,10 @@ const updateMan = (() => {
/** UserCSS metadata may be embedded in the original USO style so let's use its updateURL */
function getUsoEmbeddedMeta(code = style.sourceCode) {
const m = code.includes('@updateURL') && code.replace(RX_META, '').match(RX_META);
const isRaw = arguments[0];
const m = code.includes('@updateURL') && (isRaw ? code : code.replace(RX_META, '')).match(RX_META);
return m && API.usercss.buildMeta({sourceCode: m[0]}).catch(() => null);
}
function getVarOptByName(varDef, name) {
return varDef.options.find(o => o.name === name);
}
}
function schedule() {
@ -348,4 +317,32 @@ const updateMan = (() => {
logLastWriteTime = Date.now();
logQueue = [];
}
function usoSpooferStart() {
if (++usoReferers === 1) {
chrome.webRequest.onBeforeSendHeaders.addListener(
usoSpoofer,
{types: ['xmlhttprequest'], urls: [USO_STYLES_API + '*']},
['blocking', 'requestHeaders', chrome.webRequest.OnBeforeSendHeadersOptions.EXTRA_HEADERS]
.filter(Boolean));
}
}
function usoSpooferStop() {
if (--usoReferers <= 0) {
usoReferers = 0;
chrome.webRequest.onBeforeSendHeaders.removeListener(usoSpoofer);
}
}
/** @param {chrome.webRequest.WebResponseHeadersDetails | browser.webRequest._OnBeforeSendHeadersDetails} info */
function usoSpoofer(info) {
if (info.tabId < 0 && URLS.ownOrigin.startsWith(info.initiator || info.originUrl || '')) {
const {requestHeaders: hh} = info;
const i = (hh.findIndex(h => /^referer$/i.test(h.name)) + 1 || hh.push({})) - 1;
hh[i].name = 'referer';
hh[i].value = URLS.uso;
return {requestHeaders: hh};
}
}
})();

View File

@ -74,6 +74,10 @@ bgReady.all.then(() => {
) && download(url);
}
function makeInstallerUrl(url) {
return `${URLS.installUsercss}?updateUrl=${encodeURIComponent(url)}`;
}
function makeUsercssGlobs(host, path) {
return '%css,%css?*,%styl,%styl?*'.replace(/%/g, `*://${host}${path}.user.`).split(',');
}
@ -82,11 +86,11 @@ bgReady.all.then(() => {
if (url.includes('.user.') &&
/^(https?|file|ftps?):/.test(url) &&
/\.user\.(css|styl)$/.test(url.split(/[#?]/, 1)[0]) &&
!oldUrl.startsWith(URLS.installUsercss)) {
!oldUrl.startsWith(makeInstallerUrl(url))) {
const inTab = url.startsWith('file:') && !chrome.app;
const code = await (inTab ? loadFromFile : loadFromUrl)(tabId, url);
if (!/^\s*</.test(code) && RX_META.test(code)) {
openInstallerPage(tabId, url, {code, inTab});
await openInstallerPage(tabId, url, {code, inTab});
}
}
}
@ -99,25 +103,33 @@ bgReady.all.then(() => {
openInstallerPage(tabId, url, {});
// Silently suppress navigation.
// Don't redirect to the install URL as it'll flash the text!
return {redirectUrl: 'javascript:void 0'}; // eslint-disable-line no-script-url
return {cancel: true};
}
}
function openInstallerPage(tabId, url, {code, inTab} = {}) {
const newUrl = `${URLS.installUsercss}?updateUrl=${encodeURIComponent(url)}`;
async function openInstallerPage(tabId, url, {code, inTab} = {}) {
const newUrl = makeInstallerUrl(url);
if (inTab) {
browser.tabs.get(tabId).then(tab =>
openURL({
url: `${newUrl}&tabId=${tabId}`,
active: tab.active,
index: tab.index + 1,
openerTabId: tabId,
currentWindow: null,
}));
} else {
const timer = setTimeout(clearInstallCode, 10e3, url);
installCodeCache[url] = {code, timer};
chrome.tabs.update(tabId, {url: newUrl});
const tab = await browser.tabs.get(tabId);
return openURL({
url: `${newUrl}&tabId=${tabId}`,
active: tab.active,
index: tab.index + 1,
openerTabId: tabId,
currentWindow: null,
});
}
const timer = setTimeout(clearInstallCode, 10e3, url);
installCodeCache[url] = {code, timer};
try {
await browser.tabs.update(tabId, {url: newUrl});
} catch (err) {
// FIXME: remove this when kiwi supports tabs.update
// https://github.com/openstyles/stylus/issues/1367
if (/Tabs cannot be edited right now/i.test(err.message)) {
return browser.tabs.create({url: newUrl});
}
throw err;
}
}

View File

@ -12,10 +12,12 @@ const usercssMan = {
name: null,
}),
async assignVars(style, oldStyle) {
/** `src` is a style or vars */
async assignVars(style, src) {
const meta = style.usercssData;
const vars = meta.vars;
const oldVars = (oldStyle.usercssData || {}).vars;
const meta2 = src.usercssData;
const {vars} = meta;
const oldVars = meta2 ? meta2.vars : src;
if (vars && oldVars) {
// The type of var might be changed during the update. Set value to null if the value is invalid.
for (const [key, v] of Object.entries(vars)) {
@ -43,7 +45,7 @@ const usercssMan = {
let log;
if (!metaOnly) {
if (vars || assignVars) {
await usercssMan.assignVars(style, vars ? {usercssData: {vars}} : dup);
await usercssMan.assignVars(style, vars || dup);
}
await usercssMan.buildCode(style);
log = style.log; // extracting the non-enumerable prop, otherwise it won't survive messaging
@ -137,17 +139,18 @@ const usercssMan = {
}
},
async install(style) {
return API.styles.install(await usercssMan.parse(style));
async install(style, opts) {
return API.styles.install(await usercssMan.parse(style, opts));
},
async parse(style) {
async parse(style, {dup, vars} = {}) {
style = await usercssMan.buildMeta(style);
// preserve style.vars during update
const dup = await usercssMan.find(style);
if (dup) {
if (dup || (dup = await usercssMan.find(style))) {
style.id = dup.id;
await usercssMan.assignVars(style, dup);
}
if (vars || (vars = dup)) {
await usercssMan.assignVars(style, vars);
}
return usercssMan.buildCode(style);
},

158
background/uso-api.js Normal file
View File

@ -0,0 +1,158 @@
/* global URLS stringAsRegExp */// toolbox.js
/* global usercssMan */
'use strict';
const usoApi = {};
(() => {
const pingers = {};
usoApi.pingback = (usoId, delay) => {
clearTimeout(pingers[usoId]);
delete pingers[usoId];
if (delay > 0) {
return new Promise(resolve => (pingers[usoId] = setTimeout(ping, delay, usoId, resolve)));
} else if (delay !== false) {
return ping(usoId);
}
};
/**
* Replicating USO-Archive format
* https://github.com/33kk/uso-archive/blob/flomaster/lib/uso.js
* https://github.com/33kk/uso-archive/blob/flomaster/lib/converters.js
*/
usoApi.toUsercss = async (data, {metaOnly = true, varsUrl} = {}) => {
const badKeys = {};
const newKeys = [];
const descr = JSON.stringify(data.description.trim());
const vars = (data.style_settings || []).map(makeVar, {badKeys, newKeys}).join('');
const sourceCode = `\
/* ==UserStyle==
@name ${data.name}
@namespace USO Archive
@version ${data.updated.replace(/-/g, '').replace(/[T:]/g, '.').slice(0, 14)}
@description ${/^"['`]|\\/.test(descr) ? descr : descr.slice(1, -1)}
@author ${(data.user || {}).name || '?'}
@license ${makeLicense(data.license)}${vars ? '\n@preprocessor uso' + vars : ''}`
.replace(/\*\//g, '*\\/') +
`==/UserStyle== */\n${newKeys[0] ? useNewKeys(data.css, badKeys) : data.css}`;
const {style} = await usercssMan.build({sourceCode, metaOnly});
usoApi.useVarsUrl(style, varsUrl);
return {style, badKeys, newKeys};
};
usoApi.useVarsUrl = (style, url) => {
if (!/\?ik-/.test(url)) {
return;
}
const cfg = {badKeys: {}, newKeys: []};
const {vars} = style.usercssData;
if (!vars) {
return;
}
for (let [key, val] of new URLSearchParams(url.split('?')[1])) {
if (!key.startsWith('ik-')) continue;
key = makeKey(key.slice(3), cfg);
const v = vars[key];
if (!v) continue;
if (v.options) {
let sel = val.startsWith('ik-') && optByName(v, makeKey(val.slice(3), cfg));
if (!sel) {
key += '-custom';
sel = optByName(v, key + '-dropdown');
if (sel) vars[key].value = val;
}
if (sel) v.value = sel.name;
} else {
v.value = val;
}
}
return true;
};
async function ping(id, resolve) {
await fetch(`${URLS.uso}styles/install/${id}?source=stylish-ch`);
if (resolve) resolve(true);
return true;
}
function makeKey(key, {badKeys, newKeys}) {
let res = badKeys[key];
if (!res) {
res = key.replace(/[^-\w]/g, '-');
res += newKeys.includes(res) ? '-' : '';
if (key !== res) {
badKeys[key] = res;
newKeys.push(res);
}
}
return res;
}
function makeLicense(s) {
return !s ? 'NO-REDISTRIBUTION' :
s === 'publicdomain' ? 'CC0-1.0' :
s.startsWith('ccby') ? `${s.toUpperCase().match(/(..)/g).join('-')}-4.0` :
s;
}
function makeVar({
label,
setting_type: type,
install_key: ik,
style_setting_options: opts,
}) {
const cfg = this;
let value, suffix;
ik = makeKey(ik, cfg);
label = JSON.stringify(label);
switch (type) {
case 'color':
value = opts[0].value;
break;
case 'text':
value = JSON.stringify(opts[0].value);
break;
case 'image': {
const ikCust = `${ik}-custom`;
opts.push({
label: 'Custom',
install_key: `${ikCust}-dropdown`,
value: `/*[[${ikCust}]]*/`,
});
suffix = `\n@advanced text ${ikCust} ${label.slice(0, -1)} (Custom)" "https://foo.com/123.jpg"`;
type = 'dropdown';
} // fallthrough
case 'dropdown':
value = '';
for (const o of opts) {
const def = o.default ? '*' : '';
const val = o.value;
const s = ` ${makeKey(o.install_key, cfg)} ${JSON.stringify(o.label + def)} <<<EOT${
val.includes('\n') ? '\n' : ' '}${val} EOT;\n`;
value = def ? s + value : value + s;
}
value = `{\n${value}}`;
break;
default:
value = '"ERROR: unknown type"';
}
return `\n@advanced ${type} ${ik} ${label} ${value}${suffix || ''}`;
}
function optByName(v, name) {
return v.options.find(o => o.name === name);
}
function useNewKeys(css, badKeys) {
const rxsKeys = stringAsRegExp(Object.keys(badKeys).join('\n'), '', true).replace(/\n/g, '|');
const rxUsoVars = new RegExp(`(/\\*\\[\\[)(${rxsKeys})(?=]]\\*/)`, 'g');
return css.replace(rxUsoVars, (s, a, key) => a + badKeys[key]);
}
})();

View File

@ -35,7 +35,7 @@ const uswApi = (() => {
const maxKeyLen = meta.reduce((res, [k]) => Math.max(res, k.length), 0);
return [
'/* ==UserStyle==',
...meta.map(([k, v]) => `${k}${' '.repeat(maxKeyLen - k.length + 2)}${v || ''}`),
...meta.map(([k, v]) => v && `${k}${' '.repeat(maxKeyLen - k.length + 2)}${v}`).filter(Boolean),
'==/UserStyle== */',
].join('\n') + '\n\n';
}
@ -77,14 +77,15 @@ const uswApi = (() => {
*/
async publish(id, sourceCode) {
const style = await API.styles.get(id);
const code = style.usercssData ? sourceCode
: fakeUsercssHeader(style) + sourceCode;
const data = (style._usw || {}).token
? style._usw
: await linkStyle(style, sourceCode);
const header = style.usercssData ? '' : fakeUsercssHeader(style);
: await linkStyle(style, code);
return uswFetch(`style/${data.id}`, data.token, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({code: header + sourceCode}),
body: JSON.stringify({code}),
});
},

View File

@ -5,6 +5,7 @@
(() => {
if (window.INJECTED === 1) return;
window.INJECTED = 1;
/** true -> when the page styles are received,
* false -> when disableAll mode is on at start, the styles won't be sent
@ -13,11 +14,16 @@
let hasStyles = false;
let isDisabled = false;
let isTab = !chrome.tabs || location.pathname !== '/popup.html';
const order = {main: [], prio: []};
const calcOrder = ({id}) =>
(order.prio[id] || 0) * 1e6 ||
order.main[id] ||
id + .5e6; // no order = at the end of `main`
const isFrame = window !== parent;
const isFrameAboutBlank = isFrame && location.href === 'about:blank';
const isUnstylable = !chrome.app && document instanceof XMLDocument;
const styleInjector = StyleInjector({
compare: (a, b) => a.id - b.id,
compare: (a, b) => calcOrder(a) - calcOrder(b),
onUpdate: onInjectorUpdate,
});
// dynamic iframes don't have a URL yet so we'll use their parent's URL (hash isn't inherited)
@ -38,20 +44,23 @@
/* about:blank iframes are often used by sites for file upload or background tasks
* and they may break if unexpected DOM stuff is present at `load` event
* so we'll add the styles only if the iframe becomes visible */
const {IntersectionObserver} = window;
const xoEventId = `${Math.random()}`;
/** @type IntersectionObserver */
let xo;
if (IntersectionObserver) {
window[Symbol.for('xo')] = (el, cb) => {
if (!xo) xo = new IntersectionObserver(onIntersect, {rootMargin: '100%'});
el.addEventListener(xoEventId, cb, {once: true});
xo.observe(el);
};
}
window[Symbol.for('xo')] = (el, cb) => {
if (!xo) xo = new IntersectionObserver(onIntersect, {rootMargin: '100%'});
el.addEventListener(xoEventId, cb, {once: true});
xo.observe(el);
};
// FIXME: move this to background page when following bugs are fixed:
// https://bugzil.la/1587723, https://crbug.com/968651
const mqDark = matchMedia('(prefers-color-scheme: dark)');
mqDark.onchange = e => API.colorScheme.updateSystemPreferDark(e.matches);
mqDark.onchange(mqDark);
// Declare all vars before init() or it'll throw due to "temporal dead zone" of const/let
const ready = init();
init();
// the popup needs a check as it's not a tab but can be opened in a tab manually for whatever reason
if (!isTab) {
@ -62,19 +71,17 @@
}
msg.onTab(applyOnMessage);
window.addEventListener('pageshow', e => {
if (e.isTrusted && e.persisted) { // bfcache
updateCount();
}
});
if (!chrome.tabs) {
window.dispatchEvent(new CustomEvent(orphanEventId));
window.addEventListener(orphanEventId, orphanCheck, true);
}
// detect media change in content script
// FIXME: move this to background page when following bugs are fixed:
// https://bugzilla.mozilla.org/show_bug.cgi?id=1561546
// https://bugs.chromium.org/p/chromium/issues/detail?id=968651
const media = window.matchMedia('(prefers-color-scheme: dark)');
media.addListener(() => API.colorScheme.updateSystemPreferDark().catch(console.error));
function onInjectorUpdate() {
if (!isOrphaned) {
updateCount();
@ -100,7 +107,10 @@
parentStyles && await new Promise(onFrameElementInView) && parentStyles ||
!isFrameAboutBlank && chrome.app && !chrome.tabs && tryCatch(getStylesViaXhr) ||
await API.styles.getSectionsByUrl(matchUrl, null, true);
isDisabled = styles.disableAll;
if (styles.cfg) {
isDisabled = styles.cfg.disableAll;
Object.assign(order, styles.cfg.order);
}
hasStyles = !isDisabled;
if (hasStyles) {
window[SYM] = styles;
@ -166,6 +176,11 @@
}
break;
case 'styleSort':
Object.assign(order, request.order);
styleInjector.sort();
break;
case 'urlChanged':
if (!hasStyles && isDisabled || matchUrl === request.url) break;
matchUrl = request.url;
@ -175,13 +190,6 @@
});
break;
case 'backgroundReady':
ready.catch(err =>
msg.isIgnorableError(err)
? init()
: console.error(err));
break;
case 'updateCount':
updateCount();
break;
@ -231,11 +239,7 @@
}
function onFrameElementInView(cb) {
if (IntersectionObserver) {
parent[parent.Symbol.for('xo')](frameElement, cb);
} else {
requestAnimationFrame(cb);
}
parent[parent.Symbol.for('xo')](frameElement, cb);
}
/** @param {IntersectionObserverEntry[]} entries */
@ -255,10 +259,11 @@
}
function orphanCheck() {
if (tryCatch(() => chrome.i18n.getUILanguage())) return;
if (chrome.runtime.id) return;
// In Chrome content script is orphaned on an extension update/reload
// so we need to detach event listeners
window.removeEventListener(orphanEventId, orphanCheck, true);
mqDark.onchange = null;
isOrphaned = true;
setTimeout(styleInjector.clear, 1000); // avoiding FOUC
tryCatch(msg.off, applyOnMessage);

View File

@ -0,0 +1,324 @@
/* global API */// msg.js
'use strict';
// eslint-disable-next-line no-unused-expressions
/^\/styles\/(\d+)(\/([^/]*))?([?#].*)?$/.test(location.pathname) && (async () => {
if (window.INJECTED_USO === 1) return;
window.INJECTED_USO = 1;
const usoId = RegExp.$1;
const USO = 'https://userstyles.org';
const apiUrl = `${USO}/api/v1/styles/${usoId}`;
const md5Url = `https://update.userstyles.org/${usoId}.md5`;
const CLICK = [
['#install_stylish_style_button', onInstall],
['#update_stylish_style_button', onInstall],
['.customize_style_button', onCustomize],
['.uninstall_stylish_style_button', onUninstall],
];
const pageEventId = `${performance.now()}${Math.random()}`;
const contentEventId = pageEventId + ':';
const orphanEventId = chrome.runtime.id; // id won't be available in the orphaned script
const $ = (sel, base = document) => base.querySelector(sel);
const toggleListener = (isOn, ...args) => (isOn ? addEventListener : removeEventListener)(...args);
const togglePageListener = isOn => toggleListener(isOn, contentEventId, onPageEvent, true);
const mo = new MutationObserver(onMutation);
const observeColors = isOn =>
isOn ? mo.observe(document.body, {subtree: true, attributes: true, attributeFilter: ['value']})
: mo.disconnect();
let style, dup, md5, pageData, badKeys;
runInPage(inPageContext, pageEventId, contentEventId, usoId, apiUrl);
addEventListener(orphanEventId, orphanCheck, true);
addEventListener('click', onClick, true);
togglePageListener(true);
[md5, dup] = await Promise.all([
fetch(md5Url).then(r => r.text()),
API.styles.find({md5Url}, {installationUrl: `https://uso.kkx.one/style/${usoId}`})
.then(sendVarsToPage),
document.body || new Promise(resolve => addEventListener('load', resolve, {once: true})),
]);
if (!dup) {
sendStylishEvent('styleCanBeInstalledChrome');
} else if (dup.originalMd5 && dup.originalMd5 !== md5 || !dup.usercssData || !dup.md5Url) {
// allow update if 1) changed, 2) is a classic USO style, 3) is from USO-archive
sendStylishEvent('styleCanBeUpdatedChrome');
} else {
sendStylishEvent('styleAlreadyInstalledChrome');
}
async function onClick(e) {
for (const [sel, fn] of CLICK) {
const el = e.target.closest(sel);
if (!el) continue;
try {
el.disabled = true;
await fn(e);
} catch (e) {
alert(chrome.i18n.getMessage('styleInstallFailed', e.message || e));
} finally {
el.disabled = false;
}
}
}
function onCustomize() {
const ss = $('#style-settings');
const willShow = !ss || !ss.offsetHeight;
observeColors(willShow);
toggleListener(willShow, 'change', onChange);
}
async function onInstall(e) {
const {id} = dup;
e.stopPropagation();
if (!style) await buildStyle();
style = dup = await API.usercss.install(style, {
dup: {id},
vars: getPageVars(),
});
sendStylishEvent('styleInstalledChrome');
API.uso.pingback(id);
}
function onUninstall() {
const {id} = dup;
dup = style = false;
observeColors(false);
removeEventListener('change', onChange);
return API.styles.delete(id);
}
function onChange({target: el}) {
if (dup && el.matches('[name^="ik-"], [type=file]')) {
API.usercss.configVars(dup.id, getPageVars());
}
}
function onMutation(mutations) {
for (const {target: el} of mutations) {
if (el.style.display === 'none' &&
/^ik-/.test(el.name) &&
/^#[\da-f]{6}$/.test(el.value)) {
onChange({target: el});
}
}
}
function onPageEvent(e) {
pageData = e.detail;
togglePageListener(false);
}
async function buildStyle() {
if (!pageData) pageData = await (await fetch(apiUrl)).json();
({style, badKeys} = await API.uso.toUsercss(pageData, {varsUrl: dup.updateUrl}));
Object.assign(style, {
md5Url,
id: dup.id,
originalMd5: md5,
updateUrl: apiUrl,
});
}
function getPageVars() {
const {vars} = (style || dup).usercssData;
for (const el of document.querySelectorAll('[name^="ik-"]')) {
const name = el.name.slice(3); // dropping "ik-"
const ik = (badKeys || {})[name] || name;
const v = vars[ik] || false;
const isImage = el.type === 'radio';
if (v && (!isImage || el.checked)) {
const val = el.value;
const isFile = val === 'user-upload';
if (isImage && (isFile || val === 'user-url')) {
const el2 = $(`[type=${isFile ? 'file' : 'url'}]`, el.parentElement);
const ikCust = `${ik}-custom`;
v.value = `${ikCust}-dropdown`;
vars[ikCust].value = isFile ? getFileUriFromPage(el2) : el2.value;
} else {
v.value = v.type === 'select' ? val.replace(/^ik-/, '') : val;
}
}
}
return vars;
}
function getFileUriFromPage(el) {
togglePageListener(true);
sendPageEvent(el);
return pageData;
}
function runInPage(fn, ...args) {
const div = document.createElement('div');
div.attachShadow({mode: 'closed'})
.appendChild(document.createElement('script'))
.textContent = `(${fn})(${JSON.stringify(args).slice(1, -1)})`;
document.documentElement.appendChild(div).remove();
}
function sendPageEvent(data) {
dispatchEvent(data instanceof Node
? new MouseEvent(pageEventId, {relatedTarget: data})
: new CustomEvent(pageEventId, {detail: data}));
//* global cloneInto */// WARNING! Firefox requires cloning of an object `detail`
}
function sendStylishEvent(type) {
document.dispatchEvent(new Event(type));
}
function sendVarsToPage(style) {
if (style) {
const vars = (style.usercssData || {}).vars || `${style.updateUrl}`.split('?')[1];
if (vars) sendPageEvent('vars:' + JSON.stringify(vars));
}
return style || false;
}
function orphanCheck() {
if (chrome.runtime.id) return true;
removeEventListener(orphanEventId, orphanCheck, true);
removeEventListener('click', onClick, true);
removeEventListener('change', onChange);
sendPageEvent('quit');
observeColors(false);
togglePageListener(false);
}
})();
function inPageContext(eventId, eventIdHost, styleId, apiUrl) {
let done, orphaned, vars;
// `chrome` may be empty if no extensions use externally_connectable but USO needs it
if (!window.chrome) window.chrome = {runtime: {sendMessage: () => {}}};
const EXT_ID = 'fjnbnpbmkenffdnngjfgmeleoegfcffe';
const {defineProperty} = Object;
const {dispatchEvent, CustomEvent, removeEventListener} = window;
const apply = Map.call.bind(Map.apply);
const OVR = [
[chrome.runtime, 'sendMessage', (fn, me, args) => {
const [id, /*msg*/, opts, cb = opts] = args;
if (id !== EXT_ID) return apply(fn, me, args);
if (typeof cb !== 'function') return Promise.resolve(true);
cb(true);
}],
[Response.prototype, 'json', async (fn, me, args) => {
const res = await apply(fn, me, args);
try {
if (!done && me.url === apiUrl) {
done = true;
send(res);
setVars(res);
}
} catch (e) {}
return res;
}],
[window, 'fetch', (fn, me, args) =>
args[0] === `chrome-extension://${EXT_ID}/index.html`
? Promise.resolve(new Response('<!doctype html><html lang="en"></html>'))
: apply(fn, me, args),
],
];
OVR.forEach(([obj, name, caller], i) => {
const orig = obj[name];
const ovr = new Proxy(orig, {
apply(fn, me, args) {
if (orphaned) restore(obj, name, ovr, fn);
return (orphaned ? apply : caller)(fn, me, args);
},
});
defineProperty(obj, name, {value: ovr});
OVR[i] = [obj, name, ovr, orig]; // same args as restore()
});
/* We set `isInstalled` at page start intentionally not trying to replicate Stylish login events.
* This difference allows USO site to detect presence of Stylus (or another similar extension). */
window.isInstalled = true;
addEventListener(eventId, onCommand, true);
function onCommand(e) {
if (e.detail === 'quit') {
removeEventListener(eventId, onCommand, true);
OVR.forEach(restore);
done = orphaned = true;
} else if (/^vars:/.test(e.detail)) {
vars = JSON.parse(e.detail.slice(5));
} else if (e.relatedTarget) {
send(e.relatedTarget.uploadedData);
}
}
function restore(obj, name, ovr, orig) { // same order as OVR after patching
if (obj[name] === ovr) {
defineProperty(obj, name, {value: orig});
}
}
function send(data) {
dispatchEvent(new CustomEvent(eventIdHost, {__proto: null, detail: data}));
}
function setVars(json) {
const images = new Map();
const isNew = typeof vars === 'object';
const badKeys = {};
const newKeys = [];
const makeKey = ({install_key: key}) => {
let res = isNew ? badKeys[key] : key;
if (!res) {
res = key.replace(/[^-\w]/g, '-');
res += newKeys.includes(res) ? '-' : '';
if (key !== res) {
badKeys[key] = res;
newKeys.push(res);
}
}
return res;
};
if (!isNew) vars = new URLSearchParams(vars);
for (const ss of json.style_settings || []) {
const ik = makeKey(ss);
let value = isNew ? (vars[ik] || {}).value : vars.get('ik-' + ik);
if (value == null || !(ss.style_setting_options || [])[0]) {
continue;
}
if (ss.setting_type === 'image') {
let isListed;
for (const opt of ss.style_setting_options) {
isListed |= opt.default = (opt.install_key === value);
}
images.set(ik, {url: isNew && !isListed ? vars[`${ik}-custom`].value : value, isListed});
} else if (value.startsWith('ik-') || isNew && vars[ik].type === 'select') {
value = value.replace(/^ik-/, '');
const def = ss.style_setting_options.find(item => item.default);
if (!def || makeKey(def) !== value) {
if (def) def.default = false;
for (const item of ss.style_setting_options) {
if (makeKey(item) === value) {
item.default = true;
break;
}
}
}
} else {
const item = ss.style_setting_options[0];
if (item.value !== value && item.install_key === 'placeholder') {
item.value = value;
}
}
}
if (!images.size) return;
new MutationObserver((_, observer) => {
if (!document.getElementById('style-settings')) return;
observer.disconnect();
for (const [name, {url, isListed}] of images) {
const elRadio = document.querySelector(`input[name="ik-${name}"][value="user-url"]`);
const elUrl = elRadio && document.getElementById(elRadio.id.replace('url-choice', 'user-url'));
if (elUrl) {
elRadio.checked = !isListed;
elUrl.value = url;
}
}
}).observe(document, {childList: true, subtree: true});
}
}

View File

@ -9,12 +9,14 @@ window.StyleInjector = window.INJECTED === 1 ? window.StyleInjector : ({
const PATCH_ID = 'transition-patch';
// styles are out of order if any of these elements is injected between them
const ORDERED_TAGS = new Set(['head', 'body', 'frameset', 'style', 'link']);
const docRewriteObserver = RewriteObserver(_sort);
const docRootObserver = RootObserver(_sortIfNeeded);
const docRewriteObserver = RewriteObserver(sort);
const docRootObserver = RootObserver(sortIfNeeded);
const toSafeChar = c => String.fromCharCode(0xFF00 + c.charCodeAt(0) - 0x20);
const list = [];
const table = new Map();
let isEnabled = true;
let isTransitionPatched;
let isTransitionPatched = chrome.app && CSS.supports('accent-color', 'red'); // Chrome 93
let exposeStyleName;
// will store the original method refs because the page can override them
let creationDoc, createElement, createElementNS;
@ -23,24 +25,24 @@ window.StyleInjector = window.INJECTED === 1 ? window.StyleInjector : ({
list,
async apply(styleMap) {
const styles = _styleMapToArray(styleMap);
const styles = styleMapToArray(styleMap);
const value = !styles.length
? []
: await docRootObserver.evade(() => {
if (!isTransitionPatched && isEnabled) {
_applyTransitionPatch(styles);
applyTransitionPatch(styles);
}
return styles.map(_addUpdate);
return styles.map(addUpdate);
});
_emitUpdate();
emitUpdate();
return value;
},
clear() {
_addRemoveElements(false);
addRemoveElements(false);
list.length = 0;
table.clear();
_emitUpdate();
emitUpdate();
},
clearOrphans() {
@ -53,12 +55,12 @@ window.StyleInjector = window.INJECTED === 1 ? window.StyleInjector : ({
},
remove(id) {
_remove(id);
_emitUpdate();
remove(id);
emitUpdate();
},
replace(styleMap) {
const styles = _styleMapToArray(styleMap);
const styles = styleMapToArray(styleMap);
const added = new Set(styles.map(s => s.id));
const removed = [];
for (const style of list) {
@ -66,22 +68,24 @@ window.StyleInjector = window.INJECTED === 1 ? window.StyleInjector : ({
removed.push(style.id);
}
}
styles.forEach(_addUpdate);
removed.forEach(_remove);
_emitUpdate();
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);
if (!enable) toggleObservers(false);
addRemoveElements(enable);
if (enable) toggleObservers(true);
},
sort: sort,
};
function _add(style) {
const el = style.el = _createStyle(style.id, style.code);
function add(style) {
const el = style.el = createStyle(style);
const i = list.findIndex(item => compare(item, style) > 0);
table.set(style.id, style);
if (isEnabled) {
@ -91,7 +95,7 @@ window.StyleInjector = window.INJECTED === 1 ? window.StyleInjector : ({
return el;
}
function _addRemoveElements(add) {
function addRemoveElements(add) {
for (const {el} of list) {
if (add) {
document.documentElement.appendChild(el);
@ -101,11 +105,11 @@ window.StyleInjector = window.INJECTED === 1 ? window.StyleInjector : ({
}
}
function _addUpdate(style) {
return table.has(style.id) ? _update(style) : _add(style);
function addUpdate(style) {
return table.has(style.id) ? update(style) : add(style);
}
function _applyTransitionPatch(styles) {
function applyTransitionPatch(styles) {
isTransitionPatched = true;
// CSS transition bug workaround: since we insert styles asynchronously,
// the browsers, especially Firefox, may apply all transitions on page load
@ -114,19 +118,20 @@ window.StyleInjector = window.INJECTED === 1 ? window.StyleInjector : ({
!styles.some(s => s.code.includes('transition'))) {
return;
}
const el = _createStyle(PATCH_ID, `
const el = createStyle({id: PATCH_ID, code: `
:root:not(#\\0):not(#\\0) * {
transition: none !important;
}
`);
`});
document.documentElement.appendChild(el);
// wait for the next paint to complete
// note: requestAnimationFrame won't fire in inactive tabs
requestAnimationFrame(() => setTimeout(() => el.remove()));
}
function _createStyle(id, code = '') {
if (!creationDoc) _initCreationDoc();
function createStyle(style = {}) {
const {id} = style;
if (!creationDoc) initCreationDoc();
let el;
if (document.documentElement instanceof SVGSVGElement) {
// SVG document style
@ -146,18 +151,27 @@ window.StyleInjector = window.INJECTED === 1 ? window.StyleInjector : ({
el.type = 'text/css';
// SVG className is not a string, but an instance of SVGAnimatedString
el.classList.add('stylus');
el.textContent = code;
setTextAndName(el, style);
return el;
}
function _toggleObservers(shouldStart) {
function setTextAndName(el, {id, code = '', name}) {
if (exposeStyleName && name) {
el.dataset.name = name;
name = encodeURIComponent(name.replace(/[?#/']/g, toSafeChar));
code += `\n/*# sourceURL=${chrome.runtime.getURL(name)}.user.css#${id} */`;
}
el.textContent = code;
}
function toggleObservers(shouldStart) {
const onOff = shouldStart && isEnabled ? 'start' : 'stop';
docRewriteObserver[onOff]();
docRootObserver[onOff]();
}
function _emitUpdate() {
_toggleObservers(list.length);
function emitUpdate() {
toggleObservers(list.length);
onUpdate();
}
@ -168,11 +182,11 @@ window.StyleInjector = window.INJECTED === 1 ? window.StyleInjector : ({
and since userAgent.navigator can be spoofed via about:config or devtools,
we're checking for getPreventDefault that was removed in FF59
*/
function _initCreationDoc() {
function initCreationDoc() {
creationDoc = !Event.prototype.getPreventDefault && document.wrappedJSObject;
if (creationDoc) {
({createElement, createElementNS} = creationDoc);
const el = document.documentElement.appendChild(_createStyle());
const el = document.documentElement.appendChild(createStyle());
const isApplied = el.sheet;
el.remove();
if (isApplied) return;
@ -181,7 +195,7 @@ window.StyleInjector = window.INJECTED === 1 ? window.StyleInjector : ({
({createElement, createElementNS} = document);
}
function _remove(id) {
function remove(id) {
const style = table.get(id);
if (!style) return;
table.delete(id);
@ -189,14 +203,14 @@ window.StyleInjector = window.INJECTED === 1 ? window.StyleInjector : ({
style.el.remove();
}
function _sort() {
function sort() {
docRootObserver.evade(() => {
list.sort(compare);
_addRemoveElements(true);
addRemoveElements(true);
});
}
function _sortIfNeeded() {
function sortIfNeeded() {
let needsSort;
let el = list.length && list[0].el;
if (!el) {
@ -217,22 +231,29 @@ window.StyleInjector = window.INJECTED === 1 ? window.StyleInjector : ({
// some styles are not injected to the document
if (i < list.length) needsSort = true;
}
if (needsSort) _sort();
if (needsSort) sort();
return needsSort;
}
function _styleMapToArray(styleMap) {
return Object.values(styleMap).map(s => ({
id: s.id,
code: s.code.join(''),
function styleMapToArray(styleMap) {
if (styleMap.cfg) {
({exposeStyleName} = styleMap.cfg);
delete styleMap.cfg;
}
return Object.values(styleMap).map(({id, code, name}) => ({
id,
name,
code: code.join(''),
}));
}
function _update({id, code}) {
function update(newStyle) {
const {id, code} = newStyle;
const style = table.get(id);
if (style.code !== code) {
if (style.code !== code ||
style.name !== newStyle.name && exposeStyleName) {
style.code = code;
style.el.textContent = code;
setTextAndName(style.el, newStyle);
}
}
@ -241,14 +262,14 @@ window.StyleInjector = window.INJECTED === 1 ? window.StyleInjector : ({
let root;
let observing = false;
let timer;
const observer = new MutationObserver(_check);
const observer = new MutationObserver(check);
return {start, stop};
function start() {
if (observing) return;
// detect dynamic iframes rewritten after creation by the embedder i.e. externally
root = document.documentElement;
timer = setTimeout(_check);
timer = setTimeout(check);
observer.observe(document, {childList: true});
observing = true;
}
@ -260,7 +281,7 @@ window.StyleInjector = window.INJECTED === 1 ? window.StyleInjector : ({
observing = false;
}
function _check() {
function check() {
if (root !== document.documentElement) {
root = document.documentElement;
onChange();
@ -290,7 +311,7 @@ window.StyleInjector = window.INJECTED === 1 ? window.StyleInjector : ({
function evade(fn) {
const restore = observing && start;
stop();
return new Promise(resolve => _run(fn, resolve, _waitForRoot))
return new Promise(resolve => run(fn, resolve, waitForRoot))
.then(restore);
}
@ -308,7 +329,7 @@ window.StyleInjector = window.INJECTED === 1 ? window.StyleInjector : ({
observing = false;
}
function _run(fn, resolve, wait) {
function run(fn, resolve, wait) {
if (document.documentElement) {
resolve(fn());
return true;
@ -316,8 +337,8 @@ window.StyleInjector = window.INJECTED === 1 ? window.StyleInjector : ({
if (wait) wait(fn, resolve);
}
function _waitForRoot(...args) {
new MutationObserver((_, observer) => _run(...args) && observer.disconnect())
function waitForRoot(...args) {
new MutationObserver((_, observer) => run(...args) && observer.disconnect())
.observe(document, {childList: true});
}
}

View File

@ -1,100 +0,0 @@
/* global prefs */
/* exported colorScheme */
'use strict';
const colorScheme = (() => {
let systemPreferDark = false;
let timePreferDark = false;
const changeListeners = new Set();
const checkTime = ['schemeSwitcher.nightStart', 'schemeSwitcher.nightEnd'];
prefs.subscribe(checkTime, (key, value) => {
updateTimePreferDark();
createAlarm(key, value);
});
checkTime.forEach(key => createAlarm(key, prefs.get(key)));
prefs.subscribe(['schemeSwitcher.enabled'], emitChange);
chrome.alarms.onAlarm.addListener(info => {
if (checkTime.includes(info.name)) {
updateTimePreferDark();
}
});
updateSystemPreferDark();
updateTimePreferDark();
return {shouldIncludeStyle, onChange, updateSystemPreferDark};
function createAlarm(key, value) {
const date = new Date();
applyDate(date, value);
if (date.getTime() < Date.now()) {
date.setDate(date.getDate() + 1);
}
chrome.alarms.create(key, {
when: date.getTime(),
periodInMinutes: 24 * 60,
});
}
function shouldIncludeStyle(style) {
const isDark = style.preferScheme === 'dark';
const isLight = style.preferScheme === 'light';
if (!isDark && !isLight) {
return true;
}
const switcherState = prefs.get('schemeSwitcher.enabled');
if (switcherState === 'never') {
return true;
}
if (switcherState === 'system') {
return systemPreferDark && isDark ||
!systemPreferDark && isLight;
}
return timePreferDark && isDark ||
!timePreferDark && isLight;
}
function updateSystemPreferDark() {
const oldValue = systemPreferDark;
systemPreferDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (systemPreferDark !== oldValue) {
emitChange();
}
return true;
}
function updateTimePreferDark() {
const oldValue = timePreferDark;
const date = new Date();
const now = date.getTime();
applyDate(date, prefs.get('schemeSwitcher.nightStart'));
const start = date.getTime();
applyDate(date, prefs.get('schemeSwitcher.nightEnd'));
const end = date.getTime();
timePreferDark = start > end ?
now >= start || now < end :
now >= start && now < end;
if (timePreferDark !== oldValue) {
emitChange();
}
}
function applyDate(date, time) {
const [h, m] = time.split(':').map(Number);
date.setHours(h, m, 0, 0);
}
function onChange(listener) {
changeListeners.add(listener);
}
function emitChange() {
for (const listener of changeListeners) {
listener();
}
}
})();

View File

@ -1,31 +0,0 @@
/* global API */// msg.js
'use strict';
/**
* Common stuff that's loaded first so it's immediately available to all background scripts
*/
/* exported
addAPI
bgReady
compareRevision
*/
const bgReady = {};
bgReady.styles = new Promise(r => (bgReady._resolveStyles = r));
bgReady.all = new Promise(r => (bgReady._resolveAll = r));
function addAPI(methods) {
for (const [key, val] of Object.entries(methods)) {
const old = API[key];
if (old && Object.prototype.toString.call(old) === '[object Object]') {
Object.assign(old, val);
} else {
API[key] = val;
}
}
}
function compareRevision(rev1, rev2) {
return rev1 - rev2;
}

View File

@ -1,101 +0,0 @@
/* global browserCommands */// background.js
/* global msg */
/* global prefs */
/* global CHROME FIREFOX URLS ignoreChromeError */// toolbox.js
'use strict';
(() => {
const contextMenus = {
'show-badge': {
title: 'menuShowBadge',
click: info => prefs.set(info.menuItemId, info.checked),
},
'disableAll': {
title: 'disableAllStyles',
click: browserCommands.styleDisableAll,
},
'open-manager': {
title: 'openStylesManager',
click: browserCommands.openManage,
},
'open-options': {
title: 'openOptions',
click: browserCommands.openOptions,
},
'reload': {
presentIf: async () => (await browser.management.getSelf()).installType === 'development',
title: 'reload',
click: browserCommands.reload,
},
'editor.contextDelete': {
presentIf: () => !FIREFOX && prefs.get('editor.contextDelete'),
title: 'editDeleteText',
type: 'normal',
contexts: ['editable'],
documentUrlPatterns: [URLS.ownOrigin + 'edit*'],
click: (info, tab) => {
msg.sendTab(tab.id, {method: 'editDeleteText'}, undefined, 'extension')
.catch(msg.ignoreError);
},
},
};
// "Delete" item in context menu for browsers that don't have it
if (CHROME &&
// looking at the end of UA string
/(Vivaldi|Safari)\/[\d.]+$/.test(navigator.userAgent) &&
// skip forks with Flash as those are likely to have the menu e.g. CentBrowser
!Array.from(navigator.plugins).some(p => p.name === 'Shockwave Flash')) {
prefs.__defaults['editor.contextDelete'] = true;
}
const keys = Object.keys(contextMenus);
prefs.subscribe(keys.filter(id => typeof prefs.defaults[id] === 'boolean'),
CHROME >= 62 && CHROME <= 64 ? toggleCheckmarkBugged : toggleCheckmark);
prefs.subscribe(keys.filter(id => contextMenus[id].presentIf && prefs.knownKeys.includes(id)),
togglePresence);
createContextMenus(keys);
chrome.contextMenus.onClicked.addListener((info, tab) =>
contextMenus[info.menuItemId].click(info, tab));
async function createContextMenus(ids) {
for (const id of ids) {
let item = contextMenus[id];
if (item.presentIf && !await item.presentIf()) {
continue;
}
item = Object.assign({id}, item);
delete item.presentIf;
item.title = chrome.i18n.getMessage(item.title);
if (!item.type && typeof prefs.defaults[id] === 'boolean') {
item.type = 'checkbox';
item.checked = prefs.get(id);
}
if (!item.contexts) {
item.contexts = ['browser_action'];
}
delete item.click;
chrome.contextMenus.create(item, ignoreChromeError);
}
}
function toggleCheckmark(id, checked) {
chrome.contextMenus.update(id, {checked}, ignoreChromeError);
}
/** Circumvents the bug with disabling check marks in Chrome 62-64 */
async function toggleCheckmarkBugged(id) {
await browser.contextMenus.remove(id).catch(ignoreChromeError);
createContextMenus([id]);
}
function togglePresence(id, checked) {
if (checked) {
createContextMenus([id]);
} else {
chrome.contextMenus.remove(id, ignoreChromeError);
}
}
})();

95
dist/background/db.js vendored
View File

@ -1,95 +0,0 @@
/* global chromeLocal */// storage-util.js
/* global cloneError */// worker-util.js
'use strict';
/*
Initialize a database. There are some problems using IndexedDB in Firefox:
https://www.reddit.com/r/firefox/comments/74wttb/note_to_firefox_webextension_developers_who_use/
Some of them are fixed in FF59:
https://www.reddit.com/r/firefox/comments/7ijuaq/firefox_59_webextensions_can_use_indexeddb_when/
*/
/* exported db */
const db = (() => {
const DATABASE = 'stylish';
const STORE = 'styles';
const FALLBACK = 'dbInChromeStorage';
const dbApi = {
async exec(...args) {
dbApi.exec = await tryUsingIndexedDB().catch(useChromeStorage);
return dbApi.exec(...args);
},
};
return dbApi;
async function tryUsingIndexedDB() {
// we use chrome.storage.local fallback if IndexedDB doesn't save data,
// which, once detected on the first run, is remembered in chrome.storage.local
// note that accessing indexedDB may throw, https://github.com/openstyles/stylus/issues/615
if (typeof indexedDB === 'undefined') {
throw new Error('indexedDB is undefined');
}
switch (await chromeLocal.getValue(FALLBACK)) {
case true: throw null;
case false: break;
default: await testDB();
}
chromeLocal.setValue(FALLBACK, false);
return dbExecIndexedDB;
}
async function testDB() {
const id = `${performance.now()}.${Math.random()}.${Date.now()}`;
await dbExecIndexedDB('put', {id});
const e = await dbExecIndexedDB('get', id);
await dbExecIndexedDB('delete', e.id); // throws if `e` or id is null
}
async function useChromeStorage(err) {
chromeLocal.setValue(FALLBACK, true);
if (err) {
chromeLocal.setValue(FALLBACK + 'Reason', cloneError(err));
console.warn('Failed to access indexedDB. Switched to storage API.', err);
}
await require(['/background/db-chrome-storage']); /* global createChromeStorageDB */
return createChromeStorageDB();
}
async function dbExecIndexedDB(method, ...args) {
const mode = method.startsWith('get') ? 'readonly' : 'readwrite';
const store = (await open()).transaction([STORE], mode).objectStore(STORE);
const fn = method === 'putMany' ? putMany : storeRequest;
return fn(store, method, ...args);
}
function storeRequest(store, method, ...args) {
return new Promise((resolve, reject) => {
/** @type {IDBRequest} */
const request = store[method](...args);
request.onsuccess = () => resolve(request.result);
request.onerror = reject;
});
}
function putMany(store, _method, items) {
return Promise.all(items.map(item => storeRequest(store, 'put', item)));
}
function open() {
return new Promise((resolve, reject) => {
const request = indexedDB.open(DATABASE, 2);
request.onsuccess = () => resolve(request.result);
request.onerror = reject;
request.onupgradeneeded = create;
});
}
function create(event) {
if (event.oldVersion === 0) {
event.target.result.createObjectStore(STORE, {
keyPath: 'id',
autoIncrement: true,
});
}
}
})();

View File

@ -1,15 +0,0 @@
/* global chromeLocal */// storage-util.js
'use strict';
// Removing unused stuff from storage on extension update
// TODO: delete this by the middle of 2021
try {
localStorage.clear();
} catch (e) {}
setTimeout(async () => {
const del = Object.keys(await chromeLocal.get())
.filter(key => key.startsWith('usoSearchCache'));
if (del.length) chromeLocal.remove(del);
}, 15e3);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,378 +0,0 @@
/* global API msg */// msg.js
'use strict';
// eslint-disable-next-line no-unused-expressions
/^\/styles\/(\d+)(\/([^/]*))?([?#].*)?$/.test(location.pathname) && (() => {
const styleId = RegExp.$1;
const pageEventId = `${performance.now()}${Math.random()}`;
window.dispatchEvent(new CustomEvent(chrome.runtime.id + '-install'));
window.addEventListener(chrome.runtime.id + '-install', orphanCheck, true);
document.addEventListener('stylishInstallChrome', onClick);
document.addEventListener('stylishUpdateChrome', onClick);
msg.on(onMessage);
let currentMd5;
const md5Url = getMeta('stylish-md5-url') || `https://update.userstyles.org/${styleId}.md5`;
Promise.all([
API.styles.find({md5Url}),
getResource(md5Url),
onDOMready(),
]).then(checkUpdatability);
document.documentElement.appendChild(
Object.assign(document.createElement('script'), {
textContent: `(${inPageContext})('${pageEventId}')`,
}));
function onMessage(msg) {
switch (msg.method) {
case 'ping':
// orphaned content script check
return true;
case 'openSettings':
openSettings();
return true;
}
}
/* since we are using "stylish-code-chrome" meta key on all browsers and
US.o does not provide "advanced settings" on this url if browser is not Chrome,
we need to fix this URL using "stylish-update-url" meta key
*/
function getStyleURL() {
const textUrl = getMeta('stylish-update-url') || '';
const jsonUrl = getMeta('stylish-code-chrome') ||
textUrl.replace(/styles\/(\d+)\/[^?]*/, 'styles/chrome/$1.json');
const paramsMissing = !jsonUrl.includes('?') && textUrl.includes('?');
return jsonUrl + (paramsMissing ? textUrl.replace(/^[^?]+/, '') : '');
}
function checkUpdatability([installedStyle, md5]) {
// TODO: remove the following statement when USO is fixed
document.dispatchEvent(new CustomEvent(pageEventId, {
detail: installedStyle && installedStyle.updateUrl,
}));
currentMd5 = md5;
if (!installedStyle) {
sendEvent({type: 'styleCanBeInstalledChrome'});
return;
}
const isCustomizable = /\?/.test(installedStyle.updateUrl);
const md5Url = getMeta('stylish-md5-url');
if (md5Url && installedStyle.md5Url && installedStyle.originalMd5) {
reportUpdatable(isCustomizable || md5 !== installedStyle.originalMd5);
} else {
getStyleJson().then(json => {
reportUpdatable(
isCustomizable ||
!json ||
!styleSectionsEqual(json, installedStyle));
});
}
function prepareInstallButton() {
return new Promise(resolve => {
const observer = new MutationObserver(check);
observer.observe(document.documentElement, {
childList: true,
subtree: true,
});
check();
function check() {
if (document.querySelector('#install_style_button')) {
resolve();
observer.disconnect();
}
}
});
}
function reportUpdatable(isUpdatable) {
prepareInstallButton().then(() => {
sendEvent({
type: isUpdatable
? 'styleCanBeUpdatedChrome'
: 'styleAlreadyInstalledChrome',
detail: {
updateUrl: installedStyle.updateUrl,
},
});
});
}
}
function sendEvent(event) {
sendEvent.lastEvent = event;
let {type, detail = null} = event;
if (typeof cloneInto !== 'undefined') {
// Firefox requires explicit cloning, however USO can't process our messages anyway
// because USO tries to use a global "event" variable deprecated in Firefox
detail = cloneInto({detail}, document); /* global cloneInto */
} else {
detail = {detail};
}
document.dispatchEvent(new CustomEvent(type, detail));
}
function onClick(event) {
if (onClick.processing || !orphanCheck()) {
return;
}
onClick.processing = true;
doInstall()
.then(() => {
if (!event.type.includes('Update')) {
// FIXME: sometimes the button is broken i.e. the button sends
// 'install' instead of 'update' event while the style is already
// install.
// This triggers an incorrect install count but we don't really care.
return getResource(getMeta('stylish-install-ping-url-chrome'));
}
})
.catch(console.error)
.then(done);
function done() {
setTimeout(() => {
onClick.processing = false;
});
}
}
function doInstall() {
let oldStyle;
return API.styles.find({
md5Url: getMeta('stylish-md5-url') || location.href,
})
.then(_oldStyle => {
oldStyle = _oldStyle;
return oldStyle ?
oldStyle.name :
getResource(getMeta('stylish-description'));
})
.then(name => {
const props = {};
if (oldStyle) {
props.id = oldStyle.id;
}
return saveStyleCode(oldStyle ? 'styleUpdate' : 'styleInstall', name, props);
});
}
async function saveStyleCode(message, name, addProps = {}) {
const isNew = message === 'styleInstall';
const needsConfirmation = isNew || !saveStyleCode.confirmed;
if (needsConfirmation && !confirm(chrome.i18n.getMessage(message, [name]))) {
return Promise.reject();
}
saveStyleCode.confirmed = true;
enableUpdateButton(false);
const json = await getStyleJson();
if (!json) {
prompt(chrome.i18n.getMessage('styleInstallFailed', ''),
'https://github.com/openstyles/stylus/issues/195');
return;
}
// Update originalMd5 since USO changed it (2018-11-11) to NOT match the current md5
const style = await API.styles.install(Object.assign(json, addProps, {originalMd5: currentMd5}));
if (!isNew && style.updateUrl.includes('?')) {
enableUpdateButton(true);
} else {
sendEvent({type: 'styleInstalledChrome'});
}
function enableUpdateButton(state) {
const important = s => s.replace(/;/g, '!important;');
const button = document.getElementById('update_style_button');
if (button) {
button.style.cssText = state ? '' : important('pointer-events: none; opacity: .35;');
const icon = button.querySelector('img[src*=".svg"]');
if (icon) {
icon.style.cssText = state ? '' : important('transition: transform 5s; transform: rotate(0);');
if (state) {
setTimeout(() => (icon.style.cssText += important('transform: rotate(10turn);')));
}
}
}
}
}
function getMeta(name) {
const e = document.querySelector(`link[rel="${name}"]`);
return e ? e.getAttribute('href') : null;
}
async function getResource(url, opts) {
try {
return url.startsWith('#')
? document.getElementById(url.slice(1)).textContent
: await API.download(url, opts);
} catch (error) {
alert('Error\n' + error.message);
return Promise.reject(error);
}
}
// USO providing md5Url as "https://update.update.userstyles.org/#####.md5"
// instead of "https://update.userstyles.org/#####.md5"
async function getStyleJson() {
try {
const style = await getResource(getStyleURL(), {responseType: 'json'});
const codeElement = document.getElementById('stylish-code');
if (!style || !Array.isArray(style.sections) || style.sections.length ||
codeElement && !codeElement.textContent.trim()) {
return style;
}
const code = await getResource(getMeta('stylish-update-url'));
style.sections = (await API.worker.parseMozFormat({code})).sections;
if (style.md5Url) style.md5Url = style.md5Url.replace('update.update', 'update');
return style;
} catch (e) {}
}
/**
* The sections are checked in successive order because it matters when many sections
* match the same URL and they have rules with the same CSS specificity
* @param {Object} a - first style object
* @param {Object} b - second style object
* @returns {?boolean}
*/
function styleSectionsEqual({sections: a}, {sections: b}) {
const targets = ['urls', 'urlPrefixes', 'domains', 'regexps'];
return a && b && a.length === b.length && a.every(sameSection);
function sameSection(secA, i) {
return equalOrEmpty(secA.code, b[i].code, 'string', (a, b) => a === b) &&
targets.every(target => equalOrEmpty(secA[target], b[i][target], 'array', arrayMirrors));
}
function equalOrEmpty(a, b, type, comparator) {
const typeA = type === 'array' ? Array.isArray(a) : typeof a === type;
const typeB = type === 'array' ? Array.isArray(b) : typeof b === type;
return typeA && typeB && comparator(a, b) ||
(a == null || typeA && !a.length) &&
(b == null || typeB && !b.length);
}
function arrayMirrors(a, b) {
return a.length === b.length &&
a.every(el => b.includes(el)) &&
b.every(el => a.includes(el));
}
}
function onDOMready() {
return document.readyState !== 'loading'
? Promise.resolve()
: new Promise(resolve => document.addEventListener('DOMContentLoaded', resolve, {once: true}));
}
function openSettings(countdown = 10e3) {
const button = document.querySelector('.customize_button');
if (button) {
button.dispatchEvent(new MouseEvent('click', {bubbles: true}));
setTimeout(function pollArea(countdown = 2000) {
const area = document.getElementById('advancedsettings_area');
if (area || countdown < 0) {
(area || button).scrollIntoView({behavior: 'smooth', block: area ? 'end' : 'center'});
} else {
setTimeout(pollArea, 100, countdown - 100);
}
}, 500);
} else if (countdown > 0) {
setTimeout(openSettings, 100, countdown - 100);
}
}
function orphanCheck() {
try {
if (chrome.i18n.getUILanguage()) {
return true;
}
} catch (e) {}
// In Chrome content script is orphaned on an extension update/reload
// so we need to detach event listeners
window.removeEventListener(chrome.runtime.id + '-install', orphanCheck, true);
document.removeEventListener('stylishInstallChrome', onClick);
document.removeEventListener('stylishUpdateChrome', onClick);
try {
msg.off(onMessage);
} catch (e) {}
}
})();
function inPageContext(eventId) {
document.currentScript.remove();
window.isInstalled = true;
const origMethods = {
json: Response.prototype.json,
byId: document.getElementById,
};
let vars;
// USO bug workaround: prevent errors in console after install and busy cursor
document.getElementById = id =>
origMethods.byId.call(document, id) ||
(/^(stylish-code|stylish-installed-style-installed-\w+|post-install-ad|style-install-unknown)$/.test(id)
? Object.assign(document.createElement('p'), {className: 'afterdownload-ad'})
: null);
// USO bug workaround: use the actual image data in customized settings
document.addEventListener(eventId, ({detail}) => {
vars = /\?/.test(detail) && new URL(detail).searchParams;
if (!vars) Response.prototype.json = origMethods.json;
}, {once: true});
Response.prototype.json = async function () {
const json = await origMethods.json.apply(this, arguments);
if (vars && json && Array.isArray(json.style_settings)) {
Response.prototype.json = origMethods.json;
const images = new Map();
for (const ss of json.style_settings) {
let value = vars.get('ik-' + ss.install_key);
if (!value || !(ss.style_setting_options || [])[0]) {
continue;
}
if (value.startsWith('ik-')) {
value = value.replace(/^ik-/, '');
const def = ss.style_setting_options.find(item => item.default);
if (!def || def.install_key !== value) {
if (def) def.default = false;
for (const item of ss.style_setting_options) {
if (item.install_key === value) {
item.default = true;
break;
}
}
}
} else if (ss.setting_type === 'image') {
let isListed;
for (const opt of ss.style_setting_options) {
isListed |= opt.default = (opt.value === value);
}
images.set(ss.install_key, {url: value, isListed});
} else {
const item = ss.style_setting_options[0];
if (item.value !== value && item.install_key === 'placeholder') {
item.value = value;
}
}
}
if (images.size) {
new MutationObserver((_, observer) => {
if (document.getElementById('style-settings')) {
observer.disconnect();
for (const [name, {url, isListed}] of images) {
const elRadio = document.querySelector(`input[name="ik-${name}"][value="user-url"]`);
const elUrl = elRadio &&
document.getElementById(elRadio.id.replace('url-choice', 'user-url'));
if (elUrl) {
elRadio.checked = !isListed;
elUrl.value = url;
}
}
}
}).observe(document, {childList: true, subtree: true});
}
}
return json;
};
}

View File

@ -1,76 +0,0 @@
/* Built-in CodeMirror and addon customization */
.CodeMirror-hints {
z-index: 999;
}
.CodeMirror-hint:hover {
color: white;
background: #08f;
}
.CodeMirror {
border: solid #CCC 1px;
transition: box-shadow .1s;
}
#stylus#stylus .CodeMirror {
/* Using a specificity hack to override userstyles */
/* Not using the ring-color hack as it became ugly in new Chrome */
outline: none !important;
}
.CodeMirror-dialog {
animation: highlight 3s cubic-bezier(.18, .02, 0, .94);
}
.CodeMirror-search-field {
width: 10em;
}
.CodeMirror-jump-field {
width: 5em;
}
.CodeMirror-search-hint {
color: #888;
}
.CodeMirror-activeline .applies-to:before {
background-color: hsla(214, 100%, 90%, 0.15);
content: "";
top: 1em;
left: 0;
right: 0;
bottom: 1em;
position: absolute;
pointer-events: none;
}
.CodeMirror-activeline .applies-to ul {
z-index: 2;
}
.CodeMirror-foldgutter-open::after,
.CodeMirror-foldgutter-folded::after {
top: 5px;
width: 0;
height: 0;
content: "";
position: absolute;
border-style: solid;
opacity: .5;
left: 1px;
}
.CodeMirror-foldgutter-open::after {
border-width: 5px 3px 0 3px;
border-color: currentColor transparent transparent transparent;
}
.CodeMirror-foldgutter-folded::after {
margin-top: -2px;
margin-left: 1px;
border-width: 4px 0 4px 5px;
border-color: transparent transparent transparent currentColor;
}
.CodeMirror-linenumber {
cursor: pointer; /* for bookmarking */
}
/* Custom stuff we add to CodeMirror */
.cm-uso-variable {
font-weight: bold;
}
.gutter-bookmark {
background: linear-gradient(0deg, hsla(180, 100%, 30%, .75) 2px, hsla(180, 100%, 30%, .2) 2px);
}

View File

@ -1,71 +0,0 @@
/* Do not edit. This file is auto-generated by build-vendor.js */
'use strict';
/* exported CODEMIRROR_THEMES */
const CODEMIRROR_THEMES = [
'3024-day',
'3024-night',
'abbott',
'abcdef',
'ambiance',
'ambiance-mobile',
'ayu-dark',
'ayu-mirage',
'base16-dark',
'base16-light',
'bespin',
'blackboard',
'cobalt',
'colorforth',
'darcula',
'dracula',
'duotone-dark',
'duotone-light',
'eclipse',
'elegant',
'erlang-dark',
'gruvbox-dark',
'hopscotch',
'icecoder',
'idea',
'isotope',
'juejin',
'lesser-dark',
'liquibyte',
'lucario',
'material',
'material-darker',
'material-ocean',
'material-palenight',
'mbo',
'mdn-like',
'midnight',
'monokai',
'moxer',
'neat',
'neo',
'night',
'nord',
'oceanic-next',
'panda-syntax',
'paraiso-dark',
'paraiso-light',
'pastel-on-dark',
'railscasts',
'rubyblue',
'seti',
'shadowfox',
'solarized',
'ssms',
'the-matrix',
'tomorrow-night-bright',
'tomorrow-night-eighties',
'ttcn',
'twilight',
'vibrant-ink',
'xq-dark',
'xq-light',
'yeti',
'yonce',
'zenburn',
];

View File

@ -1,46 +0,0 @@
.style-settings {
padding: 0.7rem 1.7rem;
border: 0;
margin: 0;
}
.form-group {
display: block;
margin: .6em 0;
padding: 0;
}
.form-label {
display: inline-block;
margin: .3em 0;
}
[disabled] .form-label {
opacity: 0.4;
}
.form-group input[type=text],
.form-group input[type=number],
.form-group select,
.form-group textarea {
display: block;
width: 100%;
box-sizing: border-box;
}
.radio-group .form-label {
display: block;
}
.radio-item {
display: flex;
margin: 0.3em 0 .3em;
padding: 0;
align-items: center;
width: max-content;
}
.radio-item input {
margin: 0 0.6em 0 0;
}
[disabled] .radio-label {
opacity: 0.4;
}
.style-settings textarea {
resize: vertical;
min-height: 2.5em;
max-height: 50vh;
}

84
dist/edit/settings.js vendored
View File

@ -1,84 +0,0 @@
/* global $ $$ */// dom.js
/* global API */// msg.js
/* exported StyleSettings */
'use strict';
function StyleSettings(editor) {
let {style} = editor;
const inputs = [
createInput('.style-update-url input', () => style.updateUrl || '',
e => API.styles.config(style.id, 'updateUrl', e.target.value)),
createRadio('.style-prefer-scheme input', () => style.preferScheme || 'none',
e => API.styles.config(style.id, 'preferScheme', e.target.value)),
...[
['.style-include', 'inclusions'],
['.style-exclude', 'exclusions'],
].map(createArea),
];
update(style);
editor.on('styleChange', update);
function textToList(text) {
const list = text.split(/\s*\r?\n\s*/g);
return list.filter(Boolean);
}
function update(newStyle, reason) {
if (!newStyle.id) return;
if (reason === 'editSave') return;
style = newStyle;
$('.style-settings').disabled = false;
inputs.forEach(i => i.update());
}
function createArea([parentSel, type]) {
const sel = parentSel + ' textarea';
const el = $(sel);
el.on('input', () => {
const val = el.value;
el.rows = val.match(/^/gm).length + !val.endsWith('\n');
});
return createInput(sel,
() => {
const list = style[type] || [];
const text = list.join('\n');
el.rows = (list.length || 1) + 1;
return text;
},
() => API.styles.config(style.id, type, textToList(el.value))
);
}
function createRadio(selector, getter, setter) {
const els = $$(selector);
for (const el of els) {
el.addEventListener('change', e => {
if (el.checked) {
setter(e);
}
});
}
return {
update() {
for (const el of els) {
if (el.value === getter()) {
el.checked = true;
}
}
},
};
}
function createInput(selector, getter, setter) {
const el = $(selector);
el.addEventListener('change', setter);
return {
update() {
el.value = getter();
},
};
}
}

28
dist/edit/tab.css vendored
View File

@ -1,28 +0,0 @@
.tab-container {
display: flex;
flex-direction: column;
}
.tab-bar {
display: flex;
flex-direction: row;
border-bottom: 1px solid silver;
padding: 5px 5px 0 15px;
}
.tab-bar-item {
margin: 0 0.3em;
padding: 0.3em 0.6em;
border: 1px solid silver;
border-bottom: none;
background: silver;
cursor: pointer;
}
.tab-bar-item.active {
background: white;
}
.tab-panel {
flex-grow: 1;
}
.tab-panel > :not(.active) {
display: none;
}

19
dist/edit/tab.js vendored
View File

@ -1,19 +0,0 @@
'use strict';
(() => {
for (const container of document.querySelectorAll('.tab-container')) {
init(container);
}
function init(container) {
const tabButtons = [...container.querySelector('.tab-bar').children];
const tabPanels = [...container.querySelector('.tab-panel').children];
tabButtons.forEach((button, i) => button.addEventListener('click', () => activate(i)));
function activate(index) {
const toggleActive = (button, i) => button.classList.toggle('active', i === index);
tabButtons.forEach(toggleActive);
tabPanels.forEach(toggleActive);
}
}
})();

View File

@ -1,104 +0,0 @@
<!DOCTYPE html>
<html id="stylus" lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Loading...</title>
<link href="global.css" rel="stylesheet">
<script src="js/polyfill.js"></script>
<script src="js/msg.js"></script>
<script src="js/toolbox.js"></script>
<script src="install-usercss/preinit.js"></script>
<script src="js/prefs.js"></script>
<script src="js/dom.js"></script>
<script src="js/localization.js"></script>
<script src="content/style-injector.js"></script>
<script src="content/apply.js"></script>
<link href="spinner.css" rel="stylesheet">
<link href="install-usercss/install-usercss.css" rel="stylesheet">
</head>
<body id="stylus-install-usercss">
<div class="container">
<div id="header">
<div id="header-content-wrapper">
<h1>
<span class="meta-name"></span>
<small class="meta-version"></small>
</h1>
<div class="actions">
<h2 hidden class="installed" i18n-text="installButtonInstalled"></h2>
<button class="install" i18n-text="installButton"></button>
<a class="configure-usercss" i18n-title="configureStyle" tabindex="0">
<svg class="svg-icon config"><use xlink:href="#svg-icon-config"></use></svg>
</a>
<p id="live-reload-install-hint" hidden></p>
<label class="set-update-url">
<input type="checkbox">
<svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>
<span i18n-text="installUpdateFromLabel"></span>
<p></p>
</label>
<label class="live-reload">
<input type="checkbox">
<svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>
<span i18n-text="liveReloadLabel"></span>
</label>
<label class="set-prefer-scheme">
<span i18n-text="installPreferSchemeLabel"></span>
<select>
<option value="none" i18n-text="installPreferSchemeNone"></option>
<option value="dark" i18n-text="installPreferSchemeDark"></option>
<option value="light" i18n-text="installPreferSchemeLight"></option>
</select>
</label>
<p hidden class="installed-actions">
<a href="manage.html" tabindex="0"><button i18n-text="openManage"></button></a>
<a href="edit.html?id=" tabindex="0"><button i18n-text="editStyleLabel"></button></a>
<a id="delete" tabindex="0"><button i18n-text="deleteStyleLabel"></button></a>
</p>
</div>
<p class="meta-description"></p>
<div>
<h3 i18n-text="author"></h3>
<span class="meta-author"></span>
</div>
<div>
<h3 i18n-text="license"></h3>
<span class="meta-license"></span>
</div>
<div class="external-link"></div>
<div id="applies-to-wrapper">
<h3 i18n-text="appliesLabel"></h3>
<ul class="applies-to">
</ul>
</div>
</div>
</div>
<div class="main">
<div class="warnings"></div>
</div>
</div>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none !important;">
<symbol id="svg-icon-checked" viewBox="0 0 1000 1000">
<path fill-rule="evenodd" d="M983.2,184.3L853,69.8c-4-3.5-9.3-5.3-14.5-5c-5.3,0.4-10.3,2.8-13.8,6.8L352.3,609.2L184.4,386.9c-3.2-4.2-8-7-13.2-7.8c-5.3-0.8-10.6,0.6-14.9,3.9L18,487.5c-8.8,6.7-10.6,19.3-3.9,28.1L325,927.2c3.6,4.8,9.3,7.7,15.3,8c0.2,0,0.5,0,0.7,0c5.8,0,11.3-2.5,15.1-6.8L985,212.6C992.3,204.3,991.5,191.6,983.2,184.3z"/>
</symbol>
<symbol id="svg-icon-select-arrow" viewBox="0 0 1792 1792">
<path fill-rule="evenodd" d="M1408 704q0 26-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45t19-45 45-19h896q26 0 45 19t19 45z"/>
</symbol>
<symbol id="svg-icon-config" viewBox="0 0 16 16">
<path d="M13.3,12.8l1.5-2.6l-2.2-1.5c0-0.2,0.1-0.5,0.1-0.7c0-0.2,0-0.5-0.1-0.7l2.2-1.5l-1.5-2.6l-2.4,1.2 c-0.4-0.3-0.8-0.5-1.2-0.7L9.5,1h-3L6.3,3.7C5.9,3.8,5.5,4.1,5.1,4.4L2.7,3.2L1.2,5.8l2.2,1.5c0,0.2-0.1,0.5-0.1,0.7 c0,0.2,0,0.5,0.1,0.7l-2.2,1.5l1.5,2.6l2.4-1.2c0.4,0.3,0.8,0.5,1.2,0.7L6.5,15h3l0.2-2.7c0.4-0.2,0.8-0.4,1.2-0.7L13.3,12.8z M8,10.3c-1.3,0-2.3-1-2.3-2.3c0-1.3,1-2.3,2.3-2.3c1.3,0,2.3,1,2.3,2.3C10.3,9.3,9.3,10.3,8,10.3z"/>
</symbol>
</svg>
<script src="js/dlg/message-box.js"></script>
<script src="install-usercss/install-usercss.js"></script>
</body>
</html>

View File

@ -1,373 +0,0 @@
'use strict';
const colorConverter = (() => {
return {
parse,
format,
formatAlpha,
RGBtoHSV,
HSVtoRGB,
HSLtoHSV,
HSVtoHSL,
constrainHue,
snapToInt,
ALPHA_DIGITS: 3,
// NAMED_COLORS is added below
};
function format(color = '', type = color.type, hexUppercase, usoMode) {
if (!color || !type) return typeof color === 'string' ? color : '';
const {a} = color;
let aStr = formatAlpha(a);
if (aStr) aStr = ', ' + aStr;
if (type !== 'hsl' && color.type === 'hsl') {
color = HSVtoRGB(HSLtoHSV(color));
}
const {r, g, b, h, s, l} = color;
switch (type) {
case 'hex': {
let res = '#' + hex2(r) + hex2(g) + hex2(b) + (aStr ? hex2(Math.round(a * 255)) : '');
if (!usoMode) res = res.replace(/^#(.)\1(.)\2(.)\3(?:(.)\4)?$/, '#$1$2$3$4');
return hexUppercase ? res.toUpperCase() : res;
}
case 'rgb': {
const rgb = [r, g, b].map(Math.round).join(', ');
return usoMode ? rgb : `rgb${aStr ? 'a' : ''}(${rgb}${aStr})`;
}
case 'hsl':
return `hsl${aStr ? 'a' : ''}(${h}, ${s}%, ${l}%${aStr})`;
}
}
// Copied from _hexcolor() in parserlib.js
function validateHex(color) {
return /^#[a-f\d]+$/i.test(color) && [4, 5, 7, 9].some(n => color.length === n);
}
function validateRGB(nums) {
const isPercentage = nums[0].endsWith('%');
const valid = isPercentage ? validatePercentage : validateNum;
return nums.slice(0, 3).every(valid);
}
function validatePercentage(s) {
if (!s.endsWith('%')) return false;
const n = Number(s.slice(0, -1));
return n >= 0 && n <= 100;
}
function validateNum(s) {
const n = Number(s);
return n >= 0 && n <= 255;
}
function validateHSL(nums) {
return validateAngle(nums[0]) && nums.slice(1, 3).every(validatePercentage);
}
function validateAngle(s) {
return /^-?(\d+|\d*\.\d+)(deg|grad|rad|turn)?$/i.test(s);
}
function validateAlpha(alpha) {
if (alpha.endsWith('%')) {
return validatePercentage(alpha);
}
const n = Number(alpha);
return n >= 0 && n <= 1;
}
function parse(str) {
if (typeof str !== 'string') return;
str = str.trim();
if (!str) return;
if (str[0] !== '#' && !str.includes('(')) {
// eslint-disable-next-line no-use-before-define
str = colorConverter.NAMED_COLORS.get(str);
if (!str) return;
}
if (str[0] === '#') {
if (!validateHex(str)) {
return null;
}
str = str.slice(1);
const [r, g, b, a = 255] = str.length <= 4 ?
str.match(/(.)/g).map(c => parseInt(c + c, 16)) :
str.match(/(..)/g).map(c => parseInt(c, 16));
return {type: 'hex', r, g, b, a: a === 255 ? undefined : a / 255};
}
const [, type, value] = str.match(/^(rgb|hsl)a?\((.*?)\)|$/i);
if (!type) return;
const comma = value.includes(',') && !value.includes('/');
const num = value.trim().split(comma ? /\s*,\s*/ : /\s+(?!\/)|\s*\/\s*/);
if (num.length < 3 || num.length > 4) return;
if (num[3] && !validateAlpha(num[3])) return null;
let a = !num[3] ? 1 : parseFloat(num[3]) / (num[3].endsWith('%') ? 100 : 1);
if (isNaN(a)) a = 1;
const first = num[0];
if (/rgb/i.test(type)) {
if (!validateRGB(num)) {
return null;
}
const k = first.endsWith('%') ? 2.55 : 1;
const [r, g, b] = num.map(s => Math.round(parseFloat(s) * k));
return {type: 'rgb', r, g, b, a};
} else {
if (!validateHSL(num)) {
return null;
}
let h = parseFloat(first);
if (first.endsWith('grad')) h *= 360 / 400;
else if (first.endsWith('rad')) h *= 180 / Math.PI;
else if (first.endsWith('turn')) h *= 360;
const s = parseFloat(num[1]);
const l = parseFloat(num[2]);
return {type: 'hsl', h, s, l, a};
}
}
function formatAlpha(a) {
return isNaN(a) ? '' :
(a + .5 * Math.pow(10, -colorConverter.ALPHA_DIGITS))
.toFixed(colorConverter.ALPHA_DIGITS + 1)
.slice(0, -1)
.replace(/^0(?=\.[1-9])|^1\.0+?$|\.?0+$/g, '');
}
function RGBtoHSV({r, g, b, a}) {
r /= 255;
g /= 255;
b /= 255;
const MaxC = Math.max(r, g, b);
const MinC = Math.min(r, g, b);
const DeltaC = MaxC - MinC;
let h =
DeltaC === 0 ? 0 :
MaxC === r ? 60 * (((g - b) / DeltaC) % 6) :
MaxC === g ? 60 * (((b - r) / DeltaC) + 2) :
MaxC === b ? 60 * (((r - g) / DeltaC) + 4) :
0;
h = constrainHue(h);
return {
h,
s: MaxC === 0 ? 0 : DeltaC / MaxC,
v: MaxC,
a,
};
}
function HSVtoRGB({h, s, v}) {
h = constrainHue(h) % 360;
const C = s * v;
const X = C * (1 - Math.abs((h / 60) % 2 - 1));
const m = v - C;
const [r, g, b] =
h >= 0 && h < 60 ? [C, X, 0] :
h >= 60 && h < 120 ? [X, C, 0] :
h >= 120 && h < 180 ? [0, C, X] :
h >= 180 && h < 240 ? [0, X, C] :
h >= 240 && h < 300 ? [X, 0, C] :
h >= 300 && h < 360 ? [C, 0, X] : [];
return {
r: snapToInt(Math.round((r + m) * 255)),
g: snapToInt(Math.round((g + m) * 255)),
b: snapToInt(Math.round((b + m) * 255)),
};
}
function HSLtoHSV({h, s, l, a}) {
const t = s * (l < 50 ? l : 100 - l) / 100;
return {
h: constrainHue(h),
s: t + l ? 200 * t / (t + l) / 100 : 0,
v: (t + l) / 100,
a,
};
}
function HSVtoHSL({h, s, v}) {
const l = (2 - s) * v / 2;
const t = l < .5 ? l * 2 : 2 - l * 2;
return {
h: Math.round(constrainHue(h)),
s: Math.round(t ? s * v / t * 100 : 0),
l: Math.round(l * 100),
};
}
function constrainHue(h) {
return h < 0 ? h % 360 + 360 :
h > 360 ? h % 360 :
h;
}
function snapToInt(num) {
const int = Math.round(num);
return Math.abs(int - num) < 1e-3 ? int : num;
}
function hex2(val) {
return (val < 16 ? '0' : '') + (val >> 0).toString(16);
}
})();
colorConverter.NAMED_COLORS = new Map([
['transparent', 'rgba(0, 0, 0, 0)'],
// CSS4 named colors
['aliceblue', '#f0f8ff'],
['antiquewhite', '#faebd7'],
['aqua', '#00ffff'],
['aquamarine', '#7fffd4'],
['azure', '#f0ffff'],
['beige', '#f5f5dc'],
['bisque', '#ffe4c4'],
['black', '#000000'],
['blanchedalmond', '#ffebcd'],
['blue', '#0000ff'],
['blueviolet', '#8a2be2'],
['brown', '#a52a2a'],
['burlywood', '#deb887'],
['cadetblue', '#5f9ea0'],
['chartreuse', '#7fff00'],
['chocolate', '#d2691e'],
['coral', '#ff7f50'],
['cornflowerblue', '#6495ed'],
['cornsilk', '#fff8dc'],
['crimson', '#dc143c'],
['cyan', '#00ffff'],
['darkblue', '#00008b'],
['darkcyan', '#008b8b'],
['darkgoldenrod', '#b8860b'],
['darkgray', '#a9a9a9'],
['darkgrey', '#a9a9a9'],
['darkgreen', '#006400'],
['darkkhaki', '#bdb76b'],
['darkmagenta', '#8b008b'],
['darkolivegreen', '#556b2f'],
['darkorange', '#ff8c00'],
['darkorchid', '#9932cc'],
['darkred', '#8b0000'],
['darksalmon', '#e9967a'],
['darkseagreen', '#8fbc8f'],
['darkslateblue', '#483d8b'],
['darkslategray', '#2f4f4f'],
['darkslategrey', '#2f4f4f'],
['darkturquoise', '#00ced1'],
['darkviolet', '#9400d3'],
['deeppink', '#ff1493'],
['deepskyblue', '#00bfff'],
['dimgray', '#696969'],
['dimgrey', '#696969'],
['dodgerblue', '#1e90ff'],
['firebrick', '#b22222'],
['floralwhite', '#fffaf0'],
['forestgreen', '#228b22'],
['fuchsia', '#ff00ff'],
['gainsboro', '#dcdcdc'],
['ghostwhite', '#f8f8ff'],
['gold', '#ffd700'],
['goldenrod', '#daa520'],
['gray', '#808080'],
['grey', '#808080'],
['green', '#008000'],
['greenyellow', '#adff2f'],
['honeydew', '#f0fff0'],
['hotpink', '#ff69b4'],
['indianred', '#cd5c5c'],
['indigo', '#4b0082'],
['ivory', '#fffff0'],
['khaki', '#f0e68c'],
['lavender', '#e6e6fa'],
['lavenderblush', '#fff0f5'],
['lawngreen', '#7cfc00'],
['lemonchiffon', '#fffacd'],
['lightblue', '#add8e6'],
['lightcoral', '#f08080'],
['lightcyan', '#e0ffff'],
['lightgoldenrodyellow', '#fafad2'],
['lightgray', '#d3d3d3'],
['lightgrey', '#d3d3d3'],
['lightgreen', '#90ee90'],
['lightpink', '#ffb6c1'],
['lightsalmon', '#ffa07a'],
['lightseagreen', '#20b2aa'],
['lightskyblue', '#87cefa'],
['lightslategray', '#778899'],
['lightslategrey', '#778899'],
['lightsteelblue', '#b0c4de'],
['lightyellow', '#ffffe0'],
['lime', '#00ff00'],
['limegreen', '#32cd32'],
['linen', '#faf0e6'],
['magenta', '#ff00ff'],
['maroon', '#800000'],
['mediumaquamarine', '#66cdaa'],
['mediumblue', '#0000cd'],
['mediumorchid', '#ba55d3'],
['mediumpurple', '#9370db'],
['mediumseagreen', '#3cb371'],
['mediumslateblue', '#7b68ee'],
['mediumspringgreen', '#00fa9a'],
['mediumturquoise', '#48d1cc'],
['mediumvioletred', '#c71585'],
['midnightblue', '#191970'],
['mintcream', '#f5fffa'],
['mistyrose', '#ffe4e1'],
['moccasin', '#ffe4b5'],
['navajowhite', '#ffdead'],
['navy', '#000080'],
['oldlace', '#fdf5e6'],
['olive', '#808000'],
['olivedrab', '#6b8e23'],
['orange', '#ffa500'],
['orangered', '#ff4500'],
['orchid', '#da70d6'],
['palegoldenrod', '#eee8aa'],
['palegreen', '#98fb98'],
['paleturquoise', '#afeeee'],
['palevioletred', '#db7093'],
['papayawhip', '#ffefd5'],
['peachpuff', '#ffdab9'],
['peru', '#cd853f'],
['pink', '#ffc0cb'],
['plum', '#dda0dd'],
['powderblue', '#b0e0e6'],
['purple', '#800080'],
['rebeccapurple', '#663399'],
['red', '#ff0000'],
['rosybrown', '#bc8f8f'],
['royalblue', '#4169e1'],
['saddlebrown', '#8b4513'],
['salmon', '#fa8072'],
['sandybrown', '#f4a460'],
['seagreen', '#2e8b57'],
['seashell', '#fff5ee'],
['sienna', '#a0522d'],
['silver', '#c0c0c0'],
['skyblue', '#87ceeb'],
['slateblue', '#6a5acd'],
['slategray', '#708090'],
['slategrey', '#708090'],
['snow', '#fffafa'],
['springgreen', '#00ff7f'],
['steelblue', '#4682b4'],
['tan', '#d2b48c'],
['teal', '#008080'],
['thistle', '#d8bfd8'],
['tomato', '#ff6347'],
['turquoise', '#40e0d0'],
['violet', '#ee82ee'],
['wheat', '#f5deb3'],
['white', '#ffffff'],
['whitesmoke', '#f5f5f5'],
['yellow', '#ffff00'],
['yellowgreen', '#9acd32'],
]);

View File

@ -1,37 +0,0 @@
/* exported EventEmitter */
'use strict';
function EventEmitter() {
const listeners = new Map();
return {
on(ev, cb, opt) {
if (!listeners.has(ev)) {
listeners.set(ev, new Map());
}
listeners.get(ev).set(cb, opt);
if (opt && opt.runNow) {
cb();
}
},
off(ev, cb) {
const cbs = listeners.get(ev);
if (cbs) {
cbs.delete(cb);
}
},
emit(ev, ...args) {
const cbs = listeners.get(ev);
if (!cbs) return;
for (const [cb, opt] of cbs.entries()) {
try {
cb(...args);
} catch (err) {
console.error(err);
}
if (opt && opt.once) {
cbs.delete(cb);
}
}
},
};
}

View File

@ -1,476 +0,0 @@
html {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
background: none;
}
body {
background: none;
margin: 0;
font-family: "Helvetica Neue", Helvetica, sans-serif;
font-size: 12px;
display: flex;
flex-direction: column;
width: auto;
max-width: 800px;
max-height: calc(100vh - 32px);
border: 1px solid #999;
box-shadow: 0px 5px 15px 3px hsla(0, 0%, 0%, .35);
animation: scalein .25s ease-in-out;
}
body.scaleout {
animation: scaleout .25s ease-in-out;
}
#options {
background: #fff;
display: flex;
flex-direction: column;
overflow: hidden;
}
.options-wrapper {
overflow-y: auto;
}
a {
color: #000;
transition: color .5s;
}
a:hover {
color: #666;
}
a:hover .svg-icon,
.svg-icon:hover {
fill: #000;
}
.svg-inline-wrapper .svg-icon {
pointer-events: none;
}
#options-close-icon .svg-icon {
fill: #666;
transition: fill .5s;
}
#options-close-icon:hover .svg-icon {
fill: #000;
}
#options-close-icon {
display: inline-flex;
cursor: pointer;
position: absolute;
right: 6px;
top: 6px;
}
#options-close-icon .svg-icon {
height: 20px;
width: 20px;
}
#options-title {
font-weight: bold;
background-color: rgb(145, 208, 198);
padding: .75rem 26px .75rem calc(30% + 4px);
font-size: 22px;
letter-spacing: .5px;
position: relative;
min-height: 42px;
box-sizing: border-box;
border-bottom: 1px solid #999;
}
#options-title::before {
content: "";
width: 0;
height: 0;
padding: 0 32px 32px 0;
background: url(/images/icon/32.png);
position: absolute;
left: 26px;
top: 0;
bottom: 0;
margin: auto;
}
.firefox .chromium-only,
.chromium-only.chrome-no-popup-border {
display: none;
}
.block {
display: flex;
align-items: center;
margin: 1em 0;
border-bottom: 1px dotted #ccc;
padding: 0 16px .75em;
position: relative;
}
.options-wrapper .block:last-child {
margin-bottom: 0;
border-bottom: none;
}
.collapsed, .collapsible h1 {
cursor: pointer;
}
.collapsed .items {
display: none;
}
h1 {
min-width: 30%;
width: 30%;
margin: 0;
font-size: 120%;
font-weight: bold;
padding-right: 8px;
box-sizing: border-box;
overflow-wrap: break-word;
}
.items {
min-width: 70%;
width: 70%;
}
label,
.label {
display: flex;
margin: .25ex 0;
align-items: center;
}
.label {
flex-grow: 1;
justify-content: space-between;
}
label > :first-child {
margin-right: 8px;
flex-grow: 1;
transition: text-shadow .1s;
}
label:not([disabled]),
label:not([disabled]) :not([type="number"]):not([type="text"]):not([type="password"]) {
cursor: pointer;
}
label:not([disabled]):hover > :first-child {
text-shadow: 0 0 0.01px rgba(0, 0, 0, .25);
}
input[type=number],
input[type="color"],
select,
.onoffswitch {
width: 60px;
box-sizing: border-box;
flex-shrink: 0;
}
select.cloud-name {
width: auto;
}
button {
text-align: center;
}
input[type=number] {
text-align: right;
}
input[type=number]:invalid,
input[type=text]:invalid {
background-color: rgba(255, 0, 0, 0.1);
color: darkred;
}
input[type="color"] {
box-sizing: border-box;
height: 2em;
}
.iconset {
display: flex;
}
.iconset input {
display: block;
}
.iconset input[type="radio"] {
margin: 2px 4px 0 0;
}
#actions {
justify-content: space-around;
align-items: stretch;
flex-wrap: wrap;
padding: .5em 1em 1em;
white-space: nowrap;
background-color: rgba(0, 0, 0, .05);
margin: 0;
border-top: 1px solid #999;
border-bottom: none;
min-height: min-content; /* workaround for old Chrome ~70 bug when the window height is small */
}
#actions button {
width: auto;
margin-top: .5em;
}
#actions button:not(:last-child) {
margin-right: 4px;
}
[data-cmd="check-updates"] button {
position: relative;
}
.update-in-progress [data-cmd="check-updates"] {
opacity: .5;
pointer-events: none;
}
.update-in-progress #update-progress {
position: absolute;
top: 0;
left: 0;
bottom: 0;
background-color: currentColor;
content: "";
opacity: .35;
}
#updates-installed {
position: absolute;
font-size: 85%;
margin-top: 1px;
}
#updates-installed::after {
content: attr(data-value);
margin-left: .5ex;
font-weight: bold;
}
#updates-installed:not([data-value]),
#updates-installed[data-value=""] {
display: none;
}
#advanced.collapsible.collapsed {
height: 30px;
padding: 0;
margin: 0;
justify-content: center;
}
html:not(.firefox):not(.opera) #updates {
margin-bottom: 0;
}
#advanced.collapsible:not(.collapsed) {
margin-bottom: 0;
}
#advanced.collapsible:not(.collapsed) .collapsible-resizer,
#advanced:not(.collapsible) .collapsible-resizer {
padding-right: 8px;
box-sizing: border-box;
min-width: 30%;
width: 30%;
}
#advanced.collapsible h1 {
width: unset;
padding: 0;
color: #333;
transition: color .5s;
display: inline-flex;
align-items: center;
}
#advanced:not(.collapsible) .collapsible-resizer h1 {
width: unset;
padding: 0;
display: inline-flex;
}
#advanced.collapsible:not(.collapsed) h1:hover {
color: #666;
}
#advanced.collapsible.collapsed h1 {
padding: 0;
color: #666;
}
#advanced.collapsible.collapsed:hover h1 {
color: #333;
}
.collapsible-resizer .svg-icon {
fill: #333;
transition: fill .5s;
height: 16px;
width: 16px;
}
#advanced.collapsible.collapsed .collapsible-resizer .svg-icon,
#advanced.collapsible:not(.collapsed) .collapsible-resizer h1:hover .svg-icon {
fill: #666;
}
#advanced.collapsible.collapsed:hover .collapsible-resizer .svg-icon {
fill: #333;
}
#advanced.collapsible h1 .svg-icon {
margin-left: 2px;
}
#advanced.collapsible.collapsed .is-expanded,
#advanced:not(.collapsible) .collapsible-resizer .svg-icon {
display: none;
}
#advanced.collapsible:not(.collapsed) .is-collapsed {
display: none;
}
.svg-inline-wrapper .svg-icon {
width: 16px;
height: 16px;
fill: #666;
vertical-align: sub;
}
.svg-inline-wrapper:hover .svg-icon {
fill: #000;
}
#message-box.note {
align-items: center;
justify-content: center;
white-space: pre-wrap;
}
#message-box.note > div {
max-width: 40em;
top: unset;
right: unset;
position: relative;
}
/* radio group */
.radio-group-item {
display: flex;
align-items: center;
min-height: 1.5em;
}
.radio-group-item > input {
margin: 0 8px 0 0;
flex-grow: 0;
}
.radio-group-label {
display: block;
margin: 0 0 .3em;
}
.input-sm {
width: 3em;
}
/* pixel perfect radio */
input[type="radio"].radio::after {
position: absolute;
top: -1px;
right: -1px;
bottom: -1px;
left: -1px;
height: auto;
width: auto;
transform: scale(0);
}
input[type="radio"].radio:checked::after {
transform: scale(.65);
}
@keyframes fadeinout {
0% { opacity: 0 }
10% { opacity: 1 }
25% { opacity: 1 }
100% { opacity: 0 }
}
@media (hover: none) {
.expanded-note {
font-size: 90%;
white-space: normal;
color: #666;
margin-top: .5em;
hyphens: auto;
}
}
.sync-status {
width: 0; /* together with flex-grow makes it reuse the current width */
flex-grow: 1;
padding-right: 8px;
box-sizing: border-box;
}
.sync-status::first-letter {
text-transform: uppercase;
}
.sync-options .drive-options {
margin: 0;
padding: 0;
border: 0;
}
.drive-options > :not([hidden]) {
display: table;
width: 100%;
}
.drive-options > * > label {
display: table-row;
}
.drive-options > * > label > * {
display: table-cell;
}
.drive-options > * input {
width: 100%;
box-sizing: border-box;
}
.sync-options .actions button {
margin-top: .5em;
}
@keyframes scalein {
0% {
transform: scale3d(.3, .3, .3);
}
100% {
transform: scale3d(1, 1, 1);
}
}
@keyframes scaleout {
100% {
transform: scale3d(0, 0, 0);
}
}

View File

@ -1,303 +0,0 @@
/* global API msg */// msg.js
/* global prefs */
/* global t */// localization.js
/* global
$
$$
$create
$createLink
getEventKeyName
messageBoxProxy
setupLivePrefs
*/// dom.js
/* global
CHROME
CHROME_POPUP_BORDER_BUG
FIREFOX
OPERA
URLS
capitalize
ignoreChromeError
openURL
*/// toolbox.js
'use strict';
setupLivePrefs();
$$('input[min], input[max]').forEach(enforceInputRange);
if (CHROME_POPUP_BORDER_BUG) {
const borderOption = $('.chrome-no-popup-border');
if (borderOption) {
borderOption.classList.remove('chrome-no-popup-border');
}
}
// collapse #advanced block in Chrome pre-66 (classic chrome://extensions UI)
if (!FIREFOX && !OPERA && CHROME < 66) {
const block = $('#advanced');
$('h1', block).onclick = event => {
event.preventDefault();
block.classList.toggle('collapsed');
const isCollapsed = block.classList.contains('collapsed');
const visibleToggle = $(isCollapsed ? '.is-collapsed' : '.is-expanded', block);
visibleToggle.focus();
};
block.classList.add('collapsible', 'collapsed');
}
if (FIREFOX && 'update' in (chrome.commands || {})) {
$('[data-cmd="open-keyboard"]').classList.remove('chromium-only');
}
// actions
$('#options-close-icon').onclick = () => {
top.dispatchEvent(new CustomEvent('closeOptions'));
};
document.onclick = e => {
const target = e.target.closest('[data-cmd]');
if (!target) {
return;
}
// prevent double-triggering in case a sub-element was clicked
e.stopPropagation();
switch (target.dataset.cmd) {
case 'open-manage':
API.openManage();
break;
case 'check-updates':
checkUpdates();
break;
case 'open-keyboard':
if (FIREFOX) {
customizeHotkeys();
} else {
openURL({url: URLS.configureCommands});
}
e.preventDefault();
break;
case 'reset':
$$('input')
.filter(input => prefs.knownKeys.includes(input.id))
.forEach(input => prefs.reset(input.id));
break;
}
};
// sync to cloud
(() => {
const elCloud = $('.sync-options .cloud-name');
const elStart = $('.sync-options .connect');
const elStop = $('.sync-options .disconnect');
const elSyncNow = $('.sync-options .sync-now');
const elStatus = $('.sync-options .sync-status');
const elLogin = $('.sync-options .sync-login');
const elDriveOptions = $('.sync-options .drive-options');
/** @type {Sync.Status} */
let status = {};
msg.onExtension(e => {
if (e.method === 'syncStatusUpdate') {
setStatus(e.status);
}
});
API.sync.getStatus()
.then(setStatus);
elCloud.on('change', updateButtons);
for (const [btn, fn] of [
[elStart, async () => {
await API.sync.setDriveOptions(elCloud.value, getDriveOptions());
await API.sync.start(elCloud.value);
}],
[elStop, API.sync.stop],
[elSyncNow, API.sync.syncNow],
[elLogin, async () => {
await API.sync.login();
await API.sync.syncNow();
}],
]) {
btn.on('click', e => {
if (getEventKeyName(e) === 'MouseL') {
fn();
}
});
}
function getDriveOptions() {
const result = {};
for (const el of $$(`[data-drive=${elCloud.value}] [data-option]`)) {
result[el.dataset.option] = el.value;
}
return result;
}
function setDriveOptions(options) {
for (const el of $$(`[data-drive=${elCloud.value}] [data-option]`)) {
el.value = options[el.dataset.option] || '';
}
}
function setStatus(newStatus) {
status = newStatus;
updateButtons();
}
async function updateButtons() {
const {state, STATES} = status;
const isConnected = state === STATES.connected;
const isDisconnected = state === STATES.disconnected;
if (status.currentDriveName) {
elCloud.value = status.currentDriveName;
}
for (const [el, enable] of [
[elCloud, isDisconnected],
[elDriveOptions, isDisconnected],
[elStart, isDisconnected && elCloud.value !== 'none'],
[elStop, isConnected && !status.syncing],
[elSyncNow, isConnected && !status.syncing && status.login],
]) {
el.disabled = !enable;
}
elStatus.textContent = getStatusText();
elLogin.hidden = !isConnected || status.login;
for (const el of elDriveOptions.children) {
el.hidden = el.dataset.drive !== elCloud.value;
}
setDriveOptions(await API.sync.getDriveOptions(elCloud.value));
}
function getStatusText() {
if (status.syncing) {
const {phase, loaded, total} = status.progress || {};
return phase
? t(`optionsSyncStatus${capitalize(phase)}`, [loaded + 1, total], false) ||
`${phase} ${loaded} / ${total}`
: t('optionsSyncStatusSyncing');
}
const {state, errorMessage, STATES} = status;
if (errorMessage && (state === STATES.connected || state === STATES.disconnected)) {
return errorMessage;
}
if (state === STATES.connected && !status.login) {
return t('optionsSyncStatusRelogin');
}
return t(`optionsSyncStatus${capitalize(state)}`, null, false) || state;
}
})();
function checkUpdates() {
let total = 0;
let checked = 0;
let updated = 0;
const maxWidth = $('#update-progress').parentElement.clientWidth;
chrome.runtime.onConnect.addListener(function onConnect(port) {
if (port.name !== 'updater') return;
port.onMessage.addListener(observer);
chrome.runtime.onConnect.removeListener(onConnect);
});
API.updater.checkAllStyles({observe: true});
function observer(info) {
if ('count' in info) {
total = info.count;
document.body.classList.add('update-in-progress');
} else if (info.updated) {
updated++;
checked++;
} else if (info.error) {
checked++;
} else if (info.done) {
document.body.classList.remove('update-in-progress');
}
$('#update-progress').style.width = Math.round(checked / total * maxWidth) + 'px';
$('#updates-installed').dataset.value = updated || '';
}
}
function customizeHotkeys() {
// command name -> i18n id
const hotkeys = new Map([
['_execute_browser_action', 'optionsCustomizePopup'],
['openManage', 'openManage'],
['styleDisableAll', 'disableAllStyles'],
]);
messageBoxProxy.show({
title: t('shortcutsNote'),
contents: [
$create('table',
[...hotkeys.entries()].map(([cmd, i18n]) =>
$create('tr', [
$create('td', t(i18n)),
$create('td',
$create('input', {
id: 'hotkey.' + cmd,
type: 'search',
//placeholder: t('helpKeyMapHotkey'),
})),
]))),
],
className: 'center',
buttons: [t('confirmClose')],
onshow(box) {
const ids = [];
for (const cmd of hotkeys.keys()) {
const id = 'hotkey.' + cmd;
ids.push(id);
$('#' + id).oninput = onInput;
}
setupLivePrefs(ids);
$('button', box).insertAdjacentElement('beforebegin',
$createLink(
'https://developer.mozilla.org/Add-ons/WebExtensions/manifest.json/commands#Key_combinations',
t('helpAlt')));
},
});
function onInput() {
const name = this.id.split('.')[1];
const shortcut = this.value.trim();
if (!shortcut) {
browser.commands.reset(name).catch(ignoreChromeError);
this.setCustomValidity('');
return;
}
try {
browser.commands.update({name, shortcut}).then(
() => this.setCustomValidity(''),
err => this.setCustomValidity(err)
);
} catch (err) {
this.setCustomValidity(err);
}
}
}
function enforceInputRange(element) {
const min = Number(element.min);
const max = Number(element.max);
const doNotify = () => element.dispatchEvent(new Event('change', {bubbles: true}));
const onChange = ({type}) => {
if (type === 'input' && element.checkValidity()) {
doNotify();
} else if (type === 'change' && !element.checkValidity()) {
element.value = Math.max(min, Math.min(max, Number(element.value)));
doNotify();
}
};
element.on('change', onChange);
element.on('input', onChange);
}
window.onkeydown = event => {
if (getEventKeyName(event) === 'Escape') {
top.dispatchEvent(new CustomEvent('closeOptions'));
}
};

288
dist/popup.html vendored
View File

@ -1,288 +0,0 @@
<!DOCTYPE html>
<html id="stylus">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="global.css">
<template data-id="style">
<div class="entry">
<div class="entry-content">
<div class="main-controls">
<label class="style-name">
<div class="checkmate">
<input class="checker" type="checkbox">
<svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>
</div>
</label>
</div>
<div class="actions">
<a class="configure" i18n-title="configureStyle" tabindex="0">
<svg class="svg-icon config"><use xlink:href="#svg-icon-config"></use></svg>
</a>
<a class="style-edit-link" href="edit.html" i18n-title="editStyleLabel">
<svg class="svg-icon edit" viewBox="0 0 14 16">
<path fill-rule="evenodd" d="M0 12v3h3l8-8-3-3-8 8zm3 2H1v-2h1v1h1v1zm10.3-9.3L12 6 9 3l1.3-1.3a.996.996 0 0 1 1.41 0l1.59 1.59c.39.39.39 1.02 0 1.41z"/>
</svg>
</a>
<a class="menu-button" i18n-title="popupMenuButtonTooltip" tabindex="0">
<svg class="svg-icon menu-button-icon" viewBox="0 0 3 16">
<path fill-rule="evenodd" d="M0 2.5a1.5 1.5 0 1 0 3 0 1.5 1.5 0 0 0-3 0zm0 5a1.5 1.5 0 1 0 3 0 1.5 1.5 0 0 0-3 0zM1.5 14a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z"/>
</svg>
</a>
</div>
</div>
<div class="menu">
<div class="menu-items-wrapper">
<b class="menu-title"></b>
<label class="menu-item exclude-by-domain button">
<div class="menu-icon">
<div class="checkbox-container">
<input type="checkbox" class="exclude-by-domain-checkbox">
<svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>
</div>
</div>
<span i18n-text="excludeStyleByDomainLabel"></span>
</label>
<label class="menu-item exclude-by-url button">
<div class="menu-icon">
<div class="checkbox-container">
<input type="checkbox" class="exclude-by-url-checkbox">
<svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>
</div>
</div>
<span i18n-text="excludeStyleByUrlLabel"></span>
</label>
<div class="menu-buttons-wrapper">
<button class="delete" i18n-text="deleteStyleLabel"></button>
<button class="menu-close" i18n-text="confirmClose"></button>
</div>
</div>
</div>
</div>
</template>
<template data-id="writeStyle">
<a class="write-style-link"></a>
</template>
<template data-id="noStyles">
<div id="no-styles" i18n-text="noStylesForSite"></div>
</template>
<template data-id="regexpProblemIndicator">
<div class="regexp-problem-indicator" i18n-title="styleRegexpProblemTooltip"></div>
</template>
<template data-id="regexpProblemExplanation">
<div id="regexp-explanation">
<div id="regexp-partial" i18n-html="styleRegexpPartialExplanation"></div>
<div id="regexp-invalid" i18n-text="styleRegexpInvalidExplanation"></div>
<button i18n-text="confirmOK"></button>
</div>
</template>
<template data-id="unavailableInfo">
<div class="blocked-info">
<label i18n-text="stylusUnavailableForURL"></label>
<p i18n-text="stylusUnavailableForURLdetails"></p>
</div>
</template>
<template data-id="unreachableInfo">
<div class="blocked-info">
<div class="copy-message" i18n-text="copied"></div>
<label i18n-text="unreachableContentScript"></label>
</div>
</template>
<template data-id="searchResult">
<div class="search-result">
<a class="search-result-title"><span></span></a>
<div class="search-result-info">
<img class="search-result-screenshot" i18n-title="installButton">
<div class="search-result-status"></div>
<div class="search-result-actions">
<button class="search-result-install" i18n-text="installButton"></button>
<button class="search-result-uninstall" i18n-text="deleteStyleLabel"></button>
<button class="search-result-customize" i18n-text="configureStyle"></button>
</div>
<dl class="search-result-meta">
<div data-type="author">
<dt i18n-text="author"></dt>
<dd><a target="_blank" i18n-title="author"></a></dd>
</div>
<div data-type="rating">
<dt i18n-text="searchResultRating"></dt>
<dd i18n-title="searchResultRating"></dd>
</div>
<div data-type="updated">
<dt i18n-text="searchResultUpdated"></dt>
<dd i18n-title="searchResultUpdated"><time></time></dd>
</div>
<div data-type="weekly">
<dt i18n-text="searchResultWeeklyCount"></dt>
<dd i18n-title="searchResultWeeklyCount"></dd>
</div>
<div data-type="total">
<dt i18n-text="searchResultInstallCount"></dt>
<dd i18n-title="searchResultInstallCount"></dd>
</div>
</dl>
<div class="search-result-description"></div>
</div>
</div>
</template>
<template data-id="searchNav">
<div>
<button data-type="prev" i18n-title="paginationPrevious" disabled></button>
<label>
<span data-type="page" i18n-title="paginationCurrent">-</span>
/
<span data-type="total" i18n-title="paginationEstimated">-</span>
</label>
<button data-type="next" i18n-title="paginationNext" disabled></button>
</div>
</template>
<template data-id="emptySearchResult">
<div class="search-result-empty"></div>
</template>
<template data-id="searchResultNotMatching">
<p class="not-matching-explainer"
i18n-text="searchResultNotMatching"
i18n-title="searchResultNotMatchingNote"></p>
</template>
<script src="js/polyfill.js"></script>
<script src="js/msg.js"></script>
<script src="js/toolbox.js"></script>
<script src="popup/preinit.js"></script>
<script src="js/prefs.js"></script>
<script src="js/dom.js"></script>
<script src="js/localization.js"></script>
<script src="content/style-injector.js"></script>
<script src="content/apply.js"></script>
<link rel="stylesheet" href="popup/popup.css">
</head>
<body id="stylus-popup">
<div id="confirm">
<div>
<b>Style's Name</b>
<span i18n-text="deleteStyleConfirm"></span>
<div>
<button i18n-text="confirmDelete" data-cmd="ok"></button>
<button i18n-text="confirmCancel" data-cmd="cancel"></button>
</div>
</div>
</div>
<div id="installed">
<aside id="hotkey-info" i18n-title="popupHotkeysTooltip"></aside>
</div>
<div class="actions">
<div id="disable-all-wrapper">
<div class="main-controls">
<label id="disableAll-label" i18n-text="disableAllStyles">
<input id="disableAll" type="checkbox">
<svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>
</label>
</div>
</div>
<div class="main-controls">
<div id="find-styles">
<a id="find-styles-link" i18n-text="findStyles" i18n-title="findStylesForSite"
href="https://to.be.replaced.on.click/" target="_blank"></a>
<span id="find-styles-inline-group">
<label i18n-title="findStylesInlineTooltip">
<input id="popup.findStylesInline" class="checker" type="checkbox">
<svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>
<span i18n-text="findStylesInline"></span>
</label>
</span>
</div>
<div id="write-style">
<a id="write-for-frames" title="&lsaquo;iframe&rsaquo;..." tabindex="0" hidden></a>
<span id="write-style-for" i18n-text="writeStyleFor"></span>
</div>
</div>
<!-- Actions -->
<div id="popup-options">
<button id="popup-manage-button" i18n-text="openManage"
data-href="manage.html" i18n-title="popupManageTooltip"></button>
<button id="popup-options-button" i18n-text="openOptions"></button>
<button id="popup-wiki-button"
i18n-text="linkStylusWiki"
i18n-title="linkGetHelp"
data-href="https://github.com/openstyles/stylus/wiki"></button>
</div>
</div>
<div id="search-results-error" class="hidden"></div>
<div id="search-results" class="hidden">
<div class="search-results-nav" data-type="top"></div>
<div id="search-params">
<input id="search-query" type="search" i18n-placeholder="search"
i18n-title="searchStyleQueryHint">
<div class="select-resizer">
<select id="search-order" i18n-title="sortStylesHelpTitle">
<option value="n" i18n-text="genericTitle">
<option value="u" i18n-text="searchResultUpdated">
<option value="t" i18n-text="searchResultInstallCount">
<option value="w" i18n-text="searchResultWeeklyCount">
<option value="r" i18n-text="searchResultRating">
</select>
<svg class="svg-icon select-arrow"><use xlink:href="#svg-icon-select-arrow"/></svg>
</div>
<label>
<span class="checkbox-container">
<input id="search-globals" type="checkbox" checked>
<svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>
</span>
<span i18n-text="searchGlobalStyles"></span>
</label>
</div>
<div id="search-results-list"></div>
<div class="search-results-nav" data-type="bottom"></div>
</div>
<!-- Here we can use the above elements before DOMContentLoaded -->
<script src="popup/events.js"></script>
<script src="popup/popup.js"></script>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none !important;">
<symbol id="svg-icon-checked" viewBox="0 0 1000 1000">
<path fill-rule="evenodd" d="M983.2,184.3L853,69.8c-4-3.5-9.3-5.3-14.5-5c-5.3,0.4-10.3,2.8-13.8,6.8L352.3,609.2L184.4,386.9c-3.2-4.2-8-7-13.2-7.8c-5.3-0.8-10.6,0.6-14.9,3.9L18,487.5c-8.8,6.7-10.6,19.3-3.9,28.1L325,927.2c3.6,4.8,9.3,7.7,15.3,8c0.2,0,0.5,0,0.7,0c5.8,0,11.3-2.5,15.1-6.8L985,212.6C992.3,204.3,991.5,191.6,983.2,184.3z"/>
</symbol>
<symbol id="svg-icon-select-arrow" viewBox="0 0 1792 1792">
<path fill-rule="evenodd" d="M1408 704q0 26-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45t19-45 45-19h896q26 0 45 19t19 45z"/>
</symbol>
<symbol id="svg-icon-config" viewBox="0 0 16 16">
<path d="M13.3,12.8l1.5-2.6l-2.2-1.5c0-0.2,0.1-0.5,0.1-0.7c0-0.2,0-0.5-0.1-0.7l2.2-1.5l-1.5-2.6l-2.4,1.2 c-0.4-0.3-0.8-0.5-1.2-0.7L9.5,1h-3L6.3,3.7C5.9,3.8,5.5,4.1,5.1,4.4L2.7,3.2L1.2,5.8l2.2,1.5c0,0.2-0.1,0.5-0.1,0.7 c0,0.2,0,0.5,0.1,0.7l-2.2,1.5l1.5,2.6l2.4-1.2c0.4,0.3,0.8,0.5,1.2,0.7L6.5,15h3l0.2-2.7c0.4-0.2,0.8-0.4,1.2-0.7L13.3,12.8z M8,10.3c-1.3,0-2.3-1-2.3-2.3c0-1.3,1-2.3,2.3-2.3c1.3,0,2.3,1,2.3,2.3C10.3,9.3,9.3,10.3,8,10.3z"/>
</symbol>
<symbol id="svg-icon-config-uso" viewBox="0 0 20 20">
<path d="M4,4h5v2H6v8h8v-3h2v5H4V4z M11,3h6v6l-2-2l-4,4L9,9l4-4L11,3z"/>
</symbol>
<symbol id="svg-icon-help" viewBox="0 0 14 16">
<title i18n-text="helpAlt"></title>
<path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path>
</symbol>
</svg>
</body>
</html>

View File

@ -1,99 +0,0 @@
## codemirror v5.63.3
Following files are copied from npm (node_modules):
* addon\comment\comment.js
* addon\dialog
* addon\edit\closebrackets.js
* addon\edit\matchbrackets.js
* addon\fold\brace-fold.js
* addon\fold\comment-fold.js
* addon\fold\foldcode.js
* addon\fold\foldgutter.css
* addon\fold\foldgutter.js
* addon\fold\indent-fold.js
* addon\hint\css-hint.js
* addon\hint\show-hint.css
* addon\hint\show-hint.js
* addon\lint\css-lint.js
* addon\lint\json-lint.js
* addon\lint\lint.css
* addon\lint\lint.js
* addon\scroll\annotatescrollbar.js
* addon\search\matchesonscrollbar.css
* addon\search\matchesonscrollbar.js
* addon\search\searchcursor.js
* addon\selection\active-line.js
* keymap\emacs.js
* keymap\sublime.js
* keymap\vim.js
* lib\codemirror.css
* lib\codemirror.js
* mode\css
* mode\javascript
* mode\stylus
* theme\3024-day.css
* theme\3024-night.css
* theme\abbott.css
* theme\abcdef.css
* theme\ambiance-mobile.css
* theme\ambiance.css
* theme\ayu-dark.css
* theme\ayu-mirage.css
* theme\base16-dark.css
* theme\base16-light.css
* theme\bespin.css
* theme\blackboard.css
* theme\cobalt.css
* theme\colorforth.css
* theme\darcula.css
* theme\dracula.css
* theme\duotone-dark.css
* theme\duotone-light.css
* theme\eclipse.css
* theme\elegant.css
* theme\erlang-dark.css
* theme\gruvbox-dark.css
* theme\hopscotch.css
* theme\icecoder.css
* theme\idea.css
* theme\isotope.css
* theme\juejin.css
* theme\lesser-dark.css
* theme\liquibyte.css
* theme\lucario.css
* theme\material-darker.css
* theme\material-ocean.css
* theme\material-palenight.css
* theme\material.css
* theme\mbo.css
* theme\mdn-like.css
* theme\midnight.css
* theme\monokai.css
* theme\moxer.css
* theme\neat.css
* theme\neo.css
* theme\night.css
* theme\nord.css
* theme\oceanic-next.css
* theme\panda-syntax.css
* theme\paraiso-dark.css
* theme\paraiso-light.css
* theme\pastel-on-dark.css
* theme\railscasts.css
* theme\rubyblue.css
* theme\seti.css
* theme\shadowfox.css
* theme\solarized.css
* theme\ssms.css
* theme\the-matrix.css
* theme\tomorrow-night-bright.css
* theme\tomorrow-night-eighties.css
* theme\ttcn.css
* theme\twilight.css
* theme\vibrant-ink.css
* theme\xq-dark.css
* theme\xq-light.css
* theme\yeti.css
* theme\yonce.css
* theme\zenburn.css

View File

@ -1,41 +0,0 @@
/*
Name: 3024 day
Author: Jan T. Sott (http://github.com/idleberg)
CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
*/
.cm-s-3024-day.CodeMirror { background: #f7f7f7; color: #3a3432; }
.cm-s-3024-day div.CodeMirror-selected { background: #d6d5d4; }
.cm-s-3024-day .CodeMirror-line::selection, .cm-s-3024-day .CodeMirror-line > span::selection, .cm-s-3024-day .CodeMirror-line > span > span::selection { background: #d6d5d4; }
.cm-s-3024-day .CodeMirror-line::-moz-selection, .cm-s-3024-day .CodeMirror-line > span::-moz-selection, .cm-s-3024-day .CodeMirror-line > span > span::selection { background: #d9d9d9; }
.cm-s-3024-day .CodeMirror-gutters { background: #f7f7f7; border-right: 0px; }
.cm-s-3024-day .CodeMirror-guttermarker { color: #db2d20; }
.cm-s-3024-day .CodeMirror-guttermarker-subtle { color: #807d7c; }
.cm-s-3024-day .CodeMirror-linenumber { color: #807d7c; }
.cm-s-3024-day .CodeMirror-cursor { border-left: 1px solid #5c5855; }
.cm-s-3024-day span.cm-comment { color: #cdab53; }
.cm-s-3024-day span.cm-atom { color: #a16a94; }
.cm-s-3024-day span.cm-number { color: #a16a94; }
.cm-s-3024-day span.cm-property, .cm-s-3024-day span.cm-attribute { color: #01a252; }
.cm-s-3024-day span.cm-keyword { color: #db2d20; }
.cm-s-3024-day span.cm-string { color: #fded02; }
.cm-s-3024-day span.cm-variable { color: #01a252; }
.cm-s-3024-day span.cm-variable-2 { color: #01a0e4; }
.cm-s-3024-day span.cm-def { color: #e8bbd0; }
.cm-s-3024-day span.cm-bracket { color: #3a3432; }
.cm-s-3024-day span.cm-tag { color: #db2d20; }
.cm-s-3024-day span.cm-link { color: #a16a94; }
.cm-s-3024-day span.cm-error { background: #db2d20; color: #5c5855; }
.cm-s-3024-day .CodeMirror-activeline-background { background: #e8f2ff; }
.cm-s-3024-day .CodeMirror-matchingbracket { text-decoration: underline; color: #a16a94 !important; }

View File

@ -1,39 +0,0 @@
/*
Name: 3024 night
Author: Jan T. Sott (http://github.com/idleberg)
CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
*/
.cm-s-3024-night.CodeMirror { background: #090300; color: #d6d5d4; }
.cm-s-3024-night div.CodeMirror-selected { background: #3a3432; }
.cm-s-3024-night .CodeMirror-line::selection, .cm-s-3024-night .CodeMirror-line > span::selection, .cm-s-3024-night .CodeMirror-line > span > span::selection { background: rgba(58, 52, 50, .99); }
.cm-s-3024-night .CodeMirror-line::-moz-selection, .cm-s-3024-night .CodeMirror-line > span::-moz-selection, .cm-s-3024-night .CodeMirror-line > span > span::-moz-selection { background: rgba(58, 52, 50, .99); }
.cm-s-3024-night .CodeMirror-gutters { background: #090300; border-right: 0px; }
.cm-s-3024-night .CodeMirror-guttermarker { color: #db2d20; }
.cm-s-3024-night .CodeMirror-guttermarker-subtle { color: #5c5855; }
.cm-s-3024-night .CodeMirror-linenumber { color: #5c5855; }
.cm-s-3024-night .CodeMirror-cursor { border-left: 1px solid #807d7c; }
.cm-s-3024-night span.cm-comment { color: #cdab53; }
.cm-s-3024-night span.cm-atom { color: #a16a94; }
.cm-s-3024-night span.cm-number { color: #a16a94; }
.cm-s-3024-night span.cm-property, .cm-s-3024-night span.cm-attribute { color: #01a252; }
.cm-s-3024-night span.cm-keyword { color: #db2d20; }
.cm-s-3024-night span.cm-string { color: #fded02; }
.cm-s-3024-night span.cm-variable { color: #01a252; }
.cm-s-3024-night span.cm-variable-2 { color: #01a0e4; }
.cm-s-3024-night span.cm-def { color: #e8bbd0; }
.cm-s-3024-night span.cm-bracket { color: #d6d5d4; }
.cm-s-3024-night span.cm-tag { color: #db2d20; }
.cm-s-3024-night span.cm-link { color: #a16a94; }
.cm-s-3024-night span.cm-error { background: #db2d20; color: #807d7c; }
.cm-s-3024-night .CodeMirror-activeline-background { background: #2F2F2F; }
.cm-s-3024-night .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }

View File

@ -1,268 +0,0 @@
/*
* abbott.css
* A warm, dark theme for prose and code, with pastels and pretty greens.
*
* Ported from abbott.vim (https://github.com/bcat/abbott.vim) version 2.1.
* Original design and CodeMirror port by Jonathan Rascher.
*
* This theme shares the following color palette with the Vim color scheme.
*
* Brown shades:
* bistre: #231c14
* chocolate: #3c3022
* cocoa: #745d42
* vanilla_cream: #fef3b4
*
* Red shades:
* crimson: #d80450
* cinnabar: #f63f05
*
* Green shades:
* dark_olive: #273900
* forest_green: #24a507
* chartreuse: #a0ea00
* pastel_chartreuse: #d8ff84
*
* Yellow shades:
* marigold: #fbb32f
* lemon_meringue: #fbec5d
*
* Blue shades:
* cornflower_blue: #3f91f1
* periwinkle_blue: #8ccdf0
*
* Magenta shades:
* french_pink: #ec6c99
* lavender: #e6a2f3
*
* Cyan shades:
* zomp: #39a78d
* seafoam_green: #00ff7f
*/
/* Style the UI: */
/* Equivalent to Vim's Normal group. */
.cm-s-abbott.CodeMirror {
background: #231c14 /* bistre */;
color: #d8ff84 /* pastel_chartreuse */;
}
/* Roughly equivalent to Vim's LineNr group. */
.cm-s-abbott .CodeMirror-gutters {
background: #231c14 /* bistre */;
border: none;
}
.cm-s-abbott .CodeMirror-linenumber { color: #fbec5d /* lemon_meringue */; }
.cm-s-abbott .CodeMirror-guttermarker { color: #f63f05 /* cinnabar */; }
/* Roughly equivalent to Vim's FoldColumn group. */
.cm-s-abbott .CodeMirror-guttermarker-subtle { color: #fbb32f /* marigold */; }
/*
* Roughly equivalent to Vim's CursorColumn group. (We use a brighter color
* since Vim's cursorcolumn option highlights a whole column, whereas
* CodeMirror's rule just highlights a thin line.)
*/
.cm-s-abbott .CodeMirror-ruler { border-color: #745d42 /* cocoa */; }
/* Equivalent to Vim's Cursor group in insert mode. */
.cm-s-abbott .CodeMirror-cursor { border-color: #a0ea00 /* chartreuse */; }
/* Equivalent to Vim's Cursor group in normal mode. */
.cm-s-abbott.cm-fat-cursor .CodeMirror-cursor,
.cm-s-abbott .cm-animate-fat-cursor {
/*
* CodeMirror doesn't allow changing the foreground color of the character
* under the cursor, so we can't use a reverse video effect for the cursor.
* Instead, make it semitransparent.
*/
background: rgba(160, 234, 0, 0.5) /* chartreuse */;
}
.cm-s-abbott.cm-fat-cursor .CodeMirror-cursors {
/*
* Boost the z-index so the fat cursor shows up on top of text and
* matchingbracket/matchingtag highlights.
*/
z-index: 3;
}
/* Equivalent to Vim's Cursor group in replace mode. */
.cm-s-abbott .CodeMirror-overwrite .CodeMirror-cursor {
border-bottom: 1px solid #a0ea00 /* chartreuse */;
border-left: none;
width: auto;
}
/* Roughly equivalent to Vim's CursorIM group. */
.cm-s-abbott .CodeMirror-secondarycursor {
border-color: #00ff7f /* seafoam_green */;
}
/* Roughly equivalent to Vim's Visual group. */
.cm-s-abbott .CodeMirror-selected,
.cm-s-abbott.CodeMirror-focused .CodeMirror-selected {
background: #273900 /* dark_olive */;
}
.cm-s-abbott .CodeMirror-line::selection,
.cm-s-abbott .CodeMirror-line > span::selection,
.cm-s-abbott .CodeMirror-line > span > span::selection {
background: #273900 /* dark_olive */;
}
.cm-s-abbott .CodeMirror-line::-moz-selection,
.cm-s-abbott .CodeMirror-line > span::-moz-selection,
.cm-s-abbott .CodeMirror-line > span > span::-moz-selection {
background: #273900 /* dark_olive */;
}
/* Roughly equivalent to Vim's SpecialKey group. */
.cm-s-abbott .cm-tab { color: #00ff7f /* seafoam_green */; }
/* Equivalent to Vim's Search group. */
.cm-s-abbott .cm-searching {
background: #fef3b4 /* vanilla_cream */ !important;
color: #231c14 /* bistre */ !important;
}
/* Style syntax highlighting modes: */
/* Equivalent to Vim's Comment group. */
.cm-s-abbott span.cm-comment {
color: #fbb32f /* marigold */;
font-style: italic;
}
/* Equivalent to Vim's String group. */
.cm-s-abbott span.cm-string,
.cm-s-abbott span.cm-string-2 {
color: #e6a2f3 /* lavender */;
}
/* Equivalent to Vim's Constant group. */
.cm-s-abbott span.cm-number,
.cm-s-abbott span.cm-string.cm-url { color: #f63f05 /* cinnabar */; }
/* Roughly equivalent to Vim's SpecialKey group. */
.cm-s-abbott span.cm-invalidchar { color: #00ff7f /* seafoam_green */; }
/* Equivalent to Vim's Special group. */
.cm-s-abbott span.cm-atom { color: #fef3b4 /* vanilla_cream */; }
/* Equivalent to Vim's Delimiter group. */
.cm-s-abbott span.cm-bracket,
.cm-s-abbott span.cm-punctuation {
color: #fef3b4 /* vanilla_cream */;
}
/* Equivalent Vim's Operator group. */
.cm-s-abbott span.cm-operator { font-weight: bold; }
/* Roughly equivalent to Vim's Identifier group. */
.cm-s-abbott span.cm-def,
.cm-s-abbott span.cm-variable,
.cm-s-abbott span.cm-variable-2,
.cm-s-abbott span.cm-variable-3 {
color: #8ccdf0 /* periwinkle_blue */;
}
/* Roughly equivalent to Vim's Function group. */
.cm-s-abbott span.cm-builtin,
.cm-s-abbott span.cm-property,
.cm-s-abbott span.cm-qualifier {
color: #3f91f1 /* cornflower_blue */;
}
/* Equivalent to Vim's Type group. */
.cm-s-abbott span.cm-type { color: #24a507 /* forest_green */; }
/* Equivalent to Vim's Keyword group. */
.cm-s-abbott span.cm-keyword {
color: #d80450 /* crimson */;
font-weight: bold;
}
/* Equivalent to Vim's PreProc group. */
.cm-s-abbott span.cm-meta { color: #ec6c99 /* french_pink */; }
/* Equivalent to Vim's htmlTagName group (linked to Statement). */
.cm-s-abbott span.cm-tag {
color: #d80450 /* crimson */;
font-weight: bold;
}
/* Equivalent to Vim's htmlArg group (linked to Type). */
.cm-s-abbott span.cm-attribute { color: #24a507 /* forest_green */; }
/* Equivalent to Vim's htmlH1, markdownH1, etc. groups (linked to Title). */
.cm-s-abbott span.cm-header {
color: #d80450 /* crimson */;
font-weight: bold;
}
/* Equivalent to Vim's markdownRule group (linked to PreProc). */
.cm-s-abbott span.cm-hr { color: #ec6c99 /* french_pink */; }
/* Roughly equivalent to Vim's Underlined group. */
.cm-s-abbott span.cm-link { color: #e6a2f3 /* lavender */; }
/* Equivalent to Vim's diffRemoved group. */
.cm-s-abbott span.cm-negative {
background: #d80450 /* crimson */;
color: #231c14 /* bistre */;
}
/* Equivalent to Vim's diffAdded group. */
.cm-s-abbott span.cm-positive {
background: #a0ea00 /* chartreuse */;
color: #231c14 /* bistre */;
font-weight: bold;
}
/* Equivalent to Vim's Error group. */
.cm-s-abbott span.cm-error {
background: #d80450 /* crimson */;
color: #231c14 /* bistre */;
}
/* Style addons: */
/* Equivalent to Vim's MatchParen group. */
.cm-s-abbott span.CodeMirror-matchingbracket {
background: #745d42 /* cocoa */ !important;
color: #231c14 /* bistre */ !important;
font-weight: bold;
}
/*
* Roughly equivalent to Vim's Error group. (Vim doesn't seem to have a direct
* equivalent in its own matchparen plugin, but many syntax highlighting plugins
* mark mismatched brackets as Error.)
*/
.cm-s-abbott span.CodeMirror-nonmatchingbracket {
background: #d80450 /* crimson */ !important;
color: #231c14 /* bistre */ !important;
}
.cm-s-abbott .CodeMirror-matchingtag,
.cm-s-abbott .cm-matchhighlight {
outline: 1px solid #39a78d /* zomp */;
}
/* Equivalent to Vim's CursorLine group. */
.cm-s-abbott .CodeMirror-activeline-background,
.cm-s-abbott .CodeMirror-activeline-gutter {
background: #3c3022 /* chocolate */;
}
/* Equivalent to Vim's CursorLineNr group. */
.cm-s-abbott .CodeMirror-activeline-gutter .CodeMirror-linenumber {
color: #d8ff84 /* pastel_chartreuse */;
font-weight: bold;
}
/* Roughly equivalent to Vim's Folded group. */
.cm-s-abbott .CodeMirror-foldmarker {
color: #f63f05 /* cinnabar */;
text-shadow: none;
}

View File

@ -1,32 +0,0 @@
.cm-s-abcdef.CodeMirror { background: #0f0f0f; color: #defdef; }
.cm-s-abcdef div.CodeMirror-selected { background: #515151; }
.cm-s-abcdef .CodeMirror-line::selection, .cm-s-abcdef .CodeMirror-line > span::selection, .cm-s-abcdef .CodeMirror-line > span > span::selection { background: rgba(56, 56, 56, 0.99); }
.cm-s-abcdef .CodeMirror-line::-moz-selection, .cm-s-abcdef .CodeMirror-line > span::-moz-selection, .cm-s-abcdef .CodeMirror-line > span > span::-moz-selection { background: rgba(56, 56, 56, 0.99); }
.cm-s-abcdef .CodeMirror-gutters { background: #555; border-right: 2px solid #314151; }
.cm-s-abcdef .CodeMirror-guttermarker { color: #222; }
.cm-s-abcdef .CodeMirror-guttermarker-subtle { color: azure; }
.cm-s-abcdef .CodeMirror-linenumber { color: #FFFFFF; }
.cm-s-abcdef .CodeMirror-cursor { border-left: 1px solid #00FF00; }
.cm-s-abcdef span.cm-keyword { color: darkgoldenrod; font-weight: bold; }
.cm-s-abcdef span.cm-atom { color: #77F; }
.cm-s-abcdef span.cm-number { color: violet; }
.cm-s-abcdef span.cm-def { color: #fffabc; }
.cm-s-abcdef span.cm-variable { color: #abcdef; }
.cm-s-abcdef span.cm-variable-2 { color: #cacbcc; }
.cm-s-abcdef span.cm-variable-3, .cm-s-abcdef span.cm-type { color: #def; }
.cm-s-abcdef span.cm-property { color: #fedcba; }
.cm-s-abcdef span.cm-operator { color: #ff0; }
.cm-s-abcdef span.cm-comment { color: #7a7b7c; font-style: italic;}
.cm-s-abcdef span.cm-string { color: #2b4; }
.cm-s-abcdef span.cm-meta { color: #C9F; }
.cm-s-abcdef span.cm-qualifier { color: #FFF700; }
.cm-s-abcdef span.cm-builtin { color: #30aabc; }
.cm-s-abcdef span.cm-bracket { color: #8a8a8a; }
.cm-s-abcdef span.cm-tag { color: #FFDD44; }
.cm-s-abcdef span.cm-attribute { color: #DDFF00; }
.cm-s-abcdef span.cm-error { color: #FF0000; }
.cm-s-abcdef span.cm-header { color: aquamarine; font-weight: bold; }
.cm-s-abcdef span.cm-link { color: blueviolet; }
.cm-s-abcdef .CodeMirror-activeline-background { background: #314151; }

View File

@ -1,5 +0,0 @@
.cm-s-ambiance.CodeMirror {
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}

File diff suppressed because one or more lines are too long

View File

@ -1,44 +0,0 @@
/* Based on https://github.com/dempfi/ayu */
.cm-s-ayu-dark.CodeMirror { background: #0a0e14; color: #b3b1ad; }
.cm-s-ayu-dark div.CodeMirror-selected { background: #273747; }
.cm-s-ayu-dark .CodeMirror-line::selection, .cm-s-ayu-dark .CodeMirror-line > span::selection, .cm-s-ayu-dark .CodeMirror-line > span > span::selection { background: rgba(39, 55, 71, 99); }
.cm-s-ayu-dark .CodeMirror-line::-moz-selection, .cm-s-ayu-dark .CodeMirror-line > span::-moz-selection, .cm-s-ayu-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(39, 55, 71, 99); }
.cm-s-ayu-dark .CodeMirror-gutters { background: #0a0e14; border-right: 0px; }
.cm-s-ayu-dark .CodeMirror-guttermarker { color: white; }
.cm-s-ayu-dark .CodeMirror-guttermarker-subtle { color: #3d424d; }
.cm-s-ayu-dark .CodeMirror-linenumber { color: #3d424d; }
.cm-s-ayu-dark .CodeMirror-cursor { border-left: 1px solid #e6b450; }
.cm-s-ayu-dark.cm-fat-cursor .CodeMirror-cursor { background-color: #a2a8a175 !important; }
.cm-s-ayu-dark .cm-animate-fat-cursor { background-color: #a2a8a175 !important; }
.cm-s-ayu-dark span.cm-comment { color: #626a73; }
.cm-s-ayu-dark span.cm-atom { color: #ae81ff; }
.cm-s-ayu-dark span.cm-number { color: #e6b450; }
.cm-s-ayu-dark span.cm-comment.cm-attribute { color: #ffb454; }
.cm-s-ayu-dark span.cm-comment.cm-def { color: rgba(57, 186, 230, 80); }
.cm-s-ayu-dark span.cm-comment.cm-tag { color: #39bae6; }
.cm-s-ayu-dark span.cm-comment.cm-type { color: #5998a6; }
.cm-s-ayu-dark span.cm-property, .cm-s-ayu-dark span.cm-attribute { color: #ffb454; }
.cm-s-ayu-dark span.cm-keyword { color: #ff8f40; }
.cm-s-ayu-dark span.cm-builtin { color: #e6b450; }
.cm-s-ayu-dark span.cm-string { color: #c2d94c; }
.cm-s-ayu-dark span.cm-variable { color: #b3b1ad; }
.cm-s-ayu-dark span.cm-variable-2 { color: #f07178; }
.cm-s-ayu-dark span.cm-variable-3 { color: #39bae6; }
.cm-s-ayu-dark span.cm-type { color: #ff8f40; }
.cm-s-ayu-dark span.cm-def { color: #ffee99; }
.cm-s-ayu-dark span.cm-bracket { color: #f8f8f2; }
.cm-s-ayu-dark span.cm-tag { color: rgba(57, 186, 230, 80); }
.cm-s-ayu-dark span.cm-header { color: #c2d94c; }
.cm-s-ayu-dark span.cm-link { color: #39bae6; }
.cm-s-ayu-dark span.cm-error { color: #ff3333; }
.cm-s-ayu-dark .CodeMirror-activeline-background { background: #01060e; }
.cm-s-ayu-dark .CodeMirror-matchingbracket {
text-decoration: underline;
color: white !important;
}

Some files were not shown because too many files have changed in this diff Show More