History

Fix merge conflict

Jasper van Merle committed 8 years ago

Commit 536fa352 parents e894a2f e8d52c9175 files · +2496 −1111Browse files

Unified · Split

175 files
  1. .editorconfig +8 −0
  2. .travis.yml +3 −0
  3. Dockerfile +2 −0
  4. Dockerfile-alpine +2 −0
  5. Gemfile +1 −0
  6. Gemfile.lock +31 −27
  7. README.md +4 −8
  8. assets/images/docs-2.png +0 −0
  9. assets/images/docs-2@2x.png +0 −0
  10. assets/javascripts/app/app.coffee +1 −6
  11. assets/javascripts/app/shortcuts.coffee +3 −0
  12. assets/javascripts/lib/page.coffee +1 −1
  13. assets/javascripts/news.json +9 −0
  14. assets/javascripts/templates/error_tmpl.coffee +4 −7
  15. assets/javascripts/templates/pages/about_tmpl.coffee +36 −1
  16. assets/javascripts/templates/pages/help_tmpl.coffee +3 −0
  17. assets/javascripts/templates/pages/root_tmpl.coffee.erb +0 −11
  18. assets/javascripts/vendor/prism.js +633 −352
  19. assets/javascripts/views/content/root_page.coffee +0 −4
  20. assets/javascripts/views/content/settings_page.coffee +3 −4
  21. assets/javascripts/views/search/search.coffee +5 −0
  22. assets/stylesheets/application-dark.css.scss +0 −105
  23. assets/stylesheets/application.css.scss +7 −1
  24. assets/stylesheets/components/_app.scss +5 −5
  25. assets/stylesheets/components/_content.scss +27 −32
  26. assets/stylesheets/components/_fail.scss +2 −2
  27. assets/stylesheets/components/_header.scss +25 −35
  28. assets/stylesheets/components/_mobile.scss +2 −2
  29. assets/stylesheets/components/_notice.scss +5 −5
  30. assets/stylesheets/components/_notif.scss +12 −12
  31. assets/stylesheets/components/_page.scss +4 −4
  32. assets/stylesheets/components/_path.scss +6 −6
  33. assets/stylesheets/components/_prism.scss +25 −32
  34. assets/stylesheets/components/_settings.scss +12 −12
  35. assets/stylesheets/components/_sidebar.scss +37 −39
  36. assets/stylesheets/global/_base.scss +37 −31
  37. assets/stylesheets/global/_classes.scss +24 −25
  38. assets/stylesheets/global/_icons.scss +9 −2
  39. assets/stylesheets/global/_mixins.scss +6 −0
  40. assets/stylesheets/global/_print.scss +2 −2
  41. assets/stylesheets/global/_variables-dark.scss +53 −69
  42. assets/stylesheets/global/_variables-light.scss +76 −0
  43. assets/stylesheets/global/_variables.scss +25 −82
  44. assets/stylesheets/pages/_angularjs.scss +1 −1
  45. assets/stylesheets/pages/_async.scss +2 −2
  46. assets/stylesheets/pages/_bash.scss +12 −0
  47. assets/stylesheets/pages/_bootstrap.scss +1 −1
  48. assets/stylesheets/pages/_c.scss +2 −2
  49. assets/stylesheets/pages/_clojure.scss +1 −1
  50. assets/stylesheets/pages/_d.scss +3 −3
  51. assets/stylesheets/pages/_dart.scss +12 −0
  52. assets/stylesheets/pages/_dojo.scss +1 −1
  53. assets/stylesheets/pages/_ember.scss +2 −2
  54. assets/stylesheets/pages/_erlang.scss +1 −1
  55. assets/stylesheets/pages/_graphite.scss +7 −0
  56. assets/stylesheets/pages/_jquery.scss +2 −2
  57. assets/stylesheets/pages/_love.scss +2 −2
  58. assets/stylesheets/pages/_mdn.scss +3 −3
  59. assets/stylesheets/pages/_meteor.scss +2 −2
  60. assets/stylesheets/pages/_npm.scss +1 −1
  61. assets/stylesheets/pages/_phalcon.scss +1 −1
  62. assets/stylesheets/pages/_php.scss +2 −2
  63. assets/stylesheets/pages/_postgres.scss +1 −1
  64. assets/stylesheets/pages/_qt.scss +9 −0
  65. assets/stylesheets/pages/_rdoc.scss +4 −4
  66. assets/stylesheets/pages/_react_native.scss +1 −1
  67. assets/stylesheets/pages/_redis.scss +2 −2
  68. assets/stylesheets/pages/_rfc.scss +1 −1
  69. assets/stylesheets/pages/_rust.scss +10 −1
  70. assets/stylesheets/pages/_simple.scss +1 −31
  71. assets/stylesheets/pages/_sphinx.scss +2 −2
  72. assets/stylesheets/pages/_sphinx_simple.scss +1 −1
  73. assets/stylesheets/pages/_support_tables.scss +1 −1
  74. assets/stylesheets/pages/_yard.scss +1 −1
  75. assets/stylesheets/pages/_yii.scss +1 −1
  76. lib/app.rb +2 −16
  77. lib/docs/filters/bash/clean_html.rb +74 −0
  78. lib/docs/filters/bash/entries.rb +56 −0
  79. lib/docs/filters/dart/clean_html.rb +66 −0
  80. lib/docs/filters/dart/entries.rb +42 −0
  81. lib/docs/filters/dom/entries.rb +3 −0
  82. lib/docs/filters/elixir/clean_html.rb +1 −0
  83. lib/docs/filters/express/clean_html.rb +5 −0
  84. lib/docs/filters/graphite/clean_html.rb +27 −0
  85. lib/docs/filters/graphite/entries.rb +46 −0
  86. lib/docs/filters/handlebars/clean_html.rb +44 −0
  87. lib/docs/filters/handlebars/entries.rb +19 −0
  88. lib/docs/filters/puppeteer/clean_html.rb +24 −0
  89. lib/docs/filters/puppeteer/entries.rb +41 −0
  90. lib/docs/filters/pygame/clean_html.rb +102 −0
  91. lib/docs/filters/pygame/entries.rb +29 −0
  92. lib/docs/filters/python/clean_html.rb +5 −3
  93. lib/docs/filters/python/entries_v3.rb +12 −10
  94. lib/docs/filters/qt/clean_html.rb +31 −0
  95. lib/docs/filters/qt/entries.rb +141 −0
  96. lib/docs/filters/redis/entries.rb +2 −1
  97. lib/docs/filters/rust/clean_html.rb +37 −6
  98. lib/docs/filters/rust/entries.rb +8 −5
  99. lib/docs/filters/typescript/entries.rb +1 −0
  100. lib/docs/scrapers/apache.rb +1 −1
  101. lib/docs/scrapers/apache_pig.rb +1 −1
  102. lib/docs/scrapers/bash.rb +21 −0
  103. lib/docs/scrapers/bootstrap.rb +1 −1
  104. lib/docs/scrapers/bower.rb +1 −1
  105. lib/docs/scrapers/chai.rb +1 −1
  106. lib/docs/scrapers/cmake.rb +12 −2
  107. lib/docs/scrapers/codeceptjs.rb +1 −1
  108. lib/docs/scrapers/crystal.rb +1 −1
  109. lib/docs/scrapers/dart.rb +37 −0
  110. lib/docs/scrapers/django.rb +6 −0
  111. lib/docs/scrapers/docker.rb +1 −1
  112. lib/docs/scrapers/electron.rb +1 −1
  113. lib/docs/scrapers/elixir.rb +13 −0
  114. lib/docs/scrapers/express.rb +1 −1
  115. lib/docs/scrapers/fish.rb +1 −1
  116. lib/docs/scrapers/flow.rb +2 −2
  117. lib/docs/scrapers/gnu.rb +1 −1
  118. lib/docs/scrapers/graphite.rb +21 −0
  119. lib/docs/scrapers/grunt.rb +1 −1
  120. lib/docs/scrapers/handlebars.rb +23 −0
  121. lib/docs/scrapers/haxe.rb +1 −1
  122. lib/docs/scrapers/immutable.rb +1 −1
  123. lib/docs/scrapers/influxdata.rb +1 −1
  124. lib/docs/scrapers/jasmine.rb +3 −3
  125. lib/docs/scrapers/jest.rb +2 −2
  126. lib/docs/scrapers/julia.rb +22 −2
  127. lib/docs/scrapers/laravel.rb +14 −1
  128. lib/docs/scrapers/less.rb +1 −1
  129. lib/docs/scrapers/lodash.rb +1 −1
  130. lib/docs/scrapers/marionette.rb +8 −1
  131. lib/docs/scrapers/markdown.rb +1 −1
  132. lib/docs/scrapers/mocha.rb +1 −1
  133. lib/docs/scrapers/mongoose.rb +1 −1
  134. lib/docs/scrapers/nim.rb +1 −1
  135. lib/docs/scrapers/node.rb +3 −3
  136. lib/docs/scrapers/npm.rb +1 −1
  137. lib/docs/scrapers/php.rb +1 −1
  138. lib/docs/scrapers/puppeteer.rb +18 −0
  139. lib/docs/scrapers/pygame.rb +20 −0
  140. lib/docs/scrapers/qt.rb +121 −0
  141. lib/docs/scrapers/redis.rb +1 −1
  142. lib/docs/scrapers/redux.rb +1 −1
  143. lib/docs/scrapers/requirejs.rb +1 −1
  144. lib/docs/scrapers/rust.rb +5 −5
  145. lib/docs/scrapers/typescript.rb +2 −2
  146. lib/docs/scrapers/vagrant.rb +1 −1
  147. lib/docs/scrapers/vulkan.rb +1 −1
  148. lib/docs/scrapers/webpack.rb +1 −1
  149. lib/docs/scrapers/yarn.rb +2 −2
  150. lib/tasks/docs.thor +6 −2
  151. public/icons/docs-2.pxm +0 −0
  152. public/icons/docs-2@2x.pxm +0 −0
  153. public/icons/docs/bash/16.png +0 −0
  154. public/icons/docs/bash/16@2x.png +0 −0
  155. public/icons/docs/bash/SOURCE +1 −0
  156. public/icons/docs/dart/16.png +0 −0
  157. public/icons/docs/dart/16@2x.png +0 −0
  158. public/icons/docs/dart/SOURCE +1 −0
  159. public/icons/docs/handlebars/16.png +0 −0
  160. public/icons/docs/handlebars/16@2x.png +0 −0
  161. public/icons/docs/handlebars/SOURCE +1 −0
  162. public/icons/docs/puppeteer/16.png +0 −0
  163. public/icons/docs/puppeteer/16@2x.png +0 −0
  164. public/icons/docs/puppeteer/SOURCE +1 −0
  165. public/icons/docs/pygame/16.png +0 −0
  166. public/icons/docs/pygame/16@2x.png +0 −0
  167. public/icons/docs/qt/16.png +0 −0
  168. public/icons/docs/qt/16@2x.png +0 −0
  169. public/icons/docs/qt/SOURCE +1 −0
  170. public/images/webapp-icon-512.png +0 −0
  171. public/manifest.json +5 −0
  172. test/app_test.rb +43 −21
  173. views/index.erb +2 −2
  174. views/other.erb +2 −2
  175. views/unsupported.erb +4 −7
.editorconfig+8−0
@@ -0,0 +1,8 @@
1+root = true
2+
3+[*]
4+charset = utf-8
5+indent_style = space
6+indent_size = 2
7+insert_final_newline = true
8+trim_trailing_whitespace = true
.travis.yml+3−0
@@ -1,4 +1,7 @@
11 language: ruby
2+
3+cache: bundler
4+
25 before_script:
36 - gem update --system
47 - gem install bundler
Dockerfile+2−0
@@ -1,5 +1,7 @@
11 FROM ruby:2.5.1
22
3+ENV LANG=C.UTF-8
4+
35 WORKDIR /devdocs
46
57 RUN apt-get update && \
Dockerfile-alpine+2−0
@@ -1,5 +1,7 @@
11 FROM ruby:2.5.1-alpine
22
3+ENV LANG=C.UTF-8
4+
35 WORKDIR /devdocs
46
57 COPY . /devdocs
Gemfile+1−0
@@ -11,6 +11,7 @@ group :app do · 10 unmodified lines
1111 gem 'rack'
1212 gem 'sinatra'
1313 gem 'sinatra-contrib'
14+ gem 'rack-ssl-enforcer'
1415 gem 'thin'
1516 gem 'sprockets'
1617 gem 'sprockets-helpers'
Gemfile.lock+31−27
@@ -1,13 +1,13 @@
11 GEM
22 remote: https://rubygems.org/
33 specs:
4− activesupport (5.2.0)
4+ activesupport (5.2.1)
55 concurrent-ruby (~> 1.0, >= 1.0.2)
66 i18n (>= 0.7, < 2)
77 minitest (~> 5.1)
88 tzinfo (~> 1.1)
9− backports (3.11.3)
10− better_errors (2.4.0)
9+ backports (3.11.4)
10+ better_errors (2.5.0)
1111 coderay (>= 1.0.0)
1212 erubi (>= 1.0.0)
1313 rack (>= 0.9.0)
@@ -27,75 +27,78 @@ GEM · 13 unmodified lines
2727 exifr (1.3.4)
2828 ffi (1.9.25)
2929 fspath (3.1.0)
30− highline (1.7.10)
31− html-pipeline (2.8.3)
30+ highline (2.0.0)
31+ html-pipeline (2.8.4)
3232 activesupport (>= 2)
3333 nokogiri (>= 1.4)
34− i18n (1.0.1)
34+ i18n (1.1.0)
3535 concurrent-ruby (~> 1.0)
36− image_optim (0.26.1)
36+ image_optim (0.26.2)
3737 exifr (~> 1.2, >= 1.2.2)
3838 fspath (~> 3.0)
39− image_size (~> 1.5)
39+ image_size (>= 1.5, < 3)
4040 in_threads (~> 1.3)
4141 progress (~> 3.0, >= 3.0.1)
4242 image_optim_pack (0.5.1)
4343 fspath (>= 2.1, < 4)
4444 image_optim (~> 0.19)
45− image_size (1.5.0)
45+ image_size (2.0.0)
4646 in_threads (1.5.0)
4747 method_source (0.9.0)
4848 mini_portile2 (2.3.0)
4949 minitest (5.11.3)
5050 multi_json (1.13.1)
51− mustermann (1.0.2)
52− newrelic_rpm (5.2.0.345)
51+ mustermann (1.0.3)
52+ newrelic_rpm (5.4.0.347)
5353 nokogiri (1.8.4)
5454 mini_portile2 (~> 2.3.0)
5555 options (2.3.2)
5656 progress (3.4.0)
57− progress_bar (1.2.0)
58− highline (~> 1.6)
57+ progress_bar (1.3.0)
58+ highline (>= 1.6, < 3)
5959 options (~> 2.3.0)
6060 pry (0.11.3)
6161 coderay (~> 1.1.0)
6262 method_source (~> 0.9.0)
6363 rack (2.0.5)
64− rack-protection (2.0.3)
64+ rack-protection (2.0.4)
6565 rack
66− rack-test (1.0.0)
66+ rack-ssl-enforcer (0.2.9)
67+ rack-test (1.1.0)
6768 rack (>= 1.0, < 3)
6869 rake (12.3.1)
6970 rb-fsevent (0.10.3)
7071 rb-inotify (0.9.10)
7172 ffi (>= 0.5.0, < 2)
7273 rr (1.2.1)
73− sass (3.5.6)
74+ sass (3.6.0)
7475 sass-listen (~> 4.0.0)
7576 sass-listen (4.0.0)
7677 rb-fsevent (~> 0.9, >= 0.9.4)
7778 rb-inotify (~> 0.9, >= 0.9.7)
78− sinatra (2.0.3)
79+ sinatra (2.0.4)
7980 mustermann (~> 1.0)
8081 rack (~> 2.0)
81− rack-protection (= 2.0.3)
82+ rack-protection (= 2.0.4)
8283 tilt (~> 2.0)
83− sinatra-contrib (2.0.3)
84+ sinatra-contrib (2.0.4)
8485 activesupport (>= 4.0.0)
8586 backports (>= 2.8.2)
8687 multi_json
8788 mustermann (~> 1.0)
88− rack-protection (= 2.0.3)
89− sinatra (= 2.0.3)
89+ rack-protection (= 2.0.4)
90+ sinatra (= 2.0.4)
9091 tilt (>= 1.3, < 3)
9192 sprockets (3.7.2)
9293 concurrent-ruby (~> 1.0)
9394 rack (> 1, < 3)
9495 sprockets-helpers (1.2.1)
9596 sprockets (>= 2.2)
96− strings (0.1.1)
97− unicode-display_width (~> 1.3.0)
97+ strings (0.1.4)
98+ strings-ansi (~> 0.1.0)
99+ unicode-display_width (~> 1.4.0)
98100 unicode_utils (~> 1.4.0)
101+ strings-ansi (0.1.0)
99102 thin (1.7.2)
100103 daemons (~> 1.0, >= 1.0.9)
101104 eventmachine (~> 1.0, >= 1.0.4)
@@ -107,18 +110,18 @@ GEM · 5 unmodified lines
107110 strings (~> 0.1.0)
108111 tty-screen (~> 0.6.4)
109112 tty-which (~> 0.3.0)
110− tty-screen (0.6.4)
113+ tty-screen (0.6.5)
111114 tty-which (0.3.0)
112115 typhoeus (1.3.0)
113116 ethon (>= 0.9.0)
114117 tzinfo (1.2.5)
115118 thread_safe (~> 0.1)
116− uglifier (4.1.14)
119+ uglifier (4.1.19)
117120 execjs (>= 0.3.0, < 3)
118− unicode-display_width (1.3.3)
121+ unicode-display_width (1.4.0)
119122 unicode_utils (1.4.0)
120123 unix_utils (0.0.15)
121− yajl-ruby (1.4.0)
124+ yajl-ruby (1.4.1)
122125
123126 PLATFORMS
124127 ruby
@@ -138,6 +141,7 @@ DEPENDENCIES · 13 unmodified lines
138141 progress_bar
139142 pry (~> 0.11.0)
140143 rack
144+ rack-ssl-enforcer
141145 rack-test
142146 rake
143147 rr
README.md+4−8
@@ -64,14 +64,10 @@ Another driving factor is performance and the fact that everything happens in th · 63 unmodified lines
6464
6565 DevDocs being a developer tool, the browser requirements are high:
6666
67−1. On the desktop:
68− * Recent version of Chrome, Firefox, or Opera
69− * Safari 8+
70− * IE / Edge 10+
71−2. On mobile:
72− * iOS 8+
73− * Android 4.1+
74− * Windows Phone 8+
67+* Recent versions of Firefox, Chrome, or Opera
68+* Safari 9.1+
69+* Edge 16+
70+* iOS 10+
7571
7672 This allows the code to take advantage of the latest DOM and HTML5 APIs and make developing DevDocs a lot more fun!
7773
assets/images/docs-2.png+0−0

Binary file not shown.

assets/images/docs-2@2x.png+0−0

Binary file not shown.

