Compare commits

..

2462 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
eight
f6e6a138db
Add: webdav sync (#1363) 2021-12-12 03:05:58 +03:00
eight
3ea7e45624
Change: stop revoking google token, change syncErrorRelogin message, recognize token manager errors as grant error (#1362)
* WIP: don't revoke google token, add TokenError

* Fix: stop suggesting disconnecting

* Add: recognize token error as grant error

* Change: sync immediately after re-login
2021-12-09 12:00:38 +08:00
eight
7e3c6f16e9
Fix: bump db-to-cloud, show detailed LockError (#1361)
* Bump db-to-cloud

* Fix: bump db-to-cloud, show detailed LockError

* Fix: used -> use

* Change: drop our retry code
2021-12-09 00:00:30 +08:00
eight
e23077a7ea
Add: support inclusions (#1359)
* Add: support inclusions

* Fix: refresh settings page after configuring in popup
2021-12-08 18:30:16 +08:00
tophf
9ab5369393
autosize textareas in style settings (#1360) 2021-12-07 14:43:21 +03:00
eight
9d1243073b
Add: style settings (#1358)
* Add: style settings

* Change: use radio instead of select for dark/light mode

* Change: x -> Delete

* Change: (in|ex)clusion messages

* Fix: avoid extra space when there is no rule

* Fix: UI in mobile

* Change: delete priority

* Change: use textarea for include/exclude, remove isCodeUpdated

* Fix: separate toggle

* Fix: minor

* Fix: remove codeIsUpdated in styleman
2021-12-07 12:44:49 +08:00
tophf
a59aab73fc enforce plain-text for styleInstallOverwrite
fixes #1357
2021-12-03 15:37:47 +03:00
eight
6c13db1468
Add: toggle dark/night mode styles automatically (#736)
* Add: color-scheme.js

* Add: handle color scheme

* Add: styleManager.setMeta

* Add: make setupLivePrefs work with radio

* Change: drop setupRadioButtons

* Add: UI for schemeSwitcher

* Add: prefer-scheme select in installation page

* Fix: add alarm listener

* Add: display excluded reason in popup

* Fix: rely on data-value-type instead of input name

* Fix: oldValue and newValue should have the same type

* Change: detect media change in content script

* Fix: duplicate capitalize

* Fix: minor

* Update web-ext

* Fix: valueAsNumber doesn't work for all inputs

* Fix: disable colorscheme selection after install

* Fix: API error
2021-12-03 00:49:03 +08:00
tophf
19ebeedf6a
add vars after @import in compiled code (#1348)
fixes #1347
2021-11-14 11:00:12 +03:00
tophf
b17eef4053 allow live-reload on localhost and updates on file://
...if file access is allowed
2021-11-02 18:15:26 +03:00
tophf
7ad3f94697 unbork and simplify applies-to css 2021-10-24 00:11:09 +03:00
tophf
8b67eb885d fix compact usercss height + vcenter fixed header 2021-10-23 23:56:38 +03:00
tophf
707d8bb1a7 parserlib: update transforms 2021-10-21 23:25:32 +03:00
tophf
0034dcb941 preserve installationUrl 2021-10-12 20:26:57 +03:00
tophf
992b89f0eb more stuff in fixKnownProblems
fixes #1342
2021-10-12 20:20:54 +03:00
tophf
37a174b092 CodeMirror 5.63.3 2021-10-12 16:05:21 +03:00
tophf
4243815349 update external urls in manager 2021-10-04 09:46:33 +03:00
tophf
11028bd635 update locales 2021-10-01 17:49:38 +03:00
tophf
dc18320b60 codemirror 5.63.1 2021-10-01 17:48:04 +03:00
tophf
eaef854bcf show iframe "+" only if there's a unique url 2021-09-24 19:18:57 +03:00
tophf
e5807a7823 fix tooltip for iframe "+" 2021-09-24 19:14:34 +03:00
tophf
818031a86b preserve iframe's sender.url 2021-09-24 11:05:55 +03:00
tophf
fce049a911
fix iframe visibility detection (#1336) 2021-09-24 09:43:10 +03:00
tophf
cf0ecbfd4a support EyeDropper API in color picker
Chrome 95+
https://wicg.github.io/eyedropper-api/
2021-09-24 09:40:49 +03:00
tophf
997f1fe8de avoid FOUC for dark themes in applies-to widget 2021-09-21 22:51:18 +03:00
tophf
94f727dc09 avoid startup flicker in applies-to widget 2021-09-21 14:24:17 +03:00
tophf
05bc4301ad 349a8c38 follow-up: stretch editor in compact mode 2021-09-21 10:50:50 +03:00
tophf
58ad6f64d6 focus editor when clicking section name 2021-09-21 10:12:58 +03:00
tophf
349a8c3878 graduate from Quirks mode 2021-09-21 09:43:30 +03:00
tophf
4a0f74764a update regexp report when tab is removed 2021-09-11 15:58:59 +03:00
tophf
dfd8f7a1b1
fix regexp report overflow (#1332) 2021-09-11 15:53:10 +03:00
tophf
59cac7a469 fix USO-archive site search link 2021-09-08 19:13:27 +03:00
tophf
e7d5fff736 use normal warning if typo candidate is empty 2021-09-07 12:42:06 +03:00
tophf
048c267266 parserlib: check @font-face + shorten grammar tokens 2021-09-07 12:36:36 +03:00
tophf
a56676122f
csslint: add "known-pseudos" rule enabled by default (#1328) 2021-09-02 00:12:29 +03:00
tophf
701c30a6c8 fix links in linter help dialog 2021-08-31 17:22:10 +03:00
tophf
a08dd2800d fix objectDiff 2021-08-30 21:15:44 +03:00
Rob Garrison
31dd972c7a 1.5.22 2021-08-30 08:38:44 -05:00
tophf
d84e1bddab update locales 2021-08-30 14:07:47 +03:00
Gusted
d181298e56
Improve issue template (#1319)
* Improve issue template

- Add a CSS section(so I don't have to see those comments about posting CSS etc).
- Make it into more sections and separate them.
- Add notes to each section.

* Apply feedback

* Add restart/profile note

* tweaks

Co-authored-by: narcolepticinsomniac <therealdoctorgonzo@gmail.com>
2021-08-28 15:44:29 -04:00
tophf
2c31dc2af8
installer: show action buttons for installed styles (#1322) 2021-08-26 22:10:08 +03:00
tophf
abced603b4 parserlib: fix ieFunction
fixes #1325
2021-08-26 22:03:30 +03:00
tophf
a5a8d97767 csslint: fix bugs in 'box-model' and 'ids' 2021-08-26 21:01:53 +03:00
tophf
12764baacb parserlib: accept uso-var as ident/string 2021-08-24 14:38:19 +03:00
tophf
b0ed85c5ea use second metablock's @updateURL in USO-archive styles
fixes #1323
2021-08-23 16:27:31 +03:00
tophf
2eeab2c1be openusercss is on an indefinite hiatus 2021-08-22 21:09:47 +03:00
tophf
bfd0d03871 fix #1321 2021-08-22 20:30:09 +03:00
tophf
8ac43fca31
keep the original color format in usercss @var (#1320) 2021-08-22 11:57:35 +03:00
Rob Garrison
32c5e17d08 1.5.21 2021-08-20 08:01:40 -05:00
tophf
95205c70e5 parserlib: check if prop with vars inside is known 2021-08-20 13:03:23 +03:00
tophf
8e36e0277f parserlib: reuse global keywords 2021-08-20 13:01:56 +03:00
tophf
9d6542a39d CodeMirror 5.62.3 2021-08-20 12:16:24 +03:00
tophf
c08747202a fix CSS linting in new CodeMirror
fixes #1317
2021-08-17 22:03:10 +03:00
tophf
6927fa5d70 update translations 2021-08-16 16:59:20 +03:00
Rob Garrison
46b0c9005d 1.5.20 2021-08-15 12:48:52 -05:00
tophf
9722554b3b
show action hints on preview-less search results (#1313)
+ use CSS to control visibility of action buttons
+ avoid mutating DOM unnecessarily in toggleDataset()
2021-08-13 23:03:01 +03:00
Gusted
07291f9486
Add comment to await (#1311) 2021-08-13 13:40:24 +03:00
Gusted
598735fc7b
Fix Firefox's android icon (#1312) 2021-08-13 08:28:50 +03:00
tophf
1e5f118d2d
update USO-archive urls (#1308) 2021-08-12 20:35:56 +03:00
tophf
49af723078 don't let wrapped text flow below the usw icon 2021-08-12 16:56:35 +03:00
tophf
304dcb1489
show installation error inline, allow retrying (#1309) 2021-08-12 16:44:02 +03:00
tophf
434e7ff6c6
rework/simplify external links (#1244)
* rework/simplify external links
* remove title from svg (i) icon as it randomly shows instead of the parent's title
* ensure original element isn't focused when showing modal
* center more help modals
2021-08-12 16:40:27 +03:00
Gusted
2dbccf71db
Prefer webp when available (#1306) 2021-08-12 16:02:48 +03:00
Gusted
ce2250a1f3
clarify purpose of unused rule (#1307) 2021-08-12 15:30:22 +03:00
tophf
50717465b9
show config for usercss vars in installer (#1302)
* simplify messageBox code
* also bind events correctly in case messageBox is called when a messageBox was already shown
2021-08-12 14:40:03 +03:00
tophf
91324a4a48 use center-dialog class for import&history
regressed in a2c8953e which centered the contents too
2021-08-06 19:50:36 +03:00
tophf
6798114196 add buttons to hotkey input, reset on Del/BackSpace 2021-08-06 16:01:55 +03:00
tophf
ba7b55c23d parserlib: add accent-color 2021-08-03 19:45:44 +03:00
tophf
295cb4541c reduce margins for closed details
to provide more space for sections/issues
2021-08-01 21:42:23 +03:00
tophf
b6cc6a09b9 detect typo in metadata when linting
makes use of https://github.com/openstyles/usercss-meta/pull/78
2021-08-01 19:41:52 +03:00
tophf
404efcecf9 unbork max-width for details in compact mode
regressed in 6650a371
2021-08-01 19:28:08 +03:00
tophf
55046ef68c custom version validator is redundant now
...thanks to 4913ba1d2c
2021-08-01 18:38:36 +03:00
tophf
f35bf6a2a5 typo 2021-07-30 17:28:35 +03:00
tophf
c34b054642
refactor usw content script (#1300)
* extract handlers to async functions
* limit event source to the current window
2021-07-30 17:04:15 +03:00
Gusted
e1b65ae21f
Send requested info (#1294) 2021-07-30 15:52:27 +03:00
tophf
6e591b0d52
patchCSP option: allow @import from any URL (#1297) 2021-07-30 15:45:27 +03:00
tophf
6650a37194
tidy up USW-related UI and code (#1285)
* shortened the title to "Publish" and fixed the compact mode
* made collapsed <details> share the same line in compact mode
* made hard-coded strings localizable
* IIFE modules instead of generically named globals
* unified and sorted the names of localized messages
* adjusted spacing of header items
* center auth popup to current window

Co-authored-by: Gusted <williamzijl7@hotmail.com>
2021-07-30 15:44:06 +03:00
tophf
23d86c53a7 properly account for scrollbar in applies-to widget 2021-07-30 15:38:38 +03:00
tophf
ebb5fcafbc show sections on compact->normal layout switch 2021-07-30 07:58:08 +03:00
tophf
39c51435ca avoid recursion when closing regexp tester 2021-07-30 07:37:33 +03:00
tophf
a46bb103c5 update usercss-meta 0.11.0
fixes #1220
2021-07-29 18:54:37 +03:00
tophf
02db1aab6f CM apparently fixed their formula for max-height 2021-07-26 09:48:16 +03:00
tophf
7a0ac57b06 CodeMirror 5.62.2 2021-07-21 15:32:01 +03:00
tophf
33ff2c8373 CodeMirror 5.62.0
skipping 5.62.1 due to a bug in its lint.js
2021-07-21 13:01:39 +03:00
tophf
2d9d0ad1f8 synchronize version 2021-07-21 13:00:27 +03:00
Gusted
61c7d4f08c
Don't rely on _isUswLinked (#1288) 2021-07-20 15:56:45 +03:00
Gusted
69ccdb0591
Show error to user when USw returns error (#1286)
Related USw commit: d4306f2f71

Co-authored-by: tophf <tophf@gmx.com>
2021-07-18 07:25:32 +03:00
Gusted
8abcf9e754
Fix handleSave and sections TOC (#1284) 2021-07-17 02:57:50 +03:00
Rob Garrison
654403eb00 1.5.19 2021-07-15 08:28:07 -05:00
Gusted
ffcdf47ab5
Passing object -> Passing property (#1277)
- Resolves #1276
- Just pass the parameter which is either undefined or an number. No need to get it from a object, while we can just pass the property already.
2021-07-10 04:10:11 -04:00
Rob Garrison
9e9c9061dc 1.5.18 2021-07-07 22:06:55 -05:00
narcolepticinsomniac
ab44c60522
More specific name 2021-07-07 10:07:29 -04:00
narcolepticinsomniac
e8e18abe58
More specific name 2021-07-07 07:51:00 -04:00
Gusted
58fc531515
Fix integration (#1275)
* Fix integration

- Don't use sourceCode as "temporary" value as it's being used as legit value(consider that we delete it after it's non longer needed).
- Wrap the metadata into a `try {}` as some styles doesn't have any metadata.

* Typos adios magios and bonjour gutentag
2021-07-06 18:39:52 -04:00
tophf
44b08dc089
randomize sync interval to avoid infinite deadlocks (#1250)
* randomize sync interval to avoid infinite deadlocks

* autoretry with a randomly increasing delay
2021-07-06 17:19:18 -04:00
Gusted
264544dfa9
Allow dragging the message box (#1274)
* Allow dragging the message box

- Allows the message box to be dragged to any position on the screen, so the user can set it to their wishes.
- Something as discussed in #1270.

* Use CSS to prevent user select

* Remove whitespace

* Imagine wasted new lines

* Make it more niece

* Remove unnecessary check

* Fix calculation code

* cursor: move;

* fixup

* Don't declare variable here

* Cap the move to 30px in each side

* I should pay attention to my english lessons

Co-authored-by: tophf <tophf@gmx.com>
2021-07-06 17:19:00 -04:00
Gusted
a2c8953e63
Use flex to center #message-box (#1271)
* Use flex to center #message-box

- Resolves #1270
- See details on the issue mentioned.

* Use existing .center

* Remove center rule at non-center selector
2021-07-06 17:18:42 -04:00
Gusted
9e72784b2a
Change USw endpoints (#1269)
- Changes the necessary endpoints for OAuth to newer ones that make more sense.
- Related commit on USw: cf6384cf4d
2021-07-01 20:12:24 -04:00
tophf
fa43c6d94d
fix flicker when hovering buttons in popup [Firefox] (#1267) 2021-06-29 05:37:30 -04:00
Gusted
fe45781545
Linking Styles to USW (#1256)
* Prototype

Just able to log the token for the requested style.

* Store USw Token

* Fix linting

* Add revoke capabilities

* Add upload capabilities + UI?

* Add credentials for production server

* Patch up several things

* Send styleInfo

We will be adding the feature to add style based of the currentStyle, see paring commit 31813da300

* Fix clientSecret

* Pass styleInfo trough usw's hook

Related commit on USW: 461ddb03c7

* Adjusted behavior

Applied suggestions from Narco.

* Wait for `usw-ready`before sending style

* don't use `window.`

* Ensure correct style is pre-filled

* Send over metadata

Related USW commit: 7d8c4c1248

* Title Case => Title case

* _linking => _isUswLinked
2021-06-29 05:36:59 -04:00
tophf
ada46e8277 fix bookmarks being orphanized/stranded 2021-06-29 05:45:04 +03:00
tophf
4e87a060f5 use crypto.randomUUID if present 2021-06-17 05:12:25 +03:00
Gusted
83a6808c67
Disable Offscreencanvas for firefox (#1258)
Currently the offscreencanvas is being used for '2d' context, however Firefox doesn't implement this as for now, see: https://searchfox.org/mozilla-central/source/dom/canvas/OffscreenCanvas.cpp#105-110 and it will error out multiple times within the console.
2021-05-31 17:21:17 +03:00
tophf
4bd956f891 don't stretch the table in new browsers
fixes #1255
2021-05-27 18:38:42 +03:00
tophf
367ae56047 reuse openURL so that the opener tab id is set 2021-05-27 14:36:10 +03:00
tophf
18265b94c6 tab url may be empty for about:blank tabs
fixes #1254
2021-05-27 14:35:03 +03:00
Gusted
440a9f4763
Add USw hook to remove get stylus button (#1239) 2021-04-30 16:39:07 +03:00
tophf
d736a00bc1 csslint: allow globals like @import inside sections 2021-04-28 17:33:27 +03:00
tophf
be4fd17113 wait for just created script elements to load
fixes #1233
2021-04-24 16:37:30 +03:00
tophf
b0a03d53fc move lazyKeymaps definition to the base init 2021-04-24 16:26:14 +03:00
tophf
23aa036db5 show USW styles with 'stylus' category 2021-04-20 21:05:49 +03:00
tophf
0aa6d3b463 read css escapes per spec 2021-04-20 20:40:29 +03:00
Gusted
f10ebffeff
Add USw to the inline search and proper installing (#1223)
* remember sort order in popup, use "updated" by default
* add a USW link in the manager

Co-authored-by: tophf <tophf@gmx.com>
2021-04-20 20:40:04 +03:00
tophf
892b295897 CodeMirror 5.61.0 2021-04-20 11:29:24 +03:00
tophf
afcd8ebcf4 prevent FF from double-handling clicks, fixes #1232 2021-04-20 07:22:19 +03:00
tophf
711f6502b5 make transition suppressor rule more robust 2021-04-19 16:09:31 +03:00
Rob Garrison
43f1da1b4c copy policy from app details 2021-04-18 20:15:07 -05:00
Rob Garrison
baca54bf19 Add privacy policy 2021-04-18 20:06:24 -05:00
tophf
0b9b972338 update swatch's lines to match current code 2021-04-08 14:33:36 +03:00
silverwind
a934571dc7
update setup-node plugin to v2 (#1215) 2021-04-08 10:49:24 +03:00
vVde3S88xHW6EZaB63HyXQUipgFtaWooYGDs35g
82d2530669
fix installer for local files in FF (#1224) 2021-04-08 10:45:43 +03:00
tophf
33e7f920a3 fixup: load codemirror-themes.js earlier 2021-04-06 07:10:03 +03:00
tophf
fa2dec724a fix editor theme in FF containers, fixes #1222 2021-04-06 06:56:35 +03:00
tophf
2d5788766a fix Enter key clearing selected text, fixes #1219
regressed in 7a479edc
2021-04-02 07:12:44 +03:00
tophf
8c160ed40c CodeMirror 5.60.0 2021-03-20 14:23:49 +03:00
tophf
ed238183eb revert 4ae2c670's changes for the install button
as it's no longer required after 3f4fb061
2021-03-19 23:02:02 +03:00
tophf
3f4fb0617e reimplement #1192 using dummy links
as omitting href attribute is sufficient to avoid the useless tooltip
2021-03-19 22:53:52 +03:00
tophf
35e0a9d032 avoid FOUC in tabs on update/reload 2021-03-19 19:00:48 +03:00
tophf
21d902c48c deduplicate keys in prefs.subscribe 2021-03-14 20:30:44 +03:00
tophf
a7ae3fbc55 unbork selectByTokens option
...by moving custom options definitions before isEditorPref checks CodeMirror.defaults
2021-03-14 19:44:47 +03:00
tophf
db77e03e97 print stylus-lang's p() to editor console, fixes #894 2021-03-14 10:07:59 +03:00
tophf
692d3c9826
try to show applicable values in autocomplete for props (#1211)
+ restore proper toggling of autocompleteOnTyping
2021-03-14 08:33:26 +03:00
tophf
9531698dd7 show unreachableMozSiteHint on any site in FF
fixes #1210
2021-03-12 08:51:57 +03:00
tophf
9d19d61913
show time/weekday in tooltip for style entries (#1205) 2021-03-11 07:20:38 +03:00
tophf
ff63b84489 add a test for the transition suppressor rule 2021-03-09 19:24:37 +03:00
tophf
4ae2c67033 unbork install button style + dedupe svg-icon
regressed in b8f6f5db
2021-03-06 21:22:24 +03:00
tophf
65ac351699
preserve opacity in colorpicker for preprocessor uso config (#1200)
USO has always produced 6-digit #rrggbb so some styles rely on it
and use /*[[color]]*/11 notation to specify the transparency.
Now we will try to preserve the opacity customized by the user
via colorpicker unless the style specifies it inline.
2021-03-05 17:25:05 +03:00
tophf
7d08fea5e1 followup for 102121ad: apply suppressor on all pages 2021-03-01 08:46:47 +03:00
tophf
8eca4e9139 followup for 4228758c: only input should be clickable 2021-02-28 23:39:09 +03:00
tophf
102121ad8f
suppress transition bug on page open in Chrome, too (#1193) 2021-02-28 23:01:49 +03:00
tophf
4228758cec don't hide the input in onoffswitch
as it wasn't necessary and turns out it causes problems with event routing when the parent <label> includes a <button> which we use now instead of dummy links
2021-02-28 22:58:24 +03:00
tophf
c0eace302f inject styles only in visible frames
fixes #1033
2021-02-28 22:33:16 +03:00
tophf
a56e528b31 trust sender's URL in FF
fixes #1194
2021-02-28 18:01:26 +03:00
tophf
01e2e09fa5 ignore HTTP502 error when syncing 2021-02-28 08:37:56 +03:00
tophf
b8f6f5db8d
switch from dummy links to dummy buttons (#1192)
The reason is that dummy links like <a href="#"> cause the built-in tooltip pop up on hover which is just useless noise
2021-02-27 20:42:49 +03:00
tophf
41533e863d enforce eslint radix rule for parseInt 2021-02-26 13:02:54 +03:00
tophf
53c71614fc relaxed parsing of usercss @version
fixes #821
2021-02-26 10:03:32 +03:00
tophf
9b46da5846
shrink screenshots to make readme readmeable 2021-02-25 10:26:32 +03:00
tophf
81fa6b1e79 avoid a scrollbar due to rounding errors 2021-02-25 10:16:50 +03:00
Rob Garrison
a5d2d96717 1.5.17 2021-02-24 18:34:09 -06:00
tophf
69308d04e9 CodeMirror 5.59.4 2021-02-24 13:41:05 +03:00
tophf
75ae8e79bf replace webext-tx-fix with a local tools script 2021-02-24 13:37:57 +03:00
tophf
14efa1f052 fix locales 2021-02-24 11:27:39 +03:00
Rob Garrison
3e415460c6 1.5.16 2021-02-23 21:37:53 -06:00
Rob Garrison
ea6359307b Update locales 2021-02-23 21:35:26 -06:00
tophf
acaf12f694 ensure button panel is tall enough
see #1188
2021-02-23 15:13:01 +03:00
tophf
abd018d750 fix autocomplete for words starting with d/r/u
fixes #1188
2021-02-23 14:59:56 +03:00
tophf
cf1f51af0a
vivaldi bug workaround: open webAuth flow in a tab (#1186) 2021-02-22 15:12:19 +03:00
tophf
b61cd75b25 ignore style messages if started in disableAll mode 2021-02-22 00:36:40 +03:00
tophf
c5e2baaf87 pass disableAll to styleInjector, fixes #1187 2021-02-22 00:36:37 +03:00
tophf
76ee0992e7 update deps: CM 5.59.3, webAuth 0.1.1 2021-02-21 09:17:33 +03:00
tophf
a674874861 show global styles for frames if main page is blocked
fixes #1183
2021-02-16 17:03:18 +03:00
tophf
58ae4704b2 fix css autocomplete sort order 2021-02-14 21:48:44 +03:00
tophf
3102738cfb
improve linter info and config popup (#1171)
* improve linter info popup

* show rule id so the user can configure it
* add "configure" button to show the linter config UI
* add margins between items
* emphasize active rules in linter config dialog
2021-02-14 20:30:50 +03:00
eight
c17dddb0ee
Fix: less intrusive authorization (#1172)
* Update db-to-cloud

* Change: refactor sync logic, disallow implicit auth

* Add: better relog message in options page

* read prefs only when `ready`
* show the internal error text in icon tooltip
* show the internal error text in options fully
Co-authored-by: tophf <tophf@gmx.com>

* Update _locales/en/messages.json
Co-authored-by: Enrico Lamperti <910672+elamperti@users.noreply.github.com>
2021-02-14 18:24:49 +03:00
tophf
75db3601d0 fix #1177
regressed in fdbfb235
2021-02-10 19:47:07 +03:00
tophf
83adc5aa1e fix #1176 2021-02-10 18:29:34 +03:00
tophf
890ff395c0
use a new solid gear icon everywhere (#1173) 2021-02-10 12:11:52 +03:00
tophf
c00c748c1e simplify/deduplicate badge error logic
also correctly restore the real badge info when error is cleared
2021-02-09 12:53:03 +03:00
tophf
c60c764d34
add: indicate sync error as 'x' in icon badge (#1166)
* indicate sync error as 'x' in icon badge

* fix/simplify

* Add: show more errors on badge

Co-authored-by: eight04 <eight04@gmail.com>
2021-02-09 14:58:30 +08:00
tophf
1746235d0d fix showLintHelp dialog 2021-02-07 00:17:52 +03:00
tophf
94cf673f68 load semver faster, fixes #1167 2021-02-06 19:10:22 +03:00
tophf
ade8d1981b restore getStylesViaXhr check for about:blank frames
regressed in 50959354
2021-02-05 10:51:39 +03:00
tophf
50959354ec wait for next paint in about:blank frames, fixes #1165 2021-02-05 10:35:02 +03:00
tophf
784a1018f8 fixup: call getDateFromVer when updateUrl is set, #1159 2021-02-05 09:50:52 +03:00
tophf
34c067c3be hide USO-archive version in manager
* it's a hard-to-read blob of digits: 2021110.8.46
* it's somewhat redundant as we have the 'update age' column
2021-02-04 14:10:30 +03:00
tophf
c12d3fc5e3 convert USO styles to USO-archive on update 2021-02-04 14:10:30 +03:00
Rob Garrison
272dea01a2 1.5.15 2021-02-03 19:05:23 -06:00
Rob Garrison
5304805c63 Update locales 2021-02-03 19:04:35 -06:00
tophf
8ee964c045 simplify rerouteHotkeys to avoid enabling it twice 2021-02-02 22:49:00 +03:00
tophf
24a0077783 chrome bug: onCommitted is fired twice 2021-02-02 00:40:30 +03:00
tophf
c41a5f92c3 preserve dirty after importing moz-format [v2], fixes #1163 2021-02-02 00:33:56 +03:00
tophf
3a3104b30a update parserlib
* add aspect-ratio, color-adjust, forced-color-adjust
* remove ar units
2021-02-01 19:00:30 +03:00
tophf
afa4a1ac14 restore USO bug workaround for style settings
fixes #1158
2021-01-23 10:14:23 +03:00
tophf
2c9ea4fdc0 CodeMirror update leftovers 2021-01-23 10:14:16 +03:00
tophf
8cabf8a8aa CodeMirror 5.59.2 2021-01-20 14:59:31 +03:00
tophf
02bd682135 ignore executeScript errors e.g. due to frame removal 2021-01-19 09:36:53 +03:00
tophf
a88996be6f restore correct handling of openEditInWindow
regressed in fdbfb235
fixes #1156
2021-01-19 09:27:19 +03:00
tophf
a66a1f8ed6 code cosmetics 2021-01-18 09:50:27 +03:00
tophf
4338f67352 LESS: use math:parens-division
This is the default mode in LESS4.
Fixes #1154.
2021-01-16 09:18:54 +03:00
tophf
914943ed4c remove sliders
* can be already implemented as a userstyle
* will be exposed in usercss config dialog later
2021-01-15 13:24:21 +03:00
tophf
eb5fd90dc7 remember CM bookmarks on reload/revisit 2021-01-12 17:39:24 +03:00
tophf
b00e6d23fe revert CodeMirror to 5.59.0
5.59.1 is bugged https://github.com/codemirror/CodeMirror/issues/6558
2021-01-10 13:44:38 +03:00
tophf
fe176c9b62 [compact layout] show sections TOC on first click 2021-01-09 13:21:06 +03:00
tophf
ac7b33d7e0 fix resizing of last section if page is scrolled 2021-01-07 14:52:38 +03:00
tophf
39e03b0a9f fix autocomplete after var(, autocompleteOnTyping 2021-01-07 14:52:38 +03:00
tophf
312f444ec7 fix 'true' === true check in setupLivePrefs 2021-01-07 14:52:38 +03:00
tophf
1308efb8d0 fix/simplify fitSelectBox 2021-01-07 14:52:38 +03:00
tophf
11d311d1e8 avoid forced layout in highlightEditedStyle 2021-01-07 14:52:38 +03:00
tophf
767b2017e0 wait for main stylesheet to load before forcing layout 2021-01-05 19:54:49 +03:00
tophf
dfb9135f6a stylelint 13.8.0 2021-01-05 18:51:01 +03:00
tophf
7d6b4fc8ac csslint: code cosmetics 2021-01-05 18:27:46 +03:00
tophf
57233db546 csslint: add 'shorthand-overrides' rule 2021-01-05 12:14:26 +03:00
tophf
cb85fe9392 get the full list of stylelint rules 2021-01-04 09:28:59 +03:00
tophf
fd890f8e61 show "Options" heading in options UI 2021-01-02 23:34:42 +03:00
tophf
8807819f16 parserlib: update props 2021-01-01 19:49:38 +03:00
tophf
6563aca141 CodeMirror 5.59.1 + use emptyDirSync instead of shx
+ restore the original jsonlint with its trailing spaces, accidentally fixed by fdbfb235
2021-01-01 18:36:05 +03:00
tophf
d26dd92f44 use .meta.css in update check on greasyfork 2021-01-01 18:20:25 +03:00
tophf
c35302dff6 add margins for updateAllCheckSucceededSomeEdited 2021-01-01 18:20:25 +03:00
tophf
fdbfb23547
API groups + use executeScript for early injection (#1149)
* parserlib: fast section extraction, tweaks and speedups
* csslint: "simple-not" rule
* csslint: enable and fix "selector-newline" rule
* simplify db: resolve with result
* simplify download()
* remove noCode param as it wastes more time/memory on copying
* styleManager: switch style<->data names to reflect their actual contents
* inline method bodies to avoid indirection and enable better autocomplete/hint/jump support in IDE
* upgrade getEventKeyName to handle mouse clicks
* don't trust location.href as it hides text fragment
* getAllKeys is implemented since Chrome48, FF44
* allow recoverable css errors + async'ify usercss.js
* openManage: unminimize windows
* remove the obsolete Chrome pre-65 workaround
* fix temporal dead zone in apply.js
* ff bug workaround for simple editor window
* consistent window scrolling in scrollToEditor and jumpToPos
* rework waitForSelector and collapsible <details>
* blank paint frame workaround for new Chrome
* extract stuff from edit.js and load on demand
* simplify regexpTester::isShown
* move MozDocMapper to sections-util.js
* extract fitSelectBox()
* initialize router earlier
* use helpPopup.close()
* fix autofocus in popups, follow-up to 5bb1b5ef
* clone objects in prefs.get() + cosmetics
* reuse getAll result for INC
2021-01-01 17:27:58 +03:00
tophf
06823bd5b4 CodeMirror 5.59.0 + bump deps 2020-12-22 01:17:56 +03:00
tophf
1e614fa2bc don't count&title removed sections 2020-12-15 01:52:10 +03:00
tophf
7140993e6c parserlib: fix reading \\, regressed in 6d04c0e 2020-12-14 21:18:15 +03:00
tophf
775d77a3a8 clone change positions to avoid breaking CodeMirror 2020-12-10 23:25:07 +03:00
tophf
579750fbc0 fix linting when style was initially error-free
regressed in e6f94378
2020-12-10 11:00:24 +03:00
tophf
0b540fbabd parserlib: up to 10% faster first run
* inline generation of trivial tokens
* remove Tokens.CUSTOM_PROP
* allow fit-content keyword as it's used in the wild
* add color-scheme
* add path()
* don't try to validate props with vars
* auto-compile function grammar
* remove CSS4 color functions
* show full error stack
2020-12-10 01:30:17 +03:00
tophf
75cf46aaa7 fix search-target-editor style 2020-12-08 23:03:13 +03:00
tophf
26a539bd62 fix closestVisible nearby check 2020-12-08 18:50:14 +03:00
tophf
463c3b5139 fix subsequent clicks in colorpicker
seems like new CodeMirror modifies the position object
2020-12-08 14:46:03 +03:00
tophf
6d04c0eb7d optimize parserlib by ~10%
* add skipValidation option
* set `recoverable:true` on errors inside declarations
2020-11-29 15:11:31 +03:00
tophf
e6f94378bf re-enable linter after import + async'ify
regressed in 420733b9
2020-11-29 14:25:07 +03:00
tophf
207afccd65
improve autocomplete (#1136)
* fix interaction when search overlay splits `styles`
* handle @rules and @-moz-document functions
* show props in stylus-lang
2020-11-28 23:29:33 +03:00
tophf
6847681ed3 fix findSections for {} + detect reusedEnd 2020-11-27 15:10:03 +03:00
tophf
a87c49f0fc autoresize embedded popup for config dialogs 2020-11-27 15:09:16 +03:00
tophf
cb64a6bac9 use jumpToPos more, fix coords calc 2020-11-26 17:04:51 +03:00
tophf
6451eb533c switch to styleMissingName 2020-11-26 12:09:11 +03:00
tophf
355f240779 add a suffix in editor title 2020-11-26 12:04:42 +03:00
tophf
a91183e1bb fix scrolling in jumpToPos 2020-11-25 23:28:22 +03:00
tophf
a5848682b3 normalize linebreaks in parseMozFormat 2020-11-24 21:04:11 +03:00
tophf
7c2b46be83 fix PortDownloader::onDisconnect 2020-11-24 17:06:25 +03:00
tophf
c635f2e38c monkeypatch next/prevBookmark commands to use jumpToPos 2020-11-24 15:17:14 +03:00
tophf
657798d219 improve bookmarking + rework codemirror-factory.js
* pull editing-only stuff from codemirror-default.js
* switch throttledSetOption to IntersectionObserver
2020-11-24 13:16:51 +03:00
tophf
b4ca17c531 call rerouteHotkeys when restoring scrollInfo
...because we intentionally don't focus any CM in this case as it's bugged as hell
2020-11-24 13:16:51 +03:00
tophf
32cca90ddd limit button reposition to usercss (8b58b228 fixup) 2020-11-24 12:54:39 +03:00
tophf
8b58b22825 [simple-window editor] embed popup as iframe 2020-11-24 12:16:23 +03:00
tophf
b59737a012 $create: assign style property as a string/object 2020-11-24 12:16:23 +03:00
tophf
eb99101f35 inform if the found style doesn't match site url 2020-11-24 00:07:49 +03:00
tophf
5bb1b5ef35 dedup code for modals in popup 2020-11-24 00:07:49 +03:00
tophf
4d198f56e2 faster popup load to avoid resize flicker 2020-11-24 00:07:49 +03:00
tophf
51f125113d restore top margin for #no-styles after 2bf30ed1 2020-11-23 07:29:30 +03:00
tophf
00ae843f78 unicode-aware word breaking, fixes #1124 2020-11-22 14:53:10 +03:00
tophf
2bf30ed16d
tweaks and fixes (#1123)
* same color for disabled styles in popup/manager
* reduce slider knob
* fix click-to-edit in popup on slider and iframe badge
* indicate slider interactivity on hovering name
* remove 2px gap when first/last entry is striped
* stretch 'blocked' separator to full width
* unreachable dimming should not apply to frames
* restore CWS check in popup
* increase not-applied opacity on name as it's #999 now
* oldUI: restore 'disabled' bubble + show 'usercss' fully
* adjust disabled colors to match perception because transparent text is rendered using gamma-blending whereas colored text uses LCD-antialiasing so to match opacity .6 of #000 we need #888 not #666
2020-11-22 14:09:59 +03:00
tophf
e6988d2f9e update usercss-meta, #1108 2020-11-21 20:35:23 +03:00
tophf
008e33254d add option to use sliders in manager and popup 2020-11-21 10:13:30 +03:00
tophf
3dc684f85f reduce usercss bubble to UC + tweak CSS
* remove 'disabled' bubble
* simplify .style-info
* fix double padding between version and UC
* match manager's font-weight for disabled styles in popup
2020-11-21 10:13:30 +03:00
tophf
17a0bd69c0 fix applies-to expander's collapse-on-click 2020-11-20 18:08:04 +03:00
tophf
70e3ba15b7 use 'default' internally for the default theme element
* the pref won't be influenced by the current UI language
* also reset to 'default' if failed to load the theme's css file
2020-11-20 16:10:15 +03:00
tophf
420480887e update CodeMirror 5.58.3 2020-11-20 09:50:19 +03:00
tophf
1bd366beb9 restore styleSectionsEqual in updater for non-usercss
...which was broken in bc8d8b2
2020-11-19 18:18:05 +03:00
tophf
79cd6da824 increase connection timeout to 60sec 2020-11-19 18:18:05 +03:00
tophf
420733b93a
PatchCSP + tweaks/fixes/features (#1107)
* add Patch CSP option
* show style version, size, and update age in manager
* add scope selector to style search in manager
* keep scroll position and selections in tab's session
* directly install usercss from raw github links
* ditch localStorage, use on-demand SessionStore proxy
* simplify localization
* allow <code> tag in i18n-html
* keep &nbsp; nodes in HTML templates
* API.getAllStyles is actually faster with code untouched
* fix fitToContent when applies-to is taller than window
* dedupe linter.enableForEditor calls
* prioritize visible CMs in refreshOnViewListener
* don't scroll to last style on editing a new one
* delay colorview for invisible CMs
* eslint comma-dangle error + autofix files
* styleViaXhr: also toggle for disableAll pref
* styleViaXhr: allow cookies for sandbox CSP
* simplify notes in options
* simplify getStylesViaXhr
* oldUI fixups:
  * remove separator before 1st applies-to
  * center name bubbles
* fix updateToc focus on a newly added section
* fix fitToContent when cloning section
* remove CSS `contain` as it makes no difference
* replace overrides with declarative CSS + code cosmetics
* simplify adjustWidth and make it work in FF
2020-11-18 14:17:15 +03:00
Rob Garrison
7fa4d10fd6 1.5.14 2020-11-13 19:28:48 -06:00
Rob Garrison
a065039d50 update locales 2020-11-13 19:28:21 -06:00
tophf
0b3e027bfd auto-promisify browser.* methods on call 2020-11-13 20:07:43 +03:00
tophf
3db6662d2f fix 1px shift of applies-to text when favicon is added in FF 2020-11-11 20:42:13 +03:00
tophf
6259cc2e79 speed up manager: render more targets only on demand 2020-11-11 20:27:54 +03:00
tophf
a26115154a fix getPrefs error on browser startup in the active tab 2020-11-11 13:28:20 +03:00
narcolepticinsomniac
da6361637d
Replace USO link 2020-11-10 17:47:23 -05:00
tophf
d183779fb5 accept any content-type for text/ except text/html 2020-11-10 21:40:50 +03:00
tophf
3a8f47f4db revert d405bc64 - obsolete since stylus-lang 0.54.7 2020-11-10 20:40:47 +03:00
tophf
eb70e5a2aa update stylus-lang dependency to 0.54.7 2020-11-10 20:40:47 +03:00
tophf
30b9378d2c use mousewheel to change a focused input[type=range] 2020-11-09 22:59:42 +03:00
tophf
dc4819e7d0
Merge pull request #1101 from tophf/import-prefs
import/export options in backup json
2020-11-09 21:18:23 +03:00
tophf
ff1fa07267 import/export options in backup json
* import options on demand
* auto-grant declarativeContent
* include lint configs and usercss template
* simplify exportFile as crbug.com/798705 was fixed
2020-11-09 21:12:14 +03:00
tophf
7d18376cf2 always use deepCopy for prefs.values for safety 2020-11-09 21:08:50 +03:00
tophf
bc8d8b235c fix equalOrEmpty for empty strings 2020-11-09 21:08:47 +03:00
tophf
a94969e47d remove padding from linter report items
(icons already take care of proper spacing)
2020-11-08 20:29:10 +03:00
tophf
4ac92a4f9b unbork marks in linter report
CodeMirror 5.58+ uses an additional class name for common stuff
2020-11-08 20:29:09 +03:00
tophf
5e5fecbcfe
editor: section labels, TOC, tweaks (#1086)
* section labels, TOC, speedups and fixes

* show section numbers in widgets
* debounce livePreview in usercss editor
* better fixed header and compact layout compatibility
* fix section sizing for compact layout + layout speedup
* DocFuncMapper + cosmetics + fix Clone button
* don't run linter during initSections
* remove unused/unnecessary DOM polyfills
* report invalid @document function as parser error
* rewrite section finder
* simplify focusedViaClick
* simplify setPreprocessor and make it synchronous
* throttle offscreen line widgets in usercss with lots of sections
* add on, off aliases for add/removeEventListener + onOff
* use on/off aliases in changed files
* use getters in more places
2020-11-08 11:12:42 +03:00
tophf
71cabc2029 fix animateElement() when animation is disabled 2020-11-06 21:04:10 +03:00
tophf
aac0f476b2 tweaks/fixes for popup search link
* use a less specific category if the inline search wasn't used yet
* set a href in html to prevent transitions during init
2020-11-05 22:45:22 +03:00
tophf
635fc705f9 correctly clear gutter marks for sublime bookmarks 2020-11-04 17:47:41 +03:00
tophf
31558d5071 we use 'true' and 'false' strings as boolean T_T
fixup for b56dacb
2020-11-04 12:50:24 +03:00
tophf
97ad0753e0 restore direct fetching of styles in the options frame
regressed in bf40fa81
2020-11-02 22:20:41 +03:00
tophf
a997ecbe24 update CSSLint
* fix missing <zero>
* retry/consume attr()
* code cosmetics
2020-11-02 22:08:14 +03:00
tophf
32728b023b respond with null to avoid "port closed" errors 2020-11-01 22:48:42 +03:00
narcolepticinsomniac
ad44fe47c8
typo 2020-11-01 14:06:18 -05:00
narcolepticinsomniac
1c7e06e980
typos 2020-11-01 14:01:44 -05:00
tophf
21d4221df9 position colorpicker correctly, cosmetics (89431615 fixup) 2020-10-31 23:45:52 +03:00
tophf
972a83d5bc restore simpleDeepEqual (b56dacb6 fixup) 2020-10-31 21:00:19 +03:00
silverwind
caec255e16 Simplify CI action
Only run on a single node version, that way you won't get tripe error
annotations, and it's really not neccessary for this repo to test on
multiples anyways.
2020-10-30 08:22:53 +03:00
tophf
72cb5bdc9a don't spam console errors on contextMenu 'delete' command 2020-10-29 00:13:15 +03:00
tophf
b56dacb6b2 save prefs in bg to avoid data loss
* add `now` to simplify usage of prefs.subscribe
* tweak/simplify bits by separating bg/content concerns
2020-10-28 21:10:57 +03:00
tophf
be47cfc471 throttle colorview on page load 2020-10-28 21:05:19 +03:00
tophf
6d7bd650e9 strip stylelint warnings for // comments with @preprocessor 2020-10-28 13:19:17 +03:00
tophf
a81e1b8ac3 async'ify worker-util, reduce indirection 2020-10-28 13:19:17 +03:00
tophf
4764f91453 fix radiateArray when focusing search with extra CMs around 2020-10-28 13:08:00 +03:00
tophf
74364b9d63 hide incremental search textarea, 2a6850c0 fixup 2020-10-27 13:00:32 +03:00
tophf
2747d3930b simplify resizing of editor-in-new-window 2020-10-26 18:04:37 +03:00
tophf
bd3f630617 use a safe regexp for comments 2020-10-26 18:04:37 +03:00
tophf
2a6850c02e avoid scrollbar due to incremental search + subsequent filter 2020-10-26 18:04:36 +03:00
tophf
2c674bdc0c remove the extraneous margin between applies-to 2020-10-26 18:04:35 +03:00
tophf
2ed936af00 don't autojump to first match when opening search 2020-10-26 18:04:34 +03:00
tophf
89431615b3
improve colorpicker dialog (#1079)
* switch to a user-resizable palette
* allow moving
* remove hideDelay
2020-10-26 18:03:41 +03:00
tophf
bf40fa81e8
async'ify msg, don't throw for flow control (#1078) 2020-10-26 17:39:07 +03:00
tophf
1a7b51be6b
warn when paste-importing usercss with @preprocessor, #1082 2020-10-26 17:37:31 +03:00
tophf
4fade0fdfe async'ify replaceStyle 2020-10-26 17:33:23 +03:00
tophf
34ad3cfaef embed replaceSections as replace option of initSections 2020-10-26 17:24:11 +03:00
tophf
92fcb02a57 handle document.cookie exceptions in sandboxed frames 2020-10-26 07:49:08 +03:00
tophf
4eabdf3f57 warn when paste-importing usercss with @preprocessor 2020-10-25 22:36:41 +03:00
tophf
5ba111dce9 update parserlib
* min(), max(), clamp(), also in @media
* add/fix some props and units
* handle `attr()`
* use lowerCmp()
* approve functions with USO vars
2020-10-25 00:24:28 +03:00
tophf
3a615e4e06 CodeMirror 5.58.2 2020-10-23 22:35:14 +03:00
tophf
2af83ee846 remove more -webkit- prefixes 2020-10-23 21:32:02 +03:00
narcolepticinsomniac
8598b71a73
Options tweaks (#1077)
* Options tweaks

* account for last-child change
2020-10-23 09:51:46 -04:00
tophf
595b037ab1 remove unused IS_BG and wrong AMO condition
* the user may have allowed access to AMO via about:config
* the code was wrong anyway, should be `!FIREFOX`
2020-10-23 15:22:18 +03:00
tophf
5a5512aa0f use own implementation of UUIDv4 2020-10-23 09:27:33 +03:00
tophf
54605c838b set customName only on user input 2020-10-22 23:48:17 +03:00
tophf
e6e7d7d158 leave name input empty in new usercss style 2020-10-22 23:47:46 +03:00
tophf
2d9785be6e clear dirty upon swapping style 2020-10-22 23:31:09 +03:00
tophf
0199b2c0bb preserve dirty after importing moz-format, fixes #1075 2020-10-22 23:18:58 +03:00
tophf
6593d5c05a get disableAll pref earlier, fixes #1074 2020-10-22 22:58:45 +03:00
tophf
f9804036b2
instant style injection via synchronous XHR (#1070)
* don't run web-ext test as it fails on Chrome-only permissions

* generate stylus-firefox.zip without declarativeContent

* limit note's width in options

* run updateExposeIframes only in frames
2020-10-22 22:16:55 +03:00
tophf
7f15ae324d
Merge pull request #1054 from tophf/custom-name
fix local name customization for usercss/legacy
2020-10-22 15:07:33 +03:00
narcolepticinsomniac
76e2a90392 moz-format CM focus style 2020-10-22 15:05:54 +03:00
tophf
d1b9338707 make manager load real fast 2020-10-22 15:05:54 +03:00
tophf
bc6c9c826a make editor load even faster
* reorder scripts
* make style request earlier
2020-10-22 15:03:07 +03:00
tophf
2e1a903cc7 fix local name customization for usercss/legacy 2020-10-22 15:01:49 +03:00
tophf
34f899fc45 don't start incremental search on Space or Shift-Space 2020-10-22 08:51:48 +03:00
tophf
3cb9cbb862
show a palette for current editor in color picker (#1068)
also keep the dialog visible for 30 seconds instead of 5
2020-10-18 16:40:11 +03:00
tophf
e6d73be049
option to open editor in a simple window (no omnibox) (#1067) 2020-10-18 16:37:42 +03:00
tophf
d405bc64ae ignore empty documents produced by stylus-lang bug 2020-10-18 16:34:31 +03:00
tophf
5501efb1be expose version for styles installed from greasyfork/sleazyfork 2020-10-18 16:33:52 +03:00
tophf
3d0b733e9a parserlib: skip spaces before "," in @document foo() , bar() 2020-10-16 20:09:27 +03:00
tophf
56a8212fdf parserlib: add text to background-clip 2020-10-15 22:31:13 +03:00
tophf
492b75d84e parserlib: implement @supports selector() 2020-10-14 21:33:29 +03:00
tophf
a71b621bf9 remove -webkit- prefix on standardized features 2020-10-14 19:48:59 +03:00
tophf
9e487b03e5
tweak editor (#1063)
* also apply live-preview if an unsaved style was disabled

* use box-shadow instead of outline for focus everywhere

* allow focus outline on click in text/search input or textarea

* search inputs should use the same style as text inputs

* also use box-shadow focus on delete buttons

* remove URLSearchParams workaround, not needed since Chrome 55

* use `once` in addEventListener, available since Chrome 55

* update USO bug workarounds, remove obsolete ones

* ping/pong to fix openURL with `message` in FF

* use unprefixed CSS filter, available since Chrome 53

* use unprefixed CSS user-select, available since Chrome 54

* focus tweaks

* also use text query in inline search for Stylus category

* use event.key, available since Chrome 51

Co-authored-by: narcolepticinsomniac
2020-10-13 21:14:54 +03:00
tophf
60fc6f2456
Editor fixes, make sectioned editor open quickly again (#1061)
* make usercss editor full-height again

* make sectioned editor open quickly again

* remove leftovers

* autofocus when add/clone button is clicked

* don't fit to content on clicking the add button

* scroll the window to show a manually added section entirely

* autofocus on a manually added applies-to

* disable Save button while loading

* use standard CSS for a focused CodeMirror outline

* trigger refresh sooner by one viewport in advance

* declare refreshOnView as a standard function

* run fixedHeader asynchronously to prevent self-triggering

* account for header in compact mode when fitting to content

* code cosmetics
2020-10-11 17:13:25 +03:00
tophf
ad24ee0c15
switch to USO-archive for inline search in popup, #1056 2020-10-11 16:53:42 +03:00
tophf
740a16a563 disconnect port explicitly in FF 2020-10-11 14:37:55 +03:00
tophf
4d1110986c update CSSLint
* Scroll Snap L1 (CR 2020-09-18)
* dedupe border*
* fix font-variation-settings grammar
2020-10-11 09:59:05 +03:00
tophf
af726405e1 also search in global styles 2020-10-10 14:25:43 +03:00
tophf
11ce144efb remove the redundant stylus-lang warning filter 2020-10-09 19:40:11 +03:00
tophf
707cd6576f process current contents when live-reload is enabled 2020-10-09 19:22:13 +03:00
tophf
4913da2e19 use installation url on known sites as homepage 2020-10-09 13:47:58 +03:00
tophf
78b0e33ba4 faster install from known sites 2020-10-09 13:47:57 +03:00
tophf
0162f39163 switch to USO-archive for inline search in popup
feature: retry sub.domain.tld as domain.tld if no styles are found

old bug fix: show newly added style in popup

dedupe/simplify bits of popup.js
2020-10-09 13:47:57 +03:00
tophf
5196f96ee3 trigger change on wheeling inside <select> 2020-10-09 13:47:57 +03:00
tophf
b840d4897d cleanup usoSearchCache + tidy up db.js 2020-10-09 13:47:57 +03:00
tophf
9994811819 recognize 'backdrop-filter' 2020-10-08 12:19:14 +03:00
tophf
a01bd3cd61 update polyfill for Chrome>=55 2020-10-08 11:19:18 +03:00
tophf
7c205880d2 require Chrome 55 and allow native async/await syntax 2020-10-08 11:19:18 +03:00
tophf
6b2dff6687 treat empty url-prefix() as non-matching 2020-10-08 11:07:13 +03:00
tophf
cb89be8682 ignore empty code only in global (non-targeted) sections 2020-10-08 11:05:07 +03:00
tophf
7c89f7b21d autosort style elements on own pages too 2020-10-05 21:08:39 +03:00
tophf
15d854f913 fixup for c416fa7c: remove the leftovers, take 2 2020-10-05 16:19:18 +03:00
tophf
e7a6e86b6c fixup for c416fa7c: remove the leftovers 2020-10-05 13:05:35 +03:00
tophf
c416fa7ca0
rework and move newUI+theme to options.html (#1050)
* rework and move newUI+theme to options.html

* rephrase/clarify the find styles label

* switch to USO-archive

* search for 'Stylus' keyword to filter out Stylish crud

* use archive's default search order
2020-10-02 11:10:52 -04:00
tophf
3f6c85637c Containment Module L2 (WD, 2020-06-03) 2020-10-02 12:41:57 +03:00
tophf
e0a7372f4f enable starHack option 2020-10-02 12:41:57 +03:00
narcolepticinsomniac
038629517e
remove dropbox disabled (#1041) 2020-09-22 12:04:19 -04:00
tophf
ee30aa1407
convert colors in uso preprocessor to match USO site (#997)
#rrggbb for /*[[color]]*/
r,g,b for /*[[color-rgb]]*/

(no alpha channel)
2020-09-22 07:15:40 -04:00
tophf
2b149f97a5
CodeMirror 5.58.0 (#1037) 2020-09-22 07:03:31 -04:00
tophf
30983db679
Scroll Anchoring L1 (ED 2020-09-18) (#1038) 2020-09-22 06:56:53 -04:00
tophf
fa1496ecb8
use tab.pendingUrl (#1040) 2020-09-22 06:54:48 -04:00
tophf
aa43507478 parserlib: consume unknown @-rules per CSS grammar 2020-09-21 11:19:53 +03:00
eight
07ba44cc2c
Change: switch to launchWebAuthFlow polyfill (#1017)
* WIP: add webextLaunchWebAuthFlow

* Change: switch to webextLaunchWebAuthFlow

* Bump dependencies

* Fix: use minimized version

* Fix: wrong call to promisifyChrome
2020-08-31 16:38:18 +08:00
narcolepticinsomniac
01cfb435f6
Remove deprecated dropbox and add sync button (#1025)
* Remove deprecated dropbox and add sync button

* re-use existing message
2020-08-24 12:27:23 -04:00
tophf
5109f9abb3
CodeMirror 5.57 (#1023)
* codemirror 5.57

* dedupe the props defined in new codemirror
2020-08-23 11:44:27 -04:00
dependabot[bot]
e0aadb752a Bump minimist from 1.2.0 to 1.2.5
Bumps [minimist](https://github.com/substack/minimist) from 1.2.0 to 1.2.5.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.0...1.2.5)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-20 21:16:13 +03:00
dependabot[bot]
db3747d5f0 Bump lodash from 4.17.15 to 4.17.19
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-20 21:10:55 +03:00
tophf
56f1574433
fix styling of options frame in FF (#1022) 2020-08-19 15:33:04 -04:00
eight
a0172c262c
Fix: enable linter after processing metadata (#1018) 2020-08-17 21:06:52 +08:00
eight
7d93608186
Fix: show sync start error (#1016)
* Update lock file

* Fix: the first sync doesn't collect error messages
2020-08-14 22:32:24 +08:00
tophf
54b1f218e0
Enhance: promisify chrome into browser, drop promisify (#866)
* promisify `chrome` into `browser`

* comment

* comment

* comment

* Add: a naive browser polyfill

* Fix: polyfill doesn't detect content script env correctly

Co-authored-by: eight04 <eight04@gmail.com>
2020-08-14 20:16:01 +08:00
tophf
3d94c641b3
CodeMirror 5.56 + csslint update (#1014)
* CodeMirror 5.56

* csslint: Overscroll Behavior L1 (ED 2020-01-16)

* don't list rare/obsolete/future/existing css props
2020-08-13 13:58:09 -04:00
tophf
96c87fc55d fix colorpicker rgb/hsl parser with leading/trailing space 2020-08-09 15:03:20 +03:00
tophf
d18314357f
use onBoundsChanged to remember editor size/position (#1007) 2020-08-02 00:00:44 -04:00
tophf
f8402a2211
use mousewheel to change focused "input[type=number], select" (#1010)
* use mousewheel to change focused "input[type=number], select"

* revert 0f394fa8 (no longer needed)
2020-08-01 23:50:12 -04:00
tophf
0f394fa8d8 don't scroll CM when target is a scrollable input 2020-08-01 18:00:08 +03:00
tophf
7e7839bb1e
avoid adding # to the page URL when clicking dummy links (#1006) 2020-07-29 21:30:00 -04:00
tophf
c43315e697
restore Shift-Ctrl-Wheel to scroll window in multi-section mode (#1005) 2020-07-29 21:26:38 -04:00
Rob Garrison
837b119e47 1.5.13 2020-07-24 08:19:00 -05:00
Rob Garrison
282a1e7432 Update translations 2020-07-24 07:48:25 -05:00
tophf
e1807c8851 restore autosize-on-type of find input 2020-07-24 07:42:58 +03:00
tophf
7e195594b5
show all spaces in find input in firefox (#1002) 2020-07-23 17:27:29 -04:00
tophf
079b7a39f1
update the style list after DOM (#998)
regressed in 7e6edb9e
2020-07-17 15:42:21 -04:00
tophf
7e6edb9e1b
add/remove style elements on global toggle (#990) 2020-07-15 00:31:33 -04:00
tophf
787466fc40
consume leftovers when auto-completing properties (#992) 2020-07-14 16:25:19 -04:00
tophf
09f6e8d44a
prolong worker lifetime to 5 minutes (#993) 2020-07-14 16:24:00 -04:00
tophf
ca3633b896
fix column combinator detection (#994) 2020-07-14 16:21:47 -04:00
tophf
2f4658657d
increase USO style search timeout (#984) 2020-06-29 12:16:44 -04:00
tophf
429c34ca8b
csslint: Selectors L4 parts (ED 2020-04-07) (#981)
* add :where(), remove :matches()

* add "s" case-sensitivity flag

* add "||" column combinator
2020-06-26 12:47:12 -04:00
tophf
4e146d0e54
use current-line mode for csslint allow override (#977) 2020-06-25 12:08:04 -04:00
tophf
574f11b552
when sorting on updateDate use installDate as a fallback (#975) 2020-06-25 11:51:08 -04:00
tophf
60a37af0e0
add a hotkey & right-click to beautify silently (#972)
* add a hotkey & right-click to beautify silently

* fix closestVisible
2020-06-22 12:14:41 -04:00
tophf
e1ed3bf222
update CSSLint (#967)
* refactor Tokens to enable goto-symbol and find-usages

* refactor <length-percentage>

* CSS Text Module L3 (ED 2020-06-08)

* CSS Fonts Module L4 parts (ED 2020-06-11)

* CSS Scrollbars Module L1 (ED 2020-02-24)

* skip all successfully parsed parts after var()
2020-06-17 09:13:28 -04:00
silverwind
2ffad1b6bb
Add Github Actions (#958)
The tests do spew a few warnings but no errors so this should pass. I
did not bother adding macOS/Windows to the test matrix as there's
probably nothing platform-dependant in this repo, but it could be done
on request.
2020-06-11 00:48:48 -04:00
tophf
015bda764a
update deps + split devdeps/deps (#953) 2020-06-02 04:08:02 -04:00
narcolepticinsomniac
60d314b165
Improve delete confirmation autofocus visual indication (#956) 2020-06-02 02:33:07 -04:00
tophf
a1b0eb7df1
show sublime bookmarks (#951)
* remove redundant setGutterMarker optimization

* show sublime bookmarks
2020-06-01 00:54:49 -04:00
tophf
39c62e684e
throttle DOM updates in manager while importing (#950) 2020-05-31 20:14:42 -04:00
MATE
d9f5ef138c Add Korean translation 2020-05-31 22:36:40 +03:00
tophf
a7a9ee7205
use major browser version in CHROME constant (#946) 2020-05-31 01:43:56 -04:00
tophf
a8fe66550b
Fixes for csslint parserlib (#947)
* css parser: vars in @supports(--var: foo)

* css parser: @keyframes inside @supports and @media
2020-05-29 23:33:29 -04:00
tophf
379c825408
focus search field on Ctrl-F in manager (#935) 2020-05-22 23:12:54 -04:00
mcpower
367d1672c5
Add unlimitedStorage permission (#930)
IndexedDB storage may be evicted by the browser at its discretion [1].
Granting the unlimitedStorage permission ensures that IndexedDB data
will not be evicted [2], and allows the extension to store more than
5MB of data if needed [3].

[1]: https://web.dev/storage-for-the-web/#eviction
[2]: https://crbug.com/680392#c5
[3]: https://developer.chrome.com/apps/declare_permissions#unlimitedStorage
2020-05-16 15:51:50 -04:00
tophf
43f6bdf4ed
use a separate loadTimeout for the actual data transfer (#931) 2020-05-16 15:50:04 -04:00
tophf
7ab0651e4d
add ":" to prop names in css autocomplete menu (#915) 2020-05-01 01:52:18 -04:00
narcolepticinsomniac
81b6137d8a
Max version Dropbox disable and no sync pull animations (#913)
* Max version Dropbox disable and no sync pull animations

Max version Dropbox disable and no sync pull animations.

* Remove TODO

* Kill sync animations entirely, add ref
2020-04-28 10:06:57 -04:00
narcolepticinsomniac
c50b3cfddc
Fix missing CWS page icon (#907) 2020-04-23 09:43:04 -04:00
Rob Garrison
bdf32a7174 1.5.12 2020-04-22 07:26:24 -05:00
Rob Garrison
23a718d8bc 1.5.11 2020-04-20 22:54:05 -05:00
narcolepticinsomniac
0b4e946c82
CM scrollbar pointer-events (#902) 2020-04-17 07:36:37 -04:00
tophf
fea0d08f50
fix infinite loop in colorizeInvisible (#889) 2020-04-17 07:34:52 -04:00
narcolepticinsomniac
7ae0798364
fix FF shortcuts button (#900) 2020-04-16 06:17:12 -04:00
Gusted
d7ff697aa6
Contributing.md - Fix Build.md link (#887)
The non Capitalized link will give you the 404 page not found error.
[Wrong link Current one](https://github.com/openstyles/stylus/blob/master/Build.md)
[Correct link Commited one](https://github.com/openstyles/stylus/blob/master/BUILD.md)
2020-03-23 19:06:54 -04:00
narcolepticinsomniac
50aecffe4c
set min-height outside of query (#873) 2020-03-03 11:13:21 -05:00
Rob Garrison
ad4da5f37d 1.5.10 2020-02-27 08:07:47 -06:00
Rob Garrison
dc3faeeead Update locales 2020-02-27 08:04:52 -06:00
tophf
8192fab1b8
show write-style entries for iframes in popup (#861)
* account for iframes in popup list/write-style and badge

* fix and simplify openURL + onTabReady + message from popup

* fixup! resolve about:blank iframes to their parent URL

* fixup! don't underline iframe links until hovered

* fix width bug in popup only when needed (Chrome 66-69)

* fixup! reset styleIds on main page navigation

* fixup! call updateCount explicitly on extension pages

* fixup! ensure frame url is present

* fixup! frameResults entry may be empty

* fixup! init main frame first

* fixup! track iframes via ports

* fixup! reduce badge update rate during page load

* fixup! cosmetics

* fixup! don't add frames with errors

* fixup! cosmetics
2020-02-24 18:16:45 -05:00
tophf
4bbce7cb9f
fix and simplify .user.css URL installer (#856)
* fix and simplify .user.css URL installer

* Refactor: pull out tab-manager and icon-manager

* fixes/cosmetics

* usercss installer url check
* extract downloaders
* simplify tabManager
* rework/split openInstallerPage
* use a simple object instead of map
* trivial bugfixes
* cosmetics

* fixup! updateIconBadge in styleViaAPI

Co-authored-by: eight <eight04@gmail.com>
2020-02-23 10:43:26 -05:00
tophf
c3b7657433
fix category check when searching for foo.bar.tld (#863) 2020-02-22 07:37:22 -05:00
tophf
df8c258c84
fix usage of openerTabId in openURL + cosmetics (#859)
* fix usage of openerTabId in openURL + cosmetics

* fixups

* fixup
2020-02-20 17:54:54 -05:00
eight
8380a674b9
Upgrade uuid (#858)
* Upgrade uuid

* Fix: eslint
2020-02-20 07:17:15 -05:00
Rob Garrison
6875cc33b4 1.5.9 2020-02-16 11:23:47 -06:00
Rob Garrison
8ad0ec2518 README: update build instructions 2020-02-16 11:08:24 -06:00
Rob Garrison
146cd6d3a6 Update locales 2020-02-16 10:53:11 -06:00
Rob Garrison
948d596efa Meta: Update package-lock.json 2020-02-16 10:52:21 -06:00
eight
4831183207
Rewrite the build script (#852)
* npm install

* Drop remove-modules

* Drop updates

* Refactor: rewrite build script

* Add: BUILD.md

* Add: start-chrome command

* Rebuild vendor

* Update contributing.md

* Update BUILD.md

* Update BUILD.md

Co-authored-by: narcolepticinsomniac <therealdoctorgonzo@gmail.com>
2020-02-14 12:02:57 -05:00
eight
9f2261ae95
Fix: Onedrive sync is broken on Firefox (#854)
* Update lock file

* Fix: Onedrive sync is broken on Firefox
2020-02-14 11:51:00 -05:00
Rob Garrison
0defa94c6e 1.5.8 2020-02-13 21:09:19 -06:00
tophf
108907d4f1
skip transition-patch in invisible tabs (#851) 2020-02-12 11:44:25 -05:00
tophf
ccb2e899b3
Simplify & speed up style injection (#843)
* use wrappedJSObject to create style elements in page context

* skip unnecessary polyfills in content scripts

* group all style management stuff in injector

* support all API methods in content scripts
2020-02-12 09:39:00 -05:00
tophf
0b5115fc8a
also handle removed/replaced/errored tabs in injectToAllTabs (#850) 2020-02-12 17:08:25 +03:00
tophf
7109d33e4e
wait for tabs to load when reinjecting (#849) 2020-02-12 07:49:14 -05:00
narcolepticinsomniac
02a575a9d6
Add reload context menu item (#848)
* Add reload context menu item

* Recheck on initial install

* convert createContextMenus to function

* reload command
2020-02-12 07:47:24 -05:00
tophf
438fdebc5c
apply show-badge option to all tabs (#847) 2020-02-11 09:14:09 -05:00
eight
0a79bde610
Refactor chromeStorageDB (#840)
* Fix: the return type of dbExecChromeStorage('put') is wrong

* Refactor: pull out db-chrome-storage

* Fix: the signature of putMany is different
2020-02-10 09:56:07 -05:00
Rob Garrison
f32b6b6989 1.5.7 2020-02-02 11:07:55 -06:00
Rob Garrison
9d765e91c6 Update vendor dependencies 2020-02-02 11:07:22 -06:00
Rob Garrison
8e07ee697c Meta: Update dependencies 2020-02-02 10:55:32 -06:00
narcolepticinsomniac
ff6e941958
Account for Dropbox bug (#833)
* Account for Dropbox bug

* Breaking: deprecate dropbox backup

* Drop: dropbox and zipjs-browserify

* Breaking: remove dropbox backup

* Fix: remove href from the command

Co-authored-by: eight <eight04@gmail.com>
2020-02-02 09:02:25 -05:00
narcolepticinsomniac
1f12d50aaf
Embed options in manager (#828)
* Embed options in manager

* fix indent again

* Fix edit URL detected as manage URL when creating manager style from popup

* Syntax, hash only, and prevent empty hash

* Fix: move origin check to background

* Rename eslintrc

* Refactor: openURL

* Add: fixme comment about openEditor

* Fix: allow activating manager in other windows

* Add: trimHash method

* Fix: limit the scope of styleViaAPI

* Breaking: add router, keep search params

* Fix: focus options when activated

* Add: some fixme

* Fix: remove unused fixme

* Fix: minor

* Fix: remove unused message

* Add: doc

* Change: activate manager in other windows

* Fix: make sure sender is available in getTabUrlPrefix

* Add: openManage API

* Change: reuse editor in openEditor

* Fix: greedly pop the buffer

* Fix: backward detection

* Fix: remove unused important

* Fix: remove unused workaround

* Fix: avoid empty search param

* Change: detect all kinds of manager in openManage

* Fix: minor

* Manage button text

Co-authored-by: eight <eight04@gmail.com>
2020-02-01 23:36:54 -05:00
tophf
d3ee6d9498 fix an infinite loop in editor search with /^/ or /$/ (#832) 2020-01-27 21:39:36 -05:00
tophf
2b985a0a91 automatic category fallback in style search (#831)
Even better. Seems way more reliable. Thanks tophf.
2020-01-27 21:36:43 -05:00
narcolepticinsomniac
a3c22325b8
Onedrive beta and Opera compatibility 2020-01-14 19:06:35 -05:00
narcolepticinsomniac
6cb038535e
Copyable elements accessibility (#808) 2020-01-06 19:13:49 -05:00
Rob Garrison
2ea5290ea0 Fix word breaks in popup (#805)
* Fix word breaks in popup. See #312

* Click to copy

* Copy styling

* Copy message

* Copy styling

* cleanup

* cleanup
2019-11-17 22:23:12 -05:00
Conrad
a2a8908e70 Update README.md (#806) 2019-11-17 08:34:57 -06:00
narcolepticinsomniac
2742cbe120
Sync status shouldn't be clickable (#804)
* Sync status shouldn't be clickable

* sync status shouldn't be clickable
2019-11-14 19:17:25 -05:00
narcolepticinsomniac
41aa869c33
Style sync select (#803)
* Style sync select

* Style sync select

* cleanup
2019-11-14 00:50:38 -05:00
eight
f9db43a2e9 Add: sync database to a cloud drive (#787)
* Add key

* Add: a second index uuid, push changes to sync controller

* Add: sync.js

* Add: tokenManager

* Change: log entire body for http error

* Add: token flow

* Fix: minor

* Fix: move cleanup to stop function

* Add: syncNow

* Update dependencies

* Fix: handle 401 error

* Add: handle 401 error

* Fix: then -> catch

* Add: sync options to options page

* Update db-to-cloud

* Change: make prefs.set return a promise

* Add: disble selector if connected

* Add: update selector state

* Fix: return promise in prefs.set

* Fix: manage complex state

* Fix: handle prefs change

* Change: manage sync status in background

* Add: show current status in the UI

* Add: schedule a faster sync when db changed

* Update dependencies

* Add: include progress in sync status

* Add: more detail status

* Show status text only

* Bump dependencies

* Change: show loaded and total

* Fix: syncTarget is undefined

* Add: google and onedrive

* Fix: token is not reused

* Bump dependencies

* Don't use minified version since it is hard to debug

* Fix: expire time is incorrect

* Change: switch google to code flow

* Bump dependencies

* Change: only modify pref if the initialization success?

* Don't stop the sync if the first sync is not triggered by the user

* Add: implement refresh token

* Change: switch microsoft to code flow

* Add: subtract expire with a latency

* Add: microsoft client secret

* Add: display error message

* Fix: fromPref is not used

* Change: try to revoke the token when log out

* Add: revoke dropbox token

* Fix: Google only generates one refresh token for one user by default

* Bump dependencies, fix onedrive list issue

* Fix: arguments sent to sync.put is wrong

* Fix: don't schedule a sync on db changed if not connected

* Bump dependencies. Fix issue of switching drives

* Bump db-to-cloud, fix switching drive issue

* Fix: only auth user on 401 error, don't display login window without user interaction

* Fix: don't call revoke() if token is undefined

* Add: login button to generate the access token interactively

* Fix: make addMissingProperties a local

* Fix: store missing props in an object

* Fix: sync.getStatus should be sync

* LATENCY -> NETWORK_LATENCY

* Fix: cache the token forever if there is no expire time e.g. dropbox

* Add some comments

* Fix: i18n

* Fix: i18n sync status

* fixup! Fix: i18n sync status

* Fix: 'sync to cloud' is displayed twice
2019-11-05 14:30:45 -05:00
tophf
c0fd71dda6 only recalc applies-to css on live-update if style targets the editor 2019-10-13 20:59:50 +03:00
tophf
5459130111 find @-moz-doc sections faster in the editor (#786)
* find @-moz-doc sections faster in the editor

* only recreate widgets if section data is changed

* CodeMirror speedup: reuse the old folding marks

* add a reminder to remove the CodeMirror hack in the future

* use precise getTokenAt

* check doc type for string/comment to be more mode-agnostic

* fix setGutterMarker hack

* fix skipSpace: EOL is a space too

* move deepEqual next to deepCopy

* fix getTokenTypeAt check for some cases

* remove the unnecessary \s*
2019-09-25 04:44:33 -04:00
Rob Garrison
a7defbfc40
Popup border (#781)
* Popup: Fix horizontal scrollbar in Chrome

* Hide popup borer option in newer Chrome versions. Closes #780

* Add chrome bug range constant
2019-09-24 08:21:36 -05:00
Rob Garrison
d8c2cd449e Meta: Update dependencies 2019-09-11 07:19:00 -05:00
Rob Garrison
03959ffcc8 1.5.6 2019-09-11 07:05:39 -05:00
Rob Garrison
277e56ea44 Fix linting issues 2019-09-11 06:56:19 -05:00
eight
f4b1ea8a90 Change: check style.sheet instead of getComputedStyle (#779) 2019-09-11 03:32:34 -04:00
Roger
da9178096b Add primary header to README and replace HTML with markdown equivalent (#765) 2019-09-09 01:00:41 -04:00
eight
450984abf3 Fix: don't assign undefined to style object (#764) 2019-09-09 00:48:44 -04:00
eight
34dfd83056 Change: a better way to defer page script injection, switch to inline script (#766)
* Revert "Revert defer page script injection (#758)"

This reverts commit 7d52326eb7.

* Add: store style count in sessionStorage

* Change: use localStorage instead of sessionStorage

* Update web-ext

* Fix: page script doesn't work in XML

* Fix: promise never returns if the script is rejected

* Change: disable page script preload

* Drop: stylusStyleCount
2019-09-09 00:45:08 -04:00
eight
a7445011a9 Enhance: faster msg.sendBg (#774) 2019-09-09 00:40:07 -04:00
Rob Garrison
0e9d5ce08c 1.5.5 2019-08-07 21:20:10 -05:00
narcolepticinsomniac
793dc20722
linter and compact layout improvements (#749)
* linter and compact layout improvements

Closes #748

While investigating the best way to fix linter scrolling, when I double-checked the compact layout, an old bug I meant to fix a long time ago was immediately apparent. Basically, the linter adds/removes errors as you type, causing the editor to bounce up and down, making it practically unusable. 

This PR fixes scrolling, and also collapses options and the linter in the compact layout, but always shows the collapsed linter so you're aware of the error count without the content jumping. It also collapses options in the non-compact layout if the viewport is too short to accommodate them, factoring in the min-height of the linter. All automatic collapsing factors in whether a linter is active so they can adjust accordingly, and disables the setting of collapsed state prefs, since we're deciding the pref anyway, and this allows for re-expanding on resize based on the previous pref.

It's quite possible I failed to account for certain scenarios, so try to break it. Also think it's problematic for the linter to not always be visible if enabled, so I hooked up a 40px fixed header on scroll with just the linter in it for the compact layout.

A few other little details are included. I removed redundant line and column numbers spelled out at the end of lint messages to prevent horizontal overflow. I noticed that the expand/collapse prefs do not toggle correctly when clicking directly on the details-marker arrow. Simplest solution was covering them with the `h2` (we may wanna hook up the manager as well). Also, unrelated, but I switched to opacity to hide resizing sectioned editors, because `visibility: hidden;` breaks editor auto-focus.

If either of you guys wanna fix any bugs, or improve any code, feel free to just commit to this PR directly.

* linter and compact layout improvements

* linter and compact layout improvements

* No usercss scroll listener and delay header check

* Some code tweaks
2019-08-04 13:09:50 -04:00
narcolepticinsomniac
7d52326eb7
Revert defer page script injection (#758)
Closes #756

I edited this a couple days ago, so let's double check the diff and make sure I didn't screw anything up.
2019-08-04 13:04:02 -04:00
narcolepticinsomniac
00c2455b07
Slightly wider menu button 2019-07-22 02:31:11 -04:00
tophf
7206f4cd9e Fix colorpicker (#745)
* process CM5.48+ new token for color functions

* restore scientific number notation support in colors

rgba(1.5E2 0 0 / .5e2%)
2019-07-14 20:16:53 -04:00
Rob Garrison
c2e83fb3c4 1.5.4 2019-07-08 07:07:31 -05:00
Rob Garrison
b7b6ed2ff5 Update vendor libraries
Codemirror & Dropbox sdk
2019-07-08 04:59:28 -05:00
Rob Garrison
b32bafd149 Update translations 2019-07-08 04:50:51 -05:00
Rob Garrison
d415643775 Meta: Update dependencies 2019-07-08 04:33:51 -05:00
narcolepticinsomniac
bc56a7abd6
menus as dialogs (#727)
* menus as dialogs

I think it's better in general, and also eliminates the glitchiness of expandable menus in FF, not to mention possible scroll issues on long style lists with overflow, plus the fact that we could add many menu items in the future without the menu looking ridiculous.

IDEK how the formatting got screwed up and borked the diffs in the other PR. I updated my editor config plugin, so let's see if that helps. I restarted with a fresh master and copy/pasted the changes, so if it's still screwy, I guess my editor needs more help. If not, I'm not playing around with it anymore right now, and the other PR does at least work.

* menus as dialogs
2019-06-20 15:37:40 -04:00
eight
6fbc291b19 Fix: single editor doesn't stretch to full height (#728)
* Fix: single editor doesn't stretch to full height

* Fix: remove redundant selectors
2019-06-20 15:36:53 -04:00
eight
d1db77e5b0 Add: auto resize editors on init in section editor (#729)
* Add: auto resize section editor on init

* Fix: calculate cm height correctly

* Fix: query heights before set

* Fix: work with small layout, hide sections before ready
2019-06-20 15:36:27 -04:00
eight
c61806974f Fix: db initializing error, polyfill localStorage/sessionStorage (#616)
* Fix: make sure all errors are caught when initializing

* Fix: polyfill localStorage and sessionStorage
2019-06-20 15:35:41 -04:00
narcolepticinsomniac
514fa3204f
Simplify exclusions (#724)
* Change: exclusion should match urlWithoutParams

Revert to eight04's initial two commits in #681 which make exclusion toggles domain and singular URLs only, plus reincorporate the js menu height calculation.

* Change: drop excludeStyleByUrlRedundant plus menu height

* menu item text

* Make exclusion rules work like match pattern and handle invalid URLs

* Exclude rules in tooltips

* Remove leftover code

* Cross-browser overflow consistency
2019-06-11 10:44:32 -04:00
narcolepticinsomniac
19c71868a0
Improve height restriction for popup config dialog (#721)
* Improve height restriction for popup config dialog

Noticed unnecessary overflow in Github Dark's config dialog. We should allow it to utilize available height.

* Shave off 2px to allow for borders without overflow
2019-06-01 05:12:52 -04:00
eight
19ee4d46bc Change: report updatable after the install button is prepared. Prevent installing duplicated styles from USO (#717)
* Fix: don't install duplicate styles on USO

* Change: report updatable after the install button is prepared
2019-06-01 05:12:06 -04:00
eight
0d6c2bdb42 Fix: onAlarms is registered multiple times (#702) 2019-06-01 05:11:22 -04:00
eight
60693e8c3f Fix: change disabled state after the content is set (#701) 2019-06-01 05:10:44 -04:00
narcolepticinsomniac
eb6888e44c
Avoid potential transition patch conflicts (#720)
8's fix - closes #706, closes #707
2019-05-26 06:12:02 -04:00
Rob Garrison
8906cbbb1a
Prevent importing styles with no section. Fixes #687 (#697)
* Prevent importing styles with no section. Fixes #687

And prevent issues with existing styles with no section

* Revert sections checks for empty array

* Add styleJSONseemsValid function

* Clean up

* Fix eslint nags
2019-04-16 07:32:06 -05:00
stonecrusher
b48817fe01 Update Stylelint defaults for Stylus-lang at-rules (#695)
* Update Stylelint defaults for Stylus-lang at-rules

* Minor tweak
2019-04-14 08:39:22 -05:00
Rob Garrison
ab83ed8f0f Fix linter config issues. Closes #689 2019-04-05 07:42:37 -05:00
narcolepticinsomniac
6e0d073cbf Fix missing FF favicons Closes #683 (#686)
* Fix missing FF favicons Closes #683

I think the combo of  swapping `window.prefs` for `prefs`, and moving the function inside `onDOMready()` does the trick. 

@eight04 Any idea why `window.prefs` no longer works? Does the rest LGTY?

* Add suggestions
2019-03-25 07:48:53 -05:00
Rob Garrison
5f21213693 1.5.3
This version is a placeholder, the commit history does not match
the content available in the current extension
2019-03-24 19:00:05 -05:00
Rob Garrison
a29d7dc4ca Fix USO install button
Narcolepticinsomniac worked out the code
2019-03-24 18:08:01 -05:00
eight
b40849acad Refactor: rewrite style injector (#664)
* Refactor: style injector/docRootObserver/docRewriteObserver

* Fix: minor

* Fix: disabled state

* Fix: use evade

* Fix: apply.js is broken in our pages

* Fix: transition patch is broken

* Fix: also check elements after the last userstyle

* Fix: remove outdated FIXME. styleInjector.toggle now toggle all styles

* Fix: call Object.keys twice

* Add a fixme

* Fix: typo

* Add a fixme

* Fix: don't argue for mutations generated by other extensions
2019-03-09 20:58:17 -06:00
Rob Garrison
744bf01147
Firefox allow CSP UserCSS install from anywhere. See #618 (#623)
* Firefox allow CSP UserCSS install from anywhere. See #618

* Fix suffix extension
2019-03-03 20:42:03 -06:00
tophf
55189f1fdd CSSLint and parserlib (#646)
* CSSLint: add mask-image

https://drafts.fxtf.org/css-masking-1/#the-mask-image

* CSSLint: update <image> type

https://drafts.csswg.org/css-images-3/#typedef-image

* CodeMirror CSS mode: add 'mask-image'

* CodeMirror CSS mode: add CSS Round Display L1

https://www.w3.org/TR/css-round-display-1/

* CSSLint: CSS Round Display L1 (ED 2018-09-26)

https://drafts.csswg.org/css-round-display/

* CSSLint: CSS Environment Variables L1 (ED 2018-08-03)

https://drafts.csswg.org/css-env-1/

* CSSLint: parts of CSS Overflow Module L3 (WD 2018-07-31)

only overflow-* properties are added since the rest seem tentative
https://www.w3.org/TR/css-overflow-3/

* CSSLint: Selectors L4 :is() supersedes :matches()

https://drafts.csswg.org/selectors-4/#matches

* CSSLint: Text Decoration L3 (CR 2018-06-26)

https://drafts.csswg.org/css-text-decor-3/

* CSSLint: fix '&&' in grammarParser

consequences:
* fixed text-shadow
* fixed <display-listitem>
* switched to a string in <shadow>

* CSSLint: fix definition for 'rotate'

* CSSLint: fix applyEmbeddedOverrides

* CSSLint: update definition for 'rotate'

* CSSLint: reset parserlib cache when inline overrides change

* CSSLint: code cosmetics

* CSSLint: fixup d5971e9c

* CSSLint: code cosmetics

* CSSLint: start ignoring from the comment's line number
2019-03-03 16:55:15 -06:00
eight
cdc7f98150 Add: user-frendly exclusions (#666)
* WIP: popup UI

* Fix: use simple menu toggle

* Add: inclusion/exclusion API

* Add: hook exclusion UI

* Fix: minor

* Fix: don't self-edit

* Icons and accessibility

* Icons and accessibility

* Fix: disable redundant exclude-by-url checkbox

* Disabled cursor and delete leftover code

* Generic menu button tooltip and tweak menu item cursors

* Generic menu button tooltip and tweak menu item cursors

* Generic menu button tooltip and tweak menu item cursors
2019-03-03 16:54:37 -06:00
eight
1ff34fc449 Fix: return true in icon API (#669) 2019-03-03 08:29:26 -06:00
eight
4262882ac9 Add: enable usercss updateURL (#661)
* Add: use metadata.updateURL as style.updateUrl

* Change: only use the installation URL as the update URL if not specified in usercss

* Fix: hide live reload checkbox according to installationUrl
2019-02-13 19:09:18 -06:00
eight
dfb9db34c3 Fix: update live preview when the style is toggled/replaced (#662) 2019-02-03 14:00:13 -05:00
Rob Garrison
0bd738b49f Set updateDate on editSave. Closes #663 2019-02-02 07:01:08 -06:00
tophf
93a15a8284 fix colorview detection with inline comments (#660) 2019-02-01 07:36:08 -06:00
narcolepticinsomniac
756fafe263
Ensure applySections is complete 2019-01-29 23:30:37 -05:00
narcolepticinsomniac
b18d062d51
Use setTimeout for transition patch Fixes #648 (#656) 2019-01-29 11:14:07 -05:00
Rob Garrison
1bdd0512ae Prevent JS error in messages 2019-01-27 18:37:12 -06:00
Rob Garrison
e8ba51f940 Fix applies to alignment 2019-01-17 06:41:47 -06:00
narcolepticinsomniac
c56f5c32f1
Revert expose iframes by default
I don't I think I care enough to argue with someone who's technically correct.
2019-01-09 23:43:28 -05:00
narcolepticinsomniac
ae7e0799fe
Expose iframes by default 2019-01-09 21:22:43 -05:00
narcolepticinsomniac
89b18dca45
Account for max-content bug in Chrome 49 2019-01-08 02:41:39 -05:00
narcolepticinsomniac
ab688368e1
Specify width for newer versions of Chromium Fixes #639 2019-01-08 02:15:53 -05:00
narcolepticinsomniac
ddc6e79af6
Return pointer-events to error modals Fixes #637 2019-01-06 17:07:52 -05:00
eight
ad5c56c774 Fix: handle editDeleteText message (#635) 2019-01-02 07:46:51 -06:00
Rob Garrison
1fbbeae9b9
Update popup style sort after toggle. Closes #619 (#624)
* Update popup style  sort after toggle. Closes #619

* Add popup auto resort option

* Switch autoResort to true by default

* Refactor sorting

* Fix: simplify sortStyles function

* Change: autoResort=false
2018-12-31 23:11:45 -06:00
eight
f5db0a5ab0 Refactor: pull out content-scripts.js (#625) 2018-12-30 18:01:54 -06:00
eight
aa56f96585 Fix: catch syntax error (#627) 2018-12-28 20:55:52 -06:00
Rob Garrison
0c8e69fb9d Make beautify options persistent. Fixes #630 2018-12-27 07:53:37 -06:00
Rob Garrison
3ea6e94e83 Fix expose iframe option example in popup. Closes #629 2018-12-26 22:40:56 -06:00
eight
52b7742a45 Change: don't wait when broadcasting messages (#622) 2018-12-26 06:51:21 -06:00
Rob Garrison
ddd03eab1d Prevent JS error in multiple section search 2018-12-19 07:09:16 -06:00
Rob Garrison
4c11c8324e 1.5.2 2018-12-11 07:34:05 -06:00
Rob Garrison
3edea88b13 Fix linting issues 2018-12-11 07:28:30 -06:00
Rob Garrison
b57d30a70b Update locales 2018-12-11 06:25:41 -06:00
Rob Garrison
8e3ea662e4 Update dependencies 2018-12-11 06:25:23 -06:00
eight
626148c117 Fix: remove unused code (#612) 2018-12-11 06:19:19 -06:00
Rob Garrison
7f3013f477
Fix & cleanup config in popup. Closes #602 (#603)
* Fix & cleanup config in popup. Closes #602

* Hide icon for USO with no config
2018-12-10 07:57:44 -06:00
tophf
8b8a3d60ab spoof HTTP Referer for USO directly (#608) 2018-12-10 07:14:43 -06:00
Rob Garrison
68ce3a653e Focus first editor on init. Fixes #605 2018-12-08 07:51:09 -06:00
Rob Garrison
8a3c260eb9 Fix save template. Closes #607 2018-12-08 07:21:32 -06:00
eight
30d00dbd3a Fix: don't use null as id (#606) 2018-12-07 21:57:43 -06:00
Rob Garrison
779a6e4e35 Fix keyboard interaction on config icon 2018-12-03 18:25:13 -06:00
Rob Garrison
da5b4c029b Remove unnecessary code 2018-12-03 18:23:41 -06:00
Rob Garrison
9fe721945d Set installType for on new installs
Fixes Dropbox thinking the browser is in dev mode
2018-11-29 22:04:43 -06:00
Rob Garrison
aca0572f4d 1.5.1 2018-11-29 20:21:26 -06:00
Rob Garrison
53d130a179 Update vendors 2018-11-29 20:11:39 -06:00
Rob Garrison
c4af63237c update locales 2018-11-29 19:41:18 -06:00
eight
8d6c88e377 Support Chrome 49 (#561)
* Add: polyfill to support chrome 49

* Fix: fetch text in Chrome 49

* Add: polyfill element method

* Update usercss-meta

* Fix: buggy destructuring

* Fix: dialog position?

* Fix: unneeded warning

* Fix: getChromeVersion

* Fix: don't cache tab icon in old chrome

* Fix: static -> relative

* Fix: use XHR as fallback
2018-11-29 19:35:21 -06:00
Rob Garrison
5778ac0d23
Subscribe to all UI updates. Fixes #590 & #591 (#593)
* Subscribe to all UI updates. Fixes #590 & #591

* Remove unnecessary subscription to sort changes
2018-11-29 19:34:06 -06:00
Rob Garrison
6aaff7aa12
Fix usercss install error. Closes #589 (#592)
* Fix usercss install error. Closes #589

* Cleanup

* Disable input & hide icon
2018-11-29 19:33:54 -06:00
Rob Garrison
a4c08084bf
Move dropbox vendors (#576)
* Move vendor files

* Move sync/vendor & config updates

* Update dropbox sdk from v4.0.9 to v4.0.13

* Fix typo

* Fix zip path

* Pass fetch option to Dropbox
2018-11-28 18:56:17 -06:00
Rob Garrison
eafa5110c0 Fix update log error message 2018-11-28 18:07:05 -06:00
eight
43a4671c64 Change: defer page script injection. Try to inject to head (#584) 2018-11-27 22:57:44 -06:00
Rob Garrison
a1b17bb553
Fix dirty style updating. Closes #585 (#586)
* Fix dirty style updating. Closes #585

* Move common code to edit.js

* init updateDirty
2018-11-27 22:54:36 -06:00
narcolepticinsomniac
eb0b9f58f5 Fix search highlight conflict (#587)
* Fix search highlight conflict 

Regular highlight styling and search highlight styling shouldn't both be applied at the same time. Search highlight styling should also be removed when search is closed. This PR resolves those conflicts.

* Remove unnecessary dummy animation

Not sure what the point of it ever was, but I'm pretty sure it should go.
2018-11-27 22:48:45 -06:00
narcolepticinsomniac
237d5c0c06 Fix inline search (#588)
For some unknown reason, USO now requires a new param.
2018-11-27 22:39:35 -06:00
eight
e97a3ef269 Change: modify match-highlighter plugin (#578)
* Change: modify match-highlighter plugin

* Fix: boundary character should only be used when the query starts/ends with alphabet
2018-11-25 07:28:37 -06:00
eight
4120907957 Fix: failed to find the old style when the name/namespace is changed (#581) 2018-11-25 07:27:10 -06:00
tophf
319ec320c7 specify the end token for simple block in _expr() (#580) 2018-11-24 23:13:33 -06:00
Rob Garrison
764fe399f3
Fix inaccessible file message. Closes #574 (#575)
* Fix inaccessible file message. Closes #574

* Reword inaccessible message
2018-11-24 06:03:01 -06:00
eight
05ec2fb1c7 Fix: detect style CSP (#573) 2018-11-21 11:09:48 -06:00
eight
25fb5acabe Fix: cycle through editors (#572)
* Fix: cycle through editors

* Fix: command is broken
2018-11-21 09:47:28 -06:00
Rob Garrison
9250d5c624 Remove unnecessary API method 2018-11-20 19:49:20 -06:00
Rob Garrison
21b6429205 Beautify: stop new line injection before comment. Fixes #564 2018-11-20 19:41:31 -06:00
Rob Garrison
81d27288f2 Remove duplicate rules in issue modal 2018-11-20 18:57:25 -06:00
Rob Garrison
17339e933b
Show Dropbox unavailable in dev mode (#568) 2018-11-20 17:32:03 -06:00
Rob Garrison
33df061b53 Allow /*! in UserCSS metadata. Closes #571 2018-11-20 17:07:42 -06:00
Rob Garrison
99951efc80
Show error in tooltip (#566)
* Show error in tooltip

* Move error.message check
2018-11-19 22:55:38 -06:00
Rob Garrison
df2b08a75a Remove soft-hyphens in popup. Closes #562 2018-11-19 09:07:14 -06:00
Rob Garrison
62b201c6f6 Fix syntax of gecko min version 2018-11-18 22:42:02 -06:00
Rob Garrison
28dc768ce5 1.5.0 2018-11-18 22:18:50 -06:00
Rob Garrison
a6691031d5 Update dependencies 2018-11-18 22:16:00 -06:00
Rob Garrison
7ea0200234
Validate UserCSS meta colors. Fixes #554 (#559)
* Validate UserCSS meta colors. Fixes #554

* Add suggestions & optimize code

* Fix parsePercentage return value

* cleanup

* Fix: remove unused variable

* Fix: validate function should return a boolean

* Revert indent

* Fix: cleaner validateRGB

* Fix: validateHSL

* Fix: validateAlpha

* Cleanup

* Fix: remove invalid comment

* Limit color channels to integers
2018-11-18 22:05:38 -06:00
Rob Garrison
7261a074cd
Fix USO update button (#555)
* Fix USO update button

* Fix background & search-results

* Prevent JSON parse error

* Get & set currentMd5 outside of condition

* fetchMd5 with API without options

* Only update originalMd5 for valid styles

* Always set currentMd5 & add a delay before firing USO event
2018-11-18 07:30:47 -06:00
Rob Garrison
b41a39d36e Add counter(s) to CSSLint parserlib. Closes #553 2018-11-17 23:23:55 -06:00
Rob Garrison
1ff89acda3 Fix popup inline style install/uninstall 2018-11-15 07:46:52 -06:00
Rob Garrison
59c02dfbed Adjust style on backup button & dropdown 2018-11-11 21:02:13 -06:00
Rob Garrison
dab3515195 Remove text-decoration-skip:ink; Closes #229 2018-11-11 15:42:36 -06:00
eight
b2657e3ebd Change: simplify msg.js (#544)
* Fix: make API work in private windows

* Change: simplify msg.js
2018-11-11 07:07:30 -06:00
eight
b622ebc172 Add: store the reason why db failed (#550)
* Add: store the reason why db failed

* Add: add a warning

* fixup! Add: add a warning
2018-11-11 07:05:09 -06:00
eight
deeba1b900
Change: drop less, switch to less-bundle (#542)
* Change: drop less, switch to less-bundle

* fixup! Change: drop less, switch to less-bundle
2018-11-11 14:06:25 +08:00
eight
5646b8a0d9
Add: improve import performance (#547)
* Add: implement db putMany

* Fix: putMany returns a list of ids
2018-11-11 14:04:22 +08:00
eight
8291da0bb5 Chore: include stylus version in the issue template (#549) 2018-11-08 07:35:40 -06:00
eight
a1a85efc75
Update usercss-meta (#540)
* Update usercss-meta

* Add: translation for new errors

* Fix: define `anno.rule` in meta linter

* Fix: typo

* Fix: don't display rule id if undefined

* fixup! Fix: don't display rule id if undefined
2018-11-07 23:33:56 +08:00
eight
4db8a9ea9a Fix: output codemirror themes to a separated file (#538) 2018-11-07 05:33:14 -06:00
eight
e3d3604afc
Refactor the entire storage system and the section editor (#518)
* Squashed commit of the following:

commit d84c4dc3fe
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 19:13:29 2018 +0800

    Fix: remove unused comment

commit 46027120ec
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 19:09:06 2018 +0800

    Add: handle styleUpdated message

commit f85d4de39b
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 18:59:29 2018 +0800

    Fix: handle styleAdded message in popup

commit 81f3e69574
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 18:50:54 2018 +0800

    Change: getStylesInfoByUrl -> getStylesByUrl

commit f9dc04558f
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 18:48:20 2018 +0800

    Fix: drop getStylesInfo

commit fea04d591f
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 18:39:28 2018 +0800

    Fix: remove unused ignoreChromeError

commit 2aff14e213
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 18:09:53 2018 +0800

    Fix: don't dup promisify in prefs

commit d4ddfcc713
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 17:56:16 2018 +0800

    Change: drop .last and .rotate

commit 85e70491e4
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 17:36:00 2018 +0800

    Fix: unused renderIndex

commit 7acb131642
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 17:32:49 2018 +0800

    Fix: update title on input

commit a39405ac4c
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 17:17:20 2018 +0800

    Fix: remove unused messages

commit 14c2fdbb58
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 16:36:12 2018 +0800

    Fix: dirty state for new added applies

commit fb1b49b8bb
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 16:27:17 2018 +0800

    Fix: minor

commit 2c2d849fa4
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 16:20:14 2018 +0800

    Fix: drop unused getCode

commit f133c3e67a
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 16:18:14 2018 +0800

    Fix: drop unused lastActive

commit 05a6208f5c
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 16:17:45 2018 +0800

    Fix: minor

commit 05a87ed00f
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 15:58:33 2018 +0800

    Fix: minor

commit 576f73f333
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 03:03:35 2018 +0800

    Fix: always register listeners

commit e93819deb4
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 02:58:49 2018 +0800

    Fix: unused statement

commit 39b11685b4
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 02:54:29 2018 +0800

    Fix: minor

commit 9dd3cd43c1
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 02:49:22 2018 +0800

    Fix: don't reorder options

commit 90aadfd728
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 02:43:52 2018 +0800

    Fix: drop __ERROR__

commit 838c21e3b3
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 02:36:20 2018 +0800

    Fix: use findStyle API

commit 93a4cdf595
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 02:34:05 2018 +0800

    Add: findStyle API

commit 8e75871b9b
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 02:19:01 2018 +0800

    Breaking: drop getStylesFallback

commit ad06551440
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 02:16:48 2018 +0800

    Fix: use dataurl to inject page script

commit cb5cbb4d10
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 01:39:50 2018 +0800

    Fix: various

commit 53efd78b89
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 01:12:57 2018 +0800

    Update doc

commit 7d005f3eaa
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 01:09:22 2018 +0800

    Change: kill style.reason

commit fc53bed3de
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 00:56:04 2018 +0800

    Fix: doo many indents

commit 14e321d258
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 00:40:23 2018 +0800

    Fix: don't update icon for popup and options

commit 01bdd529bc
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 00:39:17 2018 +0800

    Fix: updateCount

commit b9968830d3
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 00:38:49 2018 +0800

    Fix: don't send null value

commit ff3bf6f52d
Author: eight <eight04@gmail.com>
Date:   Sun Oct 14 00:03:34 2018 +0800

    Add: styleViaAPI updateCount

commit 39d21c3d29
Author: eight <eight04@gmail.com>
Date:   Sat Oct 13 23:57:45 2018 +0800

    Fix: broadcastError -> ignoreError

commit ecb622c93c
Author: eight <eight04@gmail.com>
Date:   Sat Oct 13 21:29:06 2018 +0800

    Fix: implement styleViaAPI

commit 7c3d49c005
Author: eight <eight04@gmail.com>
Date:   Sat Oct 13 17:50:28 2018 +0800

    Fix: ROOT may change in XML pages

commit 3fd8d937f3
Author: eight <eight04@gmail.com>
Date:   Sat Oct 13 16:49:43 2018 +0800

    Fix: various

commit 859afc8ee9
Author: eight <eight04@gmail.com>
Date:   Sat Oct 13 16:39:54 2018 +0800

    Enhance: don't cache enabled state

commit fbe77a8d15
Author: eight <eight04@gmail.com>
Date:   Sat Oct 13 16:15:07 2018 +0800

    Fix: various

commit a4fc3e9162
Author: eight <eight04@gmail.com>
Date:   Sat Oct 13 16:11:38 2018 +0800

    Fix: various

commit 7e0eddeb8f
Author: eight <eight04@gmail.com>
Date:   Sat Oct 13 15:58:31 2018 +0800

    Fix: various

commit 8b4ab47d89
Author: eight <eight04@gmail.com>
Date:   Sat Oct 13 15:20:10 2018 +0800

    Add: some type hint

commit 7d340d62dc
Author: eight <eight04@gmail.com>
Date:   Sat Oct 13 15:13:11 2018 +0800

    Change: drop storage.js, some functions are moved to sections-util

commit d286997d6a
Author: eight <eight04@gmail.com>
Date:   Sat Oct 13 15:12:00 2018 +0800

    Fix: minor

commit d60db9dbef
Author: eight <eight04@gmail.com>
Date:   Sat Oct 13 15:03:10 2018 +0800

    Fix: minor

commit 43afa31fa0
Author: eight <eight04@gmail.com>
Date:   Sat Oct 13 14:50:31 2018 +0800

    Fix: update tab icon on forward/backward

commit f08faea149
Author: eight <eight04@gmail.com>
Date:   Sat Oct 13 13:50:03 2018 +0800

    Fix: parallel import

commit 4d06435486
Author: eight <eight04@gmail.com>
Date:   Fri Oct 12 23:32:03 2018 +0800

    Add: importStyle API

commit c55675912e
Author: eight <eight04@gmail.com>
Date:   Fri Oct 12 23:14:46 2018 +0800

    Fix: refactor import-export

commit 86ea846a89
Author: eight <eight04@gmail.com>
Date:   Fri Oct 12 17:34:36 2018 +0800

    Fix: search db is broken

commit 831ca07c2d
Author: eight <eight04@gmail.com>
Date:   Fri Oct 12 17:29:35 2018 +0800

    fixup! Add: implement sloppy regexp indicator

commit e67b7f4f36
Author: eight <eight04@gmail.com>
Date:   Fri Oct 12 17:27:19 2018 +0800

    Add: implement sloppy regexp indicator

commit 36e13f88f0
Author: eight <eight04@gmail.com>
Date:   Fri Oct 12 16:59:23 2018 +0800

    Add: return excluded/sloppy state in getStylesInfoByUrl

commit f6ce78f55b
Author: eight <eight04@gmail.com>
Date:   Fri Oct 12 16:39:47 2018 +0800

    Fix: dead object

commit 5ae95a1ad9
Author: eight <eight04@gmail.com>
Date:   Fri Oct 12 16:27:54 2018 +0800

    Fix: don't reinit all editors on save

commit 1a5a206fe6
Author: eight <eight04@gmail.com>
Date:   Fri Oct 12 16:18:40 2018 +0800

    Refactor: pull out sections editor section

commit 8016346035
Author: eight <eight04@gmail.com>
Date:   Fri Oct 12 15:30:35 2018 +0800

    Fix: replaceStyle make style name undefined

commit fa080d1913
Author: eight <eight04@gmail.com>
Date:   Fri Oct 12 15:21:36 2018 +0800

    Fix: catch csp error

commit e0b064115d
Author: eight <eight04@gmail.com>
Date:   Fri Oct 12 15:03:00 2018 +0800

    Fix: use a simple eval to execute page scripts

commit 405b7f8f06
Author: eight <eight04@gmail.com>
Date:   Fri Oct 12 03:48:13 2018 +0800

    Fix: removed unused API

commit 1b2c88f926
Author: eight <eight04@gmail.com>
Date:   Fri Oct 12 03:46:51 2018 +0800

    Fix: no need to access db

commit a8131fc9c5
Author: eight <eight04@gmail.com>
Date:   Fri Oct 12 03:43:31 2018 +0800

    Fix: remove unused methods

commit 3ae0c4dd13
Author: eight <eight04@gmail.com>
Date:   Fri Oct 12 03:10:26 2018 +0800

    Enhance: allow matcher to return verbose info

commit 0ea7ada48f
Author: eight <eight04@gmail.com>
Date:   Fri Oct 12 02:02:14 2018 +0800

    Fix: content script may load before the background is ready

commit 04c2d6bbf6
Author: eight <eight04@gmail.com>
Date:   Fri Oct 12 01:49:52 2018 +0800

    Fix: throw receiving end doesn't exist message

commit f0c0bc4d6a
Author: eight <eight04@gmail.com>
Date:   Fri Oct 12 01:11:17 2018 +0800

    Fix: unwrap error

commit 4d42765d6c
Author: eight <eight04@gmail.com>
Date:   Thu Oct 11 23:55:16 2018 +0800

    fixup! Fix: match subdomain

commit 99626e4a48
Author: eight <eight04@gmail.com>
Date:   Thu Oct 11 23:54:58 2018 +0800

    Fix: match subdomain

commit a57b3b2716
Author: eight <eight04@gmail.com>
Date:   Thu Oct 11 23:39:11 2018 +0800

    Fix: firefox

commit 5cfea3933f
Author: eight <eight04@gmail.com>
Date:   Thu Oct 11 22:46:34 2018 +0800

    Add some comment to db.js

commit 25fd3a1c2b
Author: eight <eight04@gmail.com>
Date:   Thu Oct 11 22:14:56 2018 +0800

    Fix: remove unused prop

commit bdae1c3697
Author: eight <eight04@gmail.com>
Date:   Thu Oct 11 20:00:25 2018 +0800

    Change: simpler styleCodeEmpty

commit bd4a453f45
Merge: c1bf9f5 9058c06
Author: eight <eight04@gmail.com>
Date:   Thu Oct 11 19:49:37 2018 +0800

    Merge branch 'dev-usercss-meta' into dev-exclusions

commit c1bf9f57e9
Author: eight <eight04@gmail.com>
Date:   Thu Oct 11 19:29:17 2018 +0800

    Fix: minor

commit fd5eeb4b81
Author: eight <eight04@gmail.com>
Date:   Thu Oct 11 19:00:05 2018 +0800

    Add: refresh on view

commit 3e38810a49
Author: eight <eight04@gmail.com>
Date:   Thu Oct 11 18:13:24 2018 +0800

    Fix: make sure icons are refreshed at startup

commit c657d7e55c
Author: eight <eight04@gmail.com>
Date:   Thu Oct 11 17:32:27 2018 +0800

    Add: implement bug 461

commit 7ed39ab6ef
Author: eight <eight04@gmail.com>
Date:   Thu Oct 11 15:42:44 2018 +0800

    fixup! Add: icon-util

commit 30e494eda9
Author: eight <eight04@gmail.com>
Date:   Thu Oct 11 15:42:23 2018 +0800

    Add: icon-util

commit 510a886e14
Author: eight <eight04@gmail.com>
Date:   Thu Oct 11 03:21:38 2018 +0800

    Fix: exposeIframes

commit c7f81662c4
Author: eight <eight04@gmail.com>
Date:   Thu Oct 11 02:19:14 2018 +0800

    Fix: autoCloseBrackets is true by default

commit f3a103645d
Author: eight <eight04@gmail.com>
Date:   Thu Oct 11 02:11:14 2018 +0800

    Fix: various

commit d4436cde20
Author: eight <eight04@gmail.com>
Date:   Thu Oct 11 01:39:10 2018 +0800

    Add: implement exposeIframe

commit 43db875fd8
Author: eight <eight04@gmail.com>
Date:   Thu Oct 11 01:26:24 2018 +0800

    Kill more globals

commit dc491e9be3
Author: eight <eight04@gmail.com>
Date:   Thu Oct 11 01:22:13 2018 +0800

    Kill old storage, storage-dummy

commit ba64b95575
Author: eight <eight04@gmail.com>
Date:   Thu Oct 11 00:54:38 2018 +0800

    WIP: kill cachedStyles

commit 7eba890a21
Merge: d2b36a1 81e4823
Author: eight <eight04@gmail.com>
Date:   Wed Oct 10 23:15:14 2018 +0800

    Merge branch 'dev-private-prefs' into dev-exclusions

commit d2b36a168e
Author: eight <eight04@gmail.com>
Date:   Wed Oct 10 23:05:20 2018 +0800

    Kill hidden globals

commit 22d4767511
Author: eight <eight04@gmail.com>
Date:   Wed Oct 10 19:23:34 2018 +0800

    Fix: margin for deleted sections

commit 00687983f0
Author: eight <eight04@gmail.com>
Date:   Wed Oct 10 18:21:07 2018 +0800

    Fix: default value

commit ff6fd8cad3
Author: eight <eight04@gmail.com>
Date:   Wed Oct 10 18:02:51 2018 +0800

    Fix: default options

commit c23f315c52
Author: eight <eight04@gmail.com>
Date:   Wed Oct 10 17:40:07 2018 +0800

    Refactor: use CodeMirror.defineOption

commit 4419c5dc1e
Author: eight <eight04@gmail.com>
Date:   Wed Oct 10 16:32:39 2018 +0800

    Change: kill editors, styleId

commit 6494985b50
Author: eight <eight04@gmail.com>
Date:   Wed Oct 10 16:14:51 2018 +0800

    Fix: various

commit 37e1f43f75
Author: eight <eight04@gmail.com>
Date:   Wed Oct 10 15:04:03 2018 +0800

    Fix: minor

commit d26ce3238e
Author: eight <eight04@gmail.com>
Date:   Wed Oct 10 14:49:37 2018 +0800

    Add: codemirror-factory

commit 15a1f552f6
Author: eight <eight04@gmail.com>
Date:   Wed Oct 10 12:08:35 2018 +0800

    WIP: kill getSection

commit ba6159e067
Author: eight <eight04@gmail.com>
Date:   Wed Oct 10 02:43:09 2018 +0800

    WIP: edit page

commit fd9ab5d6e5
Author: eight <eight04@gmail.com>
Date:   Wed Oct 10 00:41:07 2018 +0800

    Fix: switch to editor

commit 06e22d0d18
Author: eight <eight04@gmail.com>
Date:   Tue Oct 9 23:38:29 2018 +0800

    Change: add sections-editor

commit 30e8662946
Author: eight <eight04@gmail.com>
Date:   Mon Oct 8 20:12:39 2018 +0800

    Add: preview error

commit 47b2b4fc49
Author: eight <eight04@gmail.com>
Date:   Mon Oct 8 18:38:01 2018 +0800

    Add: livePreview.show

commit 7b5e7c96d5
Author: eight <eight04@gmail.com>
Date:   Mon Oct 8 18:16:45 2018 +0800

    Hook up live preview

commit 15efafff3c
Author: eight <eight04@gmail.com>
Date:   Mon Oct 8 17:49:57 2018 +0800

    Add: live preview

commit a38558ef78
Author: eight <eight04@gmail.com>
Date:   Mon Oct 8 15:30:39 2018 +0800

    WIP: make notifyAllTabs a noop

commit 582e9078af
Author: eight <eight04@gmail.com>
Date:   Mon Oct 8 14:39:08 2018 +0800

    Fix: inject all scripts

commit f4651da8d8
Author: eight <eight04@gmail.com>
Date:   Sun Oct 7 23:41:46 2018 +0800

    Drop deleteStyle

commit 0489fb3b2f
Author: eight <eight04@gmail.com>
Date:   Sun Oct 7 23:33:51 2018 +0800

    Drop saveStyle

commit 02f471f077
Author: eight <eight04@gmail.com>
Date:   Sun Oct 7 23:28:41 2018 +0800

    Fix: usercss API

commit 057111b171
Author: eight <eight04@gmail.com>
Date:   Sun Oct 7 22:59:31 2018 +0800

    Update usercss API

commit 69cae02381
Author: eight <eight04@gmail.com>
Date:   Sun Oct 7 21:40:29 2018 +0800

    Drop getStyles

commit c5d41529d9
Author: eight <eight04@gmail.com>
Date:   Sun Oct 7 21:28:51 2018 +0800

    Minor fixes

commit 5b3b4e680f
Author: eight <eight04@gmail.com>
Date:   Sun Oct 7 21:20:39 2018 +0800

    Add: navigator-util

commit b5107b78a5
Author: eight <eight04@gmail.com>
Date:   Sun Oct 7 01:42:43 2018 +0800

    Add: broadcast messages with reasons

commit e7ef4948cd
Author: eight <eight04@gmail.com>
Date:   Sat Oct 6 18:10:47 2018 +0800

    Fix: observer is unavailable?

commit 1c635b5bc1
Author: eight <eight04@gmail.com>
Date:   Sat Oct 6 17:47:43 2018 +0800

    Drop requestStyles

commit 75f2561154
Author: eight <eight04@gmail.com>
Date:   Sat Oct 6 16:38:04 2018 +0800

    Fix: don't recreate element when style update in popup

commit 583ca31d97
Author: eight <eight04@gmail.com>
Date:   Sat Oct 6 15:40:07 2018 +0800

    fixup! Add: isCodeEmpty

commit 1cf6008514
Author: eight <eight04@gmail.com>
Date:   Sat Oct 6 15:33:18 2018 +0800

    Add: isCodeEmpty

commit 450cd60aeb
Author: eight <eight04@gmail.com>
Date:   Sat Oct 6 15:22:04 2018 +0800

    Fix: ignore comment block

commit 196b6aac63
Author: eight <eight04@gmail.com>
Date:   Sat Oct 6 15:16:00 2018 +0800

    Fix: the return value of getSectionsByUrl is changed

commit 3122d28c1a
Author: eight <eight04@gmail.com>
Date:   Sat Oct 6 15:14:05 2018 +0800

    Fix: always use promise in API call

commit e594b8ccb1
Author: eight <eight04@gmail.com>
Date:   Sat Oct 6 15:11:01 2018 +0800

    Cache enabled state

commit 1f18b13a92
Author: eight <eight04@gmail.com>
Date:   Sat Oct 6 13:48:46 2018 +0800

    Add: match global sections

commit fedf844ddd
Author: eight <eight04@gmail.com>
Date:   Sat Oct 6 13:45:37 2018 +0800

    Add: getStylesInfoByUrl

commit 095998f07c
Author: eight <eight04@gmail.com>
Date:   Sat Oct 6 13:27:58 2018 +0800

    Change: switch to msg.js

commit fa3127d988
Author: eight <eight04@gmail.com>
Date:   Sat Oct 6 13:02:45 2018 +0800

    Change: switch to msg.js

commit 05d582c726
Author: eight <eight04@gmail.com>
Date:   Sat Oct 6 11:43:42 2018 +0800

    Add: msg.sendBg

commit 171339f710
Author: eight <eight04@gmail.com>
Date:   Sat Oct 6 04:39:48 2018 +0800

    WIP: drop api.js

commit 3a618aca2a
Author: eight <eight04@gmail.com>
Date:   Sat Oct 6 03:19:51 2018 +0800

    WIP: use deepCopy

commit bb1cb58024
Author: eight <eight04@gmail.com>
Date:   Sat Oct 6 03:10:04 2018 +0800

    WIP: msg.js

commit 2472e91f57
Author: eight <eight04@gmail.com>
Date:   Fri Oct 5 21:28:19 2018 +0800

    WIP: emitChangesToTabs

commit 34497ebe16
Author: eight <eight04@gmail.com>
Date:   Fri Oct 5 18:47:52 2018 +0800

    WIP: switch to API

commit f1639cc33e
Author: eight <eight04@gmail.com>
Date:   Fri Oct 5 01:03:40 2018 +0800

    WIP: broadcastMessage

commit 81e4823f46
Author: eight <eight04@gmail.com>
Date:   Thu Oct 4 19:39:59 2018 +0800

    Debounce updateAllTabsIcon

commit dc5f3e209f
Author: eight <eight04@gmail.com>
Date:   Thu Oct 4 19:34:36 2018 +0800

    Fix: settings could be empty on the first install

commit 2328cf623a
Author: eight <eight04@gmail.com>
Date:   Thu Oct 4 19:34:22 2018 +0800

    Change: start-firefox -> start

commit 7be6a1cba9
Author: eight <eight04@gmail.com>
Date:   Thu Oct 4 19:24:35 2018 +0800

    Add: applications

commit 630725196f
Author: eight <eight04@gmail.com>
Date:   Thu Oct 4 19:22:44 2018 +0800

    fixup! Fix: update all icons when some prefs changed

commit 0d0e1b4dc0
Author: eight <eight04@gmail.com>
Date:   Thu Oct 4 19:20:36 2018 +0800

    Fix: update all icons when some prefs changed

commit 5c0288e9ba
Author: eight <eight04@gmail.com>
Date:   Thu Oct 4 19:20:11 2018 +0800

    fixup! Remove unused FIREFOX_NO_DOM_STORAGE

commit 56b737b65a
Author: eight <eight04@gmail.com>
Date:   Thu Oct 4 18:14:57 2018 +0800

    Remove unused FIREFOX_NO_DOM_STORAGE

commit 829a134ed1
Author: eight <eight04@gmail.com>
Date:   Thu Oct 4 18:10:53 2018 +0800

    Fix: this -> prefs

commit d35f92250e
Author: eight <eight04@gmail.com>
Date:   Thu Oct 4 18:08:19 2018 +0800

    Fixme: styleViaAPI

commit 8a6e8ac03a
Author: eight <eight04@gmail.com>
Date:   Thu Oct 4 18:05:41 2018 +0800

    Change: drop prefChanged, use prefs service

commit 10f9449144
Author: eight <eight04@gmail.com>
Date:   Thu Oct 4 17:46:45 2018 +0800

    Change: move setupLivePrefs to dom.js. Remove prefs.js dependencies

commit dd2b8ed091
Author: eight <eight04@gmail.com>
Date:   Thu Oct 4 17:18:38 2018 +0800

    Fix: type error

commit 3af310c341
Author: eight <eight04@gmail.com>
Date:   Thu Oct 4 17:09:26 2018 +0800

    Fix: open-manager has no default value

commit 874a2da33e
Author: eight <eight04@gmail.com>
Date:   Thu Oct 4 17:04:23 2018 +0800

    Enhance: make prefs use storage.sync

commit c01f93f62c
Author: eight <eight04@gmail.com>
Date:   Thu Oct 4 15:57:02 2018 +0800

    WIP

commit 6d32ffb76b
Author: eight <eight04@gmail.com>
Date:   Thu Oct 4 12:46:19 2018 +0800

    WIP

commit 0f148eac32
Author: eight <eight04@gmail.com>
Date:   Thu Oct 4 03:35:07 2018 +0800

    WIP

commit 282bdf7706
Author: eight <eight04@gmail.com>
Date:   Wed Oct 3 20:24:06 2018 +0800

    Fix: numbers are not compared correctly

commit 24b1eea8a4
Merge: 8a6011d 5cbe8a8
Author: eight <eight04@gmail.com>
Date:   Wed Oct 3 15:00:07 2018 +0800

    Merge branch 'master' of https://github.com/openstyles/stylus into dev-exclusions

commit 5cbe8a8d78
Author: eight <eight04@gmail.com>
Date:   Tue Oct 2 20:22:18 2018 +0800

    Add: fetch style object from DB directly in the editor (#507)

commit 9058c06c54
Author: eight <eight04@gmail.com>
Date:   Mon Oct 1 23:24:29 2018 +0800

    Fix: bad API

commit 1f2d116aae
Author: eight <eight04@gmail.com>
Date:   Mon Oct 1 23:14:56 2018 +0800

    Fix: use meta parser

commit 918e47b1ed
Author: eight <eight04@gmail.com>
Date:   Mon Oct 1 23:01:21 2018 +0800

    Fix: emit update event if no fatal errors

commit 81a7bb9ac9
Author: eight <eight04@gmail.com>
Date:   Mon Oct 1 22:56:25 2018 +0800

    Add: editorWorker.metalint

commit f47d57aea8
Author: eight <eight04@gmail.com>
Date:   Mon Oct 1 22:49:16 2018 +0800

    Change: use editorWorker.metalint

commit 5778d5c858
Author: eight <eight04@gmail.com>
Date:   Mon Oct 1 22:39:01 2018 +0800

    Change: editor-worker-body -> editor-worker

commit 268e1716b4
Author: eight <eight04@gmail.com>
Date:   Mon Oct 1 22:38:06 2018 +0800

    Change: switch to worker-util

commit cc2980b647
Author: eight <eight04@gmail.com>
Date:   Mon Oct 1 22:30:16 2018 +0800

    Drop: parserlib-loader

commit 08adcb60f2
Merge: 6909c73 2fd531e
Author: eight <eight04@gmail.com>
Date:   Mon Oct 1 22:29:39 2018 +0800

    Merge branch 'master' into dev-usercss-meta

commit e4135ce35d
Author: eight <eight04@gmail.com>
Date:   Fri Sep 28 11:57:34 2018 +0800

    Fix: remove unused function

commit 39a6d1909f
Author: eight <eight04@gmail.com>
Date:   Fri Sep 28 00:26:29 2018 +0800

    Fix: prefs doesn't work in FF's private windows. Add web-ext. Drop prefs.readOnlyValues

commit 6909c73c69
Author: eight <eight04@gmail.com>
Date:   Wed Sep 26 12:16:33 2018 +0800

    Fix: minor

commit 79833d8bba
Author: eight <eight04@gmail.com>
Date:   Wed Sep 26 11:40:04 2018 +0800

    Fix: a better way to draw list?

commit a849fd6dda
Author: eight <eight04@gmail.com>
Date:   Wed Sep 26 11:39:53 2018 +0800

    Fix: missing placeholders

commit d5ee31a080
Author: eight <eight04@gmail.com>
Date:   Wed Sep 26 11:37:50 2018 +0800

    Fix: a better way to draw character list?

commit 7b959af3e3
Author: eight <eight04@gmail.com>
Date:   Wed Sep 26 11:30:10 2018 +0800

    Update usercss-meta

commit fefa987c4d
Author: eight <eight04@gmail.com>
Date:   Wed Sep 26 10:37:28 2018 +0800

    Change: sections-equal -> sections-util

commit 2abbf670d8
Author: eight <eight04@gmail.com>
Date:   Wed Sep 26 10:37:14 2018 +0800

    Fix: check err.code

commit 1fe0586b29
Author: eight <eight04@gmail.com>
Date:   Wed Sep 26 10:33:02 2018 +0800

    Add: i18n error message

commit ab0ef239cf
Author: eight <eight04@gmail.com>
Date:   Wed Sep 26 09:34:57 2018 +0800

    Change: move styleCodeEmpty to sections-util, load colorConverter in background worker

commit d5ade807f0
Author: eight <eight04@gmail.com>
Date:   Wed Sep 26 09:27:30 2018 +0800

    Fix: display error message

commit 4f5337e51d
Author: eight <eight04@gmail.com>
Date:   Wed Sep 26 09:26:55 2018 +0800

    Fix: remove unused colorconverter

commit 29b8f51292
Author: eight <eight04@gmail.com>
Date:   Tue Sep 25 23:21:44 2018 +0800

    Fix: vars could be undefined

commit a7cfeb22e4
Author: eight <eight04@gmail.com>
Date:   Tue Sep 25 22:54:40 2018 +0800

    Fix: window is undefined

commit 9713c6a3be
Author: eight <eight04@gmail.com>
Date:   Tue Sep 25 21:56:38 2018 +0800

    Fix: throw an error for unparsable color

commit 3c30bc3eb0
Author: eight <eight04@gmail.com>
Date:   Tue Sep 25 21:55:55 2018 +0800

    Fix: try to get error message

commit 3d32b0428b
Author: eight <eight04@gmail.com>
Date:   Tue Sep 25 21:38:40 2018 +0800

    Fix: vars might be empty

commit 7d75dd8754
Author: eight <eight04@gmail.com>
Date:   Tue Sep 25 21:18:39 2018 +0800

    Add: meta-parser

commit a4df641b96
Author: eight <eight04@gmail.com>
Date:   Tue Sep 25 21:18:18 2018 +0800

    Enhance: set flag in parserlib so we don't need another loader

commit 8028a3529f
Author: eight <eight04@gmail.com>
Date:   Tue Sep 25 21:17:40 2018 +0800

    Include util, worker-util in background

commit ba5d6cc31a
Author: eight <eight04@gmail.com>
Date:   Tue Sep 25 21:16:59 2018 +0800

    Fix: use spread syntax in loadScript

commit b853be13f8
Author: eight <eight04@gmail.com>
Date:   Tue Sep 25 21:14:46 2018 +0800

    Enhance: swith to usercss-meta (in worker)

commit a3e7915199
Author: eight <eight04@gmail.com>
Date:   Tue Sep 25 21:11:54 2018 +0800

    Fix: use promise API

commit 5d07a8cd4e
Author: eight <eight04@gmail.com>
Date:   Tue Sep 25 21:11:09 2018 +0800

    Fix: buildMeta now returns a promise

commit a004bc3c7d
Author: eight <eight04@gmail.com>
Date:   Tue Sep 25 21:10:35 2018 +0800

    Move styleCodeEmpty to util

commit 41ac66a137
Author: eight <eight04@gmail.com>
Date:   Tue Sep 25 21:09:40 2018 +0800

    Add: background worker

commit ffb13bf1db
Author: eight <eight04@gmail.com>
Date:   Tue Sep 25 21:09:04 2018 +0800

    Enhance: move moz-parser/meta-parser/usercss compiler to worker

commit 42e97ef153
Author: eight <eight04@gmail.com>
Date:   Tue Sep 25 20:45:07 2018 +0800

    Fix: display error on install page

commit 64aa9fcf53
Author: eight <eight04@gmail.com>
Date:   Tue Sep 25 17:34:54 2018 +0800

    Add: background worker

commit b0e407e98f
Author: eight <eight04@gmail.com>
Date:   Tue Sep 25 14:52:35 2018 +0800

    Add: worker util

commit 7a24547e09
Author: eight <eight04@gmail.com>
Date:   Tue Sep 25 00:01:18 2018 +0800

    Add: usercss-meta

commit 8a6011de8c
Author: Rob Garrison <wowmotty@gmail.com>
Date:   Sun Jul 22 09:15:09 2018 -0500

    Attempt to update icon count

commit 4fcb1a88d7
Author: Rob Garrison <wowmotty@gmail.com>
Date:   Sun Jul 15 13:44:29 2018 -0500

    Fix empty exclusion storage error

commit bfe54ab4c4
Author: Rob Garrison <wowmotty@gmail.com>
Date:   Sun Jul 15 12:59:51 2018 -0500

    Add tab communication

commit 983a7bc219
Author: Rob Garrison <wowmotty@gmail.com>
Date:   Sun Jul 15 10:51:11 2018 -0500

    Fix escaped regex example

commit 3950482f34
Author: Rob Garrison <wowmotty@gmail.com>
Date:   Wed Apr 25 18:11:37 2018 -0500

    Fix undefined error

commit e94c7edb38
Author: Rob Garrison <wowmotty@gmail.com>
Date:   Wed Apr 25 17:09:45 2018 -0500

    Attempt to fix popup exclusion issues

commit 2b4a1a5635
Author: Rob Garrison <wowmotty@gmail.com>
Date:   Thu Apr 19 13:00:27 2018 -0500

    Modify input method

commit 9f75b69cd8
Author: Rob Garrison <wowmotty@gmail.com>
Date:   Wed Mar 7 11:54:05 2018 -0600

    Include iframe urls in exclusion popup

commit 68dfa0153c
Author: Rob Garrison <wowmotty@gmail.com>
Date:   Wed Jan 24 19:42:02 2018 -0600

    Add style exclusions. Closes #113

* Revert: exclusions

* Fix: pass eslint

* Fix: the style is injected twice

* Fix: don't load script async

* Fix: styleCodeEmpty returns true for empty string

* Fix: drop array selection

* Fix: the config dialog is broken

* Fix: popup doesn't use getStyle/getStylesByUrl correctly

* Fix: keep disabled state in setStyleContent

* Fix: allow live-preview to assign newest vars

* Fix: transition fix is broken because setStyleContent becomes async

* Fix: typo, TypeError in styleExists

* Fix: use new API

* Fix: pass linter

* Fix: LICENCE -> LICENSE

* Fix: remove unused distroy function
2018-11-07 14:09:29 +08:00
Matheus Faustino
79c6506c5c Implement Dropbox export (#82) (#393)
* Implement Dropbox export (#82)

* Remove wrong dropbox api key

* Improve implementation of Dropbox by using identity.launchWebAuthFlow api and get rid of web_accessible_resources

* We don't need a dropbox receiver anymore, remove constante with the html file

* Implement compression in dropbox export

* Add LICENSE file from dropbox and zipjs

* Fix code style error

* Fix code style and folder structure of the feature

* Fix eslint error in dropbox implementation

* Add real dropbox api key from stylus dropbox account

* For test only: fixed addon's ID on firefox

* Change the file not found message to a better one

* Add dropdown style on export and import buttons

* Changes arrow from buttons to svg

* Remove applications entry on manifest.json

* Remove unnecessary break line
2018-11-03 13:33:35 -05:00
Rob Garrison
5c6cf72a4c 1.4.23 2018-11-03 12:58:39 -05:00
Rob Garrison
14144c287c Update dev dependencies & CodeMirror 2018-11-03 12:12:02 -05:00
Rob Garrison
5536f7ad22
Locales (#532)
* Add gitattributes

* Add update locales script

* Update locales

* Remove old script files

* Switch to use transifex client app
2018-11-03 09:37:25 -05:00
Rob Garrison
30cf5b2458
Fix incorrect USO md5Url (#523) (#527)
* Fix incorrect USO md5Url (#523)

* Fix md5Url in getAll

* Remove variable reassignment
2018-10-26 08:48:58 -05:00
eight
100e1dc28d Fix: TypeError in style-via-api (#521) 2018-10-18 19:19:36 -05:00
eight
5cbe8a8d78
Add: fetch style object from DB directly in the editor (#507) 2018-10-02 20:22:18 +08:00
eight
2fd531e253 Rewrite linter system (#487)
* Add: implement new linter system

* Refactor: pull out editor worker

* Switch to new linter and worker

* Enable eslint cache

* Fix: undefined error

* Windows compatibility

* Fix: refresh linter if the editor.linter changes

* Add: stylelint

* Add: getStylelintRules, getCsslintRules

* Fix: logic to get correct linter

* WIP: linter-report

* Fix: toggle hidden state

* Add: matain the order of lint report for section editor

* Add: unhook event

* Add: gotoLintIssue

* Fix: shouldn't delete rule.init

* Add: linter-help-dialog

* Drop linterConfig

* Add: linter-config-dialog, cacheFn

* Add: use cacheFn

* Drop lint.js

* Add: refresh. Fix report order

* Fix: hide empty table

* Add: updateCount. Fix table caption

* Switch to new linter/worker

* Fix: remove unneeded comment

* Fix: cacheFn -> cacheFirstCall

* Fix: use cacheFirstCall

* Fix: cache metaIndex

* Fix: i < trs.length

* Fix: drop isEmpty

* Fix: expose some simple states to global

* Fix: return object code style

* Fix: use proxy to reflect API

* Fix: eslint-disable-line -> eslint-disable-next-line

* Fix: requestId -> id

* Fix: one-liner

* Fix: one-liner

* Fix: move dom event block to top

* Fix: pending -> pendingResponse

* Fix: onSuccess -> onUpdated

* Fix: optimize row removing when i === 0

* Fix: hook/unhook -> enableForEditor/disableForEditor

* Fix: linter.refresh -> linter.run

* Fix: some shadowing

* Fix: simplify getAnnotations

* Fix: cacheFirstCall -> memoize

* Fix: table.update -> table.updateCaption

* Fix: unneeded reassign

* Fix: callbacks -> listeners

* Fix: don't compose but extend

* Refactor: replace linter modules with linter-defaults and linter-engines

* Fix: implement linter fallbacks

* Fix: linter.onChange -> linter.onLintingUpdated

* Fix: cms -> tables

* Fix: parseMozFormat is not called correctly

* Move csslint-loader to background

* Fix: watch config changes

* Fix: switch to LINTER_DEFAULTS

* Fix: csslint-loader -> parserlib-loader
2018-10-01 09:03:17 -05:00
Rob Garrison
5f60c519ce Alas, poor clamp! I knew it well 2018-09-24 07:02:04 -05:00
Rob Garrison
b0fbdfb6e9 Update number input on blur 2018-09-24 07:02:04 -05:00
Rob Garrison
93dee41c11 Don't re-render input while focused 2018-09-24 07:02:04 -05:00
Rob Garrison
c18671c91c Fix undefined value 2018-09-24 07:02:04 -05:00
Rob Garrison
a0ffdb7645 Update current value in updateRangeCurrentValue 2018-09-24 07:02:04 -05:00
Rob Garrison
ec16a0c1e0 Remove onblur, don't save invalid inputs 2018-09-24 07:02:04 -05:00
Rob Garrison
40f580a0b2 Change stored number value on change 2018-09-24 07:02:04 -05:00
Rob Garrison
5af74a9d80 Remove isNumber function 2018-09-24 07:02:04 -05:00
Rob Garrison
40a3abbee8 Fix isNumber function 2018-09-24 07:02:04 -05:00
Rob Garrison
d00e5f4ddb Change clamp function order & only call onblur 2018-09-24 07:02:04 -05:00
Rob Garrison
a4d2e3dd9c Remove misleading comment 2018-09-24 07:02:04 -05:00
Rob Garrison
75d2ef2cc1 Fix strict equals 2018-09-24 07:02:04 -05:00
Rob Garrison
f2c973096b Fix clamp function 2018-09-24 07:02:04 -05:00
Rob Garrison
2c7742e56f Check for null in isNumber 2018-09-24 07:02:04 -05:00
Rob Garrison
15a0521408 Fix clamp function 2018-09-24 07:02:04 -05:00
Rob Garrison
f35077afce Fix clamp undefined step 2018-09-24 07:02:04 -05:00
Rob Garrison
7fff670683 Fix clamp undefined min/max 2018-09-24 07:02:04 -05:00
Rob Garrison
375e0ec448 Switch to isNumber function 2018-09-24 07:02:04 -05:00
Rob Garrison
314ec99e5c More suggested changes 2018-09-24 07:02:04 -05:00
Rob Garrison
0678a6b302 Remove unnecessary css 2018-09-24 07:02:04 -05:00
Rob Garrison
ff0145a129 Fix clamp to step floor 2018-09-24 07:02:04 -05:00
Rob Garrison
7be33a9237 Fix default values 2018-09-24 07:02:04 -05:00
Rob Garrison
d136fdbafa Allow including null in number/range variables 2018-09-24 07:02:04 -05:00
Rob Garrison
7d533d4d4a Fix select default option extraction 2018-09-24 07:02:04 -05:00
Rob Garrison
153a066fbe Fix clampValue issue if min/max are not defined 2018-09-24 07:02:04 -05:00
Rob Garrison
2a2191049f Don't allow step to be set to zero 2018-09-24 07:02:04 -05:00
Rob Garrison
1ba0173422 Remove rangeToProps & fix clampValue functions 2018-09-24 07:02:04 -05:00
Rob Garrison
1881552348 Remove va.range & add min/max/step to va directly 2018-09-24 07:02:04 -05:00
Rob Garrison
568fc336e7 Remove console.logs 2018-09-24 07:02:04 -05:00
Rob Garrison
06629224c6 Minor cleanup 2018-09-24 07:02:04 -05:00
Rob Garrison
a277800868 Fix all the things 2018-09-24 07:02:04 -05:00
Rob Garrison
7cd4380ee4 Ensure range default & value types match 2018-09-24 07:02:04 -05:00
Rob Garrison
ae6e2647a3 Add proper number & range validation 2018-09-24 07:02:04 -05:00
Rob Garrison
f6998de6ec Include units in number & range variable 2018-09-24 07:02:04 -05:00
Rob Garrison
1a8d628be5 Clamp number input from user 2018-09-24 07:02:04 -05:00
Rob Garrison
2291197277 UserCSS Number variable now accepts a range 2018-09-24 07:02:04 -05:00
Rob Garrison
d9c748d92f Change range settings to [default, min, max, step] 2018-09-24 07:02:04 -05:00
Rob Garrison
1dc24fac1b Use string slice instead of replace 2018-09-24 07:02:04 -05:00
Rob Garrison
1edfda5417 Wrap default & remove unnecessary break 2018-09-24 07:02:04 -05:00
Rob Garrison
e2b7f194c3 Don't set value on all types of input 2018-09-24 07:02:04 -05:00
Rob Garrison
3fd3c53bd9 Rename select all text function 2018-09-24 07:02:04 -05:00
Rob Garrison
95f9f9c5d4 Rename to defaultValue 2018-09-24 07:02:04 -05:00
Rob Garrison
9b483d993b Add default select option. See #492 2018-09-24 07:02:04 -05:00
Rob Garrison
74892a3130 Add select all text on focus. See #492 2018-09-24 07:02:04 -05:00
Rob Garrison
1632a8f364 Add number & range variables. See #492 2018-09-24 07:02:04 -05:00
tophf
ec477f0c02 1.4.22 2018-09-20 12:55:52 +03:00
tophf
448cd3381b update locales 2018-09-20 12:53:32 +03:00
tophf
2a52139b6a preserve the focused element when replacing entry in-place 2018-09-13 08:41:15 +03:00
tophf
0cffb564ea don't re-toggle the style back on pressing Spacebar
fixes #501
2018-09-13 08:36:19 +03:00
tophf
e128498518 code cosmetics: convert to a lintable template string 2018-09-11 17:41:46 +03:00
tophf
6fdc01201b FF: preserve sheet's disabled state in workaround for #461 2018-09-11 17:39:43 +03:00
tophf
3243e37fbc 1.4.21 2018-09-10 18:01:34 +03:00
tophf
06425c4e6f update locales 2018-09-10 17:36:00 +03:00
tophf
b90f7bfce5 don't autofocus external links like feedback
#495
2018-09-06 20:59:04 +03:00
tophf
4a877ad27b fixup c57fef7b: always set lastFocusedViaClick
#495
2018-09-06 20:42:48 +03:00
tophf
26d7c26770 notify embedder on closing colorpicker
fixup 7fea2cfc: messageBox's Esc handler wasn't restored
2018-09-06 19:34:46 +03:00
tophf
373fe5f510 code cosmetics 2018-09-06 19:08:56 +03:00
tophf
c57fef7b1e suppress focus outline when invoked via mouse
fixes #495
2018-09-06 19:05:10 +03:00
tophf
dcdb4be10b FF59+: always set style's textContent in page context
see #461
2018-09-05 15:58:15 +03:00
tophf
74eb7c7ecd CSSLint: add conic-gradient
https://www.w3.org/TR/css-images-4/#gradients
2018-09-04 21:08:53 +03:00
tophf
79f6e7c3b3 rename OK to Close in the import notification
to disambiguate its actual function
2018-09-04 00:36:56 +03:00
tophf
3ba9201663 hyphenate long tokens in unreachableAMO message 2018-09-03 20:54:25 +03:00
tophf
c49f4dd11e don't hook auxiliary CMs
fixes #491
2018-09-03 20:54:25 +03:00
tophf
5933cf3586 CSSLint: add Q unit
https://www.w3.org/TR/css-values-3/#absolute-lengths
2018-08-30 13:41:26 +03:00
tophf
4f8953adde refresh the just edited style entry after history back 2018-08-30 09:23:55 +03:00
tophf
681176ce31 use showHelp.close when it's defined
fixes #485
2018-08-29 15:39:18 +03:00
tophf
8cf05ee185 make the hover effect less CPU-hungry
* it lagged even on a fast 4GHz i7 CPU + nVidia GPU
* the 'will-change' property didn't help and even increased memory consumption
2018-08-28 20:24:43 +03:00
tophf
af77b55eea fixup 2fdfd966
#482
2018-08-27 20:42:51 +03:00
tophf
2fdfd96699 use the new originalDigest in update UI
...when force-updating a locally edited style that turned out to be equal to the remote one

fixes #482
2018-08-27 20:39:36 +03:00
tophf
95524df6f4 code cosmetics: use :: for pseudo elements 2018-08-27 17:20:48 +03:00
tophf
699b5453fb emphasize data-skipped-edited main status message
thus visually separating it from the wall of text afterwards
2018-08-27 17:20:48 +03:00
tophf
f07e1b269e don't wrap the force-check button
* the label text is too long and contains meaningful info
* it's displayed only rarely in normal usage scenario
2018-08-27 17:19:45 +03:00
tophf
f09380af76 update locales 2018-08-25 20:25:15 +03:00
tophf
687dba8adb typo 2018-08-25 19:50:45 +03:00
tophf
6f53d20491 update package.json 2018-08-25 15:11:14 +03:00
tophf
ea594550a9 CodeMirror v5.40.0 2018-08-25 15:11:03 +03:00
tophf
0dbb55cc0c actually copy codemirror.js before patching 2018-08-25 15:10:14 +03:00
tophf
bfe18e74a4 FF bug workaround: set style element code in page context
fixes #461
2018-08-25 09:42:35 +03:00
tophf
2ac9a9db29 fix headerOnScroll 2018-08-24 14:31:29 +03:00
tophf
918debe110 fix show-more in old UI and simplify generation of targets 2018-08-24 14:02:31 +03:00
tophf
74d9a0d8ba 1.4.20 2018-08-20 17:41:32 +03:00
tophf
47a66ac94b update locales 2018-08-20 17:36:36 +03:00
tophf
b82b8e10d6 simplified font CSS 2018-08-20 13:11:02 +03:00
tophf
c0c5f1dbcc avoid overwriting existing usercss on saving a new one 2018-08-18 23:17:20 +03:00
tophf
4bcdbb78b1 ensure max>=min to keep colorpicker in view 2018-08-16 19:58:05 +03:00
tophf
adc165723c actually run restoreWindowScrollPos in a microtask 2018-08-16 18:09:50 +03:00
tophf
24fdad5f41 no need to open issues that notify about transifex 2018-08-16 13:59:46 +03:00
tophf
1a8481ca80 remove the useless redirection of <text-decoration-color> 2018-08-15 19:12:01 +03:00
tophf
1ac858bd38 make font consistent and define it only once 2018-08-15 10:14:42 +03:00
tophf
ec0b1373fe show update-all button on individual check too
sometimes users may want to check a bunch of styles for updates individually and install the found updates at once
2018-08-15 10:13:52 +03:00
Rob Garrison
799178a16f Add information about the build zip process 2018-08-13 10:50:34 -05:00
tophf
fd745836a5 1.4.19 2018-08-12 15:22:31 +03:00
tophf
c308829977 remove locales without translated messages 2018-08-12 15:21:20 +03:00
tophf
4302b8f69d 1.4.18 2018-08-12 14:58:20 +03:00
tophf
115977046d update locales 2018-08-12 14:54:16 +03:00
tophf
208aa86196 sort locales 2018-08-12 14:52:11 +03:00
Rob Garrison
4795154cf7 Use rimraf in build process
So it works on Windows 7
2018-08-12 04:51:15 -05:00
Rob Garrison
489c014fe9 update vendor files 2018-08-12 04:51:15 -05:00
Rob Garrison
9d15120402 Add "update-quick" script
Using "npm run update" now re-installs all modules
2018-08-12 04:51:15 -05:00
tophf
d7b87130f9 correctly detect when #RGBA isn't supported 2018-08-11 12:34:16 +03:00
tophf
80ea415287 use only one ::pseudo for color swatches 2018-08-11 12:18:23 +03:00
tophf
406a7cd4c0 FF bug workaround: apply styles to more iframes 2018-08-09 21:22:26 +03:00
tophf
92d6530c8f simplify listener registration
since the function reference is constant, only one listener will be registered
2018-08-07 20:11:11 +03:00
tophf
e3d1526b52 don't show messageBox caption if title is empty 2018-08-07 20:05:26 +03:00
tophf
eff0a7030c display only style name in the editor tab title
"Edit Style" was redundant and made the title unreadable when many tabs were opened.
"Add Style" is still displayed for the new styles.
2018-08-07 19:59:16 +03:00
tophf
1b7c131c37 fixup 1a42e6bf 2018-08-06 21:27:48 +03:00
tophf
bfb35e77b8 strip more trailing spaces in a custom usercss template 2018-08-06 20:56:33 +03:00
tophf
baf037e0c4 add "Translate" link in the manager
#448
2018-08-06 18:48:05 +03:00
tophf
be94303bad simplify onInstalled 2018-08-06 18:20:57 +03:00
tophf
91fb0579f1 code clarification 2018-08-06 17:38:38 +03:00
tophf
1a42e6bf00 move the iframe styles in the next animation frame
fixes #461
2018-08-06 17:38:38 +03:00
tophf
2db52c9e2d code cosmetics 2018-08-06 15:11:27 +03:00
tophf
f6a90ad166 suppress stylelint warning for stylus-lang's @css block
fixes #459
2018-08-06 15:10:42 +03:00
tophf
5f623f2f0e fill an empty @name with the default placeholder
fixes #462
2018-08-06 13:35:33 +03:00
tophf
e27636b93d preserve linebreaks in live-preview error text
fixes #460
2018-08-06 13:13:15 +03:00
tophf
a5a713be8a correctly handle the space before ::pseudo 2018-08-06 12:45:53 +03:00
tophf
35baf6f018 show the reason why update/liveReload is unavailable
fixes #458
2018-08-06 12:45:53 +03:00
tophf
d8914c38a7 highlight edited style on history back in FF 2018-08-02 21:10:43 +03:00
tophf
5da1e0fb9b set onbeforeunload only when dirty
https://developers.google.com/web/updates/2018/07/page-lifecycle-api#legacy-lifecycle-apis-to-avoid
2018-08-02 20:54:40 +03:00
tophf
fa4dfd680b simplify manage:export code 2018-08-02 15:52:34 +03:00
tophf
71e2db773b typo 2018-08-02 14:48:26 +03:00
tophf
e2c053f81b keep the exported styles URL alive indefinitely 2018-08-02 14:19:03 +03:00
tophf
d3c8812e51 listen on newly added section's CodeMirror too 2018-08-02 01:44:10 +03:00
tophf
9cebf91e28 don't call updatePreview twice for the same input event 2018-08-02 00:46:14 +03:00
tophf
68cc033942 trigger live preview also for changes in applies-to 2018-08-01 23:29:21 +03:00
tophf
e5a557369b vertically center the labels
this also fixes the bug with covering the descender in letters like "g" when the label is shown in the second row of a style name due to wrapping
2018-07-30 11:45:33 +03:00
tophf
ee4c4de059 code cosmetics: combine and simplify 2018-07-28 23:39:49 +03:00
tophf
363b8a7bf1 skip empty applies-to values 2018-07-28 21:04:29 +03:00
tophf
c7870ee2d1 bump version 2018-07-23 21:25:37 +03:00
tophf
b34a3fd9a4 update locales 2018-07-23 21:25:36 +03:00
tophf
0c58783a6c add buttons to restore, clone, move a section 2018-07-23 21:24:35 +03:00
tophf
0a3ffb0bc8 show an empty applies-to URL-prefix in manually added sections
because global sections are less frequently used.
2018-07-23 21:24:35 +03:00
Rob Garrison
d03ed69b6e Update to semver with LF normalization 2018-07-23 12:47:57 -05:00
Rob Garrison
e2b754bad6 Remove $1 in CodeMirror$1 for development 2018-07-23 12:47:57 -05:00
Rob Garrison
eea72befb1 Update less library 2018-07-23 12:47:57 -05:00
tophf
47c4b8157a expose 'preserve_newlines' in beautifier; dehtmlize
fixes #435
2018-07-23 00:28:11 +03:00
tophf
7d1bf4119a show "close" button in beautifier dialog
fixes #436
2018-07-22 20:12:42 +03:00
tophf
4283cc53a7 use the global line wrapping option in moz-export popup 2018-07-22 20:08:13 +03:00
tophf
662b4f8e49 don't show "saved" note in linter config
* because we don't show it anywhere else
* disabling the save button is a sufficient indicator used by lots of apps
2018-07-22 19:58:40 +03:00
tophf
126d909ca7 use a typical OS order for #help-popup buttons
* horizontally centered in Windows
* right-aligned otherwise
2018-07-22 19:55:27 +03:00
tophf
87da06037f make showCodeMirrorPopup modal
closes #437
2018-07-22 19:37:49 +03:00
tophf
03d02ad405 use codemirror theme in usercss installer page 2018-07-22 17:46:42 +03:00
tophf
67f48d5e60 make a copy of the applies-to template
fixes #442
2018-07-22 16:36:50 +03:00
Rob Garrison
2cb87d44e0 Another vendor readme fix 2018-07-21 13:49:07 -05:00
Rob Garrison
59d80c32c4 Vendor readme fixes 2018-07-21 13:46:48 -05:00
tophf
c6724b02d3 code cosmetics: pacify eslint 2018-07-21 21:04:47 +03:00
Rob Garrison
c61d34d053 Update libraries (#440) 2018-07-21 20:58:54 +03:00
tophf
b781c2b7b3 properly remove dead swatches 2018-07-20 17:51:43 +03:00
tophf
9266d6bbc5 clarify help text for url: search 2018-07-17 16:40:01 +03:00
tophf
247452b68a
use explicit line breaks instead of trailing spaces 2018-07-17 14:46:43 +03:00
tophf
2e95fcc32b code cosmetics: spaces 2018-07-17 11:34:35 +03:00
tophf
6f64bd840c code cosmetics: strip trailing spaces 2018-07-17 11:24:13 +03:00
narcolepticinsomniac
70b8a1172f Responsive layout (#410) 2018-07-16 19:37:01 +03:00
tophf
165f7b5684 don't add varDef to code if there are no vars 2018-07-15 17:55:54 +03:00
stonecrusher
e60628b51a Update on CONTRIBUTING.md (#430)
Update contribution guidelines
2018-07-14 19:56:26 +03:00
tophf
513e4337eb 1.4.16 2018-07-13 08:51:18 +03:00
tophf
290ea9f1ee use "matches" since "include_globs" is buggy in FF
see #428
2018-07-13 08:51:08 +03:00
tophf
64d26481c3 rebuild stylelint bundle 2018-07-13 08:40:51 +03:00
tophf
f7ab87ddcb remove the no longer needed file 2018-07-13 08:40:16 +03:00
tophf
36f9609a14 site is optional in @author
fixes #429
2018-07-13 00:25:47 +03:00
tophf
d8627f3768 recognize .user.css URLs with params
fixes #428
2018-07-12 15:18:34 +03:00
stonecrusher
d5cb08011e updated links, reworked help (#426)
Update README.md
2018-07-11 22:22:38 +03:00
tophf
b5b0bcaf19 tabs should open next to the manager tab
closes #427
2018-07-11 19:04:05 +03:00
tophf
17d81099b1 1.4.15 2018-07-11 16:11:56 +03:00
tophf
0a6135c2cc update locales 2018-07-11 16:11:48 +03:00
tophf
cfdd276bdc rebuild stylelint 8.0.0
npm 5.6.0
node 9.10.1
2018-07-11 16:08:40 +03:00
tophf
dccde14614 LESS 3.6.0
Allows plain conditions in if(true, 1, 2) (vs. if((true), 1, 2))
Fixes svg-gradient() for Firefox
2018-07-11 08:27:03 +03:00
tophf
8782d34f14 1.4.14 2018-07-10 11:46:20 +03:00
tophf
e51c632db6 fixup 74ef2f6f: 'editors' is a const 2018-07-10 11:45:52 +03:00
tophf
26aab6c926 update locales 2018-07-10 11:37:13 +03:00
tophf
26f673f30d move linter worker loaders to edit/ 2018-07-10 11:35:19 +03:00
tophf
9cdacc85ec build stylelint with a script
* the new one: https://github.com/openstyles/stylelint-bundle/tree/v8.0.0
* the old one was built manually so it was hard for AMO reviewers to repro
2018-07-10 10:55:43 +03:00
tophf
279c8c12e5 we don't modify stylelint per se, we only bundle it 2018-07-10 10:55:43 +03:00
tophf
d053cc4d39 typo 2018-07-09 16:48:44 +03:00
stonecrusher
df691b7a13 Adding external licenses (#424)
Add/update license info
2018-07-09 16:39:31 +03:00
tophf
fb275ec777 LESS 3.5.3 2018-07-09 15:59:19 +03:00
tophf
15c3c7c8ab fixup 3418ac9c: explicitly set the optional parameter
fixes #423
2018-07-09 09:10:36 +03:00
stonecrusher
7869e6e96a Update release links
- removed Firefox Beta
- added note to opera release
2018-07-08 21:27:19 +03:00
tophf
e6131d48da 1.4.13 2018-07-08 12:57:23 +03:00
tophf
07925f113a update locales 2018-07-08 12:56:13 +03:00
tophf
3bb4e0af9f autosize filters only if the width > 0 2018-07-07 20:47:00 +03:00
tophf
796b2b132d FF execCommand bug workaround needs 'input' event dispatched
fixes #419
2018-07-06 12:37:35 +03:00
tophf
c09f7c341c use more of webRequest info to restrict stripResources 2018-07-06 00:20:01 +03:00
tophf
7f4bc71a23 1.4.12 2018-07-05 22:50:37 +03:00
tophf
fbd0b96f49 fixup 7f5a5fec: give iframe time to run our content script 2018-07-05 22:49:47 +03:00
tophf
41e2d43ecc fixup 7c9fd5e6: the enclosed code had nested backticks! 2018-07-05 22:49:28 +03:00
tophf
6c07e8a223 1.4.11 2018-07-05 22:18:29 +03:00
tophf
54bd8effea update locales 2018-07-05 22:18:22 +03:00
tophf
7f5a5fecbf invoke USO style API in iframe
fixes #417
2018-07-05 22:15:45 +03:00
tophf
626030c42c run a cache cleanup next time if popup is closed too soon 2018-07-05 15:46:01 +03:00
tophf
0d7b8152e8 code cosmetics 2018-07-05 15:46:01 +03:00
tophf
d8b776bedf try installing from full code if 'sections' is empty in style json
fixes #414
2018-07-05 15:46:01 +03:00
tophf
9992ae3374 explicitly parse a text response into JSON 2018-07-05 11:40:23 +03:00
tophf
561e7c585b use monospace + pre in usercss parsing warning 2018-07-04 19:32:02 +03:00
tophf
766a38e9e8 polyfill Error.captureStackTrace in FF
fixes #412
2018-07-04 19:21:21 +03:00
tophf
01ffcf63e4 use js from http://stylus-lang.com/try/stylus.min.js 2018-07-04 19:20:52 +03:00
tophf
770163f40b 1.4.10 2018-07-04 15:39:30 +03:00
tophf
802da575a8 update locales 2018-07-04 15:39:29 +03:00
tophf
7c9fd5e611 spoof USO referrer for their style search API
fixes #413
2018-07-04 15:39:27 +03:00
tophf
5b2dba4cdf 1.4.9 2018-07-04 01:23:50 +03:00
tophf
3f761973e0 update locales 2018-07-04 01:22:50 +03:00
tophf
2c22d98421 code cosmetics; old typo fixup 2018-07-04 01:22:49 +03:00
tophf
2bb00d2559 spoof Stylish installation check on USO
see #379
2018-07-04 01:22:46 +03:00
tophf
74ef2f6fcf editors isn't defined on some pages like install-usercss
fixes #411
2018-07-03 08:42:13 +03:00
tophf
d02d93f476 switch "Shortcuts" to "Wiki" in the popup
fixes #409
2018-07-02 18:28:38 +03:00
tophf
d37b113d0d retry on HTTP status 429 "Too Many Requests" 2018-07-02 17:20:22 +03:00
tophf
5e34c9705c 1.4.8 2018-07-02 12:22:40 +03:00
tophf
b49254aca2 colorConverter.format: passthru if string and no type given
fixes #408
fixes f7f679bb
2018-06-30 20:23:45 +03:00
tophf
361feb90d4 1.4.7 2018-06-29 18:23:32 +03:00
tophf
3c13f13ae2 FF workaround for broken execCommand and getSelection
closes #407
2018-06-29 13:00:25 +03:00
tophf
31ed15a8f6 update less.js to 3.50 beta
fixes #376
2018-06-28 13:25:50 +03:00
tophf
fc50ee2e2c disable '#header select' autosizing in Vivaldi 2018-06-27 15:42:35 +03:00
tophf
6fb6b4ee6a update locales 2018-06-19 02:58:08 +03:00
tophf
4dc0f33341 1.4.6 2018-06-19 02:45:08 +03:00
tophf
692cb29c11 beautify: don't keep space before ::pseudo elements 2018-06-15 08:24:36 +03:00
tophf
f6f6a7814f beautify: recognize the end of a condition 2018-06-15 08:24:36 +03:00
tophf
79c93ce54a typo 2018-06-15 08:24:35 +03:00
tophf
468b2f6499 CodeMirror: recognize 'zoom' CSS property 2018-06-15 08:24:35 +03:00
tophf
7fea2cfc9c Esc/Enter should only close colorpicker
fixes #401
2018-06-15 08:24:35 +03:00
tophf
28fe59f8c2 buttons are outside of option block and shouldn't be constrained
closes #399
2018-06-14 14:49:05 +03:00
tophf
a762d47795 CSSLint: function contents may start with a whitespace
#397
2018-06-12 12:51:04 +03:00
tophf
2b268fc589 CSSLint/CodeMirror: background-position-x and -y
These have been used for a long time in the real world and will finally get standardized by the upcoming CSS Backgrounds and Borders Module L4.

fixes #397
2018-06-12 12:31:12 +03:00
tophf
44f3a79353 CSS Logical Properties and Values L1 - CodeMirror 2018-06-10 12:42:41 +03:00
tophf
1619803a64 CSS Logical Properties and Values L1 (WD 2018-05-29)
https://drafts.csswg.org/css-logical/
2018-06-06 11:43:34 +03:00
tophf
711a3afeee logQueue can be empty 2018-05-24 21:09:00 +03:00
tophf
f0c31f75b3 CSS Containment L1 (CR 2018-05-24)
https://www.w3.org/TR/css-contain-1/
2018-05-24 12:53:36 +03:00
tophf
261b74d6ad 1.4.5 2018-05-17 19:00:08 +03:00
tophf
0e81a4679d typo: FF doesn't have window.event 2018-05-17 01:33:18 +03:00
tophf
349c33b478 set even/odd class based on html { --columns: # } variable 2018-05-16 03:53:38 +03:00
tophf
1d0ca613f9 handleUpdate may alter/add an entry which needs to be sorted 2018-05-15 14:56:12 +03:00
tophf
68165e8fa2 filters affect striping, not the sort order 2018-05-15 12:21:30 +03:00
tophf
de2986a7c1 1.4.4 2018-05-14 09:01:32 +03:00
tophf
82b797738a use Alarms API since js timers are limited to 596 hours
fixes #388
2018-05-14 08:56:31 +03:00
tophf
d149ab662c 1.4.3 2018-05-12 15:12:08 +03:00
tophf
3282994b8f group FF-related CSS 2018-05-12 13:26:39 +03:00
tophf
d978322be8 revert 983e944: constrain options dialog size
fixes #387
2018-05-12 13:20:30 +03:00
tophf
41198e0b48 [Chrome 66+] expand advanced options in MD-exts 2018-05-09 20:52:45 +03:00
tophf
d36fea27ad fixup 3418ac9c: append to updateLog 2018-05-09 18:33:28 +03:00
tophf
3548a6caed fixup c26fa76f: parameter is an object =_=' 2018-05-09 18:11:59 +03:00
tophf
5730eb1206 bump version 2018-05-06 13:22:50 +03:00
tophf
22e76cc5f2 update locales 2018-05-06 13:22:34 +03:00
tophf
e354a4af94 add indent-fold.js for stylus preprocessor 2018-05-06 13:17:39 +03:00
tophf
5c444b4b96 draw fold marks in CSS since some fonts may not have them 2018-05-06 13:11:19 +03:00
tophf
10a0fedd05 make sure BG.API_METHODS is defined 2018-05-05 20:17:33 +03:00
tophf
f214e6a31b bump version 2018-05-04 22:31:28 +03:00
tophf
6da7328d08 update locales 2018-05-04 22:29:13 +03:00
tophf
f5750c7ab6 properly start live-preview after first save 2018-05-04 22:27:14 +03:00
tophf
1f347df8cf fixup c26fa76f: Set#has
#380
2018-05-04 22:08:19 +03:00
Frank Dana
d0115acdf2 Change target of CSSLint "full list of rules" link
The "See a full list of rules" link in the CSSLint settings popup currently points to https://github.com/CSSLint/csslint/wiki/Rules-by-ID which is... rather sparse.

Instead, link to https://github.com/CSSLint/csslint/wiki/Rules 

It contains all of the same rules / documentation-page links, but presents slightly more information to the user up front, without forcing them to click on everty rule for an explanation of what it is.
2018-05-04 14:23:04 +03:00
tophf
05dbcff7c3 insert spaces on <Tab> when editor.indentWithTabs is false 2018-05-01 23:13:53 +03:00
tophf
923f55d532 bump version 2018-04-30 20:45:42 +03:00
tophf
8f203c7a1e update locales 2018-04-30 20:45:37 +03:00
tophf
c26fa76f53 retry the update check on 503
fixes #380
2018-04-30 20:05:52 +03:00
tophf
9aea35799d tweak USO handshake to match Stylish
fixes #379
2018-04-30 19:31:43 +03:00
tophf
f9dd704134 CSS Grid L2 (WD 2018-04-27) added aspect-ratio 2018-04-28 10:17:16 +03:00
tophf
fbdfc68022 CSS Display Module Level 3 (ED 2018-04-20) 2018-04-27 17:15:01 +03:00
tophf
0a082f30d2 Chrome with NativeCrxBindings: ignore lastError in injectCS 2018-04-25 10:37:07 +03:00
tophf
677bf7b9bf Chrome with NativeCrxBindings: check lastError in injectCS 2018-04-24 22:16:21 +03:00
tophf
4a1c1636fe bump version 2018-04-19 20:02:23 +03:00
tophf
8de37d300c update locales 2018-04-19 20:02:23 +03:00
tophf
5ef347a4d9 LESS preprocessor
closes #373
2018-04-19 20:02:23 +03:00
tophf
0614aa2eee new editor option: selectByTokens
implements #361 except for toggling via Ctrl
2018-04-18 19:33:36 +03:00
tophf
f7f679bbf9 colorpicker: keep internal HSV
fixes #372
2018-04-17 22:35:23 +03:00
tophf
58f4fbec41 colorConverter.format: use color.type by default 2018-04-17 22:34:55 +03:00
tophf
8cad7d61eb scrollElementIntoView: skip if orphaned 2018-04-17 22:34:18 +03:00
tophf
97178eca46 bump version 2018-04-13 14:30:53 +03:00
tophf
32f05861e3 FF: register hotkeys on startup; reset if empty 2018-04-13 14:30:36 +03:00
tophf
5bc6ce33be bump version 2018-04-12 21:32:08 +03:00
tophf
e80efa7604 FF: hotkeys dialog 2018-04-12 21:28:45 +03:00
tophf
ff9e37ec5f messageBox: keep children specified via appendChild in buttons 2018-04-12 21:02:02 +03:00
tophf
5b9fd4454b $create should read opt.appendChild if selector is string 2018-04-12 20:42:01 +03:00
tophf
3d6b46a14b bump version 2018-04-12 09:14:23 +03:00
tophf
2a75159d2a USO bug workaround: collapse long URL vars
#195
2018-04-12 09:13:55 +03:00
tophf
1d7437d181 revert 07e1d3b9, USO still can't handle POST properly 2018-04-12 07:37:51 +03:00
tophf
9f10a30067 bump version 2018-04-11 13:01:15 +03:00
tophf
16d46edfba increase USO style installation/update timeout
#195
2018-04-11 12:55:23 +03:00
tophf
07e1d3b902 USO can handle POST now
#195
2018-04-11 12:55:23 +03:00
tophf
c51a345689 bump version 2018-04-09 17:33:35 +03:00
tophf
4b0a71918a update locales 2018-04-09 17:33:10 +03:00
tophf
8524c76f66 setBadgeText has a callback in Chrome 67+ 2018-04-05 00:41:05 +03:00
tophf
5174e7481f stricter "var(" check and code cosmetics 2018-04-04 11:37:39 +03:00
tophf
1cc8ac7559 autocomplete for --css-variables inside var() 2018-04-03 21:39:09 +03:00
tophf
745d16b488 bump version 2018-03-31 17:16:45 +03:00
tophf
5d684b3d7d update locales 2018-03-31 17:16:44 +03:00
tophf
009970965f let openURL() replace browser-specific New/empty Tab Page 2018-03-30 03:23:21 +03:00
tophf
a2c80f7017 Vivaldi requires tabindex="0" for <a> with svg icon inside 2018-03-29 06:37:04 +03:00
tophf
5a6a403cc9 use <a> wrapper for the toggle icon in options 2018-03-29 06:27:37 +03:00
tophf
d4c3df6a09 bump version 2018-03-28 14:20:54 +03:00
tophf
983e94473f don't constrain options page width in Chrome
1. it wasn't actually really in Chrome-like browsers
2. it caused wrong sizing due to a bug introduced in https://crrev.com/c/967456
2018-03-23 14:39:22 +03:00
tophf
9969266379 FF60+: show additional info in popup on AMO
#312
2018-03-23 01:44:40 +03:00
tophf
18fc5fc1e5 bump version 2018-03-22 04:37:18 +03:00
tophf
36b0e8f4bb clear entire cache when updating styles with global sections 2018-03-22 04:26:43 +03:00
tophf
89d4bb1ed4 handle chrome:// scheme in openURL() 2018-03-22 03:09:20 +03:00
tophf
b185140176 show an error for misplaced @document
#367
2018-03-21 09:32:32 +03:00
tophf
dd5cd5c686 correctly show "Everything" in applies-to column
* don't show it twice
* show it if the style targets were actually removed since the last paint
2018-03-19 07:10:59 +03:00
tophf
65905edec9 parserlib actions are void 2018-03-18 07:10:33 +03:00
tophf
0a4f0663d0 bump version 2018-03-15 20:37:27 +03:00
tophf
71b478fe98 use CM theme for applies-to buttons 2018-03-15 20:15:23 +03:00
tophf
f2d49ecbb9 resolve activateTab() to tab instead of [tab, window] 2018-03-14 22:00:25 +03:00
tophf
06ded49131 openURL+message: use onTabReady instead of repeated sending
because the tab may take many seconds to start loading depending on connectivity etc.
2018-03-14 05:58:28 +03:00
tophf
de0920da53 enable 'editor.autoCloseBrackets' in fresh installs by default
because now that we have LivePreview enabled by default typing a single { breaks the style until a closing } is entered.
2018-03-13 20:43:19 +03:00
tophf
4901e97f9f open USO style settings even if the site tab is auto-activated 2018-03-13 18:35:28 +03:00
tophf
a7774c26fb bump version 2018-03-13 17:24:10 +03:00
tophf
40054902e9 USO can't handle POST requests for style json 2018-03-13 17:23:47 +03:00
tophf
64f18ab901 bump version 2018-03-13 00:15:34 +03:00
tophf
5c04e1100d hide the weird gap in Chrome 66+, see https://crbug.com/821143 2018-03-13 00:14:59 +03:00
tophf
34799263eb fixup 259f3732: only switch to POST if 'body' wasn't customized 2018-03-12 22:39:19 +03:00
tophf
6c62b9feac bump version 2018-03-12 21:41:48 +03:00
tophf
259f373207 properly cut URL#href on '?' when sending a POST request
fixes #365
2018-03-12 21:41:25 +03:00
tophf
f35a943726 bump version 2018-03-12 19:15:09 +03:00
tophf
dbba338229 report line:ch in live-preview errors for usercss 2018-03-11 16:47:27 +03:00
tophf
66704a78b3 actually use 'pre' font for code errors in messageBox.alert/confirm 2018-03-11 16:31:25 +03:00
tophf
32cd558dda parse a few nonstandard webkit CSS properties 2018-03-09 02:34:29 +03:00
tophf
28ef5572ba FF: ensure styles are applied to about:blank iframes
fixes #215
2018-03-08 19:25:09 +03:00
tophf
2eb0a309b5 bump version 2018-03-04 16:30:17 +03:00
tophf
850b7dc635 clear localStorage for CM themes on extension update 2018-03-03 23:45:14 +03:00
tophf
f9789e327b show the new CM themes in the editor options 2018-03-03 23:36:29 +03:00
tophf
2c86f2f4b9 move commentSelection command to other editing commands 2018-03-03 23:36:29 +03:00
tophf
6e8ff5b9ef simplify toggleEditorFocus now that CM 5.35 handles Ctrl-Pause 2018-03-03 23:36:29 +03:00
tophf
77d44c233e preUpdateLinting hack isn't needed since CM 5.33 2018-03-03 23:36:28 +03:00
tophf
513845c289 CodeMirror 5.35.1 2018-03-03 23:36:28 +03:00
tophf
5acf815b79 report invalid selector in :not() as a warning
to prevent failures when updating usercss styles that have to override [currently] invalid :not() selectors used by the site

see #356
2018-03-03 17:28:29 +03:00
tophf
808ad0f059 bump version 2018-03-02 18:55:59 +03:00
tophf
fa2b6f07ce send style status to USO even more insistently
see #354
2018-03-02 18:08:25 +03:00
tophf
e6b486d25f bump version 2018-03-02 15:58:39 +03:00
tophf
049c131e77 update locales 2018-03-02 15:58:23 +03:00
tophf
db256f73f5 send style status to USO twice if #install_button reappears
see #354
2018-03-02 15:55:39 +03:00
tophf
b220b2d2f0 code refactor: define parser actions just once 2018-03-01 21:26:57 +03:00
tophf
3a68c4e636 CSSLint: parse CSS4 :matches(), the future of :any() 2018-03-01 21:04:39 +03:00
tophf
e4c399a1c0 try to ignore /*[[USO-var]]*// first 2018-02-28 21:16:00 +03:00
tophf
696690c8da
show invalid :not() as a nonfatal error (#357) 2018-02-28 20:53:50 +03:00
tophf
0ba26072f7 restore Chrome 49 compatibility: remove "u" flag in RegExp
since it wasn't used globally (e.g. vendor code) it made no real difference
2018-02-28 05:15:28 +03:00
tophf
6b0628a7ee CSS containment was buggy in Chrome before 58.0.3004
fixes #355
2018-02-28 05:04:35 +03:00
tophf
85f5f72832 bump version 2018-02-27 21:35:45 +03:00
tophf
d4b4b07ab3 [Chrome] restore the install/update button functionality on USO
resolves #354 in Chrome only since the USO site is broken in FF
(the site checks for chrome-extension:// URL which should be moz-extension://)
2018-02-27 21:30:29 +03:00
tophf
d1f35a15e3 bump version 2018-02-27 12:10:28 +03:00
tophf
fd3a09eee9 ensure the state tooltip is above the sites 2018-02-26 23:20:25 +03:00
tophf
ab4f7f3e91 entry state may exceed entry bounds 2018-02-26 23:18:49 +03:00
tophf
0fd5d100c9 update filter stats after deleting a style 2018-02-26 23:16:10 +03:00
tophf
e4150aa8b0 sort only after filtering is complete 2018-02-26 22:57:03 +03:00
tophf
ceb11ae52a ignore dates and other meta data when diffing 2018-02-26 22:56:42 +03:00
tophf
e42ea2e383 restore correct position of update state faux button tooltip 2018-02-26 22:55:30 +03:00
tophf
42c7f39e73 refilter just once on a single update job
fixes #353
2018-02-26 22:54:35 +03:00
tophf
fd496dd546 bump version 2018-02-25 16:51:21 +03:00
tophf
a8769e375b browser.runtime.getBrowserInfo was added in FF 51 2018-02-25 16:51:07 +03:00
tophf
f40c9f9a16 update locales 2018-02-25 16:46:21 +03:00
tophf
589cc53ad9 adjust selector for "config on homepage" of USO styles 2018-02-23 15:14:10 +03:00
tophf
4e4f0501d2 fixup: add the empty line correctly 2018-02-22 18:34:15 +03:00
tophf
4bb1a191cc replace the last @-moz-document if present in a usercss template
when creating a new style for the site via popup
see #352
2018-02-22 12:59:56 +03:00
tophf
c5ef92cf9c add the site section to a custom usercss template for new styles
fixes #352
2018-02-22 12:41:55 +03:00
tophf
d0d429bd8e bump version 2018-02-17 14:21:54 +03:00
tophf
7f70445174 update locales 2018-02-17 14:20:54 +03:00
tophf
918888ffb0 code cosmetics 2018-02-16 18:05:25 +03:00
tophf
d82dceada9 code cosmetics 2018-02-16 12:49:53 +03:00
tophf
b9b2c4cbd7 correctly finish check-all-updates before updating UI
now that we use messaging for the observer we can't use Promise for the final task;
fixes #341
2018-02-16 12:43:22 +03:00
tophf
654f63b894 remove unused code
see #348
2018-02-15 16:48:37 +03:00
tophf
c564aab48f code cosmetics 2018-02-15 16:48:00 +03:00
tophf
683e73ceb9 close the source tab in case the port didn't report onDisconnect
fixes #349
2018-02-15 16:47:42 +03:00
DecentM
44a11508ff Add OpenUserCSS support (#328) 2018-02-15 11:27:00 +03:00
narcolepticinsomniac
8821c2f23f Prevent traditional button active state from applying to usercss install button (#346) 2018-02-14 05:58:27 +03:00
tophf
e3d1c6588d prefill new style name with the domain/hostname
implements #344
2018-02-14 05:53:35 +03:00
narcolepticinsomniac
c1b47e4b23
Style non-select filter labels to match
Non-select filter labels and their contents were misaligned. They were also shorter with lighter hover backgrounds. Everything should match up now. There's only one currently, but I used general selectors which should work in case any new ones are added.
2018-02-13 16:44:21 -05:00
tophf
e84afd9a20 fix a copypaste error 2018-02-03 06:31:43 +03:00
tophf
4772178689 bump version 2018-02-02 09:04:47 +03:00
tophf
ddc6c3e1c3 update locales 2018-02-02 09:04:26 +03:00
tophf
7a479edc56 more consistent focus/scroll behavior of global search
* keep page scroll position on Esc/close
* focus the match on Enter
2018-02-02 09:04:25 +03:00
tophf
32f0f4bd7a preserve page scroll position after [de]beautification 2018-02-01 23:51:30 +03:00
tophf
f6991c4f57 fallback to 'path' when Canvas is blocked in FF
fixes #335
2018-01-30 19:42:30 +03:00
tophf
95a24cd29b catch fatal parsing errors 2018-01-30 18:59:28 +03:00
tophf
02989edb05 eat unclosed comments 2018-01-30 18:59:28 +03:00
tophf
90aacefff8 ignore @charset when deciding if section is empty
fixes #337
2018-01-30 18:59:28 +03:00
tophf
ca5f8c941b don't refresh own tabs twice
fixes #336
2018-01-29 04:37:24 +03:00
tophf
4719088d39 use (i) icon in options for the extra info
#334
2018-01-24 23:22:27 +03:00
tophf
545f0a3622 bump version 2018-01-24 03:48:00 +03:00
tophf
10b82ae7cc actually import settings from sync
fixes #331
2018-01-24 03:47:26 +03:00
tophf
5b4ecfc3e4 fix click area of filter checkboxes
#332
2018-01-24 03:26:52 +03:00
tophf
b03d9030e4 bump version 2018-01-23 18:01:14 +03:00
tophf
d94ded8d94 update locales 2018-01-23 18:00:20 +03:00
tophf
75a9ce4696 don't overwrite url in stylus-iframe attr with "true" 2018-01-20 16:26:13 +03:00
tophf
cd794b981b bump version 2018-01-20 02:32:19 +03:00
tophf
bc2da3f66a prevent hanging when parent frame is absent 2018-01-20 02:28:20 +03:00
tophf
a3962b7adf put https://top.site.origin in "stylus-iframe" attr 2018-01-19 15:37:26 +03:00
tophf
75aee2085a load storage-util in all pages
prefs::doSyncSet uses it now, there'll be more in the future when we convert all direct chrome.storage calls
2018-01-19 15:14:09 +03:00
tophf
4dc6d56533 bump version 2018-01-18 20:42:31 +03:00
tophf
1c0cd2da9e show color swatches for rgb/hsl with unary + - in numbers 2018-01-16 15:11:07 +03:00
tophf
0fa391732b workaround for Chrome devtools bug (fixed in v65)
recreate the style element on style code change because older devtools inspector can't edit injected rules after we update textContent of an existing element
2018-01-15 19:43:35 +03:00
tophf
0f8bca03b8 fixup eaed0de4: don't enable livepreview for unsaved code 2018-01-15 19:16:48 +03:00
tophf
100f7716fd bump version 2018-01-14 18:36:16 +03:00
tophf
efbbe147e4 update locales 2018-01-14 18:36:02 +03:00
tophf
4493c9e9f0 don't double-process 'styleUpdated' in manager 2018-01-14 18:18:08 +03:00
tophf
dc1cd890ee notify event subscribers when toggling the style via Alt-Enter 2018-01-14 17:40:09 +03:00
tophf
72e0f5fbf5 update refreshAllTabs cache and icon on disabling livepreview 2018-01-14 17:32:25 +03:00
tophf
823926a025 fix getStyleAtPos() for pos === EOL 2018-01-14 17:11:00 +03:00
tophf
3c15521fc2 tweak autocomplete helper
* use the faster getStyleAtPos
* autocomplete !important on typing !
* don't autocomplete hex colors
2018-01-14 17:10:54 +03:00
tophf
eaed0de486 init autocomplete/blur/focus for usercss in a common hook 2018-01-14 15:57:29 +03:00
tophf
b42dfc8300 fixup bb34538d: decrement styles.length on delete 2018-01-14 15:40:36 +03:00
tophf
eabfaca08e run webNavUsercssInstallerFF on the entire githubusercontent.com
fixes #329
2018-01-14 15:23:09 +03:00
tophf
76d9d32dce skip uso-var between declarations 2018-01-12 15:01:13 +03:00
tophf
9005f93f56 bump version 2018-01-12 14:36:32 +03:00
tophf
fb1ef71f25 don't save the style in toggleStyle; use data-hotkey-tooltip 2018-01-12 14:32:15 +03:00
tophf
9affcd13bc don't preview unsaved styles 2018-01-12 14:11:24 +03:00
tophf
bb34538da0 smart invalidateCache: try to update filters in-place 2018-01-12 00:54:40 +03:00
tophf
989df35b05 live preview in editor
* refreshAllTabs was extracted
* ...and fixed to use each frame's url when getting the styles
2018-01-12 00:54:36 +03:00
tophf
0c2c86a8de update favicons in handleUpdate 2018-01-12 00:53:35 +03:00
tophf
b754635b81 lenient parsing of invalid single \ in regexp() function 2018-01-11 15:29:52 +03:00
tophf
650cf3521b correctly strip 'code' from style hash 2018-01-10 22:18:35 +03:00
tophf
9fdabe3582 simplify getStyles
* 'asHash' implies 'enabled'
* 'length' is added to the style hash
2018-01-10 22:18:30 +03:00
tophf
11dbfea897 apply.js: FF forgets the extra methods on MutationObserver 2018-01-10 19:50:48 +03:00
tophf
9aa382ebf5 disconnect an orphaned chrome.runtime message/port listener 2018-01-10 19:50:29 +03:00
tophf
885919e7d9 colorize namedcolor followed by ! without a space 2018-01-09 20:16:59 +03:00
tophf
bbfda6d33b expose findUsercss 2018-01-09 19:13:37 +03:00
tophf
68777f6163 bump version 2018-01-08 11:31:57 +03:00
tophf
79e95eadf2 code cosmetics 2018-01-07 23:26:47 +03:00
tophf
224771b34e reduce colorpicker alpha digits to 3 from 6 2018-01-07 20:02:58 +03:00
tophf
80ad6418aa keep alpha in hex colorpicker view 2018-01-07 20:00:22 +03:00
tophf
9111ebcd2b unget the unary token if got no term to finalize 2018-01-07 19:11:00 +03:00
tophf
acbb69e5ad expr may be null 2018-01-07 18:59:31 +03:00
tophf
b659dde35d bump version 2018-01-07 17:30:55 +03:00
tophf
50c4580f64 update locales 2018-01-07 17:30:55 +03:00
tophf
23fcbd6c27 fixup 7de3e37a: handleUpdateInstalled is for .updatable only 2018-01-07 16:53:41 +03:00
tophf
022e588c97 allow errors in usercss when saving in editor and live-reloading 2018-01-07 16:36:30 +03:00
tophf
3df4a86428 add a workaround for Chrome 65 bug https://crbug.com/714373 2018-01-07 15:12:14 +03:00
tophf
a6e2cf47ed don't update the tally when the dialog isn't shown 2018-01-07 12:52:31 +03:00
tophf
5941dd4338 colorpicker hotkey popup: find colors in attributes 2018-01-07 12:51:22 +03:00
tophf
825fd00a80 fixes for FF52 2018-01-07 12:50:17 +03:00
tophf
102d0a45c8 load colorconverter.js in style manager 2018-01-07 12:37:02 +03:00
tophf
67ceaa2e43 fixups; code cosmetics
* show #{min,max} if constraints are present
* parse [row names] in grid properties
* skip uso-vars in selector sequence
* recognize number tokens with +-
* skip comments/whitespace in stream.mustMatch();
2018-01-07 12:33:48 +03:00
tophf
57f0afbc9c CSS Intrinsic & Extrinsic Sizing L3 for *width/*height
https://drafts.csswg.org/css-sizing-3/#sizing-properties
2018-01-07 12:32:50 +03:00
tophf
e7bd155300 CSS Transform Module Level 2 (ED 2017-11-09) - 3d transforms
https://drafts.csswg.org/css-transforms-2/#three-d-transform-functions
2018-01-07 12:32:50 +03:00
tophf
e684f677a6 CSS Display Module Level 3 (ED 2017-11-09)
https://drafts.csswg.org/css-display/
2018-01-07 12:32:50 +03:00
tophf
2036819442 reuse parserCache on subsequent saving of usercss 2018-01-07 12:31:23 +03:00
tophf
d2cba96e10 refactor CSSLint
* reduce linting delay
* parse mozformat in worker
* allow empty functions in 'filter:' property
  https://drafts.fxtf.org/filter-effects/#supported-filter-functions
* support comma-separated list in :lang()
* strip vendor prefix in isLiteral()
2018-01-07 12:31:23 +03:00
tophf
b8506e1e45 find colors in comments/strings regardless of overlays 2018-01-07 11:52:46 +03:00
tophf
87d28d3fc7 silence eslint 2018-01-07 11:52:46 +03:00
tophf
807ea6aa70 extract colorconverter.js 2018-01-07 11:52:43 +03:00
tophf
1fe290fb8c bump version 2018-01-06 10:43:12 +03:00
tophf
eb426f6ee3 update locales 2018-01-06 10:42:30 +03:00
tophf
385dda9923 fixup 227dce01: new styles don't have usercssData 2018-01-06 09:50:48 +03:00
tophf
4a7c675d06 fix '.add-applies-to' click listener 2018-01-06 09:31:37 +03:00
tophf
42bd77ec17 beautify: keep semicolon after /*comment*/ on the same line 2018-01-05 14:10:27 +03:00
tophf
b32832e237 delete the unused original beautify-css.js 2018-01-05 14:07:16 +03:00
tophf
227dce0177 don't disable Beautify (let the user decide); code cosmetics 2018-01-05 14:05:35 +03:00
tophf
bced23052c remove some unnecessary deepCopy calls 2018-01-05 14:05:35 +03:00
tophf
45219a88c1 microoptimization: 'style' is already a deep-copy 2018-01-04 22:47:29 +03:00
tophf
c553c0270e unstick the unchecked newUI option from the buttons below 2018-01-04 22:36:31 +03:00
tophf
392ca4c988 add "configure" button in the old UI 2018-01-04 22:35:12 +03:00
tophf
1c432b2868 fixup 77a07b7f: don't invoke editor on clicking the name 2018-01-04 22:25:03 +03:00
tophf
66f176992b fixup 671b2765: don't show favicons in old UI 2018-01-04 22:20:03 +03:00
tophf
bd1e6175af bump version 2018-01-04 18:24:47 +03:00
tophf
71c3e0c7a8 extract and improve dummy chrome.storage in FF
* chrome.storage.onChanged supported in own pages
* values are stored in the background page
* chrome.storage in own pages accesses that background storage
2018-01-04 17:04:23 +03:00
tophf
bf17c7de94 preserve section indentation in usercss template 2018-01-04 16:45:41 +03:00
tophf
4674424764 code cosmetics 2018-01-04 16:44:34 +03:00
tophf
2374c88e1b extract styleSectionsEqual 2018-01-04 16:43:54 +03:00
tophf
9be2f942c7 restore default template on saving empty code
fixes 3418ac9c
2018-01-04 16:41:55 +03:00
tophf
cb3e9973bd also display #live-reload-install-hint after installing 2018-01-04 13:43:57 +03:00
tophf
2ca702c976 show color swatches on usercss installer page 2018-01-04 13:36:56 +03:00
tophf
a339b50e27 allow live-reload without reinstalling 2018-01-04 13:36:27 +03:00
tophf
c9e60dc19b t() is not defined in content scripts 2018-01-04 11:13:40 +03:00
tophf
e6d04fad6d meta value starts after a name on the same line 2018-01-04 11:10:59 +03:00
tophf
d94b9a0ab7 fixup: show available updates on manual check 2018-01-03 20:26:20 +03:00
tophf
eb3c770612 bump version 2018-01-03 18:45:21 +03:00
tophf
1eea8fdbbf fixups for refreshAllTabs 2018-01-03 18:26:31 +03:00
tophf
d346cb0a5a reduce newUI entry vertical padding and define it in one place 2018-01-03 16:53:00 +03:00
tophf
9165e6c1e2 unstick #search-results-error from the buttons block 2018-01-03 14:07:18 +03:00
tophf
eb65ce1a88 bump version 2018-01-03 10:47:06 +03:00
tophf
a572620765 cache icon imageData because the browser doesn't 2018-01-03 10:44:12 +03:00
tophf
3f570c4d3a FF injects content script automatically 2018-01-03 10:44:12 +03:00
tophf
28e9e38dad remove 'dysfunctional' page 2018-01-03 10:44:12 +03:00
tophf
3418ac9cb9 FF: support private/container tabs 2018-01-03 10:43:56 +03:00
tophf
62e333a0ba update locales 2018-01-01 14:14:43 +03:00
tophf
27fe9fa9db search/replace in extra CodeMirror boxes e.g. lint config 2018-01-01 10:35:22 +03:00
tophf
b2100ea853 fixes for global search/replace
* Enter key in input fields:
  * [Find mode] closes the dialog and focuses the matched text
  * [Replace mode] performs a single replace action

* Undo button checks the new CM changeGeneration and disables itself
  if the changes were already undone

* doUndo focuses the visible undo button
2018-01-01 09:56:41 +03:00
Rob Garrison
671b276532 Attempt to get favicon for RegExp match (#321)
show favicons for regexp() in applies-to column
2018-01-01 08:17:43 +03:00
tophf
60a6fdb481 clear previous update status classes 2018-01-01 08:04:52 +03:00
tophf
5bc4206593 reuse existing usercss installer tab
A few additional checks were needed to circumvent FF bugs
so openURL was refactored to keep the code readable
2017-12-31 17:59:32 +03:00
narcolepticinsomniac
0368759081
Fix overlapping hover backgrounds 2017-12-31 04:25:58 -05:00
tophf
205b9ab73f
replace the editor screenshot 2017-12-31 08:34:00 +03:00
tophf
8153a03c19
Add highlights and screenshots sections to readme (#320)
* Add highlights and screenshots sections to readme
2017-12-30 16:19:10 +03:00
tophf
319b2c2411 bump version 2017-12-30 04:34:55 +03:00
tophf
5e95193ed8 update locales 2017-12-30 04:34:30 +03:00
tophf
46a3038394 don't add soft hyphens at the end of text 2017-12-29 23:37:17 +03:00
tophf
441de984b0 make action buttons in popup auto-fit contents
several languages have labels of wildly different lengths so we try to maintain the proportion
2017-12-29 20:27:37 +03:00
tophf
16f98ed250 auto-adjust #add-style-wrapper to various font height 2017-12-29 20:27:37 +03:00
tophf
fef10b1638 use a readable font for Japanese/Chinese 2017-12-29 20:23:54 +03:00
tophf
0f96e2fa4d set language for CSS :lang and [FF-only] hyphenation 2017-12-29 18:19:35 +03:00
tophf
dea0edbdac don't wrap entry labels 2017-12-29 18:19:25 +03:00
tophf
673906cfd5 don't cut the text in a closed sort selector
#319
2017-12-29 17:54:15 +03:00
tophf
af6c3a79d5 don't show update buttons for local styles in old UI
#319
2017-12-29 17:53:11 +03:00
tophf
5ac3662699 fixup 5a07bbb1: parse ISO date strings
#319
2017-12-29 17:52:47 +03:00
tophf
a0b2d0ef68 typo in description 2017-12-29 13:22:41 +03:00
tophf
a66c377d8a fix scrolling over linter issues in usercss mode 2017-12-28 07:01:43 +03:00
tophf
c1dd196acd fix regexp search in manager 2017-12-28 07:01:18 +03:00
tophf
d9f8d1361f bump version 2017-12-26 14:42:58 +03:00
tophf
05c9e6db0c update locales 2017-12-26 14:42:26 +03:00
tophf
743deb14c9 CSSLint: validations for animation, background, cursor and more
* CSS Animations Level 1 (ED 2017-11-29) https://drafts.csswg.org/css-animations/
* validation for background, border-image, cursor, text-shadow, background-position
2017-12-26 13:37:25 +03:00
tophf
b6f0b4a44f CSSLint: CSS Timing Functions Level 1 (WD & ED 2017)
WD 2017-02-21 https://www.w3.org/TR/css-timing-1/
ED 2017-12-03 https://drafts.csswg.org/css-timing/
2017-12-26 12:46:27 +03:00
tophf
6e0cb2bc86 CSSLint: validate using an unprefixed definition 2017-12-26 12:14:18 +03:00
tophf
1749f06674 CSSLint: CSS Transform Module Level 2 (ED 2017-11-09)
https://drafts.csswg.org/css-transforms-2/
2017-12-26 12:14:18 +03:00
tophf
c3cb687db6 CSSLint: CSS Transforms Module Level 1 (WD 2017-11-14)
https://drafts.csswg.org/css-transforms/
2017-12-26 11:51:48 +03:00
tophf
b8d1a0a9ff CSSLint: expose function's inner expression 2017-12-26 11:50:29 +03:00
tophf
e4f8cf5fb5 simplify usePrefsDuringPageLoad 2017-12-26 08:54:01 +03:00
tophf
4da6eeb746 manage: speed up first meaningful paint
by postponing creation of favicon placeholders for the visible entries to the second render run when rendering in chunks or after all styles were displayed when rendering the entire list
2017-12-26 08:52:19 +03:00
tophf
8c5ad8fe4b postpone addTooltipsToEllipsized more to avoid accidental layout 2017-12-26 08:46:05 +03:00
tophf
afbee9d68f CSSLint: more microoptimizations 2017-12-26 06:28:27 +03:00
tophf
37f7f1898f fixup 1406cae6: ) may belong to the parent, also fix readString 2017-12-25 15:32:07 +03:00
tophf
fc673fe9c6 fixup ea709c93: remove the unused variable 2017-12-25 12:25:53 +03:00
tophf
d3c0999541 CSSLint: fixes and tweaks to reduce memory consumption
* _hexcolor - actually validate length
* all number regexps - support +- in the exponent
* readCount - single slice
* readMatch - use sticky regexps or string comparison on a chunk of pattern length
* readComment - single sticky match & slice
* readWhile - collect in an array, then join
* PropertyValuePart - do native num/str checks first
* isXXX - do a string comparison first
2017-12-25 12:25:19 +03:00
tophf
1406cae6c5 CSSLint: parse <declaration-value> for --custom-property
https://drafts.csswg.org/css-syntax-3/#typedef-declaration-value

Example:

:root {
  --fit: {
    position: absolute;
    top: 0; bottom: 0;
    left: 0; right: 0;
  }
}
2017-12-25 12:25:19 +03:00
tophf
12fe1b619f render 20+ styles at once
so that the page on a typical 1080p display is completely filled in initial frame at 200ms
2017-12-25 12:18:24 +03:00
tophf
53eac84312 load visible favicons immediately, lazy-load the rest 2017-12-25 12:18:24 +03:00
Rob Garrison
5a07bbb1e3 Add manager sort block 2017-12-25 12:17:18 +03:00
Rob Garrison
1fd0c26e1d MessageBox: Add focus to OK button 2017-12-25 10:45:11 +03:00
tophf
f2efff64fd FF weird bug workaround: delay initLint() by 100ms 2017-12-25 09:28:26 +03:00
tophf
5df76b04e2 disable #save button right after opening a style 2017-12-25 02:26:01 +03:00
tophf
4b4b65d961 colorview: support a signed number exponent 2017-12-25 02:21:25 +03:00
tophf
b70beac3c9 CSSLint: rewrite readNumber() 2017-12-25 02:20:53 +03:00
Rob Garrison
4b2bfd4113 CSSLint: Remove tabs causing properties to be ignored 2017-12-25 01:35:01 +03:00
Rob Garrison
b2ea9be73f CSSLint: Add text-decoration-skip 2017-12-25 01:35:01 +03:00
tophf
1040c20330 don't autohide colorpicker popup when invoked via hotkey 2017-12-24 14:33:58 +03:00
tophf
a53fb162a8 unbind 'display' listeners on first run 2017-12-24 14:28:25 +03:00
tophf
306b21b75e show Ctrl-Pause hotkey in keymap info using a dummy command 2017-12-24 12:28:33 +03:00
tophf
8decffc6b5 FF52 workaround: only transform the outer svg 2017-12-24 11:12:13 +03:00
tophf
57806bed45 don't set sessionStorage.justEditedStyleId to null 2017-12-24 02:37:26 +03:00
tophf
487bc77baa actually replace 'usercssTemplate' 2017-12-24 01:50:53 +03:00
tophf
9279390e8c handle double-click between number and % 2017-12-23 09:51:28 +03:00
tophf
9f00e5a2f7 update locales 2017-12-23 07:25:26 +03:00
tophf
8c96165fb4 refactor and improve selectTokenOnDoubleclick logic 2017-12-23 05:39:06 +03:00
tophf
a249167539 remove the no longer used defocusEditor command 2017-12-22 18:35:46 +03:00
tophf
d6c595d94e detect double-clicked token boundaries better 2017-12-22 16:55:56 +03:00
tophf
068f23b029 fixup: include -+, exclude whitespace at line start 2017-12-22 16:29:52 +03:00
tophf
bf6b4eda83 select entire CSS token on double click
* .class-name
* property-name
* #some-id
* #123
* -webkit-any
* !important
* 12.5
2017-12-22 16:23:20 +03:00
tophf
a2644fdaba update locales 2017-12-22 12:05:19 +03:00
tophf
c958186245 FF workaround: set position:fixed prior to appending 2017-12-22 11:52:53 +03:00
tophf
8f71a9f051 temporarily patch codemirror::mode::stylus to see CSS4 hex colors 2017-12-22 11:22:36 +03:00
tophf
d82efe37b5 rewrite colorpicker popup positioning to prevent occlusion 2017-12-22 11:22:35 +03:00
tophf
d0380f76c3 rewrite colorview to use CodeMirror::TextMarker
* solves all problems with glitching on selection etc.
* perceived performance is same due to lazy-processing
* colors unsupported in current browser are displayed internally as RGB
* the color text is highlighted in the editor when popup is invoked
2017-12-22 11:22:35 +03:00
tophf
2dfaa22c35 Ctrl-Pause defocuses/focuses the editor 2017-12-22 11:22:02 +03:00
tophf
2d12bfd1f5 l10n: actually stop observing 2017-12-22 11:22:02 +03:00
tophf
e9a2cb92e3 csslint: functions MUST end with ) 2017-12-22 11:22:02 +03:00
tophf
d5d863d998 disable incremental search when #message-box is shown
fixes #313
2017-12-22 10:53:22 +03:00
tophf
4946aad684 FF: allow access to AMO in FF (actually works in 59+)
fixes #312
2017-12-22 08:36:10 +03:00
tophf
7d8507743d add the missing CSS colors to codemirror parser 2017-12-20 00:42:51 +03:00
tophf
c34786358a csslint: CSS4 syntax for rgb/hsl 2017-12-20 00:42:51 +03:00
tophf
4ddd78d40a reuse global.css for button style 2017-12-19 08:48:55 +03:00
tophf
3178ee9f10 more reliable centering of the popup in FF 2017-12-19 08:48:55 +03:00
tophf
a8f292815a don't stretch the usercss-install button 2017-12-19 08:48:55 +03:00
tophf
154187f1bc use offsetWidth to decide if the button text is ellipsized 2017-12-19 08:48:55 +03:00
tophf
78080df6fd show "click to uninstall" overlay, hide install/delete buttons 2017-12-19 08:48:54 +03:00
tophf
80926c8d7e show download errors inline 2017-12-19 05:29:21 +03:00
tophf
9e1e5cec46 update locales 2017-12-19 03:32:15 +03:00
tophf
e50ff316ba toggle narrow width mode tooltips via html+css; code cosmetics 2017-12-19 02:48:47 +03:00
tophf
1348eeb4e3 code cosmetics 2017-12-18 16:48:33 +03:00
tophf
8bfc36efbe csslint: warn about @media inside @supports 2017-12-18 12:18:54 +03:00
tophf
a7a589b785 csslint: CSS Grid Layout - actual implementation 2017-12-18 12:17:42 +03:00
tophf
4ecb6e7bc2 optimistically show 1 in tally only for a code match 2017-12-18 11:28:11 +03:00
tophf
4522362f76 csslint: CSS Grid Layout Module Level 1 (ED, Nov 28, 2017) 2017-12-18 10:27:58 +03:00
tophf
6607455e8f silence eslint; switch shirt-circuiting to single-line if/else 2017-12-18 10:27:50 +03:00
tophf
31fd551264 trivial speed-ups for the single editor case 2017-12-18 10:27:50 +03:00
tophf
d10e83d15c editor: rewrite global search/replace 2017-12-18 10:27:50 +03:00
tophf
f29e3bc587 colorpicker: remove old theme class on re-invocation 2017-12-18 10:27:50 +03:00
tophf
fd047f8323 move getRealColors to colorpicker and reuse it 2017-12-18 10:27:50 +03:00
tophf
97e486e139 code cosmetics: silence a warning in edit.css 2017-12-18 10:27:50 +03:00
tophf
db2c4cd6fc use standard font size in keymap info dialog 2017-12-18 10:27:50 +03:00
tophf
1f45618954 group similar items in keymap option selector 2017-12-18 10:27:50 +03:00
tophf
70d935d1a0 Ctrl-R to invoke replace in pcDefault/sublime keymaps 2017-12-18 10:27:50 +03:00
tophf
b78110aa1c .CodeMirror-dialog: shorten yellow highlight bright phase 2017-12-18 10:27:50 +03:00
tophf
41f3103a16 code cosmetics: use closest() in messageBox 2017-12-18 10:27:50 +03:00
tophf
be20b5a8b4 match-highlighter: always use originalToken 2017-12-18 10:27:50 +03:00
tophf
8119dd4f62 match-highlighter: skip exact tokens highlighted by search 2017-12-18 10:27:50 +03:00
tophf
001db9a19f make editor fully clean on saving 2017-12-18 10:27:50 +03:00
tophf
9e11435923 make editor permanently dirty when a section is deleted 2017-12-18 10:27:50 +03:00
tophf
4a924d6aa8 add 'textarea' to focusAccessibility.ELEMENTS 2017-12-18 10:27:50 +03:00
tophf
5aba0377a0 use helper's decisions in colorview renderer 2017-12-18 10:27:50 +03:00
tophf
50d3dbe394 expose prefs.defaults 2017-12-18 10:27:50 +03:00
tophf
2c47407afb eslintrc: allow shirt-circuit and ternary expressions 2017-12-18 10:27:50 +03:00
tophf
748b9afdb4 remember last used search text in editor 2017-12-14 11:35:32 +03:00
tophf
cc5a254e01 make multi-section search instantaneous 2017-12-14 11:20:22 +03:00
tophf
49a995afae fixup 1c68ac1a: init the find hook after the original one 2017-12-14 09:27:46 +03:00
tophf
6f81544ebe use a theme-friendly transparent color for the #actions bg 2017-12-14 06:29:23 +03:00
tophf
8dbdbe988f fixup dc126e1b: more adjustments for persistent child in #installed
* use .entry collection instead of installed.children
* adjust CSS counters

also:

* KeyboardEvent#code is checked first now - available since Chrome48 and FF32
* synthetic click event is cancelable, otherwise FF would open the editor in popup
2017-12-14 06:08:28 +03:00
tophf
1283e85a8e update USO style install counter
the USO site reports style installation unconditionally even if you uninstall it in 5 seconds, but we do it only if the style isn't uninstalled during 60 seconds while the popup is open - thus we exclude previewing of styles, which is a very popular use case
2017-12-14 01:46:32 +03:00
tophf
f048649e58 keep scroll position on install/delete 2017-12-14 01:13:16 +03:00
tophf
78c14dd93c also apply styleDeleted/Added to invisible search results 2017-12-14 01:08:05 +03:00
tophf
addc5af96d update locales 2017-12-14 00:13:15 +03:00
tophf
3ee502c3a4 fixup/cosmetics 2017-12-13 23:17:45 +03:00
tophf
4601a136a9 fix the popup width bug in FF when scrollbar is shown
* scrollbar width is not subtracted in FF from the actual width
* in some versions of FF the paddings should be added on both sides
2017-12-13 23:13:35 +03:00
tophf
8265d0c8e4 fixup 6d3cb733: remove trailing comma 2017-12-13 20:14:51 +03:00
tophf
6d3cb73324 "Estimated number of total pages" in the tooltip 2017-12-13 09:34:51 +03:00
tophf
3c2421d875 always scroll to the style on "history back" from editor to manager 2017-12-13 09:19:49 +03:00
tophf
8d9c7acb3c only preserve old style name on update if it was actually customized
We didn't detect that previously and just blindly assumed that a local name is always customized by a user, which is nonsense, obviously. To ensure reliable detection a new property is added to the style object: "originalName". From now on the styles that didn't change their name remotely will be successfully marked as having non-customized names, hence the names will update along with the code. Should be like 99% of styles. As for the remaining 1%, welp, only uninstalling and reinstalling the style anew would switch to the new remote name.
2017-12-13 09:12:54 +03:00
tophf
0fe0423757 prevent freezing of inline search nav pager in some cases 2017-12-13 07:46:28 +03:00
tophf
6ee952f3d3 more things made focusable
* mozilla-format (i) icon
* showHelp() restores original focus
* showHelp's nested confirmation is debounced to enable focusing Yes/No
* RegExp tester tab URLs are focusable now
2017-12-13 07:38:36 +03:00
tophf
fd4300f841 add a wiki link, shorten the USO link, use https everywhere 2017-12-13 07:15:40 +03:00
tophf
9fbe97bfd6
Merge pull request #294 from openstyles/narcolepticinsomniac-accessibility
Hide focus outlines without crippling accessibility, plus buttons
2017-12-13 06:20:30 +03:00
tophf
f9153b96eb make #sections-help icon focusable 2017-12-13 06:19:57 +03:00
narcolepticinsomniac
9b93e3e116
Margin tweak 2017-12-12 22:10:50 -05:00
narcolepticinsomniac
a6c10fe49d
Adjust margins
Removed some redundant fixes. Remaining tweaks were mostly info icons. I also applied a hacky margin for checkbox/label options and `.aligned` select options on edit page. They were too close IMO.
2017-12-12 22:09:51 -05:00
tophf
51ad84e6a9 don't open the homepage on first install as it's not helpful
see #112
2017-12-13 05:35:02 +03:00
tophf
7519b38df5 adjust some margins 2017-12-13 05:28:31 +03:00
tophf
a03809e68e make applies-to-help icon focusable 2017-12-13 04:00:05 +03:00
tophf
fefe82fd54 remove what-input, use own implementation, rebase on master 2017-12-13 03:27:10 +03:00
Rob Garrison
2cdd264780 fixups
Manage: Disable tabindex in nested buttons
Manage: Fix homepage link alignment
Manage: Make entry actions keyboard navigatable
Manage: Add search help accessibility
Msgbox: Save and restore focus
Manage: Fix delete confirmation cancel
Manage: Make history button accessible
Manage: Make favicons dropdown accessible
Manage: Prevent focus on hidden textarea
Msgbox: Stop tabbing outside of msgbox
Usercss: Make nondefault reset accessible
Usercss: Make colorpicker accessible
Edit: Disable tabindex in nested buttons
Edit: Make info and config icons accessible
Options: Cleanup HTML
Options: Make advanced toggle accessible
Edit: Fix issues popup
Edit: Remove link underlines from icons
2017-12-12 21:40:31 +03:00
narcolepticinsomniac
e2842f69c3 Hide focus outlines without crippling a11y, plus active state change for buttons 2017-12-12 21:39:55 +03:00
tophf
56c1476e67 code cosmetics 2017-12-12 17:35:38 +03:00
tophf
3ffbce0bc7 adapt to #installed having a persistent child now 2017-12-12 17:09:42 +03:00
narcolepticinsomniac
dc126e1b58 Popup overflow (#302) 2017-12-12 17:04:58 +03:00
tophf
ad692d4f61 chrome.contextMenus.update bug is fixed in Chrome 65.0.3289
#272
2017-12-12 06:20:07 +03:00
tophf
bb8dc04954 re-add #no-styles when inline-search deletes the last one 2017-12-12 05:21:06 +03:00
tophf
5452979366 simplify the options page 2017-12-12 04:20:51 +03:00
tophf
510ae91ac0 don't insert &shy; before whitespace 2017-12-12 03:18:37 +03:00
tophf
c23e192b7a bump version 2017-12-11 23:58:01 +03:00
tophf
dc535ee509 update locales 2017-12-11 23:57:00 +03:00
tophf
c3d9e8030b typos and code cosmetics 2017-12-11 23:45:42 +03:00
tophf
50b489478c prefetch next page on scroll past midpage 2017-12-11 23:25:41 +03:00
tophf
0390a703af restore findStylesForSite to avoid retranslation 2017-12-11 23:25:03 +03:00
tophf
3410a58cd9 don't add &shy; on word boundaries and strip it from tooltips
addresses #300
2017-12-11 22:39:22 +03:00
tophf
23733bd9fe show 'Style installed' in search result after inline install 2017-12-11 22:26:33 +03:00
tophf
866f54c307 code cosmetics 2017-12-11 13:26:07 +03:00
tophf
1d9ec09d62 simplify inline search DOM structure 2017-12-11 13:03:03 +03:00
tophf
3a82a66954 open editor a bit faster, fixup <select> bug and widget style 2017-12-11 09:12:56 +03:00
tophf
1b19cc0cf6 import report shouldn't alter #header 2017-12-11 08:44:41 +03:00
tophf
fb29638d00 defocus codemirror on Esc 2017-12-11 08:32:27 +03:00
tophf
60a5fb96be don't steal focus from the find input on page open 2017-12-11 08:32:11 +03:00
tophf
180e813ac4 tweak spinner opacity 2017-12-11 08:31:15 +03:00
tophf
752af458a3 redesign inline search cards 2017-12-11 07:35:23 +03:00
tophf
f4bfeea5a6 intermediate tweaks and fixes for inline search
* caching of search results and downloaded style info for one day
* no prefetching of styles
* only the next search results page is prefetched in unattended fashion
* the "configure" button is shown only after installation
* join the code in one closure, regroup and simplify some functions
2017-12-11 05:21:23 +03:00
tophf
adabb9aeff use LZString alias for LZStringUnsafe 2017-12-11 04:49:59 +03:00
tophf
b9c6be1676 disable the useless no-unmodified-loop-condition rule 2017-12-11 04:46:33 +03:00
tophf
f44ed87646 use a thin underline under big bold titles in inline search 2017-12-10 12:00:40 +03:00
tophf
6fb9d2d157 switch to a much faster LZStringUnsafe
https://github.com/pieroxy/lz-string/pull/98
2017-12-10 11:30:57 +03:00
tophf
8679e55206 unregister listeners on closing showCodeMirrorPopup 2017-12-10 11:24:52 +03:00
tophf
baab837be4 adjust style properties on installing
* reason = 'install'
* updateUrl += '?' when configurable
2017-12-10 10:56:09 +03:00
tophf
f120ae9753 fixup 0a865318: preserve normal behavior on normal links 2017-12-10 10:49:34 +03:00
tophf
b365962bbf don't scroll search list into view in old FF
couldn't find the reason in a couple minutes I can waste on this
2017-12-10 10:42:03 +03:00
tophf
888f93281d reduce DOM thrashing in adjustInfoPosition 2017-12-10 10:29:04 +03:00
tophf
abc4923059 cache search results for 1 hour 2017-12-10 10:11:19 +03:00
tophf
780053a19e darken search result description 2017-12-10 10:11:19 +03:00
tophf
d035e18b9f expose responseType in download() 2017-12-10 10:11:19 +03:00
tophf
405400de68 move 'tempUsercssCode' cleanup to usercss helper 2017-12-10 10:11:18 +03:00
tophf
5d54ce3464 DRY chromeLocal and chromeSync 2017-12-10 10:11:18 +03:00
tophf
b2b82f8310 break shorter words (5-10) followed by punctuation in tWordBreak 2017-12-10 10:11:18 +03:00
tophf
522a2bdab3 deep-copy style for popup's configDialog
see #298
2017-12-10 10:11:18 +03:00
tophf
242e3384b2 adjust #hotkey-info position for scrollingElement 2017-12-10 08:09:36 +03:00
tophf
0a865318a4 popup: "configure" opens USO page and expands the settings area 2017-12-10 07:56:41 +03:00
tophf
30fa9671c8 debounce autosave more, prevent re-entry
see #298
2017-12-10 06:02:25 +03:00
tophf
4d4247f0d8 fixup ce278fb4: unsplit .actions block 2017-12-10 05:52:20 +03:00
tophf
e0e5ab393f de-conflictize a11y PR 2017-12-10 04:19:55 +03:00
tophf
4b207f3dd4 basic tweaks/fixes for inline search 2017-12-10 04:03:04 +03:00
tophf
ce61112020 reuse "configure" message and simplified tooltip
we'll implement a built-in config dialog for USO styles in the future
2017-12-10 00:05:31 +03:00
derv
ce278fb4d0 Show styles from userstyles.org in Stylus popup (#251) 2017-12-10 00:03:17 +03:00
tophf
42e458ad69 saved.name is absent when checking in manager 2017-12-09 23:27:40 +03:00
tophf
ed1b163087 update log viewer: "Delete" and "[x] Only with updates or issues"
fixes #293
2017-12-09 23:26:28 +03:00
tophf
fa6365d297 bump version 2017-12-09 21:37:58 +03:00
tophf
7832c3c581 code cosmetics 2017-12-09 21:31:34 +03:00
tophf
a6fdb49503 content script may run before documentElement is present 2017-12-09 21:29:49 +03:00
tophf
e41dda1b68 refreshAllTabs should always try to refresh the main page 2017-12-09 21:19:03 +03:00
tophf
2fe4c0793c countStylesInHash when skipping styleReplaceAll 2017-12-09 21:16:41 +03:00
tophf
e45748d515 bump version 2017-12-09 20:48:13 +03:00
tophf
62521e132b update locales from transifex 2017-12-09 20:47:42 +03:00
tophf
db8c3585dd off-by-one in showKeyMapHelp: text after <mark> was lost 2017-12-09 20:43:47 +03:00
tophf
cb32b9debf skip styleReplaceAll if same; add some safety checks 2017-12-09 20:37:08 +03:00
tophf
491fcef08b also move style element when it's the first child
see #295
2017-12-09 19:37:31 +03:00
tophf
ca40eb9481 fixup 3318db19: read 'checked' state from checkboxes
fixes #297
2017-12-09 19:29:17 +03:00
tophf
f11235aaf9 Revert 1e1ff736 "simplify theme preloader" 2017-12-09 19:05:44 +03:00
tophf
443e3a3c7c second lockPageUI runs after there's no codebox anymore 2017-12-09 19:05:00 +03:00
tophf
ab98d46baa show import errors in messageBox 2017-12-09 19:04:19 +03:00
tophf
57e335abb8 raise style restoration limit; don't count own changes 2017-12-09 18:41:05 +03:00
tophf
5f1f9c4d86 unregister CM on closing showCodeMirrorPopup 2017-12-09 18:23:18 +03:00
tophf
9c1c15465e refreshAllTabs: process all frames 2017-12-09 18:15:57 +03:00
tophf
36fcb02b51 auto-unsubscribe prefs observer when element is gone 2017-12-09 17:38:00 +03:00
tophf
ae2efaa4a1 update manager search filter
fixes #296

* don't ignore 1-letter input if it's the only thing
* normal minimum word length is now 2 letters
* switch to AND combination mode so searching for dark github lists only what you expect
2017-12-09 17:17:33 +03:00
tophf
9486c7f3df don't report usercss as installed on USO if homepage matches 2017-12-09 04:43:02 +03:00
tophf
d52664d11c code cosmetics 2017-12-09 00:03:07 +03:00
tophf
9b4f76d776 adjust #hotkey-info position dynamically 2017-12-08 23:16:59 +03:00
tophf
ae9d33cf37 use the much shorter "Reset" label in config dialog 2017-12-08 22:32:35 +03:00
tophf
8a777b5d23 restore disabled state dimming on buttons and selects 2017-12-08 22:26:53 +03:00
tophf
240ccc8309 FF: actually prevent scrolling in focusNoScroll 2017-12-08 22:06:17 +03:00
tophf
18b20d13be onDOMscriptReady: notify all matching subscribers 2017-12-08 21:55:08 +03:00
tophf
32d89e58ea update locales from transifex 2017-12-08 20:32:53 +03:00
tophf
a1f2d2a719 bump version to 1.1.7.6 2017-12-08 20:26:37 +03:00
narcolepticinsomniac
599dc24862
Custom radio buttons and the last few Linux details (#292)
* Custom radio buttons and the last few Linux details

* Radio button margin

* Account for FF ESR
2017-12-08 12:02:01 -05:00
tophf
5faff66fab fix cross-section cursor navigation via keyboard 2017-12-08 11:42:33 +03:00
narcolepticinsomniac
526fa46edf
Load global.css in options 2017-12-07 23:40:08 -05:00
narcolepticinsomniac
c61932e0e9
Load global.css in options 2017-12-07 23:39:39 -05:00
tophf
1c68ac1a3a initialize editor page fully in First Meaningful Paint frame
* previously it wasn't the case when colorpicker option was enabled
* the cost of always loading colorview is ~1ms for >200ms here
2017-12-08 06:20:56 +03:00
tophf
0413736a29 remove the now redundant "chrome_style" from the options page 2017-12-08 06:20:30 +03:00
narcolepticinsomniac
ce47e69b8a Custom UI elements (#291) 2017-12-08 06:18:47 +03:00
tophf
2deffbc622 show "x" to reset non-default values in usercss config individually
also:
* simplified CSS selectors where possible
* .config-name = var name, 1st element in <label>
* .config-value = var value, 2nd element in <label>
* .nondefault class added on <label>
2017-12-08 03:23:09 +03:00
tophf
3318db1999 show .config-error on failure to save 2017-12-08 01:08:25 +03:00
tophf
99cce55a8e ensure long words break before breaking the layout
supersedes 40075a0d
2017-12-07 23:21:27 +03:00
tophf
fbcd3cc965 clarify the tooltip for USO userstyle "configure" icon 2017-12-07 20:58:02 +03:00
tophf
6a838e9d5e make sure all pre-create hooks finished 2017-12-07 20:26:41 +03:00
tophf
a71d2fa226 ...even less eager 2017-12-07 11:10:32 +03:00
tophf
6e1a6d1ad6 don't be too eager at restoring style elements to prevent deadlocks 2017-12-07 10:49:47 +03:00
tophf
6d4689e559 ensure own style elements dominance over other style elements 2017-12-07 10:12:01 +03:00
tophf
f40dc29497 add rudimentary reject/catch for mozParser inside worker 2017-12-07 08:41:52 +03:00
tophf
08c70a5192 csslint: only suppress validation errors caused by USO-vars 2017-12-07 08:09:22 +03:00
tophf
e4e8f04c95 code cosmeticsiv 2017-12-07 06:54:51 +03:00
tophf
fb3138f700 add .vivaldi class on <html> 2017-12-07 06:52:43 +03:00
tophf
aeca16f663 csslint: show real text of expected token if possible
now instead of the nerdy LBRACE users will see {
2017-12-07 05:37:36 +03:00
tophf
7a07ee9fd9 unbreak narrow editor layout 2017-12-07 05:31:42 +03:00
tophf
9c8e835a80 relay scrolling over #header to usercss code section 2017-12-07 04:36:46 +03:00
tophf
d4ffa04bb6 raise applies-to widget above .CodeMirror-activeline 2017-12-07 04:00:26 +03:00
tophf
b96cee1012 use Event#key for hotkey recognition in manager and popup
should help #286
2017-12-07 02:11:50 +03:00
tophf
119a3803ec realign #only-updates filter and rename as it's not linked to prefs 2017-12-07 01:39:15 +03:00
tophf
ebef35c28c drop linter name from "see all rules" and make it a link 2017-12-07 01:21:05 +03:00
tophf
d998fb235a center editor config icons 2017-12-07 01:20:04 +03:00
tophf
38e0937f45 config dialog tweaks
* same icon in manager
  (didn't change the editor config icons as those aren't for usercss)

* "external" icon for USO styles to avoid confusion
  (opening a tab is an extremely different action)

* smaller paddings in popup

* removed hover effect on label text
  (necause native <select> elements cannot be expanded from js)

* various fixups
2017-12-07 01:07:55 +03:00
tophf
543132aafa auto-apply on changes - new option in usercss config 2017-12-06 23:33:48 +03:00
tophf
945ec5604d don't overwrite button padding globally in old FF
...since it breaks custom ones
2017-12-06 22:42:34 +03:00
tophf
f337e18515 recognize usercss @updateURL
* installation URL is preferred - same behavior as before

* @updateURL is used when the style was drag'n'dropped into the manage page
  because there's no real URL in this case

* install-usercss page shows the new update URL, which is set as per the above,
  under the checkbox that enables updates
2017-12-06 22:35:19 +03:00
tophf
0659ff6233 set "use default" button actual state on opening config dialog 2017-12-06 11:35:04 +03:00
tophf
1273903b05 import usercss files drag'n'dropped into the manage page 2017-12-06 11:03:43 +03:00
tophf
cc57d39443 align #filters header; group FF-related rules 2017-12-06 10:37:01 +03:00
tophf
e3a67351d5 make protected tokens language-agnostic in search help message 2017-12-06 10:23:28 +03:00
tophf
03b6f6c263 manage: search regexps, add search help, fix favicons toggle icon
* the toggle icon is now a triangle, rotated when open
2017-12-06 09:39:45 +03:00
tophf
69ee57f88f manage: search in usercss full source code 2017-12-06 06:34:02 +03:00
tophf
974b1f9152 csslint: don't throw on errors caused by USO vars 2017-12-06 06:34:02 +03:00
tophf
8f9705c165 recognize USO vars ending with -rgb 2017-12-06 06:34:02 +03:00
tophf
aa44077212 rename #newStyleAsUsercss-wrapper to a standard CSS scheme 2017-12-06 06:34:01 +03:00
tophf
a712d92b52 fixup db621b86: add .active class only to the block title 2017-12-06 04:21:30 +03:00
tophf
31941110e8 manage: show "x" icon after #filters-stats to reset active filters
implements #286
2017-12-06 04:18:51 +03:00
tophf
579ffcc68d removed the extra tag 2017-12-06 03:34:53 +03:00
tophf
30aeb8d2c4 don't fade popup config dialog backdrop as it looks glitchy 2017-12-06 03:16:53 +03:00
tophf
e776a45dfa allow continuous tweaking in usercss config dialog
* don't close on clicking "save" to allow continuous tweaking
* dirty item's label is marked with * and switches to italic
* "save" button is enabled when some value differs from saved
* "use default" button is enabled when some value differs from its default
* "close" becomes "cancel" when there are unsaved changed values
2017-12-06 03:03:50 +03:00
tophf
de74c70778 actually use selected values in popup config dialog 2017-12-06 01:17:22 +03:00
tophf
85c67872a5 make colorpicker notify embedder on closing
re-enables Esc key in config-dialog after colorpicker closed itself due to an outside click
2017-12-06 00:24:27 +03:00
eight
07a0518586 Add config dialog to popup (#283) 2017-12-06 00:14:21 +03:00
Rob Garrison
db621b8657 Manage: Make filter & backup containers collapsible 2017-12-06 00:09:56 +03:00
tophf
44ce51e54f dim regexp-tester note and avoid extending the report width 2017-12-05 22:12:04 +03:00
tophf
61003b378c usercss editor: show all section regexps in tester 2017-12-05 21:52:24 +03:00
tophf
963930ea1d usercss editor: restore "Add" and "Regexp test", convert \ in regexps 2017-12-05 21:32:28 +03:00
tophf
36ec8de04f stop calc when color is opaque 2017-12-05 21:01:32 +03:00
tophf
bd0f460c56 usercss editor: use real theme color for inputs in widgets 2017-12-05 21:01:32 +03:00
tophf
69736ef5a1 FF: de-blur svg icons 2017-12-05 21:01:10 +03:00
tophf
fe4be8d5db actually keep "[x] as userccs" together 2017-12-05 21:00:12 +03:00
narcolepticinsomniac
82e45460fa
Remove obsolete selector which hid filters when lowest max-width media-screen kicked in 2017-12-05 08:41:05 -05:00
narcolepticinsomniac
93a8f99b12
Keep FF garbage separate 2017-12-05 07:50:49 -05:00
narcolepticinsomniac
e61877b9f9
Style disabled checkboxes, and use currentColor for select text/arrows
Select text color needs to be specified to override system color in Linux. Also got rid of he stupid dotted line around focused element text which still occurs in Linux FF.
2017-12-05 06:23:07 -05:00
tophf
2b22494f3f move style elements after head/body regardless of prior stuff
fixes #284
2017-12-05 08:50:07 +03:00
tophf
edfca7bfed match-highlighter-helper: do nothing when disabled 2017-12-05 07:40:28 +03:00
tophf
3bf0f7e2f8 FF: ensure styles are ordered correctly in background tabs
should probably help #284
2017-12-05 06:27:51 +03:00
tophf
3e34c77625 clear previous token/selection highlight from scrollbar 2017-12-05 05:40:33 +03:00
tophf
8e992299c6 clear previous search highlight from scrollbar in all sections 2017-12-05 05:40:27 +03:00
tophf
cb7f1de348 use hyphens when breaking words (works only in FF though) 2017-12-05 05:02:28 +03:00
tophf
40075a0d39 forcefully break long labels in aligned options 2017-12-05 04:39:29 +03:00
tophf
1e1ff73612 simplify theme preloader 2017-12-05 04:39:29 +03:00
tophf
a6f63d096e extract checkboxes to global.css, fixes 2017-12-05 04:39:29 +03:00
narcolepticinsomniac
7339643ec3 Custom checkbox and select elements 2017-12-05 04:39:29 +03:00
tophf
8ca4253be4 fix the note for good, hopefully 2017-12-04 21:14:31 +03:00
tophf
a0c6450fc1 only show the note if filtering something 2017-12-04 21:00:06 +03:00
tophf
30d84d15fa remove the note sooner when unhiding entries 2017-12-04 20:24:07 +03:00
tophf
3e9810678a fixup 0e61de29: use break/continue instead of return
fixes #282
2017-12-04 20:13:56 +03:00
tophf
dd05955a38 fixup d97337de: preceding comment may be absent 2017-12-04 20:12:47 +03:00
tophf
e50de59669 fixup 1951bc89: always debounce note update 2017-12-04 20:06:14 +03:00
tophf
294917ed4d fixup 1951bc89: update the note twice 2017-12-04 19:51:52 +03:00
tophf
81c6d9912c fixup 1951bc89: wait for bg when the browser is starting up 2017-12-04 11:28:32 +03:00
tophf
1951bc89bb manage: inform when hiding all styles due to active filters 2017-12-04 10:31:28 +03:00
tophf
1785bac9d2 fix usercss updater: skip if code hasn't changed 2017-12-04 10:28:24 +03:00
tophf
01e8c3b080 disable spellchecking in input fields 2017-12-04 09:00:14 +03:00
tophf
48dda41e2e fixup 99512da9 and 493c1a65: show csslint rule info in issues info box 2017-12-04 08:57:12 +03:00
tophf
c0c60fb7a2 add a terse invocation syntax for $element and rename it to $create 2017-12-04 08:57:12 +03:00
tophf
6e142a7444 install-usercss: show error position and source
fixes #276
2017-12-03 23:29:36 +03:00
tophf
e905e4e079 properly escape/unescape regexp in applies-to widgets 2017-12-03 22:51:03 +03:00
tophf
489546e35c use just one event listener per applies-to widget in usercss editor 2017-12-03 21:21:51 +03:00
tophf
c723ec58ce bump version to 1.1.7.2 2017-12-03 20:36:20 +03:00
tophf
f4677a7b7b actually use the name when saving 2017-12-03 20:32:50 +03:00
tophf
0f3ddb9c03 bump version to 1.1.7.1 2017-12-03 17:14:13 +03:00
tophf
b161d17bbf update zh_TW locale 2017-12-03 17:14:13 +03:00
tophf
c1d15cfeb4 bump version to 1.1.7 2017-12-03 08:27:41 +03:00
tophf
d6172e43d1 pull locales from transifex 2017-12-03 08:26:57 +03:00
tophf
b4670f759a update #hotkey-info height calc 2017-12-03 08:19:31 +03:00
tophf
39a521fb80 FF: don't style checkboxes in FF < 54, not 57
See #271
2017-12-03 07:59:41 +03:00
tophf
d9e3d15098 fix #no-styles margins; remove the hotkey number 2017-12-03 07:07:43 +03:00
tophf
e6e762505f FF: don't style checkboxes in FF < 57 2017-12-03 07:07:43 +03:00
tophf
e9a38c8eda fixup 387193d3: don't try to parse unsupported URLs 2017-12-03 06:15:03 +03:00
tophf
387193d347 popup: USO bug workaround for find-styles link url
fixes #273
2017-12-03 06:02:30 +03:00
tophf
9314fa0e8a fixup 0e61de29: register the listener before setupLivePrefs() 2017-12-03 04:18:58 +03:00
tophf
8622dffe1e usercss: make nextPrevMozDocument work with minified CSS 2017-12-03 04:05:35 +03:00
narcolepticinsomniac
a185b6b182
Another popup mockup (#271)
* Another popup mockup

This is a fraction of what I want to do with the popup, but these are improvements that can be made to the existing version without a complete overhaul. Should be no difference appearance-wise, only some simple enhancements to existing functionality in terms of click area and stylability. 

Eliminates ill-conceived `.left-gutter` altogether. Checkboxes and labels are now either parent/child or siblings, with no weird spaces between them, and their hovers can therefore be styled together. `entry` checkbox/label `.style-name` now occupies the entire height/width of the `.entry` to the left of the `.actions` icons, so no more errant clicks.

* Another popup mockup

* Delete popup.css

* Another popup mockup

* Custom checkboxes

* Custom checkboxes

* Subtlety

>an animated checkbox needlessly draws attention to itself

But... I feel the need. Drawing attention to the checkbox is intentional to indicate click action.

>In case the entire row is highlighted there will be no distraction

Clickable area isn't the entire row, it's everything left of action icons. Hovering background on part of the row will look odd, and it's also a less obvious indicator of click action IMO.

Didn't change "disable all" yet. It's a special kinda function, so maybe slightly more drastic is warranted, but I can tone that down too.
2017-12-02 18:55:23 -05:00
tophf
55564b543a replace 'about:blank' tabs in openURL() 2017-12-03 02:44:20 +03:00
tophf
43fc26619d editor: raise highlight limit from 10k to 100k chars in one line 2017-12-03 02:02:22 +03:00
tophf
a5c3c2e895 editor: use 'editor.lineWrapping' option on opening 2017-12-03 01:52:46 +03:00
tophf
904e6017f2 close showHelp() if input element has can-close-on-esc class 2017-12-03 00:22:03 +03:00
tophf
a5f31162f6 de-htmlize showKeymapHelp 2017-12-03 00:20:42 +03:00
tophf
0e61de2920 edit.js: pull out hooks, sections, keymap help, beautify
just a simple preparation for a proper encapsulation in the future
2017-12-02 23:46:00 +03:00
tophf
6704956b22 fixup 0de69e30: avoid passing falsy selectors to $() 2017-12-02 21:41:28 +03:00
tophf
0de69e306d code refactor: add $.remove() and $$.remove() 2017-12-02 19:54:54 +03:00
tophf
d4c0930723 FF: workaround for vertical-align bug on usercss-docs svg icon 2017-12-02 19:39:20 +03:00
tophf
0ba3cfb725 FF: fix transition-bug-suppressor condition 2017-12-02 19:38:03 +03:00
tophf
e32fecd1e3 usercss: tint the active line's @mozdoc widget 2017-12-02 18:53:37 +03:00
tophf
fbd7526092 usercss: Alt-PgUp/PgDn go to prev/next @-moz-document 2017-12-02 18:29:12 +03:00
tophf
05d1013699 fixup 2e03c9c9: the element should be in DOM before reposition() 2017-12-02 17:18:58 +03:00
tophf
d263bc8e55 disallow more nav keys in colorpicker hotkey config dialog 2017-12-02 17:15:55 +03:00
tophf
c11c100cbb circumvent the bug with disabling check marks in Chrome 62+
fixes #272
2017-12-02 16:13:40 +03:00
tophf
fdcdaf3db5 process the just added/updated styles in "only external" filter 2017-12-02 07:07:51 +03:00
tophf
7de3e37a51 show "Style installed" in manager for styles added while it's open 2017-12-02 07:07:12 +03:00
tophf
536064ae9a csslint fixup 88885403: 'simple' doesn't support conditional grammar 2017-12-02 05:13:55 +03:00
tophf
f05debf686 popup: show hotkey info upon clicking the area on the right 2017-12-02 04:07:09 +03:00
Rob Garrison
3c0b14a477 Install usercss (#269)
install-usercss: restyle "Install style" button
2017-12-02 02:43:01 +03:00
tophf
0eaee16f7e csslint: allow "transparent" in SVG colors 2017-12-01 23:04:38 +03:00
tophf
f3be825d25 csslint: expand referenced rules when describing errors 2017-12-01 22:55:39 +03:00
tophf
5bdaacc049 stabilize token highlighting for the match/search mode 2017-12-01 21:16:19 +03:00
tophf
2760b0764b fixup b41cc8bc: only rewrite query if regexp 2017-12-01 16:22:43 +03:00
tophf
bf8d33a3f4 followup for a60d53de: move #footer down when #lint is collapsed 2017-12-01 06:17:24 +03:00
tophf
88885403ad csslint: CSS Box Alignment Module Level 3 (ED Nov 14)
https://drafts.csswg.org/css-align/
2017-12-01 05:52:23 +03:00
tophf
b41cc8bca3 4x speed-up of showMatchesOnScrollbar
at the cost of a marginally reduced accuracy when line wrapping is enabled, but the difference shouldn't be more than a few pixels, presumably
2017-12-01 05:14:52 +03:00
tophf
a6fbc9db11 render lint squigglies 4x faster
* turns out codemirror lint addon doesn't open an overall op,
  instead it creates an op for each marker.

* also, now there's no need to disable the lint option when initializing codemirror
2017-12-01 03:49:09 +03:00
tophf
f5516db8f4 off-load mozParser to a worker 2017-12-01 02:35:56 +03:00
tophf
9c3229717f fixup d660e6bd: off-by-1 in parseStringUnquoted 2017-12-01 00:23:06 +03:00
tophf
71f3dfbffd usercss: don't relint on save; mode is an object once initialized 2017-11-30 20:42:52 +03:00
tophf
a61ee5f093 fixup 362d9444: autoscroll manage page only during incremental search 2017-11-30 01:13:13 +03:00
tophf
6f0dd5e9b6 fixup 362d9444: never scroll manage page on toggling a visible entry 2017-11-30 00:54:40 +03:00
tophf
e6109d509b increase opacity on disabled entries to restore readability
followup to 56fb1c2f
2017-11-30 00:14:17 +03:00
tophf
a60d53de29 edit: workaround for <details> not showing the toggle 2017-11-29 19:27:31 +03:00
tophf
189342472e manage: collapsible #options block 2017-11-29 19:27:31 +03:00
tophf
c0a227fa39 popup: show style numbers, add more hotkeys
numpad 0-9 same as 0-9
numpad + enables all listed
numpad - disables all listed
numpad * and ` (backtick) - toggles initially enabled styles;
         doesn't apply to subsequently enabled styles while the popup is open
         so you can restore the initial selection after testing stuff:
         simply disable all, then toggle i.e. numpad -, numpad *
2017-11-29 17:59:02 +03:00
tophf
362d944428 manage: incremental search on typing + up/down arrows 2017-11-29 17:59:02 +03:00
tophf
b762f48135 usercss install: reuse current tab for editor when possible 2017-11-29 17:59:01 +03:00
tophf
cbe90272b9 silence some useless warnings in console 2017-11-29 17:59:01 +03:00
tophf
fc0b1dc739 fixup 493c1a65: missed some null checks and a return 2017-11-29 17:59:00 +03:00
tophf
c4690a839f also restore the subdued appearance of "disabled" suffix
originally it didn't even have a background so even the faint one we had for the last year is borderline acceptable so let's keep it
2017-11-29 17:56:13 +03:00
tophf
9779c0439f unfade disabled entry's action buttons only on hover
thus the historical appearance is preserved by default
2017-11-29 17:39:21 +03:00
Rob Garrison
56fb1c2f93 Fix appearance of non-disabled elements 2017-11-29 17:28:04 +03:00
tophf
d72aa0fa36 manage: fix applies-to overflow with long strings; add some vars 2017-11-29 15:15:34 +03:00
narcolepticinsomniac
e90de3783a
svg-icon hover and dim disabled checkbox label text
@tophf The bold font and copious padding on the install button is overkill IMO. Almost all our buttons are default, but if we wanna go a little bigger, I'd prefer them more like the "overwrite" and "append" buttons.
2017-11-29 06:24:46 -05:00
narcolepticinsomniac
efecfd926a
Same SVG selector for install page 2017-11-29 05:37:37 -05:00
tophf
be633bf903 usercss: update URL and sessionStorage on replacing the style 2017-11-29 13:35:27 +03:00
tophf
260cbddae0 usercss: force-refresh codemirror on saving to repaint vars 2017-11-29 13:27:55 +03:00
tophf
b995a9d316 usercssData.vars may be absent (e.g. in unsaved style)
fixes #267
2017-11-29 13:24:13 +03:00
tophf
bf13383c93 workaround for URLSearchParams not stripping "?" in chrome 49-51 2017-11-28 22:19:00 +03:00
tophf
a64dc26dd7 popup: toggle/edit styles from keyboard
1-9, 0 - toggles Nth displayed style (0 is 10)
a-z:   - toggles first style with a name that starts with the letter
Shift  - opens editor instead of toggling
2017-11-28 20:37:53 +03:00
tophf
39c6d897ed mozImport: show hotkey in button tooltip 2017-11-28 20:07:38 +03:00
tophf
d39e9f6037 show most of the sidebar in big codemirror popups 2017-11-28 20:07:38 +03:00
tophf
493c1a65c0 worker for stylelint; hints in linter config popup 2017-11-28 20:07:37 +03:00
narcolepticinsomniac
c2d68612ec
Common selector for non-traditional checkbox inputs 2017-11-27 23:10:32 -05:00
narcolepticinsomniac
1f0d6fb4e9
Common selector for non-traditional checkbox inputs 2017-11-27 23:09:52 -05:00
tophf
99512da9da use CSSLint in a web werkker 2017-11-27 17:02:30 +03:00
tophf
f3cf6e1856 usercss config: delete only missing vars on save 2017-11-27 15:57:32 +03:00
tophf
0b57fa4810 fixup: don't constrain unset values 2017-11-27 15:22:49 +03:00
tophf
c31495c283 usercss config: skip and warn about mismatching vars on saving 2017-11-27 15:02:10 +03:00
tophf
fad03fb7c9 colorpicker: invoke callback on first color change 2017-11-27 14:54:19 +03:00
tophf
761f6a5085 fix an ancient bug with setting tabSize option to a string 2017-11-27 14:54:19 +03:00
tophf
d660e6bd72 usercss validator: more precise error position report 2017-11-27 14:54:18 +03:00
tophf
06a2a4c04d constrain manually typed values in colorpicker 2017-11-27 14:54:18 +03:00
tophf
2e03c9c9c0 same colorpicker in the manager 2017-11-27 14:54:18 +03:00
tophf
a603cc081b use the same "configure" icon in editor an manager 2017-11-27 14:53:34 +03:00
tophf
13d7e30a75 usercss saving: display errors from mozparser in <pre> 2017-11-27 06:55:12 +03:00
tophf
8d3fd9cc3b fixups for a58f42de (backtick) and 05677d93 (copy changed meta) 2017-11-27 03:19:31 +03:00
tophf
841e556f42 calc an actual per-item height even though CM doesn't seem to care 2017-11-27 02:59:44 +03:00
tophf
170bd0ccb1 reuse line index cache for posFromIndex
100ms -> 50ms rendering time in updateInvisible() for "RU AdList CSS Fixes" style
300ms -> 50ms is the final speedup with the widget height cache in 3fd4343c
2017-11-27 02:43:10 +03:00
eight
5dbd2249dd Add: use cache template 2017-11-27 02:43:10 +03:00
tophf
3fd4343cfd usercss: don't recalc widget height => spend 0 time in CM
300ms -> 100ms rendering time in updateInvisible() for "RU AdList CSS Fixes" style
2017-11-27 01:33:16 +03:00
tophf
05677d93b3 usercss: use cm.changeGeneration() to detect dirtiness 2017-11-27 00:57:25 +03:00
tophf
76b49af81f finally rename the only camelCase-named file 2017-11-26 22:09:01 +03:00
tophf
23efcb1db8 usercss: inform when the entire metadata block is missing/invalid 2017-11-26 21:13:54 +03:00
tophf
0d80177691 accept xhr options in download(url, options)
also fixup d1964bbc: an error should reject with a code, not XHR's ProgressEvent
2017-11-26 21:09:29 +03:00
tophf
ff175d9af4 store installDate and updateDate 2017-11-26 20:47:23 +03:00
tophf
4fd25f9e1a add hover on filter selectors to indicate the clickable area 2017-11-26 20:36:43 +03:00
tophf
77a07b7f2b open editor on clicking anywhere in the cell; add hover effect 2017-11-26 20:36:14 +03:00
tophf
5a489e7043 add "usercss" label
reimplements #262
2017-11-26 20:24:42 +03:00
tophf
a58f42dee0 usercss editor: save as template when @name is empty
* reduced the flickering on page open
* show * in title for new styles
* align the values in the default template
* don't ask to save an untouched template
* don't spam the console with errors
* trivial code refactor and cosmetics
2017-11-26 18:43:40 +03:00
tophf
b63449f299 show tooltips in popup on ellipsized names 2017-11-26 15:31:00 +03:00
tophf
af64ec4ac0 show a real hotkey in Save button tooltip 2017-11-26 15:08:47 +03:00
tophf
fb9abee285 FF options: match the default FF theme color 2017-11-26 14:25:46 +03:00
tophf
288f347e40 fixup 978e5ca9 and ee86ef30: editor.contextDelete option 2017-11-26 14:20:44 +03:00
tophf
74e6ea5a56 fixup c8c02805: +1 only when no previous widget found 2017-11-26 05:10:31 +03:00
narcolepticinsomniac
95ebe96bc2
Proper IDs like other pages 2017-11-25 20:53:21 -05:00
tophf
0e518bddcb don't add usercss vars to empty sections 2017-11-26 04:52:14 +03:00
tophf
fb3554a351 simplify orphanCheck; use IIFE; fix comm issues 2017-11-26 04:24:23 +03:00
tophf
babeb695c1 kick out orphaned script 2017-11-26 00:23:38 +03:00
tophf
e4de02995c fixup 978e5ca9: don't reuse the same object in async code! 2017-11-26 00:04:19 +03:00
tophf
2495ded507 fixup c8b6672d: restore deleted elements 2017-11-25 23:47:39 +03:00
tophf
47c6e7a52e bump version to 1.1.6.3 2017-11-25 20:24:50 +03:00
tophf
6aef6cdcd7 0 is a valid tab id 2017-11-25 20:24:15 +03:00
tophf
ea277bcf4c show a spinner on usercss install page while fetching code 2017-11-25 18:24:37 +03:00
tophf
e7175c261a don't confirm on clicking "install" for a new usercss 2017-11-25 18:24:37 +03:00
tophf
aedb02bbb1 install usercss from raw.githubusercontent.com 2017-11-25 18:24:37 +03:00
tophf
59d32e6f2f inline and simplify closeTab() 2017-11-25 18:00:41 +03:00
tophf
978e5ca9f0 sendMessage()
Promise mode [default]:
  - rejects on receiving {__ERROR__: message} created by
    background.js::onRuntimeMessage
  - suppresses chrome.runtime.lastError
    by browserAction.setText which lacks a callback param in chrome API

Callback mode:
  - enabled by passing a second param
  - doesn't suppress chrome.runtime.lastError
2017-11-25 18:00:38 +03:00
tophf
226fc471eb bump version to 1.1.6.2 2017-11-25 17:44:32 +03:00
tophf
c8c02805f4 fixup 82651ed6: recreate widgets for active line if needed 2017-11-25 17:44:32 +03:00
tophf
326dc5fb86 don't autofocus colorpicker input fields on small touch devices 2017-11-25 16:47:05 +03:00
tophf
71b2ab14a0 pull locales from transifex 2017-11-25 16:34:43 +03:00
tophf
8f04e17d27 fix #223 - Android compatibility 2017-11-25 16:25:20 +03:00
tophf
febaefd8dc don't show autocomplete on numbers 2017-11-25 04:30:19 +03:00
tophf
3ed98cb506 fixup 80547aef: autocomplete should fallback to original helper 2017-11-25 04:29:56 +03:00
tophf
2dda22f700 fix color swatch glitch on lint markers 2017-11-25 04:28:55 +03:00
tophf
08fab9559c CodeMirror 5.32 2017-11-24 13:19:20 +03:00
tophf
15c5df0e6e colorpicker always picks up the only color in a line 2017-11-24 13:19:19 +03:00
tophf
7c0d8f0841 prevent inline overlays from breaking color swatches 2017-11-24 13:19:19 +03:00
tophf
7e4683d417 USO-vars in CSSLint 2017-11-24 13:19:19 +03:00
tophf
60247a6443 don't lowercase the original line! 2017-11-24 13:19:18 +03:00
tophf
7c746ab9a3 fix colorpicker keyboard increment with #HEX in CAPS 2017-11-24 13:19:18 +03:00
tophf
80547aef70 recognize USO-variables /*[[foo]]*/ and provide autocomplete hints 2017-11-24 13:19:18 +03:00
tophf
3152a7ebfe simpler plain string method for same token check 2017-11-24 13:19:18 +03:00
tophf
8bff4a297e disallow Space as a colorpicker hotkey 2017-11-24 13:19:17 +03:00
tophf
d2826d92f6 CodeMirror css mode: recognize "isolation" 2017-11-24 13:19:17 +03:00
tophf
def05f2f0a csslint: add "isolation" 2017-11-24 13:19:17 +03:00
tophf
55360c731a move helpers and defaults to the end when everything is ready 2017-11-24 13:19:17 +03:00
tophf
c1d1c26c23 CodeMirror css mode: recognize "mix-blend-mode" 2017-11-24 13:19:16 +03:00
tophf
8cced2da35 csslint: add "mix-blend-mode" and the internal <blend-mode> 2017-11-24 13:19:16 +03:00
tophf
3fe3f08407 USO page: animate the update button's spinner on consequent clicks 2017-11-24 13:19:16 +03:00
tophf
d97337ded7 fix mozImport: properly discern comments outside of @-moz-document 2017-11-24 13:19:16 +03:00
tophf
4fc54450b7 de-marginalize usercss editor; fix narrow @media 2017-11-24 13:19:15 +03:00
tophf
74701810b7 remove cruft; silence eslint 2017-11-24 13:19:15 +03:00
tophf
479d95711b linter report expands/collapses on click; the state is saved 2017-11-24 13:19:15 +03:00
tophf
06cda0b2c1 fix colorpicker swatch glitches by monkeypatching match-highlighter 2017-11-24 13:19:14 +03:00
tophf
a30ef3ed14 restore the original match-highlighter and monkeypatch it 2017-11-24 13:19:14 +03:00
tophf
c1c61ed590 find more rgb/hsl colors near cursor in comments and strings 2017-11-24 13:19:14 +03:00
tophf
0c3b3a1631 remove border from filter selector & generalize CSS 2017-11-24 13:19:14 +03:00
tophf
828f09fdb2 tweaks/fixes for "[x] as usercss" 2017-11-24 13:19:13 +03:00
tophf
c8b6672d79 always sort applied style elements by id 2017-11-24 13:19:13 +03:00
tophf
607160655d colorpicker shouldn't overwrite non-colors 2017-11-24 13:19:13 +03:00
tophf
44206ef166 some fix for @media query from @Mottie 2017-11-24 13:19:13 +03:00
tophf
fe3b1511f6 add "[x] only Usercss" filter in the manager 2017-11-24 13:19:12 +03:00
tophf
65f0a2ac3c add doc link for "[x] as usercss" option in the manager 2017-11-24 13:19:12 +03:00
tophf
62aec5c359 put "[x] as Usercss" option next to "Write new style" button 2017-11-24 13:19:12 +03:00
tophf
44c0f3d076 supernarrow mode at 4" 2017-11-24 13:19:11 +03:00
tophf
a7b8286e4f remove textareas 2017-11-24 13:19:11 +03:00
tophf
e1fae23927 init CM to usercss @preprocessor before setting the code 2017-11-24 13:19:11 +03:00
tophf
0ed6e3d4bf don't reinsert reinterpreted color on start
do it only on the Enter key or once the user explicitly changed the color at least once
2017-11-24 13:19:10 +03:00
tophf
e0ea76a940 colorpicker hotkey: find color at cursor in strings/comments 2017-11-24 13:19:10 +03:00
tophf
8c5471092c rework install-usercss: CSS, layout, warnings 2017-11-24 13:19:10 +03:00
tophf
78bf2c8d9b close colorpicker config on Enter 2017-11-24 13:19:10 +03:00
tophf
612b21c732 register colorpicker command on first use 2017-11-24 13:19:09 +03:00
tophf
64cb128b06 intercept the hotkey assigned to colorpicker via hotkeyRerouter 2017-11-24 13:19:09 +03:00
tophf
5d00602ada switch colorpicker popup format on PgUp/PgDn only, not Tab 2017-11-24 13:19:09 +03:00
tophf
e9abcc8031 install-usercss: css tweaks
* pad the Install button
* remove global * selector
* add narrow @media query
* simplify css
2017-11-24 13:19:09 +03:00
tophf
d767ad7a8c autoLoadMode -> loadScript; chain to avoid flicker on load 2017-11-24 13:19:08 +03:00
tophf
786cde781d pull out colorpicker-helper.js 2017-11-24 13:19:08 +03:00
tophf
fc20479ab4 correctly unhook colorpicker in usercss#stylus mode 2017-11-24 13:19:08 +03:00
tophf
2c82cc3bbc fix glitching on highlighting of current token 2017-11-24 13:19:08 +03:00
tophf
7bae73bcb4 add onclick for colorpicker-settings icon in usercss mode 2017-11-24 13:19:07 +03:00
tophf
75da5c50ce colorpicker Ctrl-up/down steps in 50 on S, L, .5 on alpha 2017-11-24 13:19:07 +03:00
tophf
6c858d6449 fix colorpicker hotkey config 2017-11-24 13:19:07 +03:00
tophf
2a0ecec28e show color swatches in usercss with stylus preprocessor 2017-11-24 13:19:07 +03:00
tophf
aa2fef7f72 more keyboard control in colorpicker popup
hex mode similar to chrome-devtools:
* Ctrl-Up/Down for R channel
* Shift-Up/Down for G channel
* Alt-Up/Down for B channel
* Up/Down treats the entire color as a hex integer e.g. #00f -> #010

rgb/hsl modes similar to chrome-devtools:
* Ctrl-Up/Down steps by 100 (alpha: by 1)
* Shift-Up/Down steps by 10 (alpha: by .1)
* Up/Down steps by 1  (alpha: by .01)

* PgUp/PgDn to switch format
* Tab to switch format when at the first/last input field
2017-11-24 13:19:06 +03:00
tophf
b99391887d add colorpicker hotkey config icon [default: none]
* uses the last submitted color by default
* doesn't insert the default color until a change or the Enter key
* fix a few bugs in colorpicker introduced in the rewrite
2017-11-24 13:19:06 +03:00
tophf
352846c8b4 fix and update ColorView.openPopup() 2017-11-24 13:19:06 +03:00
tophf
ce8a0a2d42 assign color swatches correctly: skip overlays in the middle 2017-11-24 13:19:05 +03:00
tophf
7f37b8d1dd unify markup and CSS for icons within options 2017-11-24 13:19:05 +03:00
tophf
aa1ac63c1c fix svg icon rendering in FF: symbols don't need size 2017-11-24 13:19:05 +03:00
Rob Garrison
eee9e30413 Add Discord chat badge 2017-11-23 13:33:59 +03:00
tophf
777adf1bae correctly fix the USO bug with populating settings on their site
previously we disconnected the interceptor on first XHR response, which is not necessarily for the style, so now we wait until an actual one.
2017-11-21 13:42:51 +03:00
tophf
e8d0c7d039 update button on USO page now confirms only on the first click 2017-11-21 13:33:11 +03:00
tophf
f1836f399f try to get style json on USO install page twice
also report errors
fixes #195
2017-11-21 13:23:32 +03:00
tophf
4e9e4d24b1 bump version to 1.1.6.1 2017-11-21 11:03:22 +03:00
tophf
24c60b7e8a fixup 8a1908b7: don't protect disabled elements 2017-11-21 10:59:14 +03:00
tophf
46df47bf31 bump version to 1.1.6 2017-11-21 10:10:29 +03:00
tophf
00ead83da9 don't hardcode homepage URL, extract it from "Get Help" translation 2017-11-21 09:48:55 +03:00
tophf
8a1908b760 protect own style elements (100 times max to avoid deadlocks)
fixes #252
2017-11-21 09:45:44 +03:00
tophf
5d905c2952
Merge pull request #239 from openstyles/colorpicker
Colorpicker in the editor
2017-11-20 15:21:40 +03:00
tophf
37a62b0407 fix/rewrite/integrate colorpicker
* full rewrite of colorview.js to make it 10-100 times faster (render on demand via extendMode)
* full rewrite of colorpicker.js to simplify CSS
* automatic light/dark theme based on current color of the editor
* fixes, tweaks, speedups
* color spot will always be on the left of its text i.e. no line break on wrapping
* support #RRGGBBAA and #RGBA hex colors
* support "transparent" as rgba(0, 0, 0, 0)
* HEX/hex toggle
* fix HSLA regexp
* Esc/Enter key to close
* innerHTML -> textContent
* toggle the feature correctly
* fade out before autohiding
* always show alpha 1 like devtools does
* set cursor:pointer only on the clickable part of the sliders
* bigger color format switcher with a tooltip
* autofocus input on open, disable spellcheck
* try not to obscure the source color spot & text
* restore focus without scrolling
2017-11-20 15:19:58 +03:00
tophf
271aa79355 pull locales from transifex 2017-11-20 15:06:27 +03:00
tophf
c50b251ae4 add original colorpicker plugin 2017-11-19 15:55:35 +03:00
tophf
10ce4eeefa prefs.subscribe: allow multiple listeners for one key 2017-11-19 15:55:35 +03:00
tophf
0ded91d987 apply extension userstyles to install-usercss page 2017-11-18 12:04:12 +03:00
tophf
9689288bdc new editor option: autoclose brackets/quotes [default: off] 2017-11-17 02:36:05 +03:00
tophf
09c16ac541 force break-wrapping in regexp-tester's details 2017-11-17 02:17:21 +03:00
tophf
559420a461 FF: outline the active code box
-webkit-focus-ring-color rgb value is used, but not the blurred effect (TODO)
2017-11-15 11:49:02 +03:00
tophf
9f4066faa1 code cosmetics: remove redundant comments 2017-11-15 11:36:24 +03:00
tophf
5a9227ce8c speedup usercss opening: combine a few ops 2017-11-15 11:35:54 +03:00
tophf
15c98bac9e fixup 8ca7c363: focus() must be the last action 2017-11-15 11:33:37 +03:00
tophf
82651ed6cd usercss: create applies-to widgets faster on load
only the visible portion is built immediately, the rest is throttled
2017-11-15 10:54:19 +03:00
tophf
06cc703887 use CSS variables for applies-to line widgets 2017-11-15 09:04:09 +03:00
tophf
14dbfdd915 update applies-to widget on any style changes 2017-11-15 08:32:22 +03:00
tophf
9868a1819c actually focus code after import 2017-11-15 08:15:06 +03:00
tophf
fc5c00e37d all actions must always return a Promise 2017-11-15 07:11:46 +03:00
narcolepticinsomniac
d8ceb35cd5
New line for selector 2017-11-14 22:48:47 -05:00
narcolepticinsomniac
24c513929e
Advanced options toggle (#238)
* Advanced options toggle

Whole div is clickable. Arrows to indicate functions. I went with carets and centered collapsed text, but we can use different arrow and/or keep the text to the left.

* advanced options toggle

* advanced options toggle

* Only apply to Chrome

* Delete options.css

* Delete options.js

* Only apply to Chrome

* Only apply to Chrome

* Fix label

* Fix label again
2017-11-14 22:25:30 -05:00
tophf
b9f6095db5 focus code on opening standard editor immediately 2017-11-15 04:53:37 +03:00
tophf
8ca7c36380 focus code on opening usercss editor 2017-11-15 04:27:33 +03:00
tophf
8517e392fe throttle mozImport after 100ms, display progress after 500ms
* Ctrl-Enter = append button
* Shift-Ctrl-Enter = replace button
* instantaneous readiness of import dialog on non-blank input
* code dedup: addSections()
* trimNewLines() -> trim()
2017-11-15 04:24:36 +03:00
tophf
102b5e03d4 superfast cm.isBlank() instead of !cm.getValue().trim() 2017-11-15 02:50:53 +03:00
tophf
40f9413207 version 1.1.5 2017-11-14 11:57:05 +03:00
tophf
0ed37c2667 popup: add side borders in Chrome 62+
fixes #226
2017-11-14 11:20:49 +03:00
tophf
94ed435e75 fixup d2b9b302: prevent setting version var to 'undefined' 2017-11-14 11:12:18 +03:00
Jeremy Schomery
12e2fbdd37 version 1.1.4.3 2017-11-14 10:57:20 +03:30
Jeremy Schomery
ec23620b29 updating locales 2017-11-14 10:51:10 +03:30
tophf
f2a6c99498 options: move newStyleAsUsercss to the top of the advanced block 2017-11-14 09:58:45 +03:00
tophf
68d72215a2 disable the useless "no-empty-function" warning 2017-11-14 09:52:51 +03:00
tophf
ac8331e6ae FF: use tabs API for XML viewer 2017-11-14 09:52:51 +03:00
tophf
e4cd984061 regexp tester: switch to existing tabs also in other windows 2017-11-14 09:49:07 +03:00
tophf
135d8d9c54 force wrapping in regexp-report summary 2017-11-14 09:38:09 +03:00
tophf
9503acc2bf styleSectionsEqual() order of sections should be identical
Thus we account for the case of multiple sections matching the same URL because the order of rules is part of cascading
2017-11-14 09:38:09 +03:00
tophf
3c08342e98 open usercss installer tab next to the source tab 2017-11-14 09:38:08 +03:00
tophf
95be66cb61 convert another tHTML in edit.js to $element 2017-11-14 09:36:43 +03:00
tophf
417d6855ff remove backtrackTo and trimNewLines from mozParser
* backtrackTo is not needed since 2e86c958
* trimNewLines does exactly the same as trim()
2017-11-14 09:24:38 +03:00
tophf
2a95793de0 csslint: fix PropertyValuePart.serializeString
Two old csslint bugs fixed:
* in the absence of capturing groups the replacer function receives the text and index
* the actual string "c" should be used to get character codes, not String class
2017-11-14 09:08:04 +03:00
tophf
70a827b033 dd69e1e5 followup + handle empty at-values
see #235
2017-11-14 08:55:53 +03:00
tophf
5a4e1290d3 csslint: fire "enddocument" on }
fixes #235
2017-11-14 08:55:45 +03:00
tophf
1d463d7820
Merge pull request #134 from eight04/dev-user-css
Install styles from *.user.css file
2017-11-14 08:22:56 +03:00
tophf
8b28262fe7 emphasize disableAll mode: make the label red and bold
fixes #227 which is quite typical for new users
2017-11-13 20:42:35 +03:00
tophf
b6703e7b15 fix disableAll in XML documents: tag names are case-sensitive in XML 2017-11-13 20:25:07 +03:00
tophf
8efe4b806b revert 3cf32048: Chrome 49+ XML viewer works with styles under <html> 2017-11-13 20:09:19 +03:00
eight
58c0239d85 Change: allow select to stretch up to 124px 2017-11-11 13:30:52 +08:00
eight
26e46a99f5 Fix: min height of message box title 2017-11-11 13:30:52 +08:00
eight
9b41a70c9b Fix: link style 2017-11-11 13:30:51 +08:00
eight
d59f24caa6 Change: a simpler installUpdateFromLabel 2017-11-11 13:30:41 +08:00
eight
ecc306dd1f Change: move header to the top 2017-11-11 13:30:34 +08:00
eight
7543b8406f Fix: messageBox global 2017-11-09 15:56:29 +08:00
eight
a1c1eb328b Add: draw line pointer for parsing error 2017-11-09 15:55:06 +08:00
eight
79a7a218c4 Fix: align text to left in pre 2017-11-09 15:54:31 +08:00
eight
d02984ee2a Add: expose parseError.index 2017-11-09 15:53:09 +08:00
eight
4d8268bb27 Fix: use messageBox 2017-11-09 14:40:46 +08:00
eight
ae50cbe12a Refactor: move alert/confirm util to msgbox.js 2017-11-09 14:35:10 +08:00
eight
c2687573b3 Add setStyleDirty, refactor replaceStyle 2017-11-09 14:11:27 +08:00
eight
d93bf05f64 Fix: isWarm -> isTouched 2017-11-09 14:11:27 +08:00
eight
6d411c01fc Fix: use sticky flag to avoid text slicing 2017-11-09 14:11:27 +08:00
eight
53770c0db6 i18n: appliesRemoveError 2017-11-09 14:11:26 +08:00
eight
d03c752dd5 Fix: promise indent 2017-11-09 14:11:26 +08:00
eight
988a920a2f Fix: use getOwnTab in closeCurrentTab 2017-11-09 14:11:26 +08:00
eight
9a8c19b09b Fix: move isClean into unbeforeunload handler 2017-11-09 14:11:26 +08:00
eight
3011ba836d Fix: isInit -> initialized 2017-11-09 14:11:26 +08:00
eight
29f5daa912 i18n: live reload error 2017-11-09 14:11:25 +08:00
eight
1dd0dbf907 Revert: isSame/isEdited util 2017-11-09 14:11:25 +08:00
eight
4a8894de2e Add: use messageBox in install page 2017-11-09 12:26:50 +08:00
eight
137198e951 Refactor: messageBox 2017-11-09 09:12:17 +08:00
eight
f070d7ff8e Fix: indent of promises 2017-11-09 09:12:16 +08:00
eight
5dd322e512 Refactor: shouldShowConfig 2017-11-09 09:12:16 +08:00
eight
78c1a1bd3c Fix: el -> elements 2017-11-09 09:12:16 +08:00
eight
dd64551a36 Fix: set dirty prop in one line 2017-11-09 09:12:16 +08:00
eight
c17433c350 Fix: use switch-case 2017-11-09 09:12:16 +08:00
eight
7842ac752a i18n: styleMetaErrorPreprocessor 2017-11-09 09:12:15 +08:00
eight
09e7d67dd2 Refactor: buildMeta 2017-11-09 09:12:15 +08:00
eight
a1b818f0c5 Fix: invalid default value for dropdown 2017-11-09 09:12:15 +08:00
eight
f86d0fc2e7 Fix: use sticky flag to avoid slicing string 2017-11-09 09:12:15 +08:00
eight
6358162bec Fix: createOption in one line 2017-11-09 09:12:15 +08:00
eight
3a78681d9e Fix: use .map to build varDef 2017-11-09 09:12:14 +08:00
eight
95e3ba13cd Fix: newStyleInUsercss -> newStyleAsUsercss 2017-11-09 09:12:14 +08:00
eight
0c292c3150 Fix: download should throw status code 2017-11-09 09:12:14 +08:00
eight
5f5b06b10c Fix: use FIREFOX variable 2017-11-09 09:12:14 +08:00
eight
2b614bdee2 Fix: dom.js is not a content script anymore 2017-11-09 09:12:13 +08:00
eight
7266c38d56 Fix: inline svg 2017-11-09 09:12:13 +08:00
eight
fa1c55bc2a Fix: EOF 2017-11-09 09:12:13 +08:00
eight
0d06f32735 Fix: updateMetas -> updateMeta 2017-11-09 09:12:13 +08:00
eight
48e565079c Fix: reindent promise 2017-11-09 09:12:12 +08:00
eight
eef17cc4f8 Fix: replaceMetas -> replaceMeta 2017-11-09 09:12:12 +08:00
eight
b4dfe5c836 Fix: use isArray 2017-11-09 09:12:12 +08:00
eight
c4c4b5638e Refactor: isUsercss 2017-11-09 09:12:12 +08:00
eight
92cadc03fa Fix: avoid return short circuit for editor selection 2017-11-09 09:12:11 +08:00
eight
2edd22e37c Fix: normalizeString -> unquote 2017-11-09 09:12:10 +08:00
eight
3844b3db73 Fix: cm.findPosH in one line 2017-11-09 09:12:10 +08:00
eight
0c64e6013b Fix: insertBefore -> insertAdjancentElement 2017-11-09 09:12:09 +08:00
eight
3d57fd4158 Fix: e.target -> this 2017-11-09 09:12:09 +08:00
eight
809414941e Refactor: add createApply 2017-11-09 09:12:08 +08:00
eight
3c5136171e Fix: use messageBox 2017-11-09 09:12:08 +08:00
eight
9d1b0884e5 Fix: use this.value 2017-11-09 09:12:08 +08:00
eight
191603ae01 Fix: makeInputEl -> makeLi 2017-11-09 09:12:07 +08:00
eight
caaeec08e4 Fix: use Math.max 2017-11-09 09:12:06 +08:00
eight
a7b73e859f Fix: use debounce 2017-11-09 09:12:06 +08:00
eight
285f3144ca Fix: style -> gutterStyle 2017-11-09 09:12:04 +08:00
eight
f70cf01155 Fix: move let definition into one line 2017-11-09 09:12:04 +08:00
eight
e0bd991482 Fix: promise indent 2017-11-09 09:12:03 +08:00
eight
92b01e19e8 Fix: reindent single then 2017-11-09 09:12:03 +08:00
eight
8d19e0b09a Fix: noReject in one line 2017-11-09 09:12:02 +08:00
eight
08c7004123 Fix: use switch for version compare 2017-11-09 09:12:02 +08:00
eight
90be1dae25 Fix: status: 'success' -> success: true 2017-11-09 05:35:45 +08:00
eight
391cfb52dd Fix: then -> than the 2017-11-09 05:29:38 +08:00
tophf
684f445957 workaround for USO double-firing of install/update events 2017-11-08 07:00:38 +03:00
tophf
d053d78c8f popup: use "height: min-content" instead of the hack 2017-11-08 06:54:30 +03:00
tophf
d2b9b30239 reliable userAgent detection in FF before 57
fixes #228
2017-11-08 06:53:36 +03:00
tophf
93f1bed66c CodeMirror 5.31.0
fixes #225
2017-11-05 09:13:26 +03:00
tophf
72714160bb storage: fallback on any IndexedDB-related failure 2017-11-05 06:13:51 +03:00
eight
5a9f78e2ac Add: key:label syntax in var select 2017-11-04 08:38:17 +08:00
eight
2b17c07cd6 Fix: use CodeMirror.defineExtension 2017-11-01 11:18:42 +08:00
eight
0ad0c70f7c Fix: unnecessary trim line 2017-11-01 11:18:18 +08:00
eight
db1643e9b8 Refactor: pull out colorParser 2017-11-01 11:18:13 +08:00
eight
71a1c5e18a Fix: old -> oldStyle 2017-11-01 11:17:01 +08:00
eight
f35fbb5b36 Fix: add styleMetaErrorSelectValueMismatch 2017-11-01 11:17:01 +08:00
eight
45e70b2b6a Fix: use Array.isArray 2017-11-01 11:17:01 +08:00
eight
d981660983 Fix: drop getParams 2017-11-01 11:17:00 +08:00
eight
6a53ea423c Refactor: pull out createAppliesToLineWidget 2017-11-01 11:17:00 +08:00
eight
8f642dc05c Fix: drop innerHTML 2017-11-01 11:17:00 +08:00
eight
534803ccfd Fix: isWarm 2017-11-01 11:17:00 +08:00
eight
9dddbbba9f Fix: unused getName 2017-11-01 11:16:59 +08:00
eight
45da3ff50e Fix: style.id consistency 2017-11-01 11:16:59 +08:00
eight
13ca45a104 Fix: reorder global comment 2017-11-01 11:16:46 +08:00
eight
398056c262 Fix: _source -> newSource 2017-11-01 11:15:18 +08:00
eight
098dc10f85 Fix: pull out runtimeSend 2017-11-01 11:15:11 +08:00
eight
79b6266cf9 Fix: no new line before use strict 2017-11-01 11:13:57 +08:00
eight
6f51100c82 Fix: unused injectContent 2017-11-01 08:09:08 +08:00
eight
6536028cd4 Fix: typo 2017-11-01 08:07:17 +08:00
eight
6fac8386c9 Fix: unused translation 2017-11-01 08:06:18 +08:00
tophf
3c665aea08 widen editor input[type="number"], align to match siblings
fixes #221
2017-10-31 12:52:11 +03:00
eight
62748b3b79 Fix: use arrow function for IIFE 2017-10-30 01:22:10 +08:00
eight
adc0c8025a Fix: lazy load regexp tester 2017-10-30 01:07:08 +08:00
Sebastian Reuße
033269ac9b popup: don’t assume the browser styles text in black
Fixes #218.
2017-10-28 10:47:30 +03:00
tophf
e9a7640a3f apply: recognize moz-extension:// 2017-10-20 02:13:01 +03:00
tophf
d4ce2b2def csslint: add compat prefixes for flex*, remove ms-box-* 2017-10-19 19:25:05 +03:00
tophf
2421a7ae99 csslint: update user-select 2017-10-19 19:18:09 +03:00
tophf
213da44fcc csslint: add border-image-repeat: space 2017-10-19 19:18:05 +03:00
tophf
22284f34cb csslint: fix color values 2017-10-19 19:18:05 +03:00
tophf
5064ca1d4e prevent DOM id confusion
DOM elements with an id are propagated as global variables
https://stackoverflow.com/q/6381425
2017-10-18 21:30:17 +03:00
eight
71013623c6 Fix: description for linterCSSLintIncompatible 2017-10-17 04:09:14 +08:00
eight
ce348d4f86 Fix: add isWarm flag to decide if the editor can be reloaded 2017-10-16 16:08:13 +08:00
eight
0a6de8edb8 Add: make dirtyReporter.clear accept a key 2017-10-16 16:05:48 +08:00
eight
831a4ef939 Fix: remove logging in wrapReject 2017-10-16 14:59:45 +08:00
eight
be4a896bc9 Fix: disable CSSLint option in stylus mode 2017-10-16 14:54:47 +08:00
eight
95902388a3 Fix: default linter hacks 2017-10-16 03:58:02 +08:00
eight
368bb34811 Fix: make updateLinter wait linterConfig to load 2017-10-15 05:19:22 +08:00
eight
96a046f774 Fix: toggle style outside of the editor 2017-10-15 04:18:23 +08:00
eight
9770523660 Fix: vertical rhythm in config dialog 2017-10-15 04:18:23 +08:00
eight
c1d2857953 Add: config dialog heading - feedback link 2017-10-15 04:18:22 +08:00
eight
7c2248933a Change: let makeLink accept object 2017-10-15 02:59:55 +08:00
eight
a1ca416ef2 Fix: miss makeLink global 2017-10-15 02:59:28 +08:00
tophf
382e0428c6 code cosmetics (copypasting from MDN was a bad idea) 2017-10-14 04:34:25 +03:00
tophf
721dfc4787 export: create blob directly
fixes #211
2017-10-14 04:25:54 +03:00
narcolepticinsomniac
0b17c669de Match overlay opacity throughout
#209
2017-10-12 19:52:49 -04:00
narcolepticinsomniac
e612a305cc Moz-import background
Fixes #209

I used `!important` because I think it might be necessary to override themes.
2017-10-12 19:50:41 -04:00
eight
54076d9f17 Merge branch 'master' of https://github.com/openstyles/stylus into dev-user-css 2017-10-12 16:28:18 +08:00
eight
33607e74a7 Fix: let makeAuthor use makeLink 2017-10-12 16:15:45 +08:00
eight
40ad7837fc Change: allow makeLink to append child. Add rel=noopener 2017-10-12 16:12:34 +08:00
eight
eec52ad239 Revert "Add: detail dialog. Move makeAuthor to dom.js. Move external.svg into"
This reverts commit 5b701d06ad.
2017-10-12 16:10:17 +08:00
eight
ce2a21451a Add: usercss documentation link in the editor 2017-10-11 22:23:39 +08:00
eight
7ca993821a Change: always set updateUrl 2017-10-11 21:45:17 +08:00
eight
2642206e32 Change: the layout of color input 2017-10-11 21:39:30 +08:00
eight
5b701d06ad Add: detail dialog. Move makeAuthor to dom.js. Move external.svg into
images.
2017-10-11 14:52:42 +08:00
Rob Garrison
f5342bd37e Lint: Add -webkit-sticky support to CSSLint 2017-10-11 01:01:24 +03:00
eight
3906060aef Add: multi-line string syntax 2017-10-09 02:45:26 +08:00
eight
4115705d8f Fix: uso replace doesn't work on var select 2017-10-09 02:45:11 +08:00
eight
c0378e3f05 Fix: uso preprocessor infinite recursion 2017-10-09 02:44:17 +08:00
eight
1d1c7da19e Fix: hide the header in error page 2017-10-09 01:05:44 +08:00
eight
77b6b6c857 Change: drop looseJSONParse 2017-10-09 01:03:51 +08:00
eight
a901ca29c1 Add: allow array in var select 2017-10-09 00:59:10 +08:00
eight
cd00c20fa4 Fix: newStyleFormat -> newStyleInUsercss 2017-10-09 00:52:05 +08:00
eight
2f3c477d96 Fix: openEditor has no response 2017-10-09 00:44:09 +08:00
eight
1a6f9dfcaa Add: confirmation to replace dirty style 2017-10-09 00:43:00 +08:00
eight
228057d231 Add: make source editor work with newly created style 2017-10-08 23:26:55 +08:00
eight
3cb1943648 Add: newStyleFormat option 2017-10-08 23:26:23 +08:00
eight
8007f47c09 Revert "Add: save usercss from multi-section editor"
This reverts commit da5626a6d7.
2017-10-08 22:08:47 +08:00
eight
50a5bbecfa Add: regexp tester in applies-to line widget 2017-10-08 22:03:27 +08:00
eight
9ee7e2046c Refactor: split out regexp tester 2017-10-07 23:41:37 +08:00
eight
f255631a0b Fix: live-reload doesn't send style id 2017-10-07 18:14:49 +08:00
eight
765231581c Fix: onbeforeunload handler would disable the save button 2017-10-07 18:10:00 +08:00
eight
40a1781a53 Fix: TypeError when missing author meta 2017-10-07 18:04:37 +08:00
eight
fc51d806da Fix: force using stylelint when editor mode is not css 2017-10-07 18:00:25 +08:00
eight
56e669fbcf Fix: normalize version 2017-10-06 17:09:28 +08:00
eight
da5626a6d7 Add: save usercss from multi-section editor 2017-10-06 17:05:51 +08:00
eight
0d4d058b00 Fix: remove unused initInstallPage 2017-10-06 16:33:50 +08:00
eight
f194155830 Add: close source tab after install 2017-10-06 16:33:50 +08:00
eight
c0514a6699 Change: default linter 2017-10-06 16:33:49 +08:00
eight
b866688a87 Add: parse author string 2017-10-06 16:33:48 +08:00
narcolepticinsomniac
bfc56bedf7 Cosmetic tweaks
#206
2017-10-06 00:50:38 -04:00
eight
0f6de587ec Add: remove/add button in applies-to widget 2017-10-06 01:10:45 +08:00
eight
b69b834949 Fix: handle editor.options.expanded 2017-10-04 16:47:56 +08:00
eight
bb508b6933 Fix: import error is not displayed correctly 2017-10-04 16:39:02 +08:00
eight
6636d3382b Fix: install error when live-reload is disabled 2017-10-04 16:32:44 +08:00
eight
2912a53729 Fix: missing id when updating digest 2017-10-04 16:19:20 +08:00
tophf
b777cc1bea use FF/Chrome/spec-compliant 'overflow-wrap' for word-breaking 2017-09-30 20:14:44 +03:00
tophf
51b4fadc74 options: specify charset 2017-09-30 03:26:09 +03:00
tophf
869168f727 install: better USO title bug workaround on page>=2 2017-09-30 03:20:59 +03:00
tophf
7cf27601ae popup: USO workaround for finding extension styles 2017-09-30 03:19:27 +03:00
tophf
0978308325 openerTabId added in FF57: https://bugzil.la/1238314 2017-09-30 02:40:01 +03:00
tophf
9585aea08d insertCSS#cssOrigin requires FF53 2017-09-30 02:32:43 +03:00
tophf
bf9ebab295 extract browser version instead of boolean 2017-09-30 02:32:05 +03:00
Jeremy Schomery
91daeb4a9e updating locales 2017-09-27 15:17:50 +03:30
eight
c2eadda708 Add: live-reload 2017-09-25 20:01:50 +08:00
eight
04ebc837e2 Fix: use closeCurrentTab 2017-09-25 18:45:44 +08:00
eight
7365a8bada Fix: various fixes 2017-09-25 18:43:55 +08:00
eight
587feb3817 Fix: externalLink might be null 2017-09-25 18:21:11 +08:00
eight
cb7aaa7111 Fix: move to root 2017-09-24 17:18:38 +08:00
eight
24cd85688f WIP: install page + editor 2017-09-24 16:54:21 +08:00
eight
18fd15317e WIP: install page 2017-09-24 11:39:04 +08:00
tophf
2d8adf1173 restore size on reopening a closed editor tab 2017-09-23 21:33:57 +03:00
eight
a4e3fba968 Fix: source editor is not closed when style is removed 2017-09-19 08:51:57 +08:00
eight
2b6404cb11 Fix: stop live-reload and refresh the page when style is removed 2017-09-19 08:51:57 +08:00
eight
0852b56ce4 Fix: add set updateUrl option 2017-09-19 08:51:56 +08:00
eight
ba4c06ae82 Fix: lint initialize issue 2017-09-19 08:51:56 +08:00
eight
d1964bbc16 Fix: make download be able to read file: 2017-09-19 08:51:55 +08:00
eight
ead006a311 Fix: remove button style 2017-09-19 05:10:45 +08:00
eight
aa71984fd3 Fix: save name when updating usercss 2017-09-18 12:59:22 +08:00
eight
94a7e0cdb5 Fix: manually updated usercss doesn't keep settings 2017-09-18 12:18:55 +08:00
eight
1d829fe8f5 Fix: split up usercss logic from saveStyle 2017-09-18 11:34:12 +08:00
eight
1e9ee786ea Fix: normalize new line 2017-09-18 08:16:11 +08:00
eight
94e5336018 Fix: don't set updateUrl to a local file 2017-09-18 07:39:46 +08:00
eight
90ca2f2d23 Fix: autocomplete should use changes event 2017-09-18 07:33:07 +08:00
tophf
054528edde apply: SVG className workaround 2017-09-17 10:56:03 +03:00
eight
aed3698c74 Fix: looseJSONParse doesn't work on chrome 49 2017-09-16 10:14:24 +08:00
eight
a0495f466f Change style structure 2017-09-16 10:14:23 +08:00
eight
dc988a413e Revert: editors 2017-09-16 08:44:56 +08:00
eight
4d6f856473 Revert "Add: scroll the editor when cursor is outside of the editor"
This reverts commit 5a9ac5ce7d.
2017-09-16 07:33:12 +08:00
tophf
9210d55438 manage: unlimited height of expanded applies-to 2017-09-15 13:52:21 +03:00
eight
a73493d5d2 Add: make applies-to line widget editable 2017-09-15 17:13:58 +08:00
eight
693a0483e3 Add: offset info 2017-09-15 15:36:44 +08:00
eight
ccb5f488e5 Fix: move to new format 2017-09-15 14:11:58 +08:00
eight
eaf33afbe3 Rewrite parser, add uso preprocessor 2017-09-15 13:40:04 +08:00
eight
21256e32f7 Fix: wrap long line 2017-09-15 08:11:18 +08:00
eight
5a9ac5ce7d Add: scroll the editor when cursor is outside of the editor 2017-09-15 07:47:44 +08:00
eight
553cc94bc8 Fix: style install button 2017-09-15 01:30:26 +08:00
eight
a542d227ec Fix: adjust install page layout 2017-09-14 11:06:32 +08:00
eight
70bbc08ee0 Add editor.appliesToLineWidget option 2017-09-14 09:58:22 +08:00
eight
2ba4c4f11b Fix: remove debounce dependency 2017-09-14 09:15:58 +08:00
eight
37c83ce187 Fix: shouldn't contain new line 2017-09-14 09:10:11 +08:00
eight
b7b5888431 Fix: should't edit the style object directly returned from getStyles cache 2017-09-14 09:09:40 +08:00
eight
97fd2aa083 Compat: firefox 2017-09-13 23:35:34 +08:00
eight
40a5dab311 Fix: script order of loadLinterAssets 2017-09-13 21:26:22 +08:00
eight
411df8b051 Fix: no need to use $$ for element existence check 2017-09-13 20:39:42 +08:00
eight
3c450e7d9d Fix: resize grip style 2017-09-13 20:28:19 +08:00
eight
b61b058824 Fix: pull out makeLink 2017-09-13 17:34:27 +08:00
eight
d7f0e3c176 fixup! Fix: draw title 2017-09-13 17:33:32 +08:00
eight
0e92e6d0c7 Add applies-to line widget 2017-09-13 16:58:03 +08:00
eight
6195e558e4 Fix: draw title 2017-09-13 16:57:01 +08:00
eight
b102aa0704 Fix: beforeunload warning 2017-09-13 16:56:16 +08:00
eight
fa06b29748 Fix: add 'v' before version 2017-09-13 16:54:09 +08:00
eight
31464bb499 Fix: reference error 2017-09-13 16:53:21 +08:00
tophf
3d0b811b27 edit: throttle setOption for 'theme' and 'lineWrapping'
when the style has more than 4 sections, these options are propagated to CM instances in 100 ms chunks, and a progress overlay is shown over the corresponding option element after 100 ms
2017-09-12 23:19:10 +03:00
eight
279c7d05a7 Fix: _style -> newStyle 2017-09-13 01:39:45 +08:00
eight
93fe23f2a6 Fix: innerHTML -> textContent 2017-09-13 01:39:34 +08:00
eight
6165487db6 Fix: use lowercase placeholder 2017-09-13 00:03:23 +08:00
eight
436551a6f9 Fix: alpha channel -> opacity 2017-09-12 23:58:59 +08:00
eight
acaa1ed158 Fix: appendChild -> textContent 2017-09-12 23:23:56 +08:00
eight
2342cc50e9 fixup! Fix: rewrite loadScript, merge onDOMscripted, injectCSS, injectScript 2017-09-12 23:19:55 +08:00
eight
2506b957f8 Fix: rewrite loadScript, merge onDOMscripted, injectCSS, injectScript 2017-09-12 23:19:16 +08:00
eight
dc37588cd1 Fix: drop windowLoaded 2017-09-12 21:34:12 +08:00
eight
a1b8945996 Fix: remove try-catch in util.js 2017-09-12 21:28:26 +08:00
eight
23bd3e2cc7 fixup! Fix: err -> e 2017-09-12 20:48:03 +08:00
eight
6b1d6564fb Fix: drop pad 2017-09-12 20:44:12 +08:00
eight
8e5ffd036f Fix: use rgb() when alpha === 1 2017-09-12 20:29:09 +08:00
eight
a3f26d89b8 Fix: _parse -> parseRGB 2017-09-12 20:25:59 +08:00
eight
e3c3dcc1ff Fix: use .map to build vars 2017-09-12 20:24:25 +08:00
eight
9069562587 Fix: err -> e 2017-09-12 20:20:58 +08:00
eight
51e92e5a7b Fix: use IIFE for try-catch in tDocLoader 2017-09-12 20:08:09 +08:00
eight
7c1b140de9 Fix: drop tHTML 2017-09-12 20:06:00 +08:00
eight
431dbdc81c Fix: remove escapeHtml completely 2017-09-12 20:03:24 +08:00
eight
39df704591 Fix: move editor creation to one structure 2017-09-12 20:01:27 +08:00
eight
4b2f7a1a46 Fix: make codeIsUpdated flag work properly 2017-09-12 19:57:43 +08:00
eight
e7eb38bba9 Fix: drop dummy Promise.resolve 2017-09-12 19:47:32 +08:00
eight
02c61b9276 Fix: self -> _ 2017-09-12 19:45:08 +08:00
eight
7612cd3614 Fix: move createEmptyStyle, windowLoaded into init 2017-09-12 19:39:01 +08:00
eight
27f8bc2f85 Fix: don't use leading underscore for function name 2017-09-12 19:37:06 +08:00
eight
e4d3025fca Revert changes to editors global 2017-09-12 19:34:04 +08:00
eight
43b912c195 Fix: remove suffix check 2017-09-12 19:30:53 +08:00
eight
bbe37adfef Fix: drop tHTML 2017-09-12 19:28:20 +08:00
eight
97b4d91ec9 Fix: communicate -> runtimeSend 2017-09-12 18:58:39 +08:00
eight
f3176de950 Fix: findDupUsercss indent 2017-09-12 18:57:06 +08:00
eight
e1d221e9a9 Fix: saveStyle indent 2017-09-12 18:54:38 +08:00
eight
e13a6f6f92 Fix: saveUsercss 2017-09-12 18:52:55 +08:00
eight
a395df18f9 Fix: rewrite filterUsercss 2017-09-12 18:49:17 +08:00
eight
33200dbde4 Fix: cleanup injectContent 2017-09-12 18:34:48 +08:00
eight
8207d608be Fix: injectResource -> injectContent 2017-09-12 18:28:16 +08:00
eight
6ce4af8952 Fix: wrong indentation 2017-09-12 18:25:25 +08:00
tophf
a8796b0bd2 prevent race condition in getStyles before dbExec.initialized
fixes #184
2017-09-12 12:12:11 +03:00
eight
5fecd7e91b Drop .before, .after, .prepend, .append 2017-09-12 04:10:20 +08:00
eight
e2ea93a3c7 Fix: decodeURI -> encodeURI 2017-09-12 03:56:05 +08:00
eight
de84248e05 Fix: add editors hack 2017-09-12 03:44:19 +08:00
eight
d4ddefe8a0 Merge branch 'master' of https://github.com/openstyles/stylus into dev-user-css 2017-09-12 03:40:56 +08:00
eight
41f0174362 Add: valid url 2017-09-12 02:46:37 +08:00
eight
3730a4e483 Fix: i18n and escapeHtml, url 2017-09-12 02:32:27 +08:00
eight
20481c9180 Fix: i18n config dialog 2017-09-12 01:59:56 +08:00
eight
381ee88e94 Fix: i18n error message 2017-09-12 01:48:10 +08:00
eight
f305719db3 Fix: update progress 2017-09-12 01:23:32 +08:00
eight
a15493bfb9 Add: source editor 2017-09-12 00:10:27 +08:00
eight
8bc6986cac Change: make unknown preprocessor throw 2017-09-12 00:10:27 +08:00
eight
cfdb0b4eeb Add mode stylus, loadmode 2017-09-12 00:10:27 +08:00
eight
1c3317202f Refactor: init 2017-09-12 00:10:26 +08:00
tophf
df80a84469 options: #advanced block is collapsed by default in Chrome
* Chrome has a hardcoded limit for the options dialog height at 640px
  and it's better to avoid the vertical scrollbar on smaller displays
* Chrome users are less likely to change the weird stuff we have there
2017-09-10 21:26:21 +03:00
tophf
7bde873b3b manage: more space around the actions column 2017-09-10 21:19:38 +03:00
tophf
4f7876f961 manage: prevent wrapping in check-all and view-log row 2017-09-10 21:19:37 +03:00
tophf
522629f534 manage: restore our standard font size in the filter selector 2017-09-10 21:19:37 +03:00
eight
8c374db353 Add: live-reload 2017-09-10 22:56:44 +08:00
eight
cb23f89b6a Add: allow saveUsercss to build style 2017-09-10 22:04:43 +08:00
eight
3daff40acf Add: vars validation 2017-09-09 19:29:35 +08:00
eight
bf455752ec Use options dialog style 2017-09-07 01:51:28 +08:00
eight
4e0f4b34bb Add: colorParser 2017-09-07 01:51:27 +08:00
Jeremy Schomery
63954c986f version 1.1.4.1 2017-09-06 18:53:09 +04:30
Jeremy Schomery
ba8ca81c2e updating "ja" locale 2017-09-06 18:51:47 +04:30
Jeremy Schomery
8f28872830 version 1.1.4 2017-09-06 16:15:24 +04:30
Jeremy Schomery
fea92ddc5f updating locales 2017-09-06 16:04:32 +04:30
eight
1f44898475 Add: adopt node-semver 2017-09-06 03:08:03 +08:00
eight
f7a43d780f Add: draw different type of input 2017-09-05 18:48:19 +08:00
eight
3f06ce8152 Fix: don't mix url and updateUrl 2017-09-05 18:48:19 +08:00
eight
6e52d48c6c Add: Add 'applies to' to install page 2017-09-05 18:48:18 +08:00
eight
f74641e20d Add: make filterUsercss build code to get section includes 2017-09-05 18:48:18 +08:00
eight
78264a1c34 Add: parse more metas, add variable type 2017-09-05 18:48:18 +08:00
tophf
1daa713582 always hide lint report on switching the linter option 2017-09-04 01:07:07 +03:00
tophf
36d790e0c2 improve CSS transition suppression on own pages in FF 2017-09-04 01:05:32 +03:00
tophf
538da08a95 fixup d843b4e2: a shallow copy is needed 2017-09-03 22:34:42 +03:00
tophf
50239a49df fixup 53aa239d for new installations 2017-09-03 21:56:46 +03:00
tophf
09010c20a6 enqueue stuff dependent on DB decision 2017-09-03 21:25:19 +03:00
tophf
53aa239da3 fallback to chrome.storage when IndexedDB is dysfunctional 2017-09-03 20:06:42 +03:00
tophf
ea8eaf3146 swap parameters in prefs.subscribe 2017-09-03 20:06:30 +03:00
tophf
7a50387d35 fixup cd6bcc65: read BG.localStorage dummy properly 2017-09-03 20:06:30 +03:00
tophf
d60aea9333 followup d3b7b454: subscribe to 'editor.options.expanded' 2017-09-03 20:06:30 +03:00
tophf
e9b174f6e3 editor narrow mode: reduce options title margins 2017-09-03 19:43:38 +03:00
tophf
d843b4e23f filterStyles: code cosmetics and a bug fix 2017-09-03 19:43:38 +03:00
tophf
e69b6482b7 reopening a deleted style tab should switch to adding 2017-09-03 19:43:38 +03:00
tophf
519d745f59 globally disable CSS transitions for a moment during page opening
the problem we fix is that since we add the styles asynchronously, the browsers, esp. Firefox, sometimes apply transitions from the null/default state to the one specified in the injected CSS.

supersedes 72e8213b and 4dbca46b
2017-09-03 19:43:37 +03:00
tophf
0c205df108 fixup 85a5702f: refactor; properly clear renderLintReportNow 2017-09-03 19:36:33 +03:00
tophf
13908a60a4 Shorten "new issue" intro and move it after the details we need 2017-09-02 21:23:04 +03:00
tophf
1d1d0453e1 code cosmetics to silence eslint 2017-09-02 19:32:12 +03:00
tophf
4dbca46b41 typo 2017-09-02 09:00:03 +03:00
tophf
72e8213bd7 followup 9a55e64b: suppress CSS transitions bug in FF while loading
fixes #177
2017-09-02 08:51:58 +03:00
eight
b3b47697ca Fix: display homepage icon for usercss 2017-09-01 18:31:58 +08:00
eight
4dec09708c Rewrite usercss installation page 2017-09-01 18:31:58 +08:00
tophf
cf2f644366 code cosmetics 2017-09-01 13:30:58 +03:00
eight
3c40b52f96 Add 'injectResource' message to inject js/css 2017-09-01 18:21:45 +08:00
eight
0e5ab44f67 Fix: remove message.js dependency from localization.js 2017-09-01 18:21:01 +08:00
tophf
d3b7b45452 editor: toggle #options block upon clicking its title 2017-09-01 12:49:09 +03:00
tophf
1f237a98eb editor: focus the name input when saving a nameless style 2017-09-01 12:27:59 +03:00
tophf
874088e067 edit: focus the first section upon opening 2017-09-01 12:25:40 +03:00
tophf
96b47e7bdd editor: autoswitch to next/prev editor on cursor movement 2017-09-01 12:23:49 +03:00
tophf
8809384264 debounce indicateCodeChange per cm 2017-09-01 11:16:57 +03:00
tophf
0a5d9d86bf editor: on disabling CSS linter option, hide the report entirely 2017-09-01 11:08:48 +03:00
tophf
27ad478f8c fixup fb7f7d54: isMatching must be boolean 2017-09-01 11:04:24 +03:00
eight
acd9befc9e Change how configure dialog works. 2017-09-01 14:53:57 +08:00
eight
dfb7ac9b44 Extend messageBox to set onclick handler on buttons 2017-09-01 14:46:00 +08:00
eight
8607d779f9 Change how var is saved 2017-09-01 14:38:46 +08:00
eight
9c2acd5cc9 Fix: remove unused variable 'event' 2017-09-01 14:36:13 +08:00
eight
6aaa7ef878 Fix: configure icon 2017-09-01 13:36:03 +08:00
tophf
86ebca5e1a editor: show progress bar while opening huge styles 2017-09-01 00:52:38 +03:00
tophf
85a5702fe0 refactor lint report stuff, use $element 2017-08-31 23:19:43 +03:00
tophf
ec01914f17 separate 'rule' property in lint annotations 2017-08-31 22:25:28 +03:00
tophf
7f9c377d33 use 'changes' event to reduce overhead upon replaceAll 2017-08-31 22:25:28 +03:00
tophf
ab97108e6f properly replace the editors in initWithStyle 2017-08-31 21:27:10 +03:00
tophf
799108e880 create code box in write-new-style editor immediately 2017-08-31 21:27:10 +03:00
tophf
0189ae1d64 show lint report on open earlier; lint on import 2017-08-31 21:27:07 +03:00
tophf
4c616442f6 correctly show/hide #no-styles message in the popup 2017-08-31 13:42:30 +03:00
tophf
35615eb2d4 make message-box.danger close icon match the red title 2017-08-31 13:42:30 +03:00
tophf
fa5ebb8958 use callbacks in animateElement to avoid re-animation 2017-08-31 13:42:30 +03:00
tophf
58b52b0bf0 make #confirm popup more flexible
kinda fixes #175
2017-08-31 13:42:30 +03:00
tophf
8960a9f5ce fixup 3c5d20f8: show detection results properly
fixes #180
2017-08-30 21:21:48 +03:00
tophf
916a3bced3 fixup bf4619fc possible OOB 2017-08-30 20:54:03 +03:00
tophf
bf4619fc2e exponentially speedup getEditorInSight to avoid delaying 'find'
related: #178
2017-08-30 20:44:41 +03:00
tophf
c88438c6eb use tryCatch to simplify 7e5396a1 2017-08-30 18:05:22 +03:00
tophf
3c5d20f862 proper partial match detection and display in showRegExpTester
closes #180
2017-08-30 17:50:32 +03:00
tophf
58b1c5be81 fixup 508f71f2: revert to 'function' to use the correct 'this' 2017-08-30 16:32:08 +03:00
eight
81f490c34d Fix: csslint is moved 2017-08-30 17:41:07 +08:00
eight
7b9348a545 Fix: better error message 2017-08-30 17:40:19 +08:00
eight
dece4b57f3 Add: install styles from *.user.css file
Fix: handle dup name+namespace

Fix: eslint eqeqeq

Fix: trim @name's spaces

Add: check update for userstyle

Add: build CSS variable

Fix: only check dup when id is not provided

Refactor: userStyle2json -> userstyle.json

Add: style for input

Add: config dialog

Fix: preserve config during update

Fix: onchange doesn't fire on keyboard enter event

Fix: remove empty file

Add: validator. Metas must stay in the same line

Add: warn the user if installation failed

Fix: add some delay before starting installation

Add: open the editor after first installation

Fix: add openEditor to globals

Fix: i18n

Add: preprocessor. Move userstyle.build to background page.

Fix: remove unused global

Fix: preserved unknown prop in saveStyleSource() like saveStyle()

Add: edit userstyle source

Fix: load preprocessor dynamically

Fix: load content script dynamically

Fix: buildCode is async function

Fix: drop Object.entries

Fix: style.sections is undefined

Fix: don't hide the name input but disable it

Fix: query the style before installation

Revert: changes to editor, editor.html

Refactor: use term `usercss` instead of `userstyle`

Fix: don't show homepage action for usercss

Refactor: move script-loader to js/

Refactor: pull out mozParser

Fix: code style

Fix: we don't need to build meta anymore

Fix: use saveUsercss instead of saveStyle to get responsed error

Fix: last is undefined, load script error

Fix: switch to moz-format

Fix: drop injectContentScript. Move usercss check into install-user-css

Fix: response -> respond

Fix: globals -> global

Fix: queryUsercss -> filterUsercss

Fix: add processUsercss function

Fix: only open editor for usercss

Fix: remove findupUsercss fixme

Fix: globals -> global

Fix: globals -> global

Fix: global pollution

Revert: update.js

Refactor: checkStyle

Add: support usercss

Fix: no need to getURL in background page

Fix: merget semver.js into usercss.js

Fix: drop all_urls in match pattern

Fix: drop respondWithError

Move stylus -> stylus-lang

Add stylus-lang/readme

Fix: use include_globs

Fix: global pollution
2017-08-30 17:29:41 +08:00
tophf
6f0ab8113e suppress reverting to a blank in auto-import on paste 2017-08-30 10:51:29 +03:00
tophf
edc2ab0ead auto-open import dialog when pasted text has @-moz-document 2017-08-30 02:26:47 +03:00
tophf
f308d0be6c increase height of a single code box upon pasting 2017-08-30 02:04:41 +03:00
tophf
22824d9ad5 deepCopy linterConfig to avoid rule normalization by stylelint 2017-08-30 00:05:07 +03:00
tophf
79c6f3e578 csslint: support var() in compound properties 2017-08-29 19:10:42 +03:00
tophf
e4ea7a44af updateLinter will be called by watchStorage on save 2017-08-29 18:30:39 +03:00
tophf
c7a0759216 don't run CSS linters in the config dialog json 2017-08-29 18:22:08 +03:00
tophf
3d5383ceaf debounce and subscribe updateLinter 2017-08-29 17:59:53 +03:00
tophf
b91324992d skip already queued in onDOMscripted 2017-08-29 17:14:57 +03:00
tophf
c15082fed4 editor: preload lint gutters css; update on disabling 2017-08-29 17:12:39 +03:00
tophf
e65e3c9c0b fixup efc001c0: css_beautify is dodgy 2017-08-29 14:28:59 +03:00
tophf
73dc33d376 fixup f603d9b6: correctly apply 'highlight' selector 2017-08-29 00:12:53 +03:00
tophf
81e6720341 use $element in showLintHelp 2017-08-28 16:33:45 +03:00
tophf
76eb3f7e28 remove deprecated confirm() from onbeforeunload 2017-08-28 15:20:39 +03:00
tophf
efc001c01d fixup a44b4e78: css_beautify is exposed via exports 2017-08-28 15:20:38 +03:00
tophf
dd6182aef3 lint issues list: show rule name only on hover 2017-08-28 15:20:38 +03:00
tophf
37bff1c5c9 handle null response from API in chromeSync 2017-08-28 15:20:38 +03:00
tophf
5330db11af FF: ignore lastError in sendMessage where irrelevant 2017-08-28 15:20:38 +03:00
tophf
cd6bcc6511 FF: when not dom.storage.enabled use dummies 2017-08-28 15:20:38 +03:00
tophf
777fc06834 FF: avoid reloading if dysfunctional 2017-08-28 15:20:37 +03:00
tophf
9946f3c781 regroup some of lint* data and code
* all lint-related js files are prefixed by lint-
* config-related stuff is grouped in linterConfig
* CM helper is rewritten and moved in /edit now that CSSLint supports these features
* chromeSync methods that apply LZString got LZ in their names
* empty string is used for 'disabled' in linter selector
2017-08-28 15:20:37 +03:00
tophf
dfc3deaf01 csslint: support background-blend-mode 2017-08-28 15:20:37 +03:00
tophf
5c506f5cc9 csslint: support unicode-range 2017-08-28 12:53:10 +03:00
tophf
f80af3721c csslint: fix hsl/hsla regexp as per spec
* hue can be deg, %, rad, grad, turn - deg is default
* all numbers can be fractional
* hsla = hsl
2017-08-28 12:53:10 +03:00
tophf
da565a5fa5 Merge pull request #150 from Mottie/stylelint
Include both CSSLint and stylelint
2017-08-28 08:12:10 +03:00
Rob Garrison
fdeffde2c3 Set selected linter during import 2017-08-27 17:20:48 -05:00
Rob Garrison
6c3501bf9a Use rules or config consistently 2017-08-27 17:20:48 -05:00
Rob Garrison
21e22c2b6f Rename CSSLint ruleset to config 2017-08-27 17:20:48 -05:00
Rob Garrison
1e03910b0b Rename & organize linter messages 2017-08-27 17:20:48 -05:00
Rob Garrison
1d1a2ce1c8 Fix linter config tooltip 2017-08-27 17:20:48 -05:00
Rob Garrison
5ad23bd681 Do not automatically update the linter after a config reset 2017-08-27 17:20:48 -05:00
Rob Garrison
cb177eba4b Add linter config reset tooltip 2017-08-27 17:20:47 -05:00
Rob Garrison
1a384142ba Refocus textbox after save/reset 2017-08-27 17:20:47 -05:00
Rob Garrison
e96f0808ed Rename CSSLint rule config file & variable 2017-08-27 17:20:47 -05:00
Rob Garrison
b00d9575f8 Clear linter config history 2017-08-27 17:20:47 -05:00
Rob Garrison
ef197bcd58 Sort "cm_*" messages 2017-08-27 17:20:47 -05:00
Rob Garrison
2c234893e2 Add config cancel button 2017-08-27 17:20:47 -05:00
Rob Garrison
2df6b8bca0 Clean up lint globals 2017-08-27 17:20:47 -05:00
Rob Garrison
95ff72b722 Make linter config JSON more readable 2017-08-27 17:20:47 -05:00
Rob Garrison
52af5c85c0 Don't show nested "rules" in config 2017-08-27 17:20:47 -05:00
Rob Garrison
53af483a18 Revert 18a94cac30e18c 2017-08-27 17:20:47 -05:00
Rob Garrison
e2228964d4 Fix issue when CSSLint isn't loaded 2017-08-27 17:20:47 -05:00
Rob Garrison
988af5f1b8 Store linter rules with sync & LZ compression 2017-08-27 17:20:47 -05:00
Rob Garrison
f9c035082f Prevent JS error after closing help-popup 2017-08-27 17:20:47 -05:00
Rob Garrison
0cd88873e1 Show alert with invalid JSON and rule names 2017-08-27 17:20:47 -05:00
Rob Garrison
cbe6decb03 Assign stylelint to global, not lint 2017-08-27 17:20:47 -05:00
Rob Garrison
5b2cd77035 Fix indention 2017-08-27 17:20:47 -05:00
Rob Garrison
320fd07789 Rename as generic reset message 2017-08-27 17:20:47 -05:00
Rob Garrison
b7b99f0ed0 Disable non-essential stylelint rules 2017-08-27 17:20:47 -05:00
Rob Garrison
9c4b7bc310 Update stylelint bundle readme 2017-08-27 17:20:47 -05:00
Rob Garrison
3085b71891 Update to optimized stylelint bundle 2017-08-27 17:20:46 -05:00
Rob Garrison
ac1ffa98b5 Add CSSLint rule configuration 2017-08-27 17:20:46 -05:00
Rob Garrison
b178d3d8ee Open CSSLint rule in a new tab 2017-08-27 17:20:46 -05:00
Rob Garrison
2ae5cde274 Linkify CSSLint rules. See #167 2017-08-27 17:20:46 -05:00
Rob Garrison
487bb53145 Use optimal DOM selection functions
Reverts part of 7046d48cf9d574
2017-08-27 17:20:46 -05:00
Rob Garrison
8dc2115347 Revert no-inline-comments (2ea5a3bbaa2fdb0a) 2017-08-27 17:20:46 -05:00
Rob Garrison
4e502e57eb Fix import into editor 2017-08-27 17:20:46 -05:00
Rob Garrison
afc38b0bc8 update element selectors in all files 2017-08-27 17:20:46 -05:00
Rob Garrison
8645469d3b csslint warning update 2017-08-27 17:20:46 -05:00
Rob Garrison
ce906eb4b6 Move csslint-worker file 2017-08-27 17:20:45 -05:00
Rob Garrison
132cdc9920 Add CSSLint position sticky rule 2017-08-27 17:20:45 -05:00
Rob Garrison
1fc17861db Remove "Unexpected" from stylelint messages 2017-08-27 17:20:45 -05:00
Rob Garrison
d563495c26 Fix no-inline-comments issues 2017-08-27 17:20:45 -05:00
Rob Garrison
a3b8b7d168 Fix eslint issue 2017-08-27 17:20:45 -05:00
Rob Garrison
e387d7a5e7 Remove lint issues overflow & ellipsis 2017-08-27 17:20:45 -05:00
Rob Garrison
5ce7a925cb Move stylelint-config to edit folder 2017-08-27 17:20:45 -05:00
Rob Garrison
75deeddc0e Fix linting issues table
Also fixed severity icon alignment
2017-08-27 17:20:45 -05:00
Rob Garrison
80ed34f3e7 Use correct multi-line statement formatting 2017-08-27 17:20:45 -05:00
Rob Garrison
91825d11fd Clean up modified css-lint 2017-08-27 17:20:45 -05:00
Rob Garrison
5bfbab62d7 Use push instead of concat 2017-08-27 17:20:45 -05:00
Rob Garrison
bfe1ad60c2 Remove unnecessary braces 2017-08-27 17:20:45 -05:00
Rob Garrison
3e371f193a Set eslint no-inline-comments 2017-08-27 17:20:45 -05:00
Rob Garrison
5936d766f8 Update element selectors 2017-08-27 17:20:45 -05:00
Rob Garrison
b429735e86 Use loader script to load beautify 2017-08-27 17:20:44 -05:00
Rob Garrison
92a49759a9 Update empty stylelint rules on initial load 2017-08-27 17:20:44 -05:00
Rob Garrison
f36ce5c625 Fix undefined stylelintDefaultConfig 2017-08-27 17:20:44 -05:00
Rob Garrison
7da5bd1408 Remove link to jsonlint 2017-08-27 17:20:44 -05:00
Rob Garrison
9d1a1427a0 Fix stylelint settings json linting 2017-08-27 17:20:44 -05:00
Rob Garrison
775aec7c72 Add jsonlint resource 2017-08-27 17:20:44 -05:00
Rob Garrison
25ec79e8bb Fix jsonlint error message text 2017-08-27 17:20:44 -05:00
Rob Garrison
dded798ee3 Fix stylelint error message timer 2017-08-27 17:20:44 -05:00
Rob Garrison
7c5b4c2bcf Remove extra delay
It appears to no longer be an issue
2017-08-27 17:20:44 -05:00
Rob Garrison
29851a8de9 Dynamically load linter when selected 2017-08-27 17:20:44 -05:00
Rob Garrison
b1a7f8d4a2 Fix stylelint popup code & use codemirror 2017-08-27 17:20:44 -05:00
Rob Garrison
06130446c6 Set default stylelint severity warning 2017-08-27 17:20:43 -05:00
Rob Garrison
014adf8d8a Fix linting issues with injection code 2017-08-27 17:20:43 -05:00
Rob Garrison
3c160a3fa5 Add script/link injection code 2017-08-27 17:20:43 -05:00
Rob Garrison
f52f8c57d8 Rename linter.js to css-lint.js 2017-08-27 17:20:43 -05:00
Rob Garrison
287f16dcfa Use preventDefault 2017-08-27 17:20:43 -05:00
Rob Garrison
b89fb440f7 Replace try/catch with tryJSONparse 2017-08-27 17:20:43 -05:00
Rob Garrison
fefb8f332c Rename function to be more precise 2017-08-27 17:20:43 -05:00
Rob Garrison
6bd1768b72 Remove unnecessary global 2017-08-27 17:20:43 -05:00
Rob Garrison
0ccdf2fd7f Remove disabling of unrelated js linting issue 2017-08-27 17:20:43 -05:00
Rob Garrison
9564c21282 Split global definitions 2017-08-27 17:20:43 -05:00
Rob Garrison
73e7a9b3f1 Add stylelint config icon tooltip 2017-08-27 17:20:43 -05:00
Rob Garrison
481036c324 Fix localization messages & add placeholders 2017-08-27 17:20:43 -05:00
Rob Garrison
c2e294beff Fix js error when no linting issues exist 2017-08-27 17:20:43 -05:00
Rob Garrison
12a09976f2 Prevent vertical scrollbar on header 2017-08-27 17:20:43 -05:00
Rob Garrison
06cd78b643 Add stylelint settings popup & cleanup 2017-08-27 17:20:43 -05:00
Rob Garrison
07dce1006d Split out lint code from edit.js 2017-08-27 17:20:43 -05:00
Rob Garrison
dfa71f699e Add linter select option 2017-08-27 17:20:42 -05:00
Rob Garrison
139d7ebb98 Show stylelint warnings & use minified bundle 2017-08-27 17:20:42 -05:00
Rob Garrison
47e326d293 Remove duplicate file 2017-08-27 17:20:42 -05:00
Rob Garrison
a44b4e7822 Switch from CSSLint to stylelint 2017-08-27 17:20:42 -05:00
tophf
6f2883c6d3 remember window size only in active editor 2017-08-27 19:41:09 +03:00
tophf
a52c6ed9d7 avoid creating conflicts with stylelint PR 2017-08-27 18:03:59 +03:00
tophf
feea5e834e avoid avoiding to actually avoid
it was a Chrome bug workaround which became harmful now that it's fixed in Chrome
2017-08-27 17:50:53 +03:00
tophf
fa908d1ceb fixup 58f966be 2017-08-27 17:45:15 +03:00
tophf
ec95e8e7b4 simplify tabs.onAttached 2017-08-27 17:42:59 +03:00
tophf
58f966be98 use consistent file names for options assets 2017-08-27 17:17:28 +03:00
tophf
2631e3a685 try to fit all options in 640px max-height set by Chrome 2017-08-27 17:17:28 +03:00
tophf
5620ef606e expose openEditInWindow as an option 2017-08-27 17:17:28 +03:00
tophf
d1924c1d63 deglobalize onAttached listener for editor tabs
* bonus: one unconditional global listener less
* bonus: in FF the saved window size is restored on detaching
* theoretically possible drawback: 100+ editor tabs on a slow computer may be slower than before
2017-08-27 17:17:28 +03:00
tophf
738846a614 better remember and detect resizing of editor; FF-compatibility 2017-08-27 17:05:05 +03:00
tophf
dba3de7a86 fix&simplify narrow manager media queries 2017-08-27 17:05:05 +03:00
tophf
6256f1ab2d fix narrow editor media query in FF: use column-count 2017-08-27 14:40:23 +03:00
tophf
80ff6f6832 fixup 8976bd58: specify parent to avoid deadzoning 2017-08-27 14:30:39 +03:00
tophf
543fec82ce Use our font style for 'dysfunctional' message 2017-08-27 13:28:03 +03:00
tophf
320ea3485a hyphenate blocked-info in FF 2017-08-27 13:02:58 +03:00
tophf
90ab2959a6 abandon automatic translation in CSS
* it fails with some languages in some versions of FF
* it's not as flexible as HTML templates
* we were only using it for a few messages
2017-08-27 13:02:17 +03:00
tophf
243da0b0d1 fix opening own pages from an incognito window popup in Chrome 2017-08-26 15:57:33 +03:00
tophf
8976bd58b8 inform when dysfunctional due to FF options 2017-08-26 15:34:27 +03:00
tophf
8525ea9017 unbind properly in msgbox; hide Esc/Enter from other handlers 2017-08-26 08:32:54 +03:00
tophf
0d038c59bc make getDomains foolproof
fixes #172
2017-08-26 07:57:52 +03:00
tophf
7e5396a11d prevent browser exception bug on sendResponse to a closed tab
fixes #171
2017-08-26 07:51:28 +03:00
tophf
38c7ed1bc1 prevent text selection upon click outside of messageBox 2017-08-25 20:50:15 +03:00
tophf
d932d37cff remove unused CodeMirror test files 2017-08-25 20:04:39 +03:00
tophf
fb7f7d5471 URL-mode in manager's search and popup's manage button
* in manager use search query like url:https://github.com/openstyles/stylus
* in popup shift-click or right-click on manager button opens it and applies the filter
2017-08-23 12:16:32 +03:00
tophf
6ce8ce0425 0189fc0d followup: wait for lazyload blindly only in FF 2017-08-23 09:46:36 +03:00
tophf
9a55e64bbb autosize filter select element 2017-08-22 17:24:44 +03:00
tophf
64ba125601 manage: add inverted filters (disabled, external) 2017-08-22 17:24:44 +03:00
tophf
1ecaebc51a manage: use actual prefs while loading page 2017-08-22 17:24:44 +03:00
tophf
b011d206cf make disableAll mode more reliable in popup
fixes #159
2017-08-20 17:05:59 +03:00
tophf
92ab165192 don't restore size of editor window if it has many tabs
previously it happened occasionally on browser startup resulting in unwanted resizing of the main browser window
2017-08-18 17:09:02 +03:00
tophf
21b2ba572b tHTML: handle mixed text/element nodes in top level 2017-08-18 17:00:06 +03:00
tophf
6625cd4349 use optionsOpenManager message in popup's "manage" button tooltip 2017-08-18 14:48:35 +03:00
tophf
0189fc0d6b popup should wait for tab-on-demand to start loading
fixes a rare case of the popup being invoked right after switching to a lazily restored tab-on-demand, which doesn't have an URL yet in FF or has an URL but not the content script in some Chrome forks that implement tab-on-demand
2017-08-18 14:48:11 +03:00
tophf
fef748d128 wait for bg to load before enabling filters 2017-08-18 14:32:20 +03:00
tophf
815f8ca959 also find styles for URLs with stripped #hash
kinda fixes #155

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 we still respect url("foo#hash") set in userstyles
because the spec is outdated and doesn't account for SPA sites

collateral damage: simplified URLS.supported()
2017-08-18 13:18:19 +03:00
tophf
d24b62461c don't detect sloppy regexps in styles without regexps 2017-08-18 12:56:03 +03:00
tophf
aded4f7c01 display full text in tooltips of ellipsized buttons 2017-08-18 10:25:35 +03:00
narcolepticinsomniac
39e1421d29 'Check all styles for updates' button ellipsis
#156
2017-08-18 01:30:55 -04:00
tophf
1ca68b8488 fixup ede1187b: settings may be missing 2017-08-16 21:44:59 +03:00
tophf
a077de3624 fixup! 2017-08-16 14:06:06 +03:00
tophf
93fdd787d4 apply: ensure style elements follow <body> 2017-08-16 14:00:59 +03:00
tophf
f80f5612d6 code cosmetics: split manage.js 2017-08-16 08:18:23 +03:00
tophf
f001bca849 manage: show stats for filtered/total styles 2017-08-16 08:18:22 +03:00
tophf
a3d0a1e340 popup: simplify breadcrumbs; fix 1st word underline in FF 2017-08-14 21:15:29 +03:00
tophf
ede1187b31 popupWidth setting isn't a special sync case anymore 2017-08-13 17:33:57 +03:00
tophf
d49e44ddc1 csslint: CSS variables
* kinda fixes #149
* primitive recognition only
  (it's not like we expect csslint to be smart anyway)
2017-08-13 13:38:11 +03:00
tophf
d2b81be9d1 editor: CM scroller height fix for resize-grip (fixup b45f51f1)
fixes #142
2017-08-09 16:56:39 +03:00
Jeremy Schomery
a37281afb7 version 1.1.3.1 2017-08-09 13:57:15 +04:30
Jeremy Schomery
493d9cd764 pull locales from transifex 2017-08-09 13:19:16 +04:30
Jeremy Schomery
1b5db4872d version 1.1.3 2017-08-09 11:53:09 +04:30
tophf
aac39da053 avoid leaking of "dead objects"; fixes #141 2017-08-08 19:33:43 +03:00
narcolepticinsomniac
42d0bcd673 Eliminate popup button ellipsis and fix margins
Fixes #140
2017-08-07 18:25:01 -04:00
narcolepticinsomniac
ede3725268 Popup adjustments for common zoom levels
Fixes #133
2017-08-07 17:15:19 -04:00
tophf
975411d567 Merge pull request #135 from Mottie/template
Correct wording in issue template
2017-08-07 06:31:15 +03:00
Rob Garrison
427798e4bf Correct wording in issue template 2017-08-06 21:03:47 -05:00
tophf
30c19cf64e fixup 860443b9: BG can point to itself 2017-08-04 12:42:34 +03:00
tophf
af41d646dd Don't show editor.contextDelete option in FF; #128 2017-07-31 19:39:44 +03:00
tophf
78d7697845 Explicitly mention compatibility with Firefox 2017-07-31 16:43:24 +03:00
tophf
860443b909 ensure getBackgroundPage is fully loaded 2017-07-29 08:17:49 +03:00
tophf
3ddf812635 Don't count styles on NTP in Chrome 61+, see #122 2017-07-28 08:19:07 +03:00
Jeremy Schomery
f57240d3c1 version 1.1.2 2017-07-25 09:47:30 +04:30
tophf
acd9fc931d Bulgarian stylusUnavailableForURLdetails as per #121 2017-07-23 21:57:19 +03:00
tophf
0d2d21b54d editor->manage: always highlight the just edited style 2017-07-23 18:33:55 +03:00
tophf
3b49d83616 In Chrome 61.0.3161+ NTP can't be styled anymore 2017-07-23 12:42:34 +03:00
tophf
b37b2c5246 fixup e463ca7e: use the actual tab index 2017-07-22 16:57:52 +03:00
tophf
93ff6d0f85 Merge pull request #119 from openstyles/innerHTML
dealing with innerHTML
2017-07-22 16:49:52 +03:00
tophf
406a7ba7f1 Merge pull request #121 from AdmiralAnimE/master
Bulgarian translation
2017-07-22 16:40:49 +03:00
AdmiralAnimE
96f7d06609 Bulgarian translation 2017-07-22 15:51:11 +03:00
tophf
e463ca7ece setBadgeText: skip pre-rendered tabs 2017-07-22 12:56:38 +03:00
Jeremy Schomery
3c298995f1 a few fixes 2017-07-22 12:56:37 +03:00
Jeremy Schomery
3ccdb555da no insertAdjacentHTML usage on CM theme switching 2017-07-22 12:56:37 +03:00
Jeremy Schomery
9870a8041c no innerHTML on messageBox() 2017-07-22 12:56:37 +03:00
Jeremy Schomery
53683dcbbd empty contents of showHelp() before appending childs; based on https://github.com/openstyles/stylus/pull/119#issuecomment-316372767 2017-07-22 12:56:37 +03:00
Jeremy Schomery
7affeedd3b removing tE() 2017-07-22 12:56:37 +03:00
Jeremy Schomery
332f95e1ff i18n-html to i18n-text if possible. tNodeList now parses HTML content using tHTML 2017-07-22 12:56:37 +03:00
Jeremy Schomery
0955fc852c removing a few more innerHTMLs 2017-07-22 12:56:28 +03:00
tophf
12d67fda6c fixup 312424ff: process multiple top-level elements in tHTML 2017-07-22 12:56:28 +03:00
Jeremy Schomery
61971b97c8 tHTML uses parseFromString instead of innerHTML. showHelp now uses tHTML 2017-07-22 12:56:28 +03:00
Jeremy Schomery
5d46dcc33e customizeOpenDialog, openDialog, and originalOpenConfirm now use cloned template instead of innerHTML 2017-07-22 12:54:32 +03:00
Jeremy Schomery
0e9c8f290c optionsHtmlFromArray to optionsFromArray 2017-07-22 12:54:32 +03:00
Jeremy Schomery
f5c125d61c no more innerHTML in popup.js 2017-07-22 12:54:32 +03:00
Jeremy Schomery
7c8dbfc3a4 empty elements with textContent 2017-07-22 12:54:32 +03:00
tophf
eeb826ee97 showRegExpTester: don't blink favicons on typing 2017-07-22 12:54:32 +03:00
tophf
c963a13932 code cosmetics
Reorganize showRegExpTester()'s render stats code to better reflect the displayed structure/order of data
2017-07-22 12:54:32 +03:00
tophf
23c870ceb9 fixup b50c19a8: "errors" is now an array 2017-07-22 12:54:32 +03:00
tophf
b50c19a802 editor import: warn about invalid -moz-document functions
* fixes #118
* alleviates #116 by switching showRegExpTester() from innerHTML to DOM
2017-07-19 15:09:29 +03:00
tophf
e48e1ab874 Merge pull request #110 from Mottie/cleanup
Coding Style Cleanup
2017-07-19 10:58:17 +03:00
Rob Garrison
a46684f892 Style options cursor 2017-07-16 15:04:40 -05:00
Rob Garrison
8cfb37351d Remove unused variables 2017-07-16 14:40:13 -05:00
Rob Garrison
417e3b5de3 Add eqeqeq definition to eslint 2017-07-16 13:07:21 -05:00
Rob Garrison
24dd0cb562 More cleanup 2017-07-16 13:07:21 -05:00
Rob Garrison
1940318f0f Fix eslint issues & use arrow functions 2017-07-16 13:07:15 -05:00
Rob Garrison
a1bec922ef Update eslint rules 2017-07-16 08:55:16 -05:00
Rob Garrison
11d8687af7 Wrap case statement to fix eslint issue 2017-07-14 04:42:55 -05:00
Rob Garrison
81484bbc37 Fix for-loop index declarations 2017-07-14 04:23:47 -05:00
Rob Garrison
01e63d5b1a Remove escaped single quote 2017-07-14 04:23:46 -05:00
Rob Garrison
a3e149a30e Fix & rename scoped state variable 2017-07-14 04:22:56 -05:00
Rob Garrison
1a630033bd Use a single declaration per line 2017-07-14 04:10:00 -05:00
Rob Garrison
61327bfaf1 Restore case declarations in edit.js 2017-07-14 03:33:59 -05:00
Rob Garrison
4cbd48b9f9 Rename options.html & fix path 2017-07-14 03:25:33 -05:00
Rob Garrison
370a0a2c35 Remove duplicated code in fileSaveLoad.js 2017-07-14 03:21:07 -05:00
Rob Garrison
ac91e25eb4 Move messaging.js file & references 2017-07-13 19:52:40 -05:00
Rob Garrison
f49747e1bd Adjust pull_locales paths 2017-07-13 19:50:24 -05:00
Rob Garrison
c97151edf3 Add contributing & issue template files 2017-07-12 16:26:21 -05:00
Rob Garrison
0037c699d9 Fix eslint issues 2017-07-12 16:26:21 -05:00
Rob Garrison
508f71f26b Change tabs to spaces in edit.js 2017-07-12 16:26:20 -05:00
Rob Garrison
bb33ff3981 Fix links & split out edit.css 2017-07-12 16:26:20 -05:00
Rob Garrison
57ff0b6cb7 Update eslint rule 2017-07-12 16:26:20 -05:00
Rob Garrison
7a9d629ec8 Restructure folders 2017-07-12 16:26:20 -05:00
narcolepticinsomniac
ed83f8f77e Switch date format for backups
Fixes #114
2017-07-12 09:22:49 -04:00
tophf
36b6485cd0 deduplicate and placeholderize locales 2017-07-12 12:12:47 +03:00
tophf
bf94aa93cf pull_locales_postprocess: deduplicate and placeholderize 2017-07-12 12:12:47 +03:00
Jeremy Schomery
50a2b5dd72 Updating locales from transifex 2017-07-12 11:46:13 +04:30
tophf
38605f3ede fixup d2dd4ae1: strip trailing commas in "de" locale 2017-07-12 08:52:40 +03:00
tophf
b31dec86ba reset L10N cache if our page is loaded before bg 2017-07-11 18:03:35 +03:00
tophf
d2dd4ae178 remove non-translated messages from all locales 2017-07-11 17:47:57 +03:00
tophf
91942814f0 replace " - " with ": " in updateCheckFailServerUnreachable 2017-07-11 07:44:26 +03:00
tophf
af797b894e replace " - " with ": " in updateCheckFailBadResponseCode 2017-07-10 17:29:58 +03:00
tophf
6502cb51b3 remove "." from findStylesForSite message 2017-07-10 17:16:45 +03:00
tophf
6995752fc1 Don't submit any parameters to homepage on install 2017-07-09 22:29:54 +03:00
tophf
7bf958c5aa fixup! 2017-07-09 13:13:47 +03:00
tophf
3daeab63cd Don't submit manifest.version on install since it's unused 2017-07-09 13:10:10 +03:00
tophf
5c1555c781 code cosmetics: fix some eslint complaints
Until https://github.com/eslint/eslint/issues/8594 is sorted out, we're switching to the old indent behavior (indent-legacy).
2017-07-09 12:22:45 +03:00
tophf
877d8b19e0 set default icon (shown before webNavigation API kicks in) 2017-07-09 12:22:45 +03:00
tophf
ece3822891 option to switch toolbar icon sets 2017-07-09 12:22:44 +03:00
tophf
c3218680f1 optionsUI: vertically align options 2017-07-01 13:39:33 +03:00
tophf
b45f51f136 editor: CM scroller height fix for resize-grip 2017-07-01 13:37:35 +03:00
tophf
d02ca476a7 spellcheck="false" in text input fields 2 2017-06-29 16:51:18 +03:00
tophf
67c6bd16ba spellcheck="false" in text input fields 2017-06-29 16:47:13 +03:00
tophf
160dd95b4c CodeMirror 5.27.4 2017-06-29 16:39:01 +03:00
narcolepticinsomniac
b4f2dffca0 Correct hovers for CodeMirror auto-suggestions 2017-06-28 06:25:26 -04:00
tophf
565f23fa6e editor: add double-click to resize grip 2017-06-28 12:41:34 +03:00
tophf
9ffc525391 editor: horizontal resize grip 2017-06-28 12:40:19 +03:00
tophf
9299972a34 editor: highlight style entry upon "back to manage" 2017-06-27 23:16:03 +03:00
tophf
dc846aa7dd code cosmetics: animateElement() 'highlight' by default 2017-06-27 23:15:33 +03:00
tophf
1aa5c11b10 code cosmetics: entry id prefix => named constant 2017-06-27 23:15:32 +03:00
tophf
65d625fddf code cosmetics: missed a debounce() case 2017-06-27 15:17:52 +03:00
tophf
358e8e034f code cosmetics: add invokeOrPostpone() 2017-06-27 15:15:49 +03:00
tophf
1c1a9f2804 fixup e199e1b3 for non-e10s FF: moar timeouts! 2017-06-27 12:55:47 +03:00
tophf
9163a856f6 lazify and fix refreshAllTabs 2017-06-27 12:39:51 +03:00
tophf
e199e1b3c7 FF-e10s bug workaround: do export via iframe 2017-06-27 12:14:22 +03:00
tophf
e3e1ecf2d3 don't precompile regexps in storage.js (no gain) 2017-06-25 13:39:22 +03:00
tophf
93a4f4704f code cosmetics 2017-06-25 13:13:07 +03:00
tophf
c0fe8dbf43 Move styles after <head> once it appears; fixes #103 2017-06-22 12:16:39 +03:00
tophf
028ac1d299 editor: convert string to int; fixes #102 2017-06-21 22:05:21 +03:00
tophf
5485fbf8b3 optionsUI: more flexboxes and relative widths
* also center the UI vertically in Opera
* allow body width to grow up to 800px in FF/Opera/etc
* use :: in pseudo selectors
2017-06-19 16:00:45 +03:00
tophf
2240a0895e editor: autocomplete on typing 2017-06-18 17:04:14 +03:00
tophf
7443a4cb89 ensure BG is initialized in onBackgroundReady() 2017-06-18 17:04:13 +03:00
tophf
f603d9b61f simplify html for editor options: reuse the id 2017-06-18 15:47:15 +03:00
tophf
8e4b2fbbb0 manage: hardcode edit link; fixes #29 broken in 7084dd12 2017-06-18 15:47:15 +03:00
tophf
3128c7f063 editor: keep 's-resize' cursor over code box 2017-06-18 12:28:39 +03:00
tophf
c4f871b4ed editor: use MouseEvent.pageY in resizeGrip 2017-06-18 12:27:00 +03:00
tophf
050109428c USO bug workaround: generalize getStyleURL() 2017-06-17 14:55:34 +03:00
tophf
fba85b36cc promisify chrome.tabs.query as queryTabs() 2017-06-17 13:00:10 +03:00
tophf
b4e00cd892 Lazify notifyAllTabs() and injectCS()
* notifyAllTabs: the active tab gets notified immediately, the rest lazily
* notifyAllTabs + injectCS: don't notify lazy-loaded tabs in FF
2017-06-17 09:33:32 +03:00
Jeremy Schomery
c5a340e44e version 1.1.0 2017-06-14 09:30:19 +04:30
tophf
90275ae47a Help buggy USO support Linux Chromium 2017-06-14 00:20:35 +03:00
tophf
218c6adfa0 patch buggy USO site pagination links in category mode 2017-06-11 15:01:48 +03:00
tophf
22a2086535 FF: suppress pingCS() errors in browser console 2017-06-10 21:33:37 +03:00
tophf
2687d1e167 FF bug workaround: retranslate CSS content 2017-06-10 14:08:03 +03:00
tophf
2e86c95842 csslint: fire startdocument on { 2017-06-10 12:43:26 +03:00
Jeremy Schomery
0817a03b61 renaming the repository name from stylish-chrome to stylus 2017-06-10 11:29:17 +04:30
tophf
972968b109 FF popup has 2 buttons so each should be 50% 2017-06-09 01:46:25 +03:00
tophf
d36489216c Don't save maximized editor window size&pos
This fixes the bug with reloading the editor tab in a maximized state: previously the window was losing its state.

Assuming a detached editor window normally is expected to have a smaller size and custom position, the user may occasionally maximize it for convenience, in which case we don't save its size and position.

Even if this assumption is wrong, it's easy to manually resize the window to fill the entire screen so that the size/position are remembered.
2017-06-06 16:44:16 +03:00
tophf
4559162d45 Alt-Enter in the editor to toggle&save the style 2017-06-06 10:56:49 +03:00
tophf
6df2392132 FF bug workaround for tabs.query with moz-extension:// 2017-06-06 10:33:45 +03:00
tophf
ac5e9b965a saveStyle's codeIsUpdated can be true or false, not undefined 2017-06-06 04:40:08 +03:00
Jeremy Schomery
19754a5a90 updating es locale 2017-06-05 15:45:07 +04:30
tophf
7a4f499e0d patch buggy USO site to use actual style settings 2017-06-05 09:37:00 +03:00
tophf
cd84a33a53 fixup: "Install style" should not persist on click 2017-06-05 09:36:51 +03:00
tophf
5a67d926da manage: fix toggling a style when filtering by search
Previously a style entry would disappear when toggled on manage page with search filter applied because filterContainer() altered the original "container" parameter.
2017-06-04 12:22:51 +03:00
tophf
2b1d874236 Update style settings on USO without page reload 2017-06-04 10:39:27 +03:00
tophf
be9cfe072d openURL should not redirect incognito NTP to chrome URLs 2017-06-03 16:57:52 +03:00
tophf
cec649e0ee openURL should not open own pages in incognito tabs
We're using the default "spanning mode" which doesn't support it
2017-06-03 16:52:58 +03:00
Jeremy Schomery
14e8dedded version 1.0.9 2017-05-30 16:21:41 +04:30
tophf
1098f2666c beautifier: reworded "Undo in all sections" label 2017-05-27 11:42:54 +03:00
tophf
8bbab9e0e1 beautify: don't add extra \n after comments 2017-05-27 11:42:54 +03:00
tophf
ddc5cc0ccf beautify: option for indenting conditional blocks 2017-05-27 11:42:54 +03:00
tophf
26f84c5852 play safe in *Safe() as BG gets defined only in .then 2017-05-23 22:31:40 +03:00
tophf
0440073853 restore style code in popup::onMessage 2017-05-23 22:28:45 +03:00
narcolepticinsomniac
8e6006e705 Transparent corners for small icons
#7
2017-05-19 17:01:54 -04:00
narcolepticinsomniac
70695df64e fixup indent? 2017-05-19 04:48:43 -04:00
narcolepticinsomniac
0744c9e658 Fixup indent 2017-05-19 04:44:43 -04:00
narcolepticinsomniac
8697b3b9a6 Fixup indent (looks correct in editor not in diff) 2017-05-19 04:41:11 -04:00
narcolepticinsomniac
85fe8e876e Remove translation for changed popup message 2017-05-19 04:32:42 -04:00
narcolepticinsomniac
3d12f3e174 Remove translation for changed popup message 2017-05-19 04:29:18 -04:00
narcolepticinsomniac
c7bc86c491 Remove translation for changed popup message 2017-05-19 04:27:48 -04:00
narcolepticinsomniac
fcfec7275f Remove translation for changed popup message 2017-05-19 04:26:07 -04:00
narcolepticinsomniac
ef5c16829f Popup message update for restricted access 2017-05-19 04:20:11 -04:00
Jeremy Schomery
daaac972fe fixes https://github.com/schomery/stylish-chrome/issues/52#issuecomment-302394702 2017-05-19 11:53:04 +04:30
narcolepticinsomniac
bd817cd4be Minor adjustment for info icons 2017-05-18 08:05:13 -04:00
narcolepticinsomniac
f60dad66f3 Touched-up and smaller file size icons
#7
2017-05-18 07:29:10 -04:00
narcolepticinsomniac
67b17335f9 Reword WebStore description
Really just wanted to switch "Restyle" with "Redesign" for continuity. Translations are probably close enough to leave as they are, unless anyone thinks otherwise.
2017-05-18 07:08:14 -04:00
Jeremy Schomery
c6293a8e88 appending "advanced settings" parameters to the Chrome's download URL for Firefox, Opera, or Vivaldi browsers 2017-05-18 14:09:03 +04:30
tophf
dacca58d26 beautify: indent "{" after newline like its parent block 2017-05-18 01:55:24 +03:00
tophf
b2ab3d45ad fixup bc63ecca: unget only if matched 2017-05-17 16:04:33 +03:00
tophf
af7a402bd3 csslint warning update 2017-05-17 06:21:05 +03:00
tophf
ebd6b54e45 Enable linting in newly created styles 2017-05-17 06:15:43 +03:00
tophf
bc63eccaa9 csslint: support "i" in attribute selector 2017-05-17 06:10:51 +03:00
tophf
4250f89ed3 Add favicons only in Firefox 2017-05-17 01:09:31 +03:00
Jeremy Schomery
9228a22c6c Updating README.md with AMO link 2017-05-15 18:25:49 +04:30
Jeremy Schomery
8989a53517 version 1.0.8 2017-05-15 18:14:59 +04:30
narcolepticinsomniac
f53cd9fe29 Touched-up icons 2017-05-15 09:13:46 -04:00
tophf
3b9ec2508f Use 16px favicon by default if "sizes" attr isn't respected 2017-05-15 15:50:31 +03:00
Jeremy Schomery
c5081a0747 Fixes communication issue with US.o on Vivaldi browser 2017-05-15 17:16:09 +04:30
tophf
1706f380f2 Show favicons on own pages in FF/Opera 2017-05-15 15:41:15 +03:00
Jeremy Schomery
6119a406da Fixes communication issue with US.o on Firefox browser 2017-05-15 16:32:59 +04:30
tophf
449f86e5ef rework 4df35b82: clear the different style's id 2017-05-15 13:42:20 +03:00
tophf
4df35b829b import: don't blindly overwrite styles with same id 2017-05-15 12:40:35 +03:00
Jeremy Schomery
ab63f028eb a few Firefox related compatibility fixes 2017-05-14 15:56:51 +04:30
Jeremy Schomery
497756d838 version 1.0.7 2017-05-06 15:40:07 +04:30
Jeremy Schomery
a625323572 updating locales from transifex.com 2017-05-06 15:30:11 +04:30
tophf
54a875fab3 Map() keys must be of the same type 2017-05-05 18:04:17 +03:00
tophf
6f478cbc57 invalidate CSSOM cache in DocRewriteObserver 2017-05-05 18:02:40 +03:00
tophf
d3d3a1f9b5 only global sections are skipped if empty/comment/namespace 2017-05-05 17:21:17 +03:00
tophf
71f4a53b41 fixup! 2017-05-03 19:06:14 +03:00
tophf
5f0b57bebf embed digest in DB as style.originalDigest 2017-05-03 18:58:09 +03:00
365 changed files with 100567 additions and 43610 deletions

View File

@ -1,3 +1,2 @@
beautify/
codemirror/
csslint/
vendor/
vendor-overwrites/

View File

@ -1,7 +1,7 @@
# https://github.com/eslint/eslint/blob/master/docs/rules/README.md
parserOptions:
ecmaVersion: 2015
ecmaVersion: 2017
env:
browser: true
@ -9,51 +9,7 @@ env:
webextensions: true
globals:
# messaging.js
KEEP_CHANNEL_OPEN: false
FIREFOX: false
OPERA: false
URLS: false
BG: false
notifyAllTabs: false
getTab: false
getActiveTab: false
getActiveTabRealURL: false
getTabRealURL: false
openURL: false
activateTab: false
stringAsRegExp: false
ignoreChromeError: false
tryCatch: false
tryRegExp: false
tryJSONparse: false
debounce: false
deepCopy: false
onBackgroundReady: false
deleteStyleSafe: false
getStylesSafe: false
saveStyleSafe: false
sessionStorageHash: false
download: false
# localization.js
template: false
t: false
o: false
tE: false
tHTML: false
tNodeList: false
tDocLoader: false
# dom.js
onDOMready: false
scrollElementIntoView: false
enforceInputRange: false
animateElement: false
$: false
$$: false
$element: false
# prefs.js
prefs: false
setupLivePrefs: false
require: readonly # in polyfill.js
rules:
accessor-pairs: [2]
@ -66,19 +22,19 @@ rules:
brace-style: [2, 1tbs, {allowSingleLine: false}]
camelcase: [2, {properties: never}]
class-methods-use-this: [2]
comma-dangle: [0]
comma-dangle: [2, {arrays: always-multiline, objects: always-multiline}]
comma-spacing: [2, {before: false, after: true}]
comma-style: [2, last]
complexity: [0]
computed-property-spacing: [2, never]
consistent-return: [0]
constructor-super: [2]
curly: [2]
curly: [2, "multi-line"]
default-case: [0]
dot-location: [2, property]
dot-notation: [0]
eol-last: [2]
eqeqeq: [0]
eqeqeq: [1, smart]
func-call-spacing: [2, never]
func-name-matching: [0]
func-names: [0]
@ -89,7 +45,15 @@ rules:
id-blacklist: [0]
id-length: [0]
id-match: [0]
indent: [2, 2, {VariableDeclarator: 0, SwitchCase: 1}]
indent: [2, 2, {
SwitchCase: 1,
ignoreComments: true,
ignoredNodes: [
"TemplateLiteral > *",
"ConditionalExpression",
"ForStatement"
]
}]
jsx-quotes: [0]
key-spacing: [0]
keyword-spacing: [2]
@ -113,11 +77,11 @@ rules:
no-case-declarations: [2]
no-class-assign: [2]
no-cond-assign: [2, except-parens]
no-confusing-arrow: [1, {allowParens: true}]
no-confusing-arrow: [0, {allowParens: true}]
no-const-assign: [2]
no-constant-condition: [0]
no-continue: [0]
no-control-regex: [2]
no-control-regex: [0]
no-debugger: [2]
no-delete-var: [2]
no-div-regex: [0]
@ -131,9 +95,9 @@ rules:
no-empty-function: [0]
no-empty-pattern: [2]
no-empty: [2, {allowEmptyCatch: true}]
no-eq-null: [2]
no-eq-null: [0]
no-eval: [2]
no-ex-assign: [2]
no-ex-assign: [0]
no-extend-native: [2]
no-extra-bind: [2]
no-extra-boolean-cast: [2]
@ -162,7 +126,7 @@ rules:
no-mixed-operators: [0]
no-mixed-requires: [2, true]
no-mixed-spaces-and-tabs: [2]
no-multi-spaces: [0]
no-multi-spaces: [2, {ignoreEOLComments: true}]
no-multi-str: [2]
no-multiple-empty-lines: [2, {max: 2, maxEOF: 0, maxBOF: 0}]
no-native-reassign: [2]
@ -183,6 +147,9 @@ rules:
no-proto: [2]
no-redeclare: [2]
no-regex-spaces: [2]
no-restricted-globals: [2, name, event]
# `name` and `event` (in Chrome) are built-in globals
# but we don't use these globals so it's most likely a mistake/typo
no-restricted-imports: [0]
no-restricted-modules: [2, domain, freelist, smalloc, sys]
no-restricted-syntax: [2, WithStatement]
@ -203,17 +170,16 @@ rules:
no-trailing-spaces: [2]
no-undef-init: [2]
no-undef: [2]
no-undefined: [0]
no-underscore-dangle: [0]
no-unexpected-multiline: [2]
no-unmodified-loop-condition: [1]
no-unmodified-loop-condition: [0]
no-unneeded-ternary: [2]
no-unreachable: [2]
no-unsafe-finally: [2]
no-unsafe-negation: [2]
no-unused-expressions: [2]
no-unused-labels: [0]
no-unused-vars: [1, {args: after-used, vars: local, argsIgnorePattern: ^_}]
no-unused-vars: [2, {args: after-used}]
no-use-before-define: [2, nofunc]
no-useless-call: [2]
no-useless-computed-key: [2]
@ -228,16 +194,16 @@ rules:
object-curly-spacing: [2, never]
object-shorthand: [0]
one-var-declaration-per-line: [1]
one-var: [0]
one-var: [2, {initialized: never}]
operator-assignment: [2, always]
operator-linebreak: [2, after, overrides: {"?": ignore, ":": ignore, "&&": ignore, "||": ignore}]
padded-blocks: [2, never]
padded-blocks: [0]
prefer-numeric-literals: [2]
prefer-rest-params: [0]
prefer-const: [1, {destructuring: any, ignoreReadBeforeAssign: true}]
prefer-const: [1, {destructuring: all, ignoreReadBeforeAssign: true}]
quote-props: [0]
quotes: [1, single, avoid-escape]
radix: [2, as-needed]
radix: [2, always]
require-jsdoc: [0]
require-yield: [2]
semi-spacing: [2, {before: false, after: true}]
@ -245,7 +211,7 @@ rules:
sort-imports: [0]
sort-keys: [0]
space-before-blocks: [2, always]
space-before-function-paren: [2, never]
space-before-function-paren: [2, {anonymous: always, asyncArrow: always, named: never}]
space-in-parens: [2, never]
space-infix-ops: [2]
space-unary-ops: [2]
@ -259,3 +225,16 @@ rules:
wrap-iife: [2, inside]
yield-star-spacing: [2, {before: true, after: false}]
yoda: [2, never]
overrides:
- files: [tools/*]
env:
node: true
browser: false
webextensions: false
parserOptions:
ecmaVersion: 2017
- files: ["**/*worker*.js"]
env:
worker: true

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

46
.github/CONTRIBUTING.md vendored Normal file
View File

@ -0,0 +1,46 @@
# Contributing to Stylus
1. [Getting involved](#getting-involved)
2. [How to report issues](#how-to-report-issues)
3. [Adding translations](#adding-translations)
4. [Pull requests](#pull-requests)
5. [Scripts](#scripts)
6. [Updating locale files](#updating-locale-files-admin-only)
7. [Contact us](#contact-us)
## Getting involved
There are a number of ways to get involved with the development of Stylus. Even if you've never contributed to an Open Source project before, we're always looking for help by identifying issues and suggesting improvements.
## How to report issues
When an [**issue**](https://github.com/openstyles/stylus/issues) is opened, a template is provided. Please answer these questions as thoroughly as possible. If we were psychic, we'd be hanging out in casinos playing poker until they kicked us out. We can't read your mind! Please provide step-by-step directions on how to reproduce the issue as well as the versions of your operating system, browser and Stylus.
When adding a **feature request**, please search through the existing issues to see if it the feature has already been requested, added or rejected.
If not, then provide details describing which page the feature will effect, e.g. popup, manager or editor. Then describe the request and explain how you think it would benefit the user experience.
## 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
* First open an issue to discuss your changes.
* Then download, fork or clone this repository.
<!-- * Use [node.js](https://nodejs.org/) to run `npm install`. -->
* Use the provided `.editorconfig` file with your code editor. Don't know what that is? Then check out https://editorconfig.org/.
* Make any changes within a branch of this repository (not the `master` branch).
* Submit a pull request and include a reference to the initial issue with the discussion.
## Build scripts
See [BUILD.md](../BUILD.md) for more information.
## Contact us
If you prefer a more informal method of getting in touch or starting a conversation, please [join us on Discord](https://discordapp.com/widget?id=379521691774353408) or leave a comment in the [discussion section](https://add0n.com/stylus.html#reviews). We will monitor any discussions there and join in, and it may be a more appropriate venue for opinions and less urgent suggestions.

48
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,48 @@
---
name: Bug Report
about: Create a report about a bug you experienced while using Stylus.
title: "[Bug] Replace with title"
assignees: ''
---
<!--
⚠⚠ Do not delete this issue template! ⚠⚠
Reported issues must use this template and have all the necessary information provided.
Incomplete reports are likely to be ignored and closed.
-->
<!--
Thank you for taking the time to create a report about a bug.
Ensure that there are no other existing reports for this bug.
Please check if the issue is resolved after a restart of the browser.
Additionally, you should check if the issue persists in a new browser profile.
Remember to fill out every section on this report and remove any that are not needed.
Finally, place a brief description in the title of this report.
-->
# Bug Report
### Bug Description
<!-- Provide a clear and concise description, which will allow us to properly troubleshoot this bug. -->
### Screenshots
<!-- If applicable, add screenshots to help explain this bug. -->
### CSS Code
<!--
If the bug is related to (user)CSS or the editor,
please post the code (with a service like pastebin) in this bug report.
-->
### System Information
<!--
Specify the browser name and version as well as the Stylus version you are using.
Please do an online search for help if you are not familiar with how to get this information.
-->
- OS: <!-- e.g. Windows, macOS, Linux -->
- Browser: <!-- e.g. Chrome 91, Firefox 90, Edge 91, Safari 14 -->
- Stylus Version: <!-- e.g. 1.5.21 -->
### Additional Context
<!-- Provide any additional information about this bug. -->

14
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,14 @@
name: ci
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '14'
- run: npm install
- run: npm test

8
.gitignore vendored
View File

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

10
.tx/config Normal file
View File

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

70
BUILD.md Normal file
View File

@ -0,0 +1,70 @@
# Build this project
## Preparation
1. Install [Node.js](https://nodejs.org/en/).
2. Go to the project root, run `npm install`. This will install all required dependencies.
Extra preparations are needed if you want to pull locale files from Transifex:
1. Install Transifex client. Follow the instructions on [this page](https://docs.transifex.com/client/installing-the-client).
2. You need a `.transifexrc` file in the root folder. Contact another admin if you need one. It includes the API key to use Transifex's API.
## Generate the ZIP release
Use the following command to generate a ZIP file that can be submitted to AMO or CWS:
```
npm run zip
```
The zip file includes all the files from the repository **except**:
* All dot files (e.g. `.eslintrc` & `.gitignore`).
* `node_modules` folder.
* `tools` folder.
* `package.json` file.
* `package-lock.json` and/or `yarn.lock` file(s).
<!-- FIXME: is this statement still true?
* `vendor/codemirror/lib` files. This path is excluded because it contains a file modified for development purposes only. Instead, the CodeMirror files are copied directly from `node_modules/codemirror/lib`.
-->
## Tag a release/Bump the version
Use the `npm version (major | minor | patch)` command to tag a release.
There are some scripts that will run automatically before/after tagging a version. Includes:
1. Test.
2. Update version number in `manifest.json`.
3. Generate the ZIP file.
4. Push the tag to github.
## Translation
We host locale files (`message.json`) on Transifex. All the files exist in our GitHub repository, but if you need to update the locale files, you will need to install the [Transifex client](https://docs.transifex.com/client/installing-the-client)
To pull files from Transifex, run
```
npm run update-locales
```
To push files to Transifex:
```
npm run update-transifex
```
## 3rd-party libraries
3rd-party libraries are managed by `npm`. Since Stylus is built with vanilla JS, we only use libraries that can run in the browser.
We keep a copy of these libraries inside the `vendor` directory so users can side-load this repository without executing the build script. These files are downloaded from CDN or pulled from npm (`node_modules`).
To add/update a library to the latest version, run `npm install PACKAGE_NAME@latest`.
To remove a library, run `npm uninstall PACKAGE_NAME`.
After the (un)installation, specify files which should be copied in `tools/build-vendor.js` and run `npm run build-vendor` to rebuild the vendor folder.

View File

View File

@ -1,31 +1,58 @@
Stylus : Stylish fork for Chrome and Chrome-like things
# Stylus
Stylus is a fork of Stylish for Chrome, also compatible with Firefox as a WebExtension
## Highlights
* In addition to the userstyles.org site, styles with customizable parameters can also be installed from .user.css or .user.styl URLs (see [Usercss format wiki](https://github.com/openstyles/stylus/wiki/Usercss)).
* Site styles can be discovered and previewed in the popup using inline search with screenshot thumbnails.
* A backup feature which is compatible with other userstyles managers.
* Configurable automatic update function for installed styles.
* Customizable UI, optional layouts, and tweaks.
* Two different optional code validators with user-configurable rules: CSSLint and Stylelint.
* Both validators use Web Worker API to run in a separate background thread inside the editor tab without blocking your interaction with the code.
* CSSLint is heavily modified compared to the effectively frozen original one and supports various CSS3 features as well as CSS4 Color and CSS Grid syntax.
## Releases
1. [Chrome Web Store](https://chrome.google.com/webstore/detail/stylus/clngdbkpkpeebahjckkjfobafhncgmne)
2. [Opera add-ons](https://addons.opera.com/extensions/details/stylus/)
1. [Chrome Web Store](https://chrome.google.com/webstore/detail/stylus/clngdbkpkpeebahjckkjfobafhncgmne) (or [beta](https://chrome.google.com/webstore/detail/stylus-beta/apmmpaebfobifelkijhaljbmpcgbjbdo))
2. [Firefox add-ons](https://addons.mozilla.org/firefox/addon/styl-us/)
3. [Opera add-ons](https://addons.opera.com/extensions/details/stylus/) (see [wiki](https://github.com/openstyles/stylus/wiki/Opera,-Outdated-Stylus) for more recent version)
## Screen shot
## Screenshots
![screen shot](https://cloud.githubusercontent.com/assets/11704051/24002324/aefd19fe-0a75-11e7-8160-d8731d2a6d03.png)
Manager | Editor | Popup search | Popup config | Manager config | Options
-|-|-|-|-|-
![Style manager](https://user-images.githubusercontent.com/1310400/34453460-214eaa5c-ed67-11e7-843b-d8960b71db6e.png) | ![Style editor](https://user-images.githubusercontent.com/1310400/34459585-3932cd94-ee05-11e7-9a1b-679522dddfb3.png) | ![Popup inline search](https://user-images.githubusercontent.com/1310400/34453463-21a44368-ed67-11e7-93b2-e1c8f5aac868.png) | ![Popup config for usercss](https://user-images.githubusercontent.com/1310400/34453462-218a589a-ed67-11e7-9040-7d0469eeadc3.png) | ![Style manager config for usercss](https://user-images.githubusercontent.com/1310400/34453464-21bdaf9c-ed67-11e7-8517-62d2f02e1918.png) | ![Options](https://user-images.githubusercontent.com/1310400/34453461-216aee4c-ed67-11e7-92db-ea21c1da5826.png)
## Help
See the [help docs](http://userstyles.org/help/stylish_chrome) or [ask in userstyles.org forum](https://forum.userstyles.org). For Stylus specific questions and suggestions please use [review section](http://add0n.com/stylus.html#reviews) of the FAQs page.
* [Stylus help and FAQ in our Wiki](https://github.com/openstyles/stylus/wiki)
* [Discussion section](https://add0n.com/stylus.html#reviews) of our representation on add0n.com
* Discord: [![Discord][chat-image]][chat-link]
[chat-image]: https://img.shields.io/discord/379521691774353408.svg
[chat-link]: https://discordapp.com/widget?id=379521691774353408
## Contributing
The source is hosted on [GitHub](https://github.com/schomery/stylish-chrome) and pull requests are welcome.
The source is hosted on [GitHub](https://github.com/openstyles/stylus) and pull requests are welcome.
You can help us translate the extension on [Transifex](https://www.transifex.com/github-7/Stylus). When `messages.json` file is ready to be merged, please open a new bug report in [stylish-chrome/issues](https://github.com/schomery/stylish-chrome/issues).
You can help us translate the extension on [Transifex](https://www.transifex.com/github-7/Stylus).
See our [contributing](./.github/CONTRIBUTING.md) page for more details.
## License
For copyright status of the "codemirror" directory, see codemirror/LICENSE. Everything else is:
Inherited code from the original [Stylish](https://github.com/stylish-userstyles/stylish/):
Copyright (C) 2005-2014 Jason Barnabe <jason.barnabe@gmail.com>
Copyright &copy; 2005-2014 [Jason Barnabe](jason.barnabe@gmail.com)
Copyright (C) 2017 Stylus Team
Current Stylus:
Copyright &copy; 2017-2022 [Stylus Team](https://github.com/openstyles/stylus/graphs/contributors)
**[GNU GPLv3](./LICENSE)**
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -38,4 +65,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
along with this program. If not, see <https://www.gnu.org/licenses/>.
### External libraries
The licenses of [external libraries](./vendor) used in this project or [modified versions of external libraries](./vendor-overwrites) can be found in their respective directory.

View File

@ -1,417 +1,178 @@
{
"appliesToEverything": {
"message": "كل شيء",
"description": "Text displayed for styles that apply to all sites"
},
"defaultTheme": {
"message": "default",
"description": "Default CodeMirror CSS theme option on the edit style page"
},
"exportLabel": {
"message": "Export",
"description": "Label for the button to export a style ('edit' page) or all styles ('manage' page)"
},
"issues": {
"message": "Issues",
"description": "Label for the CSSLint issues block on the style edit page"
},
"cm_tabSize": {
"message": "Tab size",
"description": "Label for the text box controlling tab size option for the style editor."
},
"enableStyleLabel": {
"message": "تمكين",
"description": "Label for the button to enable a style"
},
"styleMissingName": {
"message": "أدخل اسمًا.",
"description": "Error displayed when user saves without providing a name"
},
"appliesDomainOption": {
"message": "عناوين URL في النطاق",
"description": "Option to make the style apply to the entered string as a domain"
},
"checkForUpdate": {
"message": "البحث عن تحديث",
"description": "Label for the button to check a single style for an update"
},
"importAppendLabel": {
"message": "Append to style",
"description": "Label for the button to import a style and append to the existing sections"
},
"updateAllCheckSucceededNoUpdate": {
"message": "All styles are up to date.",
"description": "Text that displays when an update all check completed and no updates are available"
},
"styleFromMozillaFormatPrompt": {
"message": "Paste the Mozilla-format code",
"description": "Prompt in the dialog displayed after clicking 'Import from Mozilla format' button"
},
"helpAlt": {
"message": "مساعدة",
"description": "Alternate text for help buttons"
},
"search": {
"message": "Search",
"description": "Label before the search input field in the editor shown on Ctrl-F"
},
"confirmYes": {
"message": "Yes",
"description": "'Yes' button in a confirm dialog"
},
"findStylesForSite": {
"message": "البحث عن المزيد من الأنماط لموقع الويب هذا.",
"description": "Text for a link that gets a list of styles for the current site"
},
"manageHeading": {
"message": "الأنماط المثبتة",
"description": "Heading for the manage page"
},
"styleBeautify": {
"message": "Beautify",
"description": "Label for the CSS-beautifier button on the edit style page"
},
"styleEnabledLabel": {
"message": "ممكّن",
"description": "Label for the enabled state of styles"
},
"styleToMozillaFormatHelp": {
"message": "يمكن استخدام تنسيق موزيلا للرمز باستخدام Stylus للمتصفح فايرفوكس ويمكن إرساله إلى userstyles.org.",
"description": "Help info for the Mozilla format header section that converts the code to/from Mozilla format"
},
"sectionAdd": {
"message": "إضافة قسم آخر",
"description": "Label for the button to add a section"
},
"styleSaveLabel": {
"message": "حفظ",
"description": "Label for save button for style editing"
},
"confirmStop": {
"message": "Stop",
"description": "'Stop' button in a confirm dialog"
},
"writeStyleForURL": {
"message": "this URL",
"description": "Text for link in toolbar pop-up to write a new style for the current URL"
},
"appliesAdd": {
"message": "إضافة",
"description": "Label for the button to add an 'applies' entry"
},
"appliesRegexpOption": {
"message": "عناوين URL التي تطابق regexp",
"description": "Option to make the style apply to the entered string as a regular expression"
},
"styleInstall": {
"message": "هل تريد تثبيت '$stylename$' في Stylus؟",
"description": "Confirmation when installing a style",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"manageText": {
"message": "<a href='https://userstyles.org'>Get styles on userstyles.org</a> | <a href='http://add0n.com/stylus.html'>Get help</a>",
"description": "Help text on the manage page"
},
"searchStyles": {
"message": "Search contents",
"description": "Label for the search filter textbox on the Manage styles page"
},
"disableStyleLabel": {
"message": "تعطيل",
"description": "Label for the button to disable a style"
},
"prefShowBadge": {
"message": "Show number of styles active for the current site on the toolbar button",
"description": "Label for the checkbox controlling toolbar badge text."
},
"menuShowBadge": {
"message": "Show active style count",
"description": "Label (must be very short) for the checkbox in the toolbar button context menu controlling toolbar badge text."
},
"cm_lineWrapping": {
"message": "Word wrap",
"description": "Label for the checkbox controlling word wrap option for the style editor."
},
"styleCancelEditLabel": {
"message": "رجوع للإدارة",
"description": "Label for cancel button for style editing"
},
"styleChangesNotSaved": {
"message": "لقد أجريت تغييرات على هذا النمط بدون حفظها.",
"description": "Text for the prompt when changes are made to a style and the user tries to leave without saving"
},
"importLabel": {
"message": "Import",
"description": "Label for the button to import a style ('edit' page) or all styles ('manage' page)"
},
"updateCheckFailServerUnreachable": {
"message": "أخفق التحديث - الخادم يتعذر الوصول إليه.",
"description": "Text that displays when an update check failed because the update server is unreachable"
},
"manageFilters": {
"message": "Filters",
"description": "Label for filters container"
},
"applyAllUpdates": {
"message": "Apply all updates",
"description": "Label for the button to apply all detected updates"
},
"deleteStyleConfirm": {
"message": "هل تريد بالتأكيد حذف هذا النمط؟",
"description": "Confirmation before deleting a style"
},
"confirmDelete": {
"message": "Delete"
},
"confirmCancel": {
"message": "Cancel"
},
"styleBadRegexp": {
"message": "Regexp is invalid.",
"description": "Validation message for a bad regexp in a style"
},
"optionsHeading": {
"message": "Options",
"description": "Heading for options section on manage page."
},
"appliesDisplay": {
"message": "ينطبق على: $applies$",
"description": "Text on the manage screen to describe what the style applies to",
"placeholders": {
"applies": {
"content": "$1"
}
}
},
"styleUpdate": {
"message": "Are you sure you want to update '$stylename$'?",
"description": "Confirmation when updating a style",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"styleSectionsTitle": {
"message": "الأقسام",
"description": "Title for the style sections section"
},
"editStyleTitle": {
"message": "تعديل النمط $stylename$",
"description": "Title of the page for editing styles",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"updateCheckSucceededNoUpdate": {
"message": "النمط محدّث.",
"description": "Text that displays when an update check completed and no update is available"
},
"appliesUrlPrefixOption": {
"message": "عناوين URL البادئة بـ",
"description": "Option to make the style apply to the entered string as a URL prefix"
},
"searchRegexp": {
"message": "Use /re/ syntax for regexp search",
"description": "Label after the search input field in the editor shown on Ctrl-F"
},
"importReplaceTooltip": {
"message": "Discard contents of current style and overwrite it with the imported style",
"description": "Label for the button to import and overwrite current style"
},
"popupStylesFirst": {
"message": "List styles before commands in the toolbar button menu",
"description": "Label for the checkbox controlling section order in the toolbar button menu."
},
"sectionHelp": {
"message": "تتيح لك الأقسام تحديد أجزاء مختلفة من الرمز لتطبيقها على مجموعات مختلفة من عناوين URL بالنمط نفسه. فعلى سبيل المثال، يمكن لنمط مفرد تغيير الصفحة الرئيسية لموقع ويب بطريقة، مع تغيير بقية أجزاء موقع الويب بطريقة أخرى.",
"description": "Help text for sections"
},
"noStylesForSite": {
"message": "لم يتم تثبيت أي أنماط لموقع الويب هذا.",
"description": "Text displayed when no styles are installed for the current site"
},
"appliesDisplayTruncatedSuffix": {
"message": "والمزيد",
"description": "Text added to appliesDisplay when there are more sites for the style than are displayed"
},
"appliesRemove": {
"message": "إزالة",
"description": "Label for the button to remove an 'applies' entry"
},
"styleToMozillaFormatTitle": {
"message": "Style in Mozilla format",
"description": "Title of the popup with the style code in Mozilla format, shown after pressing the Export button on Edit style page"
},
"manageTitle": {
"message": "Stylus",
"description": "Title for the manage page"
},
"writeStyleFor": {
"message": "Write style for: ",
"description": "Label for toolbar pop-up that precedes the links to write a new style"
},
"replace": {
"message": "Replace",
"description": "Label before the replace input field in the editor shown on Ctrl-H"
},
"appliesLabel": {
"message": "ينطبق على",
"description": "Label for 'applies to' fields on the edit/add screen"
},
"openManage": {
"message": "إدارة الأنماط المثبتة",
"description": "Link to open the manage page."
},
"updateCheckFailBadResponseCode": {
"message": "أخفق التحديث - استجاب الخادم بالرمز $code$.",
"description": "Text that displays when an update check failed because the response code indicates an error",
"placeholders": {
"code": {
"content": "$1"
}
}
},
"appliesSpecify": {
"message": "تحديد",
"description": "Label for the button to make a style apply only to specific sites"
},
"installUpdate": {
"message": "تثبيت التحديث",
"description": "Label for the button to install an update for a single style"
},
"styleMozillaFormatHeading": {
"message": "Mozilla Format",
"description": "Heading for the section with buttons to import/export Mozilla format of the style"
},
"sectionRemove": {
"message": "إزالة القسم",
"description": "Label for the button to remove a section"
},
"disableAllStyles": {
"message": "Turn all styles off",
"description": "Label for the checkbox that turns all enabled styles off."
},
"undoGlobal": {
"message": "Undo (global)",
"description": "CSS-beautify global Undo button label"
},
"updateCompleted": {
"message": "اكتمل التحديث.",
"description": "Text that displays when an update completed"
},
"checkingForUpdate": {
"message": "جارٍ البحث...",
"description": "Text to display when checking a style for an update"
},
"sectionCode": {
"message": "الرمز",
"description": "Label for the code for a section"
},
"cm_smartIndent": {
"message": "Use smart indentation",
"description": "Label for the checkbox controlling smart indentation option for the style editor."
},
"appliesHelp": {
"message": "استخدم عناصر تحكم 'ينطبق على' لتقييد عناوين URL التي ينطبق عليها الرمز في هذا القسم.",
"description": "Help text for 'applies to' section"
},
"editStyleHeading": {
"message": "تعديل النمط",
"description": "Title of the page for editing styles"
},
"appliesUrlOption": {
"message": "عنوان URL",
"description": "Option to make the style apply to the entered string as a URL"
},
"addStyleTitle": {
"message": "إضافة نمط",
"description": "Title of the page for adding styles"
},
"importReplaceLabel": {
"message": "Overwrite style",
"description": "Label for the button to import and overwrite current style"
},
"dbError": {
"message": "An error has occurred using the Stylus database. Would you like to visit a web page with possible solutions?",
"description": "Prompt when a DB error is encountered"
},
"importAppendTooltip": {
"message": "Append the imported style to current style",
"description": "Tooltip for the button to import a style and append to the existing sections"
},
"helpKeyMapHotkey": {
"message": "Press a hotkey",
"description": "Placeholder text of inputbox in keymap help popup on the edit style page. Must be very short"
},
"replaceAll": {
"message": "Replace all",
"description": "Label before the replace input field in the editor shown on 'replaceAll' hotkey"
},
"editGotoLine": {
"message": "Goto line (or line:col)",
"description": "Go to line or line:column on Ctrl-G in style code editor"
},
"checkAllUpdates": {
"message": "البحث عن تحديثات لكل الأنماط",
"description": "Label for the button to check all styles for updates"
},
"issuesHelp": {
"message": "The issues found by <a href='https://github.com/CSSLint/csslint' target='_blank'>CSSLint</a> with these rules enabled:",
"description": "Help popup message for the CSSLint issues block on the style edit page"
},
"confirmNo": {
"message": "No",
"description": "'No' button in a confirm dialog"
},
"undo": {
"message": "Undo",
"description": "Button label"
},
"cm_keyMap": {
"message": "Keymap",
"description": "Label for the drop-down list controlling the keymap for the style editor."
},
"cm_indentWithTabs": {
"message": "Use tabs with smart indentation",
"description": "Label for the checkbox controlling tabs with smart indentation option for the style editor."
},
"replaceWith": {
"message": "Replace with",
"description": "Label before the replace-with input field in the editor shown on Ctrl-H etc."
},
"deleteStyleLabel": {
"message": "حذف",
"description": "Label for the button to delete a style"
},
"addStyleLabel": {
"message": "كتابة نمط جديد",
"description": "Label for the button to go to the add style page"
},
"manageOnlyEnabled": {
"message": "Only enabled styles",
"description": "Checkbox to show only enabled styles"
},
"editStyleLabel": {
"message": "تعديل",
"description": "Label for the button to go to the edit style page"
},
"cm_theme": {
"message": "Theme",
"description": "Label for the style editor's CSS theme."
},
"helpKeyMapCommand": {
"message": "Type a command name",
"description": "Placeholder text of inputbox in keymap help popup on the edit style page. Must be very short"
},
"description": {
"message": "يمكنك تغيير نمط الويب باستخدام Stylus، وهي أداة لإدارة أنماط المستخدم. وتتيح Stylus لك بسهولة تثبيت المظاهر والأشكال الخارجية لكل من Google، وFacebook وYouTube وOrkut فضلاً عن الكثير جدًا من مواقع الويب الأخرى.",
"description": "Extension description"
}
"InaccessibleFileHint": {
"message": "Stylus لا يستطيع الوصول الى بعض انواع الملفات ( ملفات pdf و json )"
},
"addStyleLabel": {
"message": "كتابة نمط جديد"
},
"addStyleTitle": {
"message": "إضافة نمط"
},
"appliesAdd": {
"message": "إضافة"
},
"appliesDisplay": {
"message": "ينطبق على: $applies$",
"placeholders": {
"applies": {
"content": "$1"
}
}
},
"appliesDisplayTruncatedSuffix": {
"message": "و المزيد"
},
"appliesDomainOption": {
"message": "عناوين URL في النطاق"
},
"appliesHelp": {
"message": "استخدم عناصر تحكم 'ينطبق على' لتقييد عناوين URL التي ينطبق عليها الرمز في هذا القسم."
},
"appliesLabel": {
"message": "ينطبق على"
},
"appliesRegexpOption": {
"message": "عناوين URL التي تطابق regexp"
},
"appliesRemove": {
"message": "إزالة"
},
"appliesSpecify": {
"message": "تحديد"
},
"appliesToEverything": {
"message": "كل شيء"
},
"appliesUrlOption": {
"message": "عنوان URL"
},
"appliesUrlPrefixOption": {
"message": "عناوين URL البادئة بـ"
},
"checkAllUpdates": {
"message": "البحث عن تحديثات لكل الأنماط"
},
"checkForUpdate": {
"message": "البحث عن تحديث"
},
"checkingForUpdate": {
"message": "جارٍ البحث..."
},
"confirmDelete": {
"message": "حذف"
},
"confirmSave": {
"message": "حفظ"
},
"deleteStyleConfirm": {
"message": "هل تريد بالتأكيد حذف هذا النمط؟"
},
"deleteStyleLabel": {
"message": "حذف"
},
"description": {
"message": "يمكنك تغيير نمط الويب باستخدام Stylus، وهي أداة لإدارة أنماط المستخدم. وتتيح Stylus لك بسهولة تثبيت المظاهر والأشكال الخارجية لكل من Google، وFacebook وYouTube وOrkut فضلاً عن الكثير جدًا من مواقع الويب الأخرى."
},
"disableStyleLabel": {
"message": "تعطيل"
},
"editDeleteText": {
"message": "حذف"
},
"editStyleHeading": {
"message": "تعديل النمط"
},
"editStyleLabel": {
"message": "تعديل"
},
"editStyleTitle": {
"message": "تعديل النمط $stylename$",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"enableStyleLabel": {
"message": "تمكين"
},
"genericAdd": {
"message": "إضافة"
},
"genericEnabledLabel": {
"message": "ممكّن"
},
"helpAlt": {
"message": "مساعدة"
},
"installUpdate": {
"message": "تثبيت التحديث"
},
"manageHeading": {
"message": "الأنماط المثبتة"
},
"noStylesForSite": {
"message": "لم يتم تثبيت أي أنماط لموقع الويب هذا."
},
"openManage": {
"message": "إدارة الأنماط المثبتة"
},
"optionsSyncUrl": {
"message": "عنوان URL"
},
"sectionAdd": {
"message": "إضافة قسم آخر"
},
"sectionCode": {
"message": "الرمز"
},
"sectionRemove": {
"message": "إزالة القسم"
},
"sections": {
"message": "الأقسام"
},
"styleCancelEditLabel": {
"message": "رجوع للإدارة"
},
"styleChangesNotSaved": {
"message": "لقد أجريت تغييرات على هذا النمط بدون حفظها."
},
"styleEnabledLabel": {
"message": "ممكّن"
},
"styleInstall": {
"message": "هل تريد تثبيت '$stylename$' في Stylus؟",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"styleMissingName": {
"message": "أدخل اسمًا"
},
"styleSaveLabel": {
"message": "حفظ"
},
"styleToMozillaFormatHelp": {
"message": "يمكن استخدام تنسيق موزيلا للرمز باستخدام Stylus للمتصفح فايرفوكس ويمكن إرساله إلى userstyles.org."
},
"updateCheckFailBadResponseCode": {
"message": "أخفق التحديث - استجاب الخادم بالرمز $code$",
"placeholders": {
"code": {
"content": "$1"
}
}
},
"updateCheckFailServerUnreachable": {
"message": "أخفق التحديث - الخادم يتعذر الوصول إليه."
},
"updateCheckSucceededNoUpdate": {
"message": "النمط محدّث."
},
"updateCompleted": {
"message": "اكتمل التحديث."
}
}

566
_locales/bg/messages.json Normal file
View File

@ -0,0 +1,566 @@
{
"addStyleLabel": {
"message": "Писане на нов стил"
},
"addStyleTitle": {
"message": "Добавяне на стил"
},
"appliesAdd": {
"message": "Добавяне"
},
"appliesDisplay": {
"message": "Приложимо за: $applies$",
"placeholders": {
"applies": {
"content": "$1"
}
}
},
"appliesDisplayTruncatedSuffix": {
"message": "и още"
},
"appliesDomainOption": {
"message": "Адреси на домейна"
},
"appliesHelp": {
"message": "Използвайте 'Приложимо за', за да ограничите адресите, за които се отнася кода в отдела."
},
"appliesLabel": {
"message": "Приложимо за"
},
"appliesRegexpOption": {
"message": "Адреси, съвпадащи с регулярен израз"
},
"appliesRemove": {
"message": "Премахване"
},
"appliesSpecify": {
"message": "Уточняване"
},
"appliesToEverything": {
"message": "Всичко"
},
"appliesUrlOption": {
"message": "Адрес"
},
"appliesUrlPrefixOption": {
"message": "Адреси, започващи с"
},
"applyAllUpdates": {
"message": "Прилагане на всички обновления"
},
"backupButtons": {
"message": "Резервни копия"
},
"bckpInstStyles": {
"message": "Изнасяне на стилове"
},
"checkAllUpdates": {
"message": "Проверка на всички стилове за обновления"
},
"checkAllUpdatesForce": {
"message": "Повторна проверка"
},
"checkForUpdate": {
"message": "Проверка за обновления"
},
"checkingForUpdate": {
"message": "Проверяване..."
},
"cm_autocompleteOnTyping": {
"message": "Автоматично завършване при въвеждане"
},
"cm_indentWithTabs": {
"message": "Подпрозорци с умен отстъп"
},
"cm_keyMap": {
"message": "Клавиши"
},
"cm_lineWrapping": {
"message": "Пренасяне"
},
"cm_matchHighlight": {
"message": "Осветяване"
},
"cm_matchHighlightSelection": {
"message": "Само избраното"
},
"cm_matchHighlightToken": {
"message": "Низа под показалеца"
},
"cm_resizeGripHint": {
"message": "Щракнете два пъти за възстановяване/увеличаване на височината"
},
"cm_smartIndent": {
"message": "Умен отстъп"
},
"cm_tabSize": {
"message": "Табулация"
},
"cm_theme": {
"message": "Тема"
},
"confirmCancel": {
"message": "Отказ"
},
"confirmDelete": {
"message": "Изтриване"
},
"confirmNo": {
"message": "Не"
},
"confirmOK": {
"message": "Добре"
},
"confirmSave": {
"message": "Запазване"
},
"confirmStop": {
"message": "Спиране"
},
"confirmYes": {
"message": "Да"
},
"dbError": {
"message": "Възникна грешка с базата от данни. Искате ли да посетите страницата с възможни решения?"
},
"defaultTheme": {
"message": "по подразбиране"
},
"deleteStyleConfirm": {
"message": "Сигурни ли сте, че искате да изтриете стила?"
},
"deleteStyleLabel": {
"message": "Изтриване"
},
"description": {
"message": "Пресъздайте стила на Мрежата със Стайлус, разширението за стилове. То ви позволява лесно да инсталиране теми за много сайтове."
},
"disableAllStyles": {
"message": "Изключване на всички стилове"
},
"disableStyleLabel": {
"message": "Изключване"
},
"dragDropMessage": {
"message": "Пуснете резервното копие където и да е по страницата, за да го внесете."
},
"editDeleteText": {
"message": "Изтриване"
},
"editGotoLine": {
"message": "Отиване на ред"
},
"editStyleHeading": {
"message": "Редактиране на стила"
},
"editStyleLabel": {
"message": "Редактиране"
},
"editStyleTitle": {
"message": "Редактиране на стила $stylename$",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"enableStyleLabel": {
"message": "Включване"
},
"exportLabel": {
"message": "Изнасяне"
},
"genericAdd": {
"message": "Добавяне"
},
"genericDisabledLabel": {
"message": "Изключено"
},
"genericEnabledLabel": {
"message": "Включено"
},
"genericHistoryLabel": {
"message": "Хронология"
},
"helpAlt": {
"message": "Помощ"
},
"helpKeyMapCommand": {
"message": "Въведете име"
},
"helpKeyMapHotkey": {
"message": "Натиснете клавиш"
},
"importAppendLabel": {
"message": "Прибавяне към стила"
},
"importAppendTooltip": {
"message": "Прибавяне на внесения стил към текущия"
},
"importLabel": {
"message": "Внасяне"
},
"importReplaceLabel": {
"message": "Презаписване на стила"
},
"importReplaceTooltip": {
"message": "Презаписване на съдържанието на текщия стил с това от внесения"
},
"importReportLegendAdded": {
"message": "добавени"
},
"importReportLegendIdentical": {
"message": "пропуснати еднакви"
},
"importReportLegendInvalid": {
"message": "пропуснати невалидни"
},
"importReportLegendUpdatedBoth": {
"message": "с обновени код и метаданни"
},
"importReportLegendUpdatedCode": {
"message": "с обновен код"
},
"importReportLegendUpdatedMeta": {
"message": "с обновени метаданни"
},
"importReportTitle": {
"message": "Внасянето на стилове завърши"
},
"importReportUnchanged": {
"message": "Нищо не беше променено."
},
"importReportUndone": {
"message": "върнати стила"
},
"importReportUndoneTitle": {
"message": "Внасянето беше отменено"
},
"installUpdate": {
"message": "Инсталиране на обновлението"
},
"linkGetHelp": {
"message": "Помощ"
},
"linkGetStyles": {
"message": "Вземете стилове"
},
"linterIssues": {
"message": "Проблеми"
},
"linterIssuesHelp": {
"message": "Проблеми, намерени от $link$ при следните правила:",
"placeholders": {
"link": {
"content": "$1"
}
}
},
"manageFavicons": {
"message": "Иконки на приложимите сайтовете"
},
"manageFaviconsGray": {
"message": "Сиви"
},
"manageFilters": {
"message": "Филтри"
},
"manageHeading": {
"message": "Инсталирани стилове"
},
"manageMaxTargets": {
"message": "Брой на видимите приложими адреси"
},
"manageNewUI": {
"message": "Нов интерфейс за управление"
},
"manageOnlyEnabled": {
"message": "Само включените стилове"
},
"manageOnlyLocal": {
"message": "Само местно създадените стилове"
},
"manageOnlyLocalTooltip": {
"message": "(стиловете, които не са инсталирани през userstyles.org)"
},
"manageOnlyUpdates": {
"message": "Само стилове с обновления или проблеми"
},
"manageTitle": {
"message": "Стилове"
},
"menuShowBadge": {
"message": "Брой на активните стилове"
},
"noStylesForSite": {
"message": "Няма инсталирани стилове за сайта."
},
"openManage": {
"message": "Управление"
},
"openOptions": {
"message": "Настройки"
},
"openStylesManager": {
"message": "Управление на стиловете"
},
"optionsActions": {
"message": "Действия"
},
"optionsAdvanced": {
"message": "Разширени"
},
"optionsAdvancedContextDelete": {
"message": "Добавяне на 'Изтриване' в контекстното меню на редактора"
},
"optionsAdvancedExposeIframes": {
"message": "Разкриване на 'iframes' чрез HTML[stylus-iframe]"
},
"optionsBadgeDisabled": {
"message": "Цвят на фона, когато е изключено"
},
"optionsBadgeNormal": {
"message": "Цвят на фона"
},
"optionsCheck": {
"message": "Обновяване на стиловете"
},
"optionsCheckUpdate": {
"message": "Проверка и инсталиране на наличните обновления"
},
"optionsCustomizeBadge": {
"message": "Значка на иконката на лентата"
},
"optionsCustomizeIcon": {
"message": "Иконка на лентата със сечива"
},
"optionsCustomizePopup": {
"message": "Падащ прозорец"
},
"optionsCustomizeUpdate": {
"message": "Обновления"
},
"optionsHeading": {
"message": "Настройки"
},
"optionsIconDark": {
"message": "Тъмни теми"
},
"optionsIconLight": {
"message": "Светли теми"
},
"optionsOpen": {
"message": "Отваряне"
},
"optionsOpenManager": {
"message": "Управление на стиловете"
},
"optionsPopupWidth": {
"message": "Ширина на падащия прозорец (в пиксели)"
},
"optionsReset": {
"message": "Зануляване на настройки на първоначалните стойности"
},
"optionsResetButton": {
"message": "Зануляване на настройките"
},
"optionsSubheading": {
"message": "Още настройки"
},
"optionsSyncUrl": {
"message": "Адрес"
},
"optionsUpdateImportNote": {
"message": "При внасянето на резервни копия от стари версии или от Стайлиш направете ръчна проверка за обновления, за да сте сигурни, че стиловете са актуални."
},
"popupStylesFirst": {
"message": "Стилове преди командите"
},
"prefShowBadge": {
"message": "Брой на активните стилове за текущия сайт"
},
"replace": {
"message": "Заместване"
},
"replaceAll": {
"message": "Заместване на всички"
},
"replaceWith": {
"message": "Заместване с"
},
"retrieveBckp": {
"message": "Внасяне на стилове"
},
"search": {
"message": "Търсене"
},
"searchRegexp": {
"message": "Използвайте синтаксиса /re/ за търсене с регулярни изрази"
},
"sectionAdd": {
"message": "Добавяне на друг отдел"
},
"sectionCode": {
"message": "Код"
},
"sectionRemove": {
"message": "Премахване на отдела"
},
"sections": {
"message": "Отдели"
},
"shortcuts": {
"message": "Клавишни комбинации"
},
"shortcutsNote": {
"message": "Задаване на клавишни комбинации"
},
"styleBadRegexp": {
"message": "Регулярният израз не е правилен."
},
"styleBeautify": {
"message": "Разкрасяване"
},
"styleBeautifyIndentConditional": {
"message": "Отстъп на @media, @supports"
},
"styleCancelEditLabel": {
"message": "Назад към стиловете"
},
"styleChangesNotSaved": {
"message": "Направили сте промени по стила без да ги запазите."
},
"styleEnabledLabel": {
"message": "Включено"
},
"styleFromMozillaFormatPrompt": {
"message": "Поставете кода във формат на Мозила"
},
"styleInstall": {
"message": "Да се инсталира ли '$stylename$'?",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"styleMissingName": {
"message": "Въведете име"
},
"styleMozillaFormatHeading": {
"message": "Формат на Мозила"
},
"styleNotAppliedRegexpProblemTooltip": {
"message": "Стилът не е приложен поради неправилно използване на регулярни изрази"
},
"styleRegexpInvalidExplanation": {
"message": "Има правила на регулярни изрази, които не могат да бъдат компилирани."
},
"styleRegexpPartialExplanation": {
"message": "Стилът използва частично съвпадащи регулярни изрази и нарушава <a href='https://developer.mozilla.org/docs/Web/CSS/@document'>Спецификацията @document</a>, която изисква пълно съвпадение на адреса. Засегнатите отдели не са приложени. Стилът вероятно е създаден в Stylish-for-Chrome, което неправилно проверява правилата на 'regexp()' още от първата версия (познат дефект)."
},
"styleRegexpProblemTooltip": {
"message": "Брой на неприложените отдели поради неправилно използване на регулярни изрази"
},
"styleRegexpTestFull": {
"message": "Съвпадащи подпрозорци"
},
"styleRegexpTestInvalid": {
"message": "Неправилните регулярни изрази са пропуснати"
},
"styleRegexpTestNone": {
"message": "Няма съвпадащи подпрозорци"
},
"styleRegexpTestPartial": {
"message": "Не съвпада напълно, затова е пропуснато"
},
"styleRegexpTestTitle": {
"message": "Списък със съвпадащи отворени подпрозорци (щракнете на адреса, за да се фокусира на подпрозореца)"
},
"styleSaveLabel": {
"message": "Запазване"
},
"styleToMozillaFormatHelp": {
"message": "Форматът на Мозила може да се подаде в userstyles.org и да се използва със Стайлиш (Stylish)"
},
"styleToMozillaFormatTitle": {
"message": "Стил във формат на Мозила"
},
"styleUpdate": {
"message": "Сигурни ли сте, че искате да обновите '$stylename$'?",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"stylusUnavailableForURL": {
"message": "Разширението не работи на такива страници."
},
"stylusUnavailableForURLdetails": {
"message": "Като предпазна мярка, четецът забранява на разширенията да влияят на вградените страници (например chrome://version, about:addons, стандартната страница от Хром 61 и други), както и на страниците на други разширения. Достъпът до магазина с добавки на всеки четец също е ограничен."
},
"toggleStyle": {
"message": "Превключване на стила"
},
"undo": {
"message": "Отмяна"
},
"undoGlobal": {
"message": "Отмяна във всички отдели"
},
"unreachableContentScript": {
"message": "Няма връзка със страницата. Презаредете подпрозореца."
},
"unreachableFileHint": {
"message": "Разширението ще има достъп до адреси от типа file:// само ако включите съответната отметка на страницата chrome://extensions."
},
"updateAllCheckSucceededNoUpdate": {
"message": "Няма намерени обновления."
},
"updateAllCheckSucceededSomeEdited": {
"message": "Някои от стиловете не са проверени, за да не се загубят местните редакции. Обновленията могат да бъдат принудени с индивидуална проверка или с пускането на още една проверка за всички (местните промени ще бъдат презаписани)."
},
"updateCheckFailBadResponseCode": {
"message": "Неуспешно обновяване: сървърът отговори с код $code$.",
"placeholders": {
"code": {
"content": "$1"
}
}
},
"updateCheckFailServerUnreachable": {
"message": "Неуспешно обновяване: няма връзка със сървъра."
},
"updateCheckHistory": {
"message": "Хронология на проверките"
},
"updateCheckManualUpdateForce": {
"message": "Инсталиране на обновлението (местните редакции ще бъдат презаписани)"
},
"updateCheckManualUpdateHint": {
"message": "Принудителното обновяване ще презапише местните редакции."
},
"updateCheckSkippedLocallyEdited": {
"message": "Стилът е бил местно редактиран."
},
"updateCheckSkippedMaybeLocallyEdited": {
"message": "Стилът може да е бил местно редактиран."
},
"updateCheckSucceededNoUpdate": {
"message": "Стилът е обновен."
},
"updateCompleted": {
"message": "Обновяването е завършено."
},
"updatesCurrentlyInstalled": {
"message": "Инсталирани обновления:"
},
"writeStyleFor": {
"message": "Писане на стил за: "
},
"writeStyleForURL": {
"message": "този адрес"
}
}

View File

@ -0,0 +1,278 @@
{
"addStyleLabel": {
"message": "Напиши нов стил"
},
"addStyleTitle": {
"message": "Добави стил"
},
"appliesAdd": {
"message": "Добави"
},
"appliesDisplay": {
"message": "Прилага се към: $applies$",
"placeholders": {
"applies": {
"content": "$1"
}
}
},
"appliesDisplayTruncatedSuffix": {
"message": "и още"
},
"appliesDomainOption": {
"message": "URLи на домейна"
},
"appliesHelp": {
"message": "Използвайте \"Прилага се към\", за да ограничете адресите, за които ще работи кодът в тази секция."
},
"appliesLabel": {
"message": "Прилага се към"
},
"appliesRegexpOption": {
"message": "Адреси, съвпадащи с regexp"
},
"appliesRemove": {
"message": "Премахни"
},
"appliesSpecify": {
"message": "Уточни"
},
"appliesToEverything": {
"message": "Всички"
},
"appliesUrlPrefixOption": {
"message": "URL започващи с"
},
"applyAllUpdates": {
"message": "Приложи всички промени"
},
"checkAllUpdates": {
"message": "Провери всички стилове за обновления"
},
"checkForUpdate": {
"message": "Провери за обновление"
},
"checkingForUpdate": {
"message": "Проверявам..."
},
"cm_indentWithTabs": {
"message": "Използвай табулация с умно отместване"
},
"cm_keyMap": {
"message": "Клавишни комбинации"
},
"cm_lineWrapping": {
"message": "Автоматично пренасяне"
},
"cm_smartIndent": {
"message": "Използвай умно отместване"
},
"cm_tabSize": {
"message": "Размер на табулацията"
},
"cm_theme": {
"message": "Тема"
},
"confirmNo": {
"message": "Не"
},
"confirmStop": {
"message": "Спри"
},
"confirmYes": {
"message": "Да"
},
"dbError": {
"message": "Грешка в базата данни на Stylus. Желаеш ли да посетиш уебстраницата с възможни решения?"
},
"defaultTheme": {
"message": "по подразбиране"
},
"deleteStyleConfirm": {
"message": "Наистина ли искаш да изтриеш този стил?"
},
"deleteStyleLabel": {
"message": "Изтрий"
},
"description": {
"message": "Промени уеба със Stylus, мениджър на потребителски стилове. Stylus ти позволява лесно да инсталираш теми и скинове за много популярни сайтове."
},
"disableAllStyles": {
"message": "Изключи всички стилове"
},
"disableStyleLabel": {
"message": "Забрани"
},
"editGotoLine": {
"message": "Иди на ред (или ред:кол)"
},
"editStyleHeading": {
"message": "Промени стила"
},
"editStyleLabel": {
"message": "Редактирай"
},
"editStyleTitle": {
"message": "Редактирай стил $stylename$",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"enableStyleLabel": {
"message": "Разреши"
},
"exportLabel": {
"message": "Експорт"
},
"helpAlt": {
"message": "Помощ"
},
"helpKeyMapCommand": {
"message": "Напиши име на команда"
},
"helpKeyMapHotkey": {
"message": "Натисни клавишна комбинация"
},
"importAppendLabel": {
"message": "Добави към стил"
},
"importAppendTooltip": {
"message": "Добави импортирания стил към текущия"
},
"importLabel": {
"message": "Импорт"
},
"importReplaceLabel": {
"message": "Презапиши стила"
},
"importReplaceTooltip": {
"message": "Презапишете съдържанието на текущия стил с импортирания"
},
"installButton": {
"message": "Инсталирай стил"
},
"installButtonInstalled": {
"message": "Стилът е инсталиран"
},
"installButtonReinstall": {
"message": "Преинсталирай стила"
},
"installButtonUpdate": {
"message": "Обнови стила"
},
"installUpdate": {
"message": "Инсталирай обновление"
},
"installUpdateFrom": {
"message": "В момента стилът се обновява от $url$",
"placeholders": {
"url": {
"content": "$1"
}
}
},
"installUpdateFromLabel": {
"message": "Провери за обновления"
},
"license": {
"message": "Лиценз"
},
"linkGetHelp": {
"message": "Получете помощ"
},
"linkGetStyles": {
"message": "Вземете стилове"
},
"linkTranslate": {
"message": "Преведете"
},
"linterCSSLintIncompatible": {
"message": "CSSLint не поддържа $preprocessorname$ preprocessor",
"placeholders": {
"preprocessorname": {
"content": "$1"
}
}
},
"linterCSSLintSettings": {
"message": "(Укажете правилата: 0 = забранен; 1 = предупреждения; 2 = грешки)"
},
"linterConfigPopupTitle": {
"message": "Настройте конфигурация за $linter$ правила",
"placeholders": {
"linter": {
"content": "$1"
}
}
},
"linterConfigTooltip": {
"message": "Щракнете, за да конфигурирате този linter"
},
"linterInvalidConfigError": {
"message": "Не е записано заради тези неправилни настройки"
},
"linterIssues": {
"message": "Проблеми"
},
"linterIssuesHelp": {
"message": "Тези проблеми бяха намерени от $link$:",
"placeholders": {
"link": {
"content": "$1"
}
}
},
"linterJSONError": {
"message": "Невалиден JSON формат"
},
"linterResetMessage": {
"message": "За да върнете погрешно нулиране, натиснете Ctrl-Z (или Cmd-Z) в текстовия прозорец"
},
"linterRulesLink": {
"message": "Вижте пълния списък с правила"
},
"liveReloadError": {
"message": "Получи се грешка докато наблюдавахме файла"
},
"liveReloadLabel": {
"message": "Преглед на живо"
},
"manageFilters": {
"message": "Филтри"
},
"manageHeading": {
"message": "Инсталирани стилове"
},
"manageNewStyleAsUsercss": {
"message": "като Потребителскиcss"
},
"manageNewUI": {
"message": "Нова подредба на UI"
},
"manageOnlyDisabled": {
"message": "Само забранените стилове"
},
"manageOnlyEnabled": {
"message": "Само разрешените стилове"
},
"manageOnlyExternal": {
"message": "Само външните стилове"
},
"manageOnlyLocal": {
"message": "Само локалните стилове"
},
"manageOnlyLocalTooltip": {
"message": "(стиловете не инсталирани чрез страницата на userstyles.org)"
},
"manageOnlyNonUsercss": {
"message": "Само не-Потребителскитеcss стилове"
},
"manageOnlyUpdates": {
"message": "Само с обновления или проблеми"
},
"manageOnlyUsercss": {
"message": "Само Потребителскиcss стилове"
}
}

File diff suppressed because it is too large Load Diff

100
_locales/da/messages.json Normal file
View File

@ -0,0 +1,100 @@
{
"addStyleLabel": {
"message": "Skriv ny stil"
},
"addStyleTitle": {
"message": "Tilføj stil"
},
"alphaChannel": {
"message": "Gennemsigtighed"
},
"appliesAdd": {
"message": "Tilføj"
},
"appliesDisplay": {
"message": "Anvendes på: $applies$",
"placeholders": {
"applies": {
"content": "$1"
}
}
},
"appliesDisplayTruncatedSuffix": {
"message": "og mere"
},
"appliesDomainOption": {
"message": "URL'er på domænet"
},
"appliesHelp": {
"message": "Brug 'Anvendt på'-styring til at begrænse hvilke URL'er koden i denne sektion anvendes på."
},
"appliesLabel": {
"message": "Anvendes på"
},
"appliesLineWidgetLabel": {
"message": "Vis 'Anvendes på'-info"
},
"appliesRegexpOption": {
"message": "URL'er der matcher regexp'en"
},
"appliesRemove": {
"message": "Fjern"
},
"appliesRemoveError": {
"message": "Kan ikke fjerne sidste 'Anvendes på'-optegnelse"
},
"appliesSpecify": {
"message": "Specificér"
},
"appliesToEverything": {
"message": "Alt"
},
"appliesUrlPrefixOption": {
"message": "URL'er der starter med"
},
"applyAllUpdates": {
"message": "Anvend alle opdateringer"
},
"author": {
"message": "Forfatter"
},
"bckpInstStyles": {
"message": "Eksportér stil"
},
"checkAllUpdates": {
"message": "Tjek alle stiler for opdateringer"
},
"checkAllUpdatesForce": {
"message": "Tjek igen, jeg redigerede ikke nogen stil!"
},
"checkForUpdate": {
"message": "Tjek efter opdatering"
},
"checkingForUpdate": {
"message": "Tjekker..."
},
"clickToUninstall": {
"message": "Klik for at afinstallere"
},
"cm_autoCloseBrackets": {
"message": "Luk automatisk paranteser og citationstegn"
},
"cm_autoCloseBracketsTooltip": {
"message": "Tilføj automatisk et lukket par når man åbner en af ()[]{}''\"\""
},
"cm_autocompleteOnTyping": {
"message": "Autoudfyld på indtastning"
},
"cm_colorpicker": {
"message": "Farvevælgere for CSS-farver"
},
"cm_indentWithTabs": {
"message": "Brug tabs med smart indrykning"
},
"cm_keyMap": {
"message": "Tastegenveje"
},
"genericAdd": {
"message": "Tilføj"
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,64 @@
{
"appliesRemoveError": {
"message": "Cannot remove last 'applies to' entry"
},
"checkAllUpdatesForce": {
"message": "Check again—I didn't edit any styles!"
},
"cm_autoCloseBrackets": {
"message": "Auto-close brackets and quotes"
},
"cm_colorpicker": {
"message": "Colour pickers for CSS colours"
},
"cm_resizeGripHint": {
"message": "Double-click to maximise/restore the height"
},
"colorpickerTooltip": {
"message": "Open colour picker"
},
"description": {
"message": "Redesign the web with Stylus, a user-style manager. Stylus allows you to easily install themes and skins for many popular sites."
},
"editGotoLine": {
"message": "Go to line (or line:col)"
},
"editStyleHeading": {
"message": "Edit style"
},
"license": {
"message": "Licence"
},
"manageFaviconsGray": {
"message": "Greyed out"
},
"optionsBadgeDisabled": {
"message": "Background colour when disabled"
},
"optionsBadgeNormal": {
"message": "Background colour"
},
"optionsUpdateImportNote": {
"message": "When importing style backups from an old version or from Stylish, do a one-time check for updates manually in the styles manager to ensure all styles are updated."
},
"optionsUpdateInterval": {
"message": "Userstyle auto-update interval in hours (specify 0 to disable)"
},
"styleInstallFailed": {
"message": "Failed to install userstyle\n$error$",
"placeholders": {
"error": {
"content": "$1"
}
}
},
"styleRegexpPartialExplanation": {
"message": "This style uses partially matching regexps in violation of <a href='https://developer.mozilla.org/docs/Web/CSS/@document'>CSS4 @document specification</a> which requires a full URL match. The affected CSS sections were not applied to the page. This style was probably created in Stylish-for-Chrome, which incorrectly checks 'regexp()' rules since the very first version (known bug)."
},
"styleUpdateDiscardChanges": {
"message": "The style has been changed outside the editor. Would you like to reload the style?"
},
"usercssConfigIncomplete": {
"message": "The style was updated or deleted after the configuration dialogue was shown. These variables were not saved to avoid corrupting the style's metadata:"
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1124
_locales/et/messages.json Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,417 +1,184 @@
{
"appliesToEverything": {
"message": "Kaikki",
"description": "Text displayed for styles that apply to all sites"
},
"defaultTheme": {
"message": "default",
"description": "Default CodeMirror CSS theme option on the edit style page"
},
"exportLabel": {
"message": "Export",
"description": "Label for the button to export a style ('edit' page) or all styles ('manage' page)"
},
"issues": {
"message": "Issues",
"description": "Label for the CSSLint issues block on the style edit page"
},
"cm_tabSize": {
"message": "Tab size",
"description": "Label for the text box controlling tab size option for the style editor."
},
"enableStyleLabel": {
"message": "Aktivoi",
"description": "Label for the button to enable a style"
},
"styleMissingName": {
"message": "Syötä nimi.",
"description": "Error displayed when user saves without providing a name"
},
"appliesDomainOption": {
"message": "URL ositteita domainilla",
"description": "Option to make the style apply to the entered string as a domain"
},
"checkForUpdate": {
"message": "Hae päivityksiä",
"description": "Label for the button to check a single style for an update"
},
"importAppendLabel": {
"message": "Append to style",
"description": "Label for the button to import a style and append to the existing sections"
},
"updateAllCheckSucceededNoUpdate": {
"message": "All styles are up to date.",
"description": "Text that displays when an update all check completed and no updates are available"
},
"styleFromMozillaFormatPrompt": {
"message": "Paste the Mozilla-format code",
"description": "Prompt in the dialog displayed after clicking 'Import from Mozilla format' button"
},
"helpAlt": {
"message": "Apu",
"description": "Alternate text for help buttons"
},
"search": {
"message": "Search",
"description": "Label before the search input field in the editor shown on Ctrl-F"
},
"confirmYes": {
"message": "Yes",
"description": "'Yes' button in a confirm dialog"
},
"findStylesForSite": {
"message": "Hae lisää tyylejä tälle sivustolle.",
"description": "Text for a link that gets a list of styles for the current site"
},
"manageHeading": {
"message": "Asennetut Tyylit",
"description": "Heading for the manage page"
},
"styleBeautify": {
"message": "Beautify",
"description": "Label for the CSS-beautifier button on the edit style page"
},
"styleEnabledLabel": {
"message": "Aktivoitu",
"description": "Label for the enabled state of styles"
},
"styleToMozillaFormatHelp": {
"message": "Mozilla formaattia koodista voidaan käyttää Stylish Firefoxille ohjelmassa ja voidaan lähettää userstyles.orgiin.",
"description": "Help info for the Mozilla format header section that converts the code to/from Mozilla format"
},
"sectionAdd": {
"message": "Lisää uusi osio",
"description": "Label for the button to add a section"
},
"styleSaveLabel": {
"message": "Tallenna",
"description": "Label for save button for style editing"
},
"confirmStop": {
"message": "Stop",
"description": "'Stop' button in a confirm dialog"
},
"writeStyleForURL": {
"message": "this URL",
"description": "Text for link in toolbar pop-up to write a new style for the current URL"
},
"appliesAdd": {
"message": "Lisää",
"description": "Label for the button to add an 'applies' entry"
},
"appliesRegexpOption": {
"message": "URL ositteet jotka vastaavat regexpiä",
"description": "Option to make the style apply to the entered string as a regular expression"
},
"styleInstall": {
"message": "Asennetaanko '$stylename$' Stylusiin?",
"description": "Confirmation when installing a style",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"manageText": {
"message": "<a href='https://userstyles.org'>Get styles on userstyles.org</a> | <a href='http://add0n.com/stylus.html'>Get help</a>",
"description": "Help text on the manage page"
},
"searchStyles": {
"message": "Search contents",
"description": "Label for the search filter textbox on the Manage styles page"
},
"disableStyleLabel": {
"message": "Poista Käytöstä",
"description": "Label for the button to disable a style"
},
"prefShowBadge": {
"message": "Show number of styles active for the current site on the toolbar button",
"description": "Label for the checkbox controlling toolbar badge text."
},
"menuShowBadge": {
"message": "Show active style count",
"description": "Label (must be very short) for the checkbox in the toolbar button context menu controlling toolbar badge text."
},
"cm_lineWrapping": {
"message": "Word wrap",
"description": "Label for the checkbox controlling word wrap option for the style editor."
},
"styleCancelEditLabel": {
"message": "Takaisin hallintapaneeliin",
"description": "Label for cancel button for style editing"
},
"styleChangesNotSaved": {
"message": "Olet tehnyt muutoksia tähän tyyliin tallentamatta.",
"description": "Text for the prompt when changes are made to a style and the user tries to leave without saving"
},
"importLabel": {
"message": "Import",
"description": "Label for the button to import a style ('edit' page) or all styles ('manage' page)"
},
"updateCheckFailServerUnreachable": {
"message": "Päivitys epäonnistui - ei voitu yhdistää palvelimeen.",
"description": "Text that displays when an update check failed because the update server is unreachable"
},
"manageFilters": {
"message": "Filters",
"description": "Label for filters container"
},
"applyAllUpdates": {
"message": "Apply all updates",
"description": "Label for the button to apply all detected updates"
},
"deleteStyleConfirm": {
"message": "Oletko varma että haluat poistaa tämän tyylin?",
"description": "Confirmation before deleting a style"
},
"confirmDelete": {
"message": "Delete"
},
"confirmCancel": {
"message": "Cancel"
},
"styleBadRegexp": {
"message": "Regexp ei kelpaa.",
"description": "Validation message for a bad regexp in a style"
},
"optionsHeading": {
"message": "Options",
"description": "Heading for options section on manage page."
},
"appliesDisplay": {
"message": "Kooskee: $applies$",
"description": "Text on the manage screen to describe what the style applies to",
"placeholders": {
"applies": {
"content": "$1"
}
}
},
"styleUpdate": {
"message": "Are you sure you want to update '$stylename$'?",
"description": "Confirmation when updating a style",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"styleSectionsTitle": {
"message": "Osiot",
"description": "Title for the style sections section"
},
"editStyleTitle": {
"message": "Muokkaa Tyyliä $stylename$",
"description": "Title of the page for editing styles",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"updateCheckSucceededNoUpdate": {
"message": "Tyyli on ajan tasalla.",
"description": "Text that displays when an update check completed and no update is available"
},
"appliesUrlPrefixOption": {
"message": "URL osoitteet jotka alkavat",
"description": "Option to make the style apply to the entered string as a URL prefix"
},
"searchRegexp": {
"message": "Use /re/ syntax for regexp search",
"description": "Label after the search input field in the editor shown on Ctrl-F"
},
"importReplaceTooltip": {
"message": "Discard contents of current style and overwrite it with the imported style",
"description": "Label for the button to import and overwrite current style"
},
"popupStylesFirst": {
"message": "List styles before commands in the toolbar button menu",
"description": "Label for the checkbox controlling section order in the toolbar button menu."
},
"sectionHelp": {
"message": "Osiot antavat sinun tarkentaa koodin eri osia niin että ne koskevat eri URL osoitteita samassa tyylissä. Esimerkiksi, yksi tyyli voi muokata kotisivua yhdellä tavalla kun se muokkaa koko muuta sivustoa toisella tavalla.",
"description": "Help text for sections"
},
"noStylesForSite": {
"message": "Ei asennettuja tyylejä tällä sivustolla.",
"description": "Text displayed when no styles are installed for the current site"
},
"appliesDisplayTruncatedSuffix": {
"message": "ja lisää",
"description": "Text added to appliesDisplay when there are more sites for the style than are displayed"
},
"appliesRemove": {
"message": "Poista",
"description": "Label for the button to remove an 'applies' entry"
},
"styleToMozillaFormatTitle": {
"message": "Style in Mozilla format",
"description": "Title of the popup with the style code in Mozilla format, shown after pressing the Export button on Edit style page"
},
"manageTitle": {
"message": "Tyylikäs",
"description": "Title for the manage page"
},
"writeStyleFor": {
"message": "Write style for: ",
"description": "Label for toolbar pop-up that precedes the links to write a new style"
},
"replace": {
"message": "Replace",
"description": "Label before the replace input field in the editor shown on Ctrl-H"
},
"appliesLabel": {
"message": "Koskee",
"description": "Label for 'applies to' fields on the edit/add screen"
},
"openManage": {
"message": "Hallitse asennettuja tyylejä",
"description": "Link to open the manage page."
},
"updateCheckFailBadResponseCode": {
"message": "Päivitys epäonnistui - palvelin vastasi koodilla $code$.",
"description": "Text that displays when an update check failed because the response code indicates an error",
"placeholders": {
"code": {
"content": "$1"
}
}
},
"appliesSpecify": {
"message": "Tarkenna",
"description": "Label for the button to make a style apply only to specific sites"
},
"installUpdate": {
"message": "Asenna päivitys",
"description": "Label for the button to install an update for a single style"
},
"styleMozillaFormatHeading": {
"message": "Mozilla Format",
"description": "Heading for the section with buttons to import/export Mozilla format of the style"
},
"sectionRemove": {
"message": "Poista osio",
"description": "Label for the button to remove a section"
},
"disableAllStyles": {
"message": "Turn all styles off",
"description": "Label for the checkbox that turns all enabled styles off."
},
"undoGlobal": {
"message": "Undo (global)",
"description": "CSS-beautify global Undo button label"
},
"updateCompleted": {
"message": "Päivitys suoritettu.",
"description": "Text that displays when an update completed"
},
"checkingForUpdate": {
"message": "Tarkistetaan...",
"description": "Text to display when checking a style for an update"
},
"sectionCode": {
"message": "Koodi",
"description": "Label for the code for a section"
},
"cm_smartIndent": {
"message": "Use smart indentation",
"description": "Label for the checkbox controlling smart indentation option for the style editor."
},
"appliesHelp": {
"message": "Käytä 'Koskee' kontrolleja rajoittaaksesi mitä URL osoitteisiin tämä osio koodista koskee.",
"description": "Help text for 'applies to' section"
},
"editStyleHeading": {
"message": "Muokkaa Tyyliä",
"description": "Title of the page for editing styles"
},
"appliesUrlOption": {
"message": "URL",
"description": "Option to make the style apply to the entered string as a URL"
},
"addStyleTitle": {
"message": "Lisää Tyyli",
"description": "Title of the page for adding styles"
},
"importReplaceLabel": {
"message": "Overwrite style",
"description": "Label for the button to import and overwrite current style"
},
"dbError": {
"message": "An error has occurred using the Stylus database. Would you like to visit a web page with possible solutions?",
"description": "Prompt when a DB error is encountered"
},
"importAppendTooltip": {
"message": "Append the imported style to current style",
"description": "Tooltip for the button to import a style and append to the existing sections"
},
"helpKeyMapHotkey": {
"message": "Press a hotkey",
"description": "Placeholder text of inputbox in keymap help popup on the edit style page. Must be very short"
},
"replaceAll": {
"message": "Replace all",
"description": "Label before the replace input field in the editor shown on 'replaceAll' hotkey"
},
"editGotoLine": {
"message": "Goto line (or line:col)",
"description": "Go to line or line:column on Ctrl-G in style code editor"
},
"checkAllUpdates": {
"message": "Tarkista kaikki tyylit päivityksien varalta",
"description": "Label for the button to check all styles for updates"
},
"issuesHelp": {
"message": "The issues found by <a href='https://github.com/CSSLint/csslint' target='_blank'>CSSLint</a> with these rules enabled:",
"description": "Help popup message for the CSSLint issues block on the style edit page"
},
"confirmNo": {
"message": "No",
"description": "'No' button in a confirm dialog"
},
"undo": {
"message": "Undo",
"description": "Button label"
},
"cm_keyMap": {
"message": "Keymap",
"description": "Label for the drop-down list controlling the keymap for the style editor."
},
"cm_indentWithTabs": {
"message": "Use tabs with smart indentation",
"description": "Label for the checkbox controlling tabs with smart indentation option for the style editor."
},
"replaceWith": {
"message": "Replace with",
"description": "Label before the replace-with input field in the editor shown on Ctrl-H etc."
},
"deleteStyleLabel": {
"message": "Poista",
"description": "Label for the button to delete a style"
},
"addStyleLabel": {
"message": "Uusi Tyyli",
"description": "Label for the button to go to the add style page"
},
"manageOnlyEnabled": {
"message": "Only enabled styles",
"description": "Checkbox to show only enabled styles"
},
"editStyleLabel": {
"message": "Muokkaa",
"description": "Label for the button to go to the edit style page"
},
"cm_theme": {
"message": "Theme",
"description": "Label for the style editor's CSS theme."
},
"helpKeyMapCommand": {
"message": "Type a command name",
"description": "Placeholder text of inputbox in keymap help popup on the edit style page. Must be very short"
},
"description": {
"message": "Uudelleen stailaa netti Stylusillä, käyttäjän tyyli hallintapaneelilla. Stylus antaa sinun helposti asentaa teemoja ja skinejä palvelluille kuten Google, Facebook, YouTube, Orkut, ja monelle, monelle muulle sivustolle.",
"description": "Extension description"
}
"addStyleLabel": {
"message": "Uusi Tyyli"
},
"addStyleTitle": {
"message": "Lisää Tyyli"
},
"appliesAdd": {
"message": "Lisää"
},
"appliesDisplay": {
"message": "Kooskee: $applies$",
"placeholders": {
"applies": {
"content": "$1"
}
}
},
"appliesDisplayTruncatedSuffix": {
"message": "ja lisää"
},
"appliesDomainOption": {
"message": "URL ositteita domainilla"
},
"appliesHelp": {
"message": "Käytä 'Koskee' kontrolleja rajoittaaksesi mitä URL osoitteisiin tämä osio koodista koskee."
},
"appliesLabel": {
"message": "Koskee"
},
"appliesRegexpOption": {
"message": "URL ositteet jotka vastaavat regexpiä"
},
"appliesRemove": {
"message": "Poista"
},
"appliesSpecify": {
"message": "Tarkenna"
},
"appliesToEverything": {
"message": "Kaikki"
},
"appliesUrlPrefixOption": {
"message": "URL osoitteet jotka alkavat"
},
"checkAllUpdates": {
"message": "Tarkista kaikki tyylit päivityksien varalta"
},
"checkForUpdate": {
"message": "Hae päivityksiä"
},
"checkingForUpdate": {
"message": "Tarkistetaan..."
},
"confirmDelete": {
"message": "Poista"
},
"confirmSave": {
"message": "Tallenna"
},
"deleteStyleConfirm": {
"message": "Oletko varma että haluat poistaa tämän tyylin?"
},
"deleteStyleLabel": {
"message": "Poista"
},
"description": {
"message": "Uudelleen stailaa netti Stylusillä, käyttäjän tyyli hallintapaneelilla. Stylus antaa sinun helposti asentaa teemoja ja skinejä palvelluille kuten Google, Facebook, YouTube, Orkut, ja monelle, monelle muulle sivustolle."
},
"disableStyleLabel": {
"message": "Poista Käytöstä"
},
"editDeleteText": {
"message": "Poista"
},
"editStyleHeading": {
"message": "Muokkaa Tyyliä"
},
"editStyleLabel": {
"message": "Muokkaa"
},
"editStyleTitle": {
"message": "Muokkaa Tyyliä $stylename$",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"enableStyleLabel": {
"message": "Aktivoi"
},
"genericAdd": {
"message": "Lisää"
},
"genericEnabledLabel": {
"message": "Aktivoitu"
},
"helpAlt": {
"message": "Apu"
},
"installUpdate": {
"message": "Asenna päivitys"
},
"manageHeading": {
"message": "Asennetut Tyylit"
},
"manageTitle": {
"message": "Tyylikäs"
},
"noStylesForSite": {
"message": "Ei asennettuja tyylejä tällä sivustolla."
},
"openManage": {
"message": "Hallitse asennettuja tyylejä"
},
"popupStylesFirst": {
"message": "List styles before commands in the toolbar button menu"
},
"prefShowBadge": {
"message": "Show number of styles active for the current site on the toolbar button"
},
"sectionAdd": {
"message": "Lisää uusi osio"
},
"sectionCode": {
"message": "Koodi"
},
"sectionRemove": {
"message": "Poista osio"
},
"sections": {
"message": "Osiot"
},
"styleBadRegexp": {
"message": "Regexp ei kelpaa."
},
"styleCancelEditLabel": {
"message": "Takaisin hallintapaneeliin"
},
"styleChangesNotSaved": {
"message": "Olet tehnyt muutoksia tähän tyyliin tallentamatta."
},
"styleEnabledLabel": {
"message": "Aktivoitu"
},
"styleInstall": {
"message": "Asennetaanko '$stylename$' Stylusiin?",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"styleMissingName": {
"message": "Syötä nimi"
},
"styleSaveLabel": {
"message": "Tallenna"
},
"styleToMozillaFormatHelp": {
"message": "Mozilla formaattia koodista voidaan käyttää Stylish Firefoxille ohjelmassa ja voidaan lähettää userstyles.orgiin."
},
"updateAllCheckSucceededNoUpdate": {
"message": "All styles are up to date."
},
"updateCheckFailBadResponseCode": {
"message": "Päivitys epäonnistui: palvelin vastasi koodilla $code$.",
"placeholders": {
"code": {
"content": "$1"
}
}
},
"updateCheckFailServerUnreachable": {
"message": "Päivitys epäonnistui: ei voitu yhdistää palvelimeen."
},
"updateCheckSucceededNoUpdate": {
"message": "Tyyli on ajan tasalla."
},
"updateCompleted": {
"message": "Päivitys suoritettu."
}
}

File diff suppressed because it is too large Load Diff

97
_locales/fy/messages.json Normal file
View File

@ -0,0 +1,97 @@
{
"addStyleLabel": {
"message": "Nije styl skriuwe"
},
"addStyleTitle": {
"message": "Styl tafoegje"
},
"appliesAdd": {
"message": "Tafoegje"
},
"appliesDisplay": {
"message": "Fan tapassing op: $applies$",
"placeholders": {
"applies": {
"content": "$1"
}
}
},
"appliesDisplayTruncatedSuffix": {
"message": "en mear"
},
"appliesDomainOption": {
"message": "URLs op it domein"
},
"appliesHelp": {
"message": "Brûk de Fan tapassing op-funksjes om de URLs foar de koade yn dizze seksje te beheinen."
},
"appliesLabel": {
"message": "Fan tapassing op"
},
"appliesRegexpOption": {
"message": "URLs oerienkommend mei de regexp"
},
"appliesRemove": {
"message": "Fuortsmite"
},
"appliesSpecify": {
"message": "Spesifisearje"
},
"appliesToEverything": {
"message": "Alles"
},
"appliesUrlPrefixOption": {
"message": "URLs begjinnend mei"
},
"applyAllUpdates": {
"message": "Alle fernijingen tapasse"
},
"checkAllUpdates": {
"message": "Alle stilen kontrolearje op fernijingen"
},
"checkForUpdate": {
"message": "Kontrolearje op fernijing"
},
"checkingForUpdate": {
"message": "Kontrolearje..."
},
"cm_indentWithTabs": {
"message": "Ljepblêden mei tûke ynspringing brûke"
},
"cm_keyMap": {
"message": "Toetseboerdyndieling"
},
"cm_lineWrapping": {
"message": "Teksttebekrin"
},
"cm_smartIndent": {
"message": "Tûke ynspringing brûke"
},
"cm_tabSize": {
"message": "Ljepblêdgrutte"
},
"cm_theme": {
"message": "Tema"
},
"confirmNo": {
"message": "Nee"
},
"confirmStop": {
"message": "Stoppe"
},
"confirmYes": {
"message": "Ja"
},
"dbError": {
"message": "Der is in flater bard by it brûken fan de Stylus-database. Wolle jo in webside mei mooglike oplossingen besykje?"
},
"defaultTheme": {
"message": "standert"
},
"deleteStyleConfirm": {
"message": "Binne jo wis dat jo dizze styl fuortsmite wolle?"
},
"deleteStyleLabel": {
"message": "Fuortsmite"
}
}

52
_locales/gl/messages.json Normal file
View File

@ -0,0 +1,52 @@
{
"addStyleTitle": {
"message": "Engadir Estilo"
},
"alphaChannel": {
"message": "Opacidade"
},
"appliesAdd": {
"message": "Engadir"
},
"appliesDisplay": {
"message": "Aplica a: $applies$",
"placeholders": {
"applies": {
"content": "$1"
}
}
},
"appliesDisplayTruncatedSuffix": {
"message": "e mais"
},
"appliesDomainOption": {
"message": "URLs no dominio"
},
"appliesLabel": {
"message": "Aplica para"
},
"appliesLineWidgetWarning": {
"message": "Non funciona con CSS minificado"
},
"appliesRegexpOption": {
"message": "URLs que concorden co regexp"
},
"appliesRemove": {
"message": "Suprimir"
},
"appliesSpecify": {
"message": "Especificar"
},
"appliesToEverything": {
"message": "Todo"
},
"appliesUrlPrefixOption": {
"message": "URLs que comecen por"
},
"applyAllUpdates": {
"message": "Aplicar tódalas actualizacións"
},
"author": {
"message": "Autor"
}
}

1040
_locales/he/messages.json Normal file

File diff suppressed because it is too large Load Diff

1222
_locales/hu/messages.json Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1356
_locales/ko/messages.json Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1536
_locales/pl/messages.json Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1088
_locales/pt_PT/messages.json Normal file

File diff suppressed because it is too large Load Diff

860
_locales/ro/messages.json Normal file
View File

@ -0,0 +1,860 @@
{
"addStyleLabel": {
"message": "Scrieți o temă nouă"
},
"addStyleTitle": {
"message": "Adăugați o temă"
},
"alphaChannel": {
"message": "Opacitate"
},
"appliesAdd": {
"message": "Adăugați"
},
"appliesDisplay": {
"message": "Aplicabil pentru: $applies$",
"placeholders": {
"applies": {
"content": "$1"
}
}
},
"appliesDisplayTruncatedSuffix": {
"message": "mai mult"
},
"appliesDomainOption": {
"message": "URLs din domain"
},
"appliesHelp": {
"message": "Folosiți 'Aplicabil pentru' pentru a limita pe ce URLs va fi aplicată temă."
},
"appliesLabel": {
"message": "Aplicabil pentru"
},
"appliesLineWidgetLabel": {
"message": "Arată informații despre 'Aplicabil pentru'"
},
"appliesLineWidgetWarning": {
"message": "Nu funcționează cu CSS minimizat"
},
"appliesRegexpOption": {
"message": "URLs găsite cu regexp"
},
"appliesRemove": {
"message": "Ștergeți"
},
"appliesRemoveError": {
"message": "Nu se poate șterge 'aplicabil pentru'"
},
"appliesSpecify": {
"message": "Specificați"
},
"appliesToEverything": {
"message": "Totul"
},
"appliesUrlPrefixOption": {
"message": "URL-uri începănd cu"
},
"applyAllUpdates": {
"message": "Aplicați toate update-urile"
},
"author": {
"message": "Autor"
},
"bckpInstStyles": {
"message": "Exportați teme"
},
"checkAllUpdates": {
"message": "Verificați toate temele pentru update-uri"
},
"checkAllUpdatesForce": {
"message": "Verifică iar, nu am modificat temele!"
},
"checkForUpdate": {
"message": "Verificați pentru update-uri"
},
"checkingForUpdate": {
"message": "Verficare..."
},
"clickToUninstall": {
"message": "Click pentru dezinstalare"
},
"cm_autoCloseBrackets": {
"message": "Închideți automat parantezele și ghilimelele"
},
"cm_autoCloseBracketsTooltip": {
"message": "Închideți automat când deschizideți una dintre ()[]{}''\"\""
},
"cm_autocompleteOnTyping": {
"message": "Autocompletare în timpul scrierii"
},
"cm_colorpicker": {
"message": "Alegere de culori pentru CSS"
},
"cm_indentWithTabs": {
"message": "Folosiți tab-uri cu autoindentare"
},
"cm_matchHighlightSelection": {
"message": "Doar selecție"
},
"cm_matchHighlightToken": {
"message": "Token-ul de sub cursor"
},
"cm_resizeGripHint": {
"message": "Dublu click pentru a maximiza sau restaura înălțimea"
},
"cm_selectByTokens": {
"message": "Dublu-click pentru a selecta simbolurile"
},
"cm_selectByTokensTooltip": {
"message": "Exemple de simboluri: .foo-bar-2 #aabbcc 0.32 !important\nCand inactiv: cuvinte delimitate cu punctuatie sunt selectate."
},
"cm_smartIndent": {
"message": "Folosiți indentare inteligentă"
},
"cm_tabSize": {
"message": "Mărimea tab-urilor"
},
"cm_theme": {
"message": "Temă pentru cod"
},
"colorpickerSwitchFormatTooltip": {
"message": "Schimbați formatul: HEX -> RGB -> HSL.\nShift-click pentru inversarea direcției.\nDe asemenea cu PgUp (PageUp), PgDn (PageDown)."
},
"colorpickerTooltip": {
"message": "Deschideți color picker"
},
"configOnChange": {
"message": "la schimbare"
},
"configOnChangeTooltip": {
"message": "Autosalvare și aplicare a modificărilor automată"
},
"configureStyle": {
"message": "Modificați"
},
"configureStyleOnHomepage": {
"message": "Modificați pe pagina homepage"
},
"confirmDefault": {
"message": "Folosiți default"
},
"confirmDelete": {
"message": "Ștergeți"
},
"confirmDiscardChanges": {
"message": "Pierdeți modificările?"
},
"confirmNo": {
"message": "Nu"
},
"confirmSave": {
"message": "Salvați"
},
"confirmYes": {
"message": "Da"
},
"dateInstalled": {
"message": "Data instalării"
},
"dateUpdated": {
"message": "Data updatării"
},
"dbError": {
"message": "O eroare în baza de date a apărut. Doriți să vizitați pagina web pentru o soluție?"
},
"deleteStyleConfirm": {
"message": "Sunteți sigur că doriți să ștergeți această temă?"
},
"deleteStyleLabel": {
"message": "Ștergeți"
},
"description": {
"message": "Stilizați internetul cu Stylus, un manager de teme. Stylus vă permite să instalați cu ușurință teme pentru multe site-uri populare."
},
"disableAllStyles": {
"message": "Dezactivați toate temele"
},
"disableStyleLabel": {
"message": "Dezactivați"
},
"dragDropMessage": {
"message": "Drag and drop backup-ul oriunde pentru import."
},
"editDeleteText": {
"message": "Ștergeți"
},
"editGotoLine": {
"message": "Mergeți la linia"
},
"editStyleHeading": {
"message": "Modificați tema"
},
"editStyleLabel": {
"message": "Modificați"
},
"editStyleTitle": {
"message": "Modificați tema $stylename$",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"enableStyleLabel": {
"message": "Activați"
},
"externalLink": {
"message": "Link extern"
},
"externalSupport": {
"message": "Suport"
},
"externalUsercssDocument": {
"message": "Documentație pentru Usercss"
},
"filteredStyles": {
"message": "$numShown$ vizualizabile din $numTotal$ ",
"placeholders": {
"numShown": {
"content": "$1"
},
"numTotal": {
"content": "$2"
}
}
},
"filteredStylesAllHidden": {
"message": "Filtrele aplicate nu au găsit nicio temă"
},
"findStyles": {
"message": "Găsiți teme"
},
"genericAdd": {
"message": "Adaugă"
},
"genericClone": {
"message": "Clonează"
},
"genericDisabledLabel": {
"message": "Dezactivat"
},
"genericEnabledLabel": {
"message": "Activat"
},
"genericError": {
"message": "Eroare"
},
"genericHistoryLabel": {
"message": "Historic"
},
"genericNext": {
"message": "Următor"
},
"genericPrevious": {
"message": "Precedent"
},
"genericResetLabel": {
"message": "Resetați"
},
"genericSavedMessage": {
"message": "Salvat"
},
"genericTitle": {
"message": "Titlu"
},
"genericUnknown": {
"message": "Necunoscut"
},
"helpAlt": {
"message": "Ajutor"
},
"helpKeyMapCommand": {
"message": "Tastați un nume de comandă"
},
"helpKeyMapHotkey": {
"message": "Tastați o hotkey"
},
"importAppendLabel": {
"message": "Concatenare la temă"
},
"importAppendTooltip": {
"message": "Concatenați tema importată la cea curentă"
},
"importReplaceLabel": {
"message": "Scrieți peste tema curentă"
},
"importReplaceTooltip": {
"message": "Scrieți peste tema curentă conținutul temei importate"
},
"importReportLegendAdded": {
"message": "adăugat"
},
"importReportLegendIdentical": {
"message": "cele identice au fost sărite"
},
"importReportLegendInvalid": {
"message": "cele invalide au fost ignorate"
},
"importReportLegendUpdatedBoth": {
"message": "meta info și codul au fost updatate"
},
"importReportLegendUpdatedCode": {
"message": "cod updatat"
},
"importReportLegendUpdatedMeta": {
"message": "meta info updatată"
},
"importReportTitle": {
"message": "Importul temelor finalizat"
},
"importReportUnchanged": {
"message": "Nimic nu a fost schimbat."
},
"importReportUndone": {
"message": "temele au fost înlocuite cu variantele precedente"
},
"importReportUndoneTitle": {
"message": "Importarea a fost anulată"
},
"installButton": {
"message": "Instalați tema"
},
"installButtonInstalled": {
"message": "Tema a fost instalată"
},
"installButtonReinstall": {
"message": "Reinstalați tema"
},
"installUpdate": {
"message": "Instalați update-uri"
},
"installUpdateFrom": {
"message": "Tema este updatată de la $url$",
"placeholders": {
"url": {
"content": "$1"
}
}
},
"installUpdateFromLabel": {
"message": "Verificați update-urile"
},
"license": {
"message": "Licență"
},
"linkGetHelp": {
"message": "Găsiți ajutor"
},
"linkGetStyles": {
"message": "Căutați teme"
},
"linkTranslate": {
"message": "Traduce"
},
"linterCSSLintIncompatible": {
"message": "CSSLint nu suportă preprocesorul $preprocessorname$ ",
"placeholders": {
"preprocessorname": {
"content": "$1"
}
}
},
"linterCSSLintSettings": {
"message": "(Setați regula ca: 0 = dezactivat; 1 = avertisment; 2 = eroare)"
},
"linterConfigPopupTitle": {
"message": "Setați $linter$ pentru configurarea regulilor",
"placeholders": {
"linter": {
"content": "$1"
}
}
},
"linterConfigTooltip": {
"message": "Click pentru a configura linter-ul"
},
"linterInvalidConfigError": {
"message": "Nu a fost salvat din cauza acestor setări invalide:"
},
"linterIssues": {
"message": "Probleme"
},
"linterIssuesHelp": {
"message": "Aceste probleme au fost găsite te $link$:",
"placeholders": {
"link": {
"content": "$1"
}
}
},
"linterResetMessage": {
"message": "Pentru a reveni la varianta precedentă, apăsați Ctrl-Z (sau Cmd-Z) în text box"
},
"linterRulesLink": {
"message": "Vizualizați lista completă de reguli"
},
"liveReloadError": {
"message": "A avut loc o eroare în timpul monitorizării acestui fișier"
},
"manageFavicons": {
"message": "Favicons în coloana 'se aplică la'"
},
"manageFaviconsGray": {
"message": "Hașurat"
},
"manageFaviconsHelp": {
"message": "Stylus folosește un serviciu extern https://icons.duckduckgo.com"
},
"manageFilters": {
"message": "Filtre"
},
"manageHeading": {
"message": "Teme instalate"
},
"manageMaxTargets": {
"message": "Numărul obiectelor la care se aplică"
},
"manageNewUI": {
"message": "UI layout pentru mesajele noi"
},
"manageOnlyDisabled": {
"message": "Doar teme dezactivate"
},
"manageOnlyEnabled": {
"message": "Doar temele activate"
},
"manageOnlyExternal": {
"message": "Doar teme externe"
},
"manageOnlyLocal": {
"message": "Doar temele create local"
},
"manageOnlyLocalTooltip": {
"message": "(temele neinstalate prin userstyles.org)"
},
"manageOnlyNonUsercss": {
"message": "Doar teme non-Usercss"
},
"manageOnlyUpdates": {
"message": "Doar cu update-uri sau erori"
},
"manageOnlyUsercss": {
"message": "Doar teme Usercss"
},
"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"
},
"optionsActions": {
"message": "Acțiuni"
},
"optionsAdvanced": {
"message": "Avansat"
},
"optionsAdvancedContextDelete": {
"message": "Adaugați 'Ștergeți' în meniul de click dreapta"
},
"optionsAdvancedExposeIframes": {
"message": "Expuneți iframes via HTML[stylus-iframe]"
},
"optionsAdvancedNewStyleAsUsercss": {
"message": "Scrieți temă nouă în formatul usercss"
},
"optionsBadgeDisabled": {
"message": "Culoare de fundal pentru modul inactiv"
},
"optionsBadgeNormal": {
"message": "Culoare de fundal"
},
"optionsCheck": {
"message": "Updatați temele"
},
"optionsCheckUpdate": {
"message": "Verificați și instalează toate update-urile"
},
"optionsCustomizeBadge": {
"message": "Bulinuța de pe iconița din toolbar"
},
"optionsCustomizeUpdate": {
"message": "Update-uri"
},
"optionsHeading": {
"message": "Opțiuni"
},
"optionsIconDark": {
"message": "Teme întunecate pentru browser"
},
"optionsIconLight": {
"message": "Teme albe pentru browser"
},
"optionsOpen": {
"message": "Deschideți"
},
"optionsOpenManager": {
"message": "Managerul de teme"
},
"optionsPopupWidth": {
"message": "Mărimea ferestrei popup (în pixeli)"
},
"optionsReset": {
"message": "Resetați opțiunile"
},
"optionsResetButton": {
"message": "Resetați opțiunile"
},
"optionsSubheading": {
"message": "Mai multe opțiuni"
},
"optionsUpdateImportNote": {
"message": "Atunci când sunt importate teme din backup-uri din versiuni mai vechi sau din Stylish, verifică upate-urile manual pentru a fi sigur că toate temele sunt la zi."
},
"optionsUpdateInterval": {
"message": "Intervalul de autoupdate în ore (0 pentru dezactivat)"
},
"paginationCurrent": {
"message": "Pagina curentă"
},
"paginationEstimated": {
"message": "Număr estimat de pagini"
},
"paginationNext": {
"message": "Pagina următoare"
},
"paginationPrevious": {
"message": "Pagina precedentă"
},
"paginationTotal": {
"message": "Număr total de pagini"
},
"parseUsercssError": {
"message": "Stylus nu a putut analiza usercss-ul"
},
"popupBorders": {
"message": "Adăugați bordură albă pe margini"
},
"popupBordersTooltip": {
"message": "Folositor pentru teme întunecate in noul Chrome deoarece nu mai colorează bordurile"
},
"popupHotkeysInfo": {
"message": "<1>-<9>, <0>, de asemenea îm numpad - activează/dezactivează tema numărul N (0 este 10)\n<A>-<Z> activează/dezactivează prima temă cu un nume care începe cu o litera\n<Shift> deschide editorul și nu activează/dezactivează ceva\n<Numpad +> activează temele listate\n<Numpad > dezactiveaza temele listate\n<Numpad *> și <`> (backtick) - activează/dezactivează temele activate inițial; nu se aplică altor teme activate când popup-ul este deschid pentru a permite restaurarea seleției inițiale pentru a permite testări; dezactivează tot, apoi activează/dezactivează, spre exemplu<Numpad > <Numpad *>\nMai multe informații sunt avabile în wiki"
},
"popupHotkeysTooltip": {
"message": "Click pentru a vedea hotkeys avabile"
},
"popupManageTooltip": {
"message": "Shift-click sau right-click pentru a deschide managerurl cu teme aplicabile site-ului curent"
},
"popupOpenEditInWindow": {
"message": "Deschide editorul în alt window"
},
"popupOpenEditInWindowTooltip": {
"message": "Activ când tabul editorului este detașat de browser,\nși dezactivat când un singur tab cu editor este atașat la alt window."
},
"popupStylesFirst": {
"message": "Temele înaintea comenzilor"
},
"prefShowBadge": {
"message": "Numărul de teme active pentru site-ul curent"
},
"previewTooltip": {
"message": "Aplică temporar modificările fără a salva.\nSalvează tema pentru a face schimbările permanente."
},
"replace": {
"message": "Înlocuiți"
},
"replaceAll": {
"message": "Înlocuiți tot"
},
"replaceWith": {
"message": "Înlocuiți cu"
},
"retrieveBckp": {
"message": "Importați teme"
},
"search": {
"message": "Căutați"
},
"searchNumberOfResults": {
"message": "Număr de rezultate"
},
"searchNumberOfResults2": {
"message": "Număr de rezultate în cod și în 'aplicabil pentru'"
},
"searchRegexp": {
"message": "Folosiți sintaxă /re/ pentru căutare tip regexp"
},
"searchResultInstallCount": {
"message": "Număr total de instalări"
},
"searchResultNoneFound": {
"message": "Nicio tema găsită pentru acest site."
},
"searchResultUpdated": {
"message": "Updatate"
},
"searchResultWeeklyCount": {
"message": "Instalări săptămânale"
},
"sectionAdd": {
"message": "Adăugați o altă secțiune"
},
"sectionCode": {
"message": "Cod"
},
"sectionRemove": {
"message": "Ștergeți secțiunea"
},
"sectionRestore": {
"message": "Restaurează o secțiune ștearsă"
},
"sections": {
"message": "Secțiuni"
},
"shortcutsNote": {
"message": "Creeați keyboard shortcuts"
},
"sortDateNewestFirst": {
"message": "cele mai noi la început"
},
"sortDateOldestFirst": {
"message": "cel mai vechi la început"
},
"sortLabel": {
"message": "Alegeți o sortare care să fie aplicată temelor instalate"
},
"sortLabelTitleAsc": {
"message": "Titlu crescător"
},
"sortLabelTitleDesc": {
"message": "Titlu descrescător"
},
"sortStylesHelp": {
"message": "Alegeți ce fel de sortare doriți să fie aplicată temelor instalate, din cadrul meniului dropdown. În mod implicit se aplică sortare alfabetică (A la Z) titlurilor temelor. Sortarea de tip \"Titlu descrescător\" va aplica sortare descrescătoare (Z la A) titlurilor.\nSunt alte presets care permit sortări după mai multe criterii. Este ca și cum ați sorta un tabel cu mai multe coloane iar fiecare categorie (între semnele +) reprezintă o coloană, sau un grup..\nSpre exemplu, dacă se alege \"Activată (prima) + Titlu\", atunci toate temele vor fi grupate astfel încât cele active sunt cap de listă, iar apoi temele sunt sortate alfabetic."
},
"sortStylesHelpTitle": {
"message": "Sortare conținut"
},
"styleBadRegexp": {
"message": "Regexp invalid."
},
"styleBeautify": {
"message": "Înfrumusețați"
},
"styleBeautifyIndentConditional": {
"message": "Indentare @media, @supports"
},
"styleBeautifyPreserveNewlines": {
"message": "Menține linii noi"
},
"styleCancelEditLabel": {
"message": "Înapoi la manager"
},
"styleChangesNotSaved": {
"message": "Ați modificat tema fără a o salva."
},
"styleEnabledLabel": {
"message": "Activat"
},
"styleFromMozillaFormatError": {
"message": "Importul din formatul Mozilla eșuat"
},
"styleFromMozillaFormatPrompt": {
"message": "Paste cod în format Mozilla"
},
"styleInstall": {
"message": "Instalați '$stylename$' în Stylus?",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"styleInstallFailed": {
"message": "Instalarea temei eșuată!\n$error$",
"placeholders": {
"error": {
"content": "$1"
}
}
},
"styleInstallOverwrite": {
"message": "'$stylename$' este deja instalată. Scrieți peste?\nVersiune: $oldVersion$ -> $newVersion$",
"placeholders": {
"newVersion": {
"content": "$3"
},
"oldVersion": {
"content": "$2"
},
"stylename": {
"content": "$1"
}
}
},
"styleMissingName": {
"message": "Introduceți un nume"
},
"styleMozillaFormatHeading": {
"message": "Format Mozilla"
},
"styleNotAppliedRegexpProblemTooltip": {
"message": "Tema nu a fost aplicată din cauza incorectei aplicări a 'regexp()'"
},
"styleRegexpInvalidExplanation": {
"message": "Unele reguli 'regexp()' care nu au putut fi compilate."
},
"styleRegexpPartialExplanation": {
"message": "Această temă folosește regexp parțiale care încalcă <a href='https://developer.mozilla.org/docs/Web/CSS/@document'> specificațiile CSS4 @document</a> care are nevoie de o potrivire regexp exactă. Părțile afectate de CSS nu au fost aplicate paginii. Cel mai probabil tema a fost creată în Stylish-for-Chrome care verifică incorect 'regexp()' de la prima sa versiune (bug cunoscut)."
},
"styleRegexpProblemTooltip": {
"message": " Numărul de secțiuni care nu au fost aplicate din cauza utilizării incorecte a 'regexp()'"
},
"styleRegexpTestFull": {
"message": "Taburi găsite"
},
"styleRegexpTestInvalid": {
"message": "Invalid regexps au fost sărite"
},
"styleRegexpTestNone": {
"message": "Niciun tab nu se potrivește căutării"
},
"styleRegexpTestNote": {
"message": "Notă: folosiți \\ pentru ignorarea caracterelor speciale în regexp, care va fi transformat automat în \\\\ în codul temei, urmând specificațiile pentru text citat în CSS."
},
"styleRegexpTestPartial": {
"message": "Potrivire parțială, deci ignorată"
},
"styleRegexpTestTitle": {
"message": "Listă cu taburi deschise care se potrivesc căutării (click URL pentru a activa tabul)"
},
"styleSaveLabel": {
"message": "Salvați"
},
"styleToMozillaFormatHelp": {
"message": "Formatul Mozilla al codului poate fi uploadat pe userstyles.org și folosit de clasicul Stylish pentru Firefox."
},
"styleToMozillaFormatTitle": {
"message": "Scrieți în format Mozilla"
},
"styleUpdate": {
"message": "Sunteți sigur că doriți să faceți update la '$stylename$'?",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"styleUpdateDiscardChanges": {
"message": "Tema a fost modificată în afara editorului. Doriți să reâncărcați tema?"
},
"stylusUnavailableForURL": {
"message": "Stylus nu funcționează în astfel de pagini."
},
"stylusUnavailableForURLdetails": {
"message": "Ca o măsură de securitate, browser-ul împiedică extensiile să afecteze paginile corespunzătoare browser-ului (precum chrome://version, adresa unui nou tab începând cu Chrome 61, about:addons, în Firefox etc) și de asemenea paginile altor extensii. De asemenea este restricționat accesul la galeriile de extensii (Chrome Web Store sau AMO)."
},
"syncStorageErrorSaving": {
"message": "Valoarea nu a putut fi salvată. Încercați să reduceți dimensiunea textului."
},
"toggleStyle": {
"message": "Activați/Dezactivați tema"
},
"undoGlobal": {
"message": "Undo în toate secțiunile"
},
"unreachableAMO": {
"message": "Firefox împiedică accesul la site."
},
"unreachableAMOHint": {
"message": "Pentru a permite accesul deschideți <about:config>, right-click pe listă, click 'New', apoi 'Boolean', paste <privacy.resistFingerprinting.block_mozAddonManager> și click OK, <true>, OK, reâncărcați pagina <addons.mozilla.org>."
},
"unreachableContentScript": {
"message": "Nu s-a putut comunica cu pagina. Reîncărcați tabul."
},
"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."
},
"updateAllCheckSucceededSomeEdited": {
"message": "Unele teme care au update-uri nu au fost updatate pentru a nu pierde modificări locale. Update-urile pot fi forțate individual sau prin a reverifica update-urile pentru toate temele (modificările locale vor fi pierdute)."
},
"updateCheckFailBadResponseCode": {
"message": "Update eșuat: server-ul a răspuns cu acest cod $code$.",
"placeholders": {
"code": {
"content": "$1"
}
}
},
"updateCheckFailServerUnreachable": {
"message": "Update eșuat: server-ul nu este avabil."
},
"updateCheckHistory": {
"message": "Historicul update-urilor"
},
"updateCheckManualUpdateForce": {
"message": "Instalați update-urile (modificările locale vor fi șterse)"
},
"updateCheckManualUpdateHint": {
"message": "Update-ul forțat va șterge toate modificările locale."
},
"updateCheckSkippedLocallyEdited": {
"message": "Tema a fost editată local."
},
"updateCheckSkippedMaybeLocallyEdited": {
"message": "Tema poate a fost modificată local."
},
"updateCheckSucceededNoUpdate": {
"message": "Tema este cu update-urile la zi."
},
"updateCompleted": {
"message": "Update realizat."
},
"updatesCurrentlyInstalled": {
"message": "Update-uri instalate:"
},
"usercssAvoidOverwriting": {
"message": "Vă rugăm să modificați valoarea @name și @namespace pentru a împiedica scrierea peste o temă existentă."
},
"usercssConfigIncomplete": {
"message": "Tema a fost updatată sau ștearsă după ce configurațiile au fost afișate. Aceste variabile nu au fost salvate pentru a nu corupe metadata temei."
},
"usercssEditorNamePlaceholder": {
"message": "Specificați @name"
},
"usercssReplaceTemplateConfirmation": {
"message": "Înlocuiți tema de bază a formatului Usercss cu acest cod?"
},
"usercssReplaceTemplateSectionBody": {
"message": "Introduce cod aici..."
},
"versionInvalidOlder": {
"message": "Versiunea este mai veche decât cea instalată."
},
"writeStyleFor": {
"message": "Scrieți temă pentru: "
},
"writeStyleForURL": {
"message": "acest URL"
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,421 +1,335 @@
{
"appliesToEverything": {
"message": "Све",
"description": "Text displayed for styles that apply to all sites"
},
"defaultTheme": {
"message": "подразумевано",
"description": "Default CodeMirror CSS theme option on the edit style page"
},
"exportLabel": {
"message": "Извези",
"description": "Label for the button to export a style ('edit' page) or all styles ('manage' page)"
},
"issues": {
"message": "Проблеми",
"description": "Label for the CSSLint issues block on the style edit page"
},
"cm_tabSize": {
"message": "Величина картице",
"description": "Label for the text box controlling tab size option for the style editor."
},
"enableStyleLabel": {
"message": "Омогући",
"description": "Label for the button to enable a style"
},
"styleMissingName": {
"message": "Унесите назив",
"description": "Error displayed when user saves without providing a name"
},
"appliesDomainOption": {
"message": "УРЛ адресе на домену",
"description": "Option to make the style apply to the entered string as a domain"
},
"checkForUpdate": {
"message": "Проверите ажурирање",
"description": "Label for the button to check a single style for an update"
},
"importAppendLabel": {
"message": "Додај стилу",
"description": "Label for the button to import a style and append to the existing sections"
},
"updateAllCheckSucceededNoUpdate": {
"message": "Сви стилови су ажурирани.",
"description": "Text that displays when an update all check completed and no updates are available"
},
"styleFromMozillaFormatPrompt": {
"message": "Налепи код у Mozilla формату",
"description": "Prompt in the dialog displayed after clicking 'Import from Mozilla format' button"
},
"helpAlt": {
"message": "Помоћ",
"description": "Alternate text for help buttons"
},
"search": {
"message": "Претражи",
"description": "Label before the search input field in the editor shown on Ctrl-F"
},
"confirmYes": {
"message": "Да",
"description": "'Yes' button in a confirm dialog"
},
"findStylesForSite": {
"message": "Пронађи још стилова за овај сајт.",
"description": "Text for a link that gets a list of styles for the current site"
},
"manageHeading": {
"message": "Инсталирани стилови",
"description": "Heading for the manage page"
},
"styleBeautify": {
"message": " Улепшај",
"description": "Label for the CSS-beautifier button on the edit style page"
},
"styleEnabledLabel": {
"message": "Омогућено",
"description": "Label for the enabled state of styles"
},
"styleToMozillaFormatHelp": {
"message": "Mozilla формат кода се може користити у Stylish за Firefox и може се послати на userstyles.org.",
"description": "Help info for the Mozilla format header section that converts the code to/from Mozilla format"
},
"sectionAdd": {
"message": "Додај нови одељак",
"description": "Label for the button to add a section"
},
"styleSaveLabel": {
"message": "Сачувај",
"description": "Label for save button for style editing"
},
"confirmStop": {
"message": "Заустави",
"description": "'Stop' button in a confirm dialog"
},
"writeStyleForURL": {
"message": "ову УРЛ адресу",
"description": "Text for link in toolbar pop-up to write a new style for the current URL"
},
"appliesAdd": {
"message": "Додај",
"description": "Label for the button to add an 'applies' entry"
},
"appliesRegexpOption": {
"message": "УРЛ адресе које одговарају регуларном изразу",
"description": "Option to make the style apply to the entered string as a regular expression"
},
"styleInstall": {
"message": "Инсталирати '$stylename$' у Stylus?",
"description": "Confirmation when installing a style",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"manageText": {
"message": "<a href='https://userstyles.org'>Преузмите стилове са userstyles.org</a> | <a href='http://add0n.com/stylus.html'>Помоћ</a>",
"description": "Help text on the manage page"
},
"searchStyles": {
"message": "Претражи садржај",
"description": "Label for the search filter textbox on the Manage styles page"
},
"disableStyleLabel": {
"message": "Онемогући",
"description": "Label for the button to disable a style"
},
"prefShowBadge": {
"message": "Прикажи број активних стилова за тренутни сајт на дугмету на алатној траци",
"description": "Label for the checkbox controlling toolbar badge text."
},
"menuShowBadge": {
"message": "Прикажи број активних стилова",
"description": "Label (must be very short) for the checkbox in the toolbar button context menu controlling toolbar badge text."
},
"cm_lineWrapping": {
"message": "Преламање текста",
"description": "Label for the checkbox controlling word wrap option for the style editor."
},
"styleCancelEditLabel": {
"message": "Назад на управљање",
"description": "Label for cancel button for style editing"
},
"styleChangesNotSaved": {
"message": "Направили сте измене овог стила које нисте сачували.",
"description": "Text for the prompt when changes are made to a style and the user tries to leave without saving"
},
"importLabel": {
"message": "Увези",
"description": "Label for the button to import a style ('edit' page) or all styles ('manage' page)"
},
"updateCheckFailServerUnreachable": {
"message": "Ажурирање није успело - сервер није доступан.",
"description": "Text that displays when an update check failed because the update server is unreachable"
},
"manageFilters": {
"message": "Филтери",
"description": "Label for filters container"
},
"applyAllUpdates": {
"message": "Примени сва ажурирања",
"description": "Label for the button to apply all detected updates"
},
"deleteStyleConfirm": {
"message": "Да ли сте сигурни да желите да избришете овај стил?",
"description": "Confirmation before deleting a style"
},
"confirmDelete": {
"message": "Delete"
},
"confirmCancel": {
"message": "Cancel"
},
"styleBadRegexp": {
"message": "Регуларни израз је неисправан.",
"description": "Validation message for a bad regexp in a style"
},
"optionsHeading": {
"message": "Опције",
"description": "Heading for options section on manage page."
},
"appliesDisplay": {
"message": "Примењује се на: $applies$",
"description": "Text on the manage screen to describe what the style applies to",
"placeholders": {
"applies": {
"content": "$1"
}
}
},
"styleUpdate": {
"message": "Да ли сте сигурни да желите да ажурирате '$stylename$'?",
"description": "Confirmation when updating a style",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"styleSectionsTitle": {
"message": "Одељци",
"description": "Title for the style sections section"
},
"editStyleTitle": {
"message": "Уреди стил $stylename$",
"description": "Title of the page for editing styles",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"updateCheckSucceededNoUpdate": {
"message": "Стил је ажуриран.",
"description": "Text that displays when an update check completed and no update is available"
},
"appliesUrlPrefixOption": {
"message": "УРЛ адресе које почињу са",
"description": "Option to make the style apply to the entered string as a URL prefix"
},
"searchRegexp": {
"message": "Користи /re/ синтаксу за претрагу регуларним изразом",
"description": "Label after the search input field in the editor shown on Ctrl-F"
},
"importReplaceTooltip": {
"message": "Одбаци садржај тренутног стила и упиши преко њега увезени стил",
"description": "Label for the button to import and overwrite current style"
},
"popupStylesFirst": {
"message": "Излистај стилове пре команди у менију дугмета на алатној траци",
"description": "Label for the checkbox controlling section order in the toolbar button menu."
},
"sectionHelp": {
"message": "Одељци вам омогућавају да дефинишете различите делове кода који се примењују на раличите скупове УРЛ-ова у истом стилу. На пример, један исти стил може променити почетну страницу једног сајта на један начин а остатак сајта на други начин.",
"description": "Help text for sections"
},
"noStylesForSite": {
"message": "Нема инсталираних стилова за овај сајт.",
"description": "Text displayed when no styles are installed for the current site"
},
"appliesDisplayTruncatedSuffix": {
"message": "и још",
"description": "Text added to appliesDisplay when there are more sites for the style than are displayed"
},
"appliesRemove": {
"message": "Уклони",
"description": "Label for the button to remove an 'applies' entry"
},
"styleToMozillaFormatTitle": {
"message": "Стил у Mozilla формату",
"description": "Title of the popup with the style code in Mozilla format, shown after pressing the Export button on Edit style page"
},
"manageTitle": {
"message": "Stylus",
"description": "Title for the manage page"
},
"writeStyleFor": {
"message": "Упиши стил за:",
"description": "Label for toolbar pop-up that precedes the links to write a new style"
},
"replace": {
"message": "Замени",
"description": "Label before the replace input field in the editor shown on Ctrl-H"
},
"appliesLabel": {
"message": "Примењује се на",
"description": "Label for 'applies to' fields on the edit/add screen"
},
"openManage": {
"message": "Управљај инсталираним стиловима",
"description": "Link to open the manage page."
},
"updateCheckFailBadResponseCode": {
"message": "Ажурирање није успело - сервер је одговорио кодом $code$.",
"description": "Text that displays when an update check failed because the response code indicates an error",
"placeholders": {
"code": {
"content": "$1"
}
}
},
"appliesSpecify": {
"message": "Детаљније",
"description": "Label for the button to make a style apply only to specific sites"
},
"installUpdate": {
"message": "Инсталирај ажурирање",
"description": "Label for the button to install an update for a single style"
},
"styleMozillaFormatHeading": {
"message": "Mozilla формат",
"description": "Heading for the section with buttons to import/export Mozilla format of the style"
},
"stylusUnavailableForURL": {
"message": "Stylus не ради на страницама као што је ова.",
"description": "Note in the toolbar pop-up when on a URL Stylus can't affect"
},
"sectionRemove": {
"message": "Уклони одељак",
"description": "Label for the button to remove a section"
},
"disableAllStyles": {
"message": "Искључи све стилове",
"description": "Label for the checkbox that turns all enabled styles off."
},
"undoGlobal": {
"message": "Опозови (свеобухватно)",
"description": "CSS-beautify global Undo button label"
},
"updateCompleted": {
"message": "Ажурирање је комплетирано.",
"description": "Text that displays when an update completed"
},
"checkingForUpdate": {
"message": "Проверавање...",
"description": "Text to display when checking a style for an update"
},
"sectionCode": {
"message": "Код",
"description": "Label for the code for a section"
},
"cm_smartIndent": {
"message": "Користи паметно увлачење редова",
"description": "Label for the checkbox controlling smart indentation option for the style editor."
},
"appliesHelp": {
"message": "Употреба 'Примењује се на' одређује опсег УРЛ адреса на које се код у овом одељку примењује.",
"description": "Help text for 'applies to' section"
},
"editStyleHeading": {
"message": "Уреди стил",
"description": "Title of the page for editing styles"
},
"appliesUrlOption": {
"message": "УРЛ",
"description": "Option to make the style apply to the entered string as a URL"
},
"addStyleTitle": {
"message": "Додај стил",
"description": "Title of the page for adding styles"
},
"importReplaceLabel": {
"message": "Упиши преко стила",
"description": "Label for the button to import and overwrite current style"
},
"dbError": {
"message": "Дошло је до грешке користећи Stylus базу података. Да ли желите да посетите веб страницу са могућим решењима?",
"description": "Prompt when a DB error is encountered"
},
"importAppendTooltip": {
"message": "Додај увезени стил тренутном стилу",
"description": "Tooltip for the button to import a style and append to the existing sections"
},
"helpKeyMapHotkey": {
"message": "Притисни пречицу",
"description": "Placeholder text of inputbox in keymap help popup on the edit style page. Must be very short"
},
"replaceAll": {
"message": "Замени све",
"description": "Label before the replace input field in the editor shown on 'replaceAll' hotkey"
},
"editGotoLine": {
"message": "Иди на ред (или line:col)",
"description": "Go to line or line:column on Ctrl-G in style code editor"
},
"checkAllUpdates": {
"message": "Проверите ажурирања за све стилове",
"description": "Label for the button to check all styles for updates"
},
"issuesHelp": {
"message": "Проблем пронађен од стране <a href='https://github.com/CSSLint/csslint' target='_blank'>CSSLint</a> са овим омогућеним правилима:",
"description": "Help popup message for the CSSLint issues block on the style edit page"
},
"confirmNo": {
"message": "Не",
"description": "'No' button in a confirm dialog"
},
"undo": {
"message": "Опозови",
"description": "Button label"
},
"cm_keyMap": {
"message": "Мапа тастера",
"description": "Label for the drop-down list controlling the keymap for the style editor."
},
"cm_indentWithTabs": {
"message": "Користи картице са паметним увлачењем редова",
"description": "Label for the checkbox controlling tabs with smart indentation option for the style editor."
},
"replaceWith": {
"message": "Замени са",
"description": "Label before the replace-with input field in the editor shown on Ctrl-H etc."
},
"deleteStyleLabel": {
"message": "Избриши",
"description": "Label for the button to delete a style"
},
"addStyleLabel": {
"message": "Упиши нови стил",
"description": "Label for the button to go to the add style page"
},
"manageOnlyEnabled": {
"message": "Само омогућени стилови",
"description": "Checkbox to show only enabled styles"
},
"editStyleLabel": {
"message": "Уреди",
"description": "Label for the button to go to the edit style page"
},
"cm_theme": {
"message": "Тема",
"description": "Label for the style editor's CSS theme."
},
"helpKeyMapCommand": {
"message": "Укуцај име команде",
"description": "Placeholder text of inputbox in keymap help popup on the edit style page. Must be very short"
},
"description": {
"message": "Измените стил интернет мреже управљачем корисничких стилова. Stylus вам омогућава да лако инсталирате теме и скинове за многе популарне сајтове.",
"description": "Extension description"
}
}
{
"addStyleLabel": {
"message": "Упиши нови стил"
},
"addStyleTitle": {
"message": "Додај стил"
},
"appliesAdd": {
"message": "Додај"
},
"appliesDisplay": {
"message": "Примењује се на: $applies$",
"placeholders": {
"applies": {
"content": "$1"
}
}
},
"appliesDisplayTruncatedSuffix": {
"message": "и још"
},
"appliesDomainOption": {
"message": "УРЛ адресе на домену"
},
"appliesHelp": {
"message": "Употреба 'Примењује се на' одређује опсег УРЛ адреса на које се код у овом одељку примењује."
},
"appliesLabel": {
"message": "Примењује се на"
},
"appliesRegexpOption": {
"message": "УРЛ адресе које одговарају регуларном изразу"
},
"appliesRemove": {
"message": "Уклони"
},
"appliesSpecify": {
"message": "Детаљније"
},
"appliesToEverything": {
"message": "Све"
},
"appliesUrlOption": {
"message": "УРЛ"
},
"appliesUrlPrefixOption": {
"message": "УРЛ адресе које почињу са"
},
"applyAllUpdates": {
"message": "Примени сва ажурирања"
},
"checkAllUpdates": {
"message": "Проверите ажурирања за све стилове"
},
"checkForUpdate": {
"message": "Проверите ажурирање"
},
"checkingForUpdate": {
"message": "Проверавање..."
},
"cm_indentWithTabs": {
"message": "Користи картице са паметним увлачењем редова"
},
"cm_keyMap": {
"message": "Мапа тастера"
},
"cm_lineWrapping": {
"message": "Преламање текста"
},
"cm_smartIndent": {
"message": "Користи паметно увлачење редова"
},
"cm_tabSize": {
"message": "Величина картице"
},
"cm_theme": {
"message": "Тема"
},
"confirmDelete": {
"message": "Избриши"
},
"confirmNo": {
"message": "Не"
},
"confirmSave": {
"message": "Сачувај"
},
"confirmStop": {
"message": "Заустави"
},
"confirmYes": {
"message": "Да"
},
"dbError": {
"message": "Дошло је до грешке користећи Stylus базу података. Да ли желите да посетите веб страницу са могућим решењима?"
},
"defaultTheme": {
"message": "подразумевано"
},
"deleteStyleConfirm": {
"message": "Да ли сте сигурни да желите да избришете овај стил?"
},
"deleteStyleLabel": {
"message": "Избриши"
},
"description": {
"message": "Измените стил интернет мреже управљачем корисничких стилова. Stylus вам омогућава да лако инсталирате теме и скинове за многе популарне сајтове."
},
"disableAllStyles": {
"message": "Искључи све стилове"
},
"disableStyleLabel": {
"message": "Онемогући"
},
"editDeleteText": {
"message": "Избриши"
},
"editGotoLine": {
"message": "Иди на ред (или line:col)"
},
"editStyleHeading": {
"message": "Уреди стил"
},
"editStyleLabel": {
"message": "Уреди"
},
"editStyleTitle": {
"message": "Уреди стил $stylename$",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"enableStyleLabel": {
"message": "Омогући"
},
"exportLabel": {
"message": "Извези"
},
"genericAdd": {
"message": "Додај"
},
"genericEnabledLabel": {
"message": "Омогућено"
},
"helpAlt": {
"message": "Помоћ"
},
"helpKeyMapCommand": {
"message": "Укуцај име команде"
},
"helpKeyMapHotkey": {
"message": "Притисни пречицу"
},
"importAppendLabel": {
"message": "Додај стилу"
},
"importAppendTooltip": {
"message": "Додај увезени стил тренутном стилу"
},
"importLabel": {
"message": "Увези"
},
"importReplaceLabel": {
"message": "Упиши преко стила"
},
"importReplaceTooltip": {
"message": "Одбаци садржај тренутног стила и упиши преко њега увезени стил"
},
"installUpdate": {
"message": "Инсталирај ажурирање"
},
"linkGetHelp": {
"message": "Помоћ"
},
"linkGetStyles": {
"message": "Преузмите стилове"
},
"linterIssues": {
"message": "Проблеми"
},
"linterIssuesHelp": {
"message": "Проблем пронађен од стране $link$:",
"placeholders": {
"link": {
"content": "$1"
}
}
},
"manageFilters": {
"message": "Филтери"
},
"manageHeading": {
"message": "Инсталирани стилови"
},
"manageOnlyEnabled": {
"message": "Само омогућени стилови"
},
"menuShowBadge": {
"message": "Прикажи број активних стилова"
},
"noStylesForSite": {
"message": "Нема инсталираних стилова за овај сајт."
},
"openManage": {
"message": "Управљај инсталираним стиловима"
},
"openOptions": {
"message": "Опције"
},
"optionsHeading": {
"message": "Опције"
},
"optionsSyncUrl": {
"message": "УРЛ"
},
"popupStylesFirst": {
"message": "Излистај стилове пре команди у менију дугмета на алатној траци"
},
"prefShowBadge": {
"message": "Прикажи број активних стилова за тренутни сајт на дугмету на алатној траци"
},
"replace": {
"message": "Замени"
},
"replaceAll": {
"message": "Замени све"
},
"replaceWith": {
"message": "Замени са"
},
"search": {
"message": "Претражи"
},
"searchRegexp": {
"message": "Користи /re/ синтаксу за претрагу регуларним изразом"
},
"sectionAdd": {
"message": "Додај нови одељак"
},
"sectionCode": {
"message": "Код"
},
"sectionRemove": {
"message": "Уклони одељак"
},
"sections": {
"message": "Одељци"
},
"styleBadRegexp": {
"message": "Регуларни израз је неисправан."
},
"styleBeautify": {
"message": "Улепшај"
},
"styleCancelEditLabel": {
"message": "Назад на управљање"
},
"styleChangesNotSaved": {
"message": "Направили сте измене овог стила које нисте сачували."
},
"styleEnabledLabel": {
"message": "Омогућено"
},
"styleFromMozillaFormatPrompt": {
"message": "Налепи код у Mozilla формату"
},
"styleInstall": {
"message": "Инсталирати '$stylename$' у Stylus?",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"styleMissingName": {
"message": "Унесите назив"
},
"styleMozillaFormatHeading": {
"message": "Mozilla формат"
},
"styleSaveLabel": {
"message": "Сачувај"
},
"styleToMozillaFormatHelp": {
"message": "Mozilla формат кода се може користити у Stylish за Firefox и може се послати на userstyles.org."
},
"styleToMozillaFormatTitle": {
"message": "Стил у Mozilla формату"
},
"styleUpdate": {
"message": "Да ли сте сигурни да желите да ажурирате '$stylename$'?",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"stylusUnavailableForURL": {
"message": "Stylus не ради на страницама као што је ова."
},
"undo": {
"message": "Опозови"
},
"undoGlobal": {
"message": "Опозови (свеобухватно)"
},
"updateAllCheckSucceededNoUpdate": {
"message": "Сви стилови су ажурирани."
},
"updateCheckFailBadResponseCode": {
"message": "Ажурирање није успело: сервер је одговорио кодом $code$.",
"placeholders": {
"code": {
"content": "$1"
}
}
},
"updateCheckFailServerUnreachable": {
"message": "Ажурирање није успело: сервер није доступан."
},
"updateCheckSucceededNoUpdate": {
"message": "Стил је ажуриран."
},
"updateCompleted": {
"message": "Ажурирање је комплетирано."
},
"writeStyleFor": {
"message": "Упиши стил за:"
},
"writeStyleForURL": {
"message": "ову УРЛ адресу"
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,421 +0,0 @@
{
"appliesToEverything": {
"message": "Allt",
"description": "Text displayed for styles that apply to all sites"
},
"defaultTheme": {
"message": "default",
"description": "Default CodeMirror CSS theme option on the edit style page"
},
"exportLabel": {
"message": "Export",
"description": "Label for the button to export a style ('edit' page) or all styles ('manage' page)"
},
"issues": {
"message": "Issues",
"description": "Label for the CSSLint issues block on the style edit page"
},
"cm_tabSize": {
"message": "Flikstorlek",
"description": "Label for the text box controlling tab size option for the style editor."
},
"enableStyleLabel": {
"message": "Aktivera",
"description": "Label for the button to enable a style"
},
"styleMissingName": {
"message": "Ange ett namn.",
"description": "Error displayed when user saves without providing a name"
},
"appliesDomainOption": {
"message": "URL:er på domänen",
"description": "Option to make the style apply to the entered string as a domain"
},
"checkForUpdate": {
"message": "Leta efter uppdatering",
"description": "Label for the button to check a single style for an update"
},
"importAppendLabel": {
"message": "Append to style",
"description": "Label for the button to import a style and append to the existing sections"
},
"updateAllCheckSucceededNoUpdate": {
"message": "Alla stilar är fullt uppdaterade.",
"description": "Text that displays when an update all check completed and no updates are available"
},
"styleFromMozillaFormatPrompt": {
"message": "Paste the Mozilla-format code",
"description": "Prompt in the dialog displayed after clicking 'Import from Mozilla format' button"
},
"helpAlt": {
"message": "Hjälp",
"description": "Alternate text for help buttons"
},
"search": {
"message": "Search",
"description": "Label before the search input field in the editor shown on Ctrl-F"
},
"confirmYes": {
"message": "Yes",
"description": "'Yes' button in a confirm dialog"
},
"findStylesForSite": {
"message": "Hitta fler stilar för denna sida.",
"description": "Text for a link that gets a list of styles for the current site"
},
"manageHeading": {
"message": "Installerade Stilar",
"description": "Heading for the manage page"
},
"styleBeautify": {
"message": "Beautify",
"description": "Label for the CSS-beautifier button on the edit style page"
},
"styleEnabledLabel": {
"message": "Aktiverad",
"description": "Label for the enabled state of styles"
},
"styleToMozillaFormatHelp": {
"message": "Mozilla-formatet av koden fungerar i Stylish till Firefox samt vid uppladdandet till userstyles.org.",
"description": "Help info for the Mozilla format header section that converts the code to/from Mozilla format"
},
"sectionAdd": {
"message": "Lägg till ytterligare en sektion",
"description": "Label for the button to add a section"
},
"styleSaveLabel": {
"message": "Spara",
"description": "Label for save button for style editing"
},
"confirmStop": {
"message": "Stop",
"description": "'Stop' button in a confirm dialog"
},
"writeStyleForURL": {
"message": "denna URL",
"description": "Text for link in toolbar pop-up to write a new style for the current URL"
},
"appliesAdd": {
"message": "Lägg till",
"description": "Label for the button to add an 'applies' entry"
},
"appliesRegexpOption": {
"message": "URL:er som matchar regexp:en",
"description": "Option to make the style apply to the entered string as a regular expression"
},
"styleInstall": {
"message": "Installera '$stylename$' in i Stylus?",
"description": "Confirmation when installing a style",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"manageText": {
"message": "<a href='https://userstyles.org'>Get styles on userstyles.org</a> | <a href='http://add0n.com/stylus.html'>Get help</a>",
"description": "Help text on the manage page"
},
"searchStyles": {
"message": "Search contents",
"description": "Label for the search filter textbox on the Manage styles page"
},
"disableStyleLabel": {
"message": "Inaktivera",
"description": "Label for the button to disable a style"
},
"prefShowBadge": {
"message": "Visa antalet aktiva stilar för den nuvarande sidan på verktygsfältsikonen",
"description": "Label for the checkbox controlling toolbar badge text."
},
"menuShowBadge": {
"message": "Visa antalet aktiva stilar",
"description": "Label (must be very short) for the checkbox in the toolbar button context menu controlling toolbar badge text."
},
"cm_lineWrapping": {
"message": "Radbrytning",
"description": "Label for the checkbox controlling word wrap option for the style editor."
},
"styleCancelEditLabel": {
"message": "Återgå till hantera",
"description": "Label for cancel button for style editing"
},
"styleChangesNotSaved": {
"message": "Du har gjort ändringar i denna stil utan att spara.",
"description": "Text for the prompt when changes are made to a style and the user tries to leave without saving"
},
"importLabel": {
"message": "Import",
"description": "Label for the button to import a style ('edit' page) or all styles ('manage' page)"
},
"updateCheckFailServerUnreachable": {
"message": "Uppdateringen misslyckades - server onåbar.",
"description": "Text that displays when an update check failed because the update server is unreachable"
},
"manageFilters": {
"message": "Filter",
"description": "Label for filters container"
},
"applyAllUpdates": {
"message": "Verkställ alla uppdateringar",
"description": "Label for the button to apply all detected updates"
},
"deleteStyleConfirm": {
"message": "Är du säker på att du vill ta bort denna stil?",
"description": "Confirmation before deleting a style"
},
"confirmDelete": {
"message": "Delete"
},
"confirmCancel": {
"message": "Cancel"
},
"styleBadRegexp": {
"message": "Regexp:en är ogiltig.",
"description": "Validation message for a bad regexp in a style"
},
"optionsHeading": {
"message": "Alternativ",
"description": "Heading for options section on manage page."
},
"appliesDisplay": {
"message": "Gäller för: $applies$",
"description": "Text on the manage screen to describe what the style applies to",
"placeholders": {
"applies": {
"content": "$1"
}
}
},
"styleUpdate": {
"message": "Är du säker på att du vill uppdatera '$stylename$'?",
"description": "Confirmation when updating a style",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"styleSectionsTitle": {
"message": "Sektioner",
"description": "Title for the style sections section"
},
"editStyleTitle": {
"message": "Ändra i Stil $stylename$",
"description": "Title of the page for editing styles",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"updateCheckSucceededNoUpdate": {
"message": "Stilen är fullt uppdaterad.",
"description": "Text that displays when an update check completed and no update is available"
},
"appliesUrlPrefixOption": {
"message": "URL:er som börjar på",
"description": "Option to make the style apply to the entered string as a URL prefix"
},
"searchRegexp": {
"message": "Use /re/ syntax for regexp search",
"description": "Label after the search input field in the editor shown on Ctrl-F"
},
"importReplaceTooltip": {
"message": "Discard contents of current style and overwrite it with the imported style",
"description": "Label for the button to import and overwrite current style"
},
"popupStylesFirst": {
"message": "Lista stilar före kommandon i verktygsfältets knappmeny",
"description": "Label for the checkbox controlling section order in the toolbar button menu."
},
"sectionHelp": {
"message": "Sektioner låter dig definiera olika sorters kod som påverkar olika URL:er i samma stil. Till exempel, en stil kan ändra en viss hemsida på ett sätt, samtidigt som den ändrar andra delar på en helt annan sida.",
"description": "Help text for sections"
},
"noStylesForSite": {
"message": "Inga stilar installerade för denna sida.",
"description": "Text displayed when no styles are installed for the current site"
},
"appliesDisplayTruncatedSuffix": {
"message": "och mer",
"description": "Text added to appliesDisplay when there are more sites for the style than are displayed"
},
"appliesRemove": {
"message": "Ta bort",
"description": "Label for the button to remove an 'applies' entry"
},
"styleToMozillaFormatTitle": {
"message": "Style in Mozilla format",
"description": "Title of the popup with the style code in Mozilla format, shown after pressing the Export button on Edit style page"
},
"manageTitle": {
"message": "Stylus",
"description": "Title for the manage page"
},
"writeStyleFor": {
"message": "Skapa stil för:",
"description": "Label for toolbar pop-up that precedes the links to write a new style"
},
"replace": {
"message": "Replace",
"description": "Label before the replace input field in the editor shown on Ctrl-H"
},
"appliesLabel": {
"message": "Gäller för",
"description": "Label for 'applies to' fields on the edit/add screen"
},
"openManage": {
"message": "Hantera installerade stilar",
"description": "Link to open the manage page."
},
"updateCheckFailBadResponseCode": {
"message": "Uppdateringen misslyckades - servern svarade med kod $code$.",
"description": "Text that displays when an update check failed because the response code indicates an error",
"placeholders": {
"code": {
"content": "$1"
}
}
},
"appliesSpecify": {
"message": "Specificera",
"description": "Label for the button to make a style apply only to specific sites"
},
"installUpdate": {
"message": "Installera uppdatering",
"description": "Label for the button to install an update for a single style"
},
"styleMozillaFormatHeading": {
"message": "Mozilla Format",
"description": "Heading for the section with buttons to import/export Mozilla format of the style"
},
"stylusUnavailableForURL": {
"message": "Stylus fungerar inte på sidor som dessa.",
"description": "Note in the toolbar pop-up when on a URL Stylus can't affect"
},
"sectionRemove": {
"message": "Ta bort sektion",
"description": "Label for the button to remove a section"
},
"disableAllStyles": {
"message": "Stäng av alla stilar",
"description": "Label for the checkbox that turns all enabled styles off."
},
"undoGlobal": {
"message": "Undo (global)",
"description": "CSS-beautify global Undo button label"
},
"updateCompleted": {
"message": "Uppdatering slutförd.",
"description": "Text that displays when an update completed"
},
"checkingForUpdate": {
"message": "Letar...",
"description": "Text to display when checking a style for an update"
},
"sectionCode": {
"message": "Kod",
"description": "Label for the code for a section"
},
"cm_smartIndent": {
"message": "Använd smart indrag",
"description": "Label for the checkbox controlling smart indentation option for the style editor."
},
"appliesHelp": {
"message": "Använd 'Gäller för' alternativet för att begränsa vilka URL:er koden i denna sektion gäller för.",
"description": "Help text for 'applies to' section"
},
"editStyleHeading": {
"message": "Ändra i Stil",
"description": "Title of the page for editing styles"
},
"appliesUrlOption": {
"message": "URL",
"description": "Option to make the style apply to the entered string as a URL"
},
"addStyleTitle": {
"message": "Lägg till stil",
"description": "Title of the page for adding styles"
},
"importReplaceLabel": {
"message": "Overwrite style",
"description": "Label for the button to import and overwrite current style"
},
"dbError": {
"message": "Ett fel inträffades vid hanteringen av Stylus-databasen. Skulle du vilja besöka en sida med eventuella lösningar?",
"description": "Prompt when a DB error is encountered"
},
"importAppendTooltip": {
"message": "Append the imported style to current style",
"description": "Tooltip for the button to import a style and append to the existing sections"
},
"helpKeyMapHotkey": {
"message": "Press a hotkey",
"description": "Placeholder text of inputbox in keymap help popup on the edit style page. Must be very short"
},
"replaceAll": {
"message": "Replace all",
"description": "Label before the replace input field in the editor shown on 'replaceAll' hotkey"
},
"editGotoLine": {
"message": "Gå till rad (eller rad:kol)",
"description": "Go to line or line:column on Ctrl-G in style code editor"
},
"checkAllUpdates": {
"message": "Leta igenom alla stilar efter uppdateringar",
"description": "Label for the button to check all styles for updates"
},
"issuesHelp": {
"message": "The issues found by <a href='https://github.com/CSSLint/csslint' target='_blank'>CSSLint</a> with these rules enabled:",
"description": "Help popup message for the CSSLint issues block on the style edit page"
},
"confirmNo": {
"message": "No",
"description": "'No' button in a confirm dialog"
},
"undo": {
"message": "Undo",
"description": "Button label"
},
"cm_keyMap": {
"message": "Nyckelkarta",
"description": "Label for the drop-down list controlling the keymap for the style editor."
},
"cm_indentWithTabs": {
"message": "Använd flikar med smart indrag",
"description": "Label for the checkbox controlling tabs with smart indentation option for the style editor."
},
"replaceWith": {
"message": "Replace with",
"description": "Label before the replace-with input field in the editor shown on Ctrl-H etc."
},
"deleteStyleLabel": {
"message": "Ta bort",
"description": "Label for the button to delete a style"
},
"addStyleLabel": {
"message": "Skriv ny stil",
"description": "Label for the button to go to the add style page"
},
"manageOnlyEnabled": {
"message": "Endast aktiverade stilar",
"description": "Checkbox to show only enabled styles"
},
"editStyleLabel": {
"message": "Ändra",
"description": "Label for the button to go to the edit style page"
},
"cm_theme": {
"message": "Theme",
"description": "Label for the style editor's CSS theme."
},
"helpKeyMapCommand": {
"message": "Type a command name",
"description": "Placeholder text of inputbox in keymap help popup on the edit style page. Must be very short"
},
"description": {
"message": "Style:a om webben med Stylus, en användarstils-hanterare. Stylus låter dig enkelt installera teman och skal för många populära sidor.",
"description": "Extension description"
}
}

View File

@ -1,417 +1,67 @@
{
"appliesToEverything": {
"message": "అన్నిటికీ",
"description": "Text displayed for styles that apply to all sites"
},
"defaultTheme": {
"message": "default",
"description": "Default CodeMirror CSS theme option on the edit style page"
},
"exportLabel": {
"message": "Export",
"description": "Label for the button to export a style ('edit' page) or all styles ('manage' page)"
},
"issues": {
"message": "Issues",
"description": "Label for the CSSLint issues block on the style edit page"
},
"cm_tabSize": {
"message": "Tab size",
"description": "Label for the text box controlling tab size option for the style editor."
},
"enableStyleLabel": {
"message": "చేతనించు",
"description": "Label for the button to enable a style"
},
"styleMissingName": {
"message": "Enter a name.",
"description": "Error displayed when user saves without providing a name"
},
"appliesDomainOption": {
"message": "URLs on the domain",
"description": "Option to make the style apply to the entered string as a domain"
},
"checkForUpdate": {
"message": "Check for update",
"description": "Label for the button to check a single style for an update"
},
"importAppendLabel": {
"message": "Append to style",
"description": "Label for the button to import a style and append to the existing sections"
},
"updateAllCheckSucceededNoUpdate": {
"message": "All styles are up to date.",
"description": "Text that displays when an update all check completed and no updates are available"
},
"styleFromMozillaFormatPrompt": {
"message": "Paste the Mozilla-format code",
"description": "Prompt in the dialog displayed after clicking 'Import from Mozilla format' button"
},
"helpAlt": {
"message": "సహాయం",
"description": "Alternate text for help buttons"
},
"search": {
"message": "Search",
"description": "Label before the search input field in the editor shown on Ctrl-F"
},
"confirmYes": {
"message": "Yes",
"description": "'Yes' button in a confirm dialog"
},
"findStylesForSite": {
"message": "Find more styles for this site.",
"description": "Text for a link that gets a list of styles for the current site"
},
"manageHeading": {
"message": "స్థాపిత శైలులు",
"description": "Heading for the manage page"
},
"styleBeautify": {
"message": "Beautify",
"description": "Label for the CSS-beautifier button on the edit style page"
},
"styleEnabledLabel": {
"message": "Enabled",
"description": "Label for the enabled state of styles"
},
"styleToMozillaFormatHelp": {
"message": "The Mozilla format of the code can be used with Stylish for Firefox and can be submitted to userstyles.org.",
"description": "Help info for the Mozilla format header section that converts the code to/from Mozilla format"
},
"sectionAdd": {
"message": "Add another section",
"description": "Label for the button to add a section"
},
"styleSaveLabel": {
"message": "భద్రపరచు",
"description": "Label for save button for style editing"
},
"confirmStop": {
"message": "Stop",
"description": "'Stop' button in a confirm dialog"
},
"writeStyleForURL": {
"message": "this URL",
"description": "Text for link in toolbar pop-up to write a new style for the current URL"
},
"appliesAdd": {
"message": "చేర్చు",
"description": "Label for the button to add an 'applies' entry"
},
"appliesRegexpOption": {
"message": "URLs matching the regexp",
"description": "Option to make the style apply to the entered string as a regular expression"
},
"styleInstall": {
"message": "Install '$stylename$' into Stylus?",
"description": "Confirmation when installing a style",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"manageText": {
"message": "<a href='https://userstyles.org'>Get styles on userstyles.org</a> | <a href='http://add0n.com/stylus.html'>Get help</a>",
"description": "Help text on the manage page"
},
"searchStyles": {
"message": "Search contents",
"description": "Label for the search filter textbox on the Manage styles page"
},
"disableStyleLabel": {
"message": "అచేతనించు",
"description": "Label for the button to disable a style"
},
"prefShowBadge": {
"message": "Show number of styles active for the current site on the toolbar button",
"description": "Label for the checkbox controlling toolbar badge text."
},
"menuShowBadge": {
"message": "Show active style count",
"description": "Label (must be very short) for the checkbox in the toolbar button context menu controlling toolbar badge text."
},
"cm_lineWrapping": {
"message": "Word wrap",
"description": "Label for the checkbox controlling word wrap option for the style editor."
},
"styleCancelEditLabel": {
"message": "Back to manage",
"description": "Label for cancel button for style editing"
},
"styleChangesNotSaved": {
"message": "You've made changes to this style without saving.",
"description": "Text for the prompt when changes are made to a style and the user tries to leave without saving"
},
"importLabel": {
"message": "Import",
"description": "Label for the button to import a style ('edit' page) or all styles ('manage' page)"
},
"updateCheckFailServerUnreachable": {
"message": "Update failed - server unreachable.",
"description": "Text that displays when an update check failed because the update server is unreachable"
},
"manageFilters": {
"message": "Filters",
"description": "Label for filters container"
},
"applyAllUpdates": {
"message": "Apply all updates",
"description": "Label for the button to apply all detected updates"
},
"deleteStyleConfirm": {
"message": "మీరు నజంగానే ఈ శైలిని తొలగించాలనుకుంటున్నారా?",
"description": "Confirmation before deleting a style"
},
"confirmDelete": {
"message": "Delete"
},
"confirmCancel": {
"message": "Cancel"
},
"styleBadRegexp": {
"message": "Regexp is invalid.",
"description": "Validation message for a bad regexp in a style"
},
"optionsHeading": {
"message": "Options",
"description": "Heading for options section on manage page."
},
"appliesDisplay": {
"message": "వేటికి వర్తిస్తుంది; $applies$",
"description": "Text on the manage screen to describe what the style applies to",
"placeholders": {
"applies": {
"content": "$1"
}
}
},
"styleUpdate": {
"message": "Are you sure you want to update '$stylename$'?",
"description": "Confirmation when updating a style",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"styleSectionsTitle": {
"message": "విభాగాలు",
"description": "Title for the style sections section"
},
"editStyleTitle": {
"message": "Edit Style $stylename$",
"description": "Title of the page for editing styles",
"placeholders": {
"stylename": {
"content": "$1"
}
}
},
"updateCheckSucceededNoUpdate": {
"message": "Style is up to date.",
"description": "Text that displays when an update check completed and no update is available"
},
"appliesUrlPrefixOption": {
"message": "URLs starting with",
"description": "Option to make the style apply to the entered string as a URL prefix"
},
"searchRegexp": {
"message": "Use /re/ syntax for regexp search",
"description": "Label after the search input field in the editor shown on Ctrl-F"
},
"importReplaceTooltip": {
"message": "Discard contents of current style and overwrite it with the imported style",
"description": "Label for the button to import and overwrite current style"
},
"popupStylesFirst": {
"message": "List styles before commands in the toolbar button menu",
"description": "Label for the checkbox controlling section order in the toolbar button menu."
},
"sectionHelp": {
"message": "Sections let you define different pieces of code to apply to different sets of URLs in the same style. For example, a single style could change the homepage of a site one way, while changing the rest of a site another way.",
"description": "Help text for sections"
},
"noStylesForSite": {
"message": "No styles installed for this site.",
"description": "Text displayed when no styles are installed for the current site"
},
"appliesDisplayTruncatedSuffix": {
"message": "ఇంకా మరిన్ని",
"description": "Text added to appliesDisplay when there are more sites for the style than are displayed"
},
"appliesRemove": {
"message": "తొలగించు",
"description": "Label for the button to remove an 'applies' entry"
},
"styleToMozillaFormatTitle": {
"message": "Style in Mozilla format",
"description": "Title of the popup with the style code in Mozilla format, shown after pressing the Export button on Edit style page"
},
"manageTitle": {
"message": "స్టైలిష్",
"description": "Title for the manage page"
},
"writeStyleFor": {
"message": "Write style for: ",
"description": "Label for toolbar pop-up that precedes the links to write a new style"
},
"replace": {
"message": "Replace",
"description": "Label before the replace input field in the editor shown on Ctrl-H"
},
"appliesLabel": {
"message": "Applies to",
"description": "Label for 'applies to' fields on the edit/add screen"
},
"openManage": {
"message": "Manage installed styles",
"description": "Link to open the manage page."
},
"updateCheckFailBadResponseCode": {
"message": "Update failed - server responded with code $code$.",
"description": "Text that displays when an update check failed because the response code indicates an error",
"placeholders": {
"code": {
"content": "$1"
}
}
},
"appliesSpecify": {
"message": "Specify",
"description": "Label for the button to make a style apply only to specific sites"
},
"installUpdate": {
"message": "Install update",
"description": "Label for the button to install an update for a single style"
},
"styleMozillaFormatHeading": {
"message": "Mozilla Format",
"description": "Heading for the section with buttons to import/export Mozilla format of the style"
},
"sectionRemove": {
"message": "Remove section",
"description": "Label for the button to remove a section"
},
"disableAllStyles": {
"message": "Turn all styles off",
"description": "Label for the checkbox that turns all enabled styles off."
},
"undoGlobal": {
"message": "Undo (global)",
"description": "CSS-beautify global Undo button label"
},
"updateCompleted": {
"message": "Update completed.",
"description": "Text that displays when an update completed"
},
"checkingForUpdate": {
"message": "Checking...",
"description": "Text to display when checking a style for an update"
},
"sectionCode": {
"message": "Code",
"description": "Label for the code for a section"
},
"cm_smartIndent": {
"message": "Use smart indentation",
"description": "Label for the checkbox controlling smart indentation option for the style editor."
},
"appliesHelp": {
"message": "Use the 'Applies to' controls to limit what URLs the code in this section applies to.",
"description": "Help text for 'applies to' section"
},
"editStyleHeading": {
"message": "Edit Style",
"description": "Title of the page for editing styles"
},
"appliesUrlOption": {
"message": "URL",
"description": "Option to make the style apply to the entered string as a URL"
},
"addStyleTitle": {
"message": "Add Style",
"description": "Title of the page for adding styles"
},
"importReplaceLabel": {
"message": "Overwrite style",
"description": "Label for the button to import and overwrite current style"
},
"dbError": {
"message": "An error has occurred using the Stylus database. Would you like to visit a web page with possible solutions?",
"description": "Prompt when a DB error is encountered"
},
"importAppendTooltip": {
"message": "Append the imported style to current style",
"description": "Tooltip for the button to import a style and append to the existing sections"
},
"helpKeyMapHotkey": {
"message": "Press a hotkey",
"description": "Placeholder text of inputbox in keymap help popup on the edit style page. Must be very short"
},
"replaceAll": {
"message": "Replace all",
"description": "Label before the replace input field in the editor shown on 'replaceAll' hotkey"
},
"editGotoLine": {
"message": "Goto line (or line:col)",
"description": "Go to line or line:column on Ctrl-G in style code editor"
},
"checkAllUpdates": {
"message": "Check all styles for updates",
"description": "Label for the button to check all styles for updates"
},
"issuesHelp": {
"message": "The issues found by <a href='https://github.com/CSSLint/csslint' target='_blank'>CSSLint</a> with these rules enabled:",
"description": "Help popup message for the CSSLint issues block on the style edit page"
},
"confirmNo": {
"message": "No",
"description": "'No' button in a confirm dialog"
},
"undo": {
"message": "Undo",
"description": "Button label"
},
"cm_keyMap": {
"message": "Keymap",
"description": "Label for the drop-down list controlling the keymap for the style editor."
},
"cm_indentWithTabs": {
"message": "Use tabs with smart indentation",
"description": "Label for the checkbox controlling tabs with smart indentation option for the style editor."
},
"replaceWith": {
"message": "Replace with",
"description": "Label before the replace-with input field in the editor shown on Ctrl-H etc."
},
"deleteStyleLabel": {
"message": "తొలగించు",
"description": "Label for the button to delete a style"
},
"addStyleLabel": {
"message": "క్రొత్త స్టైల్ వ్రాయండి",
"description": "Label for the button to go to the add style page"
},
"manageOnlyEnabled": {
"message": "Only enabled styles",
"description": "Checkbox to show only enabled styles"
},
"editStyleLabel": {
"message": "మార్చు",
"description": "Label for the button to go to the edit style page"
},
"cm_theme": {
"message": "Theme",
"description": "Label for the style editor's CSS theme."
},
"helpKeyMapCommand": {
"message": "Type a command name",
"description": "Placeholder text of inputbox in keymap help popup on the edit style page. Must be very short"
},
"description": {
"message": "Restyle the web with Stylus, a user styles manager. Stylus lets you easily install themes and skins for many popular sites.",
"description": "Extension description"
}
"addStyleLabel": {
"message": "క్రొత్త స్టైల్ వ్రాయండి"
},
"appliesAdd": {
"message": "చేర్చు"
},
"appliesDisplay": {
"message": "వేటికి వర్తిస్తుంది; $applies$",
"placeholders": {
"applies": {
"content": "$1"
}
}
},
"appliesDisplayTruncatedSuffix": {
"message": "ఇంకా మరిన్ని"
},
"appliesRemove": {
"message": "తొలగించు"
},
"appliesToEverything": {
"message": "అన్నిటికీ"
},
"confirmDelete": {
"message": "తొలగించు"
},
"confirmSave": {
"message": "భద్రపరచు"
},
"deleteStyleConfirm": {
"message": "మీరు నజంగానే ఈ శైలిని తొలగించాలనుకుంటున్నారా?"
},
"deleteStyleLabel": {
"message": "తొలగించు"
},
"disableStyleLabel": {
"message": "అచేతనించు"
},
"editDeleteText": {
"message": "తొలగించు"
},
"editStyleLabel": {
"message": "మార్చు"
},
"enableStyleLabel": {
"message": "చేతనించు"
},
"genericAdd": {
"message": "చేర్చు"
},
"helpAlt": {
"message": "సహాయం"
},
"manageHeading": {
"message": "స్థాపిత శైలులు"
},
"manageTitle": {
"message": "స్టైలిష్"
},
"sections": {
"message": "విభాగాలు"
},
"styleSaveLabel": {
"message": "భద్రపరచు"
}
}

File diff suppressed because it is too large Load Diff

285
_locales/uk/messages.json Normal file
View File

@ -0,0 +1,285 @@
{
"InaccessibleFileHint": {
"message": "Stylus не може отримати доступ до деяких типів файлів (наприклад, файли PDF і JSON)."
},
"addStyleLabel": {
"message": "Написати новий стиль"
},
"addStyleTitle": {
"message": "Додати стиль"
},
"alphaChannel": {
"message": "Прозорість"
},
"appliesAdd": {
"message": "Додати"
},
"appliesDisplay": {
"message": "Застосувати до $applies$",
"placeholders": {
"applies": {
"content": "$1"
}
}
},
"appliesDisplayTruncatedSuffix": {
"message": "та інші"
},
"appliesDomainOption": {
"message": "URL в домені"
},
"appliesHelp": {
"message": "Щоб вказати, до яких URL відноситься код в цьому розділі, скористайтеся параметром \"Застосувати до\"."
},
"appliesLabel": {
"message": "Застосувати до"
},
"appliesLineWidgetLabel": {
"message": "Показати цільові сайти секцій"
},
"appliesRemove": {
"message": "Видалити"
},
"appliesRemoveError": {
"message": "Не можна видалити останній елемент"
},
"appliesSpecify": {
"message": "Вказати"
},
"appliesToEverything": {
"message": "Все"
},
"appliesUrlPrefixOption": {
"message": "URL, що починаються з "
},
"applyAllUpdates": {
"message": "Застосувати всі оновлення"
},
"author": {
"message": "Автор"
},
"backupButtons": {
"message": "Резервне копіювання"
},
"bckpInstStyles": {
"message": "Експорт стилів"
},
"checkingForUpdate": {
"message": "Перевірка ... "
},
"clickToUninstall": {
"message": "Натисніть, щоб видалити "
},
"cm_selectByTokensTooltip": {
"message": "Приклади токенов: .foo-бар-2 #aabbcc 0,32 !important\nЯкщо вимкнено: вибираються слова, розділені розділовими знаками."
},
"confirmCancel": {
"message": "Скасувати "
},
"confirmDelete": {
"message": "Видалити "
},
"confirmNo": {
"message": "Ні"
},
"confirmSave": {
"message": "Зберегти"
},
"confirmStop": {
"message": "Зупинити"
},
"confirmYes": {
"message": "Так"
},
"deleteStyleLabel": {
"message": "Видалити"
},
"disableStyleLabel": {
"message": "Вимкнути"
},
"editDeleteText": {
"message": "Видалити"
},
"findStyles": {
"message": "Знайти стилі"
},
"genericAdd": {
"message": "Додати"
},
"genericDescription": {
"message": "Опис"
},
"genericDisabledLabel": {
"message": "Відключено"
},
"genericEnabledLabel": {
"message": "Увімкнено"
},
"genericError": {
"message": "Помилка"
},
"genericHistoryLabel": {
"message": "Історія"
},
"genericNext": {
"message": "Наступний "
},
"genericPrevious": {
"message": "Попередній"
},
"genericResetLabel": {
"message": "Скинути"
},
"genericSavedMessage": {
"message": "Збережено"
},
"genericTitle": {
"message": "Ім'я"
},
"genericUnknown": {
"message": "Невідомо"
},
"gettingStyles": {
"message": "Отримання всіх стилів ..."
},
"helpAlt": {
"message": "Довідка"
},
"helpKeyMapCommand": {
"message": "Введіть ім'я команди"
},
"helpKeyMapHotkey": {
"message": "Натисніть клавішу"
},
"hostDisabled": {
"message": "Цей хост вимкнено через помилку в поточній версії браузера, що використовується"
},
"importLabel": {
"message": "Імпорт"
},
"importReplaceLabel": {
"message": "Замінити стиль"
},
"importReportLegendIdentical": {
"message": "ідентичні пропущені"
},
"importReportLegendInvalid": {
"message": "недісних пропущено"
},
"importReportTitle": {
"message": "Імпорт стилів закінчено"
},
"installUpdate": {
"message": "Встановити оновлення"
},
"manageFavicons": {
"message": "Піктограми для цільових сайтів"
},
"manageFilters": {
"message": "Фільтри"
},
"manageHeading": {
"message": "Встановити Styles"
},
"manageNewUI": {
"message": "Новий макет інтерфейсу управління користувача"
},
"meta_unknownJSONLiteral": {
"message": "Невірний JSON: $literal$не є дійсним літералом JSON",
"placeholders": {
"literal": {
"content": "$1"
}
}
},
"openManage": {
"message": "Керування"
},
"openOptions": {
"message": "Налаштування"
},
"optionsHeading": {
"message": "Налаштування"
},
"optionsReset": {
"message": "Скидання налаштувань до значень за замовчуванням"
},
"optionsResetButton": {
"message": "Скинути параметри"
},
"optionsSubheading": {
"message": "Додатково"
},
"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": "Код"
},
"sections": {
"message": "Розділи"
},
"styleBeautify": {
"message": "Облагородити"
},
"styleCancelEditLabel": {
"message": "Повернутися до керування"
},
"styleEnabledLabel": {
"message": "Увімкнено"
},
"stylePreferSchemeLabel": {
"message": "Темна/Світла тема"
},
"styleSaveLabel": {
"message": "Зберегти"
},
"syncErrorRelogin": {
"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"
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

336
apply.js
View File

@ -1,336 +0,0 @@
// Not using some slow features of ES6, see http://kpdecker.github.io/six-speed/
// like destructring, classes, defaults, spread, calculated key names
/* eslint no-var: 0 */
'use strict';
var ID_PREFIX = 'stylus-';
var ROOT = document.documentElement;
var isOwnPage = location.href.startsWith('chrome-extension:');
var disableAll = false;
var exposeIframes = false;
var styleElements = new Map();
var disabledElements = new Map();
var retiredStyleTimers = new Map();
var docRewriteObserver;
requestStyles();
chrome.runtime.onMessage.addListener(applyOnMessage);
if (!isOwnPage) {
window.dispatchEvent(new CustomEvent(chrome.runtime.id));
window.addEventListener(chrome.runtime.id, orphanCheck, true);
}
function requestStyles(options, callback = applyStyles) {
var matchUrl = location.href;
if (!matchUrl.match(/^(http|file|chrome|ftp)/)) {
// dynamic about: and javascript: iframes don't have an URL yet
// so we'll try the parent frame which is guaranteed to have a real URL
try {
if (window != parent) {
matchUrl = parent.location.href;
}
} catch (e) {}
}
const request = Object.assign({
method: 'getStyles',
matchUrl,
enabled: true,
asHash: true,
}, options);
// On own pages we request the styles directly to minimize delay and flicker
if (typeof getStylesSafe !== 'undefined') {
getStylesSafe(request).then(callback);
} else {
chrome.runtime.sendMessage(request, callback);
}
}
function applyOnMessage(request, sender, sendResponse) {
if (request.styles == 'DIY') {
// Do-It-Yourself tells our built-in pages to fetch the styles directly
// which is faster because IPC messaging JSON-ifies everything internally
requestStyles({}, styles => {
request.styles = styles;
applyOnMessage(request);
});
return;
}
switch (request.method) {
case 'styleDeleted':
removeStyle(request);
break;
case 'styleUpdated':
if (request.codeIsUpdated === false) {
applyStyleState(request.style);
break;
}
if (request.style.enabled) {
removeStyle({id: request.style.id, retire: true});
requestStyles({id: request.style.id});
} else {
removeStyle(request.style);
}
break;
case 'styleAdded':
if (request.style.enabled) {
requestStyles({id: request.style.id});
}
break;
case 'styleApply':
applyStyles(request.styles);
break;
case 'styleReplaceAll':
replaceAll(request.styles);
break;
case 'prefChanged':
if ('disableAll' in request.prefs) {
doDisableAll(request.prefs.disableAll);
}
if ('exposeIframes' in request.prefs) {
doExposeIframes(request.prefs.exposeIframes);
}
break;
case 'ping':
sendResponse(true);
break;
}
}
function doDisableAll(disable = disableAll) {
if (!disable === !disableAll) {
return;
}
disableAll = disable;
Array.prototype.forEach.call(document.styleSheets, stylesheet => {
if (stylesheet.ownerNode.matches(`STYLE.stylus[id^="${ID_PREFIX}"]`)
&& stylesheet.disabled != disable) {
stylesheet.disabled = disable;
}
});
}
function doExposeIframes(state = exposeIframes) {
if (state === exposeIframes || window == parent) {
return;
}
exposeIframes = state;
const attr = document.documentElement.getAttribute('stylus-iframe');
if (state && attr != '') {
document.documentElement.setAttribute('stylus-iframe', '');
} else if (!state && attr == '') {
document.documentElement.removeAttribute('stylus-iframe');
}
}
function applyStyleState({id, enabled}) {
const inCache = disabledElements.get(id) || styleElements.get(id);
const inDoc = document.getElementById(ID_PREFIX + id);
if (enabled) {
if (inDoc) {
return;
} else if (inCache) {
addStyleElement(inCache);
disabledElements.delete(id);
} else {
requestStyles({id});
}
} else {
if (inDoc) {
disabledElements.set(id, inDoc);
inDoc.remove();
}
}
}
function removeStyle({id, retire = false}) {
const el = document.getElementById(ID_PREFIX + id);
if (el) {
if (retire) {
// to avoid page flicker when the style is updated
// instead of removing it immediately we rename its ID and queue it
// to be deleted in applyStyles after a new version is fetched and applied
const deadID = 'ghost-' + id;
el.id = ID_PREFIX + deadID;
// in case something went wrong and new style was never applied
retiredStyleTimers.set(deadID, setTimeout(removeStyle, 1000, {id: deadID}));
} else {
el.remove();
}
}
styleElements.delete(ID_PREFIX + id);
disabledElements.delete(id);
retiredStyleTimers.delete(id);
}
function applyStyles(styles) {
if (!styles) {
// Chrome is starting up
requestStyles();
return;
}
if ('disableAll' in styles) {
doDisableAll(styles.disableAll);
delete styles.disableAll;
}
if ('exposeIframes' in styles) {
doExposeIframes(styles.exposeIframes);
delete styles.exposeIframes;
}
if (document.head
&& document.head.firstChild
&& document.head.firstChild.id == 'xml-viewer-style') {
// when site response is application/xml Chrome displays our style elements
// under document.documentElement as plain text so we need to move them into HEAD
// which is already autogenerated at this moment
ROOT = document.head;
}
for (const id in styles) {
applySections(id, styles[id]);
}
initDocRewriteObserver();
if (retiredStyleTimers.size) {
setTimeout(() => {
for (const [id, timer] of retiredStyleTimers.entries()) {
removeStyle({id});
clearTimeout(timer);
}
});
}
}
function applySections(styleId, sections) {
let el = document.getElementById(ID_PREFIX + styleId);
if (el) {
return;
}
if (document.documentElement instanceof SVGSVGElement) {
// SVG document style
el = document.createElementNS('http://www.w3.org/2000/svg', 'style');
} else if (document instanceof XMLDocument) {
// XML document style
el = document.createElementNS('http://www.w3.org/1999/xhtml', 'style');
} else {
// HTML document style; also works on HTML-embedded SVG
el = document.createElement('style');
}
Object.assign(el, {
id: ID_PREFIX + styleId,
className: 'stylus',
type: 'text/css',
textContent: sections.map(section => section.code).join('\n'),
});
addStyleElement(el);
styleElements.set(el.id, el);
disabledElements.delete(styleId);
}
function addStyleElement(el) {
if (ROOT && !document.getElementById(el.id)) {
ROOT.appendChild(el);
el.disabled = disableAll;
}
}
function replaceAll(newStyles) {
const oldStyles = Array.prototype.slice.call(
document.querySelectorAll(`STYLE.stylus[id^="${ID_PREFIX}"]`));
oldStyles.forEach(el => (el.id += '-ghost'));
styleElements.clear();
disabledElements.clear();
[...retiredStyleTimers.values()].forEach(clearTimeout);
retiredStyleTimers.clear();
applyStyles(newStyles);
oldStyles.forEach(el => el.remove());
}
function initDocRewriteObserver() {
if (isOwnPage || docRewriteObserver || !styleElements.size) {
return;
}
// re-add styles if we detect documentElement being recreated
const reinjectStyles = () => {
if (!styleElements) {
return orphanCheck && orphanCheck();
}
ROOT = document.documentElement;
for (const el of styleElements.values()) {
addStyleElement(document.importNode(el, true));
}
};
// detect documentElement being rewritten from inside the script
docRewriteObserver = new MutationObserver(mutations => {
for (let m = mutations.length; --m >= 0;) {
const added = mutations[m].addedNodes;
for (let n = added.length; --n >= 0;) {
if (added[n].localName == 'html') {
reinjectStyles();
return;
}
}
}
});
docRewriteObserver.observe(document, {childList: true});
// detect dynamic iframes rewritten after creation by the embedder i.e. externally
setTimeout(() => {
if (document.documentElement != ROOT) {
reinjectStyles();
}
});
}
function orphanCheck() {
const port = chrome.runtime.connect();
if (port) {
port.disconnect();
return;
}
// we're orphaned due to an extension update
// we can detach the mutation observer
if (docRewriteObserver) {
docRewriteObserver.disconnect();
}
// we can detach event listeners
window.removeEventListener(chrome.runtime.id, orphanCheck, true);
// we can't detach chrome.runtime.onMessage because it's no longer connected internally
// we can destroy our globals in this context to free up memory
[ // functions
'addStyleElement',
'applyOnMessage',
'applySections',
'applyStyles',
'applyStyleState',
'doDisableAll',
'initDocRewriteObserver',
'orphanCheck',
'removeStyle',
'replaceAll',
'requestStyles',
// variables
'ROOT',
'disabledElements',
'retiredStyleTimers',
'styleElements',
'docRewriteObserver',
].forEach(fn => (window[fn] = null));
}

View File

@ -1,287 +0,0 @@
/* global dbExec, getStyles, saveStyle, schedule, download */
'use strict';
// eslint-disable-next-line no-var
var browserCommands, contextMenus;
// *************************************************************************
// preload the DB and report errors
dbExec().catch((...args) => {
args.forEach(arg => 'message' in arg && console.error(arg.message));
});
// *************************************************************************
// register all listeners
chrome.runtime.onMessage.addListener(onRuntimeMessage);
chrome.webNavigation.onBeforeNavigate.addListener(data =>
webNavigationListener(null, data));
chrome.webNavigation.onCommitted.addListener(data =>
webNavigationListener('styleApply', data));
chrome.webNavigation.onHistoryStateUpdated.addListener(data =>
webNavigationListener('styleReplaceAll', data));
chrome.webNavigation.onReferenceFragmentUpdated.addListener(data =>
webNavigationListener('styleReplaceAll', data));
chrome.tabs.onAttached.addListener((tabId, data) => {
// When an edit page gets attached or detached, remember its state
// so we can do the same to the next one to open.
chrome.tabs.get(tabId, tab => {
if (tab.url.startsWith(URLS.ownOrigin + 'edit.html')) {
chrome.windows.get(tab.windowId, {populate: true}, win => {
// If there's only one tab in this window, it's been dragged to new window
prefs.set('openEditInWindow', win.tabs.length == 1);
});
}
});
});
chrome.contextMenus.onClicked.addListener((info, tab) =>
contextMenus[info.menuItemId].click(info, tab));
if ('commands' in chrome) {
// Not available in Firefox - https://bugzilla.mozilla.org/show_bug.cgi?id=1240350
chrome.commands.onCommand.addListener(command => browserCommands[command]());
}
// *************************************************************************
{
const onInstall = ({reason}) => {
chrome.runtime.onInstalled.removeListener(onInstall);
const manifest = chrome.runtime.getManifest();
// Open FAQs page once after installation to guide new users.
// Do not display it in development mode.
if (reason == 'install' && manifest.update_url) {
setTimeout(openURL, 100, {
url: `http://add0n.com/stylus.html?version=${manifest.version}&type=install`
});
}
// reset L10N cache on UI language change or update
const {browserUIlanguage} = tryJSONparse(localStorage.L10N) || {};
const UIlang = chrome.i18n.getUILanguage();
if (reason == 'update' || browserUIlanguage != UIlang) {
localStorage.L10N = JSON.stringify({
browserUIlanguage: UIlang,
});
}
};
// bind for 60 seconds max and auto-unbind if it's a normal run
chrome.runtime.onInstalled.addListener(onInstall);
setTimeout(onInstall, 60e3, {reason: 'unbindme'});
}
// *************************************************************************
// browser commands
browserCommands = {
openManage() {
openURL({url: '/manage.html'});
},
styleDisableAll(info) {
prefs.set('disableAll', info ? info.checked : !prefs.get('disableAll'));
},
};
// *************************************************************************
// context menus
contextMenus = Object.assign({
'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,
},
}, prefs.get('editor.contextDelete') && {
'editor.contextDelete': {
title: 'editDeleteText',
type: 'normal',
contexts: ['editable'],
documentUrlPatterns: [URLS.ownOrigin + 'edit*'],
click: (info, tab) => {
chrome.tabs.sendMessage(tab.id, {method: 'editDeleteText'});
},
}
});
{
const createContextMenus = (ids = Object.keys(contextMenus)) => {
for (const id of ids) {
const item = Object.assign({id}, contextMenus[id]);
const prefValue = prefs.readOnlyValues[id];
item.title = chrome.i18n.getMessage(item.title);
if (!item.type && typeof prefValue == 'boolean') {
item.type = 'checkbox';
item.checked = prefValue;
}
if (!item.contexts) {
item.contexts = ['browser_action'];
}
delete item.click;
chrome.contextMenus.create(item, ignoreChromeError);
}
};
createContextMenus();
prefs.subscribe((id, checked) => {
if (id == 'editor.contextDelete') {
if (checked) {
createContextMenus([id]);
} else {
chrome.contextMenus.remove(id, ignoreChromeError);
}
} else {
chrome.contextMenus.update(id, {checked}, ignoreChromeError);
}
}, Object.keys(contextMenus).filter(key => typeof prefs.readOnlyValues[key] == 'boolean'));
}
// *************************************************************************
// [re]inject content scripts
{
const NTP = 'chrome://newtab/';
const PING = {method: 'ping'};
const ALL_URLS = '<all_urls>';
const contentScripts = chrome.runtime.getManifest().content_scripts;
// expand * as .*?
const wildcardAsRegExp = (s, flags) => new RegExp(
s.replace(/[{}()[\]/\\.+?^$:=!|]/g, '\\$&')
.replace(/\*/g, '.*?'), flags);
for (const cs of contentScripts) {
cs.matches = cs.matches.map(m => (
m == ALL_URLS ? m : wildcardAsRegExp(m)
));
}
const injectCS = (cs, tabId) => {
chrome.tabs.executeScript(tabId, {
file: cs.js[0],
runAt: cs.run_at,
allFrames: cs.all_frames,
matchAboutBlank: cs.match_about_blank,
}, ignoreChromeError);
};
const pingCS = (cs, {id, url}) => {
cs.matches.some(match => {
if ((match == ALL_URLS || url.match(match))
&& (!url.startsWith('chrome') || url == NTP)) {
chrome.tabs.sendMessage(id, PING, pong => !pong && injectCS(cs, id));
return true;
}
});
};
chrome.tabs.query({}, tabs =>
tabs.forEach(tab =>
contentScripts.forEach(cs =>
pingCS(cs, tab))));
}
// *************************************************************************
function webNavigationListener(method, {url, tabId, frameId}) {
getStyles({matchUrl: url, enabled: true, asHash: true}).then(styles => {
if (method && !url.startsWith('chrome:') && tabId >= 0) {
chrome.tabs.sendMessage(tabId, {
method,
// ping own page so it retrieves the styles directly
styles: url.startsWith(URLS.ownOrigin) ? 'DIY' : styles,
}, {
frameId
});
}
// main page frame id is 0
if (frameId == 0) {
updateIcon({id: tabId, url}, styles);
}
});
}
function updateIcon(tab, styles) {
if (tab.id < 0) {
return;
}
if (styles) {
stylesReceived(styles);
return;
}
getTabRealURL(tab)
.then(url => getStyles({matchUrl: url, enabled: true, asHash: true}))
.then(stylesReceived);
function stylesReceived(styles) {
let numStyles = styles.length;
if (numStyles === undefined) {
// for 'styles' asHash:true fake the length by counting numeric ids manually
numStyles = 0;
for (const id of Object.keys(styles)) {
numStyles += id.match(/^\d+$/) ? 1 : 0;
}
}
const disableAll = 'disableAll' in styles ? styles.disableAll : prefs.get('disableAll');
const postfix = disableAll ? 'x' : numStyles == 0 ? 'w' : '';
const color = prefs.get(disableAll ? 'badgeDisabled' : 'badgeNormal');
const text = prefs.get('show-badge') && numStyles ? String(numStyles) : '';
chrome.browserAction.setIcon({
tabId: tab.id,
path: {
// Material Design 2016 new size is 16px
16: `images/icon/16${postfix}.png`,
32: `images/icon/32${postfix}.png`,
// Chromium forks or non-chromium browsers may still use the traditional 19px
19: `images/icon/19${postfix}.png`,
38: `images/icon/38${postfix}.png`,
// TODO: add Edge preferred sizes: 20, 25, 30, 40
},
}, () => {
if (chrome.runtime.lastError) {
return;
}
// Vivaldi bug workaround: setBadgeText must follow setBadgeBackgroundColor
chrome.browserAction.setBadgeBackgroundColor({color});
getTab(tab.id).then(() => {
chrome.browserAction.setBadgeText({text, tabId: tab.id});
});
});
}
}
function onRuntimeMessage(request, sender, sendResponse) {
switch (request.method) {
case 'getStyles':
getStyles(request).then(sendResponse);
return KEEP_CHANNEL_OPEN;
case 'saveStyle':
saveStyle(request).then(sendResponse);
return KEEP_CHANNEL_OPEN;
case 'healthCheck':
dbExec()
.then(() => sendResponse(true))
.catch(() => sendResponse(false));
return KEEP_CHANNEL_OPEN;
case 'download':
download(request.url)
.then(sendResponse)
.catch(() => sendResponse(null));
return KEEP_CHANNEL_OPEN;
case 'schedule':
schedule.entry(request)
.then(() => sendResponse(true))
.catch(() => sendResponse(false));
return KEEP_CHANNEL_OPEN;
}
}

View File

@ -0,0 +1,26 @@
/* global createWorkerApi */// worker-util.js
'use strict';
/** @namespace BackgroundWorker */
createWorkerApi({
async compileUsercss(...args) {
require(['/js/usercss-compiler']); /* global compileUsercss */
return compileUsercss(...args);
},
nullifyInvalidVars(vars) {
require(['/js/meta-parser']); /* global metaParser */
return metaParser.nullifyInvalidVars(vars);
},
parseMozFormat(...args) {
require(['/js/moz-parser']); /* global extractSections */
return extractSections(...args);
},
parseUsercssMeta(text) {
require(['/js/meta-parser']);
return metaParser.parse(text);
},
});

213
background/background.js Normal file
View File

@ -0,0 +1,213 @@
/* global API msg */// msg.js
/* global addAPI bgReady */// common.js
/* global createWorker */// worker-util.js
/* global prefs */
/* global styleMan */
/* global syncMan */
/* global updateMan */
/* global usercssMan */
/* global usoApi */
/* global uswApi */
/* global FIREFOX UA activateTab openURL */ // toolbox.js
/* global colorScheme */ // color-scheme.js
'use strict';
//#region API
addAPI(/** @namespace API */ {
/** Temporary storage for data needed elsewhere e.g. in a content script */
data: ((data = {}) => ({
del: key => delete data[key],
get: key => data[key],
has: key => key in data,
pop: key => {
const val = data[key];
delete data[key];
return val;
},
set: (key, val) => {
data[key] = val;
},
}))(),
styles: styleMan,
sync: syncMan,
updater: updateMan,
usercss: usercssMan,
uso: usoApi,
usw: uswApi,
colorScheme,
/** @type {BackgroundWorker} */
worker: createWorker({url: '/background/background-worker'}),
/** @returns {string} */
getTabUrlPrefix() {
return this.sender.tab.url.match(/^([\w-]+:\/+[^/#]+)/)[1];
},
/**
* Opens the editor or activates an existing tab
* @param {{
id?: number
domain?: string
'url-prefix'?: string
}} params
* @returns {Promise<chrome.tabs.Tab>}
*/
async openEditor(params) {
const u = new URL(chrome.runtime.getURL('edit.html'));
u.search = new URLSearchParams(params);
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,
newWindow: wnd && Object.assign(wndBase, !ffBug && wndPos),
});
if (ffBug) await browser.windows.update(tab.windowId, wndPos);
return tab;
},
/** @returns {Promise<chrome.tabs.Tab>} */
async openManage({options = false, search, 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)});
}
return activateTab(tab); // activateTab unminimizes the window
},
/**
* Same as openURL, the only extra prop in `opts` is `message` - it'll be sent
* when the tab is ready, which is needed in the popup, otherwise another
* extension could force the tab to open in foreground thus auto-closing the
* popup (in Chrome at least) and preventing the sendMessage code from running
* @returns {Promise<chrome.tabs.Tab>}
*/
async openURL(opts) {
const tab = await openURL(opts);
if (opts.message) {
await onTabReady(tab);
await msg.sendTab(tab.id, opts.message);
}
return tab;
function onTabReady(tab) {
return new Promise((resolve, reject) =>
setTimeout(function ping(numTries = 10, delay = 100) {
msg.sendTab(tab.id, {method: 'ping'})
.catch(() => false)
.then(pong => pong
? resolve(tab)
: numTries && setTimeout(ping, delay, numTries - 1, delay * 1.5) ||
reject('timeout'));
}));
}
},
prefs: {
getValues: () => prefs.__values, // will be deepCopy'd by apiHandler
set: prefs.set,
},
});
//#endregion
//#region Events
const browserCommands = {
openManage: () => API.openManage(),
openOptions: () => API.openManage({options: true}),
reload: () => chrome.runtime.reload(),
styleDisableAll(info) {
prefs.set('disableAll', info ? info.checked : !prefs.get('disableAll'));
},
};
if (chrome.commands) {
chrome.commands.onCommand.addListener(id => browserCommands[id]());
}
chrome.runtime.onInstalled.addListener(({reason, previousVersion}) => {
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) {}
}
}
});
msg.on((msg, sender) => {
if (msg.method === 'invokeAPI') {
let res = msg.path.reduce((res, name) => res && res[name], API);
if (!res) throw new Error(`Unknown API.${msg.path.join('.')}`);
res = res.apply({msg, sender}, msg.args);
return res === undefined ? null : res;
}
});
//#endregion
Promise.all([
browser.extension.isAllowedFileSchemeAccess()
.then(res => API.data.set('hasFileAccess', res)),
bgReady.styles,
/* These are loaded conditionally.
Each item uses `require` individually so IDE can jump to the source and track usage. */
FIREFOX &&
require(['/background/style-via-api']),
FIREFOX && ((browser.commands || {}).update) &&
require(['/background/browser-cmd-hotkeys']),
!FIREFOX &&
require(['/background/content-scripts']),
chrome.contextMenus &&
require(['/background/context-menus']),
]).then(() => {
bgReady._resolveAll();
msg.ready = true;
msg.broadcast({method: 'backgroundReady'});
});

View File

@ -0,0 +1,22 @@
/* global prefs */
'use strict';
/*
Registers hotkeys in FF
*/
(() => {
const hotkeyPrefs = prefs.knownKeys.filter(k => k.startsWith('hotkey.'));
prefs.subscribe(hotkeyPrefs, updateHotkey, {runNow: true});
async function updateHotkey(name, value) {
try {
name = name.split('.')[1];
if (value.trim()) {
await browser.commands.update({name, shortcut: value});
} else {
await browser.commands.reset(name);
}
} catch (e) {}
}
})();

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,117 @@
/* global bgReady */// common.js
/* global msg */
/* global URLS ignoreChromeError */// toolbox.js
'use strict';
/*
Reinject content scripts when the extension is reloaded/updated.
Not used in Firefox as it reinjects automatically.
*/
bgReady.all.then(() => {
const NTP = 'chrome://newtab/';
const ALL_URLS = '<all_urls>';
const SCRIPTS = chrome.runtime.getManifest().content_scripts;
// expand * as .*?
const wildcardAsRegExp = (s, flags) => new RegExp(
s.replace(/[{}()[\]/\\.+?^$:=!|]/g, '\\$&')
.replace(/\*/g, '.*?'), flags);
for (const cs of SCRIPTS) {
cs.matches = cs.matches.map(m => (
m === ALL_URLS ? m : wildcardAsRegExp(m)
));
}
const busyTabs = new Set();
let busyTabsTimer;
setTimeout(injectToAllTabs);
function injectToTab({url, tabId, frameId = null}) {
for (const script of SCRIPTS) {
if (
script.matches.some(match =>
(match === ALL_URLS || url.match(match)) &&
(!url.startsWith('chrome') || url === NTP))
) {
doInject(tabId, frameId, script);
}
}
}
function doInject(tabId, frameId, script) {
const options = frameId === null ? {} : {frameId};
msg.sendTab(tabId, {method: 'ping'}, options)
.catch(() => false)
.then(pong => {
if (pong) {
return;
}
const options = {
runAt: script.run_at,
allFrames: script.all_frames,
matchAboutBlank: script.match_about_blank,
};
if (frameId !== null) {
options.allFrames = false;
options.frameId = frameId;
}
for (const file of script.js) {
chrome.tabs.executeScript(tabId, Object.assign({file}, options), ignoreChromeError);
}
});
}
function injectToAllTabs() {
return browser.tabs.query({}).then(tabs => {
for (const tab of tabs) {
// skip unloaded/discarded/chrome tabs
if (!tab.width || tab.discarded || !URLS.supported(tab.pendingUrl || tab.url)) continue;
// our content scripts may still be pending injection at browser start so it's too early to ping them
if (tab.status === 'loading') {
trackBusyTab(tab.id, true);
} else {
injectToTab({
url: tab.pendingUrl || tab.url,
tabId: tab.id,
});
}
}
});
}
function toggleBusyTabListeners(state) {
const toggle = state ? 'addListener' : 'removeListener';
chrome.webNavigation.onCompleted[toggle](onBusyTabUpdated);
chrome.webNavigation.onErrorOccurred[toggle](onBusyTabUpdated);
chrome.webNavigation.onTabReplaced[toggle](onBusyTabReplaced);
chrome.tabs.onRemoved[toggle](onBusyTabRemoved);
if (state) {
busyTabsTimer = setTimeout(toggleBusyTabListeners, 15e3, false);
} else {
clearTimeout(busyTabsTimer);
}
}
function trackBusyTab(tabId, state) {
busyTabs[state ? 'add' : 'delete'](tabId);
if (state && busyTabs.size === 1) toggleBusyTabListeners(true);
if (!state && !busyTabs.size) toggleBusyTabListeners(false);
}
function onBusyTabUpdated({error, frameId, tabId, url}) {
if (!frameId && busyTabs.has(tabId)) {
trackBusyTab(tabId, false);
if (url && !error) {
injectToTab({tabId, url});
}
}
}
function onBusyTabReplaced({replacedTabId}) {
trackBusyTab(replacedTabId, false);
}
function onBusyTabRemoved(tabId) {
trackBusyTab(tabId, false);
}
});

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

@ -0,0 +1,64 @@
/* global chromeLocal */// storage-util.js
'use strict';
/* exported createChromeStorageDB */
function createChromeStorageDB(PREFIX) {
let INC;
const isMain = !PREFIX;
if (!PREFIX) PREFIX = 'style-';
return {
delete(id) {
return chromeLocal.remove(PREFIX + id);
},
get(id) {
return chromeLocal.getValue(PREFIX + id);
},
async getAll() {
const all = await chromeLocal.get();
if (!INC) prepareInc(all);
return Object.entries(all)
.map(([key, val]) => key.startsWith(PREFIX) &&
(!isMain || Number(key.slice(PREFIX.length))) &&
val)
.filter(Boolean);
},
async put(item) {
if (!item.id) {
if (!INC) await prepareInc();
item.id = INC++;
}
await chromeLocal.setValue(PREFIX + item.id, item);
return item.id;
},
async putMany(items) {
const data = {};
for (const item of items) {
if (!item.id) {
if (!INC) await prepareInc();
item.id = INC++;
}
data[PREFIX + item.id] = item;
}
await chromeLocal.set(data);
return items.map(_ => _.id);
},
};
async function prepareInc(data) {
INC = 1;
for (const key in data || await chromeLocal.get()) {
if (key.startsWith(PREFIX)) {
const id = Number(key.slice(PREFIX.length));
if (id >= INC) {
INC = id + 1;
}
}
}
}
}

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;
}
})();

232
background/icon-manager.js Normal file
View File

@ -0,0 +1,232 @@
/* global API */// msg.js
/* global addAPI bgReady */// common.js
/* global colorScheme */
/* global prefs */
/* global tabMan */
/* global CHROME FIREFOX UA debounce ignoreChromeError */// toolbox.js
'use strict';
/* exported iconMan */
const iconMan = (() => {
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 && 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)));
addAPI(/** @namespace API */ {
/**
* @param {(number|string)[]} styleIds
* @param {boolean} [lazyBadge=false] preventing flicker during page load
*/
updateIconBadge(styleIds, {lazyBadge} = {}) {
// FIXME: in some cases, we only have to redraw the badge. is it worth a optimization?
const {frameId, tab: {id: tabId}} = this.sender;
const value = styleIds.length ? styleIds.map(Number) : undefined;
tabMan.set(tabId, 'styleIds', frameId, value);
debounce(refreshStaleBadges, frameId && lazyBadge ? 250 : 0);
staleBadges.add(tabId);
if (!frameId) refreshIcon(tabId, true);
},
});
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',
'badgeDisabled',
'badgeNormal',
], () => debounce(refreshIconBadgeColor), {runNow: true});
prefs.subscribe([
'show-badge',
], () => debounce(refreshAllIconsBadgeText), {runNow: true});
prefs.subscribe([
'disableAll',
'iconset',
], () => debounce(refreshAllIcons), {runNow: true});
});
return {
/** Calling with no params clears the override */
overrideBadge({text = '', color = '', title = ''} = {}) {
if (badgeOvr.text === text) {
return;
}
badgeOvr.text = text;
badgeOvr.color = color;
refreshIconBadgeColor();
setBadgeText({text});
for (const tabId of tabMan.list()) {
if (text) {
setBadgeText({tabId, text});
} else {
refreshIconBadgeText(tabId);
}
}
chrome.browserAction.setTitle({
title: title && chrome.i18n.getMessage(title) || title || '',
});
},
};
function onPortDisconnected({sender}) {
if (tabMan.get(sender.tab.id, 'styleIds')) {
API.updateIconBadge.call({sender}, [], {lazyBadge: true});
}
}
function refreshIconBadgeText(tabId) {
if (badgeOvr.text) return;
const text = prefs.get('show-badge') ? `${getStyleCount(tabId)}` : '';
setBadgeText({tabId, text});
}
function getIconName(hasStyles = false) {
const i = prefs.get('iconset');
const prefix = i === 0 || i === -1 && isDark ? '' : 'light/';
const postfix = prefs.get('disableAll') ? 'x' : !hasStyles ? 'w' : '';
return `${prefix}$SIZE$${postfix}`;
}
function refreshIcon(tabId, force = false) {
const oldIcon = tabMan.get(tabId, 'icon');
const newIcon = getIconName(tabMan.get(tabId, 'styleIds', 0));
// (changing the icon only for the main page, frameId = 0)
if (!force && oldIcon === newIcon) {
return;
}
tabMan.set(tabId, 'icon', newIcon);
setIcon({
path: getIconPath(newIcon),
tabId,
});
}
function getIconPath(icon) {
return ICON_SIZES.reduce(
(obj, size) => {
obj[size] = `/images/icon/${icon.replace('$SIZE$', size)}.png`;
return obj;
},
{}
);
}
/** @return {number | ''} */
function getStyleCount(tabId) {
const allIds = new Set();
const data = tabMan.get(tabId, 'styleIds') || {};
Object.values(data).forEach(frameIds => frameIds.forEach(id => allIds.add(id)));
return allIds.size || '';
}
// Caches imageData for icon paths
async function loadImage(url) {
const {OffscreenCanvas} = !FIREFOX && self.createImageBitmap && self || {};
const img = OffscreenCanvas
? await createImageBitmap(await (await fetch(url)).blob())
: await new Promise((resolve, reject) =>
Object.assign(new Image(), {
src: url,
onload: e => resolve(e.target),
onerror: reject,
}));
const {width: w, height: h} = img;
const canvas = OffscreenCanvas
? new OffscreenCanvas(w, h)
: Object.assign(document.createElement('canvas'), {width: w, height: h});
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, w, h);
const result = ctx.getImageData(0, 0, w, h);
imageDataCache.set(url, result);
return result;
}
function refreshGlobalIcon() {
setIcon({
path: getIconPath(getIconName()),
});
}
function refreshIconBadgeColor() {
setBadgeBackgroundColor({
color: badgeOvr.color ||
prefs.get(prefs.get('disableAll') ? 'badgeDisabled' : 'badgeNormal'),
});
}
function refreshAllIcons() {
for (const tabId of tabMan.list()) {
refreshIcon(tabId);
}
refreshGlobalIcon();
}
function refreshAllIconsBadgeText() {
for (const tabId of tabMan.list()) {
refreshIconBadgeText(tabId);
}
}
function refreshStaleBadges() {
for (const tabId of staleBadges) {
refreshIconBadgeText(tabId);
}
staleBadges.clear();
}
function safeCall(method, data) {
const {browserAction = {}} = chrome;
const fn = browserAction[method];
if (fn) {
try {
// Chrome supports the callback since 67.0.3381.0, see https://crbug.com/451320
fn.call(browserAction, data, ignoreChromeError);
} catch (e) {
// FIXME: skip pre-rendered tabs?
fn.call(browserAction, data);
}
}
}
/** @param {chrome.browserAction.TabIconDetails} data */
async function setIcon(data) {
if (hasCanvas === true || await hasCanvas) {
data.imageData = {};
for (const [key, url] of Object.entries(data.path)) {
data.imageData[key] = imageDataCache.get(url) || await loadImage(url);
}
delete data.path;
}
safeCall('setIcon', data);
}
/** @param {chrome.browserAction.BadgeTextDetails} data */
function setBadgeText(data) {
safeCall('setBadgeText', data);
}
/** @param {chrome.browserAction.BadgeBackgroundColorDetails} data */
function setBadgeBackgroundColor(data) {
safeCall('setBadgeBackgroundColor', data);
}
})();

View File

@ -0,0 +1,103 @@
/* global CHROME FIREFOX URLS deepEqual ignoreChromeError */// toolbox.js
/* global bgReady */// common.js
/* global msg */
'use strict';
/* exported navMan */
const navMan = (() => {
const listeners = new Set();
let prevData = {};
chrome.webNavigation.onCommitted.addListener(onNavigation.bind('committed'));
chrome.webNavigation.onHistoryStateUpdated.addListener(onFakeNavigation.bind('history'));
chrome.webNavigation.onReferenceFragmentUpdated.addListener(onFakeNavigation.bind('hash'));
return {
/** @param {function(data: Object, type: ('committed'|'history'|'hash'))} fn */
onUrlChange(fn) {
listeners.add(fn);
},
};
/** @this {string} type */
async function onNavigation(data) {
if (CHROME && data.timeStamp === prevData.timeStamp && deepEqual(data, prevData)) {
return; // Chrome bug: listener is called twice with identical data
}
prevData = data;
if (CHROME &&
URLS.chromeProtectsNTP &&
data.url.startsWith('https://www.google.') &&
data.url.includes('/_/chrome/newtab?')) {
// Modern Chrome switched to WebUI NTP so this is obsolete, but there may be exceptions
// TODO: investigate, and maybe use a separate listener for CHROME <= ver
const tab = await browser.tabs.get(data.tabId);
const url = tab.pendingUrl || tab.url;
if (url === 'chrome://newtab/') {
data.url = url;
}
}
listeners.forEach(fn => fn(data, this));
}
/** @this {string} type */
function onFakeNavigation(data) {
const {url, frameId} = data;
onNavigation.call(this, data);
msg.sendTab(data.tabId, {method: 'urlChanged', url}, {frameId})
.catch(msg.ignoreError);
}
})();
bgReady.all.then(() => {
/*
* Expose style version on greasyfork/sleazyfork 1) info page and 2) code page
* Not using manifest.json as adding a content script disables the extension on update.
*/
const urlMatches = '/scripts/\\d+[^/]*(/code)?([?#].*)?$';
chrome.webNavigation.onCommitted.addListener(({tabId}) => {
chrome.tabs.executeScript(tabId, {
file: '/content/install-hook-greasyfork.js',
runAt: 'document_start',
});
}, {
url: [
{hostEquals: 'greasyfork.org', urlMatches},
{hostEquals: 'sleazyfork.org', urlMatches},
],
});
/*
* Removes the Get Stylus button on style pages.
* Not using manifest.json as adding a content script disables the extension on update.
*/
chrome.webNavigation.onCommitted.addListener(({tabId}) => {
chrome.tabs.executeScript(tabId, {
file: '/content/install-hook-userstylesworld.js',
runAt: 'document_start',
});
}, {
url: [
{hostEquals: 'userstyles.world'},
],
});
/*
* FF misses some about:blank iframes so we inject our content script explicitly
*/
if (FIREFOX) {
chrome.webNavigation.onDOMContentLoaded.addListener(async ({tabId, frameId}) => {
if (frameId &&
!await msg.sendTab(tabId, {method: 'ping'}, {frameId}).catch(ignoreChromeError)) {
for (const file of chrome.runtime.getManifest().content_scripts[0].js) {
chrome.tabs.executeScript(tabId, {
frameId,
file,
matchAboutBlank: true,
}, ignoreChromeError);
}
}
}, {
url: [{urlEquals: 'about:blank'}],
});
}
});

791
background/style-manager.js Normal file
View File

@ -0,0 +1,791 @@
/* global API msg */// msg.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 */
/* global usercssMan */
/* global colorScheme */
'use strict';
/*
This style manager is a layer between content script and the DB. When a style
is added/updated, it broadcast a message to content script and the content
script would try to fetch the new code.
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>,
}} StyleMapData */
/** @type {Map<number,StyleMapData>} */
const dataMap = new Map();
/** @typedef {Object<styleId,{id: number, code: string[]}>} StyleSectionsToApply */
/** @type {Map<string,{maybeMatch: Set<styleId>, sections: StyleSectionsToApply}>} */
const cachedStyleForUrl = createCache({
onDeleted(url, cache) {
for (const section of Object.values(cache.sections)) {
const data = id2data(section.id);
if (data) data.appliesTo.delete(url);
}
},
});
const BAD_MATCHER = {test: () => false};
const compileRe = createCompiler(text => `^(${text})$`);
const compileSloppyRe = createCompiler(text => `^${text}$`);
const compileExclusion = createCompiler(buildExclusion);
const uuidv4 = crypto.randomUUID ? crypto.randomUUID.bind(crypto) : (() => {
const seeds = crypto.getRandomValues(new Uint16Array(8));
// 00001111-2222-M333-N444-555566667777
seeds[3] = seeds[3] & 0x0FFF | 0x4000; // UUID version 4, M = 4
seeds[4] = seeds[4] & 0x3FFF | 0x8000; // UUID variant 1, N = 8..0xB
return Array.from(seeds, hex4dashed).join('');
});
const MISSING_PROPS = {
name: style => `ID: ${style.id}`,
_id: () => uuidv4(),
_rev: () => Date.now(),
};
const DELETE_IF_NULL = ['id', 'customName', 'md5Url', 'originalMd5'];
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});
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');
}
}
});
//#endregion
//#region Exports
return {
/** @returns {Promise<number>} style id */
async delete(id, reason) {
if (ready.then) await ready;
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(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},
});
return id;
},
/** @returns {Promise<StyleObj>} */
async editSave(style) {
if (ready.then) await ready;
style = mergeWithMapped(style);
style.updateDate = Date.now();
return saveStyle(style, {reason: 'editSave'});
},
/** @returns {Promise<?StyleObj>} */
async find(...filters) {
if (ready.then) await ready;
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;
},
/** @returns {Promise<StyleObj[]>} */
async getAll() {
if (ready.then) await ready;
return getAllAsArray();
},
/** @returns {Promise<Object<string,StyleObj[]>>}>} */
async getAllOrdered(keys) {
if (ready.then) await ready;
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 {
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
so we'll use the real URL reported by webNavigation API.
TODO: if FF will do the same, this won't work as is: FF reports onCommitted too late */
url = tabMan.get(sender.tab.id, 'url', 0) || url;
}
let cache = cachedStyleForUrl.get(url);
if (!cache) {
cache = {
sections: {},
maybeMatch: new Set(),
};
buildCache(cache, url, dataMap.values());
cachedStyleForUrl.set(url, cache);
} else if (cache.maybeMatch.size) {
buildCache(cache, url, Array.from(cache.maybeMatch, id2data).filter(Boolean));
}
return Object.assign({cfg: {exposeStyleName, order}},
id ? mapObj(cache.sections, null, [id])
: cache.sections);
},
/** @returns {Promise<StyleObj>} */
async get(id) {
if (ready.then) await ready;
return id2style(id);
},
/** @returns {Promise<StylesByUrlResult[]>} */
async getByUrl(url, id = null) {
if (ready.then) await ready;
// FIXME: do we want to cache this? Who would like to open popup rapidly
// or search the DB with the same URL?
const result = [];
const styles = id
? [id2style(id)].filter(Boolean)
: getAllAsArray();
const query = new MatchQuery(url);
for (const style of styles) {
let excluded = false;
let excludedScheme = false;
let included = false;
let sloppy = false;
let sectionMatched = false;
const match = urlMatchStyle(query, style);
// TODO: enable this when the function starts returning false
// if (match === false) {
// continue;
// }
if (match === 'included') {
included = true;
}
if (match === 'excluded') {
excluded = true;
}
if (match === 'excludedScheme') {
excludedScheme = true;
}
for (const section of style.sections) {
const match = urlMatchSection(query, section, true);
if (match) {
if (match === 'sloppy') {
sloppy = true;
}
sectionMatched = true;
break;
}
}
if (sectionMatched || included) {
result.push(/** @namespace StylesByUrlResult */ {
style, excluded, sloppy, excludedScheme, sectionMatched, included});
}
}
return result;
},
/** @returns {Promise<StyleObj[]>} */
async importMany(items) {
if (ready.then) await ready;
for (const style of items) {
beforeSave(style);
if (style.sourceCode && style.usercssData) {
await usercssMan.buildCode(style);
}
}
const events = await db.styles.putMany(items);
return Promise.all(items.map((item, i) =>
handleSave(item, {reason: 'import'}, events[i])
));
},
/** @returns {Promise<StyleObj>} */
async install(style, reason = null) {
if (ready.then) await ready;
reason = reason || dataMap.has(style.id) ? 'update' : 'install';
style = mergeWithMapped(style);
style.originalDigest = await calcStyleDigest(style);
// FIXME: update updateDate? what about usercss config?
return saveStyle(style, {reason});
},
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;
const style = Object.assign({}, id2style(id), {enabled});
await saveStyle(style, {reason: 'toggle'});
return id;
},
// using bind() to skip step-into when debugging
/** @returns {Promise<StyleObj>} */
addExclusion: addIncludeExclude.bind(null, 'exclusions'),
/** @returns {Promise<StyleObj>} */
addInclusion: addIncludeExclude.bind(null, 'inclusions'),
/** @returns {Promise<?StyleObj>} */
removeExclusion: removeIncludeExclude.bind(null, 'exclusions'),
/** @returns {Promise<?StyleObj>} */
removeInclusion: removeIncludeExclude.bind(null, 'inclusions'),
async config(id, prop, value) {
if (ready.then) await ready;
const style = Object.assign({}, id2style(id));
const {preview = {}} = dataMap.get(id);
style[prop] = preview[prop] = value;
return saveStyle(style, {reason: 'config'});
},
};
//#endregion
//#region Implementation
/** @returns {StyleMapData} */
function id2data(id) {
return dataMap.get(id);
}
/** @returns {?StyleObj} */
function id2style(id) {
return (dataMap.get(Number(id)) || {}).style;
}
/** @returns {?StyleObj} */
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} */
function createNewStyle() {
return /** @namespace StyleObj */ {
enabled: true,
updateUrl: null,
md5Url: null,
url: null,
originalMd5: null,
installDate: Date.now(),
};
}
/** @returns {void} */
function storeInMap(style) {
dataMap.set(style.id, {
style,
appliesTo: new Set(),
});
uuidIndex.set(style._id, style.id);
}
/** @returns {StyleObj} */
function mergeWithMapped(style) {
return Object.assign({},
id2style(style.id) || createNewStyle(),
style);
}
function handleDraft(port) {
const id = port.name.split(':').pop();
port.onDisconnect.addListener(() => API.drafts.delete(Number(id) || id));
}
function handleLivePreview(port) {
let id;
port.onMessage.addListener(style => {
if (!id) id = style.id;
const data = id2data(id);
data.preview = style;
broadcastStyleUpdated(style, 'editPreview');
});
port.onDisconnect.addListener(() => {
port = null;
if (id) {
const data = id2data(id);
if (data) {
data.preview = null;
broadcastStyleUpdated(data.style, 'editPreviewEnd');
}
}
});
}
async function addIncludeExclude(type, id, rule) {
if (ready.then) await ready;
const style = Object.assign({}, id2style(id));
const list = style[type] || (style[type] = []);
if (list.includes(rule)) {
throw new Error('The rule already exists');
}
style[type] = list.concat([rule]);
return saveStyle(style, {reason: 'config'});
}
async function removeIncludeExclude(type, id, rule) {
if (ready.then) await ready;
const style = Object.assign({}, id2style(id));
const list = style[type];
if (!list || !list.includes(rule)) {
return;
}
style[type] = list.filter(r => r !== rule);
return saveStyle(style, {reason: 'config'});
}
function broadcastStyleUpdated(style, reason, method = 'styleUpdated') {
const {id} = style;
const data = id2data(id);
const excluded = new Set();
const updated = new Set();
for (const [url, cache] of cachedStyleForUrl.entries()) {
if (!data.appliesTo.has(url)) {
cache.maybeMatch.add(id);
continue;
}
const code = getAppliedCode(new MatchQuery(url), style);
if (code) {
updated.add(url);
buildCacheEntry(cache, style, code);
} else {
excluded.add(url);
delete cache.sections[id];
}
}
data.appliesTo = updated;
return msg.broadcast({
method,
reason,
style: {
id,
md5Url: style.md5Url,
enabled: style.enabled,
},
});
}
function beforeSave(style) {
if (!style.name) {
throw new Error('Style name is empty');
}
for (const key of DELETE_IF_NULL) {
if (style[key] == null) {
delete style[key];
}
}
if (!style._id) {
style._id = uuidv4();
}
style._rev = Date.now();
fixKnownProblems(style);
}
async function saveStyle(style, handlingOptions) {
beforeSave(style);
const newId = await db.styles.put(style);
return handleSave(style, handlingOptions, newId);
}
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;
}
// get styles matching a URL, including sloppy regexps and excluded items.
function getAppliedCode(query, data) {
const result = urlMatchStyle(query, data);
if (result === 'included') {
// return all sections
return data.sections.map(s => s.code);
}
if (result !== true) {
return;
}
const code = [];
for (const section of data.sections) {
if (urlMatchSection(query, section) === true && !styleCodeEmpty(section.code)) {
code.push(section.code);
}
}
return code.length && code;
}
async function init() {
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.styles.putMany(updated);
}
setOrder(await orderPromise, {store: false});
styles.forEach(storeInMap);
ready = true;
bgReady._resolveStyles();
}
function fixKnownProblems(style, initIndex, initArray) {
let res = 0;
for (const key in MISSING_PROPS) {
if (!style[key]) {
style[key] = MISSING_PROPS[key](style);
res = 1;
}
}
/* Upgrade the old way of customizing local names */
const {originalName} = style;
if (originalName) {
if (originalName !== style.name) {
style.customName = style.name;
style.name = originalName;
}
delete style.originalName;
res = 1;
}
/* wrong homepage url in 1.5.20-1.5.21 due to commit 1e5f118d */
for (const key of ['url', 'installationUrl']) {
const url = style[key];
const fixedUrl = url && url.replace(/([^:]\/)\//, '$1');
if (fixedUrl !== url) {
res = 1;
style[key] = fixedUrl;
}
}
let url;
/* USO bug, duplicate "update" subdomain, see #523 */
if ((url = style.md5Url) && url.includes('update.update.userstyles')) {
res = style.md5Url = url.replace('update.update.userstyles', 'update.userstyles');
}
/* Default homepage URL for external styles installed from a known distro */
if (
(!style.url || !style.installationUrl) &&
(url = style.updateUrl) &&
(url = URLS.extractGreasyForkInstallUrl(url) ||
URLS.extractUsoArchiveInstallUrl(url) ||
URLS.extractUSwInstallUrl(url)
)
) {
if (!style.url) res = style.url = url;
if (!style.installationUrl) res = style.installationUrl = url;
}
/* @import must precede `vars` that we add at beginning */
if (
initArray &&
!isEmptyObj((style.usercssData || {}).vars) &&
style.sections.some(({code}) =>
code.startsWith(':root {\n --') &&
/@import\s/i.test(code))
) {
return usercssMan.buildCode(style);
}
return res && style;
}
function urlMatchStyle(query, style) {
if (
style.exclusions &&
style.exclusions.some(e => compileExclusion(e).test(query.urlWithoutParams))
) {
return 'excluded';
}
if (!style.enabled) {
return 'disabled';
}
if (!colorScheme.shouldIncludeStyle(style)) {
return 'excludedScheme';
}
if (
style.inclusions &&
style.inclusions.some(r => compileExclusion(r).test(query.urlWithoutParams))
) {
return 'included';
}
return true;
}
function urlMatchSection(query, section, skipEmptyGlobal) {
let dd, ddL, pp, ppL, rr, rrL, uu, uuL;
if (
(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;
}
/*
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 (rrL && rr.some(urlMatchRegexpSloppy, query)) {
return 'sloppy';
}
// TODO: check for invalid regexps?
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) {
// FIXME: FIFO cache doesn't work well here, if we want to match many
// regexps more than the cache size, we will never hit the cache because
// the first cache is deleted. So we use a simple map but it leaks memory.
const cache = new Map();
return text => {
let re = cache.get(text);
if (!re) {
re = tryRegExp(compile(text));
if (!re) {
re = BAD_MATCHER;
}
cache.set(text, re);
}
return re;
};
}
function compileGlob(text) {
return stringAsRegExp(text, '', true)
.replace(/\\\\\\\*|\\\*/g, m => m.length > 2 ? m : '.*');
}
function buildExclusion(text) {
// match pattern
const match = text.match(/^(\*|[\w-]+):\/\/(\*\.)?([\w.]+\/.*)/);
if (!match) {
return '^' + compileGlob(text) + '$';
}
return '^' +
(match[1] === '*' ? '[\\w-]+' : match[1]) +
'://' +
(match[2] ? '(?:[\\w.]+\\.)?' : '') +
compileGlob(match[3]) +
'$';
}
function buildCache(cache, url, styleList) {
const query = new MatchQuery(url);
for (const {style, appliesTo, preview} of styleList) {
const code = getAppliedCode(query, preview || style);
if (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
})();

View File

@ -0,0 +1,108 @@
/* global API */// msg.js
/* global RX_META debounce stringAsRegExp tryRegExp */// toolbox.js
/* global addAPI */// common.js
'use strict';
(() => {
// toLocaleLowerCase cache, autocleared after 1 minute
const cache = new Map();
const METAKEYS = ['customName', 'name', 'url', 'installationUrl', 'updateUrl'];
const extractMeta = style =>
style.usercssData
? (style.sourceCode.match(RX_META) || [''])[0]
: null;
const stripMeta = style =>
style.usercssData
? style.sourceCode.replace(RX_META, '')
: null;
const MODES = Object.assign(Object.create(null), {
code: (style, test) =>
style.usercssData
? test(stripMeta(style))
: searchSections(style, test, 'code'),
meta: (style, test, part) =>
METAKEYS.some(key => test(style[key])) ||
test(part === 'all' ? style.sourceCode : extractMeta(style)) ||
searchSections(style, test, 'funcs'),
name: (style, test) =>
test(style.customName) ||
test(style.name),
all: (style, test) =>
MODES.meta(style, test, 'all') ||
!style.usercssData && MODES.code(style, test),
});
addAPI(/** @namespace API */ {
styles: {
/**
* @param params
* @param {string} params.query - 1. url:someurl 2. text (may contain quoted parts like "qUot Ed")
* @param {'name'|'meta'|'code'|'all'|'url'} [params.mode=all]
* @param {number[]} [params.ids] - if not specified, all styles are searched
* @returns {number[]} - array of matched styles ids
*/
async searchDB({query, mode = 'all', ids}) {
let res = [];
if (mode === 'url' && query) {
res = (await API.styles.getByUrl(query)).map(r => r.style.id);
} else if (mode in MODES) {
const modeHandler = MODES[mode];
const m = /^\/(.+?)\/([gimsuy]*)$/.exec(query);
const rx = m && tryRegExp(m[1], m[2]);
const test = rx ? rx.test.bind(rx) : createTester(query);
res = (await API.styles.getAll())
.filter(style =>
(!ids || ids.includes(style.id)) &&
(!query || modeHandler(style, test)))
.map(style => style.id);
if (cache.size) debounce(clearCache, 60e3);
}
return res;
},
},
});
function createTester(query) {
const flags = `u${lower(query) === query ? 'i' : ''}`;
const words = query
.split(/(".*?")|\s+/)
.filter(Boolean)
.map(w => w.startsWith('"') && w.endsWith('"')
? w.slice(1, -1)
: w)
.filter(w => w.length > 1);
const rxs = (words.length ? words : [query])
.map(w => stringAsRegExp(w, flags));
return text => rxs.every(rx => rx.test(text));
}
function searchSections({sections}, test, part) {
const inCode = part === 'code' || part === 'all';
const inFuncs = part === 'funcs' || part === 'all';
for (const section of sections) {
for (const prop in section) {
const value = section[prop];
if (inCode && prop === 'code' && test(value) ||
inFuncs && Array.isArray(value) && value.some(str => test(str))) {
return true;
}
}
}
}
function lower(text) {
let result = cache.get(text);
if (!result) cache.set(text, result = text.toLocaleLowerCase());
return result;
}
function clearCache() {
cache.clear();
}
})();

234
background/style-via-api.js Normal file
View File

@ -0,0 +1,234 @@
/* global API */// msg.js
/* global addAPI */// common.js
/* global isEmptyObj */// toolbox.js
/* global prefs */
'use strict';
/**
* Uses chrome.tabs.insertCSS
*/
(() => {
const ACTIONS = {
styleApply,
styleDeleted,
styleUpdated,
styleAdded,
styleReplaceAll,
prefChanged,
updateCount,
};
const NOP = new Error('NOP');
const onError = () => {};
/* <tabId>: Object
<frameId>: Object
url: String, non-enumerable
<styleId>: Array of strings
section code */
const cache = new Map();
let observingTabs = false;
addAPI(/** @namespace API */ {
async styleViaAPI(request) {
try {
const fn = ACTIONS[request.method];
return fn ? fn(request, this.sender) : NOP;
} catch (e) {}
maybeToggleObserver();
},
});
function updateCount(request, sender) {
const {tab, frameId} = sender;
if (frameId) {
throw new Error('we do not count styles for frames');
}
const {frameStyles} = getCachedData(tab.id, frameId);
API.updateIconBadge.call({sender}, Object.keys(frameStyles));
}
function styleApply({id = null, ignoreUrlCheck = false}, {tab, frameId, url}) {
if (prefs.get('disableAll')) {
return NOP;
}
const {tabFrames, frameStyles} = getCachedData(tab.id, frameId);
if (id === null && !ignoreUrlCheck && frameStyles.url === url) {
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;
const code = section.code.join('\n');
if (code === (frameStyles[styleId] || []).join('\n')) {
continue;
}
frameStyles[styleId] = section.code;
tasks.push(
browser.tabs.insertCSS(tab.id, {
code,
frameId,
runAt: 'document_start',
matchAboutBlank: true,
}).catch(onError));
}
if (!removeFrameIfEmpty(tab.id, frameId, tabFrames, frameStyles)) {
Object.defineProperty(frameStyles, 'url', {value: url, configurable: true});
tabFrames[frameId] = frameStyles;
cache.set(tab.id, tabFrames);
}
return Promise.all(tasks);
})
.then(() => updateCount(null, {tab, frameId}));
}
function styleDeleted({style: {id}}, {tab, frameId}) {
const {tabFrames, frameStyles, styleSections} = getCachedData(tab.id, frameId, id);
const code = styleSections.join('\n');
if (code && !duplicateCodeExists({frameStyles, id, code})) {
delete frameStyles[id];
removeFrameIfEmpty(tab.id, frameId, tabFrames, frameStyles);
return removeCSS(tab.id, frameId, code)
.then(() => updateCount(null, {tab, frameId}));
} else {
return NOP;
}
}
function styleUpdated({style}, sender) {
if (!style.enabled) {
return styleDeleted({style}, sender);
}
const {tab, frameId} = sender;
const {frameStyles, styleSections} = getCachedData(tab.id, frameId, style.id);
const code = styleSections.join('\n');
return styleApply(style, sender).then(code && (() => {
if (!duplicateCodeExists({frameStyles, code, id: null})) {
return removeCSS(tab.id, frameId, code);
}
}));
}
function styleAdded({style}, sender) {
return style.enabled ? styleApply(style, sender) : NOP;
}
function styleReplaceAll(request, sender) {
const {tab, frameId} = sender;
const oldStylesCode = getFrameStylesJoined(sender);
return styleApply({ignoreUrlCheck: true}, sender).then(() => {
const newStylesCode = getFrameStylesJoined(sender);
const tasks = oldStylesCode
.filter(code => !newStylesCode.includes(code))
.map(code => removeCSS(tab.id, frameId, code));
return Promise.all(tasks);
});
}
function prefChanged({prefs}, sender) {
if ('disableAll' in prefs) {
if (!prefs.disableAll) {
return styleApply({}, sender);
}
const {tab, frameId} = sender;
const {tabFrames, frameStyles} = getCachedData(tab.id, frameId);
if (isEmptyObj(frameStyles)) {
return NOP;
}
removeFrameIfEmpty(tab.id, frameId, tabFrames, {});
const tasks = Object.keys(frameStyles)
.map(id => removeCSS(tab.id, frameId, frameStyles[id].join('\n')));
return Promise.all(tasks);
} else {
return NOP;
}
}
/* utilities */
function maybeToggleObserver() {
let method;
if (!observingTabs && cache.size) {
method = 'addListener';
} else if (observingTabs && !cache.size) {
method = 'removeListener';
} else {
return;
}
observingTabs = !observingTabs;
chrome.webNavigation.onCommitted[method](onNavigationCommitted);
chrome.tabs.onRemoved[method](onTabRemoved);
chrome.tabs.onReplaced[method](onTabReplaced);
}
function onNavigationCommitted({tabId, frameId}) {
if (frameId === 0) {
onTabRemoved(tabId);
return;
}
const tabFrames = cache.get(tabId);
if (tabFrames && frameId in tabFrames) {
delete tabFrames[frameId];
if (isEmptyObj(tabFrames)) {
onTabRemoved(tabId);
}
}
}
function onTabRemoved(tabId) {
cache.delete(tabId);
maybeToggleObserver();
}
function onTabReplaced(addedTabId, removedTabId) {
onTabRemoved(removedTabId);
}
function removeFrameIfEmpty(tabId, frameId, tabFrames, frameStyles) {
if (isEmptyObj(frameStyles)) {
delete tabFrames[frameId];
if (isEmptyObj(tabFrames)) {
cache.delete(tabId);
}
return true;
}
}
function getCachedData(tabId, frameId, styleId) {
const tabFrames = cache.get(tabId) || {};
const frameStyles = tabFrames[frameId] || {};
const styleSections = styleId && frameStyles[styleId] || [];
return {tabFrames, frameStyles, styleSections};
}
function getFrameStylesJoined({
tab,
frameId,
frameStyles = getCachedData(tab.id, frameId).frameStyles,
}) {
return Object.keys(frameStyles).map(id => frameStyles[id].join('\n'));
}
function duplicateCodeExists({
tab,
frameId,
frameStyles = getCachedData(tab.id, frameId).frameStyles,
frameStylesCode = {},
id,
code = frameStylesCode[id] || frameStyles[id].join('\n'),
}) {
id = String(id);
for (const styleId in frameStyles) {
if (id !== styleId &&
code === (frameStylesCode[styleId] || frameStyles[styleId].join('\n'))) {
return true;
}
}
}
function removeCSS(tabId, frameId, code) {
return browser.tabs.removeCSS(tabId, {frameId, code, matchAboutBlank: true})
.catch(onError);
}
})();

View File

@ -0,0 +1,166 @@
/* global API */// msg.js
/* global CHROME URLS ignoreChromeError */// toolbox.js
/* global prefs */
'use strict';
(() => {
const idCSP = 'patchCsp';
const idOFF = 'disableAll';
const idXHR = 'styleViaXhr';
const rxHOST = /^('none'|(https?:\/\/)?[^']+?[^:'])$/; // strips CSP sources covered by *
const blobUrlPrefix = 'blob:' + chrome.runtime.getURL('/');
/** @type {Object<string,StylesToPass>} */
const stylesToPass = {};
const state = {};
const injectedCode = CHROME && `${data => {
if (self.INJECTED !== 1) { // storing data only if apply.js hasn't run yet
window[Symbol.for('styles')] = data;
}
}}`;
toggle();
prefs.subscribe([idXHR, idOFF, idCSP], toggle);
function toggle() {
const off = prefs.get(idOFF);
const csp = prefs.get(idCSP) && !off;
const xhr = prefs.get(idXHR) && !off;
if (xhr === state.xhr && csp === state.csp && off === state.off) {
return;
}
const reqFilter = {
urls: ['*://*/*'],
types: ['main_frame', 'sub_frame'],
};
chrome.webNavigation.onCommitted.removeListener(injectData);
chrome.webRequest.onBeforeRequest.removeListener(prepareStyles);
chrome.webRequest.onHeadersReceived.removeListener(modifyHeaders);
if (xhr || csp) {
// We unregistered it above so that the optional EXTRA_HEADERS is properly re-registered
chrome.webRequest.onHeadersReceived.addListener(modifyHeaders, reqFilter, [
'blocking',
'responseHeaders',
xhr && chrome.webRequest.OnHeadersReceivedOptions.EXTRA_HEADERS,
].filter(Boolean));
}
if (CHROME ? !off : xhr || csp) {
chrome.webRequest.onBeforeRequest.addListener(prepareStyles, reqFilter);
}
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;
}
/** @param {chrome.webRequest.WebRequestBodyDetails} req */
async function prepareStyles(req) {
const sections = await API.styles.getSectionsByUrl(req.url);
stylesToPass[req2key(req)] = /** @namespace StylesToPass */ {
blobId: '',
str: JSON.stringify(sections),
timer: setTimeout(cleanUp, 600e3, req),
};
}
function injectData(req) {
const data = stylesToPass[req2key(req)];
if (data && !data.injected) {
data.injected = true;
chrome.tabs.executeScript(req.tabId, {
frameId: req.frameId,
runAt: 'document_start',
code: `(${injectedCode})(${data.str})`,
}, ignoreChromeError);
if (!state.xhr) cleanUp(req);
}
}
/** @param {chrome.webRequest.WebResponseHeadersDetails} req */
function modifyHeaders(req) {
const {responseHeaders} = req;
const data = stylesToPass[req2key(req)];
if (!data || data.str === '{}') {
cleanUp(req);
return;
}
if (state.xhr) {
data.blobId = URL.createObjectURL(new Blob([data.str])).slice(blobUrlPrefix.length);
responseHeaders.push({
name: 'Set-Cookie',
value: `${chrome.runtime.id}=${data.blobId}`,
});
}
const csp = state.csp &&
responseHeaders.find(h => h.name.toLowerCase() === 'content-security-policy');
if (csp) {
patchCsp(csp);
}
if (state.xhr || csp) {
return {responseHeaders};
}
}
/** @param {chrome.webRequest.HttpHeader} csp */
function patchCsp(csp) {
const src = {};
for (let p of csp.value.split(';')) {
p = p.trim().split(/\s+/);
src[p[0]] = p.slice(1);
}
// Allow style assets
patchCspSrc(src, 'img-src', 'data:', '*');
patchCspSrc(src, 'font-src', 'data:', '*');
// Allow our DOM styles, allow @import from any URL
patchCspSrc(src, 'style-src', "'unsafe-inline'", '*');
// Allow our XHR cookies in CSP sandbox (known case: raw github urls)
if (src.sandbox && !src.sandbox.includes('allow-same-origin')) {
src.sandbox.push('allow-same-origin');
}
csp.value = Object.entries(src).map(([k, v]) =>
`${k}${v.length ? ' ' : ''}${v.join(' ')}`).join('; ');
}
function patchCspSrc(src, name, ...values) {
let def = src['default-src'];
let list = src[name];
if (def || list) {
if (!def) def = [];
if (!list) list = [...def];
if (values.includes('*')) list = src[name] = list.filter(v => !rxHOST.test(v));
list.push(...values.filter(v => !list.includes(v) && !def.includes(v)));
if (!list.length) delete src[name];
}
}
function cleanUp(req) {
const key = req2key(req);
const data = stylesToPass[key];
if (data) {
delete stylesToPass[key];
clearTimeout(data.timer);
if (data.blobId) {
URL.revokeObjectURL(blobUrlPrefix + data.blobId);
}
}
}
/** @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;
}
})();

307
background/sync-manager.js Normal file
View File

@ -0,0 +1,307 @@
/* global API msg */// msg.js
/* global bgReady uuidIndex */// common.js
/* global chromeLocal chromeSync */// storage-util.js
/* global db */
/* global iconMan */
/* global prefs */
/* global styleUtil */
/* global tokenMan */
'use strict';
const syncMan = (() => {
//#region Init
const SYNC_DELAY = 1; // minutes
const SYNC_INTERVAL = 30; // minutes
const STATES = Object.freeze({
connected: 'connected',
connecting: 'connecting',
disconnected: 'disconnected',
disconnecting: 'disconnecting',
});
const STORAGE_KEY = 'sync/state/';
const NO_LOGIN = ['webdav'];
const status = /** @namespace SyncManager.Status */ {
STATES,
state: STATES.disconnected,
syncing: false,
progress: null,
currentDriveName: null,
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 = bgReady.styles.then(() => {
ready = true;
prefs.subscribe('sync.enabled',
(_, val) => val === 'none'
? syncMan.stop()
: syncMan.start(val, true),
{runNow: true});
});
chrome.alarms.onAlarm.addListener(async ({name}) => {
if (name === 'syncNow') {
await syncMan.syncNow();
}
});
//#endregion
//#region Exports
return {
async delete(...args) {
if (ready.then) await ready;
if (!currentDrive) return;
schedule();
return ctrl.delete(...args);
},
/** @returns {Promise<SyncManager.Status>} */
async getStatus() {
return status;
},
async login(name) {
if (ready.then) await ready;
if (!name) name = prefs.get('sync.enabled');
await tokenMan.revokeToken(name);
try {
await tokenMan.getToken(name, true);
status.login = true;
} catch (err) {
status.login = false;
throw err;
} finally {
emitStatusChange();
}
},
async putDoc({_id, _rev}) {
if (ready.then) await ready;
if (!currentDrive) return;
schedule();
return ctrl.put(_id, _rev);
},
async setDriveOptions(driveName, options) {
const key = `secure/sync/driveOptions/${driveName}`;
await chromeSync.setValue(key, options);
},
async getDriveOptions(driveName) {
const key = `secure/sync/driveOptions/${driveName}`;
return await chromeSync.getValue(key) || {};
},
async start(name, fromPref = false) {
if (ready.then) await ready;
if (!ctrl) await initController();
if (currentDrive) return;
currentDrive = await getDrive(name);
ctrl.use(currentDrive);
status.state = STATES.connecting;
status.currentDriveName = currentDrive.name;
emitStatusChange();
if (fromPref || NO_LOGIN.includes(currentDrive.name)) {
status.login = true;
} else {
try {
await syncMan.login(name);
} catch (err) {
console.error(err);
status.errorMessage = err.message;
lastError = err;
emitStatusChange();
return syncMan.stop();
}
}
await ctrl.init();
await syncMan.syncNow(name);
prefs.set('sync.enabled', name);
status.state = STATES.connected;
schedule(SYNC_INTERVAL);
emitStatusChange();
},
async stop() {
if (ready.then) await ready;
if (!currentDrive) return;
chrome.alarms.clear('syncNow');
status.state = STATES.disconnecting;
emitStatusChange();
try {
await ctrl.uninit();
await tokenMan.revokeToken(currentDrive.name);
await chromeLocal.remove(STORAGE_KEY + currentDrive.name);
} catch (e) {}
currentDrive = null;
prefs.set('sync.enabled', 'none');
status.state = STATES.disconnected;
status.currentDriveName = null;
status.login = false;
emitStatusChange();
},
async syncNow() {
if (ready.then) await ready;
if (!currentDrive || !status.login) {
console.warn('cannot sync when disconnected');
return;
}
try {
await ctrl.syncNow();
status.errorMessage = null;
lastError = null;
} catch (err) {
err.message = translateErrorMessage(err);
status.errorMessage = err.message;
lastError = err;
if (isGrantError(err)) {
status.login = false;
}
}
emitStatusChange();
},
};
//#endregion
//#region Utils
async function initController() {
await require(['/vendor/db-to-cloud/db-to-cloud']); /* global dbToCloud */
ctrl = dbToCloud.dbToCloud({
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'});
}
},
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 Object.values(uuidIndex.custom).concat(await API.styles.getAll())) {
ctrl.put(i._id, i._rev);
}
},
onProgress(e) {
if (e.phase === 'start') {
status.syncing = true;
} else if (e.phase === 'end') {
status.syncing = false;
status.progress = null;
} else {
status.progress = e;
}
emitStatusChange();
},
compareRevision,
getState(drive) {
return chromeLocal.getValue(STORAGE_KEY + drive.name);
},
setState(drive, state) {
return chromeLocal.setValue(STORAGE_KEY + drive.name, state);
},
retryMaxAttempts: 10,
retryExp: 1.2,
retryDelay: 6,
});
}
function emitStatusChange() {
msg.broadcastExtension({method: 'syncStatusUpdate', status});
iconMan.overrideBadge(getErrorBadge());
}
function isNetworkError(err) {
return (
err.name === 'TypeError' && /networkerror|failed to fetch/i.test(err.message) ||
err.code === 502
);
}
function isGrantError(err) {
if (err.code === 401) return true;
if (err.code === 400 && /invalid_grant/.test(err.message)) return true;
if (err.name === 'TokenError') return true;
return false;
}
function getErrorBadge() {
if (status.state === STATES.connected &&
(!status.login || lastError && !isNetworkError(lastError))) {
return {
text: 'x',
color: '#F00',
title: !status.login ? 'syncErrorRelogin' : `${
chrome.i18n.getMessage('syncError')
}\n---------------------\n${
// splitting to limit each line length
lastError.message.replace(/.{60,}?\s(?=.{30,})/g, '$&\n')
}`,
};
}
}
async function getDrive(name) {
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
periodInMinutes: SYNC_INTERVAL,
});
}
function translateErrorMessage(err) {
if (err.name === 'LockError') {
return browser.i18n.getMessage('syncErrorLock', new Date(err.expire).toLocaleString([], {timeStyle: 'short'}));
}
return err.message || String(err);
}
//#endregion
})();

62
background/tab-manager.js Normal file
View File

@ -0,0 +1,62 @@
/* global bgReady */// common.js
/* global navMan */
'use strict';
const tabMan = (() => {
const listeners = new Set();
const cache = new Map();
chrome.tabs.onRemoved.addListener(tabId => cache.delete(tabId));
chrome.tabs.onReplaced.addListener((added, removed) => cache.delete(removed));
bgReady.all.then(() => {
navMan.onUrlChange(({tabId, frameId, url}) => {
const oldUrl = !frameId && tabMan.get(tabId, 'url', frameId);
tabMan.set(tabId, 'url', frameId, url);
if (frameId) return;
for (const fn of listeners) {
try {
fn({tabId, url, oldUrl});
} catch (err) {
console.error(err);
}
}
});
});
return {
onUpdate(fn) {
listeners.add(fn);
},
get(tabId, ...keys) {
return keys.reduce((meta, key) => meta && meta[key], cache.get(tabId));
},
/**
* number of keys is arbitrary, last arg is value, `undefined` will delete the last key from meta
* (tabId, 'foo', 123) will set tabId's meta to {foo: 123},
* (tabId, 'foo', 'bar', 'etc', 123) will set tabId's meta to {foo: {bar: {etc: 123}}}
*/
set(tabId, ...args) {
let meta = cache.get(tabId);
if (!meta) {
meta = {};
cache.set(tabId, meta);
}
const value = args.pop();
const lastKey = args.pop();
for (const key of args) meta = meta[key] || (meta[key] = {});
if (value === undefined) {
delete meta[lastKey];
} else {
meta[lastKey] = value;
}
},
/** @returns {IterableIterator<number>} */
list() {
return cache.keys();
},
};
})();

270
background/token-manager.js Normal file
View File

@ -0,0 +1,270 @@
/* global FIREFOX getActiveTab waitForTabUrl URLS */// toolbox.js
/* global chromeLocal */// storage-util.js
'use strict';
/* exported tokenMan */
const tokenMan = (() => {
const AUTH = {
dropbox: {
flow: 'token',
clientId: 'zg52vphuapvpng9',
authURL: 'https://www.dropbox.com/oauth2/authorize',
tokenURL: 'https://api.dropboxapi.com/oauth2/token',
revoke: token =>
fetch('https://api.dropboxapi.com/2/auth/token/revoke', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
},
}),
},
google: {
flow: 'code',
clientId: '283762574871-d4u58s4arra5jdan2gr00heasjlttt1e.apps.googleusercontent.com',
clientSecret: 'J0nc5TlR_0V_ex9-sZk-5faf',
authURL: 'https://accounts.google.com/o/oauth2/v2/auth',
authQuery: {
// NOTE: Google needs 'prompt' parameter to deliver multiple refresh
// tokens for multiple machines.
// https://stackoverflow.com/q/18519185
access_type: 'offline',
prompt: 'consent',
},
tokenURL: 'https://oauth2.googleapis.com/token',
scopes: ['https://www.googleapis.com/auth/drive.appdata'],
// FIXME: https://github.com/openstyles/stylus/issues/1248
// revoke: token => {
// const params = {token};
// return postQuery(`https://accounts.google.com/o/oauth2/revoke?${new URLSearchParams(params)}`);
// },
},
onedrive: {
flow: 'code',
clientId: '3864ce03-867c-4ad8-9856-371a097d47b1',
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',
scopes: ['Files.ReadWrite.AppFolder', 'offline_access'],
},
userstylesworld: {
flow: 'code',
clientId: 'zeDmKhJIfJqULtcrGMsWaxRtWHEimKgS',
clientSecret: 'wqHsvTuThQmXmDiVvOpZxPwSIbyycNFImpAOTxjaIRqDbsXcTOqrymMJKsOMuibFaij' +
'ZZAkVYTDbLkQuYFKqgpMsMlFlgwQOYHvHFbgxQHDTwwdOroYhOwFuekCwXUlk',
authURL: URLS.usw + 'api/oauth/style/link',
tokenURL: URLS.usw + 'api/oauth/token',
redirect_uri: 'https://gusted.xyz/callback_helper/',
},
};
const NETWORK_LATENCY = 30; // seconds
const DEFAULT_REDIRECT_URI = 'https://clngdbkpkpeebahjckkjfobafhncgmne.chromiumapp.org/';
let alwaysUseTab = !chrome.windows || (FIREFOX ? false : null);
class TokenError extends Error {
constructor(provider, message) {
super(`[${provider}] ${message}`);
this.name = 'TokenError';
this.provider = provider;
if (Error.captureStackTrace) {
Error.captureStackTrace(this, TokenError);
}
}
}
return {
buildKeys(name, hooks) {
const prefix = `secure/token/${hooks ? hooks.keyName(name) : name}/`;
const k = {
TOKEN: `${prefix}token`,
EXPIRE: `${prefix}expire`,
REFRESH: `${prefix}refresh`,
};
k.LIST = Object.values(k);
return k;
},
getClientId(name) {
return AUTH[name].clientId;
},
async getToken(name, interactive, hooks) {
const k = tokenMan.buildKeys(name, hooks);
const obj = await chromeLocal.get(k.LIST);
if (obj[k.TOKEN]) {
if (!obj[k.EXPIRE] || Date.now() < obj[k.EXPIRE]) {
return obj[k.TOKEN];
}
if (obj[k.REFRESH]) {
return refreshToken(name, k, obj);
}
}
if (!interactive) {
throw new TokenError(name, 'Token is missing');
}
return authUser(k, name, interactive, hooks);
},
async revokeToken(name, hooks) {
const provider = AUTH[name];
const k = tokenMan.buildKeys(name, hooks);
if (provider.revoke) {
try {
const token = await chromeLocal.getValue(k.TOKEN);
if (token) await provider.revoke(token);
} catch (e) {
console.error(e);
}
}
await chromeLocal.remove(k.LIST);
},
};
async function refreshToken(name, k, obj) {
if (!obj[k.REFRESH]) {
throw new TokenError(name, 'No refresh token');
}
const provider = AUTH[name];
const body = {
client_id: provider.clientId,
refresh_token: obj[k.REFRESH],
grant_type: 'refresh_token',
scope: provider.scopes.join(' '),
};
if (provider.clientSecret) {
body.client_secret = provider.clientSecret;
}
const result = await postQuery(provider.tokenURL, body);
if (!result.refresh_token) {
// reuse old refresh token
result.refresh_token = obj[k.REFRESH];
}
return handleTokenResult(result, k);
}
async function authUser(keys, name, interactive = false, hooks = null) {
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 || DEFAULT_REDIRECT_URI,
state,
};
if (provider.scopes) {
query.scope = provider.scopes.join(' ');
}
if (provider.authQuery) {
Object.assign(query, provider.authQuery);
}
if (alwaysUseTab == null) {
alwaysUseTab = await detectVivaldiWebRequestBug();
}
if (hooks) hooks.query(query);
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 = !alwaysUseTab && await browser.windows.getLastFocused();
const finalUrl = await webextLaunchWebAuthFlow({
url,
alwaysUseTab,
interactive,
redirect_uri: query.redirect_uri,
windowOptions: wnd && Object.assign({
state: 'normal',
width,
height,
}, wnd.state !== 'minimized' && {
// Center the popup to the current window
top: Math.ceil(wnd.top + (wnd.height - width) / 2),
left: Math.ceil(wnd.left + (wnd.width - width) / 2),
}),
});
const params = new URLSearchParams(
provider.flow === 'token' ?
new URL(finalUrl).hash.slice(1) :
new URL(finalUrl).search.slice(1)
);
if (params.get('state') !== state) {
throw new TokenError(name, `Unexpected state: ${params.get('state')}, expected: ${state}`);
}
let result;
if (provider.flow === 'token') {
const obj = {};
for (const [key, value] of params) {
obj[key] = value;
}
result = obj;
} else {
const code = params.get('code');
const body = {
code,
grant_type: 'authorization_code',
client_id: provider.clientId,
redirect_uri: query.redirect_uri,
state,
};
if (provider.clientSecret) {
body.client_secret = provider.clientSecret;
}
result = await postQuery(provider.tokenURL, body);
}
return handleTokenResult(result, keys);
}
async function handleTokenResult(result, k) {
await chromeLocal.set({
[k.TOKEN]: result.access_token,
[k.EXPIRE]: result.expires_in
? Date.now() + (result.expires_in - NETWORK_LATENCY) * 1000
: undefined,
[k.REFRESH]: result.refresh_token,
});
return result.access_token;
}
async function postQuery(url, body) {
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: body ? new URLSearchParams(body) : null,
};
const r = await fetch(url, options);
if (r.ok) {
return r.json();
}
const text = await r.text();
const err = new Error(`Failed to fetch (${r.status}): ${text}`);
err.code = r.status;
throw err;
}
async function detectVivaldiWebRequestBug() {
// 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 || anyTab.vivExtData)) {
return false;
}
let bugged = true;
const TEST_URL = chrome.runtime.getURL('manifest.json');
const check = ({url}) => {
bugged = url !== TEST_URL;
};
chrome.webRequest.onBeforeRequest.addListener(check, {urls: [TEST_URL], types: ['main_frame']});
const {tabs: [tab]} = await browser.windows.create({
type: 'popup',
state: 'minimized',
url: TEST_URL,
});
await waitForTabUrl(tab);
chrome.windows.remove(tab.windowId);
chrome.webRequest.onBeforeRequest.removeListener(check);
return bugged;
}
})();

View File

@ -0,0 +1,348 @@
/* global API */// msg.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 */
/* global prefs */
'use strict';
/* exported updateMan */
const updateMan = (() => {
const STATES = /** @namespace UpdaterStates */ {
UPDATED: 'updated',
SKIPPED: 'skipped',
UNREACHABLE: 'server unreachable',
// details for SKIPPED status
EDITED: 'locally edited',
MAYBE_EDITED: 'may be locally edited',
SAME_MD5: 'up-to-date: MD5 is unchanged',
SAME_CODE: 'up-to-date: code sections are unchanged',
SAME_VERSION: 'up-to-date: version is unchanged',
ERROR_MD5: 'error: MD5 is invalid',
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})/,
/(0[1-9]|1(?:0|[12](?=\d\d))?|[2-9])/, // in ambiguous cases like yyyy123 the month will be 1
/(0[1-9]|[1-2][0-9]?|3[0-1]?|[4-9])/,
/\.([01][0-9]?|2[0-3]?|[3-9])/,
/\.([0-5][0-9]?|[6-9])$/,
].map(rx => rx.source).join(''));
const ALARM_NAME = 'scheduledUpdate';
const MIN_INTERVAL_MS = 60e3;
const RETRY_ERRORS = [
503, // service unavailable
429, // too many requests
];
let usoReferers = 0;
let lastUpdateTime;
let checkingAll = false;
let logQueue = [];
let logLastWriteTime = 0;
chromeLocal.getValue('lastUpdateTime').then(val => {
lastUpdateTime = val || Date.now();
prefs.subscribe('updateInterval', schedule, {runNow: true});
chrome.alarms.onAlarm.addListener(onAlarm);
});
return {
checkAllStyles,
checkStyle,
getStates: () => STATES,
};
async function checkAllStyles({
save = true,
ignoreDigest,
observe,
} = {}) {
resetInterval();
checkingAll = true;
const port = observe && chrome.runtime.connect({name: 'updater'});
const styles = (await API.styles.getAll())
.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`);
await Promise.all(
styles.map(style =>
checkStyle({style, port, save, ignoreDigest})));
if (port) port.postMessage({done: true});
if (port) port.disconnect();
log('');
checkingAll = false;
}
/**
* @param {{
id?: number,
style?: StyleObj,
port?: chrome.runtime.Port,
save?: boolean,
ignoreDigest?: boolean,
}} opts
* @returns {{
style: StyleObj,
updated?: boolean,
error?: any,
STATES: UpdaterStates,
}}
Original style digests are calculated in these cases:
* style is installed or updated from server
* non-usercss style is checked for an update and styleSectionsEqual considers it unchanged
Update check proceeds in these cases:
* style has the original digest and it's equal to the current digest
* [ignoreDigest: true] style doesn't yet have the original digest but we ignore it
* [ignoreDigest: none/false] style doesn't yet have the original digest
so we compare the code to the server code and if it's the same we save the digest,
otherwise we skip the style and report MAYBE_EDITED status
'ignoreDigest' option is set on the second manual individual update check on the manage page.
*/
async function checkStyle(opts) {
let {id} = opts;
const {
style = await API.styles.get(id),
ignoreDigest,
port,
save,
} = opts;
if (!id) id = style.id;
const {md5Url} = style;
let {usercssData: ucd, updateUrl} = style;
let res, state;
try {
await checkIfEdited();
res = {
style: await (ucd && !md5Url ? updateUsercss : updateUSO)().then(maybeSave),
updated: true,
};
state = STATES.UPDATED;
} catch (err) {
const error = err === 0 && STATES.UNREACHABLE ||
err && err.message ||
err;
res = {error, style, STATES};
state = `${STATES.SKIPPED} (${Array.isArray(err) ? err[0].message : error})`;
}
log(`${state} #${id} ${style.customName || style.name}`);
if (port) port.postMessage(res);
return res;
async function checkIfEdited() {
if (!ignoreDigest &&
style.originalDigest &&
style.originalDigest !== await calcStyleDigest(style)) {
return Promise.reject(STATES.EDITED);
}
}
async function updateUSO() {
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);
}
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 updateUsercss(css) {
let oldVer = ucd.version;
let {etag: oldEtag, updateUrl} = style;
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);
}
// TODO: when sourceCode is > 100kB use http range request(s) for version check
const {headers: {etag}, response} = await tryDownload(updateUrl, RH_ETAG);
const json = await API.usercss.buildMeta({sourceCode: response, etag, updateUrl});
const delta = compareVersion(json.usercssData.version, oldVer);
let err;
if (!delta && !ignoreDigest) {
// re-install is invalid in a soft upgrade
err = response === style.sourceCode
? STATES.SAME_CODE
: !URLS.isLocalhost(updateUrl) && STATES.SAME_VERSION;
}
if (delta < 0) {
// downgrade is always invalid
err = STATES.ERROR_VERSION;
}
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.styles.put(style);
}
return err
? Promise.reject(err)
: API.usercss.buildCode(json);
}
async function maybeSave(json) {
json.id = id;
// keep current state
delete json.customName;
delete json.enabled;
const newStyle = Object.assign({}, style, json);
newStyle.updateDate = getDateFromVer(newStyle) || Date.now();
// update digest even if save === false as there might be just a space added etc.
if (!ucd && styleSectionsEqual(json, style)) {
style.originalDigest = (await API.styles.install(newStyle)).originalDigest;
return Promise.reject(STATES.SAME_CODE);
}
if (!style.originalDigest && !ignoreDigest) {
return Promise.reject(STATES.MAYBE_EDITED);
}
return !save ? newStyle :
(ucd ? API.usercss.install : API.styles.install)(newStyle);
}
async function tryDownload(url, params) {
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) ||
retryDelay > MIN_INTERVAL_MS) {
return Promise.reject(code);
}
}
retryDelay *= 1.25;
await new Promise(resolve => setTimeout(resolve, retryDelay));
}
}
async function downloadEtag() {
const opts = Object.assign({method: 'head'}, RH_ETAG);
const req = await tryDownload(style.updateUrl, opts);
return req.headers.etag;
}
function getDateFromVer(style) {
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();
}
}
/** UserCSS metadata may be embedded in the original USO style so let's use its updateURL */
function getUsoEmbeddedMeta(code = style.sourceCode) {
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 schedule() {
const interval = prefs.get('updateInterval') * 60 * 60 * 1000;
if (interval > 0) {
const elapsed = Math.max(0, Date.now() - lastUpdateTime);
chrome.alarms.create(ALARM_NAME, {
when: Date.now() + Math.max(MIN_INTERVAL_MS, interval - elapsed),
});
} else {
chrome.alarms.clear(ALARM_NAME, ignoreChromeError);
}
}
function onAlarm({name}) {
if (name === ALARM_NAME) checkAllStyles();
}
function resetInterval() {
chromeLocal.setValue('lastUpdateTime', lastUpdateTime = Date.now());
schedule();
}
function log(text) {
logQueue.push({text, time: new Date().toLocaleString()});
debounce(flushQueue, text && checkingAll ? 1000 : 0);
}
async function flushQueue(lines) {
if (!lines) {
flushQueue(await chromeLocal.getValue('updateLog') || []);
return;
}
const time = Date.now() - logLastWriteTime > 11e3 ?
logQueue[0].time + ' ' :
'';
if (logQueue[0] && !logQueue[0].text) {
logQueue.shift();
if (lines[lines.length - 1]) lines.push('');
}
lines.splice(0, lines.length - 1000);
lines.push(time + (logQueue[0] && logQueue[0].text || ''));
lines.push(...logQueue.slice(1).map(item => item.text));
chromeLocal.setValue('updateLog', lines);
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

@ -0,0 +1,141 @@
/* global RX_META URLS download openURL */// toolbox.js
/* global addAPI bgReady */// common.js
/* global tabMan */// msg.js
'use strict';
bgReady.all.then(() => {
const installCodeCache = {};
addAPI(/** @namespace API */ {
usercss: {
getInstallCode(url) {
// when the installer tab is reloaded after the cache is expired, this will throw intentionally
const {code, timer} = installCodeCache[url];
clearInstallCode(url);
clearTimeout(timer);
return code;
},
},
});
// `glob`: pathname match pattern for webRequest
// `rx`: pathname regex to verify the URL really looks like a raw usercss
const maybeDistro = {
// https://github.com/StylishThemes/GitHub-Dark/raw/master/github-dark.user.css
'github.com': {
glob: '/*/raw/*',
rx: /^\/[^/]+\/[^/]+\/raw\/[^/]+\/[^/]+?\.user\.(css|styl)$/,
},
// https://raw.githubusercontent.com/StylishThemes/GitHub-Dark/master/github-dark.user.css
'raw.githubusercontent.com': {
glob: '/*',
rx: /^(\/[^/]+?){4}\.user\.(css|styl)$/,
},
};
chrome.webRequest.onBeforeSendHeaders.addListener(maybeInstallFromDistro, {
urls: [
URLS.usw + 'api/style/*.user.css',
...URLS.usoArchiveRaw.map(s => s + 'usercss/*.user.css'),
...['greasy', 'sleazy'].map(s => `*://${s}fork.org/scripts/*/code/*.user.css`),
...[].concat(
...Object.entries(maybeDistro)
.map(([host, {glob}]) => makeUsercssGlobs(host, glob))),
],
types: ['main_frame'],
}, ['blocking']);
chrome.webRequest.onHeadersReceived.addListener(rememberContentType, {
urls: makeUsercssGlobs('*', '/*'),
types: ['main_frame'],
}, ['responseHeaders']);
tabMan.onUpdate(maybeInstall);
function clearInstallCode(url) {
return delete installCodeCache[url];
}
/** Sites may be using custom types like text/stylus so this coarse filter only excludes html */
function isContentTypeText(type) {
return /^text\/(?!html)/i.test(type);
}
// in Firefox we have to use a content script to read file://
async function loadFromFile(tabId) {
return (await browser.tabs.executeScript(tabId, {file: '/content/install-hook-usercss.js'}))[0];
}
async function loadFromUrl(tabId, url) {
return (
url.startsWith('file:') ||
tabMan.get(tabId, isContentTypeText.name) ||
isContentTypeText((await fetch(url, {method: 'HEAD'})).headers.get('content-type'))
) && 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(',');
}
async function maybeInstall({tabId, url, oldUrl = ''}) {
if (url.includes('.user.') &&
/^(https?|file|ftps?):/.test(url) &&
/\.user\.(css|styl)$/.test(url.split(/[#?]/, 1)[0]) &&
!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)) {
await openInstallerPage(tabId, url, {code, inTab});
}
}
}
/** Faster installation on known distribution sites to avoid flicker of css text */
function maybeInstallFromDistro({tabId, url}) {
const u = new URL(url);
const m = maybeDistro[u.hostname];
if (!m || m.rx.test(u.pathname)) {
openInstallerPage(tabId, url, {});
// Silently suppress navigation.
// Don't redirect to the install URL as it'll flash the text!
return {cancel: true};
}
}
async function openInstallerPage(tabId, url, {code, inTab} = {}) {
const newUrl = makeInstallerUrl(url);
if (inTab) {
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;
}
}
/** Remember Content-Type to avoid wasting time to re-fetch in loadFromUrl **/
function rememberContentType({tabId, responseHeaders}) {
const h = responseHeaders.find(h => h.name.toLowerCase() === 'content-type');
tabMan.set(tabId, isContentTypeText.name, h && isContentTypeText(h.value) || undefined);
}
});

View File

@ -0,0 +1,163 @@
/* global API */// msg.js
/* global RX_META deepCopy download */// toolbox.js
'use strict';
const usercssMan = {
GLOBAL_META: Object.entries({
author: null,
description: null,
homepageURL: 'url',
updateURL: 'updateUrl',
name: null,
}),
/** `src` is a style or vars */
async assignVars(style, src) {
const meta = style.usercssData;
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)) {
const old = oldVars[key] && oldVars[key].value;
if (old) v.value = old;
}
meta.vars = await API.worker.nullifyInvalidVars(vars);
}
},
async build({
styleId,
sourceCode,
vars,
checkDup,
metaOnly,
assignVars,
initialUrl,
}) {
// downloading here while install-usercss page is loading to avoid the wait
if (initialUrl) sourceCode = await download(initialUrl);
const style = await usercssMan.buildMeta({sourceCode});
const dup = (checkDup || assignVars) &&
await usercssMan.find(styleId ? {id: styleId} : style);
let log;
if (!metaOnly) {
if (vars || assignVars) {
await usercssMan.assignVars(style, vars || dup);
}
await usercssMan.buildCode(style);
log = style.log; // extracting the non-enumerable prop, otherwise it won't survive messaging
}
return {style, dup, log};
},
async buildCode(style) {
const {sourceCode: code, usercssData: {vars, preprocessor}} = style;
const match = code.match(RX_META);
const i = match.index;
const j = i + match[0].length;
const codeNoMeta = code.slice(0, i) + blankOut(code, i, j) + code.slice(j);
const {sections, errors, log} = await API.worker.compileUsercss(preprocessor, codeNoMeta, vars);
const recoverable = errors.every(e => e.recoverable);
if (!sections.length || !recoverable) {
throw !recoverable ? errors : 'Style does not contain any actual CSS to apply.';
}
style.sections = sections;
// adding a non-enumerable prop so it won't be written to storage
if (log) Object.defineProperty(style, 'log', {value: log});
return style;
},
async buildMeta(style) {
if (style.usercssData) {
return style;
}
// remember normalized sourceCode
let code = style.sourceCode = style.sourceCode.replace(/\r\n?/g, '\n');
style = Object.assign({
enabled: true,
sections: [],
}, style);
const match = code.match(RX_META);
if (!match) {
return Promise.reject(new Error('Could not find metadata.'));
}
try {
code = blankOut(code, 0, match.index) + match[0];
const {metadata} = await API.worker.parseUsercssMeta(code);
style.usercssData = metadata;
// https://github.com/openstyles/stylus/issues/560#issuecomment-440561196
for (const [key, globalKey] of usercssMan.GLOBAL_META) {
const val = metadata[key];
if (val !== undefined) {
style[globalKey || key] = val;
}
}
return style;
} catch (err) {
if (err.code) {
const args = err.code === 'missingMandatory' || err.code === 'missingChar'
? err.args.map(e => e.length === 1 ? JSON.stringify(e) : e).join(', ')
: err.args;
const msg = chrome.i18n.getMessage(`meta_${(err.code)}`, args);
if (msg) err.message = msg;
}
return Promise.reject(err);
}
},
async configVars(id, vars) {
const style = deepCopy(await API.styles.get(id));
style.usercssData.vars = vars;
await usercssMan.buildCode(style);
return (await API.styles.install(style, 'config'))
.usercssData.vars;
},
async editSave(style) {
style = await usercssMan.parse(style);
return {
log: style.log, // extracting the non-enumerable prop, otherwise it won't survive messaging
style: await API.styles.editSave(style),
};
},
async find(styleOrData) {
if (styleOrData.id) {
return API.styles.get(styleOrData.id);
}
const {name, namespace} = styleOrData.usercssData || styleOrData;
for (const dup of await API.styles.getAll()) {
const data = dup.usercssData;
if (data &&
data.name === name &&
data.namespace === namespace) {
return dup;
}
}
},
async install(style, opts) {
return API.styles.install(await usercssMan.parse(style, opts));
},
async parse(style, {dup, vars} = {}) {
style = await usercssMan.buildMeta(style);
// preserve style.vars during update
if (dup || (dup = await usercssMan.find(style))) {
style.id = dup.id;
}
if (vars || (vars = dup)) {
await usercssMan.assignVars(style, vars);
}
return usercssMan.buildCode(style);
},
};
/** Replaces everything with spaces to keep the original length,
* but preserves the line breaks to keep the original line/col relation */
function blankOut(str, start = 0, end = str.length) {
return str.slice(start, end).replace(/[^\r\n]/g, ' ');
}

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]);
}
})();

120
background/usw-api.js Normal file
View File

@ -0,0 +1,120 @@
/* global API msg */// msg.js
/* global URLS */ // toolbox.js
/* global tokenMan */
'use strict';
const uswApi = (() => {
//#region Internals
class TokenHooks {
constructor(id) {
this.id = id;
}
keyName(name) {
return `${name}/${this.id}`;
}
query(query) {
return Object.assign(query, {vendor_data: this.id});
}
}
function fakeUsercssHeader(style) {
const {name, _usw: u = {}} = style;
const meta = Object.entries({
'@name': u.name || name || '?',
'@version': // Same as USO-archive version: YYYYMMDD.hh.mm
new Date().toISOString().replace(/^(\d+)-(\d+)-(\d+)T(\d+):(\d+).+/, '$1$2$3.$4.$5'),
'@namespace': u.namespace !== '?' && u.namespace ||
u.username && `userstyles.world/user/${u.username}` ||
'?',
'@description': u.description,
'@author': u.username,
'@license': u.license,
});
const maxKeyLen = meta.reduce((res, [k]) => Math.max(res, k.length), 0);
return [
'/* ==UserStyle==',
...meta.map(([k, v]) => v && `${k}${' '.repeat(maxKeyLen - k.length + 2)}${v}`).filter(Boolean),
'==/UserStyle== */',
].join('\n') + '\n\n';
}
async function linkStyle(style, sourceCode) {
const {id} = style;
const metadata = await API.worker.parseUsercssMeta(sourceCode).catch(console.warn) || {};
const uswData = Object.assign({}, style, {metadata, sourceCode});
API.data.set('usw' + id, uswData);
const token = await tokenMan.getToken('userstylesworld', true, new TokenHooks(id));
const info = await uswFetch('style', token);
const data = style._usw = Object.assign({token}, info);
style.url = style.url || data.homepage || `${URLS.usw}style/${data.id}`;
await uswSave(style);
return data;
}
async function uswFetch(path, token, opts) {
opts = Object.assign({credentials: 'omit'}, opts);
opts.headers = Object.assign({Authorization: `Bearer ${token}`}, opts.headers);
return (await (await fetch(`${URLS.usw}api/${path}`, opts)).json()).data;
}
/** Uses a custom method when broadcasting and avoids needlessly sending the entire style */
async function uswSave(style) {
const {id, _usw} = style;
await API.styles.save(style, {broadcast: false});
msg.broadcastExtension({method: 'uswData', style: {id, _usw}});
}
//#endregion
//#region Exports
return {
/**
* @param {number} id
* @param {string} sourceCode
* @return {Promise<string>}
*/
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, code);
return uswFetch(`style/${data.id}`, data.token, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({code}),
});
},
/**
* @param {number} id
* @return {Promise<void>}
*/
async revoke(id) {
await tokenMan.revokeToken('userstylesworld', new TokenHooks(id));
const style = await API.styles.get(id);
if (style) {
style._usw = {};
await uswSave(style);
}
},
};
//#endregion
})();
/* Doing this outside so we don't break IDE's recognition of the exported methods in IIFE */
for (const [k, fn] of Object.entries(uswApi)) {
uswApi[k] = async (id, ...args) => {
API.data.set('usw' + id, true);
try {
/* Awaiting inside `try` so that `finally` runs when done */
return await fn(id, ...args);
} finally {
API.data.del('usw' + id);
}
};
}

View File

@ -1,356 +0,0 @@
/* global messageBox, handleUpdate, applyOnMessage */
'use strict';
const STYLISH_DUMP_FILE_EXT = '.txt';
const STYLUS_BACKUP_FILE_EXT = '.json';
function importFromFile({fileTypeFilter, file} = {}) {
return new Promise(resolve => {
const fileInput = document.createElement('input');
if (file) {
readFile();
return;
}
fileInput.style.display = 'none';
fileInput.type = 'file';
fileInput.accept = fileTypeFilter || STYLISH_DUMP_FILE_EXT;
fileInput.acceptCharset = 'utf-8';
document.body.appendChild(fileInput);
fileInput.initialValue = fileInput.value;
fileInput.onchange = readFile;
fileInput.click();
function readFile() {
if (file || fileInput.value !== fileInput.initialValue) {
file = file || fileInput.files[0];
if (file.size > 100e6) {
console.warn("100MB backup? I don't believe you.");
importFromString('').then(resolve);
return;
}
document.body.style.cursor = 'wait';
const fReader = new FileReader();
fReader.onloadend = event => {
fileInput.remove();
importFromString(event.target.result).then(numStyles => {
document.body.style.cursor = '';
resolve(numStyles);
});
};
fReader.readAsText(file, 'utf-8');
}
}
});
}
function importFromString(jsonString) {
if (!BG) {
onBackgroundReady().then(() => importFromString(jsonString));
return;
}
// create objects in background context
const json = BG.tryJSONparse(jsonString) || [];
if (typeof json.slice != 'function') {
json.length = 0;
}
const oldStyles = json.length && BG.deepCopy(BG.cachedStyles.list || []);
const oldStylesByName = json.length && new Map(
oldStyles.map(style => [style.name.trim(), style]));
let oldDigests;
chrome.storage.local.get(null, data => (oldDigests = data));
const stats = {
added: {names: [], ids: [], legend: 'importReportLegendAdded'},
unchanged: {names: [], ids: [], legend: 'importReportLegendIdentical'},
metaAndCode: {names: [], ids: [], legend: 'importReportLegendUpdatedBoth'},
metaOnly: {names: [], ids: [], legend: 'importReportLegendUpdatedMeta'},
codeOnly: {names: [], ids: [], legend: 'importReportLegendUpdatedCode'},
invalid: {names: [], legend: 'importReportLegendInvalid'},
};
let index = 0;
let lastRenderTime = performance.now();
const renderQueue = [];
const RENDER_NAP_TIME_MAX = 1000; // ms
const RENDER_QUEUE_MAX = 50; // number of styles
const SAVE_OPTIONS = {reason: 'import', notify: false};
return new Promise(proceed);
function proceed(resolve) {
while (index < json.length) {
const item = json[index++];
const info = analyze(item);
if (info) {
// using saveStyle directly since json was parsed in background page context
return BG.saveStyle(Object.assign(item, SAVE_OPTIONS))
.then(style => account({style, info, resolve}));
}
}
renderQueue.forEach(style => handleUpdate(style, {reason: 'import'}));
renderQueue.length = 0;
done(resolve);
}
function analyze(item) {
if (!item || !item.name || !item.name.trim() || typeof item != 'object'
|| (item.sections && typeof item.sections.slice != 'function')) {
stats.invalid.names.push(`#${index}: ${limitString(item && item.name || '')}`);
return;
}
item.name = item.name.trim();
const byId = BG.cachedStyles.byId.get(item.id);
const byName = oldStylesByName.get(item.name);
const oldStyle = byId && byId.name.trim() == item.name || !byName ? byId : byName;
if (oldStyle == byName && byName) {
item.id = byName.id;
}
const oldStyleKeys = oldStyle && Object.keys(oldStyle);
const metaEqual = oldStyleKeys &&
oldStyleKeys.length == Object.keys(item).length &&
oldStyleKeys.every(k => k == 'sections' || oldStyle[k] === item[k]);
const codeEqual = oldStyle && BG.styleSectionsEqual(oldStyle, item);
if (metaEqual && codeEqual) {
stats.unchanged.names.push(oldStyle.name);
stats.unchanged.ids.push(oldStyle.id);
return;
}
return {oldStyle, metaEqual, codeEqual};
}
function account({style, info, resolve}) {
renderQueue.push(style);
if (performance.now() - lastRenderTime > RENDER_NAP_TIME_MAX
|| renderQueue.length > RENDER_QUEUE_MAX) {
renderQueue.forEach(style => handleUpdate(style, {reason: 'import'}));
setTimeout(scrollElementIntoView, 0, $('#style-' + renderQueue.pop().id));
renderQueue.length = 0;
lastRenderTime = performance.now();
}
setTimeout(proceed, 0, resolve);
const {oldStyle, metaEqual, codeEqual} = info;
if (!oldStyle) {
stats.added.names.push(style.name);
stats.added.ids.push(style.id);
return;
}
if (!metaEqual && !codeEqual) {
stats.metaAndCode.names.push(reportNameChange(oldStyle, style));
stats.metaAndCode.ids.push(style.id);
return;
}
if (!codeEqual) {
stats.codeOnly.names.push(style.name);
stats.codeOnly.ids.push(style.id);
return;
}
stats.metaOnly.names.push(reportNameChange(oldStyle, style));
stats.metaOnly.ids.push(style.id);
}
function done(resolve) {
const numChanged = stats.metaAndCode.names.length +
stats.metaOnly.names.length +
stats.codeOnly.names.length +
stats.added.names.length;
Promise.resolve(numChanged && refreshAllTabs()).then(() => {
const report = Object.keys(stats)
.filter(kind => stats[kind].names.length)
.map(kind => {
const {ids, names, legend} = stats[kind];
const listItemsWithId = (name, i) =>
$element({dataset: {id: ids[i]}, textContent: name});
const listItems = name =>
$element({textContent: name});
const block =
$element({tag: 'details', dataset: {id: kind}, appendChild: [
$element({tag: 'summary', appendChild:
$element({tag: 'b', textContent: names.length + ' ' + t(legend)})
}),
$element({tag: 'small', appendChild:
names.map(ids ? listItemsWithId : listItems)
}),
]});
return block;
});
scrollTo(0, 0);
messageBox({
title: t('importReportTitle'),
contents: report.length ? report : t('importReportUnchanged'),
buttons: [t('confirmOK'), numChanged && t('undo')],
onshow: bindClick,
}).then(({button, enter, esc}) => {
if (button == 1) {
undo();
}
});
resolve(numChanged);
});
}
function undo() {
const oldStylesById = new Map(oldStyles.map(style => [style.id, style]));
const newIds = [
...stats.metaAndCode.ids,
...stats.metaOnly.ids,
...stats.codeOnly.ids,
...stats.added.ids,
];
let resolve;
index = 0;
return new Promise(resolve_ => {
resolve = resolve_;
undoNextId();
}).then(BG.refreshAllTabs)
.then(() => messageBox({
title: t('importReportUndoneTitle'),
contents: newIds.length + ' ' + t('importReportUndone'),
buttons: [t('confirmOK')],
}));
function undoNextId() {
if (index == newIds.length) {
resolve();
return;
}
const id = newIds[index++];
deleteStyleSafe({id, notify: false}).then(id => {
const oldStyle = oldStylesById.get(id);
if (oldStyle) {
oldStyle.styleDigest = oldDigests[BG.DIGEST_KEY_PREFIX + id];
saveStyleSafe(Object.assign(oldStyle, SAVE_OPTIONS))
.then(undoNextId);
} else {
undoNextId();
}
});
}
}
function bindClick(box) {
const highlightElement = event => {
const styleElement = $('#style-' + event.target.dataset.id);
if (styleElement) {
scrollElementIntoView(styleElement);
animateElement(styleElement, {className: 'highlight'});
}
};
for (const block of $$('details')) {
if (block.dataset.id != 'invalid') {
block.style.cursor = 'pointer';
block.onclick = highlightElement;
}
}
}
function limitString(s, limit = 100) {
return s.length <= limit ? s : s.substr(0, limit) + '...';
}
function reportNameChange(oldStyle, newStyle) {
return newStyle.name != oldStyle.name
? oldStyle.name + ' —> ' + newStyle.name
: oldStyle.name;
}
function refreshAllTabs() {
return getActiveTab().then(activeTab => new Promise(resolve => {
// list all tabs including chrome-extension:// which can be ours
chrome.tabs.query({}, tabs => {
const lastTab = tabs[tabs.length - 1];
for (const tab of tabs) {
getStylesSafe({matchUrl: tab.url, enabled: true, asHash: true}).then(styles => {
const message = {method: 'styleReplaceAll', styles};
if (tab.id == activeTab.id) {
applyOnMessage(message);
} else {
chrome.tabs.sendMessage(tab.id, message);
}
BG.updateIcon(tab, styles);
if (tab == lastTab) {
resolve();
}
});
}
});
}));
}
}
$('#file-all-styles').onclick = () => {
Promise.all([
BG.chromeLocal.get(null),
getStylesSafe(),
]).then(([data, styles]) => {
styles = styles.map(style => {
const styleDigest = data[BG.DIGEST_KEY_PREFIX + style.id];
return styleDigest ? Object.assign({styleDigest}, style) : style;
});
const text = JSON.stringify(styles, null, '\t');
const url = 'data:text/plain;charset=utf-8,' + encodeURIComponent(text);
return url;
// for long URLs; https://github.com/schomery/stylish-chrome/issues/13#issuecomment-284582600
}).then(fetch)
.then(res => res.blob())
.then(blob => {
const objectURL = URL.createObjectURL(blob);
Object.assign(document.createElement('a'), {
download: generateFileName(),
href: objectURL,
type: 'application/json',
}).dispatchEvent(new MouseEvent('click'));
setTimeout(() => URL.revokeObjectURL(objectURL));
});
function generateFileName() {
const today = new Date();
const dd = ('0' + today.getDate()).substr(-2);
const mm = ('0' + (today.getMonth() + 1)).substr(-2);
const yyyy = today.getFullYear();
return `stylus-${mm}-${dd}-${yyyy}${STYLUS_BACKUP_FILE_EXT}`;
}
};
$('#unfile-all-styles').onclick = () => {
importFromFile({fileTypeFilter: STYLUS_BACKUP_FILE_EXT});
};
Object.assign(document.body, {
ondragover(event) {
const hasFiles = event.dataTransfer.types.includes('Files');
event.dataTransfer.dropEffect = hasFiles || event.target.type == 'search' ? 'copy' : 'none';
this.classList.toggle('dropzone', hasFiles);
if (hasFiles) {
event.preventDefault();
clearTimeout(this.fadeoutTimer);
this.classList.remove('fadeout');
}
},
ondragend(event) {
animateElement(this, {className: 'fadeout'}).then(() => {
this.style.animationDuration = '';
this.classList.remove('dropzone');
});
},
ondragleave(event) {
// Chrome sets screen coords to 0 on Escape key pressed or mouse out of document bounds
if (!event.screenX && !event.screenX) {
this.ondragend();
}
},
ondrop(event) {
this.ondragend();
if (event.dataTransfer.files.length) {
event.preventDefault();
if ($('#onlyUpdates input').checked) {
$('#onlyUpdates input').click();
}
importFromFile({file: event.dataTransfer.files[0]});
}
},
});

View File

@ -1,571 +0,0 @@
/*jshint curly:true, eqeqeq:true, laxbreak:true, noempty:false */
/*
The MIT License (MIT)
Copyright (c) 2007-2017 Einar Lielmanis, Liam Newman, and contributors.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
CSS Beautifier
---------------
Written by Harutyun Amirjanyan, (amirjanyan@gmail.com)
Based on code initially developed by: Einar Lielmanis, <einar@jsbeautifier.org>
http://jsbeautifier.org/
Usage:
css_beautify(source_text);
css_beautify(source_text, options);
The options are (default in brackets):
indent_size (4) indentation size,
indent_char (space) character to indent with,
preserve_newlines (default false) - whether existing line breaks should be preserved,
selector_separator_newline (true) - separate selectors with newline or
not (e.g. "a,\nbr" or "a, br")
end_with_newline (false) - end with a newline
newline_between_rules (true) - add a new line after every css rule
space_around_selector_separator (false) - ensure space around selector separators:
'>', '+', '~' (e.g. "a>b" -> "a > b")
e.g
css_beautify(css_source_text, {
'indent_size': 1,
'indent_char': '\t',
'selector_separator': ' ',
'end_with_newline': false,
'newline_between_rules': true,
'space_around_selector_separator': true
});
*/
// http://www.w3.org/TR/CSS21/syndata.html#tokenization
// http://www.w3.org/TR/css3-syntax/
(function() {
function mergeOpts(allOptions, targetType) {
var finalOpts = {};
var name;
for (name in allOptions) {
if (name !== targetType) {
finalOpts[name] = allOptions[name];
}
}
//merge in the per type settings for the targetType
if (targetType in allOptions) {
for (name in allOptions[targetType]) {
finalOpts[name] = allOptions[targetType][name];
}
}
return finalOpts;
}
var lineBreak = /\r\n|[\n\r\u2028\u2029]/;
var allLineBreaks = new RegExp(lineBreak.source, 'g');
function css_beautify(source_text, options) {
options = options || {};
// Allow the setting of language/file-type specific options
// with inheritance of overall settings
options = mergeOpts(options, 'css');
source_text = source_text || '';
var newlinesFromLastWSEat = 0;
var indentSize = options.indent_size ? parseInt(options.indent_size, 10) : 4;
var indentCharacter = options.indent_char || ' ';
var preserve_newlines = (options.preserve_newlines === undefined) ? false : options.preserve_newlines;
var selectorSeparatorNewline = (options.selector_separator_newline === undefined) ? true : options.selector_separator_newline;
var end_with_newline = (options.end_with_newline === undefined) ? false : options.end_with_newline;
var newline_between_rules = (options.newline_between_rules === undefined) ? true : options.newline_between_rules;
var space_around_combinator = (options.space_around_combinator === undefined) ? false : options.space_around_combinator;
space_around_combinator = space_around_combinator || ((options.space_around_selector_separator === undefined) ? false : options.space_around_selector_separator);
var eol = options.eol ? options.eol : 'auto';
if (options.indent_with_tabs) {
indentCharacter = '\t';
indentSize = 1;
}
if (eol === 'auto') {
eol = '\n';
if (source_text && lineBreak.test(source_text || '')) {
eol = source_text.match(lineBreak)[0];
}
}
eol = eol.replace(/\\r/, '\r').replace(/\\n/, '\n');
// HACK: newline parsing inconsistent. This brute force normalizes the input.
source_text = source_text.replace(allLineBreaks, '\n');
// tokenizer
var whiteRe = /^\s+$/;
var pos = -1,
ch;
var parenLevel = 0;
function next() {
ch = source_text.charAt(++pos);
return ch || '';
}
function peek(skipWhitespace) {
var result = '';
var prev_pos = pos;
if (skipWhitespace) {
eatWhitespace();
}
result = source_text.charAt(pos + 1) || '';
pos = prev_pos - 1;
next();
return result;
}
function eatString(endChars) {
var start = pos;
while (next()) {
if (ch === "\\") {
next();
} else if (endChars.indexOf(ch) !== -1) {
break;
} else if (ch === "\n") {
break;
}
}
return source_text.substring(start, pos + 1);
}
function peekString(endChar) {
var prev_pos = pos;
var str = eatString(endChar);
pos = prev_pos - 1;
next();
return str;
}
function eatWhitespace(preserve_newlines_local) {
var result = 0;
while (whiteRe.test(peek())) {
next();
if (ch === '\n' && preserve_newlines_local && preserve_newlines) {
print.newLine(true);
result++;
}
}
newlinesFromLastWSEat = result;
return result;
}
function skipWhitespace() {
var result = '';
if (ch && whiteRe.test(ch)) {
result = ch;
}
while (whiteRe.test(next())) {
result += ch;
}
return result;
}
function eatComment(singleLine) {
var start = pos;
singleLine = peek() === "/";
next();
while (next()) {
if (!singleLine && ch === "*" && peek() === "/") {
next();
break;
} else if (singleLine && ch === "\n") {
return source_text.substring(start, pos);
}
}
return source_text.substring(start, pos) + ch;
}
function lookBack(str) {
return source_text.substring(pos - str.length, pos).toLowerCase() ===
str;
}
// Nested pseudo-class if we are insideRule
// and the next special character found opens
// a new block
function foundNestedPseudoClass() {
var openParen = 0;
for (var i = pos + 1; i < source_text.length; i++) {
var ch = source_text.charAt(i);
if (ch === "{") {
return true;
} else if (ch === '(') {
// pseudoclasses can contain ()
openParen += 1;
} else if (ch === ')') {
if (openParen === 0) {
return false;
}
openParen -= 1;
} else if (ch === ";" || ch === "}") {
return false;
}
}
return false;
}
// printer
var basebaseIndentString = source_text.match(/^[\t ]*/)[0];
var singleIndent = new Array(indentSize + 1).join(indentCharacter);
var indentLevel = 0;
var nestedLevel = 0;
function indent() {
indentLevel++;
basebaseIndentString += singleIndent;
}
function outdent() {
indentLevel--;
basebaseIndentString = basebaseIndentString.slice(0, -indentSize);
}
var print = {};
print["{"] = function(ch) {
print.singleSpace();
output.push(ch);
if (!eatWhitespace(true)) {
print.newLine();
}
};
print["}"] = function(newline) {
if (newline) {
print.newLine();
}
output.push('}');
if (!eatWhitespace(true)) {
print.newLine();
}
};
print._lastCharWhitespace = function() {
return whiteRe.test(output[output.length - 1]);
};
print.newLine = function(keepWhitespace) {
if (output.length) {
if (!keepWhitespace && output[output.length - 1] !== '\n') {
print.trim();
} else if (output[output.length - 1] === basebaseIndentString) {
output.pop();
}
output.push('\n');
if (basebaseIndentString) {
output.push(basebaseIndentString);
}
}
};
print.singleSpace = function() {
if (output.length && !print._lastCharWhitespace()) {
output.push(' ');
}
};
print.preserveSingleSpace = function() {
if (isAfterSpace) {
print.singleSpace();
}
};
print.trim = function() {
while (print._lastCharWhitespace()) {
output.pop();
}
};
var output = [];
/*_____________________--------------------_____________________*/
var insideRule = false;
var insidePropertyValue = false;
var enteringConditionalGroup = false;
var top_ch = '';
var last_top_ch = '';
while (true) {
var whitespace = skipWhitespace();
var isAfterSpace = whitespace !== '';
var isAfterNewline = whitespace.indexOf('\n') !== -1;
last_top_ch = top_ch;
top_ch = ch;
if (!ch) {
break;
} else if (ch === '/' && peek() === '*') { /* css comment */
var header = indentLevel === 0;
if (isAfterNewline || header) {
print.newLine();
}
output.push(eatComment());
print.newLine();
if (header) {
print.newLine(true);
}
} else if (ch === '/' && peek() === '/') { // single line comment
if (!isAfterNewline && last_top_ch !== '{') {
print.trim();
}
print.singleSpace();
output.push(eatComment());
print.newLine();
} else if (ch === '@') {
print.preserveSingleSpace();
// deal with less propery mixins @{...}
if (peek() === '{') {
output.push(eatString('}'));
} else {
output.push(ch);
// strip trailing space, if present, for hash property checks
var variableOrRule = peekString(": ,;{}()[]/='\"");
if (variableOrRule.match(/[ :]$/)) {
// we have a variable or pseudo-class, add it and insert one space before continuing
next();
variableOrRule = eatString(": ").replace(/\s$/, '');
output.push(variableOrRule);
print.singleSpace();
}
variableOrRule = variableOrRule.replace(/\s$/, '');
// might be a nesting at-rule
if (variableOrRule in css_beautify.NESTED_AT_RULE) {
nestedLevel += 1;
if (variableOrRule in css_beautify.CONDITIONAL_GROUP_RULE) {
enteringConditionalGroup = true;
}
}
}
} else if (ch === '#' && peek() === '{') {
print.preserveSingleSpace();
output.push(eatString('}'));
} else if (ch === '{') {
if (peek(true) === '}') {
eatWhitespace();
next();
print.singleSpace();
output.push("{");
print['}'](false);
if (newlinesFromLastWSEat < 2 && newline_between_rules && indentLevel === 0) {
print.newLine(true);
}
} else {
indent();
print["{"](ch);
// when entering conditional groups, only rulesets are allowed
if (enteringConditionalGroup) {
enteringConditionalGroup = false;
insideRule = (indentLevel > nestedLevel);
} else {
// otherwise, declarations are also allowed
insideRule = (indentLevel >= nestedLevel);
}
}
} else if (ch === '}') {
outdent();
print["}"](true);
insideRule = false;
insidePropertyValue = false;
if (nestedLevel) {
nestedLevel--;
}
if (newlinesFromLastWSEat < 2 && newline_between_rules && indentLevel === 0) {
print.newLine(true);
}
} else if (ch === ":") {
eatWhitespace();
if ((insideRule || enteringConditionalGroup) &&
!(lookBack("&") || foundNestedPseudoClass()) &&
!lookBack("(")) {
// 'property: value' delimiter
// which could be in a conditional group query
output.push(':');
if (!insidePropertyValue) {
insidePropertyValue = true;
print.singleSpace();
}
} else {
// sass/less parent reference don't use a space
// sass nested pseudo-class don't use a space
// preserve space before pseudoclasses/pseudoelements, as it means "in any child"
if (lookBack(" ") && output[output.length - 1] !== " ") {
output.push(" ");
}
if (peek() === ":") {
// pseudo-element
next();
output.push("::");
} else {
// pseudo-class
output.push(':');
}
}
} else if (ch === '"' || ch === '\'') {
print.preserveSingleSpace();
output.push(eatString(ch));
} else if (ch === ';') {
insidePropertyValue = false;
output.push(ch);
if (!eatWhitespace(true)) {
print.newLine();
}
} else if (ch === '(') { // may be a url
if (lookBack("url")) {
output.push(ch);
eatWhitespace();
if (next()) {
if (ch !== ')' && ch !== '"' && ch !== '\'') {
output.push(eatString(')'));
} else {
pos--;
}
}
} else {
parenLevel++;
print.preserveSingleSpace();
output.push(ch);
eatWhitespace();
}
} else if (ch === ')') {
output.push(ch);
parenLevel--;
} else if (ch === ',') {
output.push(ch);
if (!eatWhitespace(true) && selectorSeparatorNewline && !insidePropertyValue && parenLevel < 1) {
print.newLine();
} else {
print.singleSpace();
}
} else if ((ch === '>' || ch === '+' || ch === '~') &&
!insidePropertyValue && parenLevel < 1) {
//handle combinator spacing
if (space_around_combinator) {
print.singleSpace();
output.push(ch);
print.singleSpace();
} else {
output.push(ch);
eatWhitespace();
// squash extra whitespace
if (ch && whiteRe.test(ch)) {
ch = '';
}
}
} else if (ch === ']') {
output.push(ch);
} else if (ch === '[') {
print.preserveSingleSpace();
output.push(ch);
} else if (ch === '=') { // no whitespace before or after
eatWhitespace();
output.push('=');
if (whiteRe.test(ch)) {
ch = '';
}
} else {
print.preserveSingleSpace();
output.push(ch);
}
}
var sweetCode = '';
if (basebaseIndentString) {
sweetCode += basebaseIndentString;
}
sweetCode += output.join('').replace(/[\r\n\t ]+$/, '');
// establish end_with_newline
if (end_with_newline) {
sweetCode += '\n';
}
if (eol !== '\n') {
sweetCode = sweetCode.replace(/[\n]/g, eol);
}
return sweetCode;
}
// https://developer.mozilla.org/en-US/docs/Web/CSS/At-rule
css_beautify.NESTED_AT_RULE = {
"@page": true,
"@font-face": true,
"@keyframes": true,
// also in CONDITIONAL_GROUP_RULE below
"@media": true,
"@supports": true,
"@document": true
};
css_beautify.CONDITIONAL_GROUP_RULE = {
"@media": true,
"@supports": true,
"@document": true
};
/*global define */
if (typeof define === "function" && define.amd) {
// Add support for AMD ( https://github.com/amdjs/amdjs-api/wiki/AMD#defineamd-property- )
define([], function() {
return {
css_beautify: css_beautify
};
});
} else if (typeof exports !== "undefined") {
// Add support for CommonJS. Just put this file somewhere on your require.paths
// and you will be able to `var html_beautify = require("beautify").html_beautify`.
exports.css_beautify = css_beautify;
} else if (typeof window !== "undefined") {
// If we're running a web page and don't have either of the above, add our one global
window.css_beautify = css_beautify;
} else if (typeof global !== "undefined") {
// If we don't even have window, try global.
global.css_beautify = css_beautify;
}
}());

View File

@ -1,64 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Depends on csslint.js from https://github.com/stubbornella/csslint
// declare global: CSSLint
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.registerHelper("lint", "css", function(text) {
var found = [];
if (!window.CSSLint) return found;
/* STYLISH: hack start (part 1) */
var rules = CSSLint.getRules();
var allowedRules = ["display-property-grouping", "duplicate-properties", "empty-rules", "errors", "known-properties"];
CSSLint.clearRules();
rules.forEach(function(rule) {
if (allowedRules.indexOf(rule.id) >= 0) {
CSSLint.addRule(rule);
}
});
/* STYLISH: hack end */
var results = CSSLint.verify(text), messages = results.messages, message = null;
for ( var i = 0; i < messages.length; i++) {
message = messages[i];
/* STYLISH: hack start (part 2) */
if (message.type === 'warning') {
// @font-face {font-family: 'Ampersand'; unicode-range: U+26;}
if (message.message.indexOf('unicode-range') !== -1) {
continue;
}
else if ( // color: hsl(210, 100%, 2.2%); or color: hsla(210, 100%, 2.2%, 0.3);
message.message.startsWith('Expected (<color>) but found \'hsl') &&
/hsla?\(\s*(-?\d+)%?\s*,\s*(-?\d+)%\s*,\s*(-?\d+|-?\d*.\d+)%(\s*,\s*(-?\d+|-?\d*.\d+))?\s*\)/.test(message.message)
) {
continue;
}
//
}
/* STYLISH: hack end */
var startLine = message.line -1, endLine = message.line -1, startCol = message.col -1, endCol = message.col;
found.push({
from: CodeMirror.Pos(startLine, startCol),
to: CodeMirror.Pos(endLine, endCol),
message: message.message,
severity : message.type
});
}
return found;
});
});

View File

@ -1,252 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Define search commands. Depends on dialog.js or another
// implementation of the openDialog method.
// Replace works a little oddly -- it will do the replace on the next
// Ctrl-G (or whatever is bound to findNext) press. You prevent a
// replace by making sure the match is no longer selected when hitting
// Ctrl-G.
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("./searchcursor"), require("../dialog/dialog"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "./searchcursor", "../dialog/dialog"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
function searchOverlay(query, caseInsensitive) {
if (typeof query == "string")
query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), caseInsensitive ? "gi" : "g");
else if (!query.global)
query = new RegExp(query.source, query.ignoreCase ? "gi" : "g");
return {token: function(stream) {
query.lastIndex = stream.pos;
var match = query.exec(stream.string);
if (match && match.index == stream.pos) {
stream.pos += match[0].length || 1;
return "searching";
} else if (match) {
stream.pos = match.index;
} else {
stream.skipToEnd();
}
}};
}
function SearchState() {
this.posFrom = this.posTo = this.lastQuery = this.query = null;
this.overlay = null;
}
function getSearchState(cm) {
return cm.state.search || (cm.state.search = new SearchState());
}
function queryCaseInsensitive(query) {
return typeof query == "string" && query == query.toLowerCase();
}
function getSearchCursor(cm, query, pos) {
// Heuristic: if the query string is all lowercase, do a case insensitive search.
return cm.getSearchCursor(query, pos, queryCaseInsensitive(query));
}
function persistentDialog(cm, text, deflt, onEnter, onKeyDown) {
cm.openDialog(text, onEnter, {
value: deflt,
selectValueOnOpen: true,
closeOnEnter: false,
onClose: function() { clearSearch(cm); },
onKeyDown: onKeyDown
});
}
function dialog(cm, text, shortText, deflt, f) {
if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true});
else f(prompt(shortText, deflt));
}
function confirmDialog(cm, text, shortText, fs) {
if (cm.openConfirm) cm.openConfirm(text, fs);
else if (confirm(shortText)) fs[0]();
}
function parseString(string) {
return string.replace(/\\(.)/g, function(_, ch) {
if (ch == "n") return "\n"
if (ch == "r") return "\r"
return ch
})
}
function parseQuery(query) {
var isRE = query.match(/^\/(.*)\/([a-z]*)$/);
if (isRE) {
try { query = new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i"); }
catch(e) {} // Not a regular expression after all, do a string search
} else {
query = parseString(query)
}
if (typeof query == "string" ? query == "" : query.test(""))
query = /x^/;
return query;
}
var queryDialog =
'Search: <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>';
function startSearch(cm, state, query) {
state.queryText = query;
state.query = parseQuery(query);
cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query));
state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query));
cm.addOverlay(state.overlay);
if (cm.showMatchesOnScrollbar) {
if (state.annotate) { state.annotate.clear(); state.annotate = null; }
state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query));
}
}
function doSearch(cm, rev, persistent, immediate) {
var state = getSearchState(cm);
if (state.query) return findNext(cm, rev);
var q = cm.getSelection() || state.lastQuery;
if (persistent && cm.openDialog) {
var hiding = null
var searchNext = function(query, event) {
CodeMirror.e_stop(event);
if (!query) return;
if (query != state.queryText) {
startSearch(cm, state, query);
state.posFrom = state.posTo = cm.getCursor();
}
if (hiding) hiding.style.opacity = 1
findNext(cm, event.shiftKey, function(_, to) {
var dialog
if (to.line < 3 && document.querySelector &&
(dialog = cm.display.wrapper.querySelector(".CodeMirror-dialog")) &&
dialog.getBoundingClientRect().bottom - 4 > cm.cursorCoords(to, "window").top)
(hiding = dialog).style.opacity = .4
})
};
persistentDialog(cm, queryDialog, q, searchNext, function(event, query) {
var keyName = CodeMirror.keyName(event)
var cmd = CodeMirror.keyMap[cm.getOption("keyMap")][keyName]
if (!cmd) cmd = cm.getOption('extraKeys')[keyName]
if (cmd == "findNext" || cmd == "findPrev" ||
cmd == "findPersistentNext" || cmd == "findPersistentPrev") {
CodeMirror.e_stop(event);
startSearch(cm, getSearchState(cm), query);
cm.execCommand(cmd);
} else if (cmd == "find" || cmd == "findPersistent") {
CodeMirror.e_stop(event);
searchNext(query, event);
}
});
if (immediate && q) {
startSearch(cm, state, q);
findNext(cm, rev);
}
} else {
dialog(cm, queryDialog, "Search for:", q, function(query) {
if (query && !state.query) cm.operation(function() {
startSearch(cm, state, query);
state.posFrom = state.posTo = cm.getCursor();
findNext(cm, rev);
});
});
}
}
function findNext(cm, rev, callback) {cm.operation(function() {
var state = getSearchState(cm);
var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo);
if (!cursor.find(rev)) {
cursor = getSearchCursor(cm, state.query, rev ? CodeMirror.Pos(cm.lastLine()) : CodeMirror.Pos(cm.firstLine(), 0));
if (!cursor.find(rev)) return;
}
cm.setSelection(cursor.from(), cursor.to());
cm.scrollIntoView({from: cursor.from(), to: cursor.to()}, 20);
state.posFrom = cursor.from(); state.posTo = cursor.to();
if (callback) callback(cursor.from(), cursor.to())
});}
function clearSearch(cm) {cm.operation(function() {
var state = getSearchState(cm);
state.lastQuery = state.query;
if (!state.query) return;
state.query = state.queryText = null;
cm.removeOverlay(state.overlay);
if (state.annotate) { state.annotate.clear(); state.annotate = null; }
});}
var replaceQueryDialog =
' <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>';
var replacementQueryDialog = 'With: <input type="text" style="width: 10em" class="CodeMirror-search-field"/>';
var doReplaceConfirm = "Replace? <button>Yes</button> <button>No</button> <button>All</button> <button>Stop</button>";
function replaceAll(cm, query, text) {
cm.operation(function() {
for (var cursor = getSearchCursor(cm, query); cursor.findNext();) {
if (typeof query != "string") {
var match = cm.getRange(cursor.from(), cursor.to()).match(query);
cursor.replace(text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
} else cursor.replace(text);
}
});
}
function replace(cm, all) {
if (cm.getOption("readOnly")) return;
var query = cm.getSelection() || getSearchState(cm).lastQuery;
var dialogText = all ? "Replace all:" : "Replace:"
dialog(cm, dialogText + replaceQueryDialog, dialogText, query, function(query) {
if (!query) return;
query = parseQuery(query);
dialog(cm, replacementQueryDialog, "Replace with:", "", function(text) {
text = parseString(text)
if (all) {
replaceAll(cm, query, text)
} else {
clearSearch(cm);
var cursor = getSearchCursor(cm, query, cm.getCursor("from"));
var advance = function() {
var start = cursor.from(), match;
if (!(match = cursor.findNext())) {
cursor = getSearchCursor(cm, query);
if (!(match = cursor.findNext()) ||
(start && cursor.from().line == start.line && cursor.from().ch == start.ch)) return;
}
cm.setSelection(cursor.from(), cursor.to());
cm.scrollIntoView({from: cursor.from(), to: cursor.to()});
confirmDialog(cm, doReplaceConfirm, "Replace?",
[function() {doReplace(match);}, advance,
function() {replaceAll(cm, query, text)}]);
};
var doReplace = function(match) {
cursor.replace(typeof query == "string" ? text :
text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
advance();
};
advance();
}
});
});
}
CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);};
CodeMirror.commands.findPersistent = function(cm) {clearSearch(cm); doSearch(cm, false, true);};
CodeMirror.commands.findPersistentNext = function(cm) {doSearch(cm, false, true, true);};
CodeMirror.commands.findPersistentPrev = function(cm) {doSearch(cm, true, true, true);};
CodeMirror.commands.findNext = doSearch;
CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);};
CodeMirror.commands.clearSearch = clearSearch;
CodeMirror.commands.replace = replace;
CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);};
});

View File

@ -1,189 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var Pos = CodeMirror.Pos;
function SearchCursor(doc, query, pos, caseFold) {
this.atOccurrence = false; this.doc = doc;
if (caseFold == null && typeof query == "string") caseFold = false;
pos = pos ? doc.clipPos(pos) : Pos(0, 0);
this.pos = {from: pos, to: pos};
// The matches method is filled in based on the type of query.
// It takes a position and a direction, and returns an object
// describing the next occurrence of the query, or null if no
// more matches were found.
if (typeof query != "string") { // Regexp match
if (!query.global) query = new RegExp(query.source, query.ignoreCase ? "ig" : "g");
this.matches = function(reverse, pos) {
if (reverse) {
query.lastIndex = 0;
var line = doc.getLine(pos.line).slice(0, pos.ch), cutOff = 0, match, start;
for (;;) {
query.lastIndex = cutOff;
var newMatch = query.exec(line);
if (!newMatch) break;
match = newMatch;
start = match.index;
cutOff = match.index + (match[0].length || 1);
if (cutOff == line.length) break;
}
var matchLen = (match && match[0].length) || 0;
if (!matchLen) {
if (start == 0 && line.length == 0) {match = undefined;}
else if (start != doc.getLine(pos.line).length) {
matchLen++;
}
}
} else {
query.lastIndex = pos.ch;
var line = doc.getLine(pos.line), match = query.exec(line);
var matchLen = (match && match[0].length) || 0;
var start = match && match.index;
if (start + matchLen != line.length && !matchLen) matchLen = 1;
}
if (match && matchLen)
return {from: Pos(pos.line, start),
to: Pos(pos.line, start + matchLen),
match: match};
};
} else { // String query
var origQuery = query;
if (caseFold) query = query.toLowerCase();
var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;};
var target = query.split("\n");
// Different methods for single-line and multi-line queries
if (target.length == 1) {
if (!query.length) {
// Empty string would match anything and never progress, so
// we define it to match nothing instead.
this.matches = function() {};
} else {
this.matches = function(reverse, pos) {
if (reverse) {
var orig = doc.getLine(pos.line).slice(0, pos.ch), line = fold(orig);
var match = line.lastIndexOf(query);
if (match > -1) {
match = adjustPos(orig, line, match);
return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)};
}
} else {
var orig = doc.getLine(pos.line).slice(pos.ch), line = fold(orig);
var match = line.indexOf(query);
if (match > -1) {
match = adjustPos(orig, line, match) + pos.ch;
return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)};
}
}
};
}
} else {
var origTarget = origQuery.split("\n");
this.matches = function(reverse, pos) {
var last = target.length - 1;
if (reverse) {
if (pos.line - (target.length - 1) < doc.firstLine()) return;
if (fold(doc.getLine(pos.line).slice(0, origTarget[last].length)) != target[target.length - 1]) return;
var to = Pos(pos.line, origTarget[last].length);
for (var ln = pos.line - 1, i = last - 1; i >= 1; --i, --ln)
if (target[i] != fold(doc.getLine(ln))) return;
var line = doc.getLine(ln), cut = line.length - origTarget[0].length;
if (fold(line.slice(cut)) != target[0]) return;
return {from: Pos(ln, cut), to: to};
} else {
if (pos.line + (target.length - 1) > doc.lastLine()) return;
var line = doc.getLine(pos.line), cut = line.length - origTarget[0].length;
if (fold(line.slice(cut)) != target[0]) return;
var from = Pos(pos.line, cut);
for (var ln = pos.line + 1, i = 1; i < last; ++i, ++ln)
if (target[i] != fold(doc.getLine(ln))) return;
if (fold(doc.getLine(ln).slice(0, origTarget[last].length)) != target[last]) return;
return {from: from, to: Pos(ln, origTarget[last].length)};
}
};
}
}
}
SearchCursor.prototype = {
findNext: function() {return this.find(false);},
findPrevious: function() {return this.find(true);},
find: function(reverse) {
var self = this, pos = this.doc.clipPos(reverse ? this.pos.from : this.pos.to);
function savePosAndFail(line) {
var pos = Pos(line, 0);
self.pos = {from: pos, to: pos};
self.atOccurrence = false;
return false;
}
for (;;) {
if (this.pos = this.matches(reverse, pos)) {
this.atOccurrence = true;
return this.pos.match || true;
}
if (reverse) {
if (!pos.line) return savePosAndFail(0);
pos = Pos(pos.line-1, this.doc.getLine(pos.line-1).length);
}
else {
var maxLine = this.doc.lineCount();
if (pos.line == maxLine - 1) return savePosAndFail(maxLine);
pos = Pos(pos.line + 1, 0);
}
}
},
from: function() {if (this.atOccurrence) return this.pos.from;},
to: function() {if (this.atOccurrence) return this.pos.to;},
replace: function(newText, origin) {
if (!this.atOccurrence) return;
var lines = CodeMirror.splitLines(newText);
this.doc.replaceRange(lines, this.pos.from, this.pos.to, origin);
this.pos.to = Pos(this.pos.from.line + lines.length - 1,
lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0));
}
};
// Maps a position in a case-folded line back to a position in the original line
// (compensating for codepoints increasing in number during folding)
function adjustPos(orig, folded, pos) {
if (orig.length == folded.length) return pos;
for (var pos1 = Math.min(pos, orig.length);;) {
var len1 = orig.slice(0, pos1).toLowerCase().length;
if (len1 < pos) ++pos1;
else if (len1 > pos) --pos1;
else return pos1;
}
}
CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) {
return new SearchCursor(this.doc, query, pos, caseFold);
});
CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) {
return new SearchCursor(this, query, pos, caseFold);
});
CodeMirror.defineExtension("selectMatches", function(query, caseFold) {
var ranges = [];
var cur = this.getSearchCursor(query, this.getCursor("from"), caseFold);
while (cur.findNext()) {
if (CodeMirror.cmpPos(cur.to(), this.getCursor("to")) > 0) break;
ranges.push({anchor: cur.from(), head: cur.to()});
}
if (ranges.length)
this.setSelections(ranges, 0);
});
});

View File

@ -1,416 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var Pos = CodeMirror.Pos;
function posEq(a, b) { return a.line == b.line && a.ch == b.ch; }
// Kill 'ring'
var killRing = [];
function addToRing(str) {
killRing.push(str);
if (killRing.length > 50) killRing.shift();
}
function growRingTop(str) {
if (!killRing.length) return addToRing(str);
killRing[killRing.length - 1] += str;
}
function getFromRing(n) { return killRing[killRing.length - (n ? Math.min(n, 1) : 1)] || ""; }
function popFromRing() { if (killRing.length > 1) killRing.pop(); return getFromRing(); }
var lastKill = null;
function kill(cm, from, to, mayGrow, text) {
if (text == null) text = cm.getRange(from, to);
if (mayGrow && lastKill && lastKill.cm == cm && posEq(from, lastKill.pos) && cm.isClean(lastKill.gen))
growRingTop(text);
else
addToRing(text);
cm.replaceRange("", from, to, "+delete");
if (mayGrow) lastKill = {cm: cm, pos: from, gen: cm.changeGeneration()};
else lastKill = null;
}
// Boundaries of various units
function byChar(cm, pos, dir) {
return cm.findPosH(pos, dir, "char", true);
}
function byWord(cm, pos, dir) {
return cm.findPosH(pos, dir, "word", true);
}
function byLine(cm, pos, dir) {
return cm.findPosV(pos, dir, "line", cm.doc.sel.goalColumn);
}
function byPage(cm, pos, dir) {
return cm.findPosV(pos, dir, "page", cm.doc.sel.goalColumn);
}
function byParagraph(cm, pos, dir) {
var no = pos.line, line = cm.getLine(no);
var sawText = /\S/.test(dir < 0 ? line.slice(0, pos.ch) : line.slice(pos.ch));
var fst = cm.firstLine(), lst = cm.lastLine();
for (;;) {
no += dir;
if (no < fst || no > lst)
return cm.clipPos(Pos(no - dir, dir < 0 ? 0 : null));
line = cm.getLine(no);
var hasText = /\S/.test(line);
if (hasText) sawText = true;
else if (sawText) return Pos(no, 0);
}
}
function bySentence(cm, pos, dir) {
var line = pos.line, ch = pos.ch;
var text = cm.getLine(pos.line), sawWord = false;
for (;;) {
var next = text.charAt(ch + (dir < 0 ? -1 : 0));
if (!next) { // End/beginning of line reached
if (line == (dir < 0 ? cm.firstLine() : cm.lastLine())) return Pos(line, ch);
text = cm.getLine(line + dir);
if (!/\S/.test(text)) return Pos(line, ch);
line += dir;
ch = dir < 0 ? text.length : 0;
continue;
}
if (sawWord && /[!?.]/.test(next)) return Pos(line, ch + (dir > 0 ? 1 : 0));
if (!sawWord) sawWord = /\w/.test(next);
ch += dir;
}
}
function byExpr(cm, pos, dir) {
var wrap;
if (cm.findMatchingBracket && (wrap = cm.findMatchingBracket(pos, true))
&& wrap.match && (wrap.forward ? 1 : -1) == dir)
return dir > 0 ? Pos(wrap.to.line, wrap.to.ch + 1) : wrap.to;
for (var first = true;; first = false) {
var token = cm.getTokenAt(pos);
var after = Pos(pos.line, dir < 0 ? token.start : token.end);
if (first && dir > 0 && token.end == pos.ch || !/\w/.test(token.string)) {
var newPos = cm.findPosH(after, dir, "char");
if (posEq(after, newPos)) return pos;
else pos = newPos;
} else {
return after;
}
}
}
// Prefixes (only crudely supported)
function getPrefix(cm, precise) {
var digits = cm.state.emacsPrefix;
if (!digits) return precise ? null : 1;
clearPrefix(cm);
return digits == "-" ? -1 : Number(digits);
}
function repeated(cmd) {
var f = typeof cmd == "string" ? function(cm) { cm.execCommand(cmd); } : cmd;
return function(cm) {
var prefix = getPrefix(cm);
f(cm);
for (var i = 1; i < prefix; ++i) f(cm);
};
}
function findEnd(cm, pos, by, dir) {
var prefix = getPrefix(cm);
if (prefix < 0) { dir = -dir; prefix = -prefix; }
for (var i = 0; i < prefix; ++i) {
var newPos = by(cm, pos, dir);
if (posEq(newPos, pos)) break;
pos = newPos;
}
return pos;
}
function move(by, dir) {
var f = function(cm) {
cm.extendSelection(findEnd(cm, cm.getCursor(), by, dir));
};
f.motion = true;
return f;
}
function killTo(cm, by, dir) {
var selections = cm.listSelections(), cursor;
var i = selections.length;
while (i--) {
cursor = selections[i].head;
kill(cm, cursor, findEnd(cm, cursor, by, dir), true);
}
}
function killRegion(cm) {
if (cm.somethingSelected()) {
var selections = cm.listSelections(), selection;
var i = selections.length;
while (i--) {
selection = selections[i];
kill(cm, selection.anchor, selection.head);
}
return true;
}
}
function addPrefix(cm, digit) {
if (cm.state.emacsPrefix) {
if (digit != "-") cm.state.emacsPrefix += digit;
return;
}
// Not active yet
cm.state.emacsPrefix = digit;
cm.on("keyHandled", maybeClearPrefix);
cm.on("inputRead", maybeDuplicateInput);
}
var prefixPreservingKeys = {"Alt-G": true, "Ctrl-X": true, "Ctrl-Q": true, "Ctrl-U": true};
function maybeClearPrefix(cm, arg) {
if (!cm.state.emacsPrefixMap && !prefixPreservingKeys.hasOwnProperty(arg))
clearPrefix(cm);
}
function clearPrefix(cm) {
cm.state.emacsPrefix = null;
cm.off("keyHandled", maybeClearPrefix);
cm.off("inputRead", maybeDuplicateInput);
}
function maybeDuplicateInput(cm, event) {
var dup = getPrefix(cm);
if (dup > 1 && event.origin == "+input") {
var one = event.text.join("\n"), txt = "";
for (var i = 1; i < dup; ++i) txt += one;
cm.replaceSelection(txt);
}
}
function addPrefixMap(cm) {
cm.state.emacsPrefixMap = true;
cm.addKeyMap(prefixMap);
cm.on("keyHandled", maybeRemovePrefixMap);
cm.on("inputRead", maybeRemovePrefixMap);
}
function maybeRemovePrefixMap(cm, arg) {
if (typeof arg == "string" && (/^\d$/.test(arg) || arg == "Ctrl-U")) return;
cm.removeKeyMap(prefixMap);
cm.state.emacsPrefixMap = false;
cm.off("keyHandled", maybeRemovePrefixMap);
cm.off("inputRead", maybeRemovePrefixMap);
}
// Utilities
function setMark(cm) {
cm.setCursor(cm.getCursor());
cm.setExtending(!cm.getExtending());
cm.on("change", function() { cm.setExtending(false); });
}
function clearMark(cm) {
cm.setExtending(false);
cm.setCursor(cm.getCursor());
}
function getInput(cm, msg, f) {
if (cm.openDialog)
cm.openDialog(msg + ": <input type=\"text\" style=\"width: 10em\"/>", f, {bottom: true});
else
f(prompt(msg, ""));
}
function operateOnWord(cm, op) {
var start = cm.getCursor(), end = cm.findPosH(start, 1, "word");
cm.replaceRange(op(cm.getRange(start, end)), start, end);
cm.setCursor(end);
}
function toEnclosingExpr(cm) {
var pos = cm.getCursor(), line = pos.line, ch = pos.ch;
var stack = [];
while (line >= cm.firstLine()) {
var text = cm.getLine(line);
for (var i = ch == null ? text.length : ch; i > 0;) {
var ch = text.charAt(--i);
if (ch == ")")
stack.push("(");
else if (ch == "]")
stack.push("[");
else if (ch == "}")
stack.push("{");
else if (/[\(\{\[]/.test(ch) && (!stack.length || stack.pop() != ch))
return cm.extendSelection(Pos(line, i));
}
--line; ch = null;
}
}
function quit(cm) {
cm.execCommand("clearSearch");
clearMark(cm);
}
CodeMirror.emacs = {kill: kill, killRegion: killRegion, repeated: repeated};
// Actual keymap
var keyMap = CodeMirror.keyMap.emacs = CodeMirror.normalizeKeyMap({
"Ctrl-W": function(cm) {kill(cm, cm.getCursor("start"), cm.getCursor("end"));},
"Ctrl-K": repeated(function(cm) {
var start = cm.getCursor(), end = cm.clipPos(Pos(start.line));
var text = cm.getRange(start, end);
if (!/\S/.test(text)) {
text += "\n";
end = Pos(start.line + 1, 0);
}
kill(cm, start, end, true, text);
}),
"Alt-W": function(cm) {
addToRing(cm.getSelection());
clearMark(cm);
},
"Ctrl-Y": function(cm) {
var start = cm.getCursor();
cm.replaceRange(getFromRing(getPrefix(cm)), start, start, "paste");
cm.setSelection(start, cm.getCursor());
},
"Alt-Y": function(cm) {cm.replaceSelection(popFromRing(), "around", "paste");},
"Ctrl-Space": setMark, "Ctrl-Shift-2": setMark,
"Ctrl-F": move(byChar, 1), "Ctrl-B": move(byChar, -1),
"Right": move(byChar, 1), "Left": move(byChar, -1),
"Ctrl-D": function(cm) { killTo(cm, byChar, 1); },
"Delete": function(cm) { killRegion(cm) || killTo(cm, byChar, 1); },
"Ctrl-H": function(cm) { killTo(cm, byChar, -1); },
"Backspace": function(cm) { killRegion(cm) || killTo(cm, byChar, -1); },
"Alt-F": move(byWord, 1), "Alt-B": move(byWord, -1),
"Alt-D": function(cm) { killTo(cm, byWord, 1); },
"Alt-Backspace": function(cm) { killTo(cm, byWord, -1); },
"Ctrl-N": move(byLine, 1), "Ctrl-P": move(byLine, -1),
"Down": move(byLine, 1), "Up": move(byLine, -1),
"Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
"End": "goLineEnd", "Home": "goLineStart",
"Alt-V": move(byPage, -1), "Ctrl-V": move(byPage, 1),
"PageUp": move(byPage, -1), "PageDown": move(byPage, 1),
"Ctrl-Up": move(byParagraph, -1), "Ctrl-Down": move(byParagraph, 1),
"Alt-A": move(bySentence, -1), "Alt-E": move(bySentence, 1),
"Alt-K": function(cm) { killTo(cm, bySentence, 1); },
"Ctrl-Alt-K": function(cm) { killTo(cm, byExpr, 1); },
"Ctrl-Alt-Backspace": function(cm) { killTo(cm, byExpr, -1); },
"Ctrl-Alt-F": move(byExpr, 1), "Ctrl-Alt-B": move(byExpr, -1),
"Shift-Ctrl-Alt-2": function(cm) {
var cursor = cm.getCursor();
cm.setSelection(findEnd(cm, cursor, byExpr, 1), cursor);
},
"Ctrl-Alt-T": function(cm) {
var leftStart = byExpr(cm, cm.getCursor(), -1), leftEnd = byExpr(cm, leftStart, 1);
var rightEnd = byExpr(cm, leftEnd, 1), rightStart = byExpr(cm, rightEnd, -1);
cm.replaceRange(cm.getRange(rightStart, rightEnd) + cm.getRange(leftEnd, rightStart) +
cm.getRange(leftStart, leftEnd), leftStart, rightEnd);
},
"Ctrl-Alt-U": repeated(toEnclosingExpr),
"Alt-Space": function(cm) {
var pos = cm.getCursor(), from = pos.ch, to = pos.ch, text = cm.getLine(pos.line);
while (from && /\s/.test(text.charAt(from - 1))) --from;
while (to < text.length && /\s/.test(text.charAt(to))) ++to;
cm.replaceRange(" ", Pos(pos.line, from), Pos(pos.line, to));
},
"Ctrl-O": repeated(function(cm) { cm.replaceSelection("\n", "start"); }),
"Ctrl-T": repeated(function(cm) {
cm.execCommand("transposeChars");
}),
"Alt-C": repeated(function(cm) {
operateOnWord(cm, function(w) {
var letter = w.search(/\w/);
if (letter == -1) return w;
return w.slice(0, letter) + w.charAt(letter).toUpperCase() + w.slice(letter + 1).toLowerCase();
});
}),
"Alt-U": repeated(function(cm) {
operateOnWord(cm, function(w) { return w.toUpperCase(); });
}),
"Alt-L": repeated(function(cm) {
operateOnWord(cm, function(w) { return w.toLowerCase(); });
}),
"Alt-;": "toggleComment",
"Ctrl-/": repeated("undo"), "Shift-Ctrl--": repeated("undo"),
"Ctrl-Z": repeated("undo"), "Cmd-Z": repeated("undo"),
"Shift-Alt-,": "goDocStart", "Shift-Alt-.": "goDocEnd",
"Ctrl-S": "findNext", "Ctrl-R": "findPrev", "Ctrl-G": quit, "Shift-Alt-5": "replace",
"Alt-/": "autocomplete",
"Enter": "newlineAndIndent",
"Ctrl-J": repeated(function(cm) { cm.replaceSelection("\n", "end"); }),
"Tab": "indentAuto",
"Alt-G G": function(cm) {
var prefix = getPrefix(cm, true);
if (prefix != null && prefix > 0) return cm.setCursor(prefix - 1);
getInput(cm, "Goto line", function(str) {
var num;
if (str && !isNaN(num = Number(str)) && num == (num|0) && num > 0)
cm.setCursor(num - 1);
});
},
"Ctrl-X Tab": function(cm) {
cm.indentSelection(getPrefix(cm, true) || cm.getOption("indentUnit"));
},
"Ctrl-X Ctrl-X": function(cm) {
cm.setSelection(cm.getCursor("head"), cm.getCursor("anchor"));
},
"Ctrl-X Ctrl-S": "save",
"Ctrl-X Ctrl-W": "save",
"Ctrl-X S": "saveAll",
"Ctrl-X F": "open",
"Ctrl-X U": repeated("undo"),
"Ctrl-X K": "close",
"Ctrl-X Delete": function(cm) { kill(cm, cm.getCursor(), bySentence(cm, cm.getCursor(), 1), true); },
"Ctrl-X H": "selectAll",
"Ctrl-Q Tab": repeated("insertTab"),
"Ctrl-U": addPrefixMap
});
var prefixMap = {"Ctrl-G": clearPrefix};
function regPrefix(d) {
prefixMap[d] = function(cm) { addPrefix(cm, d); };
keyMap["Ctrl-" + d] = function(cm) { addPrefix(cm, d); };
prefixPreservingKeys["Ctrl-" + d] = true;
}
for (var i = 0; i < 10; ++i) regPrefix(String(i));
regPrefix("-");
});

File diff suppressed because it is too large Load Diff

View File

@ -1,103 +0,0 @@
<!doctype html>
<title>CodeMirror: Closure Stylesheets (GSS) mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<link rel="stylesheet" href="../../addon/hint/show-hint.css">
<script src="../../lib/codemirror.js"></script>
<script src="css.js"></script>
<script src="../../addon/hint/show-hint.js"></script>
<script src="../../addon/hint/css-hint.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">Closure Stylesheets (GSS)</a>
</ul>
</div>
<article>
<h2>Closure Stylesheets (GSS) mode</h2>
<form><textarea id="code" name="code">
/* Some example Closure Stylesheets */
@provide 'some.styles';
@require 'other.styles';
@component {
@def FONT_FAMILY "Times New Roman", Georgia, Serif;
@def FONT_SIZE_NORMAL 15px;
@def FONT_NORMAL normal FONT_SIZE_NORMAL FONT_FAMILY;
@def BG_COLOR rgb(235, 239, 249);
@def DIALOG_BORDER_COLOR rgb(107, 144, 218);
@def DIALOG_BG_COLOR BG_COLOR;
@def LEFT_HAND_NAV_WIDTH 180px;
@def LEFT_HAND_NAV_PADDING 3px;
@defmixin size(WIDTH, HEIGHT) {
width: WIDTH;
height: HEIGHT;
}
body {
background-color: BG_COLOR;
margin: 0;
padding: 3em 6em;
font: FONT_NORMAL;
color: #000;
}
#navigation a {
font-weight: bold;
text-decoration: none !important;
}
.dialog {
background-color: DIALOG_BG_COLOR;
border: 1px solid DIALOG_BORDER_COLOR;
}
.content {
position: absolute;
margin-left: add(LEFT_HAND_NAV_PADDING, /* padding left */
LEFT_HAND_NAV_WIDTH,
LEFT_HAND_NAV_PADDING); /* padding right */
}
.logo {
@mixin size(150px, 55px);
background-image: url('http://www.google.com/images/logo_sm.gif');
}
}
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
extraKeys: {"Ctrl-Space": "autocomplete"},
lineNumbers: true,
matchBrackets: "text/x-less",
mode: "text/x-gss"
});
</script>
<p>A mode for <a href="https://github.com/google/closure-stylesheets">Closure Stylesheets</a> (GSS).</p>
<p><strong>MIME type defined:</strong> <code>text/x-gss</code>.</p>
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#gss_*">normal</a>, <a href="../../test/index.html#verbose,gss_*">verbose</a>.</p>
</article>

View File

@ -1,17 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function() {
"use strict";
var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-gss");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "gss"); }
MT("atComponent",
"[def @component] {",
"[tag foo] {",
" [property color]: [keyword black];",
"}",
"}");
})();

View File

@ -1,75 +0,0 @@
<!doctype html>
<title>CodeMirror: CSS mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<link rel="stylesheet" href="../../addon/hint/show-hint.css">
<script src="../../lib/codemirror.js"></script>
<script src="css.js"></script>
<script src="../../addon/hint/show-hint.js"></script>
<script src="../../addon/hint/css-hint.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">CSS</a>
</ul>
</div>
<article>
<h2>CSS mode</h2>
<form><textarea id="code" name="code">
/* Some example CSS */
@import url("something.css");
body {
margin: 0;
padding: 3em 6em;
font-family: tahoma, arial, sans-serif;
color: #000;
}
#navigation a {
font-weight: bold;
text-decoration: none !important;
}
h1 {
font-size: 2.5em;
}
h2 {
font-size: 1.7em;
}
h1:before, h2:before {
content: "::";
}
code {
font-family: courier, monospace;
font-size: 80%;
color: #418A8A;
}
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
extraKeys: {"Ctrl-Space": "autocomplete"}
});
</script>
<p><strong>MIME types defined:</strong> <code>text/css</code>, <code>text/x-scss</code> (<a href="scss.html">demo</a>), <code>text/x-less</code> (<a href="less.html">demo</a>).</p>
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#css_*">normal</a>, <a href="../../test/index.html#verbose,css_*">verbose</a>.</p>
</article>

View File

@ -1,152 +0,0 @@
<!doctype html>
<title>CodeMirror: LESS mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="css.js"></script>
<style>.CodeMirror {border: 1px solid #ddd; line-height: 1.2;}</style>
<div id=nav>
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">LESS</a>
</ul>
</div>
<article>
<h2>LESS mode</h2>
<form><textarea id="code" name="code">@media screen and (device-aspect-ratio: 16/9) { … }
@media screen and (device-aspect-ratio: 1280/720) { … }
@media screen and (device-aspect-ratio: 2560/1440) { … }
html:lang(fr-be)
tr:nth-child(2n+1) /* represents every odd row of an HTML table */
img:nth-of-type(2n+1) { float: right; }
img:nth-of-type(2n) { float: left; }
body > h2:not(:first-of-type):not(:last-of-type)
html|*:not(:link):not(:visited)
*|*:not(:hover)
p::first-line { text-transform: uppercase }
@namespace foo url(http://www.example.com);
foo|h1 { color: blue } /* first rule */
span[hello="Ocean"][goodbye="Land"]
E[foo]{
padding:65px;
}
input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-cancel-button {
-webkit-appearance: none; // Inner-padding issues in Chrome OSX, Safari 5
}
button::-moz-focus-inner,
input::-moz-focus-inner { // Inner padding and border oddities in FF3/4
padding: 0;
border: 0;
}
.btn {
// reset here as of 2.0.3 due to Recess property order
border-color: #ccc;
border-color: rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);
}
fieldset span button, fieldset span input[type="file"] {
font-size:12px;
font-family:Arial, Helvetica, sans-serif;
}
.rounded-corners (@radius: 5px) {
border-radius: @radius;
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
}
@import url("something.css");
@light-blue: hsl(190, 50%, 65%);
#menu {
position: absolute;
width: 100%;
z-index: 3;
clear: both;
display: block;
background-color: @blue;
height: 42px;
border-top: 2px solid lighten(@alpha-blue, 20%);
border-bottom: 2px solid darken(@alpha-blue, 25%);
.box-shadow(0, 1px, 8px, 0.6);
-moz-box-shadow: 0 0 0 #000; // Because firefox sucks.
&.docked {
background-color: hsla(210, 60%, 40%, 0.4);
}
&:hover {
background-color: @blue;
}
#dropdown {
margin: 0 0 0 117px;
padding: 0;
padding-top: 5px;
display: none;
width: 190px;
border-top: 2px solid @medium;
color: @highlight;
border: 2px solid darken(@medium, 25%);
border-left-color: darken(@medium, 15%);
border-right-color: darken(@medium, 15%);
border-top-width: 0;
background-color: darken(@medium, 10%);
ul {
padding: 0px;
}
li {
font-size: 14px;
display: block;
text-align: left;
padding: 0;
border: 0;
a {
display: block;
padding: 0px 15px;
text-decoration: none;
color: white;
&:hover {
background-color: darken(@medium, 15%);
text-decoration: none;
}
}
}
.border-radius(5px, bottom);
.box-shadow(0, 6px, 8px, 0.5);
}
}
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers : true,
matchBrackets : true,
mode: "text/x-less"
});
</script>
<p>The LESS mode is a sub-mode of the <a href="index.html">CSS mode</a> (defined in <code>css.js</code>).</p>
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#less_*">normal</a>, <a href="../../test/index.html#verbose,less_*">verbose</a>.</p>
</article>

View File

@ -1,54 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function() {
"use strict";
var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-less");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "less"); }
MT("variable",
"[variable-2 @base]: [atom #f04615];",
"[qualifier .class] {",
" [property width]: [variable percentage]([number 0.5]); [comment // returns `50%`]",
" [property color]: [variable saturate]([variable-2 @base], [number 5%]);",
"}");
MT("amp",
"[qualifier .child], [qualifier .sibling] {",
" [qualifier .parent] [atom &] {",
" [property color]: [keyword black];",
" }",
" [atom &] + [atom &] {",
" [property color]: [keyword red];",
" }",
"}");
MT("mixin",
"[qualifier .mixin] ([variable dark]; [variable-2 @color]) {",
" [property color]: [atom darken]([variable-2 @color], [number 10%]);",
"}",
"[qualifier .mixin] ([variable light]; [variable-2 @color]) {",
" [property color]: [atom lighten]([variable-2 @color], [number 10%]);",
"}",
"[qualifier .mixin] ([variable-2 @_]; [variable-2 @color]) {",
" [property display]: [atom block];",
"}",
"[variable-2 @switch]: [variable light];",
"[qualifier .class] {",
" [qualifier .mixin]([variable-2 @switch]; [atom #888]);",
"}");
MT("nest",
"[qualifier .one] {",
" [def @media] ([property width]: [number 400px]) {",
" [property font-size]: [number 1.2em];",
" [def @media] [attribute print] [keyword and] [property color] {",
" [property color]: [keyword blue];",
" }",
" }",
"}");
MT("interpolation", ".@{[variable foo]} { [property font-weight]: [atom bold]; }");
})();

View File

@ -1,157 +0,0 @@
<!doctype html>
<title>CodeMirror: SCSS mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="css.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">SCSS</a>
</ul>
</div>
<article>
<h2>SCSS mode</h2>
<form><textarea id="code" name="code">
/* Some example SCSS */
@import "compass/css3";
$variable: #333;
$blue: #3bbfce;
$margin: 16px;
.content-navigation {
#nested {
background-color: black;
}
border-color: $blue;
color:
darken($blue, 9%);
}
.border {
padding: $margin / 2;
margin: $margin / 2;
border-color: $blue;
}
@mixin table-base {
th {
text-align: center;
font-weight: bold;
}
td, th {padding: 2px}
}
table.hl {
margin: 2em 0;
td.ln {
text-align: right;
}
}
li {
font: {
family: serif;
weight: bold;
size: 1.2em;
}
}
@mixin left($dist) {
float: left;
margin-left: $dist;
}
#data {
@include left(10px);
@include table-base;
}
.source {
@include flow-into(target);
border: 10px solid green;
margin: 20px;
width: 200px; }
.new-container {
@include flow-from(target);
border: 10px solid red;
margin: 20px;
width: 200px; }
body {
margin: 0;
padding: 3em 6em;
font-family: tahoma, arial, sans-serif;
color: #000;
}
@mixin yellow() {
background: yellow;
}
.big {
font-size: 14px;
}
.nested {
@include border-radius(3px);
@extend .big;
p {
background: whitesmoke;
a {
color: red;
}
}
}
#navigation a {
font-weight: bold;
text-decoration: none !important;
}
h1 {
font-size: 2.5em;
}
h2 {
font-size: 1.7em;
}
h1:before, h2:before {
content: "::";
}
code {
font-family: courier, monospace;
font-size: 80%;
color: #418A8A;
}
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
matchBrackets: true,
mode: "text/x-scss"
});
</script>
<p>The SCSS mode is a sub-mode of the <a href="index.html">CSS mode</a> (defined in <code>css.js</code>).</p>
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#scss_*">normal</a>, <a href="../../test/index.html#verbose,scss_*">verbose</a>.</p>
</article>

View File

@ -1,110 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-scss");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "scss"); }
MT('url_with_quotation',
"[tag foo] { [property background]:[atom url]([string test.jpg]) }");
MT('url_with_double_quotes',
"[tag foo] { [property background]:[atom url]([string \"test.jpg\"]) }");
MT('url_with_single_quotes',
"[tag foo] { [property background]:[atom url]([string \'test.jpg\']) }");
MT('string',
"[def @import] [string \"compass/css3\"]");
MT('important_keyword',
"[tag foo] { [property background]:[atom url]([string \'test.jpg\']) [keyword !important] }");
MT('variable',
"[variable-2 $blue]:[atom #333]");
MT('variable_as_attribute',
"[tag foo] { [property color]:[variable-2 $blue] }");
MT('numbers',
"[tag foo] { [property padding]:[number 10px] [number 10] [number 10em] [number 8in] }");
MT('number_percentage',
"[tag foo] { [property width]:[number 80%] }");
MT('selector',
"[builtin #hello][qualifier .world]{}");
MT('singleline_comment',
"[comment // this is a comment]");
MT('multiline_comment',
"[comment /*foobar*/]");
MT('attribute_with_hyphen',
"[tag foo] { [property font-size]:[number 10px] }");
MT('string_after_attribute',
"[tag foo] { [property content]:[string \"::\"] }");
MT('directives',
"[def @include] [qualifier .mixin]");
MT('basic_structure',
"[tag p] { [property background]:[keyword red]; }");
MT('nested_structure',
"[tag p] { [tag a] { [property color]:[keyword red]; } }");
MT('mixin',
"[def @mixin] [tag table-base] {}");
MT('number_without_semicolon',
"[tag p] {[property width]:[number 12]}",
"[tag a] {[property color]:[keyword red];}");
MT('atom_in_nested_block',
"[tag p] { [tag a] { [property color]:[atom #000]; } }");
MT('interpolation_in_property',
"[tag foo] { #{[variable-2 $hello]}:[number 2]; }");
MT('interpolation_in_selector',
"[tag foo]#{[variable-2 $hello]} { [property color]:[atom #000]; }");
MT('interpolation_error',
"[tag foo]#{[variable foo]} { [property color]:[atom #000]; }");
MT("divide_operator",
"[tag foo] { [property width]:[number 4] [operator /] [number 2] }");
MT('nested_structure_with_id_selector',
"[tag p] { [builtin #hello] { [property color]:[keyword red]; } }");
MT('indent_mixin',
"[def @mixin] [tag container] (",
" [variable-2 $a]: [number 10],",
" [variable-2 $b]: [number 10])",
"{}");
MT('indent_nested',
"[tag foo] {",
" [tag bar] {",
" }",
"}");
MT('indent_parentheses',
"[tag foo] {",
" [property color]: [atom darken]([variable-2 $blue],",
" [number 9%]);",
"}");
MT('indent_vardef',
"[variable-2 $name]:",
" [string 'val'];",
"[tag tag] {",
" [tag inner] {",
" [property margin]: [number 3px];",
" }",
"}");
})();

View File

@ -1,200 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "css");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
// Error, because "foobarhello" is neither a known type or property, but
// property was expected (after "and"), and it should be in parentheses.
MT("atMediaUnknownType",
"[def @media] [attribute screen] [keyword and] [error foobarhello] { }");
// Soft error, because "foobarhello" is not a known property or type.
MT("atMediaUnknownProperty",
"[def @media] [attribute screen] [keyword and] ([error foobarhello]) { }");
// Make sure nesting works with media queries
MT("atMediaMaxWidthNested",
"[def @media] [attribute screen] [keyword and] ([property max-width]: [number 25px]) { [tag foo] { } }");
MT("atMediaFeatureValueKeyword",
"[def @media] ([property orientation]: [keyword landscape]) { }");
MT("atMediaUnknownFeatureValueKeyword",
"[def @media] ([property orientation]: [error upsidedown]) { }");
MT("tagSelector",
"[tag foo] { }");
MT("classSelector",
"[qualifier .foo-bar_hello] { }");
MT("idSelector",
"[builtin #foo] { [error #foo] }");
MT("tagSelectorUnclosed",
"[tag foo] { [property margin]: [number 0] } [tag bar] { }");
MT("tagStringNoQuotes",
"[tag foo] { [property font-family]: [variable hello] [variable world]; }");
MT("tagStringDouble",
"[tag foo] { [property font-family]: [string \"hello world\"]; }");
MT("tagStringSingle",
"[tag foo] { [property font-family]: [string 'hello world']; }");
MT("tagColorKeyword",
"[tag foo] {",
" [property color]: [keyword black];",
" [property color]: [keyword navy];",
" [property color]: [keyword yellow];",
"}");
MT("tagColorHex3",
"[tag foo] { [property background]: [atom #fff]; }");
MT("tagColorHex4",
"[tag foo] { [property background]: [atom #ffff]; }");
MT("tagColorHex6",
"[tag foo] { [property background]: [atom #ffffff]; }");
MT("tagColorHex8",
"[tag foo] { [property background]: [atom #ffffffff]; }");
MT("tagColorHex5Invalid",
"[tag foo] { [property background]: [atom&error #fffff]; }");
MT("tagColorHexInvalid",
"[tag foo] { [property background]: [atom&error #ffg]; }");
MT("tagNegativeNumber",
"[tag foo] { [property margin]: [number -5px]; }");
MT("tagPositiveNumber",
"[tag foo] { [property padding]: [number 5px]; }");
MT("tagVendor",
"[tag foo] { [meta -foo-][property box-sizing]: [meta -foo-][atom border-box]; }");
MT("tagBogusProperty",
"[tag foo] { [property&error barhelloworld]: [number 0]; }");
MT("tagTwoProperties",
"[tag foo] { [property margin]: [number 0]; [property padding]: [number 0]; }");
MT("tagTwoPropertiesURL",
"[tag foo] { [property background]: [atom url]([string //example.com/foo.png]); [property padding]: [number 0]; }");
MT("indent_tagSelector",
"[tag strong], [tag em] {",
" [property background]: [atom rgba](",
" [number 255], [number 255], [number 0], [number .2]",
" );",
"}");
MT("indent_atMedia",
"[def @media] {",
" [tag foo] {",
" [property color]:",
" [keyword yellow];",
" }",
"}");
MT("indent_comma",
"[tag foo] {",
" [property font-family]: [variable verdana],",
" [atom sans-serif];",
"}");
MT("indent_parentheses",
"[tag foo]:[variable-3 before] {",
" [property background]: [atom url](",
"[string blahblah]",
"[string etc]",
"[string ]) [keyword !important];",
"}");
MT("font_face",
"[def @font-face] {",
" [property font-family]: [string 'myfont'];",
" [error nonsense]: [string 'abc'];",
" [property src]: [atom url]([string http://blah]),",
" [atom url]([string http://foo]);",
"}");
MT("empty_url",
"[def @import] [atom url]() [attribute screen];");
MT("parens",
"[qualifier .foo] {",
" [property background-image]: [variable fade]([atom #000], [number 20%]);",
" [property border-image]: [atom linear-gradient](",
" [atom to] [atom bottom],",
" [variable fade]([atom #000], [number 20%]) [number 0%],",
" [variable fade]([atom #000], [number 20%]) [number 100%]",
" );",
"}");
MT("css_variable",
":[variable-3 root] {",
" [variable-2 --main-color]: [atom #06c];",
"}",
"[tag h1][builtin #foo] {",
" [property color]: [atom var]([variable-2 --main-color]);",
"}");
MT("supports",
"[def @supports] ([keyword not] (([property text-align-last]: [atom justify]) [keyword or] ([meta -moz-][property text-align-last]: [atom justify])) {",
" [property text-align-last]: [atom justify];",
"}");
MT("document",
"[def @document] [tag url]([string http://blah]),",
" [tag url-prefix]([string https://]),",
" [tag domain]([string blah.com]),",
" [tag regexp]([string \".*blah.+\"]) {",
" [builtin #id] {",
" [property background-color]: [keyword white];",
" }",
" [tag foo] {",
" [property font-family]: [variable Verdana], [atom sans-serif];",
" }",
"}");
MT("document_url",
"[def @document] [tag url]([string http://blah]) { [qualifier .class] { } }");
MT("document_urlPrefix",
"[def @document] [tag url-prefix]([string https://]) { [builtin #id] { } }");
MT("document_domain",
"[def @document] [tag domain]([string blah.com]) { [tag foo] { } }");
MT("document_regexp",
"[def @document] [tag regexp]([string \".*blah.+\"]) { [builtin #id] { } }");
MT("counter-style",
"[def @counter-style] [variable binary] {",
" [property system]: [atom numeric];",
" [property symbols]: [number 0] [number 1];",
" [property suffix]: [string \".\"];",
" [property range]: [atom infinite];",
" [property speak-as]: [atom numeric];",
"}");
MT("counter-style-additive-symbols",
"[def @counter-style] [variable simple-roman] {",
" [property system]: [atom additive];",
" [property additive-symbols]: [number 10] [variable X], [number 5] [variable V], [number 1] [variable I];",
" [property range]: [number 1] [number 49];",
"}");
MT("counter-style-use",
"[tag ol][qualifier .roman] { [property list-style]: [variable simple-roman]; }");
MT("counter-style-symbols",
"[tag ol] { [property list-style]: [atom symbols]([atom cyclic] [string \"*\"] [string \"\\2020\"] [string \"\\2021\"] [string \"\\A7\"]); }");
})();

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,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 { 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,38 +0,0 @@
/*
Name: Base16 Default Dark
Author: Chris Kempson (http://chriskempson.com)
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-base16-dark.CodeMirror { background: #151515; color: #e0e0e0; }
.cm-s-base16-dark div.CodeMirror-selected { background: #303030; }
.cm-s-base16-dark .CodeMirror-line::selection, .cm-s-base16-dark .CodeMirror-line > span::selection, .cm-s-base16-dark .CodeMirror-line > span > span::selection { background: rgba(48, 48, 48, .99); }
.cm-s-base16-dark .CodeMirror-line::-moz-selection, .cm-s-base16-dark .CodeMirror-line > span::-moz-selection, .cm-s-base16-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(48, 48, 48, .99); }
.cm-s-base16-dark .CodeMirror-gutters { background: #151515; border-right: 0px; }
.cm-s-base16-dark .CodeMirror-guttermarker { color: #ac4142; }
.cm-s-base16-dark .CodeMirror-guttermarker-subtle { color: #505050; }
.cm-s-base16-dark .CodeMirror-linenumber { color: #505050; }
.cm-s-base16-dark .CodeMirror-cursor { border-left: 1px solid #b0b0b0; }
.cm-s-base16-dark span.cm-comment { color: #8f5536; }
.cm-s-base16-dark span.cm-atom { color: #aa759f; }
.cm-s-base16-dark span.cm-number { color: #aa759f; }
.cm-s-base16-dark span.cm-property, .cm-s-base16-dark span.cm-attribute { color: #90a959; }
.cm-s-base16-dark span.cm-keyword { color: #ac4142; }
.cm-s-base16-dark span.cm-string { color: #f4bf75; }
.cm-s-base16-dark span.cm-variable { color: #90a959; }
.cm-s-base16-dark span.cm-variable-2 { color: #6a9fb5; }
.cm-s-base16-dark span.cm-def { color: #d28445; }
.cm-s-base16-dark span.cm-bracket { color: #e0e0e0; }
.cm-s-base16-dark span.cm-tag { color: #ac4142; }
.cm-s-base16-dark span.cm-link { color: #aa759f; }
.cm-s-base16-dark span.cm-error { background: #ac4142; color: #b0b0b0; }
.cm-s-base16-dark .CodeMirror-activeline-background { background: #202020; }
.cm-s-base16-dark .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }

View File

@ -1,38 +0,0 @@
/*
Name: Base16 Default Light
Author: Chris Kempson (http://chriskempson.com)
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-base16-light.CodeMirror { background: #f5f5f5; color: #202020; }
.cm-s-base16-light div.CodeMirror-selected { background: #e0e0e0; }
.cm-s-base16-light .CodeMirror-line::selection, .cm-s-base16-light .CodeMirror-line > span::selection, .cm-s-base16-light .CodeMirror-line > span > span::selection { background: #e0e0e0; }
.cm-s-base16-light .CodeMirror-line::-moz-selection, .cm-s-base16-light .CodeMirror-line > span::-moz-selection, .cm-s-base16-light .CodeMirror-line > span > span::-moz-selection { background: #e0e0e0; }
.cm-s-base16-light .CodeMirror-gutters { background: #f5f5f5; border-right: 0px; }
.cm-s-base16-light .CodeMirror-guttermarker { color: #ac4142; }
.cm-s-base16-light .CodeMirror-guttermarker-subtle { color: #b0b0b0; }
.cm-s-base16-light .CodeMirror-linenumber { color: #b0b0b0; }
.cm-s-base16-light .CodeMirror-cursor { border-left: 1px solid #505050; }
.cm-s-base16-light span.cm-comment { color: #8f5536; }
.cm-s-base16-light span.cm-atom { color: #aa759f; }
.cm-s-base16-light span.cm-number { color: #aa759f; }
.cm-s-base16-light span.cm-property, .cm-s-base16-light span.cm-attribute { color: #90a959; }
.cm-s-base16-light span.cm-keyword { color: #ac4142; }
.cm-s-base16-light span.cm-string { color: #f4bf75; }
.cm-s-base16-light span.cm-variable { color: #90a959; }
.cm-s-base16-light span.cm-variable-2 { color: #6a9fb5; }
.cm-s-base16-light span.cm-def { color: #d28445; }
.cm-s-base16-light span.cm-bracket { color: #202020; }
.cm-s-base16-light span.cm-tag { color: #ac4142; }
.cm-s-base16-light span.cm-link { color: #aa759f; }
.cm-s-base16-light span.cm-error { background: #ac4142; color: #505050; }
.cm-s-base16-light .CodeMirror-activeline-background { background: #DDDCDC; }
.cm-s-base16-light .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }

View File

@ -1,34 +0,0 @@
/*
Name: Bespin
Author: Mozilla / Jan T. Sott
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-bespin.CodeMirror {background: #28211c; color: #9d9b97;}
.cm-s-bespin div.CodeMirror-selected {background: #36312e !important;}
.cm-s-bespin .CodeMirror-gutters {background: #28211c; border-right: 0px;}
.cm-s-bespin .CodeMirror-linenumber {color: #666666;}
.cm-s-bespin .CodeMirror-cursor {border-left: 1px solid #797977 !important;}
.cm-s-bespin span.cm-comment {color: #937121;}
.cm-s-bespin span.cm-atom {color: #9b859d;}
.cm-s-bespin span.cm-number {color: #9b859d;}
.cm-s-bespin span.cm-property, .cm-s-bespin span.cm-attribute {color: #54be0d;}
.cm-s-bespin span.cm-keyword {color: #cf6a4c;}
.cm-s-bespin span.cm-string {color: #f9ee98;}
.cm-s-bespin span.cm-variable {color: #54be0d;}
.cm-s-bespin span.cm-variable-2 {color: #5ea6ea;}
.cm-s-bespin span.cm-def {color: #cf7d34;}
.cm-s-bespin span.cm-error {background: #cf6a4c; color: #797977;}
.cm-s-bespin span.cm-bracket {color: #9d9b97;}
.cm-s-bespin span.cm-tag {color: #cf6a4c;}
.cm-s-bespin span.cm-link {color: #9b859d;}
.cm-s-bespin .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
.cm-s-bespin .CodeMirror-activeline-background { background: #404040; }

View File

@ -1,32 +0,0 @@
/* Port of TextMate's Blackboard theme */
.cm-s-blackboard.CodeMirror { background: #0C1021; color: #F8F8F8; }
.cm-s-blackboard div.CodeMirror-selected { background: #253B76; }
.cm-s-blackboard .CodeMirror-line::selection, .cm-s-blackboard .CodeMirror-line > span::selection, .cm-s-blackboard .CodeMirror-line > span > span::selection { background: rgba(37, 59, 118, .99); }
.cm-s-blackboard .CodeMirror-line::-moz-selection, .cm-s-blackboard .CodeMirror-line > span::-moz-selection, .cm-s-blackboard .CodeMirror-line > span > span::-moz-selection { background: rgba(37, 59, 118, .99); }
.cm-s-blackboard .CodeMirror-gutters { background: #0C1021; border-right: 0; }
.cm-s-blackboard .CodeMirror-guttermarker { color: #FBDE2D; }
.cm-s-blackboard .CodeMirror-guttermarker-subtle { color: #888; }
.cm-s-blackboard .CodeMirror-linenumber { color: #888; }
.cm-s-blackboard .CodeMirror-cursor { border-left: 1px solid #A7A7A7; }
.cm-s-blackboard .cm-keyword { color: #FBDE2D; }
.cm-s-blackboard .cm-atom { color: #D8FA3C; }
.cm-s-blackboard .cm-number { color: #D8FA3C; }
.cm-s-blackboard .cm-def { color: #8DA6CE; }
.cm-s-blackboard .cm-variable { color: #FF6400; }
.cm-s-blackboard .cm-operator { color: #FBDE2D; }
.cm-s-blackboard .cm-comment { color: #AEAEAE; }
.cm-s-blackboard .cm-string { color: #61CE3C; }
.cm-s-blackboard .cm-string-2 { color: #61CE3C; }
.cm-s-blackboard .cm-meta { color: #D8FA3C; }
.cm-s-blackboard .cm-builtin { color: #8DA6CE; }
.cm-s-blackboard .cm-tag { color: #8DA6CE; }
.cm-s-blackboard .cm-attribute { color: #8DA6CE; }
.cm-s-blackboard .cm-header { color: #FF6400; }
.cm-s-blackboard .cm-hr { color: #AEAEAE; }
.cm-s-blackboard .cm-link { color: #8DA6CE; }
.cm-s-blackboard .cm-error { background: #9D1E15; color: #F8F8F8; }
.cm-s-blackboard .CodeMirror-activeline-background { background: #3C3636; }
.cm-s-blackboard .CodeMirror-matchingbracket { outline:1px solid grey;color:white !important; }

View File

@ -1,25 +0,0 @@
.cm-s-cobalt.CodeMirror { background: #002240; color: white; }
.cm-s-cobalt div.CodeMirror-selected { background: #b36539; }
.cm-s-cobalt .CodeMirror-line::selection, .cm-s-cobalt .CodeMirror-line > span::selection, .cm-s-cobalt .CodeMirror-line > span > span::selection { background: rgba(179, 101, 57, .99); }
.cm-s-cobalt .CodeMirror-line::-moz-selection, .cm-s-cobalt .CodeMirror-line > span::-moz-selection, .cm-s-cobalt .CodeMirror-line > span > span::-moz-selection { background: rgba(179, 101, 57, .99); }
.cm-s-cobalt .CodeMirror-gutters { background: #002240; border-right: 1px solid #aaa; }
.cm-s-cobalt .CodeMirror-guttermarker { color: #ffee80; }
.cm-s-cobalt .CodeMirror-guttermarker-subtle { color: #d0d0d0; }
.cm-s-cobalt .CodeMirror-linenumber { color: #d0d0d0; }
.cm-s-cobalt .CodeMirror-cursor { border-left: 1px solid white; }
.cm-s-cobalt span.cm-comment { color: #08f; }
.cm-s-cobalt span.cm-atom { color: #845dc4; }
.cm-s-cobalt span.cm-number, .cm-s-cobalt span.cm-attribute { color: #ff80e1; }
.cm-s-cobalt span.cm-keyword { color: #ffee80; }
.cm-s-cobalt span.cm-string { color: #3ad900; }
.cm-s-cobalt span.cm-meta { color: #ff9d00; }
.cm-s-cobalt span.cm-variable-2, .cm-s-cobalt span.cm-tag { color: #9effff; }
.cm-s-cobalt span.cm-variable-3, .cm-s-cobalt span.cm-def { color: white; }
.cm-s-cobalt span.cm-bracket { color: #d8d8d8; }
.cm-s-cobalt span.cm-builtin, .cm-s-cobalt span.cm-special { color: #ff9e59; }
.cm-s-cobalt span.cm-link { color: #845dc4; }
.cm-s-cobalt span.cm-error { color: #9d1e15; }
.cm-s-cobalt .CodeMirror-activeline-background { background: #002D57; }
.cm-s-cobalt .CodeMirror-matchingbracket { outline:1px solid grey;color:white !important; }

View File

@ -1,33 +0,0 @@
.cm-s-colorforth.CodeMirror { background: #000000; color: #f8f8f8; }
.cm-s-colorforth .CodeMirror-gutters { background: #0a001f; border-right: 1px solid #aaa; }
.cm-s-colorforth .CodeMirror-guttermarker { color: #FFBD40; }
.cm-s-colorforth .CodeMirror-guttermarker-subtle { color: #78846f; }
.cm-s-colorforth .CodeMirror-linenumber { color: #bababa; }
.cm-s-colorforth .CodeMirror-cursor { border-left: 1px solid white; }
.cm-s-colorforth span.cm-comment { color: #ededed; }
.cm-s-colorforth span.cm-def { color: #ff1c1c; font-weight:bold; }
.cm-s-colorforth span.cm-keyword { color: #ffd900; }
.cm-s-colorforth span.cm-builtin { color: #00d95a; }
.cm-s-colorforth span.cm-variable { color: #73ff00; }
.cm-s-colorforth span.cm-string { color: #007bff; }
.cm-s-colorforth span.cm-number { color: #00c4ff; }
.cm-s-colorforth span.cm-atom { color: #606060; }
.cm-s-colorforth span.cm-variable-2 { color: #EEE; }
.cm-s-colorforth span.cm-variable-3 { color: #DDD; }
.cm-s-colorforth span.cm-property {}
.cm-s-colorforth span.cm-operator {}
.cm-s-colorforth span.cm-meta { color: yellow; }
.cm-s-colorforth span.cm-qualifier { color: #FFF700; }
.cm-s-colorforth span.cm-bracket { color: #cc7; }
.cm-s-colorforth span.cm-tag { color: #FFBD40; }
.cm-s-colorforth span.cm-attribute { color: #FFF700; }
.cm-s-colorforth span.cm-error { color: #f00; }
.cm-s-colorforth div.CodeMirror-selected { background: #333d53; }
.cm-s-colorforth span.cm-compilation { background: rgba(255, 255, 255, 0.12); }
.cm-s-colorforth .CodeMirror-activeline-background { background: #253540; }

View File

@ -1,40 +0,0 @@
/*
Name: dracula
Author: Michael Kaminsky (http://github.com/mkaminsky11)
Original dracula color scheme by Zeno Rocha (https://github.com/zenorocha/dracula-theme)
*/
.cm-s-dracula.CodeMirror, .cm-s-dracula .CodeMirror-gutters {
background-color: #282a36 !important;
color: #f8f8f2 !important;
border: none;
}
.cm-s-dracula .CodeMirror-gutters { color: #282a36; }
.cm-s-dracula .CodeMirror-cursor { border-left: solid thin #f8f8f0; }
.cm-s-dracula .CodeMirror-linenumber { color: #6D8A88; }
.cm-s-dracula .CodeMirror-selected { background: rgba(255, 255, 255, 0.10); }
.cm-s-dracula .CodeMirror-line::selection, .cm-s-dracula .CodeMirror-line > span::selection, .cm-s-dracula .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); }
.cm-s-dracula .CodeMirror-line::-moz-selection, .cm-s-dracula .CodeMirror-line > span::-moz-selection, .cm-s-dracula .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); }
.cm-s-dracula span.cm-comment { color: #6272a4; }
.cm-s-dracula span.cm-string, .cm-s-dracula span.cm-string-2 { color: #f1fa8c; }
.cm-s-dracula span.cm-number { color: #bd93f9; }
.cm-s-dracula span.cm-variable { color: #50fa7b; }
.cm-s-dracula span.cm-variable-2 { color: white; }
.cm-s-dracula span.cm-def { color: #50fa7b; }
.cm-s-dracula span.cm-operator { color: #ff79c6; }
.cm-s-dracula span.cm-keyword { color: #ff79c6; }
.cm-s-dracula span.cm-atom { color: #bd93f9; }
.cm-s-dracula span.cm-meta { color: #f8f8f2; }
.cm-s-dracula span.cm-tag { color: #ff79c6; }
.cm-s-dracula span.cm-attribute { color: #50fa7b; }
.cm-s-dracula span.cm-qualifier { color: #50fa7b; }
.cm-s-dracula span.cm-property { color: #66d9ef; }
.cm-s-dracula span.cm-builtin { color: #50fa7b; }
.cm-s-dracula span.cm-variable-3 { color: #ffb86c; }
.cm-s-dracula .CodeMirror-activeline-background { background: rgba(255,255,255,0.1); }
.cm-s-dracula .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }

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