├── .gitignore
├── Changelog.md
├── LICENSE
├── README.md
├── description.txt
├── extension
├── icons
│ ├── 128.png
│ ├── 16.png
│ ├── 32.png
│ ├── gear.svg
│ ├── logo.png
│ ├── raw.svg
│ └── unfold.svg
├── manifest.json
├── pages
│ ├── omnibox.html
│ └── options.html
├── src
│ ├── backend.js
│ ├── json-viewer
│ │ ├── check-if-json.js
│ │ ├── content-extractor.js
│ │ ├── extract-json.js
│ │ ├── highlight-content.js
│ │ ├── highlighter.js
│ │ ├── jsl-format.js
│ │ ├── load-css.js
│ │ ├── merge.js
│ │ ├── options
│ │ │ ├── bind-reset-button.js
│ │ │ ├── bind-save-button.js
│ │ │ ├── defaults.js
│ │ │ ├── render-addons.js
│ │ │ ├── render-structure.js
│ │ │ ├── render-style.js
│ │ │ └── render-theme-list.js
│ │ ├── scratch-pad
│ │ │ ├── load-editor.js
│ │ │ ├── render-format-button.js
│ │ │ └── svg-format.js
│ │ ├── storage.js
│ │ ├── theme-darkness.js
│ │ ├── timestamp.js
│ │ ├── url-pattern.js
│ │ └── viewer
│ │ │ ├── expose-json.js
│ │ │ ├── get-options.js
│ │ │ ├── load-required-css.js
│ │ │ ├── render-alert.js
│ │ │ ├── render-extras.js
│ │ │ ├── svg-gear.js
│ │ │ ├── svg-raw.js
│ │ │ └── svg-unfold.js
│ ├── omnibox-page.js
│ ├── omnibox.js
│ ├── options-styles.js
│ ├── options.js
│ ├── viewer-styles.js
│ └── viewer.js
├── styles
│ ├── default-theme.scss
│ ├── editor-custom.scss
│ ├── options-custom.scss
│ ├── viewer-alert.scss
│ └── viewer-custom.scss
└── themes
│ ├── dark
│ ├── 3024-night.js
│ ├── 3024-night
│ │ └── 3024-night.scss
│ ├── ambiance.js
│ ├── ambiance
│ │ └── ambiance.scss
│ ├── base16-dark.js
│ ├── base16-dark
│ │ └── base16-dark.scss
│ ├── cobalt.js
│ ├── cobalt
│ │ └── cobalt.scss
│ ├── dark.js
│ ├── dark
│ │ ├── dark.scss
│ │ └── dark.theme.css
│ ├── dracula-custom.js
│ ├── dracula-custom
│ │ ├── dracula-custom.scss
│ │ └── dracula-custom.theme.css
│ ├── dracula.js
│ ├── dracula
│ │ ├── dracula.scss
│ │ └── dracula.theme.css
│ ├── jellybeans.js
│ ├── jellybeans
│ │ ├── jellybeans.scss
│ │ └── jellybeans.theme.css
│ ├── material.js
│ ├── material
│ │ ├── material.scss
│ │ └── material.theme.css
│ ├── mbo.js
│ ├── mbo
│ │ └── mbo.scss
│ ├── mehdi.js
│ ├── mehdi
│ │ ├── mehdi.scss
│ │ └── mehdi.theme.css
│ ├── midnight.js
│ ├── midnight
│ │ └── midnight.scss
│ ├── monokai.js
│ ├── monokai
│ │ └── monokai.scss
│ ├── okaidia.js
│ ├── okaidia
│ │ ├── okaidia.scss
│ │ └── okaidia.theme.css
│ ├── panda-syntax.js
│ ├── panda-syntax
│ │ ├── panda-syntax.scss
│ │ └── panda-syntax.theme.css
│ ├── solarized-dark
│ │ └── solarized-dark.scss
│ ├── solarized_dark.js
│ ├── tomorrow.js
│ ├── tomorrow
│ │ ├── tomorrow.scss
│ │ └── tomorrow.theme.css
│ ├── twilight.js
│ ├── twilight
│ │ ├── twilight.scss
│ │ └── twilight.theme.css
│ ├── zenburn.js
│ └── zenburn
│ │ └── zenburn.scss
│ └── light
│ ├── base16-light.js
│ ├── base16-light
│ └── base16-light.scss
│ ├── coy.js
│ ├── coy
│ ├── coy.scss
│ └── coy.theme.css
│ ├── funky.js
│ ├── funky
│ ├── funky.scss
│ └── funky.theme.css
│ ├── mdn-like.js
│ ├── mdn-like
│ └── mdn-like.scss
│ ├── neo.js
│ ├── neo
│ └── neo.scss
│ ├── solarized-light
│ └── solarized-light.scss
│ ├── solarized_light.js
│ ├── yeti.js
│ └── yeti
│ ├── yeti.scss
│ └── yeti.theme.css
├── lib
├── build-extension-webpack-plugin
│ ├── build-extension.js
│ └── index.js
├── build-paths
│ ├── build-paths.js
│ └── index.js
└── release-script
│ ├── index.js
│ └── release-script.js
├── logo.png
├── logo.svg
├── package.json
├── screenshot.png
├── tests
├── geojson.json
├── test.$.json
├── test.array.json
├── test.backslash.json
├── test.json
├── test.jsonp.fake.json
├── test.jsonp.for.json
├── test.jsonp.json
├── test.jsonp.spaces.json
├── test.jsonp.while.json
├── test.multiple-text-nodes.html
├── test.onlyString.json
└── test2.json
├── tryitnow.png
├── webpack.config.js
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | build/*
3 | pkg/*
4 | node_modules/*
5 | *.log
6 |
--------------------------------------------------------------------------------
/Changelog.md:
--------------------------------------------------------------------------------
1 | # 0.18.1 - 2020-12-22
2 |
3 | * Update viewer-custom.scss #267 (fix blank space)
4 | * Fixed bug where non-JSON text/html pages were polluted #218
5 | * showArraySize should default to false if undefined. #179
6 | * Set window.json when formatting from scratch page #195
7 | * Support for clickable relative paths #197
8 | * Improve link anchor wrapping #204
9 | * Enable for offline use. #189
10 |
11 | # 0.18.0 - 2017-10-23
12 |
13 | * Make clear this plugin is open source (PR #144)
14 | * Support pages with multiple nodes (PR #150)
15 | * Add option to display the array size, disabled by default (`showArraySize` PR #122)
16 | * Support JSONP with spaces around (PR #157)
17 | * Allow force highlight for oversized JSON (PR #168)
18 | * Add option to wrap links with a link tag [ ] (PR #173)
19 | * Bugfix: preserve spaces in plain strings (PR #175)
20 | * Bugfix: Remove unnecessary limitations from package.json (issue #171)
21 | * Bugfix: fix float point numbers (issues #167 #111)
22 |
23 | # 0.17.0 - 2017-01-16
24 |
25 | * Bugfix: check if all nodes are text nodes before the normalization when facing multiple nodes (issue #136)
26 | * Add key map `shift-enter` to show the previous search result (PR #135 thanks to @benvan)
27 |
28 | # 0.16.2 - 2017-01-14
29 |
30 | * Bugfix: checkIfJson fails when chrome splits text nodes (PR #133 thanks to @benvan)
31 | * Bug fix: quotes incorrectly parsed by wrapNumbers resulting in broken json (PR #134 thanks to @benvan)
32 |
33 | # 0.16.1 - 2016-12-04
34 |
35 | * Bugfix: Empty `
` prepended to body when markup contained one text node with any whitespace character inside (issue #123)
36 |
37 | # 0.16.0 - 2016-12-01
38 |
39 | * Make the extension work if the content-type is text/html (PR #117)
40 | * Included panda-syntax theme (issue #112)
41 | * Updated CodeMirror (5.21.0)
42 | * Always show fold/unfold button (issue #107)
43 |
44 | # 0.15.0 - 2016-08-13
45 |
46 | * Bugfix: fixed issue with wrapNumbers failing when string ends with backslash (PR #94)
47 |
48 | # 0.14.1 - 2016-06-17
49 |
50 | * Improved JSON check
51 |
52 | # 0.14.0 - 2016-05-30
53 |
54 | * Included UI to notify about content not highlighted due to oversize
55 |
56 | # 0.13.1 - 2016-05-26
57 |
58 | * Bugfix: The character `$` is special, to be used inside `replace` the regular expressions must be escaped with another `$` (issue #83)
59 |
60 | # 0.13.0 - 2016-05-08
61 |
62 | * Included dracula and dracula-custom theme (issue #82)
63 | * Included mehdi theme (issue #81)
64 | * Improved selection background for some themes
65 | * Bugfix: disabled cursor when on readOnly (closes #74)
66 | * Bugfix: doesn't load CSS when content is not JSON (closes #66)
67 | * Bugfix: Custom search is changing values with the highlight marks (closes #48)
68 |
69 | # 0.12.0 - 2016-04-11
70 |
71 | * Option to disable auto highlight (issue #76)
72 |
73 | # 0.11.1 - 2016-03-16
74 |
75 | * Bugfix: JSONP matcher matching agains wrong payload
76 | * Support for payloads with `for(;;);`, `while(1);` and `while(true);`
77 |
78 | # 0.11.0 - 2016-02-27
79 |
80 | * Alert about JSON size above maxJsonSize (issue #62)
81 | * Option to disable clickable URLs (issue #63)
82 |
83 | # 0.10.3 - 2015-09-06
84 |
85 | * Bugfix: default `indentCStyle: false`, it should have been since the beginning
86 | * Bugfix: read-only mode shouldn't allows paste (issue #54)
87 |
88 | # 0.10.2 - 2015-08-10
89 |
90 | * Bugfix: array data that has a parentheses immediately adjacent to text throws an error
91 |
92 | # 0.10.1 - 2015-08-08
93 |
94 | * Bugfix: highlight of JSONP callbacks which contains numbers
95 |
96 | # 0.10.0 - 2015-08-08
97 |
98 | * Option to sort json by keys (thanks to @North101)
99 | * New theme (yeti)
100 | * Updated CodeMirror (now it preserves the last search query)
101 | * Included scratch pad, a new area which you can type/paste JSON and format indefinitely using a button or key shortcut. To access type json-viewer + TAB + scratch pad ENTER
102 | * Bugfix: Javascript NO-BREAK SPACE \u00a0 is converting to  character (chrome canary)
103 | * Customizable tab size
104 | * Option for C-style braces and arrays
105 | * Handle JSONP returns that begin with a comment (thanks to @benhollander)
106 |
107 | # 0.9.3 - 2015-07-14
108 |
109 | * Bugfix: fixed an issue where numbers with exponent were incorrectly parsed
110 | * Included description of "prependHeader" add-on
111 | * Included version number into options page
112 |
113 | # 0.9.2 - 2015-07-05
114 |
115 | * Bugfix: fixed the problem with Number.MAX_VALUE in all scenarios, used solution proposed by @alexlopashev
116 |
117 | # 0.9.1 - 2015-06-26
118 |
119 | * Bugfix: new versions of chrome (45.0.2442.0 canary (64-bit)) have changed the format of the value hold by `:before content`, using a safe approach to check the CSS load (many thanks to @Wideshanks)
120 | * Removed outline from settings page
121 |
122 | # 0.9.0 - 2015-06-25
123 |
124 | * Increased loadCSS max wait to 2s
125 | * Enabled browser search on raw content
126 | * Bugfix: fixed an issue with Number.MAX_VALUE replace fix
127 | * Bugfix: allowing private and local networks with url-pattern
128 | * Sorted themes by darkness
129 | * New theme (material)
130 | * Better default font for snippets in options page (improved for windows users)
131 | * Better default font-family
132 |
133 | # 0.8.5 - 2015-06-10
134 |
135 | * Fixed typos with "alwaysFold" and "alwaysRenderAllContent"
136 |
137 | # 0.8.4 - 2015-06-10
138 |
139 | * Fixed a bug where the decoding to allow numbers bigger than Number.MAX_VALUE breaks JSON files without numbers
140 |
141 | # 0.8.3 - 2015-06-09
142 |
143 | * Fixed numbers bigger than Number.MAX_VALUE being rounded
144 | * Included search (also by regex)
145 | * Included option to render all content and use the browser search
146 |
147 | # 0.8.2 - 2015-06-08
148 |
149 | * Improved reliability of the code which migrates the old options to the new ones
150 |
151 | # 0.8.1 - 2015-06-08
152 |
153 | * Fixed a long problem with UTF-8 Characters
154 | * Clickable URLs with a better matcher
155 |
156 | # 0.8.0 - 2015-06-08
157 |
158 | * Rewritten
159 | * New logo
160 | * Based on CodeMirror (~10x more performance)
161 | * New themes (21 built-in)
162 | * Highlighted/raw toggle button
163 | * Clickable URLs
164 | * Line numbers (optional)
165 | * Accepts custom CSS
166 | * Button to unfold everything when alwaysFold true
167 | * Options to customize text wrap, gutters, etc
168 | * Removed clickable URLs. Just while I think in a better solution
169 | * Increased Max JSON size default from 200kb to 400kb
170 | * Included reset button to options page
171 |
172 | # 0.7.2 - 2015-02-01
173 |
174 | * Allow nested JSONP's by https://github.com/bluec0re
175 |
176 | # 0.7.1 - 2014-01-27
177 |
178 | * Fixed arrow state when using option "Always fold from second level"
179 | * Better arrow closed state
180 |
181 | # 0.7.0 - 2014-01-03
182 |
183 | * Included the keyword 'json-viewer' into the Omnibox to highlight anonymous json content
184 | * Gear icon to options page is now 10% visible to helps users find it
185 |
186 | # 0.6.0 - 2013-12-08
187 |
188 | * Added an easy way to access the options page
189 |
190 | # 0.5.0 - 2013-12-01
191 |
192 | * Added arrows up/down in foldable code
193 | * Option to configure the font-size
194 | * Fixed a bug where content with tags inside was being omitted - ex: {"sldXml": "#FF0000 "}
195 |
196 | # 0.4.0 - 2013-11-05
197 |
198 | * Jellybeans theme by Thiago Pontes (https://github.com/thiagopnts)
199 | * Keep settings when switching themes by Thiago Pontes (https://github.com/thiagopnts)
200 |
201 | # 0.3.0 - 2013-09-11
202 |
203 | * Collapsible nodes
204 | * Option to activate/deactivate nodes always collapsed (from 2º level)
205 | * Option to activate/deactivate the header (timestamp + url)
206 |
207 | # 0.2.0 - 2013-09-07
208 |
209 | * Options page
210 | * Six more themes and the ability to change between them
211 | * bugfix: activate only on json/jsonp sources
212 | * Better json key parser
213 | * Max JSON size option (default: 200 kb)
214 | * Uses event page to process the highlight
215 |
216 | # 0.1.0 - 2013-09-06
217 |
218 | * First release with one theme
219 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2017 Túlio Ornelas (ornelas.tulio@gmail.com)
4 |
5 | Permission is hereby granted, free of charge,
6 | to any person obtaining a copy of this software and
7 | associated documentation files (the "Software"), to
8 | deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify,
10 | merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom
12 | the Software is furnished to do so,
13 | subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice
16 | shall be included in all copies or substantial portions of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
22 | ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # JSON Viewer
4 |
5 | 
6 |
7 | The most beautiful and customizable JSON/JSONP highlighter that your eyes have ever seen. It is a Chrome extension for printing JSON and JSONP.
8 |
9 | Notes:
10 |
11 | * This extension might crash with other JSON highlighters/formatters, you may need to disable them
12 | * To highlight local files and incognito tabs you have to manually enable these options on the extensions page
13 | * Sometimes when the plugin updates chrome leaves the old background process running and revokes some options, like the access to local files. When this happen just recheck the option that everything will work again
14 | * Works on local files (if you enable this in chrome://extensions)
15 |
16 | Features:
17 |
18 | * Syntax highlighting
19 | * 27 built-in themes
20 | * Collapsible nodes
21 | * Clickable URLs (optional)
22 | * URL does not matter (the content is analysed to determine if its a JSON or not)
23 | * Inspect your json typing "json" in the console
24 | * Hot word `json-viewer` into omnibox (type `json-viewer` + TAB and paste your JSON into omnibox, hit ENTER and it will be highlighted)
25 | * Toggle button to view the raw/highlighted version
26 | * Works with numbers bigger than Number.MAX_VALUE
27 | * Option to show line numbers
28 | * Option to customize your theme
29 | * Option to customize the tab size
30 | * Option to configure a max JSON size to highlight
31 | * Option to collapse nodes from second level + Button to unfold all collapsed nodes
32 | * Option to include a header with timestamp + url
33 | * Option to allow the edition of the loaded JSON
34 | * Option to sort json by keys
35 | * Option to disable auto highlight
36 | * Option for C-style braces and arrays
37 | * Scratch pad, a new area which you can type/paste JSON and format indefinitely using a button or key shortcut. To access type `json-viewer` + `TAB` + `scratch pad` ENTER
38 |
39 | ## Installation
40 |
41 | ### Install through Chrome Web Store
42 |
43 | [](https://chrome.google.com/webstore/detail/json-viewer/gbmdgpbipfallnflgajpaliibnhdgobh)
44 |
45 | ### Or compile and load by yourself
46 |
47 | 1. It depends on node (version in `package.json` engines).
48 | 2. `npm install --global yarn`
49 | 2. `yarn install`
50 | 3. `yarn run build`
51 | 4. Open Chrome and go to: chrome://extensions/
52 | 5. Enable: "Developer mode"
53 | 6. Click: "Load unpacked extension"
54 | 7. Select: "build/json_viewer" directory.
55 |
56 | ## Try it on
57 |
58 | ### JSON
59 |
60 | [https://api.github.com/repos/tulios/json-viewer](https://api.github.com/repos/tulios/json-viewer)
61 |
62 | [http://graph.facebook.com/github](http://graph.facebook.com/github)
63 |
64 | [https//api.github.com](https://api.github.com)
65 |
66 | [https://api.github.com/gists/public](https://api.github.com/gists/public)
67 |
68 | Large files:
69 |
70 | [https://raw.githubusercontent.com/ebrelsford/geojson-examples/master/596acres-02-18-2014.geojson](https://raw.githubusercontent.com/ebrelsford/geojson-examples/master/596acres-02-18-2014.geojson)
71 |
72 | [https://api.takealot.com/rest/v-1-4-2/productlines?available=1&cat=10371&instock=1&rows=10&sort=score%20desc&start=0](https://api.takealot.com/rest/v-1-4-2/productlines?available=1&cat=10371&instock=1&rows=10&sort=score%20desc&start=0)
73 |
74 | ### JSONP
75 |
76 | [http://freemusicarchive.org/api/get/curators.jsonp?api_key=60BLHNQCAOUFPIBZ&callback=test](http://freemusicarchive.org/api/get/curators.jsonp?api_key=60BLHNQCAOUFPIBZ&callback=test)
77 |
78 | ## License
79 |
80 | See [LICENSE](https://github.com/tulios/json-viewer/blob/master/LICENSE) for more details.
81 |
--------------------------------------------------------------------------------
/description.txt:
--------------------------------------------------------------------------------
1 | It is a Chrome extension for printing JSON and JSONP.
2 |
3 | Notes:
4 | * This extension might crash with other JSON highlighters/formatters, you may need to disable them
5 | * To highlight local files and incognito tabs you have to manually enable these options on the extensions page
6 | * Sometimes when the plugin updates chrome leaves the old background process running and revokes some options, like the access to local files. When this happen just recheck the option that everything will work again
7 | * Works on local files (if you enable this in chrome://extensions)
8 |
9 | Features
10 | * Syntax highlighting
11 | * 26 built-in themes
12 | * Collapsible nodes
13 | * Clickable URLs (optional)
14 | * URL does not matter (the content is analysed to determine if its a JSON or not)
15 | * Inspect your json typing "json" in the console
16 | * Hot word `json-viewer` into omnibox (type `json-viewer` + TAB and paste your JSON into omnibox, hit ENTER and it will be highlighted)
17 | * Toggle button to view the raw/highlighted version
18 | * Works with numbers bigger than Number.MAX_VALUE
19 | * Option to show line numbers
20 | * Option to customize your theme
21 | * Option to customize the tab size
22 | * Option to configure a max JSON size to highlight
23 | * Option to collapse nodes from second level + Button to unfold all collapsed nodes
24 | * Option to include a header with timestamp + url
25 | * Option to allow the edition of the loaded JSON
26 | * Option to sort json by keys
27 | * Option for C-style braces and arrays
28 | * Scratch pad, a new area which you can type/paste JSON and format indefinitely using a button or key shortcut. To access type `json-viewer` + `TAB` + `scratch pad` ENTER
29 |
30 | This plugin is open source
31 | https://github.com/tulios
32 |
33 | Bugs and suggestions
34 | https://github.com/tulios/json-viewer/issues
35 |
36 | Contributors
37 | Thiago Pontes (@thiagopnts)
38 | @bluec0re
39 | @North101
40 | Ben Hollander (@benhollander)
41 | Mehdi Bahrami (@mehdibahraami)
42 | Reimund Trost (@reimund)
43 | Ben van Enckevort (@benvan)
44 |
45 | License
46 | MIT License
47 |
48 | Any questions tweet me @tulios
49 |
--------------------------------------------------------------------------------
/extension/icons/128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tulios/json-viewer/4195c33f4d06e622befaf1102004e2c478d4b9d8/extension/icons/128.png
--------------------------------------------------------------------------------
/extension/icons/16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tulios/json-viewer/4195c33f4d06e622befaf1102004e2c478d4b9d8/extension/icons/16.png
--------------------------------------------------------------------------------
/extension/icons/32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tulios/json-viewer/4195c33f4d06e622befaf1102004e2c478d4b9d8/extension/icons/32.png
--------------------------------------------------------------------------------
/extension/icons/gear.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/extension/icons/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tulios/json-viewer/4195c33f4d06e622befaf1102004e2c478d4b9d8/extension/icons/logo.png
--------------------------------------------------------------------------------
/extension/icons/raw.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/extension/icons/unfold.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/extension/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "JSON Viewer",
3 | "version": "0.18.1",
4 | "manifest_version": 2,
5 | "author": "Tulio Ornelas ",
6 | "description": "The most beautiful and customizable JSON/JSONP highlighter that your eyes have ever seen. Open source at https://goo.gl/fmphc7",
7 | "homepage_url": "https://github.com/tulios/json-viewer",
8 | "minimum_chrome_version": "21",
9 | "icons": {
10 | "128": "icons/128.png",
11 | "32": "icons/32.png",
12 | "16": "icons/16.png"
13 | },
14 | "web_accessible_resources": [
15 | "assets/viewer.css",
16 | "assets/viewer-alert.css",
17 | "pages/options.html",
18 | "pages/omnibox.html"
19 | ],
20 | "offline_enabled": true,
21 | "omnibox": { "keyword" : "json-viewer" },
22 | "options_page": "pages/options.html",
23 | "content_scripts": [
24 | {
25 | "matches": [""],
26 | "js": ["assets/viewer.js"],
27 | "run_at": "document_start"
28 | }
29 | ],
30 | "background": {
31 | "scripts": ["assets/backend.js", "assets/omnibox.js"],
32 | "persistent": false
33 | },
34 | "permissions": [
35 | "*://*/*",
36 | ""
37 | ]
38 | }
39 |
--------------------------------------------------------------------------------
/extension/pages/omnibox.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/extension/pages/options.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Options - JSON Viewer
8 |
9 |
10 |
11 |
12 |
13 |
14 | Options page
15 |
16 |
17 |
105 |
106 |
107 |
108 |
109 |
--------------------------------------------------------------------------------
/extension/src/backend.js:
--------------------------------------------------------------------------------
1 | var chrome = require('chrome-framework');
2 | var Storage = require('./json-viewer/storage');
3 |
4 | chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
5 | try {
6 | if (request.action === "GET_OPTIONS") {
7 | sendResponse({err: null, value: Storage.load()});
8 | }
9 | } catch(e) {
10 | console.error('[JSONViewer] error: ' + e.message, e);
11 | sendResponse({err: e});
12 | }
13 | });
14 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/check-if-json.js:
--------------------------------------------------------------------------------
1 | var extractJSON = require('./extract-json');
2 | var bodyModified = false;
3 |
4 | function allTextNodes(nodes) {
5 | return !Object.keys(nodes).some(function(key) {
6 | return nodes[key].nodeName !== '#text'
7 | })
8 | }
9 |
10 | function getPreWithSource() {
11 | var childNodes = document.body.childNodes;
12 |
13 | if (childNodes.length === 0) {
14 | return null
15 | }
16 |
17 | if (childNodes.length > 1 && allTextNodes(childNodes)) {
18 | if (process.env.NODE_ENV === 'development') {
19 | console.debug("[JSONViewer] Loaded from a multiple text nodes, normalizing");
20 | }
21 |
22 | document.body.normalize() // concatenates adjacent text nodes
23 | }
24 |
25 | var childNode = childNodes[0];
26 | var nodeName = childNode.nodeName
27 | var textContent = childNode.textContent
28 |
29 | if (nodeName === "PRE") {
30 | return childNode;
31 | }
32 |
33 | // if Content-Type is text/html
34 | if (nodeName === "#text" && textContent.trim().length > 0) {
35 | if (process.env.NODE_ENV === 'development') {
36 | console.debug("[JSONViewer] Loaded from a text node, this might have returned content-type: text/html");
37 | }
38 |
39 | var pre = document.createElement("pre");
40 | pre.textContent = textContent;
41 | document.body.removeChild(childNode);
42 | document.body.appendChild(pre);
43 | bodyModified = true;
44 | return pre;
45 | }
46 |
47 | return null
48 | }
49 |
50 | function restoreNonJSONBody() {
51 | var artificialPre = document.body.lastChild;
52 | var removedChildNode = document.createElement("text");
53 | removedChildNode.textContent = artificialPre.textContent;
54 | document.body.insertBefore(removedChildNode, document.body.firstChild);
55 | document.body.removeChild(artificialPre);
56 | }
57 |
58 | function isJSON(jsonStr) {
59 | var str = jsonStr;
60 | if (!str || str.length === 0) {
61 | return false
62 | }
63 |
64 | str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
65 | str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
66 | str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '')
67 | return (/^[\],:{}\s]*$/).test(str)
68 | }
69 |
70 | function isJSONP(jsonStr) {
71 | return isJSON(extractJSON(jsonStr));
72 | }
73 |
74 | function checkIfJson(sucessCallback, element) {
75 | var pre = element || getPreWithSource();
76 |
77 | if (pre !== null &&
78 | pre !== undefined &&
79 | (isJSON(pre.textContent) || isJSONP(pre.textContent))) {
80 |
81 | sucessCallback(pre);
82 | } else if (bodyModified) {
83 | restoreNonJSONBody();
84 | }
85 | }
86 |
87 | module.exports = {
88 | checkIfJson: checkIfJson,
89 | isJSON: isJSON
90 | };
91 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/content-extractor.js:
--------------------------------------------------------------------------------
1 | var Promise = require('promise');
2 | var jsonFormater = require('./jsl-format');
3 | var extractJSON = require('./extract-json');
4 |
5 | var TOKEN = (Math.random() + 1).toString(36).slice(2, 7);
6 | var WRAP_START = "";
7 | var WRAP_END = " ";
8 | var NUM_REGEX = /^-?\d+\.?\d*([eE]\+)?\d*$/g;
9 | var ESCAPED_REGEX = "(-?\\d+\\.?\\d*([eE]\\+)?\\d*)"
10 |
11 | var WRAP_REGEX = new RegExp(
12 | "^" + WRAP_START + ESCAPED_REGEX + WRAP_END + "$", "g"
13 | );
14 |
15 | var REPLACE_WRAP_REGEX = new RegExp(
16 | "\"" + WRAP_START + ESCAPED_REGEX + WRAP_END + "\"", "g"
17 | );
18 |
19 | function contentExtractor(pre, options) {
20 | return new Promise(function(resolve, reject) {
21 | try {
22 | var rawJsonText = pre.textContent;
23 | var jsonExtracted = extractJSON(rawJsonText);
24 | var wrappedText = wrapNumbers(jsonExtracted);
25 |
26 | var jsonParsed = JSON.parse(wrappedText);
27 | if (options.addons.sortKeys) jsonParsed = sortByKeys(jsonParsed);
28 |
29 | // Validate and decode json
30 | var decodedJson = JSON.stringify(jsonParsed);
31 | decodedJson = decodedJson.replace(REPLACE_WRAP_REGEX, "$1");
32 |
33 | var jsonFormatted = normalize(jsonFormater(decodedJson, options.structure));
34 | var jsonText = normalize(rawJsonText).replace(normalize(jsonExtracted), jsonFormatted);
35 | resolve({jsonText: jsonText, jsonExtracted: decodedJson});
36 |
37 | } catch(e) {
38 | reject(new Error('contentExtractor: ' + e.message));
39 | }
40 | });
41 | }
42 |
43 | function normalize(json) {
44 | return json.replace(/\$/g, '$$$$');
45 | }
46 |
47 | function sortByKeys(obj) {
48 | if (typeof obj !== 'object' || !obj) return obj;
49 |
50 | var sorted;
51 | if (Array.isArray(obj)) {
52 | sorted = [];
53 | obj.forEach(function(val, idx) {
54 | sorted[idx] = sortByKeys(val);
55 | });
56 |
57 | } else {
58 | sorted = {};
59 | Object.keys(obj).sort().forEach(function(key) {
60 | sorted[key] = sortByKeys(obj[key]);
61 | });
62 | }
63 |
64 | return sorted;
65 | };
66 |
67 | // Pass all numbers to json parser as strings in order to maintain precision,
68 | // unwrap them later without quotes.
69 | //
70 | // Solution with some changes from https://github.com/alexlopashev
71 | function wrapNumbers(text) {
72 | var buffer = "";
73 | var numberBuffer = "";
74 | var isInString = false;
75 | var charIsEscaped = false;
76 | var isInNumber = false;
77 | var previous = "";
78 | var beforePrevious = "";
79 |
80 | for (var i = 0, len = text.length; i < len; i++) {
81 | var char = text[i];
82 |
83 | if (char == '"' && !charIsEscaped) {
84 | isInString = !isInString;
85 | }
86 |
87 | if (!isInString && !isInNumber && isCharInNumber(char, previous)) {
88 | isInNumber = true;
89 | }
90 |
91 | if (!isInString && isInNumber && isCharInString(char, previous)) {
92 | isInNumber = false;
93 |
94 | if (numberBuffer.match(NUM_REGEX)) {
95 | buffer += '"' + WRAP_START + numberBuffer + WRAP_END + '"';
96 |
97 | } else {
98 | buffer += numberBuffer;
99 | }
100 |
101 | numberBuffer = "";
102 | }
103 |
104 | // this applies to the _next_ character - the one used in the next iteration
105 | charIsEscaped = (char == '\\') ? !charIsEscaped : false
106 |
107 | if (isInNumber) {
108 | numberBuffer += char;
109 |
110 | } else {
111 | buffer += char;
112 | beforePrevious = previous;
113 | previous = char;
114 | }
115 | }
116 |
117 | return buffer;
118 | }
119 |
120 | function isCharInNumber(char, previous) {
121 | return ('0' <= char && char <= '9') ||
122 | ('0' <= previous && previous <= '9' && (char == 'e' || char == 'E')) ||
123 | (('e' == previous || 'E' == previous) && char == '+') ||
124 | char == '.' ||
125 | char == '-';
126 | }
127 |
128 | function isCharInString(char, previous) {
129 | return ('0' > char || char > '9') &&
130 | char != 'e' &&
131 | char != 'E' &&
132 | char != '+' &&
133 | char != '.' &&
134 | char != '-';
135 | }
136 |
137 | module.exports = contentExtractor;
138 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/extract-json.js:
--------------------------------------------------------------------------------
1 | function extractJSON(rawJson) {
2 | return rawJson
3 | .replace(/\s*while\((1|true)\)\s*;?/, '')
4 | .replace(/\s*for\(;;\)\s*;?/, '')
5 | .replace(/^[^{\[].+\(\s*?{/, '{')
6 | .replace(/}\s*?\);?\s*$/, '}');
7 | }
8 |
9 | module.exports = extractJSON;
10 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/highlight-content.js:
--------------------------------------------------------------------------------
1 | var contentExtractor = require('./content-extractor');
2 | var Highlighter = require('./highlighter');
3 | var timestamp = require('./timestamp');
4 | var exposeJson = require('./viewer/expose-json');
5 | var renderExtras = require('./viewer/render-extras');
6 | var renderAlert = require('./viewer/render-alert');
7 | var getOptions = require('./viewer/get-options');
8 | var loadRequiredCss = require('./viewer/load-required-css');
9 |
10 | function oversizedJSON(pre, options, outsideViewer) {
11 | var jsonSize = pre.textContent.length;
12 | var accepted = options.addons.maxJsonSize;
13 |
14 | var loaded = jsonSize / 1024;
15 | var maxJsonSize = accepted * 1024;
16 | var isOversizedJSON = jsonSize > maxJsonSize;
17 |
18 | if (process.env.NODE_ENV === 'development') {
19 | console.debug("[JSONViewer] JSON size: " + loaded + " kbytes");
20 | console.debug("[JSONViewer] Max JSON size: " + accepted + " kbytes");
21 | console.debug("[JSONViewer] " + jsonSize + " > " + maxJsonSize + " = " + isOversizedJSON);
22 | }
23 |
24 | if (isOversizedJSON) {
25 | console.warn(
26 | "[JSONViewer] Content not highlighted due to oversize. " +
27 | "Accepted: " + accepted + " kbytes, received: " + loaded + " kbytes. " +
28 | "It's possible to change this value at options -> Add-ons -> maxJsonSize"
29 | );
30 |
31 | var container = document.createElement("div");
32 |
33 | var message = document.createElement("div");
34 | message.innerHTML = "[JSONViewer] Content not highlighted due to oversize. " +
35 | "Take a look at the console log for more information.";
36 | container.appendChild(message);
37 |
38 | var highlightAnyway = document.createElement("a");
39 | highlightAnyway.href = "#";
40 | highlightAnyway.title = "Highlight anyway!";
41 | highlightAnyway.innerHTML = "Highlight anyway!";
42 | highlightAnyway.onclick = function(e) {
43 | e.preventDefault();
44 | pre.hidden = true;
45 | highlightContent(pre, outsideViewer, true);
46 | }
47 | container.appendChild(highlightAnyway);
48 |
49 | renderAlert(pre, options, container);
50 | }
51 |
52 | return isOversizedJSON;
53 | }
54 |
55 | function prependHeader(options, outsideViewer, jsonText) {
56 | if (!outsideViewer && options.addons.prependHeader) {
57 | options.structure.firstLineNumber = options.structure.firstLineNumber - 3
58 | var header = "// " + timestamp() + "\n";
59 | header += "// " + document.location.href + "\n\n";
60 | jsonText = header + jsonText;
61 | }
62 |
63 | return jsonText;
64 | }
65 |
66 | function highlightContent(pre, outsideViewer, ignoreLimit) {
67 | getOptions().then(function(options) {
68 | if (!ignoreLimit && oversizedJSON(pre, options, outsideViewer)) {
69 | return pre.hidden = false;
70 | }
71 |
72 | return contentExtractor(pre, options).
73 | then(function(value) {
74 | return loadRequiredCss(options).then(function() { return value; });
75 | }).
76 | then(function(value) {
77 |
78 | var formatted = prependHeader(options, outsideViewer, value.jsonText);
79 | var highlighter = new Highlighter(formatted, options);
80 |
81 | if (options.addons.autoHighlight) {
82 | highlighter.highlight();
83 |
84 | } else {
85 | highlighter.highlight();
86 | highlighter.hide();
87 | pre.hidden = false;
88 |
89 | console.warn(
90 | "[JSONViewer] You are seeing the raw version because you configured the " +
91 | "addon 'autoHighlight' to false. It's possible to highlight from this page, " +
92 | "just click at the 'RAW' button in the top-right corner. " +
93 | "It's possible to change this value at options -> Add-ons -> autoHighlight"
94 | )
95 | }
96 |
97 | // "awaysFold" was a typo but to avoid any problems I'll keep it
98 | // a while
99 | if (options.addons.alwaysFold || options.addons.awaysFold) {
100 | highlighter.fold();
101 | }
102 |
103 | exposeJson(value.jsonExtracted, outsideViewer);
104 | renderExtras(pre, options, highlighter);
105 |
106 | });
107 |
108 | }).catch(function(e) {
109 | pre.hidden = false;
110 | if (process.env.NODE_ENV === 'development') {
111 | console.error('[JSONViewer] error: ' + e.message, e);
112 | }
113 | });
114 | }
115 |
116 | module.exports = highlightContent;
117 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/highlighter.js:
--------------------------------------------------------------------------------
1 | var CodeMirror = require('codemirror');
2 | require('codemirror/addon/fold/foldcode');
3 | require('codemirror/addon/fold/foldgutter');
4 | require('codemirror/addon/fold/brace-fold');
5 | require('codemirror/addon/dialog/dialog');
6 | require('codemirror/addon/scroll/annotatescrollbar');
7 | require('codemirror/addon/search/matchesonscrollbar');
8 | require('codemirror/addon/search/searchcursor');
9 | require('codemirror/addon/search/search');
10 | require('codemirror/mode/javascript/javascript');
11 | var merge = require('./merge');
12 | var defaults = require('./options/defaults');
13 | var URL_PATTERN = require('./url-pattern');
14 | var F_LETTER = 70;
15 |
16 | function Highlighter(jsonText, options) {
17 | this.options = options || {};
18 | this.text = jsonText;
19 | this.defaultSearch = false;
20 | this.theme = this.options.theme || "default";
21 | this.theme = this.theme.replace(/_/, ' ');
22 | }
23 |
24 | Highlighter.prototype = {
25 | highlight: function() {
26 | this.editor = CodeMirror(document.body, this.getEditorOptions());
27 | if (!this.alwaysRenderAllContent()) this.preventDefaultSearch();
28 | if (this.isReadOny()) this.getDOMEditor().className += ' read-only';
29 |
30 | this.bindRenderLine();
31 | this.bindMousedown();
32 | this.editor.refresh();
33 | this.editor.focus();
34 | },
35 |
36 | hide: function() {
37 | this.getDOMEditor().hidden = true;
38 | this.defaultSearch = true;
39 | },
40 |
41 | show: function() {
42 | this.getDOMEditor().hidden = false;
43 | this.defaultSearch = false;
44 | },
45 |
46 | getDOMEditor: function() {
47 | return document.getElementsByClassName('CodeMirror')[0];
48 | },
49 |
50 | fold: function() {
51 | var skippedRoot = false;
52 | var firstLine = this.editor.firstLine();
53 | var lastLine = this.editor.lastLine();
54 |
55 | for (var line = firstLine; line <= lastLine; line++) {
56 | if (!skippedRoot) {
57 | if (/(\[|\{)/.test(this.editor.getLine(line).trim())) skippedRoot = true;
58 |
59 | } else {
60 | this.editor.foldCode({line: line, ch: 0}, null, "fold");
61 | }
62 | }
63 | },
64 |
65 | unfoldAll: function() {
66 | for (var line = 0; line < this.editor.lineCount(); line++) {
67 | this.editor.foldCode({line: line, ch: 0}, null, "unfold");
68 | }
69 | },
70 |
71 | bindRenderLine: function() {
72 | var self = this;
73 | this.editor.off("renderLine");
74 | this.editor.on("renderLine", function(cm, line, element) {
75 | var elementsNode = element.getElementsByClassName("cm-string");
76 | if (!elementsNode || elementsNode.length === 0) return;
77 |
78 | var elements = [];
79 | for (var i = 0; i < elementsNode.length; i++) {
80 | elements.push(elementsNode[i]);
81 | }
82 |
83 | var textContent = elements.reduce(function(str, node) {
84 | return str += node.textContent;
85 | }, "");
86 |
87 | var text = self.removeQuotes(textContent);
88 |
89 | if (text.match(URL_PATTERN) && self.clickableUrls()) {
90 | var decodedText = self.decodeText(text);
91 | elements.forEach(function(node) {
92 | if (self.wrapLinkWithAnchorTag()) {
93 | var linkTag = document.createElement("a");
94 | linkTag.href = decodedText;
95 | linkTag.setAttribute('target', '_blank')
96 | linkTag.classList.add("cm-string");
97 |
98 | // reparent the child nodes to preserve the cursor when editing
99 | node.childNodes.forEach(function(child) {
100 | linkTag.appendChild(child);
101 | });
102 |
103 | // block CodeMirror's contextmenu handler
104 | linkTag.addEventListener("contextmenu", function(e) {
105 | if (e.bubbles) e.cancelBubble = true;
106 | });
107 |
108 | node.appendChild(linkTag);
109 | } else {
110 | node.classList.add("cm-string-link");
111 | node.setAttribute("data-url", decodedText);
112 | }
113 | });
114 | }
115 | });
116 | },
117 |
118 | bindMousedown: function() {
119 | var self = this;
120 | this.editor.off("mousedown");
121 | this.editor.on("mousedown", function(cm, event) {
122 | var element = event.target;
123 | if (element.classList.contains("cm-string-link")) {
124 | var url = element.getAttribute("data-url")
125 | var target = "_self";
126 | if (self.openLinksInNewWindow()) {
127 | target = "_blank";
128 | }
129 | window.open(url, target);
130 | }
131 | });
132 | },
133 |
134 | removeQuotes: function(text) {
135 | return text.replace(/^\"+/, '').replace(/\"+$/, '');
136 | },
137 |
138 | includeQuotes: function(text) {
139 | return "\"" + text + "\"";
140 | },
141 |
142 | decodeText: function(text) {
143 | var div = document.createElement("div");
144 | div.innerHTML = text;
145 | return div.firstChild ? div.firstChild.nodeValue : "";
146 | },
147 |
148 | getEditorOptions: function() {
149 | var obligatory = {
150 | value: this.text,
151 | theme: this.theme,
152 | readOnly: this.isReadOny() ? true : false,
153 | mode: "application/ld+json",
154 | indentUnit: 2,
155 | tabSize: 2,
156 | gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
157 | extraKeys: this.getExtraKeysMap()
158 | }
159 |
160 | if (this.alwaysRenderAllContent()) {
161 | obligatory.viewportMargin = Infinity;
162 | }
163 |
164 | var optional = defaults.structure;
165 | var configured = this.options.structure;
166 |
167 | return merge({}, optional, configured, obligatory);
168 | },
169 |
170 | getExtraKeysMap: function() {
171 | var extraKeyMap = {
172 | "Esc": function(cm) {
173 | CodeMirror.commands.clearSearch(cm);
174 | cm.setSelection(cm.getCursor());
175 | cm.focus();
176 | }
177 | }
178 |
179 | if (this.options.structure.readOnly) {
180 | extraKeyMap["Enter"] = function(cm) {
181 | CodeMirror.commands.findNext(cm);
182 | }
183 |
184 | extraKeyMap["Shift-Enter"] = function(cm) {
185 | CodeMirror.commands.findPrev(cm);
186 | }
187 |
188 | extraKeyMap["Ctrl-V"] = extraKeyMap["Cmd-V"] = function(cm) {};
189 | }
190 |
191 | var nativeSearch = this.alwaysRenderAllContent();
192 | extraKeyMap["Ctrl-F"] = nativeSearch ? false : this.openSearchDialog;
193 | extraKeyMap["Cmd-F"] = nativeSearch ? false : this.openSearchDialog;
194 | return extraKeyMap;
195 | },
196 |
197 | preventDefaultSearch: function() {
198 | document.addEventListener("keydown", function(e) {
199 | var metaKey = navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey;
200 | if (!this.defaultSearch && e.keyCode === F_LETTER && metaKey) {
201 | e.preventDefault();
202 | }
203 | }.bind(this), false);
204 | },
205 |
206 | openSearchDialog: function(cm) {
207 | cm.setCursor({line: 0, ch: 0});
208 | CodeMirror.commands.find(cm);
209 | },
210 |
211 | alwaysRenderAllContent: function() {
212 | // "awaysRenderAllContent" was a typo but to avoid any problems
213 | // I'll keep it a while
214 | return this.options.addons.alwaysRenderAllContent ||
215 | this.options.addons.awaysRenderAllContent;
216 | },
217 |
218 | clickableUrls: function() {
219 | return this.options.addons.clickableUrls;
220 | },
221 |
222 | wrapLinkWithAnchorTag: function() {
223 | return this.options.addons.wrapLinkWithAnchorTag;
224 | },
225 |
226 | openLinksInNewWindow: function() {
227 | return this.options.addons.openLinksInNewWindow;
228 | },
229 |
230 | isReadOny: function() {
231 | return this.options.structure.readOnly;
232 | }
233 | }
234 |
235 | module.exports = Highlighter;
236 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/jsl-format.js:
--------------------------------------------------------------------------------
1 | /*jslint white: true, devel: true, onevar: true, browser: true, undef: true, nomen: true, regexp: true, plusplus: false, bitwise: true, newcap: true, maxerr: 50, indent: 4 */
2 | var jsl = typeof jsl === 'undefined' ? {} : jsl;
3 |
4 | /**
5 | * jsl.format - Provide json reformatting in a character-by-character approach, so that even invalid JSON may be reformatted (to the best of its ability).
6 | *
7 | **/
8 | jsl.format = (function () {
9 |
10 | function repeat(s, count) {
11 | return new Array(count + 1).join(s);
12 | }
13 | function getSizeOfArray(jsonString,startingPosition){
14 | var currentPosition = startingPosition + 1;
15 | var inString = false;
16 | var numOpened = 1;
17 | try{
18 | while (numOpened > 0 && currentPosition < jsonString.length) {
19 | var currentChar = jsonString.charAt(currentPosition)
20 | switch (currentChar) {
21 | case '[':
22 | if(!inString){
23 | numOpened++;
24 | }
25 | break;
26 | case ']':
27 | if(!inString){
28 | numOpened--;
29 | }
30 | break;
31 | case '"':
32 | inString = !inString;
33 | break;
34 | }
35 | currentPosition++;
36 | }
37 | return JSON.parse(jsonString.substring(startingPosition,currentPosition)).length;
38 | }
39 | catch(err){
40 | return null;
41 | }
42 | }
43 | function formatJson(json, options) {
44 | options = options || {};
45 | var tabSize = options.tabSize || 2;
46 | var indentCStyle = options.indentCStyle || false;
47 | var showArraySize = (typeof options.showArraySize !== "undefined" ? Boolean(options.showArraySize) : false);
48 | var tab = "";
49 | for (var ts = 0; ts < tabSize; ts++) {
50 | tab += " ";
51 | }
52 |
53 | var i = 0,
54 | il = 0,
55 | newJson = "",
56 | indentLevel = 0,
57 | inString = false,
58 | currentChar = null;
59 | for (i = 0, il = json.length; i < il; i += 1) {
60 | currentChar = json.charAt(i);
61 |
62 | switch (currentChar) {
63 | case '{':
64 | case '[':
65 | if (!inString) {
66 | if (indentCStyle) newJson += "\n" + repeat(tab, indentLevel);
67 | if(currentChar === "["){
68 | if(showArraySize){
69 | var arraySize = getSizeOfArray(json,i);
70 | if(arraySize !== null){
71 | newJson += "Array[" + arraySize + "]";
72 | }
73 | }
74 | }
75 | newJson += currentChar;
76 |
77 | newJson += "\n" + repeat(tab, indentLevel + 1);
78 | indentLevel += 1;
79 | } else {
80 | newJson += currentChar;
81 | }
82 | break;
83 | case '}':
84 | case ']':
85 | if (!inString) {
86 | indentLevel -= 1;
87 | newJson += "\n" + repeat(tab, indentLevel) + currentChar;
88 | } else {
89 | newJson += currentChar;
90 | }
91 | break;
92 | case ',':
93 | if (!inString) {
94 | newJson += ",\n" + repeat(tab, indentLevel);
95 | } else {
96 | newJson += currentChar;
97 | }
98 | break;
99 | case ':':
100 | if (!inString) {
101 | newJson += ": ";
102 | } else {
103 | newJson += currentChar;
104 | }
105 | break;
106 | case ' ':
107 | case "\n":
108 | case "\t":
109 | if (inString) {
110 | newJson += currentChar;
111 | }
112 | break;
113 | case '"':
114 | if (i === 0) {
115 | inString = true;
116 | }
117 | else if (json.charAt(i - 1) !== '\\' || (json.charAt(i - 1) == '\\' && json.charAt(i - 2) == '\\')) {
118 | inString = !inString;
119 | }
120 | newJson += currentChar;
121 | break;
122 | default:
123 | newJson += currentChar;
124 | break;
125 | }
126 | }
127 |
128 | return newJson;
129 | }
130 |
131 | return { "formatJson": formatJson };
132 |
133 | }());
134 |
135 | module.exports = jsl.format.formatJson;
136 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/load-css.js:
--------------------------------------------------------------------------------
1 | var Promise = require('promise');
2 | var chrome = require("chrome-framework");
3 | var MAX_WAIT = 20;
4 |
5 | function loadCSS(opts) {
6 | var url = chrome.extension.getURL(opts.path);
7 |
8 | var link = document.createElement("link");
9 | var sheets = document.styleSheets;
10 | link.rel = "stylesheet";
11 | link.href = url;
12 | if (opts.id) link.id = opts.id;
13 |
14 | document.head.appendChild(link);
15 |
16 | var checkElement = document.createElement("div");
17 | checkElement.setAttribute("class", opts.checkClass);
18 | document.body.appendChild(checkElement);
19 |
20 | var scheduleId = null;
21 | var attempts = 0;
22 |
23 | return new Promise(function(resolve, reject) {
24 | function scheduleCheck() {
25 | var content = window.
26 | getComputedStyle(checkElement, ":before").
27 | getPropertyValue("content");
28 |
29 | if (attempts > MAX_WAIT) {
30 | return reject(
31 | Error("fail to load css: '" + url + "', content loaded: " + content)
32 | );
33 | }
34 |
35 | if (/loaded/.test(content)) {
36 | cancelAnimationFrame(scheduleId);
37 | document.body.removeChild(checkElement);
38 | resolve();
39 |
40 | } else {
41 | attempts++;
42 | scheduleId = requestAnimationFrame(scheduleCheck, 1);
43 | }
44 | }
45 |
46 | scheduleCheck();
47 | });
48 | }
49 |
50 | module.exports = loadCSS;
51 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/merge.js:
--------------------------------------------------------------------------------
1 | function merge() {
2 | var obj = {}, i = 0, il = arguments.length, key;
3 | if (il === 0) {
4 | return obj;
5 | }
6 |
7 | for (; i < il; i++) {
8 | for (key in arguments[i]) {
9 | if (arguments[i].hasOwnProperty(key)) {
10 | obj[key] = arguments[i][key];
11 | }
12 | }
13 | }
14 | return obj;
15 | }
16 |
17 | module.exports = merge;
18 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/options/bind-reset-button.js:
--------------------------------------------------------------------------------
1 | var sweetAlert = require('sweetalert');
2 | var defaults = require('./defaults');
3 | var Storage = require('../storage');
4 |
5 | function bindResetButton() {
6 | var button = document.getElementById("reset");
7 | button.onclick = function(e) {
8 | e.preventDefault();
9 |
10 | sweetAlert({
11 | title: "Are you sure?",
12 | text: "You will not be able to recover your custom settings",
13 | type: "warning",
14 | showCancelButton: true,
15 | confirmButtonColor: "#DD6B55",
16 | confirmButtonText: "Yes, reset!",
17 | closeOnConfirm: false
18 | }, function() {
19 |
20 | var options = {};
21 | options.theme = defaults.theme;
22 | options.addons = JSON.stringify(defaults.addons);
23 | options.structure = JSON.stringify(defaults.structure);
24 | options.style = defaults.style;
25 |
26 | Storage.save(options);
27 | document.location.reload();
28 |
29 | });
30 | }
31 | }
32 |
33 | module.exports = bindResetButton;
34 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/options/bind-save-button.js:
--------------------------------------------------------------------------------
1 | function bindSaveButton(editors, onSaveClicked) {
2 | var form = document.getElementById("options");
3 | form.onsubmit = function() { return false; }
4 |
5 | var saveButton = document.getElementById("save");
6 | saveButton.onclick = function(e) {
7 | e.preventDefault();
8 |
9 | var output = {};
10 | editors.forEach(function(editor) {
11 | editor.save();
12 | });
13 |
14 | for (var i = 0; i < form.elements.length; i++) {
15 | var e = form.elements[i];
16 | if (!/-example$/.test(e.name) && e.name.length !== 0) {
17 | output[e.name] = e.value;
18 | }
19 | }
20 |
21 | onSaveClicked(output);
22 |
23 | }
24 | }
25 |
26 | module.exports = bindSaveButton;
27 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/options/defaults.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | theme: "default",
3 | addons: {
4 | prependHeader: true,
5 | maxJsonSize: 400,
6 | alwaysFold: false,
7 | alwaysRenderAllContent: false,
8 | sortKeys: false,
9 | clickableUrls: true,
10 | wrapLinkWithAnchorTag: false,
11 | openLinksInNewWindow: true,
12 | autoHighlight: true
13 | },
14 | structure: {
15 | readOnly: true,
16 | lineNumbers: true,
17 | firstLineNumber: 1,
18 | lineWrapping: true,
19 | foldGutter: true,
20 | tabSize: 2,
21 | indentCStyle: false,
22 | showArraySize: false
23 | },
24 | style: [
25 | ".CodeMirror {",
26 | " font-family: monaco, Consolas, Menlo, Courier, monospace;",
27 | " font-size: 16px;",
28 | " line-height: 1.5em;",
29 | "}"
30 | ].join('\n')
31 | }
32 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/options/render-addons.js:
--------------------------------------------------------------------------------
1 | var jsonFormater = require('../jsl-format');
2 |
3 | function renderAddons(CodeMirror, value) {
4 | var addonsInput = document.getElementById('addons');
5 | addonsInput.innerHTML = jsonFormater(JSON.stringify(value));
6 |
7 | return CodeMirror.fromTextArea(addonsInput, {
8 | mode: "application/ld+json",
9 | lineWrapping: true,
10 | lineNumbers: true,
11 | tabSize: 2
12 | });
13 | }
14 |
15 | module.exports = renderAddons;
16 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/options/render-structure.js:
--------------------------------------------------------------------------------
1 | var jsonFormater = require('../jsl-format');
2 |
3 | function renderStructure(CodeMirror, value) {
4 | var structureInput = document.getElementById('structure');
5 | structureInput.innerHTML = jsonFormater(JSON.stringify(value));
6 |
7 | return CodeMirror.fromTextArea(structureInput, {
8 | mode: "application/ld+json",
9 | lineWrapping: true,
10 | lineNumbers: true,
11 | tabSize: 2
12 | });
13 | }
14 |
15 | module.exports = renderStructure;
16 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/options/render-style.js:
--------------------------------------------------------------------------------
1 | var defaults = require('./defaults');
2 |
3 | function renderStyle(CodeMirror, value) {
4 | var styleInput = document.getElementById('style');
5 | styleInput.innerHTML = value;
6 |
7 | return CodeMirror.fromTextArea(styleInput, {
8 | mode: "css",
9 | lineWrapping: true,
10 | lineNumbers: true,
11 | tabSize: 2,
12 | extraKeys: {"Ctrl-Space": "autocomplete"}
13 | });
14 | }
15 |
16 | module.exports = renderStyle;
17 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/options/render-theme-list.js:
--------------------------------------------------------------------------------
1 | var jsonFormater = require('../jsl-format');
2 | var loadCss = require('../load-css');
3 | var themeDarkness = require('../theme-darkness');
4 |
5 | var themeDefault = "default";
6 | var themesList = process.env.THEMES;
7 | var themeJSONExample = {
8 | title: "JSON Example",
9 | nested: {
10 | someInteger: 7,
11 | someBoolean: true,
12 | someArray: [
13 | "list of",
14 | "fake strings",
15 | "and fake keys"
16 | ]
17 | }
18 | }
19 |
20 | function onThemeChange(input, editor) {
21 | var selectedTheme = input.options[input.selectedIndex].value;
22 | // Split '_' to allow themes with variations (e.g: solarized dark; solarized light)
23 | var themeOption = selectedTheme.replace(/_/, ' ');
24 |
25 | var currentLinkTag = document.getElementById('selected-theme');
26 | if (currentLinkTag !== null) {
27 | document.head.removeChild(currentLinkTag);
28 | }
29 |
30 | var themeToLoad = {
31 | id: "selected-theme",
32 | path: "themes/" + themeDarkness(selectedTheme) + "/" + selectedTheme + ".css",
33 | checkClass: "theme-" + selectedTheme + "-css-check"
34 | };
35 |
36 | if (selectedTheme === "default") {
37 | editor.setOption("theme", themeOption);
38 |
39 | } else {
40 | loadCss(themeToLoad).then(function() {
41 | editor.setOption("theme", themeOption);
42 | });
43 | }
44 | }
45 |
46 | function renderThemeList(CodeMirror, value) {
47 | var themesInput = document.getElementById('themes');
48 | var themesExampleInput = document.getElementById('themes-example');
49 | themesExampleInput.innerHTML = jsonFormater(JSON.stringify(themeJSONExample));
50 |
51 | var themeEditor = CodeMirror.fromTextArea(themesExampleInput, {
52 | readOnly: true,
53 | mode: "application/ld+json",
54 | lineWrapping: true,
55 | lineNumbers: true,
56 | tabSize: 2,
57 | foldGutter: true,
58 | gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
59 | });
60 |
61 | themes.onchange = function() {
62 | onThemeChange(themesInput, themeEditor);
63 | }
64 |
65 | var optionSelected = value;
66 | themesInput.appendChild(createOption(themeDefault, optionSelected));
67 | themesInput.appendChild(createThemeGroup("Light", themesList.light, optionSelected));
68 | themesInput.appendChild(createThemeGroup("Dark", themesList.dark, optionSelected));
69 |
70 | if (optionSelected && optionSelected !== "default") {
71 | themes.onchange();
72 | }
73 | }
74 |
75 | function createOption(theme, optionSelected) {
76 | var option = document.createElement("option");
77 | option.value = theme
78 | option.text = theme;
79 |
80 | if (theme === optionSelected) {
81 | option.selected = "selected";
82 | }
83 |
84 | return option;
85 | }
86 |
87 | function createGroup(label) {
88 | var group = document.createElement("optgroup");
89 | group.label = label;
90 | return group;
91 | }
92 |
93 | function createThemeGroup(name, list, optionSelected) {
94 | var group = createGroup(name);
95 | list.forEach(function(theme) {
96 | group.appendChild(createOption(theme, optionSelected));
97 | });
98 | return group;
99 | }
100 |
101 | module.exports = renderThemeList;
102 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/scratch-pad/load-editor.js:
--------------------------------------------------------------------------------
1 | var merge = require('../merge');
2 | var Highlighter = require('../highlighter');
3 | var getOptions = require('../viewer/get-options');
4 | var loadRequiredCss = require('../viewer/load-required-css');
5 | var renderExtras = require('../viewer/render-extras');
6 | var renderFormatButton = require('./render-format-button');
7 | var jsonFormater = require('../jsl-format');
8 | var JSONUtils = require('../check-if-json');
9 | var exposeJson = require('../viewer/expose-json');
10 |
11 | function loadEditor(pre) {
12 | getOptions().then(function(options) {
13 | return loadRequiredCss(options).then(function() {
14 | var scratchPadOptions = merge({}, options);
15 | scratchPadOptions.structure.readOnly = false;
16 |
17 | var highlighter = new Highlighter("", scratchPadOptions);
18 | highlighter.highlight();
19 |
20 | renderExtras(pre, options, highlighter);
21 | renderFormatButton(function() {
22 | var text = highlighter.editor.getValue();
23 | highlighter.editor.setValue(jsonFormater(text));
24 | if (JSONUtils.isJSON(text)) {
25 | exposeJson(text, true);
26 | }
27 | });
28 |
29 | });
30 | }).catch(function(e) {
31 | console.error('[JSONViewer] error: ' + e.message, e);
32 | });
33 | }
34 |
35 | module.exports = loadEditor;
36 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/scratch-pad/render-format-button.js:
--------------------------------------------------------------------------------
1 | var svgFormat = require('./svg-format');
2 | var Mousetrap = require('mousetrap');
3 | require('mousetrap/plugins/global-bind/mousetrap-global-bind');
4 |
5 | function renderFormatButton(onFormatClick) {
6 | var extras = document.getElementsByClassName("extras")[0];
7 |
8 | var formatLink = document.createElement("a");
9 | formatLink.className = "json_viewer icon format";
10 | formatLink.href = "#";
11 | formatLink.title = "Format (ctrl+shift+F / command+shift+F)";
12 | formatLink.innerHTML = svgFormat;
13 | formatLink.onclick = function(e) {
14 | e.preventDefault();
15 | onFormatClick();
16 | }
17 |
18 | Mousetrap.bindGlobal(['command+shift+f', 'ctrl+shift+f'], function() {
19 | onFormatClick();
20 | return false;
21 | });
22 |
23 | extras.appendChild(formatLink);
24 | }
25 |
26 | module.exports = renderFormatButton;
27 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/scratch-pad/svg-format.js:
--------------------------------------------------------------------------------
1 | module.exports = ' ';
2 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/storage.js:
--------------------------------------------------------------------------------
1 | var defaults = require('./options/defaults');
2 | var merge = require('./merge');
3 |
4 | var OLD_NAMESPACE = "options";
5 | var NAMESPACE = "v2.options";
6 |
7 | module.exports = {
8 | save: function(obj) {
9 | localStorage.setItem(NAMESPACE, JSON.stringify(obj));
10 | },
11 |
12 | load: function() {
13 | var optionsStr = localStorage.getItem(NAMESPACE);
14 | optionsStr = this.restoreOldOptions(optionsStr);
15 |
16 | options = optionsStr ? JSON.parse(optionsStr) : {};
17 | options.theme = options.theme || defaults.theme;
18 | options.addons = options.addons ? JSON.parse(options.addons) : {};
19 | options.addons = merge({}, defaults.addons, options.addons)
20 | options.structure = options.structure ? JSON.parse(options.structure) : defaults.structure;
21 | options.style = options.style && options.style.length > 0 ? options.style : defaults.style;
22 | return options;
23 | },
24 |
25 | restoreOldOptions: function(optionsStr) {
26 | var oldOptions = localStorage.getItem(OLD_NAMESPACE);
27 | var options = null;
28 |
29 | if (optionsStr === null && oldOptions !== null) {
30 | try {
31 | oldOptions = JSON.parse(oldOptions);
32 | if(!oldOptions || typeof oldOptions !== "object") oldOptions = {};
33 |
34 | options = {};
35 | options.theme = oldOptions.theme;
36 | options.addons = {
37 | prependHeader: JSON.parse(oldOptions.prependHeader || defaults.addons.prependHeader),
38 | maxJsonSize: parseInt(oldOptions.maxJsonSize || defaults.addons.maxJsonSize, 10)
39 | }
40 |
41 | // Update to at least the new max value
42 | if (options.addons.maxJsonSize < defaults.addons.maxJsonSize) {
43 | options.addons.maxJsonSize = defaults.addons.maxJsonSize;
44 | }
45 |
46 | options.addons = JSON.stringify(options.addons);
47 | options.structure = JSON.stringify(defaults.structure);
48 | options.style = defaults.style;
49 | this.save(options);
50 |
51 | optionsStr = JSON.stringify(options);
52 |
53 | } catch(e) {
54 | console.error('[JSONViewer] error: ' + e.message, e);
55 |
56 | } finally {
57 | localStorage.removeItem(OLD_NAMESPACE);
58 | }
59 | }
60 |
61 | return optionsStr;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/theme-darkness.js:
--------------------------------------------------------------------------------
1 | var themes = process.env.THEMES;
2 | module.exports = function(name) {
3 | var darkness = "light";
4 | if (themes.dark.indexOf(name) !== -1) darkness = "dark";
5 |
6 | return darkness;
7 | }
8 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/timestamp.js:
--------------------------------------------------------------------------------
1 | function twoDigits(number) {
2 | var str = number + "";
3 | if (str.length === 1) {
4 | return "0" + str;
5 | }
6 |
7 | return str;
8 | }
9 |
10 | function getTimestamp() {
11 | var date = new Date();
12 | var month = date.getMonth() + 1;
13 | var day = date.getDate();
14 | var hour = date.getHours();
15 | var min = date.getMinutes();
16 | var sec = date.getSeconds();
17 |
18 | return date.getFullYear() + twoDigits(month) + twoDigits(day) + twoDigits(hour) + twoDigits(min) + twoDigits(sec);
19 | }
20 |
21 | module.exports = getTimestamp;
22 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/url-pattern.js:
--------------------------------------------------------------------------------
1 | // ** With some modifications **
2 | //
3 | // Regular Expression for URL validation
4 | //
5 | // Author: Diego Perini
6 | // Updated: 2010/12/05
7 | // License: MIT
8 | //
9 | // Copyright (c) 2010-2013 Diego Perini (http://www.iport.it)
10 | //
11 | // Permission is hereby granted, free of charge, to any person
12 | // obtaining a copy of this software and associated documentation
13 | // files (the "Software"), to deal in the Software without
14 | // restriction, including without limitation the rights to use,
15 | // copy, modify, merge, publish, distribute, sublicense, and/or sell
16 | // copies of the Software, and to permit persons to whom the
17 | // Software is furnished to do so, subject to the following
18 | // conditions:
19 | //
20 | // The above copyright notice and this permission notice shall be
21 | // included in all copies or substantial portions of the Software.
22 | //
23 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
25 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
27 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
28 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
30 | // OTHER DEALINGS IN THE SOFTWARE.
31 | //
32 | // the regular expression composed & commented
33 | // could be easily tweaked for RFC compliance,
34 | // it was expressly modified to fit & satisfy
35 | // these test for an URL shortener:
36 | //
37 | // http://mathiasbynens.be/demo/url-regex
38 | //
39 | // Notes on possible differences from a standard/generic validation:
40 | //
41 | // - utf-8 char class take in consideration the full Unicode range
42 | // - TLDs have been made mandatory so single names like "localhost" fails
43 | // - protocols have been restricted to ftp, http and https only as requested
44 | //
45 | // Changes:
46 | //
47 | // - IP address dotted notation validation, range: 1.0.0.0 - 223.255.255.255
48 | // first and last IP address of each class is considered invalid
49 | // (since they are broadcast/network addresses)
50 | //
51 | // - Added exclusion of private, reserved and/or local networks ranges
52 | //
53 | // - Made starting path slash optional (http://example.com?foo=bar)
54 | //
55 | // - Allow a dot (.) at the end of hostnames (http://example.com.)
56 |
57 | function relativePath() {
58 | return "(?:[/?#]\\S*)?";
59 | }
60 |
61 | function absolutePath() {
62 | return "(?:(?:https?|ftp)://)" + /* protocol identifier*/
63 | "(?:\\S+(?::\\S*)?@)?" + /* user:pass authentication*/
64 | "(?:" +
65 | "(?:\\[[a-f0-9.:]+\\])" + /* IPv6 or hybrid addresses*/
66 | "|" +
67 | "(?:[a-z0-9\\u00a1-\\uffff.-]+)" + /* anything else, including IPv4 addresses */
68 | ")" +
69 | "(?::\\d{2,5})?" + /* port number*/
70 | relativePath(); /* resource path*/
71 | }
72 |
73 | module.exports = new RegExp("^(" + absolutePath() + "|" + relativePath() + ")$", "i");
74 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/viewer/expose-json.js:
--------------------------------------------------------------------------------
1 | function exposeJson(text, outsideViewer) {
2 | console.info("[JSONViewer] Your json was stored into 'window.json', enjoy!");
3 |
4 | if (outsideViewer) {
5 | window.json = JSON.parse(text);
6 |
7 | } else {
8 | var script = document.createElement("script") ;
9 | script.innerHTML = 'window.json = ' + text + ';';
10 | document.head.appendChild(script);
11 | }
12 | }
13 |
14 | module.exports = exposeJson;
15 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/viewer/get-options.js:
--------------------------------------------------------------------------------
1 | var Promise = require('promise');
2 | var chrome = require('chrome-framework');
3 |
4 | function getOptions() {
5 | return new Promise(function(resolve, reject) {
6 | chrome.runtime.sendMessage({action: "GET_OPTIONS"}, function(response) {
7 | var err = response.err;
8 | var value = response.value;
9 |
10 | if (err) {
11 | reject('getOptions: ' + err.message);
12 |
13 | } else {
14 | resolve(value);
15 | }
16 | });
17 | });
18 | }
19 |
20 | module.exports = getOptions;
21 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/viewer/load-required-css.js:
--------------------------------------------------------------------------------
1 | var Promise = require('promise');
2 | var loadCss = require('../load-css');
3 | var themeDarkness = require('../theme-darkness');
4 |
5 | function loadRequiredCss(options) {
6 | var theme = options.theme;
7 | var loaders = [];
8 | loaders.push(loadCss({
9 | path: "assets/viewer.css",
10 | checkClass: "json-viewer-css-check"
11 | }));
12 |
13 | if (theme && theme !== "default") {
14 | loaders.push(loadCss({
15 | path: "themes/" + themeDarkness(theme) + "/" + theme + ".css",
16 | checkClass: "theme-" + theme + "-css-check"
17 | }));
18 | }
19 |
20 | return Promise.all(loaders).then(function() {
21 | var style = document.createElement("style");
22 | style.rel = "stylesheet";
23 | style.type = "text/css";
24 | style.innerHTML = options.style;
25 | document.head.appendChild(style);
26 | });
27 | }
28 |
29 | module.exports = loadRequiredCss;
30 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/viewer/render-alert.js:
--------------------------------------------------------------------------------
1 | var loadCss = require('../load-css');
2 |
3 | function renderAlert(pre, options, content) {
4 | var alertContainer = document.createElement("div");
5 | alertContainer.className = "json-viewer-alert";
6 | alertContainer.appendChild(content);
7 |
8 | var closeBtn = document.createElement("a");
9 | closeBtn.className = "close";
10 | closeBtn.href = "#";
11 | closeBtn.title = "Close";
12 | closeBtn.innerHTML = "×";
13 | closeBtn.onclick = function(e) {
14 | e.preventDefault();
15 | alertContainer.parentNode.removeChild(alertContainer);
16 | }
17 |
18 | alertContainer.appendChild(closeBtn);
19 |
20 | loadCss({path: "assets/viewer-alert.css", checkClass: "json-viewer-alert"}).then(function() {
21 | document.body.appendChild(alertContainer);
22 |
23 | }).catch(function(e) {
24 | alertContainer.hidden = false;
25 | if (process.env.NODE_ENV === 'development') {
26 | console.error('[JSONViewer] error: ' + e.message, e);
27 | }
28 | });
29 | }
30 |
31 | module.exports = renderAlert;
32 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/viewer/render-extras.js:
--------------------------------------------------------------------------------
1 | var chrome = require('chrome-framework');
2 | var svgGear = require('./svg-gear');
3 | var svgRaw = require('./svg-raw');
4 | var svgUnfold = require('./svg-unfold');
5 |
6 | function renderExtras(pre, options, highlighter) {
7 | var extras = document.createElement("div");
8 | extras.className = "extras";
9 |
10 | if (!options.addons.autoHighlight) {
11 | extras.className += ' auto-highlight-off';
12 | }
13 |
14 | var optionsLink = document.createElement("a");
15 | optionsLink.className = "json_viewer icon gear";
16 | optionsLink.href = chrome.extension.getURL("/pages/options.html");
17 | optionsLink.target = "_blank";
18 | optionsLink.title = "Options";
19 | optionsLink.innerHTML = svgGear;
20 |
21 | var rawLink = document.createElement("a");
22 | rawLink.className = "json_viewer icon raw";
23 | rawLink.href = "#";
24 | rawLink.title = "Original JSON toggle";
25 | rawLink.innerHTML = svgRaw;
26 | rawLink.onclick = function(e) {
27 | e.preventDefault();
28 | var editor = document.getElementsByClassName('CodeMirror')[0];
29 |
30 | if (pre.hidden) {
31 | // Raw enabled
32 | highlighter.hide();
33 | pre.hidden = false;
34 | extras.className += ' auto-highlight-off';
35 |
36 | } else {
37 | // Raw disabled
38 | highlighter.show();
39 | pre.hidden = true;
40 | extras.className = extras.className.replace(/\s+auto-highlight-off/, '');
41 | }
42 | }
43 |
44 | var unfoldLink = document.createElement("a");
45 | unfoldLink.className = "json_viewer icon unfold";
46 | unfoldLink.href = "#";
47 | unfoldLink.title = "Fold/Unfold all toggle";
48 | unfoldLink.innerHTML = svgUnfold;
49 | unfoldLink.onclick = function(e) {
50 | e.preventDefault();
51 | var value = pre.getAttribute('data-folded')
52 |
53 | if (value === 'true' || value === true) {
54 | highlighter.unfoldAll();
55 | pre.setAttribute('data-folded', false)
56 |
57 | } else {
58 | highlighter.fold();
59 | pre.setAttribute('data-folded', true)
60 | }
61 | }
62 |
63 | extras.appendChild(optionsLink);
64 | extras.appendChild(rawLink);
65 |
66 | // "awaysFold" was a typo but to avoid any problems I'll keep it
67 | // a while
68 | pre.setAttribute('data-folded', options.addons.alwaysFold || options.addons.awaysFold)
69 | extras.appendChild(unfoldLink);
70 |
71 | document.body.appendChild(extras);
72 | }
73 |
74 | module.exports = renderExtras;
75 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/viewer/svg-gear.js:
--------------------------------------------------------------------------------
1 | module.exports = ' ';
2 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/viewer/svg-raw.js:
--------------------------------------------------------------------------------
1 | module.exports = ' ';
2 |
--------------------------------------------------------------------------------
/extension/src/json-viewer/viewer/svg-unfold.js:
--------------------------------------------------------------------------------
1 | module.exports = ' ';
2 |
--------------------------------------------------------------------------------
/extension/src/omnibox-page.js:
--------------------------------------------------------------------------------
1 | var JSONUtils = require('./json-viewer/check-if-json');
2 | var highlightContent = require('./json-viewer/highlight-content');
3 | var loadScratchPadEditor = require('./json-viewer/scratch-pad/load-editor');
4 |
5 | function onLoad() {
6 | var pre = document.getElementsByTagName("pre")[0];
7 | var query = window.location.search.substring(1);
8 |
9 | if (isScratchPad(query)) handleScratchPad(pre);
10 | else handleJSONHighlight(pre, query);
11 | }
12 |
13 | function handleScratchPad(pre) {
14 | pre.hidden = true;
15 | loadScratchPadEditor(pre);
16 | }
17 |
18 | function handleJSONHighlight(pre, query) {
19 | var rawJson = query.replace(/^json=/, '');
20 | pre.innerText = decodeURIComponent(rawJson);
21 |
22 | JSONUtils.checkIfJson(function(pre) {
23 | pre.hidden = true;
24 | highlightContent(pre, true);
25 | }, pre);
26 | }
27 |
28 | function isScratchPad(query) {
29 | return /scratch-page=true/.test(query);
30 | }
31 |
32 | document.addEventListener("DOMContentLoaded", onLoad, false);
33 |
--------------------------------------------------------------------------------
/extension/src/omnibox.js:
--------------------------------------------------------------------------------
1 | var chrome = require('chrome-framework');
2 |
3 | chrome.omnibox.onInputChanged.addListener(function(text, suggest) {
4 | console.log('[JSONViewer] inputChanged: ' + text);
5 | suggest([
6 | {
7 | content: "Format JSON",
8 | description: "(Format JSON) Open a page with json highlighted"
9 | },
10 | {
11 | content: "Scratch pad",
12 | description: "(Scratch pad) Area to write and format/highlight JSON"
13 | }
14 | ]);
15 | });
16 |
17 | chrome.omnibox.onInputEntered.addListener(function(text) {
18 | chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
19 | var omniboxUrl = chrome.extension.getURL("/pages/omnibox.html");
20 | var path = /scratch pad/i.test(text) ? "?scratch-page=true" : "?json=" + encodeURIComponent(text);
21 | var url = omniboxUrl + path;
22 | console.log("[JSONViewer] Opening: " + url);
23 |
24 | chrome.tabs.update(tabs[0].id, {url: url});
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/extension/src/options-styles.js:
--------------------------------------------------------------------------------
1 | require('codemirror/lib/codemirror.css');
2 | require('codemirror/addon/fold/foldgutter.css');
3 | require('codemirror/addon/hint/show-hint.css');
4 | require('../styles/default-theme.scss');
5 | require('sweetalert/dist/sweetalert.css');
6 | require('../styles/editor-custom.scss');
7 | require('../styles/options-custom.scss');
8 |
--------------------------------------------------------------------------------
/extension/src/options.js:
--------------------------------------------------------------------------------
1 | require('./options-styles');
2 | var CodeMirror = require('codemirror');
3 | require('codemirror/addon/fold/foldcode');
4 | require('codemirror/addon/fold/foldgutter');
5 | require('codemirror/addon/fold/brace-fold');
6 | require('codemirror/mode/javascript/javascript');
7 | require('codemirror/addon/hint/show-hint');
8 | require('codemirror/addon/hint/css-hint');
9 | require('codemirror/mode/css/css');
10 | var sweetAlert = require('sweetalert');
11 |
12 | var Storage = require('./json-viewer/storage');
13 | var renderThemeList = require('./json-viewer/options/render-theme-list');
14 | var renderAddons = require('./json-viewer/options/render-addons');
15 | var renderStructure = require('./json-viewer/options/render-structure');
16 | var renderStyle = require('./json-viewer/options/render-style');
17 | var bindSaveButton = require('./json-viewer/options/bind-save-button');
18 | var bindResetButton = require('./json-viewer/options/bind-reset-button');
19 |
20 | function isValidJSON(pseudoJSON) {
21 | try {
22 | JSON.parse(pseudoJSON);
23 | return true;
24 |
25 | } catch(e) {
26 | return false;
27 | }
28 | }
29 |
30 | function renderVersion() {
31 | var version = process.env.VERSION;
32 | var versionLink = document.getElementsByClassName('version')[0];
33 | versionLink.innerHTML = version;
34 | versionLink.href = "https://github.com/tulios/json-viewer/tree/" + version;
35 | }
36 |
37 | function onLoaded() {
38 | var currentOptions = Storage.load();
39 |
40 | renderVersion();
41 | renderThemeList(CodeMirror, currentOptions.theme);
42 | var addonsEditor = renderAddons(CodeMirror, currentOptions.addons);
43 | var structureEditor = renderStructure(CodeMirror, currentOptions.structure);
44 | var styleEditor = renderStyle(CodeMirror, currentOptions.style);
45 |
46 | bindResetButton();
47 | bindSaveButton([addonsEditor, structureEditor, styleEditor], function(options) {
48 | if (!isValidJSON(options.addons)) {
49 | sweetAlert("Ops!", "\"Add-ons\" isn't a valid JSON", "error");
50 |
51 | } else if (!isValidJSON(options.structure)) {
52 | sweetAlert("Ops!", "\"Structure\" isn't a valid JSON", "error");
53 |
54 | } else {
55 | Storage.save(options);
56 | sweetAlert("Success", "Options saved!", "success");
57 | }
58 | });
59 | }
60 |
61 | document.addEventListener("DOMContentLoaded", onLoaded, false);
62 |
--------------------------------------------------------------------------------
/extension/src/viewer-styles.js:
--------------------------------------------------------------------------------
1 | require('codemirror/lib/codemirror.css');
2 | require('codemirror/addon/fold/foldgutter.css');
3 | require('codemirror/addon/dialog/dialog.css');
4 | require('codemirror/addon/search/matchesonscrollbar.css');
5 | require('../styles/default-theme.scss');
6 | require('../styles/viewer-custom.scss');
7 | require('../styles/editor-custom.scss');
8 |
--------------------------------------------------------------------------------
/extension/src/viewer.js:
--------------------------------------------------------------------------------
1 | require('./viewer-styles');
2 | var JSONUtils = require('./json-viewer/check-if-json');
3 | var highlightContent = require('./json-viewer/highlight-content');
4 |
5 | function onLoad() {
6 | JSONUtils.checkIfJson(function(pre) {
7 | pre.hidden = true;
8 | highlightContent(pre);
9 | });
10 | }
11 |
12 | document.addEventListener("DOMContentLoaded", onLoad, false);
13 |
--------------------------------------------------------------------------------
/extension/styles/default-theme.scss:
--------------------------------------------------------------------------------
1 | .cm-s-default .cm-keyword {color: #000;}
2 | .cm-s-default .cm-atom {color: #905;}
3 | .cm-s-default .cm-number {color: #905;}
4 | .cm-s-default .cm-def {color: #00f;}
5 | .cm-s-default .cm-variable,
6 | .cm-s-default .cm-punctuation,
7 | .cm-s-default .cm-property,
8 | .cm-s-default .cm-operator {color: #000;}
9 | .cm-s-default.CodeMirror-wrap pre {color: #999;}
10 | .cm-s-default .cm-variable-2 {color: #000;}
11 | .cm-s-default .cm-variable-3 {color: #000;}
12 | .cm-s-default .cm-comment {color: slategray;}
13 | .cm-s-default .cm-string {color: #690;}
14 | .cm-s-default .cm-string-2 {color: #690;}
15 | .cm-s-default .cm-meta {color: #555;}
16 | .cm-s-default .cm-qualifier {color: #555;}
17 | .cm-s-default .cm-builtin {color: #30a;}
18 | .cm-s-default .cm-bracket {color: #999;}
19 | .cm-s-default .cm-tag {color: #905;}
20 | .cm-s-default .cm-attribute {color: #00c;}
21 | .cm-s-default .cm-header {color: blue;}
22 | .cm-s-default .cm-quote {color: #690;}
23 | .cm-s-default .cm-hr {color: #999;}
24 | .cm-s-default .cm-link {color: #690;}
25 |
26 | .cm-negative {color: #d44;}
27 | .cm-positive {color: #292;}
28 | .cm-header, .cm-strong {font-weight: bold;}
29 | .cm-em {font-style: italic;}
30 | .cm-link {text-decoration: underline;}
31 | .cm-strikethrough {text-decoration: line-through;}
32 |
33 | .cm-s-default .cm-error {color: #f00;}
34 | .cm-invalidchar {color: #f00;}
35 |
--------------------------------------------------------------------------------
/extension/styles/editor-custom.scss:
--------------------------------------------------------------------------------
1 | .CodeMirror {
2 | span.cm-string-link {
3 | text-decoration: underline;
4 | cursor: pointer;
5 | }
6 | }
7 |
8 | .CodeMirror-foldgutter {
9 | padding: 0 5px;
10 | }
11 |
12 | .CodeMirror pre,
13 | .CodeMirror-lines .CodeMirror-cursor,
14 | div.CodeMirror-selected {
15 | margin-left: 5px;
16 | }
17 |
18 | .CodeMirror-gutter-elt {
19 | text-align: center;
20 | }
21 |
22 | .CodeMirror-sizer {
23 | margin-right: 70px;
24 | }
25 |
--------------------------------------------------------------------------------
/extension/styles/options-custom.scss:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | }
4 |
5 | *:focus {
6 | outline: 0;
7 | }
8 |
9 | .container {
10 | position: relative;
11 | max-width: 1150px;
12 | margin: 0 auto;
13 |
14 | .version {
15 | float: left;
16 | display: block;
17 | padding: 9px;
18 | text-decoration: none;
19 |
20 | &:before {
21 | content: "v";
22 | }
23 | }
24 | }
25 |
26 | h1 {
27 | line-height: 128px;
28 | margin: 0 0 0 -10px;
29 | font-size: 2.5em;
30 |
31 | .logo {
32 | float: left;
33 | }
34 |
35 | .page-title {
36 | display: inline-block;
37 | margin: 3px 0 0 10px;
38 | }
39 | }
40 |
41 | header {
42 | padding: 20px 0 15px 0;
43 |
44 | h2 {
45 | padding: 0;
46 | margin: 0;
47 | font-size: 2em;
48 | }
49 |
50 | .underline {
51 | text-decoration: underline;
52 | }
53 |
54 | .explain strong, .hint {
55 | font-size: 1.5em;
56 | }
57 |
58 | .hint {
59 | font-style: italic;
60 | color: #999;
61 | font-family: 'Helvetica Neue', Arial, sans-serif;
62 | }
63 | }
64 |
65 | .CodeMirror {
66 | font-family: monaco, Consolas, Menlo, Courier, monospace;
67 | font-size: 16px;
68 | line-height: 1.5em;
69 | }
70 |
71 | .CodeMirror-hints {
72 | font-family: monaco, Consolas, Menlo, Courier, monospace;
73 | font-size: 14px;
74 | line-height: 20px;
75 | }
76 |
77 | #themes-example + .CodeMirror {
78 | height: 300px;
79 | }
80 |
81 | #addons + .CodeMirror,
82 | #structure + .CodeMirror {
83 | height: 250px;
84 | }
85 |
86 | #style + .CodeMirror {
87 | height: 450px;
88 | margin-bottom: 100px;
89 | }
90 |
91 | #addons + .CodeMirror
92 | #structure + .CodeMirror,
93 | #style + .CodeMirror {
94 | pre {
95 | margin-left: 0;
96 | }
97 |
98 | .CodeMirror-lines .CodeMirror-cursor {
99 | margin-left: 0;
100 | }
101 | }
102 |
103 | .select-style {
104 | border: 1px solid #ccc;
105 | width: 120px;
106 | border-radius: 3px;
107 | overflow: hidden;
108 | background: #fafafa url("data:image/png;base64,R0lGODlhDwAUAIABAAAAAP///yH5BAEAAAEALAAAAAAPABQAAAIXjI+py+0Po5wH2HsXzmw//lHiSJZmUAAAOw==") no-repeat 90% 50%;
109 | }
110 |
111 | .select-style {
112 | margin-bottom: 15px;
113 |
114 | select {
115 | padding: 5px 8px;
116 | width: 130%;
117 | border: none;
118 | box-shadow: none;
119 | background: transparent;
120 | background-image: none;
121 | -webkit-appearance: none;
122 |
123 | &:focus {
124 | outline: none;
125 | }
126 | }
127 | }
128 |
129 | .action-bar {
130 | box-sizing: border-box;
131 | position: fixed;
132 | bottom: 0;
133 | left: 0;
134 |
135 | width: 100%;
136 | padding: 20px;
137 | background-color: #f0f0f0;
138 | text-align: right;
139 | z-index: 10;
140 |
141 | button {
142 | background: linear-gradient(to bottom, #79bbff 5%, #378de5 100%);
143 | background-color: #79bbff;
144 | border-radius: 6px;
145 | border: 1px solid #84bbf3;
146 | display: inline-block;
147 | cursor: pointer;
148 | color: #ffffff;
149 | font-family: Arial;
150 | font-size: 16px;
151 | font-weight: bold;
152 | padding: 6px 24px;
153 | text-decoration: none;
154 | text-shadow: 0px 1px 0px #528ecc;
155 |
156 | &:hover {
157 | background: linear-gradient(to bottom, #378de5 5%, #79bbff 100%);
158 | background-color: #378de5;
159 | }
160 |
161 | &:active {
162 | position: relative;
163 | top: 1px;
164 | }
165 | }
166 | }
167 |
168 | .logo {
169 | display: inline-block;
170 | width: 128px;
171 | height: 128px;
172 | background-image: url('data:image/png;base64,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');
173 | }
174 |
--------------------------------------------------------------------------------
/extension/styles/viewer-alert.scss:
--------------------------------------------------------------------------------
1 | .json-viewer-alert {
2 | -webkit-user-select: none;
3 | position: fixed;
4 | top: 0;
5 | right: 0;
6 | margin: 10px;
7 | padding: 10px 20px 10px 10px;
8 | border: 1px solid transparent;
9 | border-radius: 4px;
10 | max-width: 380px;
11 |
12 | color: #8a6d3b;
13 | background-color: #fcf8e3;
14 | border-color: #faebcc;
15 |
16 | .close {
17 | position: absolute;
18 | right: 10px;
19 | background-color: transparent;
20 | text-decoration: none;
21 | font-size: 30px;
22 | line-height: 0;
23 | font-weight: 700;
24 | color: #000;
25 | text-shadow: 0 1px 0 #fff;
26 | opacity: 0.2;
27 |
28 | &:hover {
29 | color: #000;
30 | cursor: pointer;
31 | opacity: 0.5;
32 | }
33 | }
34 |
35 | &:before {
36 | content: 'loaded';
37 | display: none;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/extension/styles/viewer-custom.scss:
--------------------------------------------------------------------------------
1 | html, body {
2 | padding: 0;
3 | margin: 0;
4 | height: 100%;
5 | }
6 |
7 | .json-viewer-css-check:before {
8 | content: 'loaded';
9 | display: none;
10 | }
11 |
12 | .read-only .CodeMirror-cursor {
13 | visibility: hidden;
14 | }
15 |
16 | .CodeMirror {
17 | width: 100%;
18 | height: 100%;
19 | }
20 |
21 | .extras {
22 | z-index: 10;
23 | position: absolute;
24 | top: 0;
25 | right: 16px;
26 | padding: 10px 5px 10px 15px;
27 |
28 | a {
29 | transition: all ease-in-out 250ms;
30 | visibility: visible;
31 | opacity: 0.3;
32 | }
33 |
34 | &:hover a {
35 | visibility: visible;
36 | opacity: 1;
37 | }
38 |
39 | $icon-size: 40px;
40 |
41 | .icon {
42 | svg {
43 | width: $icon-size;
44 | height: $icon-size;
45 | fill: #000000;
46 | }
47 |
48 | display: block;
49 | width: $icon-size;
50 | height: $icon-size;
51 | background-size: $icon-size;
52 | background-color: transparent;
53 | margin-bottom: 5px;
54 | border-radius: 4px;
55 |
56 | &:hover {
57 | background-color: #ccc;
58 | }
59 | }
60 |
61 | &.auto-highlight-off {
62 | .icon {
63 | background-color: #ccc;
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/extension/themes/dark/3024-night.js:
--------------------------------------------------------------------------------
1 | require('codemirror/theme/3024-night.css');
2 | require('./3024-night/3024-night.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/dark/3024-night/3024-night.scss:
--------------------------------------------------------------------------------
1 | .theme-3024-night-css-check:before {
2 | content: 'loaded';
3 | display: none;
4 | }
5 |
6 | .extras {
7 | .icon {
8 | svg {
9 | fill: #fff;
10 | }
11 |
12 | &:hover {
13 | background-color: #666;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/extension/themes/dark/ambiance.js:
--------------------------------------------------------------------------------
1 | require('codemirror/theme/ambiance.css');
2 | require('./ambiance/ambiance.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/dark/ambiance/ambiance.scss:
--------------------------------------------------------------------------------
1 | .theme-ambiance-css-check:before {
2 | content: 'loaded';
3 | display: none;
4 | }
5 |
6 | .cm-s-ambiance div.CodeMirror-selected {
7 | background: rgba(255, 255, 255, 0.25);
8 | }
9 |
10 | .extras {
11 | .icon {
12 | svg {
13 | fill: #fff;
14 | }
15 |
16 | &:hover {
17 | background-color: #666;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/extension/themes/dark/base16-dark.js:
--------------------------------------------------------------------------------
1 | require('codemirror/theme/base16-dark.css');
2 | require('./base16-dark/base16-dark.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/dark/base16-dark/base16-dark.scss:
--------------------------------------------------------------------------------
1 | .theme-base16-dark-css-check:before {
2 | content: 'loaded';
3 | display: none;
4 | }
5 |
6 | .cm-s-base16-dark div.CodeMirror-selected {
7 | background: rgba(255, 255, 255, 0.25);
8 | }
9 |
10 | .extras {
11 | .icon {
12 | svg {
13 | fill: #fff;
14 | }
15 |
16 | &:hover {
17 | background-color: #666;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/extension/themes/dark/cobalt.js:
--------------------------------------------------------------------------------
1 | require('codemirror/theme/cobalt.css');
2 | require('./cobalt/cobalt.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/dark/cobalt/cobalt.scss:
--------------------------------------------------------------------------------
1 | .cm-s-cobalt .CodeMirror-gutters{border: none;}
2 |
3 | .theme-cobalt-css-check:before {
4 | content: 'loaded';
5 | display: none;
6 | }
7 |
8 | .extras {
9 | .icon {
10 | svg {
11 | fill: #fff;
12 | }
13 |
14 | &:hover {
15 | background-color: #666;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/extension/themes/dark/dark.js:
--------------------------------------------------------------------------------
1 | require('./dark/dark.theme.css');
2 | require('./dark/dark.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/dark/dark/dark.scss:
--------------------------------------------------------------------------------
1 | .theme-dark-css-check:before {
2 | content: 'loaded';
3 | display: none;
4 | }
5 |
6 | .extras {
7 | .icon {
8 | svg {
9 | fill: #fff;
10 | }
11 |
12 | &:hover {
13 | background-color: #666;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/extension/themes/dark/dark/dark.theme.css:
--------------------------------------------------------------------------------
1 | .cm-s-dark.CodeMirror{background:hsl(30,20%,25%) !important;}
2 | .cm-s-dark.CodeMirror{color:hsl(30,20%,50%) !important;}
3 | .cm-s-dark div.CodeMirror-selected{background:hsl(30,20%,35%) !important;}
4 | .cm-s-dark .CodeMirror-gutters{background:rgba(0,0,0,0) !important; border: none;}
5 | .cm-s-dark .CodeMirror-guttermarker{color:rgba(29,117,179,1) !important;}
6 | .cm-s-dark .CodeMirror-guttermarker-subtle{color:#868889 !important;}
7 | .cm-s-dark .CodeMirror-linenumber{color:#868889 !important;}
8 | .cm-s-dark .CodeMirror-cursor{border-color:rgba(46,56,60,1) !important;}
9 | .cm-s-dark span.cm-comment{color:hsl(30,20%,60%) !important;}
10 | .cm-s-dark span.cm-atom{color:hsl(350, 40%, 70%) !important;}
11 | .cm-s-dark span.cm-number{color:hsl(350, 40%, 70%) !important;}
12 | .cm-s-dark span.cm-property{color:rgba(255,255,255,1) !important;}
13 | .cm-s-dark span.cm-attribute{color:rgba(255,255,255,1) !important;}
14 | .cm-s-dark span.cm-keyword{color:rgba(255,255,255,1) !important;}
15 | .cm-s-dark span.cm-string{color:hsl(75, 70%, 60%) !important;}
16 | .cm-s-dark span.cm-string-2{color:hsl(75, 70%, 60%) !important;}
17 | .cm-s-dark span.cm-variable{color:rgba(255,255,255,1) !important;}
18 | .cm-s-dark span.cm-variable-2{color:rgba(255,255,255,1) !important;}
19 | .cm-s-dark span.cm-def{color:rgba(46,56,60,1) !important;}
20 | .cm-s-dark span.cm-bracket{color:rgba(46,56,60,1) !important;}
21 | .cm-s-dark span.cm-tag{color:rgba(156,51,40,1) !important;}
22 | .cm-s-dark span.cm-link{color:hsl(75, 70%, 60%) !important;}
23 | .cm-s-dark span.cm-error{background:rgba(0,0,0,0) !important;}
24 | .cm-s-dark span.cm-error{color:rgba(46,56,60,1) !important;}
25 | .cm-s-dark .CodeMirror-activeline-background{color:rgba(46,56,60,1) !important;}
26 | .cm-s-dark .CodeMirror-matchingbracket{color:rgba(0,255,0,1) !important;}
27 |
--------------------------------------------------------------------------------
/extension/themes/dark/dracula-custom.js:
--------------------------------------------------------------------------------
1 | require('./dracula-custom/dracula-custom.theme.css');
2 | require('./dracula-custom/dracula-custom.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/dark/dracula-custom/dracula-custom.scss:
--------------------------------------------------------------------------------
1 | .theme-dracula-custom-css-check:before {
2 | content: 'loaded';
3 | display: none;
4 | }
5 |
6 | .cm-s-dracula-custom .CodeMirror-selected {
7 | background: rgba(230,231,243,0.25);
8 | }
9 |
10 | .extras {
11 | .icon {
12 | svg {
13 | fill: #fff;
14 | }
15 |
16 | &:hover {
17 | background-color: #666;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/extension/themes/dark/dracula-custom/dracula-custom.theme.css:
--------------------------------------------------------------------------------
1 | .cm-s-dracula-custom.CodeMirror, .cm-s-dracula-custom .CodeMirror-gutters {
2 | background-color: #282a36 !important;
3 | color: #f8f8f2 !important;
4 | border: none;
5 | }
6 | .cm-s-dracula-custom .CodeMirror-gutters { color: #282a36; }
7 | .cm-s-dracula-custom .CodeMirror-cursor { border-left: solid thin #f8f8f0; }
8 | .cm-s-dracula-custom .CodeMirror-linenumber { color: #6D8A88; }
9 | .cm-s-dracula-custom.CodeMirror-focused div.CodeMirror-selected { background: rgba(255, 255, 255, 0.10); }
10 | .cm-s-dracula-custom .CodeMirror-line::selection, .cm-s-dracula-custom .CodeMirror-line > span::selection, .cm-s-dracula-custom .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); }
11 | .cm-s-dracula-custom .CodeMirror-line::-moz-selection, .cm-s-dracula-custom .CodeMirror-line > span::-moz-selection, .cm-s-dracula-custom .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); }
12 | .cm-s-dracula-custom span.cm-comment { color: #6272a4; }
13 | .cm-s-dracula-custom span.cm-string, .cm-s-dracula-custom span.cm-string-2 { color: #f1fa8c; }
14 | .cm-s-dracula-custom span.cm-number { color: #bd93f9; }
15 | .cm-s-dracula-custom span.cm-variable { color: #50fa7b; }
16 | .cm-s-dracula-custom span.cm-variable-2 { color: white; }
17 | .cm-s-dracula-custom span.cm-def { color: #ffb86c; }
18 | .cm-s-dracula-custom span.cm-keyword { color: #ff79c6; }
19 | .cm-s-dracula-custom span.cm-operator { color: #ff79c6; }
20 | .cm-s-dracula-custom span.cm-keyword { color: #ff79c6; }
21 | .cm-s-dracula-custom span.cm-atom { color: #bd93f9; }
22 | .cm-s-dracula-custom span.cm-meta { color: #f8f8f2; }
23 | .cm-s-dracula-custom span.cm-tag { color: #ff79c6; }
24 | .cm-s-dracula-custom span.cm-attribute { color: #50fa7b; }
25 | .cm-s-dracula-custom span.cm-qualifier { color: #50fa7b; }
26 | .cm-s-dracula-custom span.cm-property { color: #ff79c6; }
27 | .cm-s-dracula-custom span.cm-builtin { color: #50fa7b; }
28 | .cm-s-dracula-custom span.cm-variable-3 { color: #50fa7b; }
29 |
30 | .cm-s-dracula-custom .CodeMirror-activeline-background { background: rgba(255,255,255,0.1); }
31 | .cm-s-dracula-custom .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
32 |
--------------------------------------------------------------------------------
/extension/themes/dark/dracula.js:
--------------------------------------------------------------------------------
1 | require('./dracula/dracula.theme.css');
2 | require('./dracula/dracula.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/dark/dracula/dracula.scss:
--------------------------------------------------------------------------------
1 | .theme-dracula-css-check:before {
2 | content: 'loaded';
3 | display: none;
4 | }
5 |
6 | .extras {
7 | .icon {
8 | svg {
9 | fill: #fff;
10 | }
11 |
12 | &:hover {
13 | background-color: #666;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/extension/themes/dark/dracula/dracula.theme.css:
--------------------------------------------------------------------------------
1 | /*
2 | Name: dracula
3 | Author: Michael Kaminsky (http://github.com/mkaminsky11)
4 |
5 | Original dracula color scheme by Zeno Rocha (https://github.com/zenorocha/dracula-theme)
6 | */
7 |
8 | .cm-s-dracula.CodeMirror, .cm-s-dracula .CodeMirror-gutters {
9 | background-color: #282a36 !important;
10 | color: #f8f8f2 !important;
11 | border: none;
12 | }
13 | .cm-s-dracula .CodeMirror-gutters { color: #282a36; }
14 | .cm-s-dracula .CodeMirror-cursor { border-left: solid thin #f8f8f0; }
15 | .cm-s-dracula .CodeMirror-linenumber { color: #6D8A88; }
16 | .cm-s-dracula.CodeMirror-focused div.CodeMirror-selected { background: rgba(255, 255, 255, 0.10); }
17 | .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); }
18 | .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); }
19 | .cm-s-dracula span.cm-comment { color: #6272a4; }
20 | .cm-s-dracula span.cm-string, .cm-s-dracula span.cm-string-2 { color: #f1fa8c; }
21 | .cm-s-dracula span.cm-number { color: #bd93f9; }
22 | .cm-s-dracula span.cm-variable { color: #50fa7b; }
23 | .cm-s-dracula span.cm-variable-2 { color: white; }
24 | .cm-s-dracula span.cm-def { color: #ffb86c; }
25 | .cm-s-dracula span.cm-keyword { color: #ff79c6; }
26 | .cm-s-dracula span.cm-operator { color: #ff79c6; }
27 | .cm-s-dracula span.cm-keyword { color: #ff79c6; }
28 | .cm-s-dracula span.cm-atom { color: #bd93f9; }
29 | .cm-s-dracula span.cm-meta { color: #f8f8f2; }
30 | .cm-s-dracula span.cm-tag { color: #ff79c6; }
31 | .cm-s-dracula span.cm-attribute { color: #50fa7b; }
32 | .cm-s-dracula span.cm-qualifier { color: #50fa7b; }
33 | .cm-s-dracula span.cm-property { color: #66d9ef; }
34 | .cm-s-dracula span.cm-builtin { color: #50fa7b; }
35 | .cm-s-dracula span.cm-variable-3 { color: #50fa7b; }
36 |
37 | .cm-s-dracula .CodeMirror-activeline-background { background: rgba(255,255,255,0.1); }
38 | .cm-s-dracula .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
39 |
--------------------------------------------------------------------------------
/extension/themes/dark/jellybeans.js:
--------------------------------------------------------------------------------
1 | require('./jellybeans/jellybeans.theme.css');
2 | require('./jellybeans/jellybeans.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/dark/jellybeans/jellybeans.scss:
--------------------------------------------------------------------------------
1 | .theme-jellybeans-css-check:before {
2 | content: 'loaded';
3 | display: none;
4 | }
5 |
6 | .extras {
7 | .icon {
8 | svg {
9 | fill: #fff;
10 | }
11 |
12 | &:hover {
13 | background-color: #333;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/extension/themes/dark/jellybeans/jellybeans.theme.css:
--------------------------------------------------------------------------------
1 | .cm-s-jellybeans.CodeMirror{background:rgba(21,21,21,1) !important;}
2 | .cm-s-jellybeans.CodeMirror{color:rgba(227,165,89,1) !important;}
3 | .cm-s-jellybeans div.CodeMirror-selected {background: #49483E !important;}
4 | .cm-s-jellybeans.CodeMirror ::selection { background: rgba(73, 72, 62, .99); }
5 | .cm-s-jellybeans.CodeMirror ::-moz-selection { background: rgba(73, 72, 62, .99); }
6 | .cm-s-jellybeans .CodeMirror-gutters{background:rgba(0,0,0,0) !important; border: none;}
7 | .cm-s-jellybeans .CodeMirror-guttermarker{color:rgba(29,117,179,1) !important;}
8 | .cm-s-jellybeans .CodeMirror-guttermarker-subtle{color:#5B5B5B !important;}
9 | .cm-s-jellybeans .CodeMirror-linenumber{color:#5B5B5B !important;}
10 | .cm-s-jellybeans .CodeMirror-cursor{border-color:rgba(46,56,60,1) !important;}
11 | .cm-s-jellybeans span.cm-comment{color:rgba(133,138,129,1) !important;}
12 | .cm-s-jellybeans span.cm-atom{color:rgba(162,76,62,1) !important;}
13 | .cm-s-jellybeans span.cm-number{color:rgba(162,76,62,1) !important;}
14 | .cm-s-jellybeans span.cm-property{color:rgba(129,142,91,1) !important;}
15 | .cm-s-jellybeans span.cm-attribute{color:rgba(129,142,91,1) !important;}
16 | .cm-s-jellybeans span.cm-keyword{color:rgba(129,142,91,1) !important;}
17 | .cm-s-jellybeans span.cm-string{color:rgba(129,142,91,1) !important;}
18 | .cm-s-jellybeans span.cm-string-2{color:rgba(129,142,91,1) !important;}
19 | .cm-s-jellybeans span.cm-variable{color:rgba(129,142,91,1) !important;}
20 | .cm-s-jellybeans span.cm-variable-2{color:rgba(129,142,91,1) !important;}
21 | .cm-s-jellybeans span.cm-def{color:rgba(46,56,60,1) !important;}
22 | .cm-s-jellybeans span.cm-bracket{color:rgba(46,56,60,1) !important;}
23 | .cm-s-jellybeans span.cm-tag{color:rgba(156,51,40,1) !important;}
24 | .cm-s-jellybeans span.cm-link{color:rgba(129,142,91,1) !important;}
25 | .cm-s-jellybeans span.cm-error{background:rgba(0,0,0,0) !important;}
26 | .cm-s-jellybeans span.cm-error{color:rgba(46,56,60,1) !important;}
27 | .cm-s-jellybeans .CodeMirror-activeline-background{color:rgba(46,56,60,1) !important;}
28 | .cm-s-jellybeans .CodeMirror-matchingbracket{color:rgba(0,255,0,1) !important;}
29 |
--------------------------------------------------------------------------------
/extension/themes/dark/material.js:
--------------------------------------------------------------------------------
1 | require('./material/material.theme.css');
2 | require('./material/material.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/dark/material/material.scss:
--------------------------------------------------------------------------------
1 | .theme-material-css-check:before {
2 | content: 'loaded';
3 | display: none;
4 | }
5 |
6 | .extras {
7 | .icon {
8 | svg {
9 | fill: #fff;
10 | }
11 |
12 | &:hover {
13 | background-color: #666;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/extension/themes/dark/material/material.theme.css:
--------------------------------------------------------------------------------
1 | .cm-s-material.CodeMirror{background:rgba(34,47,53,1) !important;}
2 | .cm-s-material.CodeMirror{color:rgba(96,125,138,1) !important;}
3 | .cm-s-material div.CodeMirror-selected{background:rgba(0,64,115,1) !important;}
4 | .cm-s-material .CodeMirror-gutters{background:rgba(0,0,0,0) !important; border: 0;}
5 | .cm-s-material .CodeMirror-guttermarker{color:#546f7a !important;}
6 | .cm-s-material .CodeMirror-guttermarker-subtle{color:#546f7a !important;}
7 | .cm-s-material .CodeMirror-linenumber{color:rgba(84,111,122,1) !important;}
8 | .cm-s-material .CodeMirror-cursor{border-color:rgba(46,56,60,1) !important;}
9 | .cm-s-material span.cm-comment{color:rgba(145,145,145,1) !important;}
10 | .cm-s-material span.cm-atom{color:rgb(255, 47, 146) !important;}
11 | .cm-s-material span.cm-number{color:rgba(215,131,255,1) !important;}
12 | .cm-s-material span.cm-property{color:rgba(0,253,255,1) !important;}
13 | .cm-s-material span.cm-attribute{color:rgba(0,253,255,1) !important;}
14 | .cm-s-material span.cm-keyword{color:rgba(122,129,255,1) !important;}
15 | .cm-s-material span.cm-string{color:rgba(0,250,146,1) !important;}
16 | .cm-s-material span.cm-string-2{color:rgba(0,250,146,1) !important;}
17 | .cm-s-material span.cm-variable{color:rgba(96,125,138,1) !important;}
18 | .cm-s-material span.cm-variable-2{color:rgba(96,125,138,1) !important;}
19 | .cm-s-material span.cm-def{color:rgba(96,125,138,1) !important;}
20 | .cm-s-material span.cm-bracket{color:rgba(0,253,255,1) !important;}
21 | .cm-s-material span.cm-tag{color:rgba(0,250,146,1) !important;}
22 | .cm-s-material span.cm-link{color:rgba(46,56,60,1) !important;}
23 | .cm-s-material span.cm-error{background:rgba(0,0,0,0) !important;}
24 | .cm-s-material span.cm-error{color:rgba(46,56,60,1) !important;}
25 | .cm-s-material .CodeMirror-activeline-background{color:rgba(46,56,60,1) !important;}
26 | .cm-s-material .CodeMirror-matchingbracket{color:rgba(0,255,0,1) !important;}
27 |
--------------------------------------------------------------------------------
/extension/themes/dark/mbo.js:
--------------------------------------------------------------------------------
1 | require('codemirror/theme/mbo.css');
2 | require('./mbo/mbo.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/dark/mbo/mbo.scss:
--------------------------------------------------------------------------------
1 | .theme-mbo-css-check:before {
2 | content: 'loaded';
3 | display: none;
4 | }
5 |
6 | .extras {
7 | .icon {
8 | svg {
9 | fill: #fff;
10 | }
11 |
12 | &:hover {
13 | background-color: #666;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/extension/themes/dark/mehdi.js:
--------------------------------------------------------------------------------
1 | require('./mehdi/mehdi.theme.css');
2 | require('./mehdi/mehdi.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/dark/mehdi/mehdi.scss:
--------------------------------------------------------------------------------
1 | .theme-mehdi-css-check:before {
2 | content: 'loaded';
3 | display: none;
4 | }
5 |
6 | .extras {
7 | .icon {
8 | svg {
9 | fill: #fff;
10 | }
11 |
12 | &:hover {
13 | background-color: #333;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/extension/themes/dark/mehdi/mehdi.theme.css:
--------------------------------------------------------------------------------
1 | .cm-s-mehdi.CodeMirror {
2 | background:#2c3e50!important;
3 | color:#ecf0f1!important;
4 | }
5 |
6 | .cm-s-mehdi div.CodeMirror-selected {
7 | background:#16a085!important;
8 | }
9 |
10 | .cm-s-mehdi .CodeMirror-gutters {
11 | background:0 0!important;
12 | border:none;
13 | }
14 |
15 | .cm-s-mehdi .CodeMirror-guttermarker {
16 | color:#3498db!important;
17 | }
18 |
19 | .cm-s-mehdi .CodeMirror-guttermarker-subtle,.cm-s-mehdi .CodeMirror-linenumber {
20 | color:#7f8c8d!important;
21 | }
22 |
23 | .cm-s-mehdi .CodeMirror-cursor {
24 | border-color:#ccc!important;
25 | }
26 |
27 | .cm-s-mehdi span.cm-comment {
28 | color:#7f8c8d!important;
29 | }
30 |
31 | .cm-s-mehdi span.cm-atom,.cm-s-mehdi span.cm-number {
32 | color:#f1c40f!important;
33 | }
34 |
35 | .cm-s-mehdi span.cm-tag {
36 | color:#e2777a!important;
37 | }
38 |
39 | .cm-s-mehdi span.cm-error {
40 | background:0 0!important;
41 | color:#7f8c8d!important;
42 | }
43 |
44 | .cm-s-mehdi .CodeMirror-matchingbracket {
45 | color:#27ae60!important;
46 | }
47 |
48 | .cm-s-mehdi.CodeMirror ::selection,.cm-s-mehdi.CodeMirror ::-moz-selection {
49 | background:rgba(73,72,62,.99);
50 | }
51 |
52 | .cm-s-mehdi span.cm-attribute,.cm-s-mehdi span.cm-keyword,.cm-s-mehdi span.cm-property,.cm-s-mehdi span.cm-variable,.cm-s-mehdi span.cm-variable-2 {
53 | color:#ecf0f1!important;
54 | }
55 |
56 | .cm-s-mehdi span.cm-string,.cm-s-mehdi span.cm-string-2,.cm-s-mehdi span.cm-link {
57 | color:#1abc9c!important;
58 | }
59 |
60 | .cm-s-mehdi span.cm-bracket,.cm-s-mehdi span.cm-def,.cm-s-mehdi .CodeMirror-activeline-background {
61 | color:#2e383c!important;
62 | }
63 |
--------------------------------------------------------------------------------
/extension/themes/dark/midnight.js:
--------------------------------------------------------------------------------
1 | require('codemirror/theme/midnight.css');
2 | require('./midnight/midnight.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/dark/midnight/midnight.scss:
--------------------------------------------------------------------------------
1 | .cm-s-midnight .CodeMirror-gutters{border: none;}
2 | .cm-s-monokai .CodeMirror-guttermarker-subtle,
3 | .cm-s-monokai .CodeMirror-linenumber {
4 | color: #7D7D7D;
5 | }
6 |
7 | .theme-midnight-css-check:before {
8 | content: 'loaded';
9 | display: none;
10 | }
11 |
12 | .extras {
13 | .icon {
14 | svg {
15 | fill: #fff;
16 | }
17 |
18 | &:hover {
19 | background-color: #666;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/extension/themes/dark/monokai.js:
--------------------------------------------------------------------------------
1 | require('codemirror/theme/monokai.css');
2 | require('./monokai/monokai.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/dark/monokai/monokai.scss:
--------------------------------------------------------------------------------
1 | .cm-s-monokai .CodeMirror-guttermarker-subtle,
2 | .cm-s-monokai .CodeMirror-linenumber {
3 | color: #686868;
4 | }
5 |
6 | .theme-monokai-css-check:before {
7 | content: 'loaded';
8 | display: none;
9 | }
10 |
11 | .extras {
12 | .icon {
13 | svg {
14 | fill: #fff;
15 | }
16 |
17 | &:hover {
18 | background-color: #666;
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/extension/themes/dark/okaidia.js:
--------------------------------------------------------------------------------
1 | require('./okaidia/okaidia.theme.css');
2 | require('./okaidia/okaidia.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/dark/okaidia/okaidia.scss:
--------------------------------------------------------------------------------
1 | .theme-okaidia-css-check:before {
2 | content: 'loaded';
3 | display: none;
4 | }
5 |
6 | .extras {
7 | .icon {
8 | svg {
9 | fill: #fff;
10 | }
11 |
12 | &:hover {
13 | background-color: #333;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/extension/themes/dark/okaidia/okaidia.theme.css:
--------------------------------------------------------------------------------
1 | .cm-s-okaidia.CodeMirror{background:rgba(39,40,34,1) !important;}
2 | .cm-s-okaidia.CodeMirror{color:rgba(255,255,255,1) !important;}
3 | .cm-s-okaidia div.CodeMirror-selected {background: #49483E !important;}
4 | .cm-s-okaidia.CodeMirror ::selection { background: rgba(73, 72, 62, .99); }
5 | .cm-s-okaidia.CodeMirror ::-moz-selection { background: rgba(73, 72, 62, .99); }
6 | .cm-s-okaidia .CodeMirror-gutters{background:rgba(0,0,0,0) !important; border: none;}
7 | .cm-s-okaidia .CodeMirror-guttermarker{color:rgba(243,55,117,1) !important;}
8 | .cm-s-okaidia .CodeMirror-guttermarker-subtle{color:#575757 !important;}
9 | .cm-s-okaidia .CodeMirror-linenumber{color:#52534E !important;}
10 | .cm-s-okaidia .CodeMirror-cursor{border-color:rgba(46,56,60,1) !important;}
11 | .cm-s-okaidia span.cm-comment{color:rgba(117,120,123,1) !important;}
12 | .cm-s-okaidia span.cm-atom{color:rgba(174,129,250,1) !important;}
13 | .cm-s-okaidia span.cm-number{color:rgba(174,129,250,1) !important;}
14 | .cm-s-okaidia span.cm-property{color:rgba(243,55,117,1) !important;}
15 | .cm-s-okaidia span.cm-attribute{color:rgba(46,56,60,1) !important;}
16 | .cm-s-okaidia span.cm-keyword{color:rgba(243,55,117,1) !important;}
17 | .cm-s-okaidia span.cm-string{color:rgba(173,222,57,1) !important;}
18 | .cm-s-okaidia span.cm-string-2{color:rgba(46,56,60,1) !important;}
19 | .cm-s-okaidia span.cm-variable{color:rgba(243,55,117,1) !important;}
20 | .cm-s-okaidia span.cm-variable-2{color:rgba(243,55,117,1) !important;}
21 | .cm-s-okaidia span.cm-def{color:rgba(46,56,60,1) !important;}
22 | .cm-s-okaidia span.cm-bracket{color:rgba(255,255,255,1) !important;}
23 | .cm-s-okaidia span.cm-tag{color:rgba(243,55,117,1) !important;}
24 | .cm-s-okaidia span.cm-link{color:rgba(173,222,57,1) !important;}
25 | .cm-s-okaidia span.cm-error{background:rgba(0,0,0,0) !important;}
26 | .cm-s-okaidia span.cm-error{color:rgba(46,56,60,1) !important;}
27 | .cm-s-okaidia .CodeMirror-activeline-background{color:rgba(46,56,60,1) !important;}
28 | .cm-s-okaidia .CodeMirror-matchingbracket{color:rgba(0,255,0,1) !important;}
29 |
--------------------------------------------------------------------------------
/extension/themes/dark/panda-syntax.js:
--------------------------------------------------------------------------------
1 | require('./panda-syntax/panda-syntax.theme.css');
2 | require('./panda-syntax/panda-syntax.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/dark/panda-syntax/panda-syntax.scss:
--------------------------------------------------------------------------------
1 | .theme-panda-syntax-css-check:before {
2 | content: 'loaded';
3 | display: none;
4 | }
5 |
6 | .extras {
7 | .icon {
8 | svg {
9 | fill: #fff;
10 | }
11 |
12 | &:hover {
13 | background-color: #333;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/extension/themes/dark/panda-syntax/panda-syntax.theme.css:
--------------------------------------------------------------------------------
1 | /*
2 | Name: Panda Syntax
3 | Author: Siamak Mokhtari (http://github.com/siamak/)
4 | CodeMirror template by Siamak Mokhtari (https://github.com/siamak/atom-panda-syntax)
5 | */
6 | .cm-s-panda-syntax {
7 | background: #292A2B;
8 | color: #E6E6E6;
9 | line-height: 1.5;
10 | font-family: 'Operator Mono', 'Source Sans Pro', Menlo, Monaco, Consolas, Courier New, monospace;
11 | }
12 | .cm-s-panda-syntax .CodeMirror-cursor { border-color: #ff2c6d; }
13 | .cm-s-panda-syntax .CodeMirror-activeline-background {
14 | background: rgba(99, 123, 156, 0.1);
15 | }
16 | .cm-s-panda-syntax .CodeMirror-selected {
17 | background: #FFF;
18 | }
19 | .cm-s-panda-syntax .cm-comment {
20 | font-style: italic;
21 | color: #676B79;
22 | }
23 | .cm-s-panda-syntax .cm-operator {
24 | color: #f3f3f3;
25 | }
26 | .cm-s-panda-syntax .cm-string {
27 | color: #19F9D8;
28 | }
29 | .cm-s-panda-syntax .cm-string-2 {
30 | color: #FFB86C;
31 | }
32 |
33 | .cm-s-panda-syntax .cm-tag {
34 | color: #ff2c6d;
35 | }
36 | .cm-s-panda-syntax .cm-meta {
37 | color: #b084eb;
38 | }
39 |
40 | .cm-s-panda-syntax .cm-number {
41 | color: #FFB86C;
42 | }
43 | .cm-s-panda-syntax .cm-atom {
44 | color: #ff2c6d;
45 | }
46 | .cm-s-panda-syntax .cm-keyword {
47 | color: #FF75B5;
48 | }
49 | .cm-s-panda-syntax .cm-variable {
50 | color: #ffb86c;
51 | }
52 | .cm-s-panda-syntax .cm-variable-2 {
53 | color: #ff9ac1;
54 | }
55 | .cm-s-panda-syntax .cm-variable-3 {
56 | color: #ff9ac1;
57 | }
58 |
59 | .cm-s-panda-syntax .cm-def {
60 | color: #e6e6e6;
61 | }
62 | .cm-s-panda-syntax .cm-property {
63 | color: #f3f3f3;
64 | }
65 | .cm-s-panda-syntax .cm-unit {
66 | color: #ffb86c;
67 | }
68 |
69 | .cm-s-panda-syntax .cm-attribute {
70 | color: #ffb86c;
71 | }
72 |
73 | .cm-s-panda-syntax .CodeMirror-matchingbracket {
74 | border-bottom: 1px dotted #19F9D8;
75 | padding-bottom: 2px;
76 | color: #e6e6e6;
77 | }
78 | .cm-s-panda-syntax .CodeMirror-gutters {
79 | background: #292a2b;
80 | border-right-color: rgba(255, 255, 255, 0.1);
81 | }
82 | .cm-s-panda-syntax .CodeMirror-linenumber {
83 | color: #e6e6e6;
84 | opacity: 0.6;
85 | }
86 |
--------------------------------------------------------------------------------
/extension/themes/dark/solarized-dark/solarized-dark.scss:
--------------------------------------------------------------------------------
1 | .theme-solarized_dark-css-check:before {
2 | content: 'loaded';
3 | display: none;
4 | }
5 |
6 | .extras {
7 | .icon {
8 | svg {
9 | fill: #fff;
10 | }
11 |
12 | &:hover {
13 | background-color: #333;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/extension/themes/dark/solarized_dark.js:
--------------------------------------------------------------------------------
1 | require('codemirror/theme/solarized.css');
2 | require('./solarized-dark/solarized-dark.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/dark/tomorrow.js:
--------------------------------------------------------------------------------
1 | require('./tomorrow/tomorrow.theme.css');
2 | require('./tomorrow/tomorrow.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/dark/tomorrow/tomorrow.scss:
--------------------------------------------------------------------------------
1 | .theme-tomorrow-css-check:before {
2 | content: 'loaded';
3 | display: none;
4 | }
5 |
6 | .extras {
7 | .icon {
8 | svg {
9 | fill: #fff;
10 | }
11 |
12 | &:hover {
13 | background-color: #333;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/extension/themes/dark/tomorrow/tomorrow.theme.css:
--------------------------------------------------------------------------------
1 | .cm-s-tomorrow.CodeMirror{background:rgba(45,45,45,1) !important;}
2 | .cm-s-tomorrow.CodeMirror{color:rgba(204,204,204,1) !important;}
3 | .cm-s-tomorrow div.CodeMirror-selected {background: #49483E !important;}
4 | .cm-s-tomorrow.CodeMirror ::selection { background: rgba(73, 72, 62, .99); }
5 | .cm-s-tomorrow.CodeMirror ::-moz-selection { background: rgba(73, 72, 62, .99); }
6 | .cm-s-tomorrow .CodeMirror-gutters{background:rgba(0,0,0,0) !important; border: none;}
7 | .cm-s-tomorrow .CodeMirror-guttermarker{color:rgba(29,117,179,1) !important;}
8 | .cm-s-tomorrow .CodeMirror-guttermarker-subtle{color:#575757 !important;}
9 | .cm-s-tomorrow .CodeMirror-linenumber{color:#575757 !important;}
10 | .cm-s-tomorrow .CodeMirror-cursor{border-color:rgba(204,204,204,1) !important;}
11 | .cm-s-tomorrow span.cm-comment{color:rgba(153,153,153,1) !important;}
12 | .cm-s-tomorrow span.cm-atom{color:rgba(240,141,73,1) !important;}
13 | .cm-s-tomorrow span.cm-number{color:rgba(240,141,73,1) !important;}
14 | .cm-s-tomorrow span.cm-property{color:rgba(204,204,204,1) !important;}
15 | .cm-s-tomorrow span.cm-attribute{color:rgba(204,204,204,1) !important;}
16 | .cm-s-tomorrow span.cm-keyword{color:rgba(204,204,204,1) !important;}
17 | .cm-s-tomorrow span.cm-string{color:rgba(126,198,153,1) !important;}
18 | .cm-s-tomorrow span.cm-string-2{color:rgba(126,198,153,1) !important;}
19 | .cm-s-tomorrow span.cm-variable{color:rgba(204,204,204,1) !important;}
20 | .cm-s-tomorrow span.cm-variable-2{color:rgba(204,204,204,1) !important;}
21 | .cm-s-tomorrow span.cm-def{color:rgba(46,56,60,1) !important;}
22 | .cm-s-tomorrow span.cm-bracket{color:rgba(46,56,60,1) !important;}
23 | .cm-s-tomorrow span.cm-tag{color:rgba(226,119,122,1) !important;}
24 | .cm-s-tomorrow span.cm-link{color:rgba(126,198,153,1) !important;}
25 | .cm-s-tomorrow span.cm-error{background:rgba(0,0,0,0) !important;}
26 | .cm-s-tomorrow span.cm-error{color:rgba(46,56,60,1) !important;}
27 | .cm-s-tomorrow .CodeMirror-activeline-background{color:rgba(46,56,60,1) !important;}
28 | .cm-s-tomorrow .CodeMirror-matchingbracket{color:rgba(0,255,0,1) !important;}
29 |
--------------------------------------------------------------------------------
/extension/themes/dark/twilight.js:
--------------------------------------------------------------------------------
1 | require('./twilight/twilight.theme.css');
2 | require('./twilight/twilight.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/dark/twilight/twilight.scss:
--------------------------------------------------------------------------------
1 | .theme-twilight-css-check:before {
2 | content: 'loaded';
3 | display: none;
4 | }
5 |
6 | .extras {
7 | .icon {
8 | svg {
9 | fill: #fff;
10 | }
11 |
12 | &:hover {
13 | background-color: #333;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/extension/themes/dark/twilight/twilight.theme.css:
--------------------------------------------------------------------------------
1 | .cm-s-twilight.CodeMirror{background:rgba(20,20,20,1) !important;}
2 | .cm-s-twilight.CodeMirror{color:rgba(107,120,120,1) !important;}
3 | .cm-s-twilight div.CodeMirror-selected{background:#434343 !important;}
4 | .cm-s-twilight .CodeMirror-gutters{background:rgba(0,0,0,0) !important; border: none;}
5 | .cm-s-twilight .CodeMirror-guttermarker{color:rgba(29,117,179,1) !important;}
6 | .cm-s-twilight .CodeMirror-guttermarker-subtle{color:#5B5B5B !important;}
7 | .cm-s-twilight .CodeMirror-linenumber{color:#5B5B5B !important;}
8 | .cm-s-twilight .CodeMirror-cursor{border-color:rgba(46,56,60,1) !important;}
9 | .cm-s-twilight span.cm-comment{color:rgba(120,120,112,1) !important;}
10 | .cm-s-twilight span.cm-atom{color:rgba(207,105,73,1) !important;}
11 | .cm-s-twilight span.cm-number{color:rgba(207,105,73,1) !important;}
12 | .cm-s-twilight span.cm-property{color:rgba(255,255,255,1) !important;}
13 | .cm-s-twilight span.cm-attribute{color:rgba(255,255,255,1) !important;}
14 | .cm-s-twilight span.cm-keyword{color:rgba(255,255,255,1) !important;}
15 | .cm-s-twilight span.cm-string{color:rgba(145,158,107,1) !important;}
16 | .cm-s-twilight span.cm-string-2{color:rgba(145,158,107,1) !important;}
17 | .cm-s-twilight span.cm-variable{color:rgba(255,255,255,1) !important;}
18 | .cm-s-twilight span.cm-variable-2{color:rgba(255,255,255,1) !important;}
19 | .cm-s-twilight span.cm-def{color:rgba(46,56,60,1) !important;}
20 | .cm-s-twilight span.cm-bracket{color:rgba(46,56,60,1) !important;}
21 | .cm-s-twilight span.cm-tag{color:rgba(156,51,40,1) !important;}
22 | .cm-s-twilight span.cm-link{color:rgba(145,158,107,1) !important;}
23 | .cm-s-twilight span.cm-error{background:rgba(0,0,0,0) !important;}
24 | .cm-s-twilight span.cm-error{color:rgba(46,56,60,1) !important;}
25 | .cm-s-twilight .CodeMirror-activeline-background{color:rgba(46,56,60,1) !important;}
26 | .cm-s-twilight .CodeMirror-matchingbracket{color:rgba(0,255,0,1) !important;}
27 |
--------------------------------------------------------------------------------
/extension/themes/dark/zenburn.js:
--------------------------------------------------------------------------------
1 | require('codemirror/theme/zenburn.css');
2 | require('./zenburn/zenburn.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/dark/zenburn/zenburn.scss:
--------------------------------------------------------------------------------
1 | .cm-s-zenburn .CodeMirror-gutters{border: none;}
2 |
3 | .theme-zenburn-css-check:before {
4 | content: 'loaded';
5 | display: none;
6 | }
7 |
8 | .extras {
9 | .icon {
10 | svg {
11 | fill: #fff;
12 | }
13 |
14 | &:hover {
15 | background-color: #333;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/extension/themes/light/base16-light.js:
--------------------------------------------------------------------------------
1 | require('codemirror/theme/base16-light.css');
2 | require('./base16-light/base16-light.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/light/base16-light/base16-light.scss:
--------------------------------------------------------------------------------
1 | .theme-base16-light-css-check:before {
2 | content: 'loaded';
3 | display: none;
4 | }
5 |
--------------------------------------------------------------------------------
/extension/themes/light/coy.js:
--------------------------------------------------------------------------------
1 | require('./coy/coy.theme.css');
2 | require('./coy/coy.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/light/coy/coy.scss:
--------------------------------------------------------------------------------
1 | .theme-coy-css-check:before {
2 | content: 'loaded';
3 | display: none;
4 | }
5 |
--------------------------------------------------------------------------------
/extension/themes/light/coy/coy.theme.css:
--------------------------------------------------------------------------------
1 | .cm-s-coy.CodeMirror{
2 | background-color: #fdfdfd;
3 | background-image: -webkit-linear-gradient(transparent 50%, rgba(69, 142, 209, 0.04) 50%);
4 | background-image: -moz-linear-gradient(transparent 50%, rgba(69, 142, 209, 0.04) 50%);
5 | background-image: -ms-linear-gradient(transparent 50%, rgba(69, 142, 209, 0.04) 50%);
6 | background-image: -o-linear-gradient(transparent 50%, rgba(69, 142, 209, 0.04) 50%);
7 | background-image: linear-gradient(transparent 50%, rgba(69, 142, 209, 0.04) 50%);
8 | background-size: 3em 3em;
9 | background-origin:content-box;
10 | }
11 | .cm-s-coy.CodeMirror{color:rgba(95,99,100,1) !important;}
12 | .cm-s-coy div.CodeMirror-selected{background:rgba(217,217,217,1) !important;}
13 | .cm-s-coy .CodeMirror-gutters{
14 | background:rgba(0,0,0,0) !important;
15 | -webkit-box-shadow: -1px 0px 0px 0px #358ccb, 0px 0px 0px 1px #dfdfdf;
16 | -moz-box-shadow: -1px 0px 0px 0px #358ccb, 0px 0px 0px 1px #dfdfdf;
17 | box-shadow: -1px 0px 0px 0px #358ccb, 0px 0px 0px 1px #dfdfdf;
18 | border-left: 10px solid #358ccb;
19 | }
20 | .cm-s-coy .CodeMirror-guttermarker{color:rgba(29,117,179,1) !important;}
21 | .cm-s-coy .CodeMirror-guttermarker-subtle{color:rgba(224,226,229,1) !important;}
22 | .cm-s-coy .CodeMirror-linenumber{color:rgba(224,226,229,1) !important;}
23 | .cm-s-coy .CodeMirror-cursor{border-color:rgba(46,56,60,1) !important;}
24 | .cm-s-coy span.cm-comment{color:rgba(125,139,153,1) !important;}
25 | .cm-s-coy span.cm-atom{color:rgba(201,44,44,1) !important;}
26 | .cm-s-coy span.cm-number{color:rgba(201,44,44,1) !important;}
27 | .cm-s-coy span.cm-property{color:rgba(243,55,117,1) !important;}
28 | .cm-s-coy span.cm-attribute{color:rgba(46,56,60,1) !important;}
29 | .cm-s-coy span.cm-keyword{color:rgba(243,55,117,1) !important;}
30 | .cm-s-coy span.cm-string{color:rgba(63,152,34,1) !important;}
31 | .cm-s-coy span.cm-string-2{color:rgba(63,152,34,1) !important;}
32 | .cm-s-coy span.cm-variable{color:rgba(243,55,117,1) !important;}
33 | .cm-s-coy span.cm-variable-2{color:rgba(243,55,117,1) !important;}
34 | .cm-s-coy span.cm-def{color:rgba(46,56,60,1) !important;}
35 | .cm-s-coy span.cm-bracket{color:rgba(46,56,60,1) !important;}
36 | .cm-s-coy span.cm-tag{color:rgba(243,55,117,1) !important;}
37 | .cm-s-coy span.cm-link{color:rgba(63,152,34,1) !important;}
38 | .cm-s-coy span.cm-error{background:rgba(0,0,0,0) !important;}
39 | .cm-s-coy span.cm-error{color:rgba(46,56,60,1) !important;}
40 | .cm-s-coy .CodeMirror-activeline-background{color:rgba(46,56,60,1) !important;}
41 | .cm-s-coy .CodeMirror-matchingbracket{color:rgba(0,255,0,1) !important;}
42 |
--------------------------------------------------------------------------------
/extension/themes/light/funky.js:
--------------------------------------------------------------------------------
1 | require('./funky/funky.theme.css');
2 | require('./funky/funky.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/light/funky/funky.scss:
--------------------------------------------------------------------------------
1 | .theme-funky-css-check:before {
2 | content: 'loaded';
3 | display: none;
4 | }
5 |
--------------------------------------------------------------------------------
/extension/themes/light/funky/funky.theme.css:
--------------------------------------------------------------------------------
1 | .cm-s-funky.CodeMirror{
2 | background: url('data:image/svg+xml;charset=utf-8,%0D%0A%0D%0A%0D%0A<%2Fsvg>');
3 | background-size: 1em 1em;
4 | }
5 | .cm-s-funky.CodeMirror{color:rgba(153,153,153,1) !important;}
6 | .cm-s-funky div.CodeMirror-selected{margin-left: 5px; background:rgba(0, 0, 0, 0.6) !important;}
7 | .cm-s-funky .CodeMirror-gutters{background: #000 !important;}
8 | .cm-s-funky .CodeMirror-guttermarker{color:rgba(29,117,179,1) !important;}
9 | .cm-s-funky .CodeMirror-guttermarker-subtle{color:rgba(224,226,229,1) !important;}
10 | .cm-s-funky .CodeMirror-linenumber{color:rgba(224,226,229,1) !important;}
11 | .cm-s-funky .CodeMirror-cursor{border-color:rgba(46,56,60,1) !important;}
12 | .cm-s-funky .CodeMirror-code pre > span {background-color: #000; padding: 1px 5px !important;}
13 | .cm-s-funky span.cm-comment{color:rgba(163,154,144,1) !important;}
14 | .cm-s-funky span.cm-atom{color:rgba(53,204,251,1) !important;}
15 | .cm-s-funky span.cm-number{color:rgba(53,204,251,1) !important;}
16 | .cm-s-funky span.cm-property{color:rgba(248,28,147,1) !important;}
17 | .cm-s-funky span.cm-attribute{color:rgba(248,28,147,1) !important;}
18 | .cm-s-funky span.cm-keyword{color:rgba(248,28,147,1) !important;}
19 | .cm-s-funky span.cm-string{color:rgba(254,251,69,1) !important;}
20 | .cm-s-funky span.cm-string-2{color:rgba(254,251,69,1) !important;}
21 | .cm-s-funky span.cm-variable{color:rgba(248,28,147,1) !important;}
22 | .cm-s-funky span.cm-variable-2{color:rgba(248,28,147,1) !important;}
23 | .cm-s-funky span.cm-def{color:rgba(46,56,60,1) !important;}
24 | .cm-s-funky span.cm-bracket{color:rgba(46,56,60,1) !important;}
25 | .cm-s-funky span.cm-tag{color:rgba(248,28,147,1) !important;}
26 | .cm-s-funky span.cm-link{color:rgba(254,251,69,1) !important;}
27 | .cm-s-funky span.cm-error{background:rgba(0,0,0,0) !important;}
28 | .cm-s-funky span.cm-error{color:rgba(46,56,60,1) !important;}
29 | .cm-s-funky .CodeMirror-activeline-background{color:rgba(46,56,60,1) !important;}
30 | .cm-s-funky .CodeMirror-matchingbracket{color:rgba(0,255,0,1) !important;}
31 |
--------------------------------------------------------------------------------
/extension/themes/light/mdn-like.js:
--------------------------------------------------------------------------------
1 | require('codemirror/theme/mdn-like.css');
2 | require('./mdn-like/mdn-like.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/light/mdn-like/mdn-like.scss:
--------------------------------------------------------------------------------
1 | .theme-mdn-like-css-check:before {
2 | content: 'loaded';
3 | display: none;
4 | }
5 |
--------------------------------------------------------------------------------
/extension/themes/light/neo.js:
--------------------------------------------------------------------------------
1 | require('codemirror/theme/neo.css');
2 | require('./neo/neo.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/light/neo/neo.scss:
--------------------------------------------------------------------------------
1 | .theme-neo-css-check:before {
2 | content: 'loaded';
3 | display: none;
4 | }
5 |
--------------------------------------------------------------------------------
/extension/themes/light/solarized-light/solarized-light.scss:
--------------------------------------------------------------------------------
1 | .theme-solarized_light-css-check:before {
2 | content: 'loaded';
3 | display: none;
4 | }
5 |
6 | .cm-s-solarized.cm-s-light div.CodeMirror-selected {
7 | background: #E2DCC8;
8 | }
9 |
10 | .extras {
11 | .icon {
12 | &:hover {
13 | background-color: #D6D1C0;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/extension/themes/light/solarized_light.js:
--------------------------------------------------------------------------------
1 | require('codemirror/theme/solarized.css');
2 | require('./solarized-light/solarized-light.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/light/yeti.js:
--------------------------------------------------------------------------------
1 | require('./yeti/yeti.theme.css');
2 | require('./yeti/yeti.scss');
3 |
--------------------------------------------------------------------------------
/extension/themes/light/yeti/yeti.scss:
--------------------------------------------------------------------------------
1 | .theme-yeti-css-check:before {
2 | content: 'loaded';
3 | display: none;
4 | }
5 |
--------------------------------------------------------------------------------
/extension/themes/light/yeti/yeti.theme.css:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Name: yeti
4 | Author: Michael Kaminsky (http://github.com/mkaminsky11)
5 |
6 | Original yeti color scheme by Jesse Weed (https://github.com/jesseweed/yeti-syntax)
7 |
8 | */
9 |
10 |
11 | .cm-s-yeti.CodeMirror {
12 | background-color: #ECEAE8 !important;
13 | color: #d1c9c0 !important;
14 | border: none;
15 | }
16 |
17 | .cm-s-yeti .CodeMirror-gutters{
18 | color: #adaba6;
19 | background-color: #E5E1DB;
20 | border: none;
21 | }
22 | .cm-s-yeti .CodeMirror-cursor {
23 | border-left: solid thin #d1c9c0 !important;
24 | }
25 | .cm-s-yeti .CodeMirror-linenumber {
26 | color: #adaba6;
27 | }
28 | .cm-s-yeti.CodeMirror-focused .CodeMirror-selected {
29 | background: #DCD8D2;
30 | }
31 | .cm-s-yeti .CodeMirror-line::selection, .cm-s-yeti .CodeMirror-line > span::selection, .cm-s-yeti .CodeMirror-line > span > span::selection {
32 | background: #DCD8D2;
33 | }
34 | .cm-s-yeti .CodeMirror-line::-moz-selection, .cm-s-yeti .CodeMirror-line > span::-moz-selection, .cm-s-yeti .CodeMirror-line > span > span::-moz-selection {
35 | background: #DCD8D2;
36 | }
37 | .cm-s-yeti span.cm-comment {
38 | color: #d4c8be;
39 | }
40 | .cm-s-yeti span.cm-string, .cm-s-yeti span.cm-string-2 {
41 | color: #96c0d8;
42 | }
43 | .cm-s-yeti span.cm-number {
44 | color: #9fb96e;
45 | }
46 | .cm-s-yeti span.cm-variable {
47 | color: #55b5db;
48 | }
49 | .cm-s-yeti span.cm-variable-2 {
50 | color: #a074c4;
51 | }
52 | .cm-s-yeti span.cm-def {
53 | color: #55b5db;
54 | }
55 | .cm-s-yeti span.cm-operator {
56 | color: #9fb96e;
57 | }
58 | .cm-s-yeti span.cm-keyword {
59 | color: #9fb96e;
60 | }
61 | .cm-s-yeti span.cm-atom {
62 | color: #55b5db;
63 | }
64 | .cm-s-yeti span.cm-meta {
65 | color: #96c0d8;
66 | }
67 | .cm-s-yeti span.cm-tag {
68 | color: #96c0d8;
69 | }
70 | .cm-s-yeti span.cm-attribute {
71 | color: #9fb96e;
72 | }
73 | .cm-s-yeti span.cm-qualifier {
74 | color: #96c0d8;
75 | }
76 | .cm-s-yeti span.cm-property {
77 | color: #a074c4;
78 | }
79 | .cm-s-yeti span.cm-builtin {
80 | color: #a074c4;
81 | }
82 | .cm-s-yeti span.cm-variable-3 {
83 | color: #96c0d8;
84 | }
85 | .cm-s-yeti .CodeMirror-activeline-background {background: #E7E4E0 !important;}
86 | .cm-s-yeti .CodeMirror-matchingbracket { text-decoration: underline;}
87 |
--------------------------------------------------------------------------------
/lib/build-extension-webpack-plugin/build-extension.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs-extra');
2 | var path = require('path');
3 | var archiver = require('archiver');
4 | var BuildPaths = require('../build-paths');
5 |
6 | function copyTheme(darkness, list) {
7 | var paths = [];
8 | list.forEach(function(theme) {
9 | var themeCSS = theme.replace(/\.js$/, '.css');
10 | var themeCSSPath = 'themes/' + darkness + '/' + theme + '.css';
11 | var themePath = path.join(BuildPaths.EXTENSION, 'assets/' + theme);
12 |
13 | if (fs.existsSync(themePath + '.js') && fs.existsSync(themePath + '.css')) {
14 | fs.removeSync(themePath + '.js');
15 | fs.copySync(themePath + '.css', path.join(BuildPaths.EXTENSION, themeCSSPath));
16 | console.log(' copied: ' + themeCSSPath);
17 | paths.push(themeCSSPath);
18 |
19 | } else {
20 | console.error(' fail to copy: ' + (themePath + '.css'));
21 | }
22 | });
23 |
24 | return paths;
25 | }
26 |
27 | function BuildExtension() {}
28 | BuildExtension.prototype.apply = function(compiler) {
29 | compiler.plugin('done', function() {
30 | console.log('\n');
31 | console.log('-> copying files');
32 | fs.copySync(path.join(BuildPaths.SRC_ROOT, 'icons'), path.join(BuildPaths.EXTENSION, 'icons'));
33 | fs.copySync(path.join(BuildPaths.SRC_ROOT, 'pages'), path.join(BuildPaths.EXTENSION, 'pages'));
34 |
35 | console.log('-> copying themes');
36 |
37 | var availableThemes = compiler.options.themes;
38 | var themesCSSPaths = copyTheme('light', availableThemes.light).
39 | concat(copyTheme('dark', availableThemes.dark));
40 |
41 | var manifest = fs.readJSONSync(path.join(BuildPaths.SRC_ROOT, 'manifest.json'));
42 | manifest.web_accessible_resources = manifest.web_accessible_resources.concat(themesCSSPaths);
43 |
44 | if (process.env.NODE_ENV !== 'production') {
45 | console.log('-> dev version');
46 | manifest.name += ' - dev';
47 | }
48 |
49 | console.log('-> copying manifest.json');
50 | fs.outputJSONSync(path.join(BuildPaths.EXTENSION, 'manifest.json'), manifest);
51 | });
52 | }
53 |
54 | module.exports = BuildExtension;
55 |
--------------------------------------------------------------------------------
/lib/build-extension-webpack-plugin/index.js:
--------------------------------------------------------------------------------
1 | module.exports = require('./build-extension');
2 |
--------------------------------------------------------------------------------
/lib/build-paths/build-paths.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var buildDir = path.join(__dirname, '../../build');
3 |
4 | module.exports = {
5 | SRC_ROOT: path.join(__dirname, '../../extension'),
6 | BUILD_DIR: buildDir,
7 | RELEASE_DIR: path.join(__dirname, '../../pkg'),
8 | EXTENSION: path.join(buildDir, 'json_viewer')
9 | }
10 |
--------------------------------------------------------------------------------
/lib/build-paths/index.js:
--------------------------------------------------------------------------------
1 | module.exports = require('./build-paths');
2 |
--------------------------------------------------------------------------------
/lib/release-script/index.js:
--------------------------------------------------------------------------------
1 | require('./release-script');
2 |
--------------------------------------------------------------------------------
/lib/release-script/release-script.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs-extra');
2 | var path = require('path');
3 | var archiver = require('archiver');
4 | var BuildPaths = require('../build-paths');
5 |
6 | console.log('-> clean up');
7 |
8 | var themesLight = fs.readdirSync(path.join(BuildPaths.EXTENSION, 'themes/light'));
9 | var themesDark = fs.readdirSync(path.join(BuildPaths.EXTENSION, 'themes/dark'));
10 | var themes = themesLight.concat(themesDark);
11 | var themesCount = themes.length + 1; // +1 for default
12 | console.log('-> ' + themesCount + ' themes');
13 |
14 | fs.removeSync(path.join(BuildPaths.EXTENSION, 'assets/viewer-alert.js'));
15 | fs.readdirSync(path.join(BuildPaths.EXTENSION, 'assets')).forEach(function(filename) {
16 | if (themes.indexOf(filename) !== -1) {
17 | console.log(' removed: assets/' + filename);
18 | fs.removeSync(path.join(BuildPaths.EXTENSION, 'assets/' + filename));
19 | }
20 | });
21 |
22 | console.log('-> zipping');
23 | var zipName = 'json_viewer.zip';
24 | var zipPath = path.join(BuildPaths.BUILD_DIR, zipName);
25 | var output = fs.createOutputStream(zipPath);
26 | var archive = archiver('zip');
27 |
28 | archive.pipe(output);
29 | archive.glob('**', { cwd: BuildPaths.EXTENSION, src: ['**'] });
30 |
31 | archive.on("finish", function() {
32 | var manifest = fs.readJSONSync(path.join(BuildPaths.EXTENSION, 'manifest.json'));
33 | var version = manifest.version;
34 |
35 | console.log('-> finishing version: ' + version);
36 | fs.copySync(zipPath, path.join(BuildPaths.RELEASE_DIR, version + '/' + zipName));
37 | console.log('-> done');
38 | });
39 |
40 | archive.finalize();
41 |
--------------------------------------------------------------------------------
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tulios/json-viewer/4195c33f4d06e622befaf1102004e2c478d4b9d8/logo.png
--------------------------------------------------------------------------------
/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "json_viewer",
3 | "description": "The most beautiful and customizable JSON/JSONP highlighter that your eyes have ever seen. Open source at https://github.com/tulios/json-viewer",
4 | "author": "Tulio Ornelas ",
5 | "license": "MIT",
6 | "repository": "https://github.com/tulios/json-viewer",
7 | "private": true,
8 | "dependencies": {
9 | "archiver": "1.2.x",
10 | "clean-webpack-plugin": "0.1.x",
11 | "codemirror": "5.21.x",
12 | "css-loader": "0.14.x",
13 | "extract-text-webpack-plugin": "0.8.x",
14 | "fs-extra": "0.18.x",
15 | "mousetrap": "1.5.x",
16 | "node-libs-browser": "^1.0.0",
17 | "node-sass": "^4.5.3",
18 | "promise": "7.0.x",
19 | "sass-loader": "6.0.x",
20 | "style-loader": "0.18.x",
21 | "sweetalert": "1.0.x",
22 | "webpack": "1.15.x"
23 | },
24 | "scripts": {
25 | "release": "NODE_ENV=production npm run build",
26 | "build": "./node_modules/.bin/webpack --progress --colors && node ./lib/release-script"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tulios/json-viewer/4195c33f4d06e622befaf1102004e2c478d4b9d8/screenshot.png
--------------------------------------------------------------------------------
/tests/test.$.json:
--------------------------------------------------------------------------------
1 | [{"price_range":2,"label":"$$"},{"price_range":3,"label":"$$$"},{"price_range":4,"label":"$$$$"}]
2 |
--------------------------------------------------------------------------------
/tests/test.array.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "city": "Stockholm",
4 | "title": "the capital of Sweden and the most populous city in the Nordic region",
5 | "url": "http://www.stockholm.se/"
6 | },
7 | {
8 | "city": "Copenhagen",
9 | "title": "the capital and most populated city of Denmark",
10 | "url": "http://www.visitcopenhagen.com/"
11 | }
12 | ]
13 |
--------------------------------------------------------------------------------
/tests/test.backslash.json:
--------------------------------------------------------------------------------
1 | {
2 | "triple-backslash": "\\\"99\\\"",
3 | "path": "C:\\foobar\\",
4 | "number": 123,
5 | "foo": "bar"
6 | }
7 |
--------------------------------------------------------------------------------
/tests/test.json:
--------------------------------------------------------------------------------
1 | {
2 | "correct_value:80402000000790837": 80402000000790837,
3 | "number_string": "53061",
4 | "float": 122.80,
5 | "big_float": 1.5034464E+9,
6 | "boolean": true,
7 | "another_boolean": false,
8 | "float_with_exponent": 8.4127988E8,
9 | "correct_value:-122.80402000000790837": -122.80402000000790837,
10 | "integer_positive": 122,
11 | "integer_negative": -122,
12 | "common_array": [1, 2, 3],
13 | "unsorted_array": [5, 1, 7, 3],
14 | "correct_value:[39977290059340801,80402000000790837]": [39977290059340801,80402000000790837],
15 | "correct_value:[-1.39977290059340801,-2.80402000000790837]": [-1.39977290059340801,-2.80402000000790837],
16 | "object": {"name": "answer to life the universe and everything", "value": 42},
17 | "repeated_integer": 122,
18 | "unicode_symbols": "Best Overall Start-up \u2022 2012 Crunchies (TechCrunch Awards)\nBest Bootstrapped Start-up \u2022 2008 Crunchies",
19 | "url_html_encoded": "https://www.facebook.com/GitHub?param1=1¶m2=2",
20 | "url_with_ip": "http://192.168.1.100:8085/api",
21 | "url_with_short_last_octet": "http://192.168.1.1/api",
22 | "url_with_dot": "http://localhost.localnet./api",
23 | "url_localhost": "http://localhost/api",
24 | "url_shortnet": "http://localhost.n/api",
25 | "url_ipv6_1": "http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html",
26 | "url_ipv6_2": "http://[3ffe:2a00:100:7031::1]",
27 | "url_hybrid1": "http://[::192.9.5.5]/api",
28 | "url_hybrid2": "http://[::FFFF:129.144.52.38]:80/api",
29 | "diatrics": "Adaptação os três porém D'Artagnan maléfico",
30 | "path_with_escaped_slash": "\/some\/path\/here",
31 | "unicode_letters": "Quando voc\u00ea vai \u00e0 praia, costuma levar comes e bebes?",
32 | "unicode_slash":"/some_action\u0026key=value",
33 | "chinese_string": "\u6CA1\u6709\u66F4\u591A\u7684\u95EE\u9898",
34 | "korean_string": "\uB354 \uC774\uC0C1 \uBB38\uC81C",
35 | "russian_string": "\u041D\u0435\u0442 \u0431\u043E\u043B\u044C\u0448\u0435 \u043F\u0440\u043E\u0431\u043B\u0435\u043C"
36 | }
37 |
--------------------------------------------------------------------------------
/tests/test.jsonp.fake.json:
--------------------------------------------------------------------------------
1 | {"readme":"# react-router [![Travis][build-badge]][build] [![npm package][npm-badge]][npm]\n\n[`react-router`](https://www.npmjs.com/package/react-router) is a complete routing library for [React](https://facebook.github.io/react).\n\nReact Router keeps your UI in sync with the URL. It has a simple API with powerful features like lazy code loading, dynamic route matching, and location transition handling built right in. Make the URL your first thought, not an after-thought.\n\n[![Coveralls][coveralls-badge]][coveralls]\n[![Discord][discord-badge]][discord]\n\n### Docs & Help\n\n- [Tutorial - Do This First!](https://github.com/reactjs/react-router-tutorial)\n- [Guides and API Docs](https://github.com/reactjs/react-router/tree/master/docs)\n- [Change Log](/CHANGES.md)\n- [Stack Overflow](http://stackoverflow.com/questions/tagged/react-router)\n- [Codepen Boilerplate](http://codepen.io/anon/pen/xwQZdy?editors=001)\n Please use for bug reports\n\n**Older Versions:**\n\n- 0.13.x - [docs](https://github.com/reactjs/react-router/tree/0.13.x/docs/guides) / [code](https://github.com/reactjs/react-router/tree/0.13.x) / [upgrade guide](https://github.com/reactjs/react-router/blob/master/upgrade-guides/v1.0.0.md)\n- 1.0.x - [docs](https://github.com/reactjs/react-router/tree/1.0.x/docs) / [code](https://github.com/reactjs/react-router/tree/1.0.x) / [upgrade guide](https://github.com/reactjs/react-router/blob/master/upgrade-guides/v2.0.0.md)\n\nFor questions and support, please visit [our channel on Reactiflux](https://discord.gg/0ZcbPKXt5bYaNQ46) or [Stack Overflow](http://stackoverflow.com/questions/tagged/react-router). The issue tracker is *exclusively* for bug reports and feature requests.\n\n### Browser Support\n\nWe support all browsers and environments where React runs.\n\n### Installation\n\nUsing [npm](https://www.npmjs.com/):\n\n $ npm install --save react-router\n\nThen with a module bundler like [webpack](https://webpack.github.io/) that supports either CommonJS or ES2015 modules, use as you would anything else:\n\n```js\n// using an ES6 transpiler, like babel\nimport { Router, Route, Link } from 'react-router'\n\n// not using an ES6 transpiler\nvar Router = require('react-router').Router\nvar Route = require('react-router').Route\nvar Link = require('react-router').Link\n```\n\nThe UMD build is also available on [npmcdn](https://npmcdn.com):\n\n```html\n\n```\n\nYou can find the library on `window.ReactRouter`.\n\n### What's it look like?\n\n```js\nimport React from 'react'\nimport { render } from 'react-dom'\nimport { Router, Route, Link, browserHistory } from 'react-router'\n\nconst App = React.createClass({/*...*/})\nconst About = React.createClass({/*...*/})\n// etc.\n\nconst Users = React.createClass({\n render() {\n return (\n \n
Users \n
\n
\n {/* use Link to route around the app */}\n {this.state.users.map(user => (\n {user.name} \n ))}\n \n
\n
\n {this.props.children}\n
\n
\n )\n }\n})\n\nconst User = React.createClass({\n componentDidMount() {\n this.setState({\n // route components are rendered with useful information, like URL params\n user: findUserById(this.props.params.userId)\n })\n },\n\n render() {\n return (\n \n
{this.state.user.name} \n {/* etc. */}\n \n )\n }\n})\n\n// Declarative route configuration (could also load this config lazily\n// instead, all you really need is a single root route, you don't need to\n// colocate the entire config).\nrender((\n \n \n \n \n \n \n \n \n \n), document.body)\n```\n\nSee more in the [Introduction](https://github.com/reactjs/react-router/tree/master/docs/Introduction.md), [Guides](https://github.com/reactjs/react-router/tree/master/docs/guides/README.md), and [Examples](https://github.com/reactjs/react-router/tree/master/examples).\n\n### Versioning and Stability\n\nWe want React Router to be a stable dependency that’s easy to keep current. We follow the same versioning as React.js itself: [React Versioning Scheme](https://facebook.github.io/react/blog/2016/02/19/new-versioning-scheme.html).\n\n### Thanks\n\nThanks to [our sponsors](/SPONSORS.md) for supporting the development of\nReact Router.\n\nReact Router was initially inspired by Ember's fantastic router. Many thanks to the Ember team.\n\nAlso, thanks to [BrowserStack](https://www.browserstack.com/) for providing the infrastructure that allows us to run our build in real browsers.\n\n[build-badge]: https://img.shields.io/travis/reactjs/react-router/master.svg?style=flat-square\n[build]: https://travis-ci.org/reactjs/react-router\n\n[npm-badge]: https://img.shields.io/npm/v/react-router.svg?style=flat-square\n[npm]: https://www.npmjs.org/package/react-router\n\n[coveralls-badge]: https://img.shields.io/coveralls/reactjs/react-router/master.svg?style=flat-square\n[coveralls]: https://coveralls.io/github/reactjs/react-router\n\n[discord-badge]: https://img.shields.io/badge/Discord-join%20chat%20%E2%86%92-738bd7.svg?style=flat-square\n[discord]: https://discord.gg/0ZcbPKXt5bYaNQ46\n"}
2 |
--------------------------------------------------------------------------------
/tests/test.jsonp.for.json:
--------------------------------------------------------------------------------
1 | for(;;);{"anoying-security": true}
2 |
--------------------------------------------------------------------------------
/tests/test.jsonp.json:
--------------------------------------------------------------------------------
1 | /**/ XY.__callback.f1c77f051c({
2 | "correct_value:80402000000790837": 80402000000790837,
3 | "number_string": "53061",
4 | "float": 122.80,
5 | "boolean": true,
6 | "another_boolean": false,
7 | "float_with_exponent": 8.4127988E8,
8 | "correct_value:-122.80402000000790837": -122.80402000000790837,
9 | "integer_positive": 122,
10 | "integer_negative": -122,
11 | "common_array": [1, 2, 3],
12 | "unsorted_array": [5, 1, 7, 3],
13 | "correct_value:[39977290059340801,80402000000790837]": [39977290059340801,80402000000790837],
14 | "correct_value:[-1.39977290059340801,-2.80402000000790837]": [-1.39977290059340801,-2.80402000000790837],
15 | "object": {"name": "answer to life the universe and everything", "value": 42},
16 | "repeated_integer": 122,
17 | "unicode_symbols": "Best Overall Start-up \u2022 2012 Crunchies (TechCrunch Awards)\nBest Bootstrapped Start-up \u2022 2008 Crunchies",
18 | "url_html_encoded": "https://www.facebook.com/GitHub?param1=1¶m2=2",
19 | "url_with_ip": "http://192.168.1.100:8085/api",
20 | "diatrics": "Adaptação os três porém D'Artagnan maléfico",
21 | "path_with_escaped_slash": "\/some\/path\/here",
22 | "unicode_letters": "Quando voc\u00ea vai \u00e0 praia, costuma levar comes e bebes?",
23 | "unicode_slash":"/some_action\u0026key=value",
24 | "chinese_string": "\u6CA1\u6709\u66F4\u591A\u7684\u95EE\u9898",
25 | "korean_string": "\uB354 \uC774\uC0C1 \uBB38\uC81C",
26 | "russian_string": "\u041D\u0435\u0442 \u0431\u043E\u043B\u044C\u0448\u0435 \u043F\u0440\u043E\u0431\u043B\u0435\u043C"
27 | })
28 |
--------------------------------------------------------------------------------
/tests/test.jsonp.spaces.json:
--------------------------------------------------------------------------------
1 | callback( {"key": "value"} )
2 |
--------------------------------------------------------------------------------
/tests/test.jsonp.while.json:
--------------------------------------------------------------------------------
1 | while(1);{"anoying-security": true}
2 |
--------------------------------------------------------------------------------
/tests/test.onlyString.json:
--------------------------------------------------------------------------------
1 | "This is a string"
2 |
--------------------------------------------------------------------------------
/tests/test2.json:
--------------------------------------------------------------------------------
1 | {"DATA":[[90,"ERROR(err)"]]}
2 |
--------------------------------------------------------------------------------
/tryitnow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tulios/json-viewer/4195c33f4d06e622befaf1102004e2c478d4b9d8/tryitnow.png
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | var path = require("path");
2 | var fs = require('fs-extra');
3 | var webpack = require("webpack");
4 | var Clean = require("clean-webpack-plugin");
5 | var BuildPaths = require("./lib/build-paths");
6 | var BuildExtension = require("./lib/build-extension-webpack-plugin");
7 | var ExtractTextPlugin = require("extract-text-webpack-plugin");
8 |
9 | var manifest = fs.readJSONSync(path.join(BuildPaths.SRC_ROOT, 'manifest.json'));
10 | var version = manifest.version;
11 |
12 | var entries = {
13 | viewer: ["./extension/src/viewer.js"],
14 | "viewer-alert": ["./extension/styles/viewer-alert.scss"],
15 | options: ["./extension/src/options.js"],
16 | backend: ["./extension/src/backend.js"],
17 | omnibox: ["./extension/src/omnibox.js"],
18 | "omnibox-page": ["./extension/src/omnibox-page.js"]
19 | };
20 |
21 | function findThemes(darkness) {
22 | return fs.readdirSync(path.join('extension', 'themes', darkness)).
23 | filter(function(filename) {
24 | return /\.js$/.test(filename);
25 | }).
26 | map(function(theme) {
27 | return theme.replace(/\.js$/, '');
28 | });
29 | }
30 |
31 | function includeThemes(darkness, list) {
32 | list.forEach(function(filename) {
33 | entries[filename] = ["./extension/themes/" + darkness + "/" + filename + ".js"];
34 | });
35 | }
36 |
37 | var lightThemes = findThemes('light');
38 | var darkThemes = findThemes('dark');
39 | var themes = {light: lightThemes, dark: darkThemes};
40 |
41 | includeThemes('light', lightThemes);
42 | includeThemes('dark', darkThemes);
43 |
44 | console.log("Entries list:");
45 | console.log(entries);
46 | console.log("\n");
47 |
48 | var manifest = {
49 | debug: false,
50 | context: __dirname,
51 | entry: entries,
52 | themes: themes,
53 | output: {
54 | path: path.join(__dirname, "build/json_viewer/assets"),
55 | filename: "[name].js"
56 | },
57 | module: {
58 | loaders: [
59 | {test: /\.(css|scss)$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader!sass-loader")}
60 | ]
61 | },
62 | resolve: {
63 | extensions: ['', '.js', '.css', '.scss'],
64 | root: path.resolve(__dirname, './extension'),
65 | },
66 | externals: [
67 | {
68 | "chrome-framework": "chrome"
69 | }
70 | ],
71 | plugins: [
72 | new Clean(["build"]),
73 | new ExtractTextPlugin("[name].css", {allChunks: true}),
74 | new webpack.DefinePlugin({
75 | "process.env": {
76 | NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'development'),
77 | VERSION: JSON.stringify(version),
78 | THEMES: JSON.stringify(themes)
79 | }
80 | }),
81 | new BuildExtension()
82 | ]
83 | };
84 |
85 | if (process.env.NODE_ENV === 'production') {
86 | manifest.plugins.push(new webpack.optimize.UglifyJsPlugin({sourceMap: false}));
87 | manifest.plugins.push(new webpack.optimize.DedupePlugin());
88 | manifest.plugins.push(new webpack.NoErrorsPlugin());
89 | }
90 |
91 | module.exports = manifest;
92 |
--------------------------------------------------------------------------------