assets/javascripts/app/app.coffee+1−6
@@ -245,7 +245,7 @@ · 244 unmodified lines
245245 matchMedia: !!window.matchMedia
246246 insertAdjacentHTML: !!document.body.insertAdjacentHTML
247247 defaultPrevented: document.createEvent('CustomEvent').defaultPrevented is false
248− cssGradients: supportsCssGradients()
248+ cssVariables: CSS.supports and CSS.supports('(--t: 0)')
249249
250250 for key, value of features when not value
251251 Raven.captureMessage "unsupported/#{key}", level: 'info'
@@ -268,9 +268,4 @@ · 16 unmodified lines
268268 isInvalidLocation: ->
269269 @config.env is 'production' and location.host.indexOf(app.config.production_host) isnt 0
270270
271−supportsCssGradients = ->
272− el = document.createElement('div')
273− el.style.cssText = "background-image: -webkit-linear-gradient(top, #000, #fff); background-image: linear-gradient(to top, #000, #fff);"
274− el.style.backgroundImage.indexOf('gradient') >= 0
275−
276271 $.extend app, Events
assets/javascripts/app/shortcuts.coffee+3−0
@@ -149,6 +149,9 @@ class app.Shortcuts · 148 unmodified lines
149149 when 40
150150 @trigger 'altDown'
151151 false
152+ when 68
153+ @trigger 'altD'
154+ false
152155 when 70
153156 @trigger 'altF', event
154157 when 71
assets/javascripts/lib/page.coffee+1−1
@@ -190,7 +190,7 @@ isSameOrigin = (url) -> · 189 unmodified lines
190190
191191 updateCanonicalLink = ->
192192 @canonicalLink ||= document.head.querySelector('link[rel="canonical"]')
193− @canonicalLink.setAttribute('href', "http://#{location.host}#{location.pathname}")
193+ @canonicalLink.setAttribute('href', "https://#{location.host}#{location.pathname}")
194194
195195 trackers = []
196196
assets/javascripts/news.json+9−0
@@ -1,5 +1,14 @@
11 [
22 [
3+ "2018-09-23",
4+ "New documentations: <a href=\"/puppeteer/\">Puppeteer</a> and <a href=\"/handlebars/\">Handlebars.js</a>"
5+ ], [
6+ "2018-08-12",
7+ "New documentations: <a href=\"/dart/\">Dart</a> and <a href=\"/qt/\">Qt</a>"
8+ ], [
9+ "2018-07-29",
10+ "New documentations: <a href=\"/bash/\">Bash</a>, <a href=\"/graphite/\">Graphite</a> and <a href=\"/pygame/\">Pygame</a>"
11+ ], [
312 "2018-07-08",
413 "New documentations: <a href=\"/leaflet/\">Leaflet</a>, <a href=\"/terraform/\">Terraform</a> and <a href=\"/koa/\">Koa</a>"
514 ], [
assets/javascripts/templates/error_tmpl.coffee+4−7
@@ -56,13 +56,10 @@ app.templates.unsupportedBrowser = """ · 55 unmodified lines
5656 <h1 class="_fail-title">Your browser is unsupported, sorry.</h1>
5757 <p class="_fail-text">DevDocs is an API documentation browser which supports the following browsers:
5858 <ul class="_fail-list">
59− <li>Recent versions of Chrome and Firefox
60− <li>Safari 5.1+
61− <li>Opera 12.1+
62− <li>Internet Explorer 10+
63− <li>iOS 6+
64− <li>Android 4.1+
65− <li>Windows Phone 8+
59+ <li>Recent versions of Firefox, Chrome, or Opera
60+ <li>Safari 9.1+
61+ <li>Edge 16+
62+ <li>iOS 10+
6663 </ul>
6764 <p class="_fail-text">
6865 If you're unable to upgrade, I apologize.
assets/javascripts/templates/pages/about_tmpl.coffee+36−1
@@ -115,6 +115,11 @@ credits = [ · 114 unmodified lines
115115 '2010-2016 Jeremy Ashkenas, DocumentCloud',
116116 'MIT',
117117 'https://raw.githubusercontent.com/jashkenas/backbone/master/LICENSE'
118+ ], [
119+ 'Bash',
120+ '2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.',
121+ 'GFDL',
122+ 'https://www.gnu.org/licenses/fdl-1.3.en.html'
118123 ], [
119124 'Bluebird',
120125 '2013-2017 Petka Antonov',
@@ -162,7 +167,7 @@ credits = [ · 41 unmodified lines
162167 'https://github.com/clojure/clojure/blob/master/epl-v10.html'
163168 ], [
164169 'CMake',
165− '2000-2017 Kitware, Inc. and Contributors',
170+ '2000-2018 Kitware, Inc. and Contributors',
166171 'BSD',
167172 'https://cmake.org/licensing/'
168173 ], [
@@ -210,6 +215,11 @@ credits = [ · 41 unmodified lines
210215 '2010-2018 Michael Bostock',
211216 'BSD',
212217 'https://raw.githubusercontent.com/d3/d3/master/LICENSE'
218+ ], [
219+ 'Dart',
220+ '2012 the Dart project authors',
221+ 'CC BY-SA',
222+ 'https://creativecommons.org/licenses/by-sa/4.0/'
213223 ], [
214224 'Django',
215225 'Django Software Foundation and individual contributors',
@@ -290,11 +300,21 @@ credits = [ · 74 unmodified lines
290300 '2014-2018 Juan Linietsky, Ariel Manzur, Godot Engine contributors',
291301 'MIT',
292302 'https://raw.githubusercontent.com/godotengine/godot/master/LICENSE.txt'
303+ ], [
304+ 'Graphite',
305+ '2008-2012 Chris Davis<br>&copy; 2011-2016 The Graphite Project',
306+ 'Apache',
307+ 'https://raw.githubusercontent.com/graphite-project/graphite-web/master/LICENSE'
293308 ], [
294309 'Grunt',
295310 'GruntJS Team',
296311 'MIT',
297312 'https://github.com/gruntjs/grunt-docs/blob/master/package.json#L10'
313+ ], [
314+ 'Handlebars',
315+ '2011-2017 Yehuda Katz',
316+ 'MIT',
317+ 'https://raw.githubusercontent.com/wycats/handlebars.js/master/LICENSE'
298318 ], [
299319 'Haskell',
300320 'The University of Glasgow',
@@ -550,6 +570,16 @@ credits = [ · 249 unmodified lines
550570 '1996-2018 The PostgreSQL Global Development Group<br>&copy; 1994 The Regents of the University of California',
551571 'PostgreSQL',
552572 'https://www.postgresql.org/about/licence/'
573+ ], [
574+ 'Puppeteer',
575+ '2017 Google Inc',
576+ 'Apache',
577+ 'https://raw.githubusercontent.com/GoogleChrome/puppeteer/master/LICENSE'
578+ ], [
579+ 'Pygame',
580+ 'Pygame Developpers',
581+ 'LGPLv2.1',
582+ 'https://raw.githubusercontent.com/pygame/pygame/master/LICENSE'
553583 ], [
554584 'Python',
555585 '2001-2018 Python Software Foundation<br>Python is a trademark of the Python Software Foundation.',
@@ -560,6 +590,11 @@ credits = [ · 4 unmodified lines
560590 '2009-2017 Kristopher Michael Kowal',
561591 'MIT',
562592 'https://raw.githubusercontent.com/kriskowal/q/master/LICENSE'
593+ ], [
594+ 'Qt',
595+ '2012-2018 The Qt Company Ltd',
596+ 'GFDL',
597+ 'https://doc.qt.io/qt-5/licensing.html'
563598 ], [
564599 'Ramda',
565600 '2013-2016 Scott Sauyet and Michael Hurley',
assets/javascripts/templates/pages/help_tmpl.coffee+3−0
@@ -131,6 +131,9 @@ app.templates.helpPage = -> · 130 unmodified lines
131131 <dt class="_shortcuts-dt">
132132 <code class="_shortcut-code">alt + s</code>
133133 <dd class="_shortcuts-dd">Search on Stack Overflow
134+ <dt class="_shortcuts-dt">
135+ <code class="_shortcut-code">alt + d</code>
136+ <dd class="_shortcuts-dd">Search on DuckDuckGo
134137 </dl>
135138 <p class="_note _note-green">
136139 <strong>Tip:</strong> If the cursor is no longer in the search field, press <code class="_label">/</code> or
assets/javascripts/templates/pages/root_tmpl.coffee.erb+0−11
@@ -72,14 +72,3 @@ app.templates.androidWarning = """ · 71 unmodified lines
7272 <p>To install DevDocs on your phone, visit <a href="https://devdocs.io" target="_blank" rel="noopener">devdocs.io</a> in Chrome and select "Add to home screen" in the menu.
7373 </div>
7474 """
75−
76−app.templates.httpWarning = """
77− <div class="_intro"><div class="_intro-message">
78− <h2 class="_intro-title">Hi there!</h2>
79− <p>DevDocs is migrating to HTTPS.
80− <p>Please update your bookmarks to point to <a href="https://devdocs.io">https://devdocs.io</a>.
81− <p>When using the HTTPS version, your preferences will carry over automatically, but your offline data will be reset. Simply re-download documentation in the <a href="https://devdocs.io/offline">Offline area</a>, and you'll be all set to use DevDocs securely offline.
82− <p>Sorry for the inconvenience. This migration is needed because browsers are removing support for certain DOM APIs that power DevDocs's offline mode over non-secure origins.
83− <p>Thanks for using DevDocs, and happy coding!
84− </div></div>
85−"""
assets/javascripts/vendor/prism.js+633−352
@@ -1,4 +1,5 @@
1−/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+c+bash+cpp+coffeescript+ruby+d+django+elixir+erlang+go+java+json+kotlin+lua+nginx+nim+perl+php+python+jsx+crystal+rust+scss+sql+typescript+yaml */
1+/* PrismJS 1.15.0
2+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+c+bash+cpp+coffeescript+ruby+d+dart+django+elixir+markup-templating+erlang+go+java+json+kotlin+lua+crystal+nginx+nim+perl+php+sql+scss+python+jsx+typescript+rust+yaml */
23 var _self = (typeof window !== 'undefined')
34 ? window // if in browser
45 : (
@@ -16,11 +17,12 @@ var _self = (typeof window !== 'undefined') · 11 unmodified lines
1617 var Prism = (function(){
1718
1819 // Private helper vars
19−var lang = /\blang(?:uage)?-(\w+)\b/i;
20+var lang = /\blang(?:uage)?-([\w-]+)\b/i;
2021 var uniqueId = 0;
2122
2223 var _ = _self.Prism = {
2324 manual: _self.Prism && _self.Prism.manual,
25+ disableWorkerMessageHandler: _self.Prism && _self.Prism.disableWorkerMessageHandler,
2426 util: {
2527 encode: function (tokens) {
2628 if (tokens instanceof Token) {
@@ -44,23 +46,38 @@ var _ = _self.Prism = { · 17 unmodified lines
4446 },
4547
4648 // Deep clone a language definition (e.g. to extend it)
47− clone: function (o) {
49+ clone: function (o, visited) {
4850 var type = _.util.type(o);
51+ visited = visited || {};
4952
5053 switch (type) {
5154 case 'Object':
55+ if (visited[_.util.objId(o)]) {
56+ return visited[_.util.objId(o)];
57+ }
5258 var clone = {};
59+ visited[_.util.objId(o)] = clone;
5360
5461 for (var key in o) {
5562 if (o.hasOwnProperty(key)) {
56− clone[key] = _.util.clone(o[key]);
63+ clone[key] = _.util.clone(o[key], visited);
5764 }
5865 }
5966
6067 return clone;
6168
6269 case 'Array':
63− return o.map(function(v) { return _.util.clone(v); });
70+ if (visited[_.util.objId(o)]) {
71+ return visited[_.util.objId(o)];
72+ }
73+ var clone = [];
74+ visited[_.util.objId(o)] = clone;
75+
76+ o.forEach(function (v, i) {
77+ clone[i] = _.util.clone(v, visited);
78+ });
79+
80+ return clone;
6481 }
6582
6683 return o;
@@ -155,6 +172,10 @@ var _ = _self.Prism = { · 88 unmodified lines
155172 plugins: {},
156173
157174 highlightAll: function(async, callback) {
175+ _.highlightAllUnder(document, async, callback);
176+ },
177+
178+ highlightAllUnder: function(container, async, callback) {
158179 var env = {
159180 callback: callback,
160181 selector: 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'
@@ -162,7 +183,7 @@ var _ = _self.Prism = { · 1 unmodified line
162183
163184 _.hooks.run("before-highlightall", env);
164185
165− var elements = env.elements || document.querySelectorAll(env.selector);
186+ var elements = env.elements || container.querySelectorAll(env.selector);
166187
167188 for (var i=0, element; element = elements[i++];) {
168189 _.highlightElement(element, async === true, env.callback);
@@ -185,11 +206,13 @@ var _ = _self.Prism = { · 16 unmodified lines
185206 // Set language on the element, if not present
186207 element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
187208
188− // Set language on the parent, for styling
189− parent = element.parentNode;
209+ if (element.parentNode) {
210+ // Set language on the parent, for styling
211+ parent = element.parentNode;
190212
191− if (/pre/i.test(parent.nodeName)) {
192− parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
213+ if (/pre/i.test(parent.nodeName)) {
214+ parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
215+ }
193216 }
194217
195218 var code = element.textContent;
@@ -251,8 +274,15 @@ var _ = _self.Prism = { · 55 unmodified lines
251274 },
252275
253276 highlight: function (text, grammar, language) {
254− var tokens = _.tokenize(text, grammar);
255− return Token.stringify(_.util.encode(tokens), language);
277+ var env = {
278+ code: text,
279+ grammar: grammar,
280+ language: language
281+ };
282+ _.hooks.run('before-tokenize', env);
283+ env.tokens = _.tokenize(env.code, env.grammar);
284+ _.hooks.run('after-tokenize', env);
285+ return Token.stringify(_.util.encode(env.tokens), env.language);
256286 },
257287
258288 matchGrammar: function (text, strarr, grammar, index, startPos, oneshot, target) {
@@ -300,15 +330,9 @@ var _ = _self.Prism = { · 41 unmodified lines
300330 continue;
301331 }
302332
303− pattern.lastIndex = 0;
304−
305− var match = pattern.exec(str),
306− delNum = 1;
307−
308− // Greedy patterns can override/remove up to two previously matched tokens
309− if (!match && greedy && i != strarr.length - 1) {
333+ if (greedy && i != strarr.length - 1) {
310334 pattern.lastIndex = pos;
311− match = pattern.exec(text);
335+ var match = pattern.exec(text);
312336 if (!match) {
313337 break;
314338 }
@@ -327,11 +351,8 @@ var _ = _self.Prism = { · 12 unmodified lines
327351 }
328352 }
329353
330− /*
331− * If strarr[i] is a Token, then the match starts inside another Token, which is invalid
332− * If strarr[k - 1] is greedy we are in conflict with another greedy pattern
333− */
334− if (strarr[i] instanceof Token || strarr[k - 1].greedy) {
354+ // If strarr[i] is a Token, then the match starts inside another Token, which is invalid
355+ if (strarr[i] instanceof Token) {
335356 continue;
336357 }
337358
@@ -339,6 +360,11 @@ var _ = _self.Prism = { · 1 unmodified line
339360 delNum = k - i;
340361 str = text.slice(pos, p);
341362 match.index -= pos;
363+ } else {
364+ pattern.lastIndex = 0;
365+
366+ var match = pattern.exec(str),
367+ delNum = 1;
342368 }
343369
344370 if (!match) {
@@ -350,7 +376,7 @@ var _ = _self.Prism = { · 5 unmodified lines
350376 }
351377
352378 if(lookbehind) {
353− lookbehindLength = match[1].length;
379+ lookbehindLength = match[1] ? match[1].length : 0;
354380 }
355381
356382 var from = match.index + lookbehindLength,
@@ -480,18 +506,21 @@ Token.stringify = function(o, language, parent) { · 123 unmodified lines
480506 // // in Node.js
481507 // return _self.Prism;
482508 // }
483−// // In worker
484−// _self.addEventListener('message', function(evt) {
485−// var message = JSON.parse(evt.data),
486−// lang = message.language,
487−// code = message.code,
488−// immediateClose = message.immediateClose;
489−
490−// _self.postMessage(_.highlight(code, _.languages[lang], lang));
491−// if (immediateClose) {
492−// _self.close();
493−// }
494−// }, false);
509+
510+// if (!_.disableWorkerMessageHandler) {
511+// // In worker
512+// _self.addEventListener('message', function (evt) {
513+// var message = JSON.parse(evt.data),
514+// lang = message.language,
515+// code = message.code,
516+// immediateClose = message.immediateClose;
517+
518+// _self.postMessage(_.highlight(code, _.languages[lang], lang));
519+// if (immediateClose) {
520+// _self.close();
521+// }
522+// }, false);
523+// }
495524
496525 // return _self.Prism;
497526 // }
@@ -535,7 +564,8 @@ Prism.languages.markup = { · 37 unmodified lines
535564 'doctype': /<!DOCTYPE[\s\S]+?>/i,
536565 'cdata': /<!\[CDATA\[[\s\S]*?]]>/i,
537566 'tag': {
538− pattern: /<\/?(?!\d)[^\s>\/=$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+))?)*\s*\/?>/i,
567+ pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+))?)*\s*\/?>/i,
568+ greedy: true,
539569 inside: {
540570 'tag': {
541571 pattern: /^<\/?[^\s>\/]+/i,
@@ -600,13 +630,13 @@ Prism.languages.css = { · 58 unmodified lines
600630 pattern: /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
601631 greedy: true
602632 },
603− 'property': /[\w-]+(?=\s*:)/i,
633+ 'property': /[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,
604634 'important': /\B!important\b/i,
605635 'function': /[-a-z0-9]+(?=\()/i,
606636 'punctuation': /[(){};:]/
607637 };
608638
609−Prism.languages.css['atrule'].inside.rest = Prism.util.clone(Prism.languages.css);
639+Prism.languages.css['atrule'].inside.rest = Prism.languages.css;
610640
611641 if (Prism.languages.markup) {
612642 Prism.languages.insertBefore('markup', 'tag', {
@@ -614,10 +644,11 @@ if (Prism.languages.markup) { · 1 unmodified line
614644 pattern: /(<style[\s\S]*?>)[\s\S]*?(?=<\/style>)/i,
615645 lookbehind: true,
616646 inside: Prism.languages.css,
617− alias: 'language-css'
647+ alias: 'language-css',
648+ greedy: true
618649 }
619650 });
620−
651+
621652 Prism.languages.insertBefore('inside', 'attr-value', {
622653 'style-attr': {
623654 pattern: /\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,
@@ -644,7 +675,8 @@ Prism.languages.clike = { · 20 unmodified lines
644675 },
645676 {
646677 pattern: /(^|[^\\:])\/\/.*/,
647− lookbehind: true
678+ lookbehind: true,
679+ greedy: true
648680 }
649681 ],
650682 'string': {
@@ -661,51 +693,53 @@ Prism.languages.clike = { · 10 unmodified lines
661693 'keyword': /\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,
662694 'boolean': /\b(?:true|false)\b/,
663695 'function': /[a-z0-9_]+(?=\()/i,
664− 'number': /\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i,
696+ 'number': /\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,
665697 'operator': /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,
666698 'punctuation': /[{}[\];(),.:]/
667699 };
668700
669701 Prism.languages.javascript = Prism.languages.extend('clike', {
670702 'keyword': /\b(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/,
671− 'number': /\b-?(?:0[xX][\dA-Fa-f]+|0[bB][01]+|0[oO][0-7]+|\d*\.?\d+(?:[Ee][+-]?\d+)?|NaN|Infinity)\b/,
703+ 'number': /\b(?:0[xX][\dA-Fa-f]+|0[bB][01]+|0[oO][0-7]+|NaN|Infinity)\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee][+-]?\d+)?/,
672704 // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
673− 'function': /[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\s*\()/i,
705+ 'function': /[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*\()/i,
674706 'operator': /-[-=]?|\+[+=]?|!=?=?|<<?=?|>>?>?=?|=(?:==?|>)?|&[&=]?|\|[|=]?|\*\*?=?|\/=?|~|\^=?|%=?|\?|\.{3}/
675707 });
676708
677709 Prism.languages.insertBefore('javascript', 'keyword', {
678710 'regex': {
679− pattern: /(^|[^/])\/(?!\/)(\[[^\]\r\n]+]|\\.|[^/\\\[\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,
711+ pattern: /((?:^|[^$\w\xA0-\uFFFF."'\])\s])\s*)\/(\[[^\]\r\n]+]|\\.|[^/\\\[\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})\]]))/,
680712 lookbehind: true,
681713 greedy: true
682714 },
683715 // This must be declared before keyword because we use "function" inside the look-forward
684716 'function-variable': {
685− pattern: /[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\s*=\s*(?:function\b|(?:\([^()]*\)|[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*)\s*=>))/i,
717+ pattern: /[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*=\s*(?:function\b|(?:\([^()]*\)|[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/i,
686718 alias: 'function'
687− }
719+ },
720+ 'constant': /\b[A-Z][A-Z\d_]*\b/
688721 });
689722
690723 Prism.languages.insertBefore('javascript', 'string', {
691724 'template-string': {
692− pattern: /`(?:\\[\s\S]|[^\\`])*`/,
725+ pattern: /`(?:\\[\s\S]|\${[^}]+}|[^\\`])*`/,
693726 greedy: true,
694727 inside: {
695728 'interpolation': {
696− pattern: /\$\{[^}]+\}/,
729+ pattern: /\${[^}]+}/,
697730 inside: {
698731 'interpolation-punctuation': {
699− pattern: /^\$\{|\}$/,
732+ pattern: /^\${|}$/,
700733 alias: 'punctuation'
701734 },
702− rest: Prism.languages.javascript
735+ rest: null // See below
703736 }
704737 },
705738 'string': /[\s\S]+/
706739 }
707740 }
708741 });
742+Prism.languages.javascript['template-string'].inside['interpolation'].inside.rest = Prism.languages.javascript;
709743
710744 if (Prism.languages.markup) {
711745 Prism.languages.insertBefore('markup', 'tag', {
@@ -713,7 +747,8 @@ if (Prism.languages.markup) { · 1 unmodified line
713747 pattern: /(<script[\s\S]*?>)[\s\S]*?(?=<\/script>)/i,
714748 lookbehind: true,
715749 inside: Prism.languages.javascript,
716− alias: 'language-javascript'
750+ alias: 'language-javascript',
751+ greedy: true
717752 }
718753 });
719754 }
@@ -723,7 +758,7 @@ Prism.languages.js = Prism.languages.javascript; · 3 unmodified lines
723758 Prism.languages.c = Prism.languages.extend('clike', {
724759 'keyword': /\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/,
725760 'operator': /-[>-]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|\|?|[~^%?*\/]/,
726− 'number': /\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)[ful]*\b/i
761+ 'number': /(?:\b0x[\da-f]+|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?)[ful]*/i
727762 });
728763
729764 Prism.languages.insertBefore('c', 'string', {
@@ -768,7 +803,7 @@ delete Prism.languages.c['boolean']; · 38 unmodified lines
768803 },
769804 /^\$\(\(/
770805 ],
771− number: /\b-?(?:0x[\dA-Fa-f]+|\d*\.?\d+(?:[Ee]-?\d+)?)\b/,
806+ number: /\b0x[\dA-Fa-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee]-?\d+)?/,
772807 // Operators according to https://www.gnu.org/software/bash/manual/bashref.html#Shell-Arithmetic
773808 operator: /--?|-=|\+\+?|\+=|!=?|~|\*\*?|\*=|\/=?|%=?|<<=?|>>=?|<=?|>=?|==?|&&?|&=|\^=?|\|\|?|\|=|\?|:/,
774809 // If there is no $ sign at the beginning highlight (( and )) as punctuation
@@ -778,6 +813,7 @@ delete Prism.languages.c['boolean']; · 3 unmodified lines
778813 // Command Substitution
779814 {
780815 pattern: /\$\([^)]+\)|`[^`]+`/,
816+ greedy: true,
781817 inside: {
782818 variable: /^\$\(|^`|\)$|`$/
783819 }
@@ -804,7 +840,7 @@ delete Prism.languages.c['boolean']; · 20 unmodified lines
804840 inside: insideString
805841 },
806842 {
807− pattern: /(["'])(?:\\[\s\S]|(?!\1)[^\\])*\1/,
843+ pattern: /(["'])(?:\\[\s\S]|\$\([^)]+\)|`[^`]+`|(?!\1)[^\\])*\1/,
808844 greedy: true,
809845 inside: insideString
810846 }
@@ -812,7 +848,7 @@ delete Prism.languages.c['boolean']; · 1 unmodified line
812848 'variable': insideString.variable,
813849 // Originally based on http://ss64.com/bash/
814850 'function': {
815− pattern: /(^|[\s;|&])(?:alias|apropos|apt-get|aptitude|aspell|awk|basename|bash|bc|bg|builtin|bzip2|cal|cat|cd|cfdisk|chgrp|chmod|chown|chroot|chkconfig|cksum|clear|cmp|comm|command|cp|cron|crontab|csplit|cut|date|dc|dd|ddrescue|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|enable|env|ethtool|eval|exec|expand|expect|export|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|getopts|git|grep|groupadd|groupdel|groupmod|groups|gzip|hash|head|help|hg|history|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|jobs|join|kill|killall|less|link|ln|locate|logname|logout|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|make|man|mkdir|mkfifo|mkisofs|mknod|more|most|mount|mtools|mtr|mv|mmv|nano|netstat|nice|nl|nohup|notify-send|npm|nslookup|open|op|passwd|paste|pathchk|ping|pkill|popd|pr|printcap|printenv|printf|ps|pushd|pv|pwd|quota|quotacheck|quotactl|ram|rar|rcp|read|readarray|readonly|reboot|rename|renice|remsync|rev|rm|rmdir|rsync|screen|scp|sdiff|sed|seq|service|sftp|shift|shopt|shutdown|sleep|slocate|sort|source|split|ssh|stat|strace|su|sudo|sum|suspend|sync|tail|tar|tee|test|time|timeout|times|touch|top|traceroute|trap|tr|tsort|tty|type|ulimit|umask|umount|unalias|uname|unexpand|uniq|units|unrar|unshar|uptime|useradd|userdel|usermod|users|uuencode|uudecode|v|vdir|vi|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yes|zip)(?=$|[\s;|&])/,
851+ pattern: /(^|[\s;|&])(?:alias|apropos|apt-get|aptitude|aspell|awk|basename|bash|bc|bg|builtin|bzip2|cal|cat|cd|cfdisk|chgrp|chmod|chown|chroot|chkconfig|cksum|clear|cmp|comm|command|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|enable|env|ethtool|eval|exec|expand|expect|export|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|getopts|git|grep|groupadd|groupdel|groupmod|groups|gzip|hash|head|help|hg|history|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|jobs|join|kill|killall|less|link|ln|locate|logname|logout|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|make|man|mkdir|mkfifo|mkisofs|mknod|more|most|mount|mtools|mtr|mv|mmv|nano|netstat|nice|nl|nohup|notify-send|npm|nslookup|open|op|passwd|paste|pathchk|ping|pkill|popd|pr|printcap|printenv|printf|ps|pushd|pv|pwd|quota|quotacheck|quotactl|ram|rar|rcp|read|readarray|readonly|reboot|rename|renice|remsync|rev|rm|rmdir|rsync|screen|scp|sdiff|sed|seq|service|sftp|shift|shopt|shutdown|sleep|slocate|sort|source|split|ssh|stat|strace|su|sudo|sum|suspend|sync|tail|tar|tee|test|time|timeout|times|touch|top|traceroute|trap|tr|tsort|tty|type|ulimit|umask|umount|unalias|uname|unexpand|uniq|units|unrar|unshar|uptime|useradd|userdel|usermod|users|uuencode|uudecode|v|vdir|vi|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yes|zip)(?=$|[\s;|&])/,
816852 lookbehind: true
817853 },
818854 'keyword': {
@@ -828,15 +864,18 @@ delete Prism.languages.c['boolean']; · 9 unmodified lines
828864 };
829865
830866 var inside = insideString.variable[1].inside;
867+ inside.string = Prism.languages.bash.string;
831868 inside['function'] = Prism.languages.bash['function'];
832869 inside.keyword = Prism.languages.bash.keyword;
833− inside.boolean = Prism.languages.bash.boolean;
870+ inside['boolean'] = Prism.languages.bash['boolean'];
834871 inside.operator = Prism.languages.bash.operator;
835872 inside.punctuation = Prism.languages.bash.punctuation;
873+
874+ Prism.languages.shell = Prism.languages.bash;
836875 })(Prism);
837876
838877 Prism.languages.cpp = Prism.languages.extend('c', {
839− 'keyword': /\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|class|compl|const|constexpr|const_cast|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,
878+ 'keyword': /\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|class|compl|const|constexpr|const_cast|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,
840879 'boolean': /\b(?:true|false)\b/,
841880 'operator': /--?|\+\+?|!=?|<{1,2}=?|>{1,2}=?|->|:{1,2}|={1,2}|\^|~|%|&{1,2}|\|\|?|\?|\*|\/|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/
842881 });
@@ -847,6 +886,15 @@ Prism.languages.insertBefore('cpp', 'keyword', { · 4 unmodified lines
847886 lookbehind: true
848887 }
849888 });
889+
890+Prism.languages.insertBefore('cpp', 'string', {
891+ 'raw-string': {
892+ pattern: /R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,
893+ alias: 'string',
894+ greedy: true
895+ }
896+});
897+
850898 (function(Prism) {
851899
852900 // Ignore comments starting with { to privilege string interpolation highlighting
@@ -947,10 +995,13 @@ delete Prism.languages.coffeescript['template-string']; · 94 unmodified lines
947995 (function(Prism) {
948996 Prism.languages.ruby = Prism.languages.extend('clike', {
949997 'comment': [
950− /#(?!\{[^\r\n]*?\}).*/,
951− /^=begin(?:\r?\n|\r)(?:.*(?:\r?\n|\r))*?=end/m
998+ /#.*/,
999+ {
1000+ pattern: /^=begin(?:\r?\n|\r)(?:.*(?:\r?\n|\r))*?=end/m,
1001+ greedy: true
1002+ }
9521003 ],
953− 'keyword': /\b(?:alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/
1004+ 'keyword': /\b(?:alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|protected|private|public|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/
9541005 });
9551006
9561007 var interpolation = {
@@ -960,7 +1011,7 @@ delete Prism.languages.coffeescript['template-string']; · 3 unmodified lines
9601011 pattern: /^#\{|\}$/,
9611012 alias: 'tag'
9621013 },
963− rest: Prism.util.clone(Prism.languages.ruby)
1014+ rest: Prism.languages.ruby
9641015 }
9651016 };
9661017
@@ -1009,7 +1060,10 @@ delete Prism.languages.coffeescript['template-string']; · 42 unmodified lines
10091060 }
10101061 ],
10111062 'variable': /[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,
1012− 'symbol': /:[a-zA-Z_]\w*(?:[?!]|\b)/
1063+ 'symbol': {
1064+ pattern: /(^|[^:]):[a-zA-Z_]\w*(?:[?!]|\b)/,
1065+ lookbehind: true
1066+ }
10131067 });
10141068
10151069 Prism.languages.insertBefore('ruby', 'number', {
@@ -1127,6 +1181,30 @@ Prism.languages.insertBefore('d', 'function', { · 111 unmodified lines
11271181 alias: 'variable'
11281182 }
11291183 });
1184+Prism.languages.dart = Prism.languages.extend('clike', {
1185+ 'string': [
1186+ {
1187+ pattern: /r?("""|''')[\s\S]*?\1/,
1188+ greedy: true
1189+ },
1190+ {
1191+ pattern: /r?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,
1192+ greedy: true
1193+ }
1194+ ],
1195+ 'keyword': [
1196+ /\b(?:async|sync|yield)\*/,
1197+ /\b(?:abstract|assert|async|await|break|case|catch|class|const|continue|default|deferred|do|dynamic|else|enum|export|external|extends|factory|final|finally|for|get|if|implements|import|in|library|new|null|operator|part|rethrow|return|set|static|super|switch|this|throw|try|typedef|var|void|while|with|yield)\b/
1198+ ],
1199+ 'operator': /\bis!|\b(?:as|is)\b|\+\+|--|&&|\|\||<<=?|>>=?|~(?:\/=?)?|[+\-*\/%&^|=!<>]=?|\?/
1200+});
1201+
1202+Prism.languages.insertBefore('dart','function',{
1203+ 'metadata': {
1204+ pattern: /@\w+/,
1205+ alias: 'symbol'
1206+ }
1207+});
11301208 // Django/Jinja2 syntax definition for Prism.js <http://prismjs.com> syntax highlighter.
11311209 // Mostly it works OK but can paint code incorrectly on complex html/template tag combinations.
11321210
@@ -1170,15 +1248,15 @@ if (Prism.languages.css) { · 37 unmodified lines
11701248 Prism.languages.jinja2 = Prism.languages.django;
11711249
11721250 Prism.languages.elixir = {
1173− // Negative look-ahead is needed for string interpolation
1174− // Negative look-behind is needed to avoid highlighting markdown headers in
1175− // multi-line doc strings
11761251 'comment': {
1177− pattern: /(^|[^#])#(?![{#]).*/m,
1252+ pattern: /#.*/m,
11781253 lookbehind: true
11791254 },
11801255 // ~r"""foo""" (multi-line), ~r'''foo''' (multi-line), ~r/foo/, ~r|foo|, ~r"foo", ~r'foo', ~r(foo), ~r[foo], ~r{foo}, ~r<foo>
1181− 'regex': /~[rR](?:("""|''')(?:\\[\s\S]|(?!\1)[^\\])+\1|([\/|"'])(?:\\.|(?!\2)[^\\\r\n])+\2|\((?:\\.|[^\\)\r\n])+\)|\[(?:\\.|[^\\\]\r\n])+\]|\{(?:\\.|[^\\}\r\n])+\}|<(?:\\.|[^\\>\r\n])+>)[uismxfr]*/,
1256+ 'regex': {
1257+ pattern: /~[rR](?:("""|''')(?:\\[\s\S]|(?!\1)[^\\])+\1|([\/|"'])(?:\\.|(?!\2)[^\\\r\n])+\2|\((?:\\.|[^\\)\r\n])+\)|\[(?:\\.|[^\\\]\r\n])+\]|\{(?:\\.|[^\\}\r\n])+\}|<(?:\\.|[^\\>\r\n])+>)[uismxfr]*/,
1258+ greedy: true
1259+ },
11821260 'string': [
11831261 {
11841262 // ~s"""foo""" (multi-line), ~s'''foo''' (multi-line), ~s/foo/, ~s|foo|, ~s"foo", ~s'foo', ~s(foo), ~s[foo], ~s{foo} (with interpolation care), ~s<foo>
@@ -1225,7 +1303,7 @@ Prism.languages.elixir = { · 40 unmodified lines
12251303 alias: 'variable'
12261304 },
12271305 'attribute': {
1228− pattern: /@[\S]+/,
1306+ pattern: /@\w+/,
12291307 alias: 'variable'
12301308 },
12311309 'number': /\b(?:0[box][a-f\d_]+|\d[\d_]*)(?:\.[\d_]+)?(?:e[+-]?[\d_]+)?\b/i,
@@ -1256,13 +1334,102 @@ Prism.languages.elixir.string.forEach(function(o) { · 24 unmodified lines
12561334 pattern: /^#\{|\}$/,
12571335 alias: 'punctuation'
12581336 },
1259− rest: Prism.util.clone(Prism.languages.elixir)
1337+ rest: Prism.languages.elixir
12601338 }
12611339 }
12621340 };
12631341 });
12641342
12651343
1344+Prism.languages['markup-templating'] = {};
1345+
1346+Object.defineProperties(Prism.languages['markup-templating'], {
1347+ buildPlaceholders: {
1348+ // Tokenize all inline templating expressions matching placeholderPattern
1349+ // If the replaceFilter function is provided, it will be called with every match.
1350+ // If it returns false, the match will not be replaced.
1351+ value: function (env, language, placeholderPattern, replaceFilter) {
1352+ if (env.language !== language) {
1353+ return;
1354+ }
1355+
1356+ env.tokenStack = [];
1357+
1358+ env.code = env.code.replace(placeholderPattern, function(match) {
1359+ if (typeof replaceFilter === 'function' && !replaceFilter(match)) {
1360+ return match;
1361+ }
1362+ var i = env.tokenStack.length;
1363+ // Check for existing strings
1364+ while (env.code.indexOf('___' + language.toUpperCase() + i + '___') !== -1)
1365+ ++i;
1366+
1367+ // Create a sparse array
1368+ env.tokenStack[i] = match;
1369+
1370+ return '___' + language.toUpperCase() + i + '___';
1371+ });
1372+
1373+ // Switch the grammar to markup
1374+ env.grammar = Prism.languages.markup;
1375+ }
1376+ },
1377+ tokenizePlaceholders: {
1378+ // Replace placeholders with proper tokens after tokenizing
1379+ value: function (env, language) {
1380+ if (env.language !== language || !env.tokenStack) {
1381+ return;
1382+ }
1383+
1384+ // Switch the grammar back
1385+ env.grammar = Prism.languages[language];
1386+
1387+ var j = 0;
1388+ var keys = Object.keys(env.tokenStack);
1389+ var walkTokens = function (tokens) {
1390+ if (j >= keys.length) {
1391+ return;
1392+ }
1393+ for (var i = 0; i < tokens.length; i++) {
1394+ var token = tokens[i];
1395+ if (typeof token === 'string' || (token.content && typeof token.content === 'string')) {
1396+ var k = keys[j];
1397+ var t = env.tokenStack[k];
1398+ var s = typeof token === 'string' ? token : token.content;
1399+
1400+ var index = s.indexOf('___' + language.toUpperCase() + k + '___');
1401+ if (index > -1) {
1402+ ++j;
1403+ var before = s.substring(0, index);
1404+ var middle = new Prism.Token(language, Prism.tokenize(t, env.grammar, language), 'language-' + language, t);
1405+ var after = s.substring(index + ('___' + language.toUpperCase() + k + '___').length);
1406+ var replacement;
1407+ if (before || after) {
1408+ replacement = [before, middle, after].filter(function (v) { return !!v; });
1409+ walkTokens(replacement);
1410+ } else {
1411+ replacement = middle;
1412+ }
1413+ if (typeof token === 'string') {
1414+ Array.prototype.splice.apply(tokens, [i, 1].concat(replacement));
1415+ } else {
1416+ token.content = replacement;
1417+ }
1418+
1419+ if (j >= keys.length) {
1420+ break;
1421+ }
1422+ }
1423+ } else if (token.content && typeof token.content !== 'string') {
1424+ walkTokens(token.content);
1425+ }
1426+ }
1427+ };
1428+
1429+ walkTokens(env.tokens);
1430+ }
1431+ }
1432+});
12661433 Prism.languages.erlang = {
12671434 'comment': /%.+/,
12681435 'string': {
@@ -1282,7 +1449,7 @@ Prism.languages.erlang = { · 13 unmodified lines
12821449 'number': [
12831450 /\$\\?./,
12841451 /\d+#[a-z0-9]+/i,
1285− /(?:\b|-)\d*\.?\d+([Ee][+-]?\d+)?\b/
1452+ /(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i
12861453 ],
12871454 'function': /\b[a-z][\w@]*(?=\()/,
12881455 'variable': {
@@ -1312,7 +1479,7 @@ Prism.languages.go = Prism.languages.extend('clike', { · 23 unmodified lines
13121479 'builtin': /\b(?:bool|byte|complex(?:64|128)|error|float(?:32|64)|rune|string|u?int(?:8|16|32|64)?|uintptr|append|cap|close|complex|copy|delete|imag|len|make|new|panic|print(?:ln)?|real|recover)\b/,
13131480 'boolean': /\b(?:_|iota|nil|true|false)\b/,
13141481 'operator': /[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,
1315− 'number': /\b(-?(0x[a-f\d]+|(\d+\.?\d*|\.\d+)(e[-+]?\d+)?)i?)\b/i,
1482+ 'number': /(?:\b0x[a-f\d]+|(?:\b\d+\.?\d*|\B\.\d+)(?:e[-+]?\d+)?)i?/i,
13161483 'string': {
13171484 pattern: /(["'`])(\\[\s\S]|(?!\1)[^\\])*\1/,
13181485 greedy: true
@@ -1322,7 +1489,7 @@ delete Prism.languages.go['class-name']; · 3 unmodified lines
13221489
13231490 Prism.languages.java = Prism.languages.extend('clike', {
13241491 'keyword': /\b(?:abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while)\b/,
1325− 'number': /\b0b[01]+\b|\b0x[\da-f]*\.?[\da-fp\-]+\b|\b\d*\.?\d+(?:e[+-]?\d+)?[df]?\b/i,
1492+ 'number': /\b0b[01]+\b|\b0x[\da-f]*\.?[\da-fp-]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?[df]?/i,
13261493 'operator': {
13271494 pattern: /(^|[^.])(?:\+[+=]?|-[-=]?|!=?|<<?=?|>>?>?=?|==?|&[&=]?|\|[|=]?|\*=?|\/=?|%=?|\^=?|[?:~])/m,
13281495 lookbehind: true
@@ -1337,14 +1504,25 @@ Prism.languages.insertBefore('java','function', { · 8 unmodified lines
13371504 }
13381505 });
13391506
1507+Prism.languages.insertBefore('java', 'class-name', {
1508+ 'generics': {
1509+ pattern: /<\s*\w+(?:\.\w+)?(?:\s*,\s*\w+(?:\.\w+)?)*>/i,
1510+ alias: 'function',
1511+ inside: {
1512+ keyword: Prism.languages.java.keyword,
1513+ punctuation: /[<>(),.:]/
1514+ }
1515+ }
1516+});
1517+
13401518 Prism.languages.json = {
13411519 'property': /"(?:\\.|[^\\"\r\n])*"(?=\s*:)/i,
13421520 'string': {
13431521 pattern: /"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,
13441522 greedy: true
13451523 },
1346− 'number': /\b-?(?:0x[\dA-Fa-f]+|\d*\.?\d+(?:[Ee][+-]?\d+)?)\b/,
1347− 'punctuation': /[{}[\]);,]/,
1524+ 'number': /-?\d+\.?\d*([Ee][+-]?\d+)?/,
1525+ 'punctuation': /[{}[\],]/,
13481526 'operator': /:/g,
13491527 'boolean': /\b(?:true|false)\b/i,
13501528 'null': /\bnull\b/i
@@ -1356,7 +1534,7 @@ Prism.languages.jsonp = Prism.languages.json; · 5 unmodified lines
13561534 Prism.languages.kotlin = Prism.languages.extend('clike', {
13571535 'keyword': {
13581536 // The lookbehind prevents wrong highlighting of e.g. kotlin.properties.get
1359− pattern: /(^|[^.])\b(?:abstract|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|else|enum|final|finally|for|fun|get|if|import|in|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|out|override|package|private|protected|public|reified|return|sealed|set|super|tailrec|this|throw|to|try|val|var|when|where|while)\b/,
1537+ pattern: /(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,
13601538 lookbehind: true
13611539 },
13621540 'function': [
@@ -1366,7 +1544,7 @@ Prism.languages.jsonp = Prism.languages.json; · 3 unmodified lines
13661544 lookbehind: true
13671545 }
13681546 ],
1369− 'number': /\b(?:0[bx][\da-fA-F]+|\d+(?:\.\d+)?(?:e[+-]?\d+)?[fFL]?)\b/,
1547+ 'number': /\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,
13701548 'operator': /\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/
13711549 });
13721550
@@ -1400,7 +1578,7 @@ Prism.languages.jsonp = Prism.languages.json; · 27 unmodified lines
14001578 pattern: /^\$\{|\}$/,
14011579 alias: 'variable'
14021580 },
1403− rest: Prism.util.clone(Prism.languages.kotlin)
1581+ rest: Prism.languages.kotlin
14041582 }
14051583 },
14061584 {
@@ -1414,6 +1592,7 @@ Prism.languages.jsonp = Prism.languages.json; · 7 unmodified lines
14141592 };
14151593
14161594 }(Prism));
1595+
14171596 Prism.languages.lua = {
14181597 'comment': /^#!.+|--(?:\[(=*)\[[\s\S]*?\]\1\]|.*)/m,
14191598 // \z may be used to skip the following space
@@ -1434,16 +1613,68 @@ Prism.languages.lua = { · 14 unmodified lines
14341613 ],
14351614 'punctuation': /[\[\](){},;]|\.+|:+/
14361615 };
1616+(function(Prism) {
1617+ Prism.languages.crystal = Prism.languages.extend('ruby', {
1618+ keyword: [
1619+ /\b(?:abstract|alias|as|asm|begin|break|case|class|def|do|else|elsif|end|ensure|enum|extend|for|fun|if|include|instance_sizeof|lib|macro|module|next|of|out|pointerof|private|protected|rescue|return|require|select|self|sizeof|struct|super|then|type|typeof|uninitialized|union|unless|until|when|while|with|yield|__DIR__|__END_LINE__|__FILE__|__LINE__)\b/,
1620+ {
1621+ pattern: /(\.\s*)(?:is_a|responds_to)\?/,
1622+ lookbehind: true
1623+ }
1624+ ],
1625+
1626+ number: /\b(?:0b[01_]*[01]|0o[0-7_]*[0-7]|0x[\da-fA-F_]*[\da-fA-F]|(?:\d(?:[\d_]*\d)?)(?:\.[\d_]*\d)?(?:[eE][+-]?[\d_]*\d)?)(?:_(?:[uif](?:8|16|32|64))?)?\b/
1627+ });
1628+
1629+ Prism.languages.insertBefore('crystal', 'string', {
1630+ attribute: {
1631+ pattern: /@\[.+?\]/,
1632+ alias: 'attr-name',
1633+ inside: {
1634+ delimiter: {
1635+ pattern: /^@\[|\]$/,
1636+ alias: 'tag'
1637+ },
1638+ rest: Prism.languages.crystal
1639+ }
1640+ },
1641+
1642+ expansion: [
1643+ {
1644+ pattern: /\{\{.+?\}\}/,
1645+ inside: {
1646+ delimiter: {
1647+ pattern: /^\{\{|\}\}$/,
1648+ alias: 'tag'
1649+ },
1650+ rest: Prism.languages.crystal
1651+ }
1652+ },
1653+ {
1654+ pattern: /\{%.+?%\}/,
1655+ inside: {
1656+ delimiter: {
1657+ pattern: /^\{%|%\}$/,
1658+ alias: 'tag'
1659+ },
1660+ rest: Prism.languages.crystal
1661+ }
1662+ }
1663+ ]
1664+ });
1665+
1666+}(Prism));
1667+
14371668 Prism.languages.nginx = Prism.languages.extend('clike', {
1438− 'comment': {
1439− pattern: /(^|[^"{\\])#.*/,
1440− lookbehind: true
1441− },
1442− 'keyword': /\b(?:CONTENT_|DOCUMENT_|GATEWAY_|HTTP_|HTTPS|if_not_empty|PATH_|QUERY_|REDIRECT_|REMOTE_|REQUEST_|SCGI|SCRIPT_|SERVER_|http|events|accept_mutex|accept_mutex_delay|access_log|add_after_body|add_before_body|add_header|addition_types|aio|alias|allow|ancient_browser|ancient_browser_value|auth|auth_basic|auth_basic_user_file|auth_http|auth_http_header|auth_http_timeout|autoindex|autoindex_exact_size|autoindex_localtime|break|charset|charset_map|charset_types|chunked_transfer_encoding|client_body_buffer_size|client_body_in_file_only|client_body_in_single_buffer|client_body_temp_path|client_body_timeout|client_header_buffer_size|client_header_timeout|client_max_body_size|connection_pool_size|create_full_put_path|daemon|dav_access|dav_methods|debug_connection|debug_points|default_type|deny|devpoll_changes|devpoll_events|directio|directio_alignment|disable_symlinks|empty_gif|env|epoll_events|error_log|error_page|expires|fastcgi_buffer_size|fastcgi_buffers|fastcgi_busy_buffers_size|fastcgi_cache|fastcgi_cache_bypass|fastcgi_cache_key|fastcgi_cache_lock|fastcgi_cache_lock_timeout|fastcgi_cache_methods|fastcgi_cache_min_uses|fastcgi_cache_path|fastcgi_cache_purge|fastcgi_cache_use_stale|fastcgi_cache_valid|fastcgi_connect_timeout|fastcgi_hide_header|fastcgi_ignore_client_abort|fastcgi_ignore_headers|fastcgi_index|fastcgi_intercept_errors|fastcgi_keep_conn|fastcgi_max_temp_file_size|fastcgi_next_upstream|fastcgi_no_cache|fastcgi_param|fastcgi_pass|fastcgi_pass_header|fastcgi_read_timeout|fastcgi_redirect_errors|fastcgi_send_timeout|fastcgi_split_path_info|fastcgi_store|fastcgi_store_access|fastcgi_temp_file_write_size|fastcgi_temp_path|flv|geo|geoip_city|geoip_country|google_perftools_profiles|gzip|gzip_buffers|gzip_comp_level|gzip_disable|gzip_http_version|gzip_min_length|gzip_proxied|gzip_static|gzip_types|gzip_vary|if|if_modified_since|ignore_invalid_headers|image_filter|image_filter_buffer|image_filter_jpeg_quality|image_filter_sharpen|image_filter_transparency|imap_capabilities|imap_client_buffer|include|index|internal|ip_hash|keepalive|keepalive_disable|keepalive_requests|keepalive_timeout|kqueue_changes|kqueue_events|large_client_header_buffers|limit_conn|limit_conn_log_level|limit_conn_zone|limit_except|limit_rate|limit_rate_after|limit_req|limit_req_log_level|limit_req_zone|limit_zone|lingering_close|lingering_time|lingering_timeout|listen|location|lock_file|log_format|log_format_combined|log_not_found|log_subrequest|map|map_hash_bucket_size|map_hash_max_size|master_process|max_ranges|memcached_buffer_size|memcached_connect_timeout|memcached_next_upstream|memcached_pass|memcached_read_timeout|memcached_send_timeout|merge_slashes|min_delete_depth|modern_browser|modern_browser_value|mp4|mp4_buffer_size|mp4_max_buffer_size|msie_padding|msie_refresh|multi_accept|open_file_cache|open_file_cache_errors|open_file_cache_min_uses|open_file_cache_valid|open_log_file_cache|optimize_server_names|override_charset|pcre_jit|perl|perl_modules|perl_require|perl_set|pid|pop3_auth|pop3_capabilities|port_in_redirect|post_action|postpone_output|protocol|proxy|proxy_buffer|proxy_buffer_size|proxy_buffering|proxy_buffers|proxy_busy_buffers_size|proxy_cache|proxy_cache_bypass|proxy_cache_key|proxy_cache_lock|proxy_cache_lock_timeout|proxy_cache_methods|proxy_cache_min_uses|proxy_cache_path|proxy_cache_use_stale|proxy_cache_valid|proxy_connect_timeout|proxy_cookie_domain|proxy_cookie_path|proxy_headers_hash_bucket_size|proxy_headers_hash_max_size|proxy_hide_header|proxy_http_version|proxy_ignore_client_abort|proxy_ignore_headers|proxy_intercept_errors|proxy_max_temp_file_size|proxy_method|proxy_next_upstream|proxy_no_cache|proxy_pass|proxy_pass_error_message|proxy_pass_header|proxy_pass_request_body|proxy_pass_request_headers|proxy_read_timeout|proxy_redirect|proxy_redirect_errors|proxy_send_lowat|proxy_send_timeout|proxy_set_body|proxy_set_header|proxy_ssl_session_reuse|proxy_store|proxy_store_access|proxy_temp_file_write_size|proxy_temp_path|proxy_timeout|proxy_upstream_fail_timeout|proxy_upstream_max_fails|random_index|read_ahead|real_ip_header|recursive_error_pages|request_pool_size|reset_timedout_connection|resolver|resolver_timeout|return|rewrite|root|rtsig_overflow_events|rtsig_overflow_test|rtsig_overflow_threshold|rtsig_signo|satisfy|satisfy_any|secure_link_secret|send_lowat|send_timeout|sendfile|sendfile_max_chunk|server|server_name|server_name_in_redirect|server_names_hash_bucket_size|server_names_hash_max_size|server_tokens|set|set_real_ip_from|smtp_auth|smtp_capabilities|so_keepalive|source_charset|split_clients|ssi|ssi_silent_errors|ssi_types|ssi_value_length|ssl|ssl_certificate|ssl_certificate_key|ssl_ciphers|ssl_client_certificate|ssl_crl|ssl_dhparam|ssl_engine|ssl_prefer_server_ciphers|ssl_protocols|ssl_session_cache|ssl_session_timeout|ssl_verify_client|ssl_verify_depth|starttls|stub_status|sub_filter|sub_filter_once|sub_filter_types|tcp_nodelay|tcp_nopush|timeout|timer_resolution|try_files|types|types_hash_bucket_size|types_hash_max_size|underscores_in_headers|uninitialized_variable_warn|upstream|use|user|userid|userid_domain|userid_expires|userid_name|userid_p3p|userid_path|userid_service|valid_referers|variables_hash_bucket_size|variables_hash_max_size|worker_connections|worker_cpu_affinity|worker_priority|worker_processes|worker_rlimit_core|worker_rlimit_nofile|worker_rlimit_sigpending|working_directory|xclient|xml_entities|xslt_entities|xslt_stylesheet|xslt_types)\b/i
1669+ 'comment': {
1670+ pattern: /(^|[^"{\\])#.*/,
1671+ lookbehind: true
1672+ },
1673+ 'keyword': /\b(?:CONTENT_|DOCUMENT_|GATEWAY_|HTTP_|HTTPS|if_not_empty|PATH_|QUERY_|REDIRECT_|REMOTE_|REQUEST_|SCGI|SCRIPT_|SERVER_|http|events|accept_mutex|accept_mutex_delay|access_log|add_after_body|add_before_body|add_header|addition_types|aio|alias|allow|ancient_browser|ancient_browser_value|auth|auth_basic|auth_basic_user_file|auth_http|auth_http_header|auth_http_timeout|autoindex|autoindex_exact_size|autoindex_localtime|break|charset|charset_map|charset_types|chunked_transfer_encoding|client_body_buffer_size|client_body_in_file_only|client_body_in_single_buffer|client_body_temp_path|client_body_timeout|client_header_buffer_size|client_header_timeout|client_max_body_size|connection_pool_size|create_full_put_path|daemon|dav_access|dav_methods|debug_connection|debug_points|default_type|deny|devpoll_changes|devpoll_events|directio|directio_alignment|disable_symlinks|empty_gif|env|epoll_events|error_log|error_page|expires|fastcgi_buffer_size|fastcgi_buffers|fastcgi_busy_buffers_size|fastcgi_cache|fastcgi_cache_bypass|fastcgi_cache_key|fastcgi_cache_lock|fastcgi_cache_lock_timeout|fastcgi_cache_methods|fastcgi_cache_min_uses|fastcgi_cache_path|fastcgi_cache_purge|fastcgi_cache_use_stale|fastcgi_cache_valid|fastcgi_connect_timeout|fastcgi_hide_header|fastcgi_ignore_client_abort|fastcgi_ignore_headers|fastcgi_index|fastcgi_intercept_errors|fastcgi_keep_conn|fastcgi_max_temp_file_size|fastcgi_next_upstream|fastcgi_no_cache|fastcgi_param|fastcgi_pass|fastcgi_pass_header|fastcgi_read_timeout|fastcgi_redirect_errors|fastcgi_send_timeout|fastcgi_split_path_info|fastcgi_store|fastcgi_store_access|fastcgi_temp_file_write_size|fastcgi_temp_path|flv|geo|geoip_city|geoip_country|google_perftools_profiles|gzip|gzip_buffers|gzip_comp_level|gzip_disable|gzip_http_version|gzip_min_length|gzip_proxied|gzip_static|gzip_types|gzip_vary|if|if_modified_since|ignore_invalid_headers|image_filter|image_filter_buffer|image_filter_jpeg_quality|image_filter_sharpen|image_filter_transparency|imap_capabilities|imap_client_buffer|include|index|internal|ip_hash|keepalive|keepalive_disable|keepalive_requests|keepalive_timeout|kqueue_changes|kqueue_events|large_client_header_buffers|limit_conn|limit_conn_log_level|limit_conn_zone|limit_except|limit_rate|limit_rate_after|limit_req|limit_req_log_level|limit_req_zone|limit_zone|lingering_close|lingering_time|lingering_timeout|listen|location|lock_file|log_format|log_format_combined|log_not_found|log_subrequest|map|map_hash_bucket_size|map_hash_max_size|master_process|max_ranges|memcached_buffer_size|memcached_connect_timeout|memcached_next_upstream|memcached_pass|memcached_read_timeout|memcached_send_timeout|merge_slashes|min_delete_depth|modern_browser|modern_browser_value|mp4|mp4_buffer_size|mp4_max_buffer_size|msie_padding|msie_refresh|multi_accept|open_file_cache|open_file_cache_errors|open_file_cache_min_uses|open_file_cache_valid|open_log_file_cache|optimize_server_names|override_charset|pcre_jit|perl|perl_modules|perl_require|perl_set|pid|pop3_auth|pop3_capabilities|port_in_redirect|post_action|postpone_output|protocol|proxy|proxy_buffer|proxy_buffer_size|proxy_buffering|proxy_buffers|proxy_busy_buffers_size|proxy_cache|proxy_cache_bypass|proxy_cache_key|proxy_cache_lock|proxy_cache_lock_timeout|proxy_cache_methods|proxy_cache_min_uses|proxy_cache_path|proxy_cache_use_stale|proxy_cache_valid|proxy_connect_timeout|proxy_cookie_domain|proxy_cookie_path|proxy_headers_hash_bucket_size|proxy_headers_hash_max_size|proxy_hide_header|proxy_http_version|proxy_ignore_client_abort|proxy_ignore_headers|proxy_intercept_errors|proxy_max_temp_file_size|proxy_method|proxy_next_upstream|proxy_no_cache|proxy_pass|proxy_pass_error_message|proxy_pass_header|proxy_pass_request_body|proxy_pass_request_headers|proxy_read_timeout|proxy_redirect|proxy_redirect_errors|proxy_send_lowat|proxy_send_timeout|proxy_set_body|proxy_set_header|proxy_ssl_session_reuse|proxy_store|proxy_store_access|proxy_temp_file_write_size|proxy_temp_path|proxy_timeout|proxy_upstream_fail_timeout|proxy_upstream_max_fails|random_index|read_ahead|real_ip_header|recursive_error_pages|request_pool_size|reset_timedout_connection|resolver|resolver_timeout|return|rewrite|root|rtsig_overflow_events|rtsig_overflow_test|rtsig_overflow_threshold|rtsig_signo|satisfy|satisfy_any|secure_link_secret|send_lowat|send_timeout|sendfile|sendfile_max_chunk|server|server_name|server_name_in_redirect|server_names_hash_bucket_size|server_names_hash_max_size|server_tokens|set|set_real_ip_from|smtp_auth|smtp_capabilities|so_keepalive|source_charset|split_clients|ssi|ssi_silent_errors|ssi_types|ssi_value_length|ssl|ssl_certificate|ssl_certificate_key|ssl_ciphers|ssl_client_certificate|ssl_crl|ssl_dhparam|ssl_engine|ssl_prefer_server_ciphers|ssl_protocols|ssl_session_cache|ssl_session_timeout|ssl_verify_client|ssl_verify_depth|starttls|stub_status|sub_filter|sub_filter_once|sub_filter_types|tcp_nodelay|tcp_nopush|timeout|timer_resolution|try_files|types|types_hash_bucket_size|types_hash_max_size|underscores_in_headers|uninitialized_variable_warn|upstream|use|user|userid|userid_domain|userid_expires|userid_name|userid_p3p|userid_path|userid_service|valid_referers|variables_hash_bucket_size|variables_hash_max_size|worker_connections|worker_cpu_affinity|worker_priority|worker_processes|worker_rlimit_core|worker_rlimit_nofile|worker_rlimit_sigpending|working_directory|xclient|xml_entities|xslt_entities|xslt_stylesheet|xslt_types)\b/i
14431674 });
14441675
14451676 Prism.languages.insertBefore('nginx', 'keyword', {
1446− 'variable': /\$[a-z_]+/i
1677+ 'variable': /\$[a-z_]+/i
14471678 });
14481679 Prism.languages.nim = {
14491680 'comment': /#.*/,
@@ -1497,31 +1728,31 @@ Prism.languages.perl = { · 47 unmodified lines
14971728 pattern: /\b(?:q|qq|qx|qw)\s*([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/,
14981729 greedy: true
14991730 },
1500−
1731+
15011732 // q a...a
15021733 {
15031734 pattern: /\b(?:q|qq|qx|qw)\s+([a-zA-Z0-9])(?:(?!\1)[^\\]|\\[\s\S])*\1/,
15041735 greedy: true
15051736 },
1506−
1737+
15071738 // q(...)
15081739 {
15091740 pattern: /\b(?:q|qq|qx|qw)\s*\((?:[^()\\]|\\[\s\S])*\)/,
15101741 greedy: true
15111742 },
1512−
1743+
15131744 // q{...}
15141745 {
15151746 pattern: /\b(?:q|qq|qx|qw)\s*\{(?:[^{}\\]|\\[\s\S])*\}/,
15161747 greedy: true
15171748 },
1518−
1749+
15191750 // q[...]
15201751 {
15211752 pattern: /\b(?:q|qq|qx|qw)\s*\[(?:[^[\]\\]|\\[\s\S])*\]/,
15221753 greedy: true
15231754 },
1524−
1755+
15251756 // q<...>
15261757 {
15271758 pattern: /\b(?:q|qq|qx|qw)\s*<(?:[^<>\\]|\\[\s\S])*>/,
@@ -1547,31 +1778,31 @@ Prism.languages.perl = { · 19 unmodified lines
15471778 pattern: /\b(?:m|qr)\s*([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1[msixpodualngc]*/,
15481779 greedy: true
15491780 },
1550−
1781+
15511782 // m a...a
15521783 {
15531784 pattern: /\b(?:m|qr)\s+([a-zA-Z0-9])(?:(?!\1)[^\\]|\\[\s\S])*\1[msixpodualngc]*/,
15541785 greedy: true
15551786 },
1556−
1787+
15571788 // m(...)
15581789 {
15591790 pattern: /\b(?:m|qr)\s*\((?:[^()\\]|\\[\s\S])*\)[msixpodualngc]*/,
15601791 greedy: true
15611792 },
1562−
1793+
15631794 // m{...}
15641795 {
15651796 pattern: /\b(?:m|qr)\s*\{(?:[^{}\\]|\\[\s\S])*\}[msixpodualngc]*/,
15661797 greedy: true
15671798 },
1568−
1799+
15691800 // m[...]
15701801 {
15711802 pattern: /\b(?:m|qr)\s*\[(?:[^[\]\\]|\\[\s\S])*\][msixpodualngc]*/,
15721803 greedy: true
15731804 },
1574−
1805+
15751806 // m<...>
15761807 {
15771808 pattern: /\b(?:m|qr)\s*<(?:[^<>\\]|\\[\s\S])*>[msixpodualngc]*/,
@@ -1586,42 +1817,42 @@ Prism.languages.perl = { · 8 unmodified lines
15861817 lookbehind: true,
15871818 greedy: true
15881819 },
1589−
1820+
15901821 // s a...a...a
15911822 {
15921823 pattern: /(^|[^-]\b)(?:s|tr|y)\s+([a-zA-Z0-9])(?:(?!\2)[^\\]|\\[\s\S])*\2(?:(?!\2)[^\\]|\\[\s\S])*\2[msixpodualngcer]*/,
15931824 lookbehind: true,
15941825 greedy: true
15951826 },
1596−
1827+
15971828 // s(...)(...)
15981829 {
15991830 pattern: /(^|[^-]\b)(?:s|tr|y)\s*\((?:[^()\\]|\\[\s\S])*\)\s*\((?:[^()\\]|\\[\s\S])*\)[msixpodualngcer]*/,
16001831 lookbehind: true,
16011832 greedy: true
16021833 },
1603−
1834+
16041835 // s{...}{...}
16051836 {
16061837 pattern: /(^|[^-]\b)(?:s|tr|y)\s*\{(?:[^{}\\]|\\[\s\S])*\}\s*\{(?:[^{}\\]|\\[\s\S])*\}[msixpodualngcer]*/,
16071838 lookbehind: true,
16081839 greedy: true
16091840 },
1610−
1841+
16111842 // s[...][...]
16121843 {
16131844 pattern: /(^|[^-]\b)(?:s|tr|y)\s*\[(?:[^[\]\\]|\\[\s\S])*\]\s*\[(?:[^[\]\\]|\\[\s\S])*\][msixpodualngcer]*/,
16141845 lookbehind: true,
16151846 greedy: true
16161847 },
1617−
1848+
16181849 // s<...><...>
16191850 {
16201851 pattern: /(^|[^-]\b)(?:s|tr|y)\s*<(?:[^<>\\]|\\[\s\S])*>\s*<(?:[^<>\\]|\\[\s\S])*>[msixpodualngcer]*/,
16211852 lookbehind: true,
16221853 greedy: true
16231854 },
1624−
1855+
16251856 // /.../
16261857 // The look-ahead tries to prevent two divisions on
16271858 // the same line from being highlighted as regex.
@@ -1665,7 +1896,7 @@ Prism.languages.perl = { · 37 unmodified lines
16651896 }
16661897 },
16671898 'keyword': /\b(?:any|break|continue|default|delete|die|do|else|elsif|eval|for|foreach|given|goto|if|last|local|my|next|our|package|print|redo|require|say|state|sub|switch|undef|unless|until|use|when|while)\b/,
1668− 'number': /\b-?(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0b[01](?:_?[01])*|(?:\d(?:_?\d)*)?\.?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)\b/,
1899+ 'number': /\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0b[01](?:_?[01])*|(?:\d(?:_?\d)*)?\.?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)\b/,
16691900 'operator': /-[rwxoRWXOezsfdlpSbctugkTBMAC]\b|\+[+=]?|-[-=>]?|\*\*?=?|\/\/?=?|=[=~>]?|~[~=]?|\|\|?=?|&&?=?|<(?:=>?|<=?)?|>>?=?|![~=]?|[%^]=?|\.(?:=|\.\.?)?|[\\?]|\bx(?:=|\b)|\b(?:lt|gt|le|ge|eq|ne|cmp|not|and|or|xor)\b/,
16701901 'punctuation': /[{}[\];(),:]/
16711902 };
@@ -1682,110 +1913,211 @@ Prism.languages.perl = { · 10 unmodified lines
16821913 * Adds the following new token classes:
16831914 * constant, delimiter, variable, function, package
16841915 */
1916+(function (Prism) {
1917+ Prism.languages.php = Prism.languages.extend('clike', {
1918+ 'keyword': /\b(?:and|or|xor|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|for|foreach|function|include|include_once|global|if|new|return|static|switch|use|require|require_once|var|while|abstract|interface|public|implements|private|protected|parent|throw|null|echo|print|trait|namespace|final|yield|goto|instanceof|finally|try|catch)\b/i,
1919+ 'constant': /\b[A-Z0-9_]{2,}\b/,
1920+ 'comment': {
1921+ pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,
1922+ lookbehind: true
1923+ }
1924+ });
16851925
1686−Prism.languages.php = Prism.languages.extend('clike', {
1687− 'keyword': /\b(?:and|or|xor|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|for|foreach|function|include|include_once|global|if|new|return|static|switch|use|require|require_once|var|while|abstract|interface|public|implements|private|protected|parent|throw|null|echo|print|trait|namespace|final|yield|goto|instanceof|finally|try|catch)\b/i,
1688− 'constant': /\b[A-Z0-9_]{2,}\b/,
1689− 'comment': {
1690− pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,
1691− lookbehind: true
1692− }
1693−});
1926+ Prism.languages.insertBefore('php', 'string', {
1927+ 'shell-comment': {
1928+ pattern: /(^|[^\\])#.*/,
1929+ lookbehind: true,
1930+ alias: 'comment'
1931+ }
1932+ });
16941933
1695−// Shell-like comments are matched after strings, because they are less
1696−// common than strings containing hashes...
1697−Prism.languages.insertBefore('php', 'class-name', {
1698− 'shell-comment': {
1699− pattern: /(^|[^\\])#.*/,
1700− lookbehind: true,
1701− alias: 'comment'
1702− }
1703−});
1934+ Prism.languages.insertBefore('php', 'keyword', {
1935+ 'delimiter': {
1936+ pattern: /\?>|<\?(?:php|=)?/i,
1937+ alias: 'important'
1938+ },
1939+ 'variable': /\$+(?:\w+\b|(?={))/i,
1940+ 'package': {
1941+ pattern: /(\\|namespace\s+|use\s+)[\w\\]+/,
1942+ lookbehind: true,
1943+ inside: {
1944+ punctuation: /\\/
1945+ }
1946+ }
1947+ });
17041948
1705−Prism.languages.insertBefore('php', 'keyword', {
1706− 'delimiter': {
1707− pattern: /\?>|<\?(?:php|=)?/i,
1708− alias: 'important'
1709− },
1710− 'variable': /\$\w+\b/i,
1711− 'package': {
1712− pattern: /(\\|namespace\s+|use\s+)[\w\\]+/,
1713− lookbehind: true,
1714− inside: {
1715− punctuation: /\\/
1949+ // Must be defined after the function pattern
1950+ Prism.languages.insertBefore('php', 'operator', {
1951+ 'property': {
1952+ pattern: /(->)[\w]+/,
1953+ lookbehind: true
17161954 }
1717− }
1718−});
1955+ });
17191956
1720−// Must be defined after the function pattern
1721−Prism.languages.insertBefore('php', 'operator', {
1722− 'property': {
1723− pattern: /(->)[\w]+/,
1724− lookbehind: true
1725− }
1726−});
1957+ Prism.languages.insertBefore('php', 'string', {
1958+ 'nowdoc-string': {
1959+ pattern: /<<<'([^']+)'(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\1;/,
1960+ greedy: true,
1961+ alias: 'string',
1962+ inside: {
1963+ 'delimiter': {
1964+ pattern: /^<<<'[^']+'|[a-z_]\w*;$/i,
1965+ alias: 'symbol',
1966+ inside: {
1967+ 'punctuation': /^<<<'?|[';]$/
1968+ }
1969+ }
1970+ }
1971+ },
1972+ 'heredoc-string': {
1973+ pattern: /<<<(?:"([^"]+)"(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\1;|([a-z_]\w*)(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\2;)/i,
1974+ greedy: true,
1975+ alias: 'string',
1976+ inside: {
1977+ 'delimiter': {
1978+ pattern: /^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i,
1979+ alias: 'symbol',
1980+ inside: {
1981+ 'punctuation': /^<<<"?|[";]$/
1982+ }
1983+ },
1984+ 'interpolation': null // See below
1985+ }
1986+ },
1987+ 'single-quoted-string': {
1988+ pattern: /'(?:\\[\s\S]|[^\\'])*'/,
1989+ greedy: true,
1990+ alias: 'string'
1991+ },
1992+ 'double-quoted-string': {
1993+ pattern: /"(?:\\[\s\S]|[^\\"])*"/,
1994+ greedy: true,
1995+ alias: 'string',
1996+ inside: {
1997+ 'interpolation': null // See below
1998+ }
1999+ }
2000+ });
2001+ // The different types of PHP strings "replace" the C-like standard string
2002+ delete Prism.languages.php['string'];
17272003
1728−// Add HTML support if the markup language exists
1729−if (Prism.languages.markup) {
2004+ var string_interpolation = {
2005+ pattern: /{\$(?:{(?:{[^{}]+}|[^{}]+)}|[^{}])+}|(^|[^\\{])\$+(?:\w+(?:\[.+?]|->\w+)*)/,
2006+ lookbehind: true,
2007+ inside: {
2008+ rest: Prism.languages.php
2009+ }
2010+ };
2011+ Prism.languages.php['heredoc-string'].inside['interpolation'] = string_interpolation;
2012+ Prism.languages.php['double-quoted-string'].inside['interpolation'] = string_interpolation;
17302013
1731− // Tokenize all inline PHP blocks that are wrapped in <?php ?>
1732− // This allows for easy PHP + markup highlighting
1733− Prism.hooks.add('before-highlight', function(env) {
1734− if (env.language !== 'php' || !/(?:<\?php|<\?)/ig.test(env.code)) {
2014+ Prism.hooks.add('before-tokenize', function(env) {
2015+ if (!/(?:<\?php|<\?)/ig.test(env.code)) {
17352016 return;
17362017 }
17372018
1738− env.tokenStack = [];
1739−
1740− env.backupCode = env.code;
1741− env.code = env.code.replace(/(?:<\?php|<\?)[\s\S]*?(?:\?>|$)/ig, function(match) {
1742− var i = env.tokenStack.length;
1743− // Check for existing strings
1744− while (env.backupCode.indexOf('___PHP' + i + '___') !== -1)
1745− ++i;
1746−
1747− // Create a sparse array
1748− env.tokenStack[i] = match;
1749−
1750− return '___PHP' + i + '___';
1751− });
2019+ var phpPattern = /(?:<\?php|<\?)[\s\S]*?(?:\?>|$)/ig;
2020+ Prism.languages['markup-templating'].buildPlaceholders(env, 'php', phpPattern);
2021+ });
17522022
1753− // Switch the grammar to markup
1754− env.grammar = Prism.languages.markup;
2023+ Prism.hooks.add('after-tokenize', function(env) {
2024+ Prism.languages['markup-templating'].tokenizePlaceholders(env, 'php');
17552025 });
17562026
1757− // Restore env.code for other plugins (e.g. line-numbers)
1758− Prism.hooks.add('before-insert', function(env) {
1759− if (env.language === 'php' && env.backupCode) {
1760− env.code = env.backupCode;
1761− delete env.backupCode;
2027+}(Prism));
2028+Prism.languages.sql= {
2029+ 'comment': {
2030+ pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,
2031+ lookbehind: true
2032+ },
2033+ 'string' : {
2034+ pattern: /(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\])*\2/,
2035+ greedy: true,
2036+ lookbehind: true
2037+ },
2038+ 'variable': /@[\w.$]+|@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,
2039+ 'function': /\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i, // Should we highlight user defined functions too?
2040+ 'keyword': /\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:_INSERT|COL)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURNS?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,
2041+ 'boolean': /\b(?:TRUE|FALSE|NULL)\b/i,
2042+ 'number': /\b0x[\da-f]+\b|\b\d+\.?\d*|\B\.\d+\b/i,
2043+ 'operator': /[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|IN|LIKE|NOT|OR|IS|DIV|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,
2044+ 'punctuation': /[;[\]()`,.]/
2045+};
2046+Prism.languages.scss = Prism.languages.extend('css', {
2047+ 'comment': {
2048+ pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,
2049+ lookbehind: true
2050+ },
2051+ 'atrule': {
2052+ pattern: /@[\w-]+(?:\([^()]+\)|[^(])*?(?=\s+[{;])/,
2053+ inside: {
2054+ 'rule': /@[\w-]+/
2055+ // See rest below
17622056 }
1763− });
2057+ },
2058+ // url, compassified
2059+ 'url': /(?:[-a-z]+-)*url(?=\()/i,
2060+ // CSS selector regex is not appropriate for Sass
2061+ // since there can be lot more things (var, @ directive, nesting..)
2062+ // a selector must start at the end of a property or after a brace (end of other rules or nesting)
2063+ // it can contain some characters that aren't used for defining rules or end of selector, & (parent selector), or interpolated variable
2064+ // the end of a selector is found when there is no rules in it ( {} or {\s}) or if there is a property (because an interpolated var
2065+ // can "pass" as a selector- e.g: proper#{$erty})
2066+ // this one was hard to do, so please be careful if you edit this one :)
2067+ 'selector': {
2068+ // Initial look-ahead is used to prevent matching of blank selectors
2069+ pattern: /(?=\S)[^@;{}()]?(?:[^@;{}()]|&|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}]+[:{][^}]+))/m,
2070+ inside: {
2071+ 'parent': {
2072+ pattern: /&/,
2073+ alias: 'important'
2074+ },
2075+ 'placeholder': /%[-\w]+/,
2076+ 'variable': /\$[-\w]+|#\{\$[-\w]+\}/
2077+ }
2078+ }
2079+});
17642080
1765− // Re-insert the tokens after highlighting
1766− Prism.hooks.add('after-highlight', function(env) {
1767− if (env.language !== 'php' || !env.tokenStack) {
1768− return;
2081+Prism.languages.insertBefore('scss', 'atrule', {
2082+ 'keyword': [
2083+ /@(?:if|else(?: if)?|for|each|while|import|extend|debug|warn|mixin|include|function|return|content)/i,
2084+ {
2085+ pattern: /( +)(?:from|through)(?= )/,
2086+ lookbehind: true
17692087 }
2088+ ]
2089+});
17702090
1771− // Switch the grammar back
1772− env.grammar = Prism.languages.php;
2091+Prism.languages.scss.property = {
2092+ pattern: /(?:[\w-]|\$[-\w]+|#\{\$[-\w]+\})+(?=\s*:)/i,
2093+ inside: {
2094+ 'variable': /\$[-\w]+|#\{\$[-\w]+\}/
2095+ }
2096+};
17732097
1774− for (var i = 0, keys = Object.keys(env.tokenStack); i < keys.length; ++i) {
1775− var k = keys[i];
1776− var t = env.tokenStack[k];
2098+Prism.languages.insertBefore('scss', 'important', {
2099+ // var and interpolated vars
2100+ 'variable': /\$[-\w]+|#\{\$[-\w]+\}/
2101+});
17772102
1778− // The replace prevents $$, $&, $`, $', $n, $nn from being interpreted as special patterns
1779− env.highlightedCode = env.highlightedCode.replace('___PHP' + k + '___',
1780− "<span class=\"token php language-php\">" +
1781− Prism.highlight(t, env.grammar, 'php').replace(/\$/g, '$$$$') +
1782− "</span>");
1783− }
2103+Prism.languages.insertBefore('scss', 'function', {
2104+ 'placeholder': {
2105+ pattern: /%[-\w]+/,
2106+ alias: 'selector'
2107+ },
2108+ 'statement': {
2109+ pattern: /\B!(?:default|optional)\b/i,
2110+ alias: 'keyword'
2111+ },
2112+ 'boolean': /\b(?:true|false)\b/,
2113+ 'null': /\bnull\b/,
2114+ 'operator': {
2115+ pattern: /(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|or|not)(?=\s)/,
2116+ lookbehind: true
2117+ }
2118+});
17842119
1785− env.element.innerHTML = env.highlightedCode;
1786− });
1787−}
1788−;
2120+Prism.languages.scss['atrule'].inside.rest = Prism.languages.scss;
17892121 Prism.languages.python = {
17902122 'comment': {
17912123 pattern: /(^|[^\\])#.*/,
@@ -1811,7 +2143,7 @@ Prism.languages.python = { · 19 unmodified lines
18112143 'keyword': /\b(?:as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|nonlocal|pass|print|raise|return|try|while|with|yield)\b/,
18122144 'builtin':/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,
18132145 'boolean': /\b(?:True|False|None)\b/,
1814− 'number': /\b-?(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*\.?\d*|\.\d+)(?:e[+-]?\d+)?j?\b/i,
2146+ 'number': /(?:\b(?=\d)|\B(?=\.))(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*\.?\d*|\.\d+)(?:e[+-]?\d+)?j?\b/i,
18152147 'operator': /[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]|\b(?:or|and|not)\b/,
18162148 'punctuation': /[{}[\];(),.:]/
18172149 };
@@ -1821,93 +2153,134 @@ Prism.languages.python = { · 3 unmodified lines
18212153 var javascript = Prism.util.clone(Prism.languages.javascript);
18222154
18232155 Prism.languages.jsx = Prism.languages.extend('markup', javascript);
1824−Prism.languages.jsx.tag.pattern= /<\/?[\w.:-]+\s*(?:\s+(?:[\w\.:-]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+|(?:\{[^}]*\})))?|\{\.{3}\w+\}))*\s*\/?>/i;
2156+Prism.languages.jsx.tag.pattern= /<\/?(?:[\w.:-]+\s*(?:\s+(?:[\w.:-]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s{'">=]+|\{(?:\{(?:\{[^}]*\}|[^{}])*\}|[^{}])+\}))?|\{\.{3}[a-z_$][\w$]*(?:\.[a-z_$][\w$]*)*\}))*\s*\/?)?>/i;
18252157
2158+Prism.languages.jsx.tag.inside['tag'].pattern = /^<\/?[^\s>\/]*/i;
18262159 Prism.languages.jsx.tag.inside['attr-value'].pattern = /=(?!\{)(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">]+)/i;
18272160
18282161 Prism.languages.insertBefore('inside', 'attr-name', {
18292162 'spread': {
1830− pattern: /\{\.{3}\w+\}/,
2163+ pattern: /\{\.{3}[a-z_$][\w$]*(?:\.[a-z_$][\w$]*)*\}/,
18312164 inside: {
1832− 'punctuation': /[{}]|\.{3}/,
2165+ 'punctuation': /\.{3}|[{}.]/,
18332166 'attr-value': /\w+/
18342167 }
18352168 }
18362169 }, Prism.languages.jsx.tag);
18372170
1838−var jsxExpression = Prism.util.clone(Prism.languages.jsx);
1839−
1840−delete jsxExpression.punctuation;
1841−
1842−jsxExpression = Prism.languages.insertBefore('jsx', 'operator', {
1843− 'punctuation': /=(?={)|[{}[\];(),.:]/
1844−}, { jsx: jsxExpression });
1845−
18462171 Prism.languages.insertBefore('inside', 'attr-value',{
18472172 'script': {
1848− // Allow for one level of nesting
1849− pattern: /=(\{(?:\{[^}]*\}|[^}])+\})/i,
1850− inside: jsxExpression,
2173+ // Allow for two levels of nesting
2174+ pattern: /=(\{(?:\{(?:\{[^}]*\}|[^}])*\}|[^}])+\})/i,
2175+ inside: {
2176+ 'script-punctuation': {
2177+ pattern: /^=(?={)/,
2178+ alias: 'punctuation'
2179+ },
2180+ rest: Prism.languages.jsx
2181+ },
18512182 'alias': 'language-javascript'
18522183 }
18532184 }, Prism.languages.jsx.tag);
18542185
1855−}(Prism));
2186+// The following will handle plain text inside tags
2187+var stringifyToken = function (token) {
2188+ if (!token) {
2189+ return '';
2190+ }
2191+ if (typeof token === 'string') {
2192+ return token;
2193+ }
2194+ if (typeof token.content === 'string') {
2195+ return token.content;
2196+ }
2197+ return token.content.map(stringifyToken).join('');
2198+};
18562199
1857−(function(Prism) {
1858− Prism.languages.crystal = Prism.languages.extend('ruby', {
1859− keyword: [
1860− /\b(?:abstract|alias|as|asm|begin|break|case|class|def|do|else|elsif|end|ensure|enum|extend|for|fun|if|include|instance_sizeof|lib|macro|module|next|of|out|pointerof|private|protected|rescue|return|require|select|self|sizeof|struct|super|then|type|typeof|uninitialized|union|unless|until|when|while|with|yield|__DIR__|__END_LINE__|__FILE__|__LINE__)\b/,
1861− {
1862− pattern: /(\.\s*)(?:is_a|responds_to)\?/,
1863− lookbehind: true
1864− }
1865− ],
2200+var walkTokens = function (tokens) {
2201+ var openedTags = [];
2202+ for (var i = 0; i < tokens.length; i++) {
2203+ var token = tokens[i];
2204+ var notTagNorBrace = false;
2205+
2206+ if (typeof token !== 'string') {
2207+ if (token.type === 'tag' && token.content[0] && token.content[0].type === 'tag') {
2208+ // We found a tag, now find its kind
2209+
2210+ if (token.content[0].content[0].content === '</') {
2211+ // Closing tag
2212+ if (openedTags.length > 0 && openedTags[openedTags.length - 1].tagName === stringifyToken(token.content[0].content[1])) {
2213+ // Pop matching opening tag
2214+ openedTags.pop();
2215+ }
2216+ } else {
2217+ if (token.content[token.content.length - 1].content === '/>') {
2218+ // Autoclosed tag, ignore
2219+ } else {
2220+ // Opening tag
2221+ openedTags.push({
2222+ tagName: stringifyToken(token.content[0].content[1]),
2223+ openedBraces: 0
2224+ });
2225+ }
2226+ }
2227+ } else if (openedTags.length > 0 && token.type === 'punctuation' && token.content === '{') {
18662228
1867− number: /\b(?:0b[01_]*[01]|0o[0-7_]*[0-7]|0x[0-9a-fA-F_]*[0-9a-fA-F]|(?:\d(?:[0-9_]*\d)?)(?:\.[0-9_]*\d)?(?:[eE][+-]?[0-9_]*\d)?)(?:_(?:[uif](?:8|16|32|64))?)?\b/
1868− });
2229+ // Here we might have entered a JSX context inside a tag
2230+ openedTags[openedTags.length - 1].openedBraces++;
18692231
1870− var rest = Prism.util.clone(Prism.languages.crystal);
2232+ } else if (openedTags.length > 0 && openedTags[openedTags.length - 1].openedBraces > 0 && token.type === 'punctuation' && token.content === '}') {
18712233
1872− Prism.languages.insertBefore('crystal', 'string', {
1873− attribute: {
1874− pattern: /@\[.+?\]/,
1875− alias: 'attr-name',
1876− inside: {
1877− delimiter: {
1878− pattern: /^@\[|\]$/,
1879− alias: 'tag'
1880− },
1881− rest: rest
1882− }
1883− },
2234+ // Here we might have left a JSX context inside a tag
2235+ openedTags[openedTags.length - 1].openedBraces--;
18842236
1885− expansion: [
1886− {
1887− pattern: /\{\{.+?\}\}/,
1888− inside: {
1889− delimiter: {
1890− pattern: /^\{\{|\}\}$/,
1891− alias: 'tag'
1892− },
1893− rest: rest
2237+ } else {
2238+ notTagNorBrace = true
18942239 }
1895− },
1896− {
1897− pattern: /\{%.+?%\}/,
1898− inside: {
1899− delimiter: {
1900− pattern: /^\{%|%\}$/,
1901− alias: 'tag'
1902− },
1903− rest: rest
2240+ }
2241+ if (notTagNorBrace || typeof token === 'string') {
2242+ if (openedTags.length > 0 && openedTags[openedTags.length - 1].openedBraces === 0) {
2243+ // Here we are inside a tag, and not inside a JSX context.
2244+ // That's plain text: drop any tokens matched.
2245+ var plainText = stringifyToken(token);
2246+
2247+ // And merge text with adjacent text
2248+ if (i < tokens.length - 1 && (typeof tokens[i + 1] === 'string' || tokens[i + 1].type === 'plain-text')) {
2249+ plainText += stringifyToken(tokens[i + 1]);
2250+ tokens.splice(i + 1, 1);
2251+ }
2252+ if (i > 0 && (typeof tokens[i - 1] === 'string' || tokens[i - 1].type === 'plain-text')) {
2253+ plainText = stringifyToken(tokens[i - 1]) + plainText;
2254+ tokens.splice(i - 1, 1);
2255+ i--;
2256+ }
2257+
2258+ tokens[i] = new Prism.Token('plain-text', plainText, null, plainText);
19042259 }
19052260 }
1906− ]
1907− });
2261+
2262+ if (token.content && typeof token.content !== 'string') {
2263+ walkTokens(token.content);
2264+ }
2265+ }
2266+};
2267+
2268+Prism.hooks.add('after-tokenize', function (env) {
2269+ if (env.language !== 'jsx' && env.language !== 'tsx') {
2270+ return;
2271+ }
2272+ walkTokens(env.tokens);
2273+});
19082274
19092275 }(Prism));
19102276
2277+Prism.languages.typescript = Prism.languages.extend('javascript', {
2278+ // From JavaScript Prism keyword list and TypeScript language spec: https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#221-reserved-words
2279+ 'keyword': /\b(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield|module|declare|constructor|namespace|abstract|require|type)\b/,
2280+ 'builtin': /\b(?:string|Function|any|number|boolean|Array|symbol|console)\b/,
2281+});
2282+
2283+Prism.languages.ts = Prism.languages.typescript;
19112284 /* TODO
19122285 Add support for Markdown notation inside doc comments
19132286 Add support for nested block comments...
@@ -1932,10 +2305,18 @@ Prism.languages.rust = { · 18 unmodified lines
19322305 greedy: true
19332306 },
19342307 {
1935− pattern: /b?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,
2308+ pattern: /b?"(?:\\.|[^\\\r\n"])*"/,
19362309 greedy: true
19372310 }
19382311 ],
2312+ 'char': {
2313+ pattern: /b?'(?:\\(?:x[0-7][\da-fA-F]|u{(?:[\da-fA-F]_*){1,6}|.)|[^\\\r\n\t'])'/,
2314+ alias: 'string'
2315+ },
2316+ 'lifetime-annotation': {
2317+ pattern: /'[^\s>']+/,
2318+ alias: 'symbol'
2319+ },
19392320 'keyword': /\b(?:abstract|alignof|as|be|box|break|const|continue|crate|do|else|enum|extern|false|final|fn|for|if|impl|in|let|loop|match|mod|move|mut|offsetof|once|override|priv|pub|pure|ref|return|sizeof|static|self|struct|super|true|trait|type|typeof|unsafe|unsized|use|virtual|where|while|yield)\b/,
19402321
19412322 'attribute': {
@@ -1955,7 +2336,7 @@ Prism.languages.rust = { · 13 unmodified lines
19552336 },
19562337
19572338 // Hex, oct, bin, dec numbers with visual separators and type suffix
1958− 'number': /\b-?(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(\d(?:_?\d)*)?\.?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:[iu](?:8|16|32|64)?|f32|f64))?\b/,
2339+ 'number': /\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(\d(?:_?\d)*)?\.?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:[iu](?:8|16|32|64)?|f32|f64))?\b/,
19592340
19602341 // Closure params should not be confused with bitwise OR |
19612342 'closure-params': {
@@ -1966,107 +2347,8 @@ Prism.languages.rust = { · 4 unmodified lines
19662347 }
19672348 },
19682349 'punctuation': /[{}[\];(),:]|\.+|->/,
1969− 'operator': /[-+*\/%!^=]=?|@|&[&=]?|\|[|=]?|<<?=?|>>?=?/
2350+ 'operator': /[-+*\/%!^]=?|=[=>]?|@|&[&=]?|\|[|=]?|<<?=?|>>?=?/
19702351 };
1971−Prism.languages.scss = Prism.languages.extend('css', {
1972− 'comment': {
1973− pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,
1974− lookbehind: true
1975− },
1976− 'atrule': {
1977− pattern: /@[\w-]+(?:\([^()]+\)|[^(])*?(?=\s+[{;])/,
1978− inside: {
1979− 'rule': /@[\w-]+/
1980− // See rest below
1981− }
1982− },
1983− // url, compassified
1984− 'url': /(?:[-a-z]+-)*url(?=\()/i,
1985− // CSS selector regex is not appropriate for Sass
1986− // since there can be lot more things (var, @ directive, nesting..)
1987− // a selector must start at the end of a property or after a brace (end of other rules or nesting)
1988− // it can contain some characters that aren't used for defining rules or end of selector, & (parent selector), or interpolated variable
1989− // the end of a selector is found when there is no rules in it ( {} or {\s}) or if there is a property (because an interpolated var
1990− // can "pass" as a selector- e.g: proper#{$erty})
1991− // this one was hard to do, so please be careful if you edit this one :)
1992− 'selector': {
1993− // Initial look-ahead is used to prevent matching of blank selectors
1994− pattern: /(?=\S)[^@;{}()]?(?:[^@;{}()]|&|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}]+[:{][^}]+))/m,
1995− inside: {
1996− 'parent': {
1997− pattern: /&/,
1998− alias: 'important'
1999− },
2000− 'placeholder': /%[-\w]+/,
2001− 'variable': /\$[-\w]+|#\{\$[-\w]+\}/
2002− }
2003− }
2004−});
2005−
2006−Prism.languages.insertBefore('scss', 'atrule', {
2007− 'keyword': [
2008− /@(?:if|else(?: if)?|for|each|while|import|extend|debug|warn|mixin|include|function|return|content)/i,
2009− {
2010− pattern: /( +)(?:from|through)(?= )/,
2011− lookbehind: true
2012− }
2013− ]
2014−});
2015−
2016−Prism.languages.scss.property = {
2017− pattern: /(?:[\w-]|\$[-\w]+|#\{\$[-\w]+\})+(?=\s*:)/i,
2018− inside: {
2019− 'variable': /\$[-\w]+|#\{\$[-\w]+\}/
2020− }
2021−};
2022−
2023−Prism.languages.insertBefore('scss', 'important', {
2024− // var and interpolated vars
2025− 'variable': /\$[-\w]+|#\{\$[-\w]+\}/
2026−});
2027−
2028−Prism.languages.insertBefore('scss', 'function', {
2029− 'placeholder': {
2030− pattern: /%[-\w]+/,
2031− alias: 'selector'
2032− },
2033− 'statement': {
2034− pattern: /\B!(?:default|optional)\b/i,
2035− alias: 'keyword'
2036− },
2037− 'boolean': /\b(?:true|false)\b/,
2038− 'null': /\bnull\b/,
2039− 'operator': {
2040− pattern: /(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|or|not)(?=\s)/,
2041− lookbehind: true
2042− }
2043−});
2044−
2045−Prism.languages.scss['atrule'].inside.rest = Prism.util.clone(Prism.languages.scss);
2046−Prism.languages.sql= {
2047− 'comment': {
2048− pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,
2049− lookbehind: true
2050− },
2051− 'string' : {
2052− pattern: /(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\])*\2/,
2053− greedy: true,
2054− lookbehind: true
2055− },
2056− 'variable': /@[\w.$]+|@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,
2057− 'function': /\b(?:COUNT|SUM|AVG|MIN|MAX|FIRST|LAST|UCASE|LCASE|MID|LEN|ROUND|NOW|FORMAT)(?=\s*\()/i, // Should we highlight user defined functions too?
2058− 'keyword': /\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR VARYING|CHARACTER (?:SET|VARYING)|CHARSET|CHECK|CHECKPOINT|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMN|COLUMNS|COMMENT|COMMIT|COMMITTED|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS|CONTAINSTABLE|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|DATA(?:BASES?)?|DATE(?:TIME)?|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITER(?:S)?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE(?: PRECISION)?|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE KEY|ELSE|ENABLE|ENCLOSED BY|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPE(?:D BY)?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|IDENTITY(?:_INSERT|COL)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTO|INVOKER|ISOLATION LEVEL|JOIN|KEYS?|KILL|LANGUAGE SQL|LAST|LEFT|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MODIFIES SQL DATA|MODIFY|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL(?: CHAR VARYING| CHARACTER(?: VARYING)?| VARCHAR)?|NATURAL|NCHAR(?: VARCHAR)?|NEXT|NO(?: SQL|CHECK|CYCLE)?|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READ(?:S SQL DATA|TEXT)?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEATABLE|REPLICATION|REQUIRE|RESTORE|RESTRICT|RETURNS?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE MODE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|START(?:ING BY)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED BY|TEXT(?:SIZE)?|THEN|TIMESTAMP|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNPIVOT|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?)\b/i,
2059− 'boolean': /\b(?:TRUE|FALSE|NULL)\b/i,
2060− 'number': /\b-?(?:0x)?\d*\.?[\da-f]+\b/,
2061− 'operator': /[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|IN|LIKE|NOT|OR|IS|DIV|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,
2062− 'punctuation': /[;[\]()`,.]/
2063−};
2064−Prism.languages.typescript = Prism.languages.extend('javascript', {
2065− // From JavaScript Prism keyword list and TypeScript language spec: https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#221-reserved-words
2066− 'keyword': /\b(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield|false|true|module|declare|constructor|string|Function|any|number|boolean|Array|symbol|namespace|abstract|require|type)\b/
2067−});
2068−
2069−Prism.languages.ts = Prism.languages.typescript;
20702352 Prism.languages.yaml = {
20712353 'scalar': {
20722354 pattern: /([\-:]\s*(?:![^\s]+)?[ \t]*[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)[^\r\n]+(?:\2[^\r\n]+)*)/,
@@ -2105,11 +2387,10 @@ Prism.languages.yaml = { · 32 unmodified lines
21052387 greedy: true
21062388 },
21072389 'number': {
2108− pattern: /([:\-,[{]\s*(?:![^\s]+)?[ \t]*)[+\-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+\.?\d*|\.?\d+)(?:e[+-]?\d+)?|\.inf|\.nan)[ \t]*(?=$|,|]|})/im,
2390+ pattern: /([:\-,[{]\s*(?:![^\s]+)?[ \t]*)[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+\.?\d*|\.?\d+)(?:e[+-]?\d+)?|\.inf|\.nan)[ \t]*(?=$|,|]|})/im,
21092391 lookbehind: true
21102392 },
21112393 'tag': /![^\s]+/,
21122394 'important': /[&*][\w]+/,
21132395 'punctuation': /---|[:[\]{}\-,|>?]|\.\.\./
21142396 };
2115−
assets/javascripts/views/content/root_page.coffee+0−4
@@ -19,10 +19,6 @@ class app.views.RootPage extends app.View · 18 unmodified lines
1919 else
2020 'intro'
2121
22− # temporary
23− if location.host is 'devdocs.io' and location.protocol is 'http:'
24− tmpl = 'httpWarning'
25−
2622 @append @tmpl(tmpl)
2723 return
2824
assets/javascripts/views/content/settings_page.coffee+3−4
@@ -24,10 +24,9 @@ class app.views.SettingsPage extends app.View · 23 unmodified lines
2424 'Preferences'
2525
2626 toggleDark: (enable) ->
27− css = $('link[rel="stylesheet"][data-alt]')
28− alt = css.getAttribute('data-alt')
29− css.setAttribute('data-alt', css.getAttribute('href'))
30− css.setAttribute('href', alt)
27+ html = document.documentElement
28+ html.classList.toggle('_theme-default')
29+ html.classList.toggle('_theme-dark')
3130 app.settings.set('dark', !!enable)
3231 app.appCache?.updateInBackground()
3332 return
assets/javascripts/views/search/search.coffee+5−0
@@ -17,6 +17,7 @@ class app.views.Search extends app.View · 16 unmodified lines
1717 typing: 'focus'
1818 altG: 'google'
1919 altS: 'stackoverflow'
20+ altD: 'duckduckgo'
2021
2122 @routes:
2223 after: 'afterRoute'
@@ -113,6 +114,10 @@ class app.views.Search extends app.View · 90 unmodified lines
113114 @externalSearch "https://stackoverflow.com/search?q="
114115 return
115116
117+ duckduckgo: =>
118+ @externalSearch "https://duckduckgo.com/?t=devdocs&q="
119+ return
120+
116121 onResults: (results) =>
117122 @hasResults = true if results.length
118123 @trigger 'results', results, @flags
assets/stylesheets/application-dark.css.scss+0−105
@@ -1,105 +0,0 @@
1−//= depend_on docs-1.png
2−//= depend_on docs-1@2x.png
3−//= depend_on docs-2.png
4−//= depend_on docs-2@2x.png
5−
6−/*!
7− * Copyright 2013-2018 Thibaut Courouble and other contributors
8− *
9− * This source code is licensed under the terms of the Mozilla
10− * Public License, v. 2.0, a copy of which may be obtained at:
11− * http://mozilla.org/MPL/2.0/
12− */
13−
14−@import 'global/variables-dark',
15− 'global/mixins',
16− 'global/icons',
17− 'global/classes',
18− 'global/base';
19−
20−@import 'components/app',
21− 'components/header',
22− 'components/notif',
23− 'components/sidebar',
24− 'components/settings',
25− 'components/content',
26− 'components/page',
27− 'components/fail',
28− 'components/path',
29− 'components/notice',
30− 'components/prism',
31− 'components/mobile';
32−
33−@import 'pages/simple',
34− 'pages/angular',
35− 'pages/angularjs',
36− 'pages/apache',
37− 'pages/async',
38− 'pages/bootstrap',
39− 'pages/c',
40− 'pages/cakephp',
41− 'pages/clojure',
42− 'pages/codeception',
43− 'pages/coffeescript',
44− 'pages/cordova',
45− 'pages/crystal',
46− 'pages/d',
47− 'pages/d3',
48− 'pages/dojo',
49− 'pages/drupal',
50− 'pages/elixir',
51− 'pages/ember',
52− 'pages/erlang',
53− 'pages/express',
54− 'pages/git',
55− 'pages/github',
56− 'pages/go',
57− 'pages/haskell',
58− 'pages/jekyll',
59− 'pages/jquery',
60− 'pages/julia',
61− 'pages/knockout',
62− 'pages/kotlin',
63− 'pages/laravel',
64− 'pages/liquid',
65− 'pages/love',
66− 'pages/lua',
67− 'pages/mariadb',
68− 'pages/mdn',
69− 'pages/meteor',
70− 'pages/modernizr',
71− 'pages/moment',
72− 'pages/nginx',
73− 'pages/node',
74− 'pages/npm',
75− 'pages/openjdk',
76− 'pages/perl',
77− 'pages/phalcon',
78− 'pages/phaser',
79− 'pages/php',
80− 'pages/phpunit',
81− 'pages/postgres',
82− 'pages/pug',
83− 'pages/python',
84− 'pages/ramda',
85− 'pages/rdoc',
86− 'pages/react_native',
87− 'pages/redis',
88− 'pages/rethinkdb',
89− 'pages/rfc',
90− 'pages/rubydoc',
91− 'pages/rust',
92− 'pages/sinon',
93− 'pages/socketio',
94− 'pages/sphinx',
95− 'pages/sphinx_simple',
96− 'pages/sqlite',
97− 'pages/support_tables',
98− 'pages/tcl_tk',
99− 'pages/tensorflow',
100− 'pages/terraform',
101− 'pages/underscore',
102− 'pages/vue',
103− 'pages/webpack',
104− 'pages/yard',
105− 'pages/yii';
assets/stylesheets/application.css.scss+7−1
@@ -11,7 +11,9 @@ · 10 unmodified lines
1111 * http://mozilla.org/MPL/2.0/
1212 */
1313
14−@import 'global/variables',
14+@import 'global/variables-light',
15+ 'global/variables-dark',
16+ 'global/variables',
1517 'global/mixins',
1618 'global/icons',
1719 'global/classes',
@@ -35,6 +37,7 @@ · 17 unmodified lines
3537 'pages/angularjs',
3638 'pages/apache',
3739 'pages/async',
40+ 'pages/bash',
3841 'pages/bootstrap',
3942 'pages/c',
4043 'pages/cakephp',
@@ -45,6 +48,7 @@ · 4 unmodified lines
4548 'pages/crystal',
4649 'pages/d',
4750 'pages/d3',
51+ 'pages/dart',
4852 'pages/dojo',
4953 'pages/drupal',
5054 'pages/elixir',
@@ -54,6 +58,7 @@ · 3 unmodified lines
5458 'pages/git',
5559 'pages/github',
5660 'pages/go',
61+ 'pages/graphite',
5762 'pages/haskell',
5863 'pages/jekyll',
5964 'pages/jquery',
@@ -81,6 +86,7 @@ · 21 unmodified lines
8186 'pages/postgres',
8287 'pages/pug',
8388 'pages/python',
89+ 'pages/qt',
8490 'pages/ramda',
8591 'pages/rdoc',
8692 'pages/react_native',
assets/stylesheets/components/_app.scss+5−5
@@ -1,6 +1,6 @@
1−html._booting { background: $contentBackground; }
1+html._booting { background: var(--contentBackground); }
22 body._max-width { background: none; }
3−html._booting body._max-width { background: $documentBackground; }
3+html._booting body._max-width { background: var(--documentBackground); }
44
55 ._app {
66 position: relative;
@@ -15,8 +15,8 @@ html._booting body._max-width { background: $documentBackground; } · 8 unmodified lines
1515
1616 ._max-width & {
1717 margin: 0 auto;
18− max-width: $maxWidth;
19− background: $contentBackground;
20− box-shadow: 1px 0 $headerBorder, -1px 0 $headerBorder;
18+ max-width: var(--maxWidth);
19+ background: var(--contentBackground);
20+ box-shadow: 1px 0 var(--headerBorder), -1px 0 var(--headerBorder);
2121 }
2222 }
assets/stylesheets/components/_content.scss+27−32
@@ -4,13 +4,13 @@ · 3 unmodified lines
44
55 ._container {
66 position: relative;
7− z-index: $contentZ;
7+ z-index: var(--contentZ);
88 height: 100%;
9− margin-left: $sidebarWidth;
9+ margin-left: var(--sidebarWidth);
1010 pointer-events: none;
1111 @extend %border-box;
1212
13− @media #{$mediumScreen} { margin-left: $sidebarMediumWidth; }
13+ @include mobile { margin-left: var(--sidebarMediumWidth); }
1414
1515 ._sidebar-hidden & { margin-left: 0; }
1616 body:not(._native-scrollbars) & { -webkit-margin-end: -1px; }
@@ -30,7 +30,7 @@ · 13 unmodified lines
3030 ._sidebar-hidden &:before {
3131 content: '';
3232 display: block;
33− margin-top: $headerHeight;
33+ margin-top: var(--headerHeight);
3434 }
3535
3636 ._overlay-scrollbars & { padding-left: .625rem; }
@@ -54,7 +54,7 @@ · 17 unmodified lines
5454 font-size: 4rem;
5555 font-weight: 300;
5656 letter-spacing: -.125rem;
57− color: $loadingText;
57+ color: var(--loadingText);
5858 text-align: center;
5959 cursor: default;
6060 }
@@ -68,7 +68,7 @@ · 7 unmodified lines
6868 //
6969
7070 ._splash-title {
71− color: $splashText;
71+ color: var(--splashText);
7272 @extend %loading, %user-select-none;
7373 }
7474
@@ -88,7 +88,7 @@ · 13 unmodified lines
8888 min-height: calc(100vh - 2.375rem);
8989
9090 ._sidebar-hidden & {
91− min-height: calc(100vh - 2.375rem - #{$headerHeight});
91+ min-height: calc(100vh - 2.375rem - var(--headerHeight));
9292 }
9393 }
9494
@@ -140,12 +140,12 @@ · 45 unmodified lines
140140
141141 ._error-text {
142142 margin: 0 0 1rem;
143− color: $textColorLight;
143+ color: var(--textColorLight);
144144 }
145145
146146 ._error-links {
147147 font-size: 1rem;
148− font-weight: $boldFontWeight;
148+ font-weight: var(--boldFontWeight);
149149 }
150150
151151 ._error-link { padding: 0 .5rem; }
@@ -167,7 +167,7 @@ · 15 unmodified lines
167167 height: 1px;
168168 margin-top: .25rem;
169169 margin-left: 1rem;
170− background: $boxBorderLight;
170+ background: var(--boxBorderLight);
171171 }
172172 }
173173
@@ -197,7 +197,7 @@ · 23 unmodified lines
197197 ._toc-title {
198198 margin: 0 0 .5rem;
199199 font-size: inherit;
200− font-weight: $boldFontWeight;
200+ font-weight: var(--boldFontWeight);
201201 }
202202
203203 ._toc-list {
@@ -252,7 +252,7 @@ · 48 unmodified lines
252252 ._docs-size {
253253 text-align: right;
254254
255− > small { color: $textColorLight; }
255+ > small { color: var(--textColorLight); }
256256 }
257257
258258 ._docs-tools {
@@ -285,7 +285,7 @@ · 26 unmodified lines
285285 padding: 0 .75rem;
286286 }
287287 ._btn-link:not(._show) { display: none; }
288− ._btn-link._show ~ ._btn-link._show { border-left: 1px solid $boxBorder; }
288+ ._btn-link._show ~ ._btn-link._show { border-left: 1px solid var(--boxBorder); }
289289 }
290290
291291 //
@@ -297,7 +297,7 @@ · 5 unmodified lines
297297 position: relative;
298298 padding-left: 10em;
299299 font-size: .8125rem;
300− color: $textColorLight;
300+ color: var(--textColorLight);
301301
302302 + ._news-row { margin-top: 1em; }
303303 }
@@ -305,7 +305,7 @@ · 1 unmodified line
305305 ._news-title {
306306 display: block;
307307 font-size: .875rem;
308− color: $textColor;
308+ color: var(--textColor);
309309 }
310310
311311 ._news-date {
@@ -372,12 +372,12 @@ · 60 unmodified lines
372372 // Utilities
373373 //
374374
375−._bold { font-weight: $boldFontWeight; }
375+._bold { font-weight: var(--boldFontWeight); }
376376 ._note { @extend %note; }
377377 ._note-green { @extend %note-green; }
378378 ._label { @extend %label; }
379379 ._code { @extend %code; }
380−._highlight { background: $highlightBackground !important; }
380+._highlight { background: var(--highlightBackground) !important; }
381381
382382 ._table { width: 100%; }
383383 ._mobile ._table { overflow-x: auto; }
@@ -396,12 +396,9 @@ · 12 unmodified lines
396396 pre:hover > & { display: block; }
397397 &:hover { opacity: 1; }
398398
399− > svg { @extend %svg-icon; }
400−
401− @if $style == 'dark' {
402− > svg { fill: white; }
403− } @else {
404− > svg { fill: black; }
399+ > svg {
400+ @extend %svg-icon;
401+ fill: var(--absolute);
405402 }
406403
407404 &._pre-clip-success > svg,
@@ -419,15 +416,13 @@ · 11 unmodified lines
419416 line-height: normal;
420417 white-space: nowrap;
421418 padding: .375rem .675rem;
422− background-image: linear-gradient(lighten($boxBackground, 4%), darken($boxBackground, 2%));
423− border: 1px solid $boxBorder;
419+ background-color: var(--boxBackground);
420+ border: 1px solid var(--boxBorder);
424421 border-radius: 3px;
425− box-shadow: 0 1px rgba($boxBorder, .08);
426422 cursor: pointer;
427423
428424 &:active {
429− background-color: $boxBackground;
430− box-shadow: inset 0 1px 1px rgba(black, .05), inset 0 1px 4px $boxBorder;
425+ box-shadow: inset 0 1px 1px rgba(black, .05), inset 0 1px 4px var(--boxBorder);
431426 }
432427 }
433428
@@ -447,18 +442,18 @@ · 13 unmodified lines
447442
448443 ._btn-link {
449444 line-height: inherit;
450− color: $linkColor;
451− text-decoration: $linkTextDecoration;
445+ color: var(--linkColor);
446+ text-decoration: var(--linkTextDecoration);
452447
453448 &:hover {
454− color: $linkColorHover;
449+ color: var(--linkColorHover);
455450 text-decoration: underline;
456451 }
457452 }
458453
459454 ._reset-btn,
460455 ._reset-btn:hover {
461− color: $textColorRed;
456+ color: var(--textColorRed);
462457 }
463458
464459 ._github-btn {
assets/stylesheets/components/_fail.scss+2−2
@@ -1,4 +1,4 @@
1−._fail {
1+._fail { // Don't use CSS variables, in case the browser doesn't support them.
22 display: block;
33 position: relative;
44 top: 1.5rem;
@@ -23,7 +23,7 @@ · 18 unmodified lines
2323 ._fail-title {
2424 margin: 0 0 1rem;
2525 font-size: 1rem;
26− font-weight: $boldFontWeight;
26+ font-weight: bold;
2727 }
2828
2929 ._fail-text, ._fail-list {
assets/stylesheets/components/_header.scss+25−35
@@ -4,20 +4,20 @@ · 3 unmodified lines
44
55 ._header {
66 position: absolute;
7− z-index: $headerZ;
7+ z-index: var(--headerZ);
88 top: 0;
99 left: 0;
1010 display: -ms-flexbox;
1111 display: flex;
12− width: $sidebarWidth;
13− height: $headerHeight;
14− background: $headerBackground;
15− border-bottom: 1px solid $headerBorder;
16− border-right: 1px solid $headerBorder;
12+ width: var(--sidebarWidth);
13+ height: var(--headerHeight);
14+ background: var(--headerBackground);
15+ border-bottom: 1px solid var(--headerBorder);
16+ border-right: 1px solid var(--headerBorder);
1717 @extend %border-box;
1818 @extend %user-select-none;
1919
20− @media #{$mediumScreen} { width: $sidebarMediumWidth; }
20+ @include mobile { width: var(--sidebarMediumWidth); }
2121 }
2222
2323 ._header-left {
@@ -35,7 +35,7 @@ · 11 unmodified lines
3535 flex: 0 0 auto;
3636 width: 2.25rem;
3737 height: 100%;
38− color: $textColorLight;
38+ color: var(--textColorLight);
3939 text-align: center;
4040
4141 &[hidden] { display: none; }
@@ -67,8 +67,8 @@ · 25 unmodified lines
6767 word-wrap: normal;
6868 overflow-wrap: normal;
6969 font-size: .875rem;
70− background: $contentBackground;
71− border: 1px solid $headerBorder;
70+ background: var(--contentBackground);
71+ border: 1px solid var(--headerBorder);
7272 border-radius: 3px;
7373 box-shadow: -1px 1px 1px rgba(black, .05);
7474 transition: all 0ms cubic-bezier(0.23, 1, 0.32, 1) 1ms;
@@ -98,10 +98,10 @@ · 23 unmodified lines
9898 margin: 0;
9999 line-height: 1.5rem;
100100 font-size: 1rem;
101− font-weight: $boldFontWeight;
101+ font-weight: var(--boldFontWeight);
102102 letter-spacing: -.5px;
103− background: $sidebarBackground;
104− border-bottom: 1px solid $sidebarBorder;
103+ background: var(--sidebarBackground);
104+ border-bottom: 1px solid var(--sidebarBorder);
105105 border-radius: 2px 2px 0 0;
106106 }
107107
@@ -109,7 +109,7 @@ · 1 unmodified line
109109 ._menu-title-link:hover {
110110 display: block;
111111 padding: .5rem 1rem;
112− color: $focusText;
112+ color: var(--focusText);
113113 text-decoration: none;
114114 }
115115
@@ -121,9 +121,9 @@ · 5 unmodified lines
121121 text-decoration: none;
122122
123123 &:hover {
124− color: $focusText;
124+ color: var(--focusText);
125125 text-decoration: none;
126− background: $sidebarBackground;
126+ background: var(--sidebarBackground);
127127 }
128128
129129 &:last-child { border-radius: 0 0 2px 2px; }
@@ -151,11 +151,7 @@ · 21 unmodified lines
151151 opacity: .42;
152152 @extend %svg-icon;
153153
154− @if $style == 'dark' {
155− fill: white;
156− } @else {
157− fill: black;
158− }
154+ fill: var(--absolute);
159155 }
160156 }
161157
@@ -166,21 +162,19 @@ · 4 unmodified lines
166162 height: 100%;
167163 padding: 0 .75rem 1px 1.75rem;
168164 font-size: .875rem;
169− background: $contentBackground;
165+ background: var(--contentBackground);
170166 border: 1px solid;
171− border-color: darken($headerBorder, 2%);
167+ border-color: var(--searchBorder);
172168 border-radius: 3px;
173169
174170 &:focus {
175171 outline: 0;
176− @if $inputFocusBorder {
177− border-color: $inputFocusBorder;
178− box-shadow: 0 0 1px $inputFocusBorder;
179− }
172+ border-color: var(--inputFocusBorder);
173+ box-shadow: 0 0 1px var(--inputFocusBorder);
180174 }
181175
182176 &[disabled] {
183− background: $sidebarBackground;
177+ background: var(--sidebarBackground);
184178 cursor: not-allowed;
185179 }
186180 }
@@ -202,13 +196,9 @@ · 15 unmodified lines
202196 top: .5rem;
203197 left: .375rem;
204198 @extend %svg-icon;
199+ fill: var(--absolute);
205200 }
206201
207− @if $style == 'dark' {
208− > svg { fill: white; }
209− } @else {
210− > svg { fill: black; }
211− }
212202 ._search-active > & { display: block; }
213203 }
214204
@@ -222,8 +212,8 @@ · 7 unmodified lines
222212 line-height: 1.25rem;
223213 max-width: 50%;
224214 font-size: .8125rem;
225− color: $textColorLight;
226− background: darken($headerBackground, 5%);
215+ color: var(--textColorLight);
216+ background: var(--searchTagBackground);
227217 border-radius: 2px;
228218 @extend %truncate-text;
229219 }
assets/stylesheets/components/_mobile.scss+2−2
@@ -4,7 +4,7 @@ · 3 unmodified lines
44
55 ._mobile {
66 font-size: 100%;
7− background: $contentBackground;
7+ background: var(--contentBackground);
88
99 ._hide-on-mobile { display: none; }
1010
@@ -18,7 +18,7 @@ · 7 unmodified lines
1818
1919 ._container {
2020 margin: 0;
21− padding-top: $headerHeight;
21+ padding-top: var(--headerHeight);
2222 }
2323
2424 ._content {
assets/stylesheets/components/_notice.scss+5−5
@@ -1,15 +1,15 @@
11 ._notice {
22 position: absolute;
3− z-index: $noticeZ;
3+ z-index: var(--noticeZ);
44 bottom: 0;
5− left: $sidebarWidth;
5+ left: var(--sidebarWidth);
66 right: 0;
77 height: 2.5rem;
88 padding: 0 1.25rem;
9− background: $noticeBackground;
10− box-shadow: inset 0 1px $noticeBorder;
9+ background: var(--noticeBackground);
10+ box-shadow: inset 0 1px var(--noticeBorder);
1111
12− @media #{$mediumScreen} { left: $sidebarMediumWidth; }
12+ @include mobile { left: var(--sidebarMediumWidth); }
1313
1414 ._sidebar-hidden & { left: 0; }
1515
assets/stylesheets/components/_notif.scss+12−12
@@ -7,9 +7,9 @@ · 6 unmodified lines
77 max-width: 90%;
88 padding: .625rem 1rem;
99 font-size: .75rem;
10− color: $notifColor;
11− background: $notifBackground;
12− border: $notifBorder;
10+ color: var(--notifColor);
11+ background: var(--notifBackground);
12+ border: var(--notifBorder);
1313 border-radius: .25rem;
1414 transition: opacity .2s;
1515 opacity: 0;
@@ -30,7 +30,7 @@ · 14 unmodified lines
3030
3131 ._notif-info {
3232 float: right;
33− color: $notifColorLight;
33+ color: var(--notifColorLight);
3434 }
3535
3636 ._notif-link,
@@ -69,13 +69,13 @@ · 32 unmodified lines
6969 &::-webkit-scrollbar { width: 10px !important; }
7070
7171 &::-webkit-scrollbar-track {
72− background: $notifBackground !important;
72+ background: var(--notifBackground) !important;
7373 border: 0 !important;
7474 border-radius: 5px !important;
7575 }
7676
7777 &::-webkit-scrollbar-thumb {
78− border: 3px solid $notifBackground !important;
78+ border: 3px solid var(--notifBackground) !important;
7979
8080 &:hover, &:active { border-width: 2px !important; }
8181 }
@@ -90,7 +90,7 @@ · 8 unmodified lines
9090 > ._news-row {
9191 line-height: 1.125rem;
9292 font-size: .6875rem;
93− color: $notifColorLight;
93+ color: var(--notifColorLight);
9494 margin-bottom: .25rem;
9595
9696 + ._news-row { margin-top: .625rem; }
@@ -107,7 +107,7 @@ · 10 unmodified lines
107107 ._news-date {
108108 float: right;
109109 margin-left: 1rem;
110− font-weight: $boldFontWeight;
110+ font-weight: var(--boldFontWeight);
111111 }
112112
113113 code {
@@ -128,9 +128,9 @@ · 14 unmodified lines
128128 }
129129
130130 ._notif-tip {
131− color: $textColor;
132− background: $tipBackground;
133− border: $tipBorder;
131+ color: var(--textColor);
132+ background: var(--tipBackground);
133+ border: var(--tipBorder);
134134
135− ._notif-info { color: $textColorLight; }
135+ ._notif-info { color: var(--textColorLight); }
136136 }
assets/stylesheets/components/_page.scss+4−4
@@ -23,7 +23,7 @@ · 22 unmodified lines
2323 max-width: 100%;
2424 margin-bottom: 1em;
2525 padding: 1px;
26− border: 1px dotted $boxBorder;
26+ border: 1px dotted var(--boxBorder);
2727 border-radius: 3px;
2828 @extend %border-box;
2929 }
@@ -50,7 +50,7 @@ · 20 unmodified lines
5050 display: inline-block;
5151 vertical-align: top;
5252 padding: 0 .5rem;
53− background: $contentBackground;
53+ background: var(--contentBackground);
5454 @extend %internal-link;
5555
5656 & + & { margin-left: .75rem; }
@@ -66,7 +66,7 @@ · 9 unmodified lines
6666 clear: both;
6767 margin: 2rem 0 1.5rem;
6868 font-size: .75rem;
69− color: $textColorLight;
69+ color: var(--textColorLight);
7070 text-align: center;
7171 -webkit-font-smoothing: subpixel-antialiased;
7272
@@ -78,7 +78,7 @@ · 5 unmodified lines
7878 display: inline-block;
7979 margin: 0;
8080 padding: .25rem .75rem;
81− background: $labelBackground;
81+ background: var(--labelBackground);
8282 border-radius: 3px;
8383 }
8484
assets/stylesheets/components/_path.scss+6−6
@@ -1,17 +1,17 @@
11 ._path {
22 position: absolute;
3− z-index: $noticeZ - 1;
3+ z-index: var(--headerZ);
44 bottom: 0;
5− left: $sidebarWidth;
5+ left: var(--sidebarWidth);
66 right: 0;
77 height: 2rem;
88 line-height: 2rem;
99 padding: 0 .375rem;
1010 font-size: .875rem;
11− background: $pathBackground;
12− box-shadow: inset 0 1px $pathBorder;
11+ background: var(--pathBackground);
12+ box-shadow: inset 0 1px var(--pathBorder);
1313
14− @media #{$mediumScreen} { left: $sidebarMediumWidth; }
14+ @include mobile { left: var(--sidebarMediumWidth); }
1515
1616 ._sidebar-hidden & { left: 0; }
1717
@@ -24,7 +24,7 @@ · 6 unmodified lines
2424 display: inline-block;
2525 vertical-align: top;
2626 padding: 0 .375rem;
27− color: $textColor;
27+ color: var(--textColor);
2828 text-decoration: none;
2929
3030 &:first-child:before {
assets/stylesheets/components/_prism.scss+25−32
@@ -1,9 +1,26 @@
1+html {
2+ --prismValue: #905;
3+ --prismText: #5e8e01;
4+ --prismOperator: #a67f59;
5+ --prismKeyword: #0070a3;
6+ --prismFunction: #dd4a68;
7+ --prismVariable: #e90;
8+}
9+html._theme-dark {
10+ --prismValue: #eb8160;
11+ --prismText: #ddcf88;
12+ --prismOperator: #b1c676;
13+ --prismKeyword: #91b3ed;
14+ --prismFunction: #c79e6b;
15+ --prismVariable: #e9c062;
16+}
17+
118 .token.comment,
219 .token.prolog,
320 .token.doctype,
421 .token.cdata,
522 .token.punctuation {
6− color: $textColorLight;
23+ color: var(--textColorLight);
724 }
825
926 .namespace {
@@ -17,11 +34,7 @@ · 7 unmodified lines
1734 .token.constant,
1835 .token.symbol,
1936 .token.deleted {
20− @if $style == 'dark' {
21− color: #eb8160;
22− } @else {
23− color: #905;
24− }
37+ color: var(--prismValue);
2538 }
2639
2740 .token.selector,
@@ -30,11 +43,7 @@ · 2 unmodified lines
3043 .token.char,
3144 .token.builtin,
3245 .token.inserted {
33− @if $style == 'dark' {
34− color: #ddcf88;
35− } @else {
36− color: #5e8e01;
37− }
46+ color: var(--prismText);
3847 }
3948
4049 .token.operator,
@@ -42,44 +51,28 @@ · 1 unmodified line
4251 .token.url,
4352 .language-css .token.string,
4453 .style .token.string {
45− @if $style == 'dark' {
46− color: #b1c676;
47− } @else {
48− color: #a67f59;
49− }
54+ color: var(--prismOperator);
5055 }
5156
5257 .token.atrule,
5358 .token.attr-value,
5459 .token.keyword {
55− @if $style == 'dark' {
56− color: #91b3ed;
57− } @else {
58− color: #0070a3;
59− }
60+ color: var(--prismKeyword);
6061 }
6162
6263 .token.function {
63− @if $style == 'dark' {
64− color: #c79e6b;
65− } @else {
66− color: #dd4a68;
67− }
64+ color: var(--prismFunction);
6865 }
6966
7067 .token.regex,
7168 .token.important,
7269 .token.variable {
73− @if $style == 'dark' {
74− color: #e9c062;
75− } @else {
76− color: #e90;
77− }
70+ color: var(--prismVariable);
7871 }
7972
8073 .token.important,
8174 .token.bold {
82− font-weight: $boldFontWeight;
75+ font-weight: var(--boldFontWeight);
8376 }
8477
8578 .token.italic {
assets/stylesheets/components/_settings.scss+12−12
@@ -7,15 +7,15 @@ · 6 unmodified lines
77 position: absolute;
88 top: 0;
99 bottom: 0;
10− z-index: $headerZ;
10+ z-index: var(--headerZ);
1111
1212 &._in { display: block; }
1313
1414 > ._header { justify-content: space-between; }
1515
1616 &._dirty > ._header {
17− background: $noteGreenBackground;
18− border-color: $noteGreenBorder;
17+ background: var(--noteGreenBackground);
18+ border-color: var(--noteGreenBorder);
1919 }
2020 }
2121
@@ -37,7 +37,7 @@ · 15 unmodified lines
3737 padding-right: .5rem;
3838 line-height: inherit;
3939 font-size: inherit;
40− font-weight: $boldFontWeight;
40+ font-weight: var(--boldFontWeight);
4141 text-align: right;
4242 @extend %border-box;
4343 }
@@ -52,7 +52,7 @@ · 8 unmodified lines
5252
5353 > small {
5454 display: block;
55− color: $textColorLight;
55+ color: var(--textColorLight);
5656 margin-left: 1.75rem;
5757 }
5858
@@ -62,7 +62,7 @@ · 3 unmodified lines
6262 }
6363 }
6464
65−@media (max-width: $maxWidth) {
65+@media (max-width: 80rem) {
6666 ._setting-max-width { display: none; }
6767 }
6868
@@ -80,7 +80,7 @@ · 11 unmodified lines
8080 line-height: 1.5rem;
8181 padding: 0 .75rem;
8282 font-size: .875rem;
83− font-weight: $boldFontWeight;
83+ font-weight: var(--boldFontWeight);
8484 color: inherit;
8585 text-align: left;
8686 cursor: pointer;
@@ -119,12 +119,12 @@ · 32 unmodified lines
119119 position: relative;
120120 vertical-align: top;
121121 padding: 0 .75rem;
122− line-height: $headerHeight;
123− color: $textColorLight;
122+ line-height: var(--headerHeight);
123+ color: var(--textColorLight);
124124
125125 &.active {
126− color: $textColor;
127− font-weight: $boldFontWeight;
128− box-shadow: inset 0 -2px $linkColor;
126+ color: var(--textColor);
127+ font-weight: var(--boldFontWeight);
128+ box-shadow: inset 0 -2px var(--linkColor);
129129 }
130130 }
assets/stylesheets/components/_sidebar.scss+37−39
@@ -4,14 +4,14 @@ · 3 unmodified lines
44
55 ._sidebar {
66 position: absolute;
7− z-index: $sidebarZ;
7+ z-index: var(--sidebarZ);
88 top: 0;
99 bottom: 0;
1010 left: 0;
1111 overflow-x: hidden;
1212 overflow-y: scroll;
13− padding-top: $headerHeight;
14− background: $sidebarBackground;
13+ padding-top: var(--headerHeight);
14+ background: var(--sidebarBackground);
1515 background-clip: content-box;
1616 -webkit-overflow-scrolling: touch;
1717 -ms-overflow-style: none; // IE 10 doesn't support pointer-events
@@ -22,13 +22,13 @@ · 4 unmodified lines
2222
2323 ._overlay-scrollbars & {
2424 padding-top: 0;
25− top: $headerHeight;
25+ top: var(--headerHeight);
2626 }
2727
2828 body:not(._native-scrollbars) & {
2929 &::-webkit-scrollbar { width: 10px; }
3030 &::-webkit-scrollbar-track {
31− background: $contentBackground;
31+ background: var(--contentBackground);
3232 border: 0;
3333 }
3434 &::-webkit-scrollbar-thumb {
@@ -52,10 +52,10 @@ · 17 unmodified lines
5252
5353 ._resizer {
5454 position: absolute;
55− z-index: $sidebarZ + 1;
56− top: $headerHeight;
57− bottom: $headerHeight;
58− left: $sidebarWidth;
55+ z-index: var(--headerZ);
56+ top: var(--headerHeight);
57+ bottom: var(--headerHeight);
58+ left: var(--sidebarWidth);
5959 margin-left: -2px;
6060 width: 3px;
6161 cursor: col-resize;
@@ -72,11 +72,11 @@ · 10 unmodified lines
7272 margin: 0;
7373 padding: 0;
7474 list-style: none;
75− width: $sidebarWidth;
76− box-shadow: inset -1px 0 $sidebarBorder;
75+ width: var(--sidebarWidth);
76+ box-shadow: inset -1px 0 var(--sidebarBorder);
7777 @extend %border-box;
7878
79− @media #{$mediumScreen} { width: $sidebarMediumWidth; }
79+ @include mobile { width: var(--sidebarMediumWidth); }
8080
8181 ._sidebar > & { min-height: 100%; }
8282
@@ -89,7 +89,7 @@ · 6 unmodified lines
8989 padding: 0 .75rem 0 2.125rem;
9090 line-height: 2rem;
9191 font-size: .75rem;
92− color: $textColorLight;
92+ color: var(--textColorLight);
9393 text-transform: uppercase;
9494 cursor: default;
9595 }
@@ -110,8 +110,8 @@ · 14 unmodified lines
110110 line-height: 1.5rem;
111111 font-size: .875rem;
112112 cursor: default;
113− background: $sidebarBackground;
114− box-shadow: inset -1px 0 $sidebarBorder;
113+ background: var(--sidebarBackground);
114+ box-shadow: inset -1px 0 var(--sidebarBorder);
115115 @extend %truncate-text;
116116
117117 &, &:hover {
@@ -123,16 +123,16 @@ · 5 unmodified lines
123123 &.focus:hover,
124124 &.active,
125125 &.active:hover {
126− color: $focusText;
127− background: $focusBackground;
128− box-shadow: inset -1px 0 $focusBorder;
126+ color: var(--focusText);
127+ background: var(--focusBackground);
128+ box-shadow: inset -1px 0 var(--focusBorder);
129129 }
130130
131131 &.active,
132132 &.active:hover {
133− color: $selectionText;
134− background: $selectionBackground;
135− box-shadow: inset -1px 0 $selectionBorder;
133+ color: var(--selectionText);
134+ background: var(--selectionBackground);
135+ box-shadow: inset -1px 0 var(--selectionBorder);
136136 }
137137
138138 &:before {
@@ -160,7 +160,7 @@ · 21 unmodified lines
160160 }
161161
162162 ._list-count {
163− color: $textColorLighter;
163+ color: var(--textColorLighter);
164164 pointer-events: none;
165165
166166 ._list-disabled:hover > & { display: none; }
@@ -168,7 +168,7 @@ · 1 unmodified line
168168
169169 ._list-enable {
170170 display: none;
171− color: $linkColor;
171+ color: var(--linkColor);
172172 cursor: pointer;
173173
174174 &:hover { text-decoration: underline; }
@@ -188,7 +188,7 @@ · 13 unmodified lines
188188 ._list-disabled {
189189 @extend %_list-dir;
190190
191− &, &:hover { color: $textColorLight; }
191+ &, &:hover { color: var(--textColorLight); }
192192 &:before { opacity: .7; }
193193 }
194194
@@ -200,11 +200,9 @@ · 5 unmodified lines
200200 width: 1rem;
201201 height: 1rem;
202202 cursor: pointer;
203− fill: black;
203+ fill: var(--absolute);
204204 opacity: .4;
205205
206− @if $style == 'dark' { fill: white; }
207−
208206 &:hover { opacity: .65; }
209207
210208 ._list-rdir > & {
@@ -239,11 +237,11 @@ · 28 unmodified lines
239237 //
240238
241239 ._list-pagelink {
242− color: $linkColor;
240+ color: var(--linkColor);
243241 cursor: pointer;
244242
245243 &:hover {
246− color: $linkColorHover;
244+ color: var(--linkColorHover);
247245 text-decoration: underline;
248246 }
249247 }
@@ -275,9 +273,9 @@ · 25 unmodified lines
275273 left: .75rem;
276274 width: .75rem;
277275 height: 1px;
278− background: rgba($selectionText, .9);
279− box-shadow: 0 -3px rgba($selectionText, .9), // top line
280− 0 3px rgba($selectionText, .9); // bottom line
276+ background: var(--transparentSelectionText);
277+ box-shadow: 0 -3px var(--transparentSelectionText), // top line
278+ 0 3px var(--transparentSelectionText); // bottom line
281279 }
282280 }
283281
@@ -289,7 +287,7 @@ · 5 unmodified lines
289287 padding: .5rem .75rem;
290288 line-height: 1.25rem;
291289 font-size: .8125rem;
292− color: $textColorLight;
290+ color: var(--textColorLight);
293291
294292 & + & { padding-top: 0; }
295293 }
@@ -303,9 +301,9 @@ · 7 unmodified lines
303301 ._list-hover.clone {
304302 position: fixed;
305303 overflow: visible;
306− z-index: $hoverZ;
304+ z-index: var(--hoverZ);
307305 left: 0;
308− min-width: $sidebarWidth;
306+ min-width: var(--sidebarWidth);
309307 padding: .25rem .75rem;
310308 pointer-events: none;
311309 -webkit-font-smoothing: subpixel-antialiased;
@@ -313,7 +311,7 @@ · 1 unmodified line
313311 transform: translate3d(0, 0, 0);
314312 @extend %border-box;
315313
316− @media #{$mediumScreen} { min-width: $sidebarMediumWidth; }
314+ @include mobile { min-width: var(--sidebarMediumWidth); }
317315
318316 > ._list-text { display: inline; }
319317
@@ -346,10 +344,10 @@ · 26 unmodified lines
346344 padding: .5rem .75rem .25rem .75rem;
347345 line-height: 1.5rem;
348346 font-size: .75rem;
349− font-weight: $bolderFontWeight;
350− color: $textColorLight;
347+ font-weight: var(--bolderFontWeight);
348+ color: var(--textColorLight);
351349 text-transform: uppercase;
352− background: linear-gradient(to bottom, $sidebarBackground, $sidebarBackground 75%, rgba($sidebarBackground, 0));
350+ background: linear-gradient(to bottom, var(--sidebarBackground), var(--sidebarBackground) 75%, var(--transparentSidebarBackground));
353351 cursor: default;
354352 }
355353
assets/stylesheets/global/_base.scss+37−31
@@ -1,9 +1,10 @@
11 html {
22 height: 100%;
33 font-size: 100%;
4− background: $documentBackground;
4+ background: #fff; // fallback to show the error message to browsers that don't support CSS variables.
5+ background: var(--documentBackground);
56
6− @media #{$mediumScreen} { font-size: 93.75%; }
7+ @include mobile { font-size: 93.75%; }
78
89 @include print { background: none; }
910 @import 'global/print';
@@ -17,10 +18,11 @@ body { · 7 unmodified lines
1718 font-weight: normal;
1819 font-family: $baseFont;
1920 line-height: 1.7;
20− color: $textColor;
21+ color: $textColor; // fallback to show the error message to browsers that don't support CSS variables.
22+ color: var(--textColor);
2123 word-wrap: break-word;
2224 overflow-wrap: break-word;
23− background: $contentBackground;
25+ background: var(--contentBackground);
2426 touch-action: manipulation;
2527 -webkit-tap-highlight-color: rgba(black, 0);
2628 -webkit-touch-callout: none;
@@ -29,11 +31,11 @@ body { · 2 unmodified lines
2931 }
3032
3133 a {
32− color: $linkColor;
33− text-decoration: $linkTextDecoration;
34+ color: var(--linkColor);
35+ text-decoration: var(--linkTextDecoration);
3436
3537 &:hover {
36− color: $linkColorHover;
38+ color: var(--linkColorHover);
3739 text-decoration: underline;
3840 }
3941 }
@@ -47,7 +49,7 @@ img { · 7 unmodified lines
4749 h1, h2, h3, h4, h5, h6 {
4850 margin: 1.5em 0 1em;
4951 line-height: 1.3;
50− font-weight: $bolderFontWeight;
52+ font-weight: var(--bolderFontWeight);
5153 }
5254
5355 h1 { font-size: 1.5em; }
@@ -59,7 +61,7 @@ h5, h6 { font-size: 1em; } · 5 unmodified lines
5961 p { margin: 0 0 1em; }
6062 p:last-child { margin-bottom: 0; }
6163
62−b, strong { font-weight: $boldFontWeight; }
64+b, strong { font-weight: var(--boldFontWeight); }
6365
6466 small { font-size: .9em; }
6567
@@ -79,7 +81,7 @@ li > ul, li > ol, dd > ul, dd > ol { margin: .5em 0; } · 13 unmodified lines
7981 li > p { margin-bottom: .25em; }
8082
8183 dl { margin: 1.5em 0; }
82−dt { font-weight: $boldFontWeight; }
84+dt { font-weight: var(--boldFontWeight); }
8385 dd {
8486 margin: .375em;
8587 padding-left: 1em;
@@ -91,15 +93,15 @@ dfn, var { font-style: normal; } · 5 unmodified lines
9193
9294 abbr, acronym, dfn {
9395 cursor: help;
94− border-bottom: 1px dotted $textColor;
96+ border-bottom: 1px dotted var(--textColor);
9597 }
9698
9799 pre, code, samp, %pre, %code {
98− font-family: $monoFont;
100+ font-family: var(--monoFont);
99101 font-weight: normal;
100102 font-style: normal;
101103 font-size: .9em;
102− color: $textColor;
104+ color: var(--textColor);
103105 white-space: pre-wrap;
104106 direction: ltr;
105107 -moz-tab-size: 2;
@@ -121,14 +123,14 @@ a > code { color: inherit; } · 15 unmodified lines
121123 table {
122124 margin: 1.5em 0;
123125 background: none;
124− border: 1px solid $boxBorder;
126+ border: 1px solid var(--boxBorder);
125127 border-collapse: separate;
126128 border-spacing: 0;
127129 border-radius: 3px;
128130 }
129131
130132 caption {
131− font-weight: $boldFontWeight;
133+ font-weight: var(--boldFontWeight);
132134 padding: 0 .7em .3em;
133135 }
134136
@@ -142,15 +144,15 @@ th, td { · 7 unmodified lines
142144 }
143145
144146 th {
145− font-weight: $boldFontWeight;
147+ font-weight: var(--boldFontWeight);
146148 border: 0;
147− border-bottom: 1px solid $boxBorder;
149+ border-bottom: 1px solid var(--boxBorder);
148150 border-radius: 0;
149151 @extend %heading-box;
150152
151153 &:empty { background: none; }
152154
153− + th, + td { border-left: 1px solid $boxBorder; }
155+ + th, + td { border-left: 1px solid var(--boxBorder); }
154156
155157 tr:first-child > &:first-child { border-top-left-radius: 3px; }
156158 tr:first-child > &:last-child { border-top-right-radius: 3px; }
@@ -161,10 +163,10 @@ th { · 4 unmodified lines
161163 }
162164
163165 td {
164− background: $contentBackground;
165− border-bottom: 1px solid $boxBorderLight;
166+ background: var(--contentBackground);
167+ border-bottom: 1px solid var(--boxBorderLight);
166168
167− + td { border-left: 1px solid $boxBorderLight; }
169+ + td { border-left: 1px solid var(--boxBorderLight); }
168170 tr:last-child > & { border-bottom: 0; }
169171
170172 > pre:only-child, > p:only-child, > ul:only-child, > ol:only-child {
@@ -190,7 +192,7 @@ input, button { · 19 unmodified lines
190192 margin: 0;
191193 font-family: inherit;
192194 font-size: 100%;
193− color: $textColor;
195+ color: var(--textColor);
194196 line-height: normal;
195197 @extend %border-box;
196198 }
@@ -218,6 +220,10 @@ button:focus { · 21 unmodified lines
218220 outline: -webkit-focus-ring-color auto 5px;
219221 }
220222
223+img, iframe {
224+ background: var(--externalsBackground);
225+}
226+
221227 input[type="search"]::-webkit-search-cancel-button,
222228 input[type="search"]::-webkit-search-decoration {
223229 -webkit-appearance: none;
@@ -230,9 +236,9 @@ input[type="search"]::-webkit-search-decoration { · 6 unmodified lines
230236 border: 0 !important;
231237 }
232238
233−::-webkit-input-placeholder { color: $textColorLighter; }
234−::-moz-placeholder { color: $textColorLighter; opacity: 1; }
235−:-ms-input-placeholder { color: $textColorLighter; }
239+::-webkit-input-placeholder { color: var(--textColorLighter); }
240+::-moz-placeholder { color: var(--textColorLighter); opacity: 1; }
241+:-ms-input-placeholder { color: var(--textColorLighter); }
236242
237243 body:not(._native-scrollbars) {
238244 *::-webkit-scrollbar { -webkit-appearance: none; }
@@ -243,12 +249,12 @@ body:not(._native-scrollbars) { · 4 unmodified lines
243249 *::-webkit-scrollbar-corner { display: none; }
244250
245251 *::-webkit-scrollbar-track {
246− background: $contentBackground;
247− border: 1px solid $contentBackground;
252+ background: var(--contentBackground);
253+ border: 1px solid var(--contentBackground);
248254
249255 &:hover {
250− background: $sidebarBackground;
251− border-color: $sidebarBorder;
256+ background: var(--sidebarBackground);
257+ border-color: var(--sidebarBorder);
252258 }
253259
254260 &:vertical { border-width: 0 0 0 1px; }
@@ -266,14 +272,14 @@ body:not(._native-scrollbars) { · 11 unmodified lines
266272
267273 *::-webkit-scrollbar-thumb {
268274 min-height: 2rem;
269− background: $scrollbarColor;
275+ background: var(--scrollbarColor);
270276 background-clip: padding-box;
271277 border: 5px solid rgba(black, 0);
272278 border-radius: 10px;
273279
274280 &:hover,
275281 &:active {
276− background-color: $scrollbarColorHover;
282+ background-color: var(--scrollbarColorHover);
277283 border-width: 4px;
278284 }
279285 }
assets/stylesheets/global/_classes.scss+24−25
@@ -36,15 +36,15 @@ · 35 unmodified lines
3636 //
3737
3838 %box {
39− background: $boxBackground;
40− border: 1px solid $boxBorder;
39+ background: var(--boxBackground);
40+ border: 1px solid var(--boxBorder);
4141 border-radius: 3px;
4242 }
4343
4444 %heading-box {
45− color: $boxHeaderColor;
46− background: $boxHeaderBackground;
47− border: 1px solid $boxBorder;
45+ color: var(--boxHeaderColor);
46+ background: var(--boxHeaderBackground);
47+ border: 1px solid var(--boxBorder);
4848 border-radius: 3px;
4949 }
5050
@@ -82,15 +82,15 @@ · 31 unmodified lines
8282 %note {
8383 margin: 1.5rem 0;
8484 padding: .5rem .875rem;
85− background: $noteBackground;
86− border: 1px solid $noteBorder;
85+ background: var(--noteBackground);
86+ border: 1px solid var(--noteBorder);
8787 border-radius: 3px;
8888 }
8989
9090 %label {
9191 margin: 0 1px;
9292 padding: 1px 4px 2px;
93− background: $labelBackground;
93+ background: var(--labelBackground);
9494 border-radius: 3px;
9595 }
9696
@@ -102,35 +102,35 @@ · 5 unmodified lines
102102 padding-right: .5em;
103103 overflow: hidden;
104104 font-size: inherit;
105− color: $boxHeaderColor;
106− border: 1px solid $boxBorder;
105+ color: var(--boxHeaderColor);
106+ border: 1px solid var(--boxBorder);
107107 border-radius: 2px;
108108 @extend %label;
109109 }
110110
111111 %label-yellow {
112− background: $noteBackground;
113− border-color: $noteBorder;
112+ background: var(--noteBackground);
113+ border-color: var(--noteBorder);
114114 }
115115
116116 %note-green, %label-green {
117− background: $noteGreenBackground;
118− border-color: $noteGreenBorder;
117+ background: var(--noteGreenBackground);
118+ border-color: var(--noteGreenBorder);
119119 }
120120
121121 %note-blue, %label-blue {
122− background: $noteBlueBackground;
123− border-color: $noteBlueBorder;
122+ background: var(--noteBlueBackground);
123+ border-color: var(--noteBlueBorder);
124124 }
125125
126126 %note-orange, %label-orange {
127− background: $noteOrangeBackground;
128− border-color: $noteOrangeBorder;
127+ background: var(--noteOrangeBackground);
128+ border-color: var(--noteOrangeBorder);
129129 }
130130
131131 %note-red, %label-red {
132− background: $noteRedBackground;
133− border-color: $noteRedBorder;
132+ background: var(--noteRedBackground);
133+ border-color: var(--noteRedBorder);
134134 }
135135
136136 //
@@ -149,12 +149,11 @@ · 12 unmodified lines
149149 pointer-events: none;
150150
151151 // <svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M15,15H2V6h2.595c0,0,0.689-0.896,2.17-2H1C0.447,4,0,4.449,0,5v11c0,0.553,0.447,1,1,1h15c0.553,0,1-0.447,1-1v-3.746 l-2,1.645V15z M13.361,8.05v3.551L20,6.4l-6.639-4.999v3.131C5.3,4.532,5.3,12.5,5.3,12.5C7.582,8.752,8.986,8.05,13.361,8.05z"/></svg>
152− @if $style == 'dark' {
153− background-image: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjAgMjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI2NiZDBkMCIgZD0iTTE1LDE1SDJWNmgyLjU5NWMwLDAsMC42ODktMC44OTYsMi4xNy0ySDFDMC40NDcsNCwwLDQuNDQ5LDAsNXYxMWMwLDAuNTUzLDAuNDQ3LDEsMSwxaDE1YzAuNTUzLDAsMS0wLjQ0NywxLTF2LTMuNzQ2IGwtMiwxLjY0NVYxNXogTTEzLjM2MSw4LjA1djMuNTUxTDIwLDYuNGwtNi42MzktNC45OTl2My4xMzFDNS4zLDQuNTMyLDUuMywxMi41LDUuMywxMi41QzcuNTgyLDguNzUyLDguOTg2LDguMDUsMTMuMzYxLDguMDV6Ii8+PC9zdmc+);
154− } @else {
155− background-image: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjAgMjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iIzMzNzdjMCIgZD0iTTE1LDE1SDJWNmgyLjU5NWMwLDAsMC42ODktMC44OTYsMi4xNy0ySDFDMC40NDcsNCwwLDQuNDQ5LDAsNXYxMWMwLDAuNTUzLDAuNDQ3LDEsMSwxaDE1YzAuNTUzLDAsMS0wLjQ0NywxLTF2LTMuNzQ2IGwtMiwxLjY0NVYxNXogTTEzLjM2MSw4LjA1djMuNTUxTDIwLDYuNGwtNi42MzktNC45OTl2My4xMzFDNS4zLDQuNTMyLDUuMywxMi41LDUuMywxMi41QzcuNTgyLDguNzUyLDguOTg2LDguMDUsMTMuMzYxLDguMDV6Ii8+PC9zdmc+);
156− }
152+ background-image: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjAgMjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iIzMzNzdjMCIgZD0iTTE1LDE1SDJWNmgyLjU5NWMwLDAsMC42ODktMC44OTYsMi4xNy0ySDFDMC40NDcsNCwwLDQuNDQ5LDAsNXYxMWMwLDAuNTUzLDAuNDQ3LDEsMSwxaDE1YzAuNTUzLDAsMS0wLjQ0NywxLTF2LTMuNzQ2IGwtMiwxLjY0NVYxNXogTTEzLjM2MSw4LjA1djMuNTUxTDIwLDYuNGwtNi42MzktNC45OTl2My4xMzFDNS4zLDQuNTMyLDUuMywxMi41LDUuMywxMi41QzcuNTgyLDguNzUyLDguOTg2LDguMDUsMTMuMzYxLDguMDV6Ii8+PC9zdmc+);
157153 }
158154 }
155+html._theme-dark %external-link:after {
156+ background-image: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjAgMjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI2NiZDBkMCIgZD0iTTE1LDE1SDJWNmgyLjU5NWMwLDAsMC42ODktMC44OTYsMi4xNy0ySDFDMC40NDcsNCwwLDQuNDQ5LDAsNXYxMWMwLDAuNTUzLDAuNDQ3LDEsMSwxaDE1YzAuNTUzLDAsMS0wLjQ0NywxLTF2LTMuNzQ2IGwtMiwxLjY0NVYxNXogTTEzLjM2MSw4LjA1djMuNTUxTDIwLDYuNGwtNi42MzktNC45OTl2My4xMzFDNS4zLDQuNTMyLDUuMywxMi41LDUuMywxMi41QzcuNTgyLDguNzUyLDguOTg2LDguMDUsMTMuMzYxLDguMDV6Ii8+PC9zdmc+);
157+}
159158
160159 %internal-link:after { content: none !important; }
assets/stylesheets/global/_icons.scss+9−2
@@ -23,8 +23,8 @@ · 22 unmodified lines
2323 %doc-icon-2 { background-image: image-url('docs-2@2x.png') !important; }
2424 }
2525
26−%darkIconFix {
27− @if $style == 'dark' {
26+html._theme-dark {
27+ %darkIconFix {
2828 filter: invert(100%) grayscale(100%);
2929 -webkit-filter: invert(100%) grayscale(100%);
3030 }
@@ -94,6 +94,7 @@ · 63 unmodified lines
9494 ._icon-marionette:before { background-position: -6rem -5rem; }
9595 ._icon-jsdoc:before,
9696 ._icon-koa:before,
97+._icon-graphite:before,
9798 ._icon-mongoose:before { background-position: -7rem -5rem; }
9899 ._icon-phpunit:before { background-position: -8rem -5rem; }
99100 ._icon-nokogiri:before { background-position: -9rem -5rem; @extend %darkIconFix !optional; }
@@ -173,3 +174,9 @@ · 73 unmodified lines
173174 ._icon-babel:before { background-position: -2rem -3rem; @extend %doc-icon-2; }
174175 ._icon-leaflet:before { background-position: -3rem -3rem; @extend %doc-icon-2; }
175176 ._icon-terraform:before { background-position: -4rem -3rem; @extend %doc-icon-2; }
177+._icon-pygame:before { background-position: -5rem -3rem; @extend %doc-icon-2; }
178+._icon-bash:before { background-position: -6rem -3rem; @extend %doc-icon-2; }
179+._icon-dart:before { background-position: -7rem -3rem; @extend %doc-icon-2; }
180+._icon-qt:before { background-position: -8rem -3rem; @extend %doc-icon-2; }
181+._icon-puppeteer:before { background-position: -9rem -3rem; @extend %doc-icon-2; }
182+._icon-handlebars:before { background-position: 0 -4rem; @extend %doc-icon-2; @extend %darkIconFix !optional; }
assets/stylesheets/global/_mixins.scss+6−0
@@ -7,3 +7,9 @@ · 6 unmodified lines
77 @content;
88 }
99 }
10+
11+@mixin mobile {
12+ @media (max-width: 800px) {
13+ @content;
14+ }
15+}
assets/stylesheets/global/_print.scss+2−2
@@ -25,14 +25,14 @@ · 24 unmodified lines
2525
2626 ._attribution-p {
2727 background: none;
28− border: 2px solid $boxBorder;
28+ border: 2px solid var(--boxBorder);
2929 }
3030
3131 ._attribution:last-child:after {
3232 content: 'Exported from DevDocs \2014 https://devdocs.io';
3333 display: block;
3434 margin-top: 1rem;
35− font-weight: $bolderFontWeight;
35+ font-weight: var(--bolderFontWeight);
3636 }
3737
3838 ._attribution {
assets/stylesheets/global/_variables-dark.scss+53−69
@@ -1,92 +1,76 @@
1−$baseFont: -apple-system, BlinkMacSystemFont, 'San Francisco', 'Segoe UI', Roboto, Ubuntu, 'Helvetica Neue', Arial, sans-serif;
2−$monoFont: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace;
3−$boldFontWeight: 500;
4−$bolderFontWeight: 600;
1+html._theme-dark {
2+ --absolute: white;
53
6−$style: 'dark';
4+ --documentBackground: #222;
5+ --contentBackground: #33373a;
76
8−$maxWidth: 80rem;
9−$headerHeight: 3rem;
10−$sidebarWidth: 20rem;
11−$sidebarMediumWidth: 16rem;
7+ --textColor: #cbd0d0;
8+ --textColorLight: #9da5ad;
9+ --textColorLighter: #77787a;
1210
13−$documentBackground: #222;
14−$contentBackground: #33373a;
11+ --externalsBackground: #fff;
1512
16−$textColor: #cbd0d0;
17−$textColorLight: #9da5ad;
18−$textColorLighter: #77787a;
19−$textColorRed: #f44336;
13+ --inputFocusBorder: transparent;
2014
21−$inputFocusBorder: false;
15+ --focusBackground: #3f4042;
16+ --focusBorder: #000;
17+ --focusText: #f7f2f2;
2218
23−$focusBackground: #3f4042;
24−$focusBorder: #000;
25−$focusText: #f7f2f2;
19+ --loadingText: #5d6164;
2620
27−$loadingText: #5d6164;
28−$splashText: $loadingText;
21+ --selectionBackground: #007acc;
22+ --selectionBorder: #000;
2923
30−$selectionBackground: #007acc;
31−$selectionBorder: #000;
32−$selectionText: #fff;
24+ --highlightBackground: #64675f;
3325
34−$highlightBackground: #64675f;
26+ --linkColor: var(--textColor);
27+ --linkColorHover: white;
28+ --linkTextDecoration: underline;
3529
36−$linkColor: $textColor;
37−$linkColorHover: white;
38−$linkTextDecoration: underline;
30+ --headerBackground: #1c1c1c;
31+ --headerBorder: #000;
32+ --searchTagBackground: #{darken(#1c1c1c, 5%)};
33+ --searchBorder: #{darken(#000, 2%)};
3934
40−$headerBackground: #1c1c1c;
41−$headerBorder: #000;
35+ --sidebarBackground: #24282a;
36+ --transparentSidebarBackground: #{rgba(#24282a, 0)};
37+ --sidebarBorder: #000;
4238
43−$sidebarBackground: #24282a;
44−$sidebarBorder: #000;
39+ --scrollbarColor: #6c6c6f;
40+ --scrollbarColorHover: #949697;
4541
46−$scrollbarColor: #6c6c6f;
47−$scrollbarColorHover: #949697;
42+ --pathBackground: var(--headerBackground);
43+ --pathBorder: var(--headerBorder);
4844
49−$pathBackground: $headerBackground;
50−$pathBorder: $headerBorder;
45+ --noticeBackground: var(--sidebarBackground);
46+ --noticeBorder: var(--sidebarBorder);
5147
52−$noticeBackground: $sidebarBackground;
53−$noticeBorder: $sidebarBorder;
48+ --boxBackground: var(--sidebarBackground);
49+ --boxBorder: var(--headerBorder);
50+ --boxBorderLight: var(--headerBorder);
51+ --boxHeaderColor: #dbe4e4;
52+ --boxHeaderBackground: var(--sidebarBackground);
5453
55−$boxBackground: $sidebarBackground;
56−$boxBorder: $headerBorder;
57−$boxBorderLight: $headerBorder;
58−$boxHeaderColor: #dbe4e4;
59−$boxHeaderBackground: $sidebarBackground;
54+ --noteBackground: #45474b;
55+ --noteBorder: #000;
6056
61−$noteBackground: #45474b;
62−$noteBorder: #000;
57+ --noteGreenBackground: #284a2a;
58+ --noteGreenBorder: #000;
6359
64−$noteGreenBackground: #284a2a;
65−$noteGreenBorder: #000;
60+ --noteBlueBackground: #2a4151;
61+ --noteBlueBorder: #000;
6662
67−$noteBlueBackground: #2a4151;
68−$noteBlueBorder: #000;
63+ --noteOrangeBackground: #563322;
64+ --noteOrangeBorder: #000;
6965
70−$noteOrangeBackground: #563322;
71−$noteOrangeBorder: #000;
66+ --noteRedBackground: #603033;
67+ --noteRedBorder: #000;
7268
73−$noteRedBackground: #603033;
74−$noteRedBorder: #000;
69+ --labelBackground: var(--boxBackground);
7570
76−$labelBackground: $boxBackground;
71+ --notifBackground: #{rgba(#555, .95)};
72+ --notifBorder: 1px solid #000;
7773
78−$notifBackground: rgba(#555, .95);
79−$notifBorder: 1px solid #000;
80−$notifColor: #fff;
81−$notifColorLight: #ccc;
82−
83−$tipBackground: $notifBackground;
84−$tipBorder: $notifBorder;
85−
86−$mediumScreen: '(max-width: 800px)';
87−
88−$contentZ: 1;
89−$sidebarZ: 2;
90−$headerZ: 3;
91−$noticeZ: 4;
92−$hoverZ: 5;
74+ --tipBackground: var(--notifBackground);
75+ --tipBorder: var(--notifBorder);
76+}
assets/stylesheets/global/_variables-light.scss+76−0
@@ -0,0 +1,76 @@
1+html._theme-default {
2+ --absolute: black;
3+
4+ --documentBackground: #f3f3f3;
5+ --contentBackground: #fff;
6+
7+ --textColor: #333;
8+ --textColorLight: #666;
9+ --textColorLighter: #888;
10+
11+ --externalsBackground: #fff;
12+
13+ --inputFocusBorder: #35b5f4;
14+
15+ --focusBackground: #e5e5e5;
16+ --focusBorder: #d4d4d4;
17+ --focusText: #000;
18+
19+ --loadingText: #ccc;
20+
21+ --selectionBackground: #398df0;
22+ --selectionBorder: #196fc2;
23+
24+ --highlightBackground: #fffdcd;
25+
26+ --linkColor: #3377c0;
27+ --linkColorHover: #2f6cb6;
28+ --linkTextDecoration: none;
29+
30+ --headerBackground: #eee;
31+ --headerBorder: #d7d7d7;
32+ --searchTagBackground: #{darken(#eee, 5%)};
33+ --searchBorder: #{darken(#d7d7d7, 2%)};
34+
35+ --sidebarBackground: #f9f9f9;
36+ --transparentSidebarBackground: #{rgba(#f9f9f9, 0)};
37+ --sidebarBorder: #e1e1e1;
38+
39+ --scrollbarColor: #ccc;
40+ --scrollbarColorHover: #999;
41+
42+ --pathBackground: var(--sidebarBackground);
43+ --pathBorder: var(--sidebarBorder);
44+
45+ --noticeBackground: #faf9e2;
46+ --noticeBorder: #e2e2c1;
47+
48+ --boxBackground: #fafafa;
49+ --boxBorder: #d8d8d8;
50+ --boxBorderLight: #e5e5e5;
51+ --boxHeaderColor: var(--textColor);
52+ --boxHeaderBackground: #f5f5f5;
53+
54+ --noteBackground: #f8f8dd;
55+ --noteBorder: #d3d952;
56+
57+ --noteGreenBackground: #e7f8e1;
58+ --noteGreenBorder: #89da70;
59+
60+ --noteBlueBackground: #d4f3fd;
61+ --noteBlueBorder: #94bbeb;
62+
63+ --noteOrangeBackground: #fbe6d1;
64+ --noteOrangeBorder: #ec8b01;
65+
66+ --noteRedBackground: #fed5d3;
67+ --noteRedBorder: #dc7874;
68+
69+ --labelBackground: #f4f4f4;
70+
71+ --notifBackground: #{rgba(#333, .85)};
72+ --notifBorder: none;
73+
74+ --tipBackground: #{rgba(#fffdcd, .95)};
75+ --tipBorder: 1px solid #e7dca9;
76+}
assets/stylesheets/global/_variables.scss+25−82
@@ -1,92 +1,35 @@
1+// Variables needed to style the error message for browsers that don't support CSS variables.
12 $baseFont: -apple-system, BlinkMacSystemFont, 'San Francisco', 'Segoe UI', Roboto, Ubuntu, 'Helvetica Neue', Arial, sans-serif;
2−$monoFont: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace;
3−$boldFontWeight: 500;
4−$bolderFontWeight: 600;
5−
6−$style: 'light';
7−
8−$maxWidth: 80rem;
9−$headerHeight: 3rem;
10−$sidebarWidth: 20rem;
11−$sidebarMediumWidth: 16rem;
12−
13−$documentBackground: #f3f3f3;
14−$contentBackground: #fff;
15−
163 $textColor: #333;
17−$textColorLight: #666;
18−$textColorLighter: #888;
19−$textColorRed: #f44336;
20−
21−$inputFocusBorder: #35b5f4;
22−
23−$focusBackground: #e5e5e5;
24−$focusBorder: #d4d4d4;
25−$focusText: #000;
26−
27−$loadingText: #ccc;
28−$splashText: #ccc;
29−
30−$selectionBackground: #398df0;
31−$selectionBorder: #196fc2;
32−$selectionText: #fff;
33−
34−$highlightBackground: #fffdcd;
35−
36−$linkColor: #3377c0;
37−$linkColorHover: #2f6cb6;
38−$linkTextDecoration: none;
39−
40−$headerBackground: #eee;
41−$headerBorder: #d7d7d7;
42−
43−$sidebarBackground: #f9f9f9;
44−$sidebarBorder: #e1e1e1;
45−
46−$scrollbarColor: #ccc;
47−$scrollbarColorHover: #999;
48−
49−$pathBackground: $sidebarBackground;
50−$pathBorder: $sidebarBorder;
51−
52−$noticeBackground: #faf9e2;
53−$noticeBorder: #e2e2c1;
54−
55−$boxBackground: #fafafa;
56−$boxBorder: #d8d8d8;
57−$boxBorderLight: #e5e5e5;
58−$boxHeaderColor: $textColor;
59−$boxHeaderBackground: #f5f5f5;
60−
61−$noteBackground: #f8f8dd;
62−$noteBorder: #d3d952;
63−
64−$noteGreenBackground: #e7f8e1;
65−$noteGreenBorder: #89da70;
664
67−$noteBlueBackground: #d4f3fd;
68−$noteBlueBorder: #94bbeb;
5+html {
6+ --baseFont: #{$baseFont};
7+ --monoFont: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace;
8+ --boldFontWeight: 500;
9+ --bolderFontWeight: 600;
6910
70−$noteOrangeBackground: #fbe6d1;
71−$noteOrangeBorder: #ec8b01;
11+ --textColorRed: #f44336;
7212
73−$noteRedBackground: #fed5d3;
74−$noteRedBorder: #dc7874;
13+ --splashText: var(--loadingText);
7514
76−$labelBackground: #f4f4f4;
15+ --selectionText: #fff;
16+ --transparentSelectionText: rgba(255, 255, 255, 0.9);
7717
78−$notifBackground: rgba(#333, .85);
79−$notifBorder: none;
80−$notifColor: #fff;
81−$notifColorLight: #ccc;
18+ --notifColor: #fff;
19+ --notifColorLight: #ccc;
8220
83−$tipBackground: rgba(#fffdcd, .95);
84−$tipBorder: 1px solid #e7dca9;
21+ --maxWidth: 80rem;
22+ --headerHeight: 3rem;
23+ --sidebarWidth: 20rem;
24+ --sidebarMediumWidth: 16rem;
8525
86−$mediumScreen: '(max-width: 800px)';
26+ --focusBackground: #e5e5e5;
27+ --focusBorder: #d4d4d4;
28+ --focusText: #000;
8729
88−$contentZ: 1;
89−$sidebarZ: 2;
90−$headerZ: 3;
91−$noticeZ: 4;
92−$hoverZ: 5;
30+ --contentZ: 1;
31+ --sidebarZ: 2;
32+ --headerZ: 3;
33+ --noticeZ: 4;
34+ --hoverZ: 5;
35+}
assets/stylesheets/pages/_angularjs.scss+1−1
@@ -8,7 +8,7 @@ · 7 unmodified lines
88 .nav-index-section {
99 margin: 1.5em 0 1em -2em;
1010 list-style: none;
11− font-weight: $boldFontWeight;
11+ font-weight: var(--boldFontWeight);
1212 text-transform: capitalize;
1313 }
1414
assets/stylesheets/pages/_async.scss+2−2
@@ -3,13 +3,13 @@ · 2 unmodified lines
33
44 h3 > .type-signature {
55 float: right;
6− color: $textColorLight;
6+ color: var(--textColorLight);
77 }
88
99 h3 > .signature-attributes {
1010 font-size: .75rem;
1111 font-weight: normal;
1212 font-style: italic;
13− color: $textColorLighter;
13+ color: var(--textColorLighter);
1414 }
1515 }
assets/stylesheets/pages/_bash.scss+12−0
@@ -0,0 +1,12 @@
1+._bash {
2+ dl > dt > code,
3+ dl > dt > kbd {
4+ @extend %block-label, %label-blue;
5+ }
6+
7+ th[align=left] {
8+ border-left: 1px solid var(--boxBorder);
9+ }
10+
11+ code { @extend %label; }
12+}
assets/stylesheets/pages/_bootstrap.scss+1−1
@@ -4,7 +4,7 @@ · 3 unmodified lines
44 h4 > code, h5 > code, strong > code { @extend %label; }
55
66 h2 > small {
7− color: $textColorLight;
7+ color: var(--textColorLight);
88 float: right;
99 }
1010
assets/stylesheets/pages/_c.scss+2−2
@@ -23,7 +23,7 @@ · 22 unmodified lines
2323
2424 .t-spar { // language/switch, language/for, etc.
2525 font-style: italic;
26− color: $textColorLight;
26+ color: var(--textColorLight);
2727 }
2828 .t-sdsc-nopad dl, .t-sdsc-nopad dd { margin: 0; }
2929
@@ -57,7 +57,7 @@ · 27 unmodified lines
5757 margin: 1rem 0;
5858 padding: .375rem;
5959 font-size: .75rem;
60− border: 1px solid $boxBorder;
60+ border: 1px solid var(--boxBorder);
6161 border-radius: 2px;
6262 }
6363
assets/stylesheets/pages/_clojure.scss+1−1
@@ -5,6 +5,6 @@ · 4 unmodified lines
55 .type {
66 float: right;
77 font-size: .9em;
8− color: $textColorLight;
8+ color: var(--textColorLight);
99 }
1010 }
assets/stylesheets/pages/_d.scss+3−3
@@ -2,10 +2,10 @@ · 1 unmodified line
22 h2 { @extend %block-heading; }
33 h3, .d_decl { @extend %block-label, %label-blue; }
44 .d_decl { @extend %code; }
5− .d_decl > small { color: $textColorLight; }
6− .d_decl > strong { font-weight: $bolderFontWeight; }
5+ .d_decl > small { color: var(--textColorLight); }
6+ .d_decl > strong { font-weight: var(--bolderFontWeight); }
77
88 p > code, li > code, td > code, dd > code { @extend %label; }
99
10− span.red { color: $textColorRed; }
10+ span.red { color: var(--textColorRed); }
1111 }
assets/stylesheets/pages/_dart.scss+12−0
@@ -0,0 +1,12 @@
1+._dart {
2+ @extend %simple;
3+
4+ dl:not(.dl-horizontal) dt, .multi-line-signature {
5+ @extend %block-label;
6+
7+ .features {
8+ float: right;
9+ color: var(--textColorLight);
10+ }
11+ }
12+}
assets/stylesheets/pages/_dojo.scss+1−1
@@ -1,5 +1,5 @@
11 ._dojo {
22 @extend %simple;
33
4− .jsdoc-inheritance { color: $textColorLight; }
4+ .jsdoc-inheritance { color: var(--textColorLight); }
55 }
assets/stylesheets/pages/_ember.scss+2−2
@@ -5,7 +5,7 @@ · 4 unmodified lines
55
66 h3 > .access {
77 float: right;
8− color: $textColorLight;
8+ color: var(--textColorLight);
99 font-weight: normal;
1010 }
1111
@@ -15,6 +15,6 @@ · 3 unmodified lines
1515 }
1616
1717 p.github-link {
18− color: $textColorLight;
18+ color: var(--textColorLight);
1919 }
2020 }
assets/stylesheets/pages/_erlang.scss+1−1
@@ -5,5 +5,5 @@ · 4 unmodified lines
55 code.code { @extend %label; }
66 .note { @extend %note; }
77 .warning { @extend %note, %note-red; }
8− .note .label, .warning .label { font-weight: $boldFontWeight; }
8+ .note .label, .warning .label { font-weight: var(--boldFontWeight); }
99 }
assets/stylesheets/pages/_graphite.scss+7−0
@@ -0,0 +1,7 @@
1+._graphite {
2+ @extend %simple;
3+
4+ dl > dt {
5+ @extend %block-label, %label-blue;
6+ }
7+}
assets/stylesheets/pages/_jquery.scss+2−2
@@ -32,7 +32,7 @@ · 31 unmodified lines
3232
3333 .toc-list {
3434 margin-top: 0;
35− font-weight: $boldFontWeight;
35+ font-weight: var(--boldFontWeight);
3636
3737 > li + li { margin-top: 1em; }
3838 > li > ul { font-weight: normal; }
@@ -48,7 +48,7 @@ · 9 unmodified lines
4848 .returns,
4949 .option-type {
5050 float: right;
51− font-weight: $boldFontWeight;
51+ font-weight: var(--boldFontWeight);
5252 margin-left: 1em;
5353 }
5454
assets/stylesheets/pages/_love.scss+2−2
@@ -12,6 +12,6 @@ · 11 unmodified lines
1212 .smwtable { width: 100%; }
1313 .smwtable td:nth-last-child(2), .smwtable td:last-child { width: 2.5em; }
1414
15− .cell-green { background: $noteGreenBackground; }
16− .cell-red { background: $noteRedBackground; }
15+ .cell-green { background: var(--noteGreenBackground); }
16+ .cell-red { background: var(--noteRedBackground); }
1717 }
assets/stylesheets/pages/_mdn.scss+3−3
@@ -7,7 +7,7 @@ · 6 unmodified lines
77 > span {
88 display: block;
99 font-size: 1rem;
10− font-weight: $boldFontWeight;
10+ font-weight: var(--boldFontWeight);
1111 }
1212
1313 ul, ol {
@@ -42,7 +42,7 @@ · 28 unmodified lines
4242 > .note {
4343 em {
4444 font-style: normal;
45− font-weight: $boldFontWeight;
45+ font-weight: var(--boldFontWeight);
4646 }
4747
4848 > ul { margin: 1em 0; }
@@ -93,7 +93,7 @@ · 44 unmodified lines
9393 dt > strong > code, // HTML element attribute
9494 dl > dt > code { // CSS property value, Javascript function argument
9595 font-family: inherit;
96− font-weight: $boldFontWeight;
96+ font-weight: var(--boldFontWeight);
9797 font-size: inherit;
9898 }
9999
assets/stylesheets/pages/_meteor.scss+2−2
@@ -9,10 +9,10 @@ · 8 unmodified lines
99 dt > code { @extend %label; }
1010
1111 .api-heading { overflow: hidden; }
12− .api-heading > code { font-weight: $boldFontWeight; }
12+ .api-heading > code { font-weight: var(--boldFontWeight); }
1313 .locus, .src-code { float: right; }
1414 .locus, .type, .src-code { margin-left: .5em; }
1515 h2 .subtext-api { margin-top: .25rem; }
1616 .locus, .subtext-api, .subtext-api > code { font-size: .75rem; }
17− .locus, .type { color: $textColorLight; }
17+ .locus, .type { color: var(--textColorLight); }
1818 }
assets/stylesheets/pages/_npm.scss+1−1
@@ -8,7 +8,7 @@ · 7 unmodified lines
88
99 .faint.heading {
1010 font-size: .9em;
11− color: $textColorLight;
11+ color: var(--textColorLight);
1212 }
1313
1414 .youtube-video iframe { width: 420px; height: 315px; }
assets/stylesheets/pages/_phalcon.scss+1−1
@@ -3,6 +3,6 @@ · 2 unmodified lines
33
44 h3 > small {
55 float: right;
6− color: $textColorLight;
6+ color: var(--textColorLight);
77 }
88 }
assets/stylesheets/pages/_php.scss+2−2
@@ -13,7 +13,7 @@ · 12 unmodified lines
1313
1414 .verinfo {
1515 float: right;
16− font-weight: $boldFontWeight;
16+ font-weight: var(--boldFontWeight);
1717 }
1818
1919 .classsynopsis,
@@ -21,7 +21,7 @@ · 1 unmodified line
2121 .description > .methodsynopsis,
2222 .description > .fieldsynopsis { @extend %note, %note-blue; }
2323
24− .classsynopsisinfo_comment { color: $textColorLight; }
24+ .classsynopsisinfo_comment { color: var(--textColorLight); }
2525
2626 .classsynopsisinfo_comment,
2727 .classsynopsis > .constructorsynopsis,
assets/stylesheets/pages/_postgres.scss+1−1
@@ -16,7 +16,7 @@ · 15 unmodified lines
1616 }
1717
1818 p > code { @extend %label; }
19− p.c2 { font-weight: $boldFontWeight; }
19+ p.c2 { font-weight: var(--boldFontWeight); }
2020
2121 .navfooter > table { width: 100%; }
2222 td[align=center] { text-align: center; }
assets/stylesheets/pages/_qt.scss+9−0
@@ -0,0 +1,9 @@
1+._qt {
2+ @extend %simple;
3+
4+ // Function headers
5+ h3.fn > code {
6+ float: right;
7+ color: var(--textColorLight);
8+ }
9+}
assets/stylesheets/pages/_rdoc.scss+4−4
@@ -6,7 +6,7 @@ · 5 unmodified lines
66 .method-description > h2, h3, h4, h5, h6 { font-size: 1em; }
77
88 .method-heading {
9− font-weight: $boldFontWeight;
9+ font-weight: var(--boldFontWeight);
1010 @extend %block-label, %label-blue;
1111
1212 + .method-heading { margin-top: -.5em; }
@@ -22,7 +22,7 @@ · 9 unmodified lines
2222 a.method-click-advice {
2323 float: right;
2424 font-size: .75rem;
25− color: $linkColor;
25+ color: var(--linkColor);
2626 cursor: pointer;
2727 @extend %user-select-none;
2828
@@ -42,8 +42,8 @@ · 13 unmodified lines
4242 top: 0;
4343 left: -1em;
4444 right: 0;
45− background: rgba($contentBackground, .95);
46− box-shadow: 0 1em 1em 1em $contentBackground;
45+ background: var(--contentBackground);
46+ box-shadow: 0 1em 1em 1em var(--contentBackground);
4747
4848 > pre { margin: 0; }
4949 }
assets/stylesheets/pages/_react_native.scss+1−1
@@ -2,7 +2,7 @@ · 1 unmodified line
22 @extend %simple;
33
44 .deprecated { @extend %note, %note-orange; }
5− .deprecatedTitle { font-weight: $boldFontWeight; }
5+ .deprecatedTitle { font-weight: var(--boldFontWeight); }
66
77 span.platform { float: right; }
88 span.propType, span.platform { font-weight: normal; }
assets/stylesheets/pages/_redis.scss+2−2
@@ -14,7 +14,7 @@ · 13 unmodified lines
1414
1515 .args {
1616 font-size: .75rem;
17− color: $textColorLight;
17+ color: var(--textColorLight);
1818 }
1919
2020 // Others
@@ -35,7 +35,7 @@ · 14 unmodified lines
3535 > .prompt {
3636 float: left;
3737 margin-right: .5em;
38− color: $textColorLight;
38+ color: var(--textColorLight);
3939 }
4040
4141 > code {
assets/stylesheets/pages/_rfc.scss+1−1
@@ -10,6 +10,6 @@ · 9 unmodified lines
1010
1111 > h1, > h2, > h3, > h4, > h5 {
1212 margin: 0;
13− font-family: $baseFont;
13+ font-family: var(--baseFont);
1414 }
1515 }
assets/stylesheets/pages/_rust.scss+10−1
@@ -3,9 +3,18 @@ · 2 unmodified lines
33
44 h4 { @extend %block-label; }
55 .docblock { margin-left: 1em; }
6+ div.information, div.important-traits {
7+ @extend %note;
8+
9+ > pre { margin: .5rem 0; }
10+ }
611
712 div.stability { margin-bottom: 1em; }
813 em.stab, span.stab { @extend %label; }
914 em.stab.unstable, span.stab.unstable { @extend %label-orange; }
10− .since, .out-of-band { float: right; }
15+ .out-of-band { float: right; }
16+ .since, .srclink {
17+ float: right;
18+ margin-left: .5rem;
19+ }
1120 }
assets/stylesheets/pages/_simple.scss+1−31
@@ -17,34 +17,4 @@ · 16 unmodified lines
1717 blockquote > h4, blockquote > h5 { margin-top: .25rem; }
1818 }
1919
20−._apache_pig,
21−._bower,
22−._chai,
23−._codeceptjs,
24−._docker,
25−._electron,
26−._fish,
27−._flow,
28−._gnu,
29−._grunt,
30−._haxe,
31−._immutable,
32−._influxdata,
33−._jasmine,
34−._jest,
35−._less,
36−._lodash,
37−._marionette,
38−._markdown,
39−._mocha,
40−._mongoose,
41−._nim,
42−._redux,
43−._requirejs,
44−._simple,
45−._typescript,
46−._vagrant,
47−._vulkan,
48−._yarn {
49− @extend %simple;
50−}
20+._simple { @extend %simple; }
assets/stylesheets/pages/_sphinx.scss+2−2
@@ -14,7 +14,7 @@ · 13 unmodified lines
1414
1515 .versionmodified, span.title, .topic-title {
1616 display: block;
17− font-weight: $boldFontWeight;
17+ font-weight: var(--boldFontWeight);
1818 }
1919
2020 p > code, li > code, dd > code, .docutils > dt > code { @extend %label; }
@@ -26,7 +26,7 @@ · 5 unmodified lines
2626 .admonition-title {
2727 float: left;
2828 margin: 0 .5em 0 0;
29− font-weight: $boldFontWeight;
29+ font-weight: var(--boldFontWeight);
3030
3131 &:after { content: ':'; }
3232 }
assets/stylesheets/pages/_sphinx_simple.scss+1−1
@@ -6,7 +6,7 @@ · 5 unmodified lines
66 .admonition.tip { @extend %note-green; }
77 .admonition-title {
88 margin: 0 0 .25rem;
9− font-weight: $boldFontWeight;
9+ font-weight: var(--boldFontWeight);
1010 }
1111
1212 code { @extend %label; }
assets/stylesheets/pages/_support_tables.scss+1−1
@@ -24,7 +24,7 @@ · 23 unmodified lines
2424 }
2525
2626 tr.current {
27− font-weight: $boldFontWeight;
27+ font-weight: var(--boldFontWeight);
2828 font-size: 1rem;
2929 }
3030
assets/stylesheets/pages/_yard.scss+1−1
@@ -1,5 +1,5 @@
11 ._yard {
22 @extend %simple;
33
4− .tag_title { font-weight: $boldFontWeight; }
4+ .tag_title { font-weight: var(--boldFontWeight); }
55 }
assets/stylesheets/pages/_yii.scss+1−1
@@ -3,6 +3,6 @@ · 2 unmodified lines
33
44 .detail-header-tag, .detailHeaderTag {
55 float: right;
6− color: $textColorLight;
6+ color: var(--textColorLight);
77 }
88 }
lib/app.rb+2−16
@@ -12,6 +12,8 @@ class App < Sinatra::Application · 11 unmodified lines
1212 Rack::Mime::MIME_TYPES['.webapp'] = 'application/x-web-app-manifest+json'
1313
1414 configure do
15+ use Rack::SslEnforcer, only_environments: ['production', 'test'], hsts: false, force_secure_cookies: false
16+
1517 set :sentry_dsn, ENV['SENTRY_DSN']
1618 set :protection, except: [:frame_options, :xss_header]
1719
@@ -194,7 +196,6 @@ class App < Sinatra::Application · 176 unmodified lines
194196 @@manifest_asset_urls ||= [
195197 javascript_path('application', asset_host: false),
196198 stylesheet_path('application'),
197− stylesheet_path('application-dark'),
198199 image_path('docs-1.png'),
199200 image_path('docs-1@2x.png'),
200201 image_path('docs-2.png'),
@@ -203,21 +204,6 @@ class App < Sinatra::Application · 2 unmodified lines
203204 ]
204205 end
205206
206− def main_stylesheet_path
207− stylesheet_paths[dark_theme? ? :dark : :default]
208− end
209−
210− def alternate_stylesheet_path
211− stylesheet_paths[dark_theme? ? :default : :dark]
212− end
213−
214− def stylesheet_paths
215− @@stylesheet_paths ||= {
216− default: stylesheet_path('application'),
217− dark: stylesheet_path('application-dark')
218− }
219− end
220−
221207 def app_size
222208 @app_size ||= memoized_cookies['size'].nil? ? '20rem' : "#{memoized_cookies['size']}px"
223209 end
lib/docs/filters/bash/clean_html.rb+74−0
@@ -0,0 +1,74 @@
1+module Docs
2+ class Bash
3+ class CleanHtmlFilter < Filter
4+ def call
5+ # Remove the navigation header and footer and the lines underneath and above it
6+ at_css('.header + hr').remove
7+ line_above = at_xpath('//div[@class="header"]/preceding::hr[1]')
8+ line_above.remove unless line_above.nil?
9+ css('.header').remove
10+
11+ # Remove chapter and section numbers from title
12+ title_node = at_css('h1, h2, h3, h4, h5, h6')
13+ title_node.content = title_node.content.gsub(/(\d+\.?)+/, '').strip
14+ title_node.name = 'h1'
15+
16+ # Remove the "D. " from names like "D. Concept Index" and "D. Function Index"
17+ title_node.content = title_node.content[3..-1] if title_node.content.start_with?("D. ")
18+
19+ # Remove columns containing a single space from tables
20+ # In the original reference they are used to add width between two columns
21+ xpath('//td[text()=" " and not(descendant::*)]').remove
22+
23+ # Add id's to additional entry nodes
24+ css('dl > dt > code').each do |node|
25+ # Only take the direct text (i.e. "<div>Hello <span>World</span></div>" becomes "Hello")
26+ node['id'] = node.xpath('text()').to_s.strip
27+ end
28+
29+ # Fix hashes of index entries so they link to the correct hash on the linked page
30+ css('table[class^=index-] td[valign=top] > a').each do |node|
31+ path = node['href'].split('#')[0]
32+ hash = node.content
33+
34+ # Fix the index entries linking to the Special Parameters page
35+ # There are multiple index entries that should link to the same paragraph on that page
36+ # Example: the documentation for "$!" is equal to the documentation for "!"
37+ if path.downcase.include?('special-parameters')
38+ if hash.size > 1 && hash[0] == '$'
39+ hash = hash[1..-1]
40+ end
41+ end
42+
43+ node['href'] = path + '#' + hash
44+ end
45+
46+ # Fix index table letter hashes (the "Jump to" hashes)
47+ css('table[class^=index-] th > a').each do |node|
48+ node['id'] = node['name']
49+ end
50+
51+ # Remove the rows with a horizontal line in them from the index tables
52+ css('td[colspan="4"]').remove
53+
54+ # Remove additional text from menu entry and index entry cells
55+ css('td[valign=top]').each do |node|
56+ link = node.at_css('a')
57+ node.children = link unless link.nil?
58+ end
59+
60+ css('tt', 'code', 'table').remove_attr('class')
61+
62+ css('tt').each do |node|
63+ node.name = 'code'
64+ end
65+
66+ css('pre').each do |node|
67+ node.content = node.content
68+ end
69+
70+ doc
71+ end
72+ end
73+ end
74+end
lib/docs/filters/bash/entries.rb+56−0
@@ -0,0 +1,56 @@
1+module Docs
2+ class Bash
3+ class EntriesFilter < Docs::EntriesFilter
4+ def get_name
5+ name = at_css('hr + a + *').content.gsub(/(\d+\.?)+/, '')
6+
7+ # Remove the "D. " from names like "D. Concept Index" and "D. Function Index"
8+ name = name[3..-1] if name.start_with?('D. ')
9+
10+ name
11+ end
12+
13+ def get_type
14+ return 'Manual: Appendices' if name.start_with?('Appendix')
15+ return 'Manual: Indexes' if at_css('a[rel=up]').content.include?("Index")
16+ "Manual"
17+ end
18+
19+ def additional_entries
20+ entry_type = {
21+ "Function Index" => "Functions",
22+ "Index of Shell Builtin Commands" => "Builtin Commands",
23+ "Index of Shell Reserved Words" => "Reserved Words",
24+ "Parameter and Variable Index" => "Parameters and Variables"
25+ }[name]
26+
27+ # Only extract additional entries from certain index pages
28+ return [] if entry_type.nil?
29+
30+ entries = []
31+
32+ css('table[class^=index-] td[valign=top] > a').each_slice(2) do |entry_node, section_node|
33+ entry_name = entry_node.content
34+
35+ page = section_node['href'].split('#')[0]
36+ hash = entry_name
37+
38+ # The Special Parameters page has multiple additional entries which should link to the same paragraph
39+ # Example: the documentation for "$!" is equal to the documentation for "!"
40+ if page == 'special-parameters'
41+ if hash.size > 1 && hash[0] == '$'
42+ hash = hash[1..-1]
43+ end
44+ end
45+
46+ # Construct path to the page which the index links to
47+ entry_path = '/html_node/' + page + '#' + hash
48+
49+ entries << [entry_name, entry_path, entry_type]
50+ end
51+
52+ entries
53+ end
54+ end
55+ end
56+end
lib/docs/filters/dart/clean_html.rb+66−0
@@ -0,0 +1,66 @@
1+module Docs
2+ class Dart
3+ class CleanHtmlFilter < Filter
4+ def call
5+ # Move the title into the main content node in the v1 docs
6+ title = at_css('h1.title')
7+ if title
8+ name = title.children.last.content.strip
9+ kind = title.at_css('.kind').content
10+ at_css('.main-content').prepend_child("<h1>#{name} #{kind}</h1>")
11+ end
12+
13+ # Add a title to the homepage of the v2 docs
14+ if subpath == 'index.html' && at_css('.main-content > h1').nil?
15+ at_css('.main-content').prepend_child('<h1>Dart SDK</h1>')
16+ end
17+
18+ # Add the library to the main content (it is not always visible in the menu entry)
19+ breadcrumbs = at_css('.breadcrumbs').css('li:not(.self-crumb) > a')
20+ if breadcrumbs.length > 1
21+ library = breadcrumbs[1].content
22+
23+ # Generate the link to the homepage of the library
24+ with_hypens = library.gsub(/:/, '-')
25+ location = "#{'../' * subpath.count('/')}#{with_hypens}/#{with_hypens}-library"
26+ link = "<a href=\"#{location}\" class=\"_links-link\">#{library}</span>"
27+
28+ # Add the link to the main title, just like how the "Homepage" and "Source code" links appear
29+ at_css('.main-content').prepend_child("<p class=\"_links\">#{link}</p>")
30+ end
31+
32+ # Extract the actual content
33+ # We can't use options[:container] here because the entries filter uses the breadcrumbs node
34+ @doc = at_css('.main-content')
35+
36+ # Move the features (i.e. "read-only, inherited") into the blue header
37+ css('.features').each do |node|
38+ header = node.xpath('parent::dd/preceding::dt').last
39+ header.add_child node unless header.nil?
40+ end
41+
42+ css('section').each do |node|
43+ if node['id'] && node.first_element_child
44+ node.first_element_child['id'] ||= node['id']
45+ end
46+
47+ node.before(node.children).remove
48+ end
49+
50+ css('span').each do |node|
51+ node.before(node.children).remove
52+ end
53+
54+ # Make code blocks detectable by Prism
55+ css('pre').each do |node|
56+ node['data-language'] = 'dart'
57+ node.content = node.content
58+ end
59+
60+ css('.properties', '.property', '.callables', '.callable').remove_attr('class')
61+
62+ doc
63+ end
64+ end
65+ end
66+end
lib/docs/filters/dart/entries.rb+42−0
@@ -0,0 +1,42 @@
1+module Docs
2+ class Dart
3+ class EntriesFilter < Docs::EntriesFilter
4+ def get_name
5+ title = at_css('h1.title')
6+ if title # v1
7+ name = title.element_children.last.content.strip
8+ kind = title.at_css('.kind').content
9+ else # v2
10+ title = at_css('.main-content > h1')
11+ name = title.content[/(.*)( )/, 1].split(' top-level')[0]
12+ kind = title.content[/(.*)( )(.+)/, 3]
13+ end
14+
15+ breadcrumbs = at_css('.breadcrumbs').css('li:not(.self-crumb) > a')
16+ first_part = ''
17+
18+ if breadcrumbs.length == 2 && !kind.include?('class')
19+ first_part = breadcrumbs[1].content
20+ elsif breadcrumbs.length == 3
21+ first_part = breadcrumbs[2].content
22+ end
23+
24+ separator = ''
25+
26+ unless first_part.empty?
27+ if kind.include?('class')
28+ separator = ':'
29+ else
30+ separator = '.'
31+ end
32+ end
33+
34+ "#{first_part}#{separator}#{name}"
35+ end
36+
37+ def get_type
38+ at_css('.breadcrumbs > li:nth-child(2)').content.split(' ')[0]
39+ end
40+ end
41+ end
42+end
lib/docs/filters/dom/entries.rb+3−0
@@ -26,6 +26,7 @@ module Docs · 25 unmodified lines
2626 'Geometry' => 'Geometry',
2727 'High Resolution Time' => 'Performance',
2828 'Intersection' => 'Intersection Observer',
29+ 'Media Capabilities' => 'Media',
2930 'Media Capture' => 'Media',
3031 'Media Session' => 'Media',
3132 'Media Source' => 'Media',
@@ -99,6 +100,7 @@ module Docs · 67 unmodified lines
99100 'MediaSession' => 'Media Session',
100101 'MediaTrack' => 'Media Streams',
101102 'Message' => 'Channel Messaging',
103+ 'Mutation' => 'DOM',
102104 'NamedNode' => 'Nodes',
103105 'Node' => 'Nodes',
104106 'Notification' => 'Notification',
@@ -116,6 +118,7 @@ module Docs · 11 unmodified lines
116118 'Shadow' => 'Shadow DOM',
117119 'StaticRange' => 'Range',
118120 'Streams' => 'Media Streams',
121+ 'StyleProperty' => 'CSS',
119122 'StyleSheet' => 'CSS',
120123 'Stylesheet' => 'CSS',
121124 'SVG' => 'SVG',
lib/docs/filters/elixir/clean_html.rb+1−0
@@ -59,6 +59,7 @@ module Docs · 58 unmodified lines
5959
6060 css('pre').each do |node|
6161 node['data-language'] = 'elixir'
62+ node.content = node.content
6263 end
6364 end
6465 end
lib/docs/filters/express/clean_html.rb+5−0
@@ -42,6 +42,11 @@ module Docs · 41 unmodified lines
4242 node.parent.content = node.parent.content
4343 end
4444
45+ # Fix links to the method reference
46+ css('a').each do |node|
47+ node['href'] = node['href'].sub('4x/api', 'index')
48+ end
49+
4550 doc
4651 end
4752 end
lib/docs/filters/graphite/clean_html.rb+27−0
@@ -0,0 +1,27 @@
1+module Docs
2+ class Graphite
3+ class CleanHtmlFilter < Filter
4+ def call
5+ # Remove the paragraph icon after all headers
6+ css('.headerlink').remove
7+
8+ css('dl.function > dt').each do |node|
9+ node.content = node.content
10+ end
11+
12+ css('.section').each do |node|
13+ node.before(node.children).remove
14+ end
15+
16+ css('div[class*="highlight-"]').each do |node|
17+ node.content = node.content.strip
18+ node.name = 'pre'
19+ node['data-language'] = node['class'][/highlight\-(\w+)/, 1]
20+ node.remove_attribute('class')
21+ end
22+
23+ doc
24+ end
25+ end
26+ end
27+end
lib/docs/filters/graphite/entries.rb+46−0
@@ -0,0 +1,46 @@
1+module Docs
2+ class Graphite
3+ class EntriesFilter < Docs::EntriesFilter
4+ def get_name
5+ at_css('h1').children[0].to_s
6+ end
7+
8+ def get_type
9+ get_name
10+ end
11+
12+ def additional_entries
13+ entries = []
14+
15+ # Sections
16+ css('.section > .section').each do |node|
17+ title = node.at_css('h2, h3')
18+
19+ next if title.nil?
20+
21+ # Move the id attribute to the title
22+ # If this is excluded, the complete section will be highlighted in yellow when someone navigates to it
23+ title['id'] = node['id']
24+ node.remove_attribute('id')
25+
26+ parent_title_selector = "parent::div[@class='section']/preceding::#{title.name == 'h2' ? 'h1' : 'h2'}"
27+
28+ entries << [
29+ title.children[0].to_s,
30+ title['id'],
31+ title.xpath(parent_title_selector).last.children[0].to_s
32+ ]
33+ end
34+
35+ # Functions
36+ css('dl.function > dt').each do |node|
37+ name = node.at_css('.descname').content
38+ name << '()'
39+ entries << [name, node['id'], 'Functions']
40+ end
41+
42+ entries
43+ end
44+ end
45+ end
46+end
lib/docs/filters/handlebars/clean_html.rb+44−0
@@ -0,0 +1,44 @@
1+module Docs
2+ class Handlebars
3+ class CleanHtmlFilter < Filter
4+ def call
5+ # Remove the t-shirt shop advertisement
6+ css('#callout').remove
7+
8+ # The title filter is used to add titles to pages without one, remove original headers
9+ css('h1').remove
10+
11+ # Remove the link to the issue tracker
12+ css('.issue-tracker').remove
13+
14+ css('pre').each do |node|
15+ # Remove nested nodes inside pre tags
16+ node.content = node.content
17+
18+ # Add syntax highlighting
19+ node['data-language'] = 'html'
20+ end
21+
22+ # Transform 'Learn More' links to headers in the "Getting Started" part of the homepage
23+ # If this step is skipped, that section looks cluttered with 4 sub-sections without any dividers
24+ css('#getting-started + .contents a.more-info').each do |node|
25+ clone = node.clone
26+
27+ # Move it to the top of the sub-section
28+ node.parent.prepend_child(clone)
29+
30+ # Turn it into a header
31+ clone.name = 'h3'
32+
33+ # Remove the "Learn More: " part
34+ clone.content = clone.content[12..-1]
35+ end
36+
37+ # Remove class attributes from div elements to reduce file size
38+ css('div').remove_attr('class')
39+
40+ doc
41+ end
42+ end
43+ end
44+end
lib/docs/filters/handlebars/entries.rb+19−0
@@ -0,0 +1,19 @@
1+module Docs
2+ class Handlebars
3+ class EntriesFilter < Docs::EntriesFilter
4+ def get_name
5+ subpath[0..-6].titleize
6+ end
7+
8+ def get_type
9+ name
10+ end
11+
12+ def additional_entries
13+ css('h2, h3').to_a.map do |node|
14+ [node.content.strip, node['id'], root_page? ? 'Manual' : nil]
15+ end
16+ end
17+ end
18+ end
19+end
lib/docs/filters/puppeteer/clean_html.rb+24−0
@@ -0,0 +1,24 @@
1+module Docs
2+ class Puppeteer
3+ class CleanHtmlFilter < Filter
4+ def call
5+ at_css('h1').content = 'Puppeteer Documentation'
6+
7+ # None of the elements to remove have classes, so the order of the remove calls is trivial
8+
9+ # Remove links to previous versions of the reference
10+ at_css('h1 + ul').remove
11+
12+ # Remove table of contents
13+ at_css('h1 + h5').remove
14+ at_css('h1 + ul').remove
15+
16+ # Make headers bigger by transforming them into a bigger variant
17+ css('h3').each { |node| node.name = 'h2' }
18+ css('h4').each { |node| node.name = 'h3' }
19+
20+ doc
21+ end
22+ end
23+ end
24+end
lib/docs/filters/puppeteer/entries.rb+41−0
@@ -0,0 +1,41 @@
1+module Docs
2+ class Puppeteer
3+ class EntriesFilter < Docs::EntriesFilter
4+ # The entire reference is one big page, so get_name and get_type are not necessary
5+
6+ def additional_entries
7+ entries = []
8+
9+ css('h3').each do |node|
10+ name = node.content.split(': ').last
11+
12+ # Find all sub-items (all h4's between the current h3 and the next)
13+ current = node.next
14+ while !current.nil? && current.name != 'h3'
15+ if current.name == 'h4'
16+ current_name = current.content
17+
18+ # Prepend events with the class name
19+ if current_name.start_with?('event: ')
20+ current_name = "#{name} event: #{current_name[/'(.*)'/, 1]}"
21+ end
22+
23+ # Remove arguments from functions
24+ if current_name.include?('(')
25+ current_name = current_name.split('(')[0] + '()'
26+ end
27+
28+ entries << [current_name, current['id'], name]
29+ end
30+
31+ current = current.next
32+ end
33+
34+ entries << [name, node['id'], name]
35+ end
36+
37+ entries
38+ end
39+ end
40+ end
41+end
lib/docs/filters/pygame/clean_html.rb+102−0
@@ -0,0 +1,102 @@
1+module Docs
2+ class Pygame
3+ class CleanHtmlFilter < Filter
4+ def call
5+ @doc = at_css '.body'
6+
7+ if root_page?
8+ # remove unneeded stuff
9+ at_css('.modindex-jumpbox').remove
10+ css('[role="navigation"],.pcap, .cap, .footer').remove
11+ # table -> list
12+ list = at_css('table')
13+ list.replace(list.children)
14+ list.name = 'ul'
15+ css('tr').each do |row|
16+ row.name = 'li'
17+ row.remove_attribute('class')
18+ end
19+ at_css('h1').content = 'Pygame'
20+ return doc
21+ end
22+
23+ # remove unwanted stuff
24+ # .headerlink => ¶ after links
25+ # .toc => table of content
26+ # .tooltip-content => tooltips after links to functions
27+ css('table.toc.docutils, .headerlink, .tooltip-content').remove
28+
29+ # Remove wrapper .section
30+ section = at_css('.section')
31+ definition = at_css('.definition')
32+ definition['id'] = section['id']
33+ section.replace(section.children)
34+
35+ # Format code for it be highlighted
36+ css('.highlight-default.notranslate').each do |node|
37+ pre = node.at_css('pre')
38+ node.replace(pre)
39+ # gets rid of the already existing syntax highlighting
40+ pre.content = pre.content
41+ pre['class'] = 'language-python'
42+ pre['data-language'] = "python"
43+ end
44+
45+ # change descriptions of functions/attributes to blockquote
46+ css('.line-block').each do |node|
47+ node.name = 'blockquote'
48+ end
49+
50+ # change functions
51+ css('.definition').each do |d|
52+
53+ # the header is the function/attribute name. It might look something like
54+ # this:
55+ # pygame.image.load()
56+ # It'll end up being something like this:
57+ # pygame.image.load(filename) -> Surface
58+ # pygame.image.load(fileobj, namehint="") -> Surface
59+
60+ header = d.at_css('dt.title')
61+ if d['class'].include?('class') or d['class'].include?('module')
62+ header.name = 'h1'
63+ @section = header.content.strip
64+ else
65+ header.name = 'h3'
66+ end
67+ # save the original header
68+ initial_header = header.content.strip
69+ # save the real name for the entries
70+ header['data-name'] = initial_header
71+ # empty the header
72+ if header.name == 'h3'
73+ header.inner_html = ''
74+ end
75+ # to replace it with the signatures
76+ next_el = header.next_element
77+ signatures = next_el.css('.signature')
78+ signatures.each do |sig|
79+ sig.name = 'code'
80+ if header.name == 'h3'
81+ sig.parent = header
82+ # the signature don't contain pygame.module. I think it's better
83+ # to display them, as it avoids confusion with methods (have a
84+ # look at the pygame.Rect page)
85+ if initial_header.start_with?(@section)
86+ sig.content = @section + '.' + sig.text
87+ end
88+ # seperate the signatures on different lines.
89+ header.add_child "<br>"
90+ end
91+ end
92+ end
93+
94+ css('> dl', '> dl > dd', 'h1 code').each do |node|
95+ node.before(node.children).remove
96+ end
97+
98+ doc
99+ end
100+ end
101+ end
102+end
lib/docs/filters/pygame/entries.rb+29−0
@@ -0,0 +1,29 @@
1+module Docs
2+ class Pygame
3+ class EntriesFilter < Docs::EntriesFilter
4+ def get_name
5+ at_css('h1').content.remove('pygame.')
6+ end
7+
8+ def get_type
9+ at_css('h1').content
10+ end
11+
12+ def additional_entries
13+ return [] if root_page?
14+
15+ css('h1, h2, h3').each_with_object [] do |node, entries|
16+ name = node['id'] || node['data-name']
17+
18+ if node.parent['class'].include?('function') or node.parent['class'].include?('method')
19+ name << '()'
20+ end
21+
22+ name.remove!('pygame.')
23+
24+ entries << [name, node['id']] unless name == self.name
25+ end
26+ end
27+ end
28+ end
29+end
lib/docs/filters/python/clean_html.rb+5−3
@@ -15,15 +15,17 @@ module Docs · 14 unmodified lines
1515
1616 def other
1717 css('h1').each do |node|
18− node.content = node.content.sub!(/\A[\d\.]+/) do |str|
18+ node.content = node.content.sub(/\A[\d\.]+/) do |str|
1919 rgx = /\A#{str}/
2020 @levelRegexp = @levelRegexp ? Regexp.union(@levelRegexp, rgx) : rgx
2121 ''
2222 end
2323 end
2424
25− css('h2', 'h3', 'h4').each do |node|
26− node.inner_html = node.inner_html.remove @levelRegexp
25+ unless @levelRegexp.nil?
26+ css('h2', 'h3', 'h4').each do |node|
27+ node.inner_html = node.inner_html.remove @levelRegexp
28+ end
2729 end
2830 end
2931 end
lib/docs/filters/python/entries_v3.rb+12−10
@@ -2,16 +2,18 @@ module Docs · 1 unmodified line
22 class Python
33 class EntriesV3Filter < Docs::EntriesFilter
44 REPLACE_TYPES = {
5− 'Cryptographic' => 'Cryptography',
6− 'Custom Interpreters' => 'Interpreters',
7− 'Data Compression & Archiving' => 'Data Compression',
8− 'Generic Operating System' => 'Operating System',
9− 'Graphical User Interfaces with Tk' => 'Tk',
10− 'Internet Data Handling' => 'Internet Data',
11− 'Internet Protocols & Support' => 'Internet',
12− 'Interprocess Communication & Networking' => 'Networking',
13− 'Program Frameworks' => 'Frameworks',
14− 'Structured Markup Processing Tools' => 'Structured Markup' }
5+ 'contextvars — Context Variables' => 'Context Variables',
6+ 'Cryptographic' => 'Cryptography',
7+ 'Custom Interpreters' => 'Interpreters',
8+ 'Data Compression & Archiving' => 'Data Compression',
9+ 'email — An email & MIME handling package' => 'Email',
10+ 'Generic Operating System' => 'Operating System',
11+ 'Graphical User Interfaces with Tk' => 'Tk',
12+ 'Internet Data Handling' => 'Internet Data',
13+ 'Internet Protocols & Support' => 'Internet',
14+ 'Interprocess Communication & Networking' => 'Networking',
15+ 'Program Frameworks' => 'Frameworks',
16+ 'Structured Markup Processing Tools' => 'Structured Markup' }
1517
1618 def get_name
1719 name = at_css('h1').content
lib/docs/filters/qt/clean_html.rb+31−0
@@ -0,0 +1,31 @@
1+module Docs
2+ class Qt
3+ class CleanHtmlFilter < Filter
4+ def call
5+ # Remove unneeded elements
6+ css('.copy-notice, .navigationbar, .headerNavi, .footerNavi, .sidebar, .toc, #ec_toggle', '.landingicons img', 'br').remove
7+
8+ # QML property/method header
9+ css('.qmlproto').each do |node|
10+ id = node.at_css('tr')['id']
11+ node.inner_html = node.at_css('td').inner_html
12+ node.name = 'h3'
13+ node['id'] = id
14+ end
15+
16+ css('.main-rounded', '.content', '.line', '.context', '.descr', '.types', '.func', '.table', 'div:not([class])', '.landing', '.col-1', '.heading', '.qmlitem', '.qmldoc', 'div.pre').each do |node|
17+ node.before(node.children).remove
18+ end
19+
20+ css('pre').each do |node|
21+ node.content = node.content
22+ node['data-language'] = 'cpp' if node['class'].include?('cpp')
23+ node['data-language'] = 'qml' if node['class'].include?('qml')
24+ node.remove_attribute('class')
25+ end
26+
27+ doc
28+ end
29+ end
30+ end
31+end
lib/docs/filters/qt/entries.rb+141−0
@@ -0,0 +1,141 @@
1+# frozen_string_literal: true
2+
3+module Docs
4+ class Qt
5+ class EntriesFilter < Docs::EntriesFilter
6+ def get_name
7+ header = at_css('h1.title + .small-subtitle a') || at_css('h1.title') || at_css('.context h2')
8+ name = header.content
9+ name.sub! %r{ Class$}, ' (class)'
10+ name.sub! %r{ QML Type$}, ' (QML type)'
11+ name.sub! %r{ QML Basic Type$}, ' (QML basic type)'
12+
13+ # Add '(class)' to the class pages where the subtitle name is used (e.g. qset-const-iterator.html)
14+ if at_css('h1.title').content.strip.end_with?(' Class') && !name.include?('(class)')
15+ name = "#{name} (class) "
16+ end
17+
18+ name
19+ end
20+
21+ def get_type
22+ breadcrumb = css('#main_title_bar + ul li')
23+ category = if breadcrumb.length < 3
24+ then 'Qt'.dup
25+ else breadcrumb.at(1).content
26+ end
27+
28+ if category == 'Qt'
29+ return 'Qt Platforms' if name.include?(' for ') || name == 'Qt Platform Abstraction'
30+ return 'Qt Quick' if name == 'Qt Quick Test' || name == 'Qt Quick Test Reference Documentation'
31+
32+ alwaysInQt = ['Qt Configure Options', 'Qt Image Formats']
33+ category = name if name.start_with?('Qt ') && !alwaysInQt.include?(name)
34+ end
35+
36+ qtPlatformsTypes = ['Qt Platform Headers', 'Qt Android Extras', 'Qt Mac Extras', 'Qt Windows Extras', 'Qt X11 Extras']
37+ return 'Qt Platforms' if qtPlatformsTypes.include?(category)
38+
39+ category.remove!(' Manual')
40+ category
41+ end
42+
43+ def include_default_entry?
44+ name != 'All Classes' && name != 'All QML Types'
45+ end
46+
47+ def additional_entries
48+ entries = []
49+ titles = []
50+
51+ className = at_css('h1.title').content.strip.remove(' Class')
52+ displayedClassName = className
53+ alternativeClassName = at_css('h1.title + .small-subtitle a')
54+ displayedClassName = alternativeClassName.content if alternativeClassName
55+
56+ # Functions signatures
57+ css('h3.fn').each do |node|
58+ header = node.clone
59+
60+ # Skip typenames
61+ next if header.content.strip.start_with?('typename ')
62+
63+ # Remove leading <a name="">
64+ header.children.css('a[name]').remove
65+
66+ # Remove leading <code> tag (virtual/static/… attributes)
67+ code = header.children.first
68+ code.remove if code.name == 'code'
69+
70+ # Remove leading ‘const’
71+ header.children.first.remove if header.content.strip.start_with?('const ')
72+
73+ # Remove return type
74+ returnType = header.children.first
75+ returnType.remove if returnType['class'] == 'type'
76+
77+ title = header.content.strip
78+
79+ # Remove leading '&'/'*'
80+ title[0] = '' if title[0] == '&' || title[0] == '*'
81+
82+ # Ignore operator overloads
83+ next if title.start_with?('operator')
84+
85+ # Remove function parameters
86+ title.sub! %r{\(.*\)}, '()'
87+
88+ # Remove template generics
89+ title.remove!(%r{^<.*> })
90+
91+ # Remove ‘const’ at the end
92+ title.remove!(%r{ const$})
93+
94+ # Enum/typedef formatting
95+ title.sub! %r{(enum|typedef) (.*)}, '\2 (\1)'
96+
97+ # Remove property type
98+ title = "#{displayedClassName}::#{title}" if title.sub!(%r{ : .*$}, '')
99+
100+ # Replace the class name by the alternative class name if available
101+ title = title.sub(className, displayedClassName) if alternativeClassName
102+
103+ unless titles.include?(title) # Remove duplicates (function overloading)
104+ entries << [title, header['id']]
105+ titles.push title
106+ end
107+ end
108+
109+ # QML properties/functions
110+ qmlTypeName = at_css('h1.title').content.remove(' QML Type', '')
111+ css('.qmlproto').each do |node|
112+ title = node.content.strip
113+ id = node.at_css('tr')['id']
114+
115+ # Remove options
116+ title.remove!(%r{^\[.*\] })
117+
118+ # Remove function parameters
119+ title.sub! %r{\(.*\)}, '()'
120+
121+ # Remove property type
122+ title.remove!(%r{ : .*$})
123+
124+ # Remove return type
125+ title.remove!(%r{.* })
126+
127+ # Remove return type
128+ title.remove!(%r{.* })
129+
130+ title = "#{qmlTypeName}.#{title.strip}"
131+ unless titles.include?(title) # Remove duplicates (function overloading)
132+ entries << [title, id]
133+ titles.push(title)
134+ end
135+ end
136+
137+ entries
138+ end
139+ end
140+ end
141+end
lib/docs/filters/redis/entries.rb+2−1
@@ -12,7 +12,7 @@ module Docs · 11 unmodified lines
1212 when 'HDEL' then 'Hashes'
1313 when 'BLPOP' then 'Lists'
1414 when 'SADD' then 'Sets'
15− when 'ZADD' then 'Sorted Sets'
15+ when 'BZPOPMAX' then 'Sorted Sets'
1616 when 'PSUBSCRIBE' then 'Pub/Sub'
1717 when 'DISCARD' then 'Transactions'
1818 when 'EVAL' then 'Scripting'
@@ -21,6 +21,7 @@ module Docs · 2 unmodified lines
2121 when 'PFADD' then 'HyperLogLog'
2222 when 'CLUSTER ADDSLOTS' then 'Cluster'
2323 when 'GEOADD' then 'Geo'
24+ when 'XADD' then 'Stream'
2425 else 'Miscellaneous'
2526 end
2627 end
lib/docs/filters/rust/clean_html.rb+37−6
@@ -2,10 +2,8 @@ module Docs · 1 unmodified line
22 class Rust
33 class CleanHtmlFilter < Filter
44 def call
5− puts subpath if at_css('#versioninfo')
6−
75 if slug.start_with?('book') || slug.start_with?('reference')
8− @doc = at_css('#content')
6+ @doc = at_css('#content main')
97 elsif slug == 'error-index'
108 css('.error-undescribed').remove
119
@@ -29,12 +27,16 @@ module Docs · 17 unmodified lines
2927
3028 css('.rusttest', '.test-arrow', 'hr').remove
3129
30+ css('.docblock.attributes').each do |node|
31+ node.remove if node.content.include?('#[must_use]')
32+ end
33+
3234 css('a.header').each do |node|
33− node.first_element_child['id'] = node['name']
35+ node.first_element_child['id'] = node['name'] || node['id']
3436 node.before(node.children).remove
3537 end
3638
37− css('.docblock > h1').each { |node| node.name = 'h4' }
39+ css('.docblock > h1:not(.section-header)').each { |node| node.name = 'h4' }
3840 css('h2.section-header').each { |node| node.name = 'h3' }
3941 css('h1.section-header').each { |node| node.name = 'h2' }
4042
@@ -44,7 +46,7 @@ module Docs · 3 unmodified lines
4446 end
4547 end
4648
47− css('> .impl-items', '> .docblock', 'pre > pre').each do |node|
49+ css('> .impl-items', '> .docblock', 'pre > pre', '.tooltiptext', '.tooltip').each do |node|
4850 node.before(node.children).remove
4951 end
5052
@@ -62,6 +64,35 @@ module Docs · 11 unmodified lines
6264 node['data-language'] = 'rust' if node['class'] && node['class'].include?('rust')
6365 end
6466
67+ doc.first_element_child.name = 'h1' if doc.first_element_child.name = 'h2'
68+ at_css('h1').content = 'Rust Documentation' if root_page?
69+
70+ css('.table-display').each do |node|
71+ node.css('td').each do |td|
72+ node.before(td.children)
73+ end
74+ node.remove
75+ end
76+
77+ css('h2 .important-traits', 'h3 .important-traits', 'h4 .important-traits').each do |node|
78+ content = node.at_css('.content.hidden .content')
79+ node.at_css('.content.hidden').replace(content) if content
80+ node.parent.after(node)
81+ end
82+
83+ css('code.content').each do |node|
84+ node.name = 'pre'
85+ node.css('.fmt-newline').each do |line|
86+ line.inner_html = line.inner_html + "\n"
87+ end
88+ node.inner_html = node.inner_html.gsub('<br>', "\n")
89+ node.content = node.content
90+ end
91+
92+ css('.since + .srclink').each do |node|
93+ node.previous_element.before(node)
94+ end
95+
6596 doc
6697 end
6798 end
lib/docs/filters/rust/entries.rb+8−5
@@ -42,11 +42,14 @@ module Docs · 41 unmodified lines
4242 entries << [node.content, node['id']] unless node.content.include?('Note:')
4343 end
4444 else
45− css('#methods + * + div > .method', '#required-methods + div > .method', '#provided-methods + div > .method').map do |node|
46− name = node.at_css('.fnname').content
47− name.prepend "#{self.name}::"
48− [name, node['id']]
49− end
45+ css('.method')
46+ .select {|node| !node.at_css('.fnname').nil?}
47+ .map {|node|
48+ name = node.at_css('.fnname').content
49+ name.prepend "#{self.name}::"
50+ [name, node['id']]
51+ }
52+ .uniq {|item| item[0]}
5053 end
5154 end
5255 end
lib/docs/filters/typescript/entries.rb+1−0
@@ -9,6 +9,7 @@ module Docs · 8 unmodified lines
99
1010 def get_type
1111 return 'Declaration Files' if subpath.include?('declaration-files')
12+ return 'Project Configuration' if slug == 'handbook/configuring-watch'
1213 type = at_css('#main-nav a.active').ancestors('.panel').first.at_css('> a').content
1314 type = name if type == 'Handbook'
1415 type
lib/docs/scrapers/apache.rb+1−1
@@ -3,7 +3,7 @@ module Docs · 2 unmodified lines
33 self.name = 'Apache HTTP Server'
44 self.slug = 'apache_http_server'
55 self.type = 'apache'
6− self.release = '2.4.33'
6+ self.release = '2.4.34'
77 self.base_url = 'https://httpd.apache.org/docs/2.4/en/'
88 self.links = {
99 home: 'https://httpd.apache.org/'
lib/docs/scrapers/apache_pig.rb+1−1
@@ -2,7 +2,7 @@ module Docs · 1 unmodified line
22 class ApachePig < UrlScraper
33 self.name = 'Apache Pig'
44 self.slug = 'apache_pig'
5− self.type = 'apache_pig'
5+ self.type = 'simple'
66 self.links = {
77 home: 'https://pig.apache.org/'
88 }
lib/docs/scrapers/bash.rb+21−0
@@ -0,0 +1,21 @@
1+module Docs
2+ class Bash < UrlScraper
3+ self.type = 'bash'
4+ self.release = '4.4'
5+ self.base_url = 'https://www.gnu.org/software/bash/manual'
6+ self.root_path = '/html_node/index.html'
7+ self.links = {
8+ home: 'https://www.gnu.org/software/bash/',
9+ code: 'http://git.savannah.gnu.org/cgit/bash.git'
10+ }
11+
12+ html_filters.push 'bash/entries', 'bash/clean_html'
13+
14+ options[:only_patterns] = [/\/html_node\//]
15+
16+ options[:attribution] = <<-HTML
17+ Copyright &copy; 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.<br>
18+ Licensed under the GNU Free Documentation License.
19+ HTML
20+ end
21+end
lib/docs/scrapers/bootstrap.rb+1−1
@@ -16,7 +16,7 @@ module Docs · 15 unmodified lines
1616 HTML
1717
1818 version '4' do
19− self.release = '4.1.1'
19+ self.release = '4.1.3'
2020 self.base_url = 'https://getbootstrap.com/docs/4.1/'
2121 self.root_path = 'getting-started/introduction/'
2222
lib/docs/scrapers/bower.rb+1−1
@@ -1,7 +1,7 @@
11 module Docs
22 class Bower < UrlScraper
33 self.name = 'Bower'
4− self.type = 'bower'
4+ self.type = 'simple'
55 self.release = '1.8.4'
66 self.base_url = 'https://bower.io/docs/'
77 self.root_path = 'api'
lib/docs/scrapers/chai.rb+1−1
@@ -1,7 +1,7 @@
11 module Docs
22 class Chai < UrlScraper
33 self.name = 'Chai'
4− self.type = 'chai'
4+ self.type = 'simple'
55 self.release = '4.1.0'
66 self.base_url = 'http://chaijs.com'
77 self.root_path = '/api/'
lib/docs/scrapers/cmake.rb+12−2
@@ -16,12 +16,22 @@ module Docs · 15 unmodified lines
1616 options[:skip_patterns] = [/\Agenerator/, /\Ainclude/, /\Arelease/]
1717
1818 options[:attribution] = <<-HTML
19− &copy; 2000&ndash;2017 Kitware, Inc. and Contributors<br>
19+ &copy; 2000&ndash;2018 Kitware, Inc. and Contributors<br>
2020 Licensed under the BSD 3-clause License.
2121 HTML
2222
23+ version '3.12' do
24+ self.release = '3.12.1'
25+ self.base_url = 'https://cmake.org/cmake/help/v3.12/'
26+ end
27+
28+ version '3.11' do
29+ self.release = '3.11.4'
30+ self.base_url = 'https://cmake.org/cmake/help/v3.11/'
31+ end
32+
2333 version '3.10' do
24− self.release = '3.10.1'
34+ self.release = '3.10.3'
2535 self.base_url = 'https://cmake.org/cmake/help/v3.10/'
2636 end
2737
lib/docs/scrapers/codeceptjs.rb+1−1
@@ -1,7 +1,7 @@
11 module Docs
22 class Codeceptjs < UrlScraper
33 self.name = 'CodeceptJS'
4− self.type = 'codeceptjs'
4+ self.type = 'simple'
55 self.root_path = 'index.html'
66 self.release = '1.3.1'
77 self.base_url = 'https://codecept.io/'
lib/docs/scrapers/crystal.rb+1−1
@@ -1,7 +1,7 @@
11 module Docs
22 class Crystal < UrlScraper
33 self.type = 'crystal'
4− self.release = '0.25.1'
4+ self.release = '0.26.0'
55 self.base_url = 'https://crystal-lang.org/'
66 self.root_path = "api/#{release}/index.html"
77 self.initial_paths = %w(docs/index.html)
lib/docs/scrapers/dart.rb+37−0
@@ -0,0 +1,37 @@
1+module Docs
2+ class Dart < FileScraper
3+ self.type = 'dart'
4+ self.root_path = 'index.html'
5+ self.links = {
6+ home: 'https://www.dartlang.org/',
7+ code: 'https://github.com/dart-lang/sdk'
8+ }
9+
10+ html_filters.push 'dart/entries', 'dart/clean_html'
11+
12+ options[:fix_urls] = ->(url) do
13+ # localhost/dart-web_audio/..dart-io/dart-io-library.html > localhost/dart-io/dart-io-library.html
14+ url.remove!(/[^\/]+\/\.\./)
15+ url
16+ end
17+
18+ options[:attribution] = <<-HTML
19+ &copy; 2012 the Dart project authors<br>
20+ Licensed under the Creative Commons Attribution-ShareAlike License v4.0.
21+ HTML
22+
23+ # Download the documentation from https://www.dartlang.org/tools/sdk/archive
24+
25+ version '2' do
26+ self.release = '2.0.0'
27+ self.dir = '/Users/Thibaut/DevDocs/Docs/Dart2'
28+ self.base_url = "https://api.dartlang.org/stable/#{release}/"
29+ end
30+
31+ version '1' do
32+ self.release = '1.24.3'
33+ self.dir = '/Users/Thibaut/DevDocs/Docs/Dart1'
34+ self.base_url = "https://api.dartlang.org/stable/#{release}/"
35+ end
36+ end
37+end
lib/docs/scrapers/django.rb+6−0
@@ -34,6 +34,12 @@ module Docs · 33 unmodified lines
3434 Licensed under the BSD License.
3535 HTML
3636
37+ version '2.1' do
38+ self.release = '2.1.0'
39+ self.dir = '/Users/Thibaut/DevDocs/Docs/Django21'
40+ self.base_url = 'https://docs.djangoproject.com/en/2.1/'
41+ end
42+
3743 version '2.0' do
3844 self.release = '2.0.7'
3945 self.dir = '/Users/Thibaut/DevDocs/Docs/Django20'
lib/docs/scrapers/docker.rb+1−1
@@ -1,6 +1,6 @@
11 module Docs
22 class Docker < UrlScraper
3− self.type = 'docker'
3+ self.type = 'simple'
44 self.links = {
55 home: 'https://docker.com/',
66 code: 'https://github.com/docker/docker'
lib/docs/scrapers/electron.rb+1−1
@@ -1,6 +1,6 @@
11 module Docs
22 class Electron < UrlScraper
3− self.type = 'electron'
3+ self.type = 'simple'
44 self.base_url = 'https://electronjs.org/docs'
55 self.release = '2.0.2'
66 self.links = {
lib/docs/scrapers/elixir.rb+13−0
@@ -33,6 +33,19 @@ module Docs · 32 unmodified lines
3333 "https://elixir-lang.org/getting-started/introduction.html" ]
3434 end
3535
36+ version '1.7' do
37+ self.release = '1.7.3'
38+ self.base_urls = [
39+ "https://hexdocs.pm/elixir/#{release}/",
40+ "https://hexdocs.pm/eex/#{release}/",
41+ "https://hexdocs.pm/ex_unit/#{release}/",
42+ "https://hexdocs.pm/iex/#{release}/",
43+ "https://hexdocs.pm/logger/#{release}/",
44+ "https://hexdocs.pm/mix/#{release}/",
45+ 'https://elixir-lang.org/getting-started/'
46+ ]
47+ end
48+
3649 version '1.6' do
3750 self.release = '1.6.5'
3851 self.base_urls = [
lib/docs/scrapers/express.rb+1−1
@@ -2,7 +2,7 @@ module Docs · 1 unmodified line
22 class Express < UrlScraper
33 self.name = 'Express'
44 self.type = 'express'
5− self.release = '4.16.1'
5+ self.release = '4.16.3'
66 self.base_url = 'http://expressjs.com/en/'
77 self.root_path = '4x/api.html'
88 self.initial_paths = %w(
lib/docs/scrapers/fish.rb+1−1
@@ -1,7 +1,7 @@
11 module Docs
22 class Fish < UrlScraper
33 self.name = 'Fish'
4− self.type = 'fish'
4+ self.type = 'simple'
55 self.root_path = 'index.html'
66 self.links = {
77 home: 'https://fishshell.com/',
lib/docs/scrapers/flow.rb+2−2
@@ -1,7 +1,7 @@
11 module Docs
22 class Flow < UrlScraper
3− self.type = 'flow'
4− self.release = '0.75.0'
3+ self.type = 'simple'
4+ self.release = '0.79.1'
55 self.base_url = 'https://flow.org/en/docs/'
66 self.links = {
77 home: 'https://flow.org/',
lib/docs/scrapers/gnu.rb+1−1
@@ -1,6 +1,6 @@
11 module Docs
22 class Gnu < FileScraper
3− self.type = 'gnu'
3+ self.type = 'simple'
44 self.root_path = 'index.html'
55 self.abstract = 'true'
66
lib/docs/scrapers/graphite.rb+21−0
@@ -0,0 +1,21 @@
1+module Docs
2+ class Graphite < UrlScraper
3+ self.type = 'graphite'
4+ self.release = '1.1.3'
5+ self.base_url = 'https://graphite.readthedocs.io/en/latest/'
6+ self.links = {
7+ code: 'https://github.com/graphite-project/graphite-web'
8+ }
9+
10+ html_filters.push 'graphite/entries', 'graphite/clean_html'
11+
12+ options[:container] = '.document > div'
13+ options[:skip] = %w(releases.html who-is-using.html composer.html search.html py-modindex.html genindex.html)
14+
15+ options[:attribution] = <<-HTML
16+ &copy; 2008&ndash;2012 Chris Davis<br>
17+ &copy; 2011&ndash;2016 The Graphite Project<br>
18+ Licensed under the Apache License, Version 2.0.
19+ HTML
20+ end
21+end
lib/docs/scrapers/grunt.rb+1−1
@@ -1,7 +1,7 @@
11 module Docs
22 class Grunt < UrlScraper
33 self.name = 'Grunt'
4− self.type = 'grunt'
4+ self.type = 'simple'
55 self.release = '1.0.1'
66 self.base_url = 'https://gruntjs.com/'
77 self.root_path = 'getting-started'
lib/docs/scrapers/handlebars.rb+23−0
@@ -0,0 +1,23 @@
1+module Docs
2+ class Handlebars < UrlScraper
3+ self.name = 'Handlebars.js'
4+ self.slug = 'handlebars'
5+ self.type = 'simple'
6+ self.release = '4.0.12'
7+ self.base_url = 'https://handlebarsjs.com/'
8+ self.links = {
9+ home: 'https://handlebarsjs.com/',
10+ code: 'https://github.com/wycats/handlebars.js/'
11+ }
12+
13+ html_filters.push 'handlebars/entries', 'handlebars/clean_html', 'title'
14+
15+ options[:container] = '#contents'
16+ options[:root_title] = 'Handlebars.js'
17+
18+ options[:attribution] = <<-HTML
19+ &copy; 2011&ndash;2017 by Yehuda Katz<br>
20+ Licensed under the MIT License.
21+ HTML
22+ end
23+end
lib/docs/scrapers/haxe.rb+1−1
@@ -1,7 +1,7 @@
11 module Docs
22 class Haxe < UrlScraper
33 self.name = 'Haxe'
4− self.type = 'haxe'
4+ self.type = 'simple'
55 self.release = '3.4.7'
66 self.base_url = 'https://api.haxe.org/'
77
lib/docs/scrapers/immutable.rb+1−1
@@ -2,7 +2,7 @@ module Docs · 1 unmodified line
22 class Immutable < UrlScraper
33 self.name = 'Immutable.js'
44 self.slug = 'immutable'
5− self.type = 'immutable'
5+ self.type = 'simple'
66 self.release = '3.8.1'
77 self.base_url = 'https://facebook.github.io/immutable-js/docs/'
88 self.links = {
lib/docs/scrapers/influxdata.rb+1−1
@@ -1,7 +1,7 @@
11 module Docs
22 class Influxdata < UrlScraper
33 self.name = 'InfluxData'
4− self.type = 'influxdata'
4+ self.type = 'simple'
55 self.release = '1.3'
66 self.base_url = 'https://docs.influxdata.com/'
77 self.links = {
lib/docs/scrapers/jasmine.rb+3−3
@@ -1,8 +1,8 @@
11 module Docs
22 class Jasmine < UrlScraper
3− self.type = 'jasmine'
4− self.release = '3.1.0'
5− self.base_url = 'https://jasmine.github.io/api/3.0/'
3+ self.type = 'simple'
4+ self.release = '3.2.1'
5+ self.base_url = 'https://jasmine.github.io/api/3.2/'
66 self.root_path = 'index.html'
77 self.links = {
88 home: 'https://jasmine.github.io/',
lib/docs/scrapers/jest.rb+2−2
@@ -1,7 +1,7 @@
11 module Docs
22 class Jest < UrlScraper
3− self.type = 'jest'
4− self.release = '23.3.0'
3+ self.type = 'simple'
4+ self.release = '23.5.0'
55 self.base_url = 'https://jestjs.io/docs/en/'
66 self.root_path = 'getting-started'
77 self.links = {
lib/docs/scrapers/julia.rb+22−2
@@ -12,9 +12,29 @@ module Docs · 11 unmodified lines
1212 Licensed under the MIT License.
1313 HTML
1414
15+ version '1.0' do
16+ self.release = '1.0.0'
17+ self.base_url = "https://docs.julialang.org/en/v#{release}/"
18+ self.type = 'julia'
19+
20+ html_filters.push 'julia/entries', 'julia/clean_html'
21+
22+ options[:container] = '#docs'
23+ end
24+
25+ version '0.7' do
26+ self.release = '0.7.0'
27+ self.base_url = "https://docs.julialang.org/en/v#{release}/"
28+ self.type = 'julia'
29+
30+ html_filters.push 'julia/entries', 'julia/clean_html'
31+
32+ options[:container] = '#docs'
33+ end
34+
1535 version '0.6' do
1636 self.release = '0.6.2'
17− self.base_url = 'https://docs.julialang.org/en/release-0.6/'
37+ self.base_url = "https://docs.julialang.org/en/v#{release}/"
1838 self.type = 'julia'
1939
2040 html_filters.push 'julia/entries', 'julia/clean_html'
@@ -24,7 +44,7 @@ module Docs · 3 unmodified lines
2444
2545 version '0.5' do
2646 self.release = '0.5.2'
27− self.base_url = 'https://docs.julialang.org/en/release-0.5/'
47+ self.base_url = "https://docs.julialang.org/en/v#{release}/"
2848 self.type = 'sphinx_simple'
2949
3050 html_filters.push 'julia/entries_sphinx', 'julia/clean_html_sphinx', 'sphinx/clean_html'
lib/docs/scrapers/laravel.rb+14−1
@@ -29,8 +29,21 @@ module Docs · 28 unmodified lines
2929 Laravel is a trademark of Taylor Otwell.
3030 HTML
3131
32+ version '5.7' do
33+ self.release = '5.7.7'
34+ self.root_path = '/api/5.7/index.html'
35+ self.initial_paths = %w(/docs/5.7/installation /api/5.7/classes.html)
36+
37+ options[:only_patterns] = [%r{\A/api/5\.7/}, %r{\A/docs/5\.7/}]
38+
39+ options[:fix_urls] = ->(url) do
40+ url.sub! %r{#{Regexp.escape(Laravel.base_url)}/docs\/(?!\d)}, "#{Laravel.base_url}/docs/5.7/"
41+ url
42+ end
43+ end
44+
3245 version '5.6' do
33− self.release = '5.6.12'
46+ self.release = '5.6.33'
3447 self.root_path = '/api/5.6/index.html'
3548 self.initial_paths = %w(/docs/5.6/installation /api/5.6/classes.html)
3649
lib/docs/scrapers/less.rb+1−1
@@ -1,6 +1,6 @@
11 module Docs
22 class Less < UrlScraper
3− self.type = 'less'
3+ self.type = 'simple'
44 self.release = '2.7.2'
55 self.base_url = 'http://lesscss.org'
66 self.root_path = '/features'
lib/docs/scrapers/lodash.rb+1−1
@@ -2,7 +2,7 @@ module Docs · 1 unmodified line
22 class Lodash < UrlScraper
33 self.name = 'lodash'
44 self.slug = 'lodash'
5− self.type = 'lodash'
5+ self.type = 'simple'
66 self.links = {
77 home: 'https://lodash.com/',
88 code: 'https://github.com/lodash/lodash/'
lib/docs/scrapers/marionette.rb+8−1
@@ -2,7 +2,7 @@ module Docs · 1 unmodified line
22 class Marionette < UrlScraper
33 self.name = 'Marionette.js'
44 self.slug = 'marionette'
5− self.type = 'marionette'
5+ self.type = 'simple'
66 self.root_path = 'index'
77 self.links = {
88 home: 'https://marionettejs.com/',
@@ -18,6 +18,13 @@ module Docs · 9 unmodified lines
1818 Licensed under the MIT License.
1919 HTML
2020
21+ version '4' do
22+ self.release = '4.0.0'
23+ self.base_url = "https://marionettejs.com/docs/v#{release}/"
24+
25+ html_filters.push 'marionette/entries_v3'
26+ end
27+
2128 version '3' do
2229 self.release = '3.5.1'
2330 self.base_url = "https://marionettejs.com/docs/v#{release}/"
lib/docs/scrapers/markdown.rb+1−1
@@ -1,7 +1,7 @@
11 module Docs
22 class Markdown < UrlScraper
33 self.name = 'Markdown'
4− self.type = 'markdown'
4+ self.type = 'simple'
55 self.base_url = 'http://daringfireball.net/projects/markdown/syntax'
66
77 html_filters.push 'markdown/clean_html', 'markdown/entries'
lib/docs/scrapers/mocha.rb+1−1
@@ -1,6 +1,6 @@
11 module Docs
22 class Mocha < UrlScraper
3− self.type = 'mocha'
3+ self.type = 'simple'
44 self.release = '5.0.1'
55 self.base_url = 'https://mochajs.org/'
66 self.links = {
lib/docs/scrapers/mongoose.rb+1−1
@@ -1,7 +1,7 @@
11 module Docs
22 class Mongoose < UrlScraper
33 self.name = 'Mongoose'
4− self.type = 'mongoose'
4+ self.type = 'simple'
55 self.release = '4.13.1'
66 self.base_url = 'http://mongoosejs.com/docs/'
77 self.root_path = 'index.html'
lib/docs/scrapers/nim.rb+1−1
@@ -1,6 +1,6 @@
11 module Docs
22 class Nim < UrlScraper
3− self.type = 'nim'
3+ self.type = 'simple'
44 self.release = '0.18.0'
55 self.base_url = 'https://nim-lang.org/docs/'
66 self.root_path = 'overview.html'
lib/docs/scrapers/node.rb+3−3
@@ -23,17 +23,17 @@ module Docs · 22 unmodified lines
2323 HTML
2424
2525 version do
26− self.release = '10.6.0'
26+ self.release = '10.9.0'
2727 self.base_url = 'https://nodejs.org/dist/latest-v10.x/docs/api/'
2828 end
2929
3030 version '8 LTS' do
31− self.release = '8.11.2'
31+ self.release = '8.11.4'
3232 self.base_url = 'https://nodejs.org/dist/latest-v8.x/docs/api/'
3333 end
3434
3535 version '6 LTS' do
36− self.release = '6.14.2'
36+ self.release = '6.14.4'
3737 self.base_url = 'https://nodejs.org/dist/latest-v6.x/docs/api/'
3838 end
3939
lib/docs/scrapers/npm.rb+1−1
@@ -2,7 +2,7 @@ module Docs · 1 unmodified line
22 class Npm < UrlScraper
33 self.name = 'npm'
44 self.type = 'npm'
5− self.release = '6.1.0'
5+ self.release = '6.4.0'
66 self.base_url = 'https://docs.npmjs.com/'
77 self.force_gzip = true
88 self.links = {
lib/docs/scrapers/php.rb+1−1
@@ -4,7 +4,7 @@ module Docs · 3 unmodified lines
44
55 self.name = 'PHP'
66 self.type = 'php'
7− self.release = '7.2.5'
7+ self.release = '7.2.9'
88 self.base_url = 'https://secure.php.net/manual/en/'
99 self.root_path = 'index.html'
1010 self.initial_paths = %w(
lib/docs/scrapers/puppeteer.rb+18−0
@@ -0,0 +1,18 @@
1+module Docs
2+ class Puppeteer < Github
3+ self.release = '1.8.0'
4+ self.base_url = 'https://github.com/GoogleChrome/puppeteer/blob/v1.8.0/docs/api.md'
5+ self.links = {
6+ code: 'https://github.com/GoogleChrome/puppeteer'
7+ }
8+
9+ html_filters.push 'puppeteer/entries', 'puppeteer/clean_html'
10+
11+ options[:container] = '.markdown-body'
12+
13+ options[:attribution] = <<-HTML
14+ &copy; 2017 Google Inc<br>
15+ Licensed under the Apache License 2.0.
16+ HTML
17+ end
18+end
lib/docs/scrapers/pygame.rb+20−0
@@ -0,0 +1,20 @@
1+module Docs
2+ class Pygame < UrlScraper
3+ self.type = 'simple'
4+ self.release = '1.9.4'
5+ self.root_path = 'py-modindex.html'
6+ self.links = {
7+ home: 'https://www.pygame.org/',
8+ code: 'https://github.com/pygame/pygame'
9+ }
10+
11+ html_filters.push 'pygame/clean_html', 'pygame/entries'
12+
13+ options[:only_patterns] = [/ref\//]
14+
15+ options[:attribution] = <<-HTML
16+ &copy; Pygame Developpers.<br>
17+ Licensed under the GNU LGPL License version 2.1.
18+ HTML
19+ end
20+end
lib/docs/scrapers/qt.rb+121−0
@@ -0,0 +1,121 @@
1+module Docs
2+ class Qt < UrlScraper
3+ self.name = 'Qt'
4+ self.type = 'qt'
5+ self.initial_paths = %w(classes.html qmltypes.html)
6+ self.root_path = 'index.html'
7+ self.links = {
8+ home: 'https://www.qt.io',
9+ code: 'https://code.qt.io/cgit/'
10+ }
11+
12+ html_filters.push 'qt/entries', 'qt/clean_html'
13+
14+ options[:container] = '.main'
15+ options[:max_image_size] = 156_000
16+ options[:skip_patterns] = [
17+ # License, copyright attributions
18+ /3rdparty/,
19+ /attribution/,
20+ /license/,
21+ /licensing/,
22+
23+ # Examples, guides, tutorials
24+ /example/,
25+ /guide$/,
26+ /tutorial/,
27+ /porting/,
28+ /usecase/,
29+ /topic/,
30+ /^modelview/,
31+ /deploy(ing|ment)/,
32+ /building/,
33+
34+ # Old versions, changelog
35+ /obsolete/,
36+ /compatibility/,
37+ /^whatsnew/,
38+ /^newclasses/,
39+
40+ # Deprecated modules
41+ /(qtopengl|qgl)/,
42+ /qt?script/,
43+
44+ # Indexes
45+ /members/,
46+ /module/,
47+ /overview/,
48+ /^qopenglfunctions/,
49+
50+ # Tooling
51+ /^(qt)?(linguist|assistant|qdbusviewer)/,
52+ ]
53+
54+ options[:skip] = [
55+ "qt5-intro.html",
56+ "compatmap.html",
57+
58+ # Indexes
59+ "classes.html",
60+ "qtmodules.html",
61+ "modules-qml.html",
62+ "modules-cpp.html",
63+ "functions.html",
64+ "namespaces.html",
65+ "qmltypes.html",
66+ "qt3d-qml.html",
67+ "qmlbasictypes.html",
68+ "guibooks.html",
69+ "annotated.html",
70+ "overviews-main.html",
71+ "reference-overview.html",
72+
73+ # Tutorials
74+ "qtvirtualkeyboard-build.html",
75+
76+ # Copyright
77+ "trademarks.html",
78+ "lgpl.html",
79+ "bughowto.html",
80+
81+ # Changelogs
82+ "changes.html",
83+ "qtlocation-changes.html",
84+ "sourcebreaks.html",
85+
86+ # Best practice guides
87+ "accessible.html",
88+ "accessible-qtquick.html",
89+ "sharedlibrary.html",
90+ "exceptionsafety.html",
91+ "scalability.html",
92+ "session.html",
93+ "appicon.html",
94+ "accelerators.html",
95+
96+ # Other
97+ "ecmascript.html",
98+ "qtremoteobjects-interaction.html",
99+ ]
100+
101+ options[:attribution] = <<-HTML
102+ &copy; The Qt Company Ltd<br>
103+ Licensed under the GNU Free Documentation License, Version 1.3.
104+ HTML
105+
106+ version '5.11' do
107+ self.release = '5.11'
108+ self.base_url = 'https://doc.qt.io/qt-5/'
109+ end
110+
111+ version '5.9' do
112+ self.release = '5.9'
113+ self.base_url = 'https://doc.qt.io/qt-5.9/'
114+ end
115+
116+ version '5.6' do
117+ self.release = '5.6'
118+ self.base_url = 'https://doc.qt.io/qt-5.6/'
119+ end
120+ end
121+end
lib/docs/scrapers/redis.rb+1−1
@@ -1,7 +1,7 @@
11 module Docs
22 class Redis < UrlScraper
33 self.type = 'redis'
4− self.release = '4.0.9'
4+ self.release = '4.0.11'
55 self.base_url = 'https://redis.io/commands'
66 self.links = {
77 home: 'https://redis.io/',
lib/docs/scrapers/redux.rb+1−1
@@ -1,6 +1,6 @@
11 module Docs
22 class Redux < UrlScraper
3− self.type = 'redux'
3+ self.type = 'simple'
44 self.release = '3.7.2'
55 self.base_url = 'http://redux.js.org/docs/'
66 self.links = {
lib/docs/scrapers/requirejs.rb+1−1
@@ -1,7 +1,7 @@
11 module Docs
22 class Requirejs < UrlScraper
33 self.name = 'RequireJS'
4− self.type = 'requirejs'
4+ self.type = 'simple'
55 self.release = '2.3.5'
66 self.base_url = 'http://requirejs.org/docs/'
77 self.links = {
lib/docs/scrapers/rust.rb+5−5
@@ -1,9 +1,9 @@
11 module Docs
22 class Rust < UrlScraper
33 self.type = 'rust'
4− self.release = '1.26.0'
4+ self.release = '1.29.1'
55 self.base_url = 'https://doc.rust-lang.org/'
6− self.root_path = 'book/first-edition/index.html'
6+ self.root_path = 'book/second-edition/index.html'
77 self.initial_paths = %w(
88 reference/introduction.html
99 collections/index.html
@@ -17,13 +17,13 @@ module Docs · 7 unmodified lines
1717 html_filters.push 'rust/entries', 'rust/clean_html'
1818
1919 options[:only_patterns] = [
20− /\Abook\/first-edition\//,
20+ /\Abook\/second-edition\//,
2121 /\Areference\//,
2222 /\Acollections\//,
2323 /\Astd\// ]
2424
25− options[:skip] = %w(book/first-edition/README.html)
26− options[:skip_patterns] = [/(?<!\.html)\z/]
25+ options[:skip] = %w(book/second-edition/README.html)
26+ options[:skip_patterns] = [/(?<!\.html)\z/, /\/print\.html/]
2727
2828 options[:fix_urls] = ->(url) do
2929 url.sub! %r{(#{Rust.base_url}.+/)\z}, '\1index.html'
lib/docs/scrapers/typescript.rb+2−2
@@ -1,8 +1,8 @@
11 module Docs
22 class Typescript < UrlScraper
33 self.name = 'TypeScript'
4− self.type = 'typescript'
5− self.release = '2.9.0'
4+ self.type = 'simple'
5+ self.release = '3.0.1'
66 self.base_url = 'https://www.typescriptlang.org/docs/'
77 self.root_path = 'tutorial.html'
88 self.links = {
lib/docs/scrapers/vagrant.rb+1−1
@@ -1,7 +1,7 @@
11 module Docs
22 class Vagrant < UrlScraper
33 self.name = 'Vagrant'
4− self.type = 'vagrant'
4+ self.type = 'simple'
55 self.release = '2.1.1'
66 self.base_url = 'https://www.vagrantup.com/docs/'
77 self.root_path = 'index.html'
lib/docs/scrapers/vulkan.rb+1−1
@@ -1,7 +1,7 @@
11 module Docs
22 class Vulkan < UrlScraper
33 self.name = 'Vulkan'
4− self.type = 'vulkan'
4+ self.type = 'simple'
55 self.release = '1.0.59'
66 self.base_url = 'https://www.khronos.org/registry/vulkan/specs/1.0/'
77 self.root_path = 'apispec.html'
lib/docs/scrapers/webpack.rb+1−1
@@ -4,7 +4,7 @@ module Docs · 3 unmodified lines
44 self.type = 'webpack'
55
66 version do
7− self.release = '4.12.0'
7+ self.release = '4.16.5'
88 self.base_url = 'https://webpack.js.org/'
99 self.root_path = 'guides/'
1010 self.initial_paths = %w(
lib/docs/scrapers/yarn.rb+2−2
@@ -1,7 +1,7 @@
11 module Docs
22 class Yarn < UrlScraper
3− self.type = 'yarn'
4− self.release = '1.7.0'
3+ self.type = 'simple'
4+ self.release = '1.9.4'
55 self.base_url = 'https://yarnpkg.com/en/docs/'
66 self.links = {
77 home: 'https://yarnpkg.com/',
lib/tasks/docs.thor+6−2
@@ -175,9 +175,13 @@ class DocsCLI < Thor · 174 unmodified lines
175175 private
176176
177177 def find_docs(names)
178− names.map do |name|
178+ names.flat_map do |name|
179179 name, version = name.split(/@|~/)
180− Docs.find(name, version)
180+ if version == 'all'
181+ Docs.find(name, false).versions
182+ else
183+ Docs.find(name, version)
184+ end
181185 end
182186 end
183187
public/icons/docs-2.pxm+0−0

Binary file not shown.

public/icons/docs-2@2x.pxm+0−0

Binary file not shown.

public/icons/docs/bash/16.png+0−0

Binary file not shown.

public/icons/docs/bash/16@2x.png+0−0

Binary file not shown.

public/icons/docs/bash/SOURCE+1−0
@@ -0,0 +1 @@
1+https://github.com/odb/official-bash-logo
public/icons/docs/dart/16.png+0−0

Binary file not shown.

public/icons/docs/dart/16@2x.png+0−0

Binary file not shown.

public/icons/docs/dart/SOURCE+1−0
@@ -0,0 +1 @@
1+https://github.com/dart-lang/logos
public/icons/docs/handlebars/16.png+0−0

Binary file not shown.

public/icons/docs/handlebars/16@2x.png+0−0

Binary file not shown.

public/icons/docs/handlebars/SOURCE+1−0
@@ -0,0 +1 @@
1+https://github.com/yahoo/formatjs-site/tree/master/public/img
public/icons/docs/puppeteer/16.png+0−0

Binary file not shown.

public/icons/docs/puppeteer/16@2x.png+0−0

Binary file not shown.

public/icons/docs/puppeteer/SOURCE+1−0
@@ -0,0 +1 @@
1+https://github.com/GoogleChromeLabs/pptr.dev/tree/master/src/favicons
public/icons/docs/pygame/16.png+0−0

Binary file not shown.

public/icons/docs/pygame/16@2x.png+0−0

Binary file not shown.

public/icons/docs/qt/16.png+0−0

Binary file not shown.

public/icons/docs/qt/16@2x.png+0−0

Binary file not shown.

public/icons/docs/qt/SOURCE+1−0
@@ -0,0 +1 @@
1+https://commons.wikimedia.org/wiki/File:Qt_logo_2016.svg
public/images/webapp-icon-512.png+0−0

Binary file not shown.

public/manifest.json+5−0
@@ -29,6 +29,11 @@ · 28 unmodified lines
2929 "src": "/images/webapp-icon-256.png",
3030 "sizes": "256x256",
3131 "type": "image/png"
32+ },
33+ {
34+ "src": "/images/webapp-icon-512.png",
35+ "sizes": "512x512",
36+ "type": "image/png"
3237 }
3338 ]
3439 }
test/app_test.rb+43−21
@@ -11,6 +11,16 @@ class AppTest < MiniTest::Spec · 10 unmodified lines
1111 App
1212 end
1313
14+ before do
15+ current_session.env('HTTPS', 'on')
16+ end
17+
18+ it 'redirects to HTTPS' do
19+ get 'http://example.com/test?q=1', {}, 'HTTPS' => 'off'
20+ assert last_response.redirect?
21+ assert_equal 'https://example.com/test?q=1', last_response['Location']
22+ end
23+
1424 describe "/" do
1525 it "works" do
1626 get '/'
@@ -20,13 +30,13 @@ class AppTest < MiniTest::Spec · 3 unmodified lines
2030 it "redirects to /#q= when there is a 'q' query param" do
2131 get '/search', q: 'foo'
2232 assert last_response.redirect?
23− assert_equal 'http://example.org/#q=foo', last_response['Location']
33+ assert_equal 'https://example.org/#q=foo', last_response['Location']
2434 end
2535
2636 it "redirects without the query string" do
2737 get '/', foo: 'bar'
2838 assert last_response.redirect?
29− assert_equal 'http://example.org/', last_response['Location']
39+ assert_equal 'https://example.org/', last_response['Location']
3040 end
3141
3242 it "sets default size" do
@@ -45,6 +55,18 @@ class AppTest < MiniTest::Spec · 12 unmodified lines
4555 get '/'
4656 assert_includes last_response.body, '<body class="foo">'
4757 end
58+
59+ it "sets the <html> theme from cookie" do
60+ get '/'
61+ assert_match %r{<html [^>]*class="[^\"]*_theme-default}, last_response.body
62+ refute_includes last_response.body, '_theme-dark'
63+
64+ set_cookie('dark=1')
65+
66+ get '/'
67+ assert_match %r{<html [^>]*class="[^\"]*_theme-dark}, last_response.body
68+ refute_includes last_response.body, '_theme-default'
69+ end
4870 end
4971
5072 describe "/[static-page]" do
@@ -52,7 +74,7 @@ class AppTest < MiniTest::Spec · 1 unmodified line
5274 %w(offline about news help).each do |page|
5375 get "/#{page}", {}, 'HTTP_USER_AGENT' => MODERN_BROWSER
5476 assert last_response.redirect?
55− assert_equal "http://example.org/#/#{page}", last_response['Location']
77+ assert_equal "https://example.org/#/#{page}", last_response['Location']
5678 end
5779 end
5880
@@ -61,7 +83,7 @@ class AppTest < MiniTest::Spec · 2 unmodified lines
6183 set_cookie('foo=bar')
6284 get "/#{page}", {}, 'HTTP_USER_AGENT' => MODERN_BROWSER
6385 assert last_response.redirect?
64− assert_equal 'http://example.org/', last_response['Location']
86+ assert_equal 'https://example.org/', last_response['Location']
6587 assert last_response['Set-Cookie'].start_with?("initial_path=%2F#{page}; path=/; expires=")
6688 end
6789 end
@@ -71,11 +93,11 @@ class AppTest < MiniTest::Spec · 3 unmodified lines
7193 it "redirects to /#q=" do
7294 get '/search'
7395 assert last_response.redirect?
74− assert_equal 'http://example.org/#q=', last_response['Location']
96+ assert_equal 'https://example.org/#q=', last_response['Location']
7597
7698 get '/search', q: 'foo'
7799 assert last_response.redirect?
78− assert_equal 'http://example.org/#q=foo', last_response['Location']
100+ assert_equal 'https://example.org/#q=foo', last_response['Location']
79101 end
80102 end
81103
@@ -148,7 +170,7 @@ class AppTest < MiniTest::Spec · 66 unmodified lines
148170 set_cookie('docs=html~5')
149171 get '/html~5/', {}, 'HTTP_USER_AGENT' => MODERN_BROWSER
150172 assert last_response.redirect?
151− assert_equal 'http://example.org/', last_response['Location']
173+ assert_equal 'https://example.org/', last_response['Location']
152174 assert last_response['Set-Cookie'].start_with?("initial_path=%2Fhtml%7E5%2F; path=/; expires=")
153175 end
154176
@@ -161,13 +183,13 @@ class AppTest < MiniTest::Spec · 6 unmodified lines
161183 set_cookie('docs=html~5')
162184 get '/html/', {}, 'HTTP_USER_AGENT' => MODERN_BROWSER
163185 assert last_response.redirect?
164− assert_equal 'http://example.org/', last_response['Location']
186+ assert_equal 'https://example.org/', last_response['Location']
165187 assert last_response['Set-Cookie'].start_with?("initial_path=%2Fhtml%2F; path=/; expires=")
166188 end
167189
168190 it "renders when the doc exists and is enabled, and the request is from Googlebot" do
169191 set_cookie('docs=html')
170− get '/html/', {}, 'HTTP_USER_AGENT' => 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'
192+ get '/html/', {}, 'HTTP_USER_AGENT' => 'Mozilla/5.0 (compatible; Googlebot/2.1; +https://www.google.com/bot.html)'
171193 assert last_response.ok?
172194 end
173195
@@ -187,17 +209,17 @@ class AppTest < MiniTest::Spec · 13 unmodified lines
187209 it "redirects with trailing slash" do
188210 get '/html'
189211 assert last_response.redirect?
190− assert_equal 'http://example.org/html/', last_response['Location']
212+ assert_equal 'https://example.org/html/', last_response['Location']
191213
192214 get '/html', bar: 'baz'
193215 assert last_response.redirect?
194− assert_equal 'http://example.org/html/?bar=baz', last_response['Location']
216+ assert_equal 'https://example.org/html/?bar=baz', last_response['Location']
195217 end
196218
197219 it "redirects old docs" do
198220 get '/iojs/'
199221 assert last_response.redirect?
200− assert_equal 'http://example.org/node/', last_response['Location']
222+ assert_equal 'https://example.org/node/', last_response['Location']
201223 end
202224 end
203225
@@ -232,17 +254,17 @@ class AppTest < MiniTest::Spec · 28 unmodified lines
232254 it "redirects with trailing slash" do
233255 get '/css-foo'
234256 assert last_response.redirect?
235− assert_equal 'http://example.org/css-foo/', last_response['Location']
257+ assert_equal 'https://example.org/css-foo/', last_response['Location']
236258
237259 get '/css-foo', bar: 'baz'
238260 assert last_response.redirect?
239− assert_equal 'http://example.org/css-foo/?bar=baz', last_response['Location']
261+ assert_equal 'https://example.org/css-foo/?bar=baz', last_response['Location']
240262 end
241263
242264 it "redirects old docs" do
243265 get '/yii1-foo/'
244266 assert last_response.redirect?
245− assert_equal 'http://example.org/yii~1.1-foo/', last_response['Location']
267+ assert_equal 'https://example.org/yii~1.1-foo/', last_response['Location']
246268 end
247269 end
248270
@@ -263,17 +285,17 @@ class AppTest < MiniTest::Spec · 14 unmodified lines
263285 it "redirects without trailing slash" do
264286 get '/css/foo/'
265287 assert last_response.redirect?
266− assert_equal 'http://example.org/css/foo', last_response['Location']
288+ assert_equal 'https://example.org/css/foo', last_response['Location']
267289
268290 get '/css/foo/', bar: 'baz'
269291 assert last_response.redirect?
270− assert_equal 'http://example.org/css/foo?bar=baz', last_response['Location']
292+ assert_equal 'https://example.org/css/foo?bar=baz', last_response['Location']
271293 end
272294
273295 it "redirects old docs" do
274296 get '/python2/foo'
275297 assert last_response.redirect?
276− assert_equal 'http://example.org/python~2.7/foo', last_response['Location']
298+ assert_equal 'https://example.org/python~2.7/foo', last_response['Location']
277299 end
278300 end
279301
@@ -281,7 +303,7 @@ class AppTest < MiniTest::Spec · 1 unmodified line
281303 it "returns to the asset path" do
282304 get '/docs.json'
283305 assert last_response.redirect?
284− assert_equal 'http://example.org/assets/docs.json', last_response['Location']
306+ assert_equal 'https://example.org/assets/docs.json', last_response['Location']
285307 end
286308 end
287309
@@ -289,7 +311,7 @@ class AppTest < MiniTest::Spec · 1 unmodified line
289311 it "returns to the asset path" do
290312 get '/application.js'
291313 assert last_response.redirect?
292− assert_equal 'http://example.org/assets/application.js', last_response['Location']
314+ assert_equal 'https://example.org/assets/application.js', last_response['Location']
293315 end
294316 end
295317
@@ -297,7 +319,7 @@ class AppTest < MiniTest::Spec · 1 unmodified line
297319 it "returns to the asset path" do
298320 get '/application.css'
299321 assert last_response.redirect?
300− assert_equal 'http://example.org/assets/application.css', last_response['Location']
322+ assert_equal 'https://example.org/assets/application.css', last_response['Location']
301323 end
302324 end
303325
views/index.erb+2−2
@@ -1,5 +1,5 @@
11 <!DOCTYPE html>
2−<html<%= ' manifest="/manifest.appcache"' if App.production? %> prefix="og: http://ogp.me/ns#" lang="en" class="_booting">
2+<html<%= ' manifest="/manifest.appcache"' if App.production? %> prefix="og: http://ogp.me/ns#" lang="en" class="_booting _theme-<%= app_theme %>">
33 <head>
44 <meta charset="utf-8">
55 <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,shrink-to-fit=no">
@@ -30,7 +30,7 @@ · 24 unmodified lines
3030 <link rel="apple-touch-icon" sizes="152x152" href="<%= App.cdn_origin %>/images/apple-icon-152.png">
3131 <link rel="apple-touch-icon" sizes="160x160" href="<%= App.cdn_origin %>/images/apple-icon-160.png">
3232 <link rel="mask-icon" href="<%= App.cdn_origin %>/images/webkit-mask-icon.svg" color="#398df0">
33− <link rel="stylesheet" href="<%= main_stylesheet_path %>" data-alt="<%= alternate_stylesheet_path %>">
33+ <%= stylesheet_tag 'application' %>
3434 </head>
3535 <body<%= %( class="#{app_layout}") if app_layout %>>
3636 <noscript class="_fail">DevDocs requires JavaScript to run.</noscript>
views/other.erb+2−2
@@ -1,5 +1,5 @@
11 <!DOCTYPE html>
2−<html lang="en" class="_booting">
2+<html lang="en" class="_booting _theme-<%= app_theme %>">
33 <head>
44 <meta charset="utf-8">
55 <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
@@ -11,7 +11,7 @@ · 5 unmodified lines
1111 <link rel="manifest" href="/manifest.json">
1212 <link rel="icon" type="image/x-icon" href="<%= App.cdn_origin %>/favicon.ico">
1313 <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="Search DevDocs">
14− <link rel="stylesheet" href="<%= main_stylesheet_path %>" data-alt="<%= alternate_stylesheet_path %>">
14+ <%= stylesheet_tag 'application' %>
1515 </head>
1616 <body<%= %( class="#{app_layout}") if app_layout %> data-doc="<%= CGI::escape_html @doc.to_json %>">
1717 <noscript class="_fail">DevDocs requires JavaScript to run.</noscript>
views/unsupported.erb+4−7
@@ -10,13 +10,10 @@ · 9 unmodified lines
1010 <h1 class="_fail-title">Your browser is unsupported, sorry.</h1>
1111 <p class="_fail-text">DevDocs is an API documentation browser which supports the following browsers:</p>
1212 <ul class="_fail-list">
13− <li>Recent versions of Chrome and Firefox</li>
14− <li>Safari 5.1+</li>
15− <li>Opera 12.1+</li>
16− <li>Internet Explorer 10+</li>
17− <li>iOS 6+</li>
18− <li>Android 4.1+</li>
19− <li>Windows Phone 8+</li>
13+ <li>Recent versions of Firefox, Chrome, or Opera</li>
14+ <li>Safari 9.1+</li>
15+ <li>Edge 16+</li>
16+ <li>iOS 10+</li>
2017 </ul>
2118 <p class="_fail-text">
2219 If you're unable to upgrade, I apologize.