public/icons/*your_scraper_name*/
directory:
+ - [ ] `16.png`: a 16×16 pixel icon for the doc
+ - [ ] `16@2x.png`: a 32×32 pixel icon for the doc
+ - [ ] `SOURCE`: A text file containing the URL to the page the image can be found on or the URL of the original image itself
+
+
diff --git a/Procfile b/Procfile
new file mode 100644
index 00000000..8c995585
--- /dev/null
+++ b/Procfile
@@ -0,0 +1 @@
+web: bundle exec rackup config.ru -p $PORT
diff --git a/README.md b/README.md
index f6859b90..630142d4 100644
--- a/README.md
+++ b/README.md
@@ -1,29 +1,27 @@
-# [DevDocs](http://devdocs.io) [![Build Status](https://travis-ci.org/Thibaut/devdocs.svg?branch=master)](https://travis-ci.org/Thibaut/devdocs)
+# [DevDocs](https://devdocs.io) — API Documentation Browser [![Build Status](https://travis-ci.org/freeCodeCamp/devdocs.svg?branch=master)](https://travis-ci.org/freeCodeCamp/devdocs)
-DevDocs combines multiple API documentations in a fast, organized, and searchable interface.
+DevDocs combines multiple developer documentations in a clean and organized web UI with instant search, offline support, mobile version, dark theme, keyboard shortcuts, and more.
-* Created by [Thibaut Courouble](https://thibaut.me)
+DevDocs was created by [Thibaut Courouble](https://thibaut.me) and is operated by [freeCodeCamp](https://www.freecodecamp.org).
Keep track of development news:
-* Watch the repository on [GitHub](https://github.com/Thibaut/devdocs/subscription)
+* Join the contributor chat room on [Gitter](https://gitter.im/FreeCodeCamp/DevDocs)
+* Watch the repository on [GitHub](https://github.com/freeCodeCamp/devdocs/subscription)
* Follow [@DevDocs](https://twitter.com/DevDocs) on Twitter
-* Join the [mailing list](https://groups.google.com/d/forum/devdocs)
-DevDocs is free and open source. If you like it, please consider supporting my work on [Gratipay](https://gratipay.com/devdocs/). Thanks!
-
-**Table of Contents:** [Quick Start](#quick-start) · [Vision](#vision) · [App](#app) · [Scraper](#scraper) · [Commands](#available-commands) · [Contributing](#contributing) · [License](#copyright--license) · [Questions?](#questions)
+**Table of Contents:** [Quick Start](#quick-start) · [Vision](#vision) · [App](#app) · [Scraper](#scraper) · [Commands](#available-commands) · [Contributing](#contributing) · [Documentation](#documentation) · [Plugins and Extensions](#plugins-and-extensions) · [License](#copyright--license) · [Questions?](#questions)
## Quick Start
-Unless you wish to contribute to the project, I recommend using the hosted version at [devdocs.io](http://devdocs.io). It's up-to-date and works offline out-of-the-box.
+Unless you wish to contribute to the project, we recommend using the hosted version at [devdocs.io](https://devdocs.io). It's up-to-date and works offline out-of-the-box.
DevDocs is made of two pieces: a Ruby scraper that generates the documentation and metadata, and a JavaScript app powered by a small Sinatra app.
-DevDocs requires Ruby 2.4.2, libcurl, and a JavaScript runtime supported by [ExecJS](https://github.com/rails/execjs#readme) (included in OS X and Windows; [Node.js](https://nodejs.org/en/) on Linux). Once you have these installed, run the following commands:
+DevDocs requires Ruby 2.6.0, libcurl, and a JavaScript runtime supported by [ExecJS](https://github.com/rails/execjs#readme) (included in OS X and Windows; [Node.js](https://nodejs.org/en/) on Linux). Once you have these installed, run the following commands:
```
-git clone https://github.com/Thibaut/devdocs.git && cd devdocs
+git clone https://github.com/freeCodeCamp/devdocs.git && cd devdocs
gem install bundler
bundle install
bundle exec thor docs:download --default
@@ -34,13 +32,13 @@ Finally, point your browser at [localhost:9292](http://localhost:9292) (the firs
The `thor docs:download` command is used to download pre-generated documentations from DevDocs's servers (e.g. `thor docs:download html css`). You can see the list of available documentations and versions by running `thor docs:list`. To update all downloaded documentations, run `thor docs:download --installed`.
-**Note:** there is currently no update mechanism other than `git pull origin master` to update the code and `thor docs:download --installed` to download the latest version of the docs. To stay informed about new releases, be sure to [watch](https://github.com/Thibaut/devdocs/subscription) this repository.
+**Note:** there is currently no update mechanism other than `git pull origin master` to update the code and `thor docs:download --installed` to download the latest version of the docs. To stay informed about new releases, be sure to [watch](https://github.com/freeCodeCamp/devdocs/subscription) this repository.
Alternatively, DevDocs may be started as a Docker container:
```
# First, build the image
-git clone https://github.com/Thibaut/devdocs.git && cd devdocs
+git clone https://github.com/freeCodeCamp/devdocs.git && cd devdocs
docker build -t thibaut/devdocs .
# Finally, start a DevDocs container (access http://localhost:9292)
@@ -61,18 +59,14 @@ The web app is all client-side JavaScript, written in [CoffeeScript](http://coff
Many of the code's design decisions were driven by the fact that the app uses XHR to load content directly into the main frame. This includes stripping the original documents of most of their HTML markup (e.g. scripts and stylesheets) to avoid polluting the main frame, and prefixing all CSS class names with an underscore to prevent conflicts.
-Another driving factor is performance and the fact that everything happens in the browser. `applicationCache` (which comes with its own set of constraints) and `localStorage` are used to speed up the boot time, while memory consumption is kept in check by allowing the user to pick his/her own set of documentations. The search algorithm is kept simple because it needs to be fast even searching through 100,000 strings.
+Another driving factor is performance and the fact that everything happens in the browser. A service worker (which comes with its own set of constraints) and `localStorage` are used to speed up the boot time, while memory consumption is kept in check by allowing the user to pick his/her own set of documentations. The search algorithm is kept simple because it needs to be fast even searching through 100,000 strings.
DevDocs being a developer tool, the browser requirements are high:
-1. On the desktop:
- * Recent version of Chrome, Firefox, or Opera
- * Safari 8+
- * IE / Edge 10+
-2. On mobile:
- * iOS 8+
- * Android 4.1+
- * Windows Phone 8+
+* Recent versions of Firefox, Chrome, or Opera
+* Safari 11.1+
+* Edge 17+
+* iOS 11.3+
This allows the code to take advantage of the latest DOM and HTML5 APIs and make developing DevDocs a lot more fun!
@@ -89,12 +83,13 @@ Modifications made to each document include:
* replacing all external (not scraped) URLs with their fully qualified counterpart
* replacing all internal (scraped) URLs with their unqualified and relative counterpart
* adding content, such as a title and link to the original document
+* ensuring correct syntax highlighting using [Prism](http://prismjs.com/)
These modifications are applied via a set of filters using the [HTML::Pipeline](https://github.com/jch/html-pipeline) library. Each scraper includes filters specific to itself, one of which is tasked with figuring out the pages' metadata.
The end result is a set of normalized HTML partials and two JSON files (index + offline data). Because the index files are loaded separately by the [app](#app) following the user's preferences, the scraper also creates a JSON manifest file containing information about the documentations currently available on the system (such as their name, version, update date, etc.).
-More information about scrapers and filters is available on the [wiki](https://github.com/Thibaut/devdocs/wiki).
+More information about [scrapers](./docs/scraper-reference.md) and [filters](./docs/filter-reference.md) is available in the `docs` folder.
## Available Commands
@@ -134,20 +129,45 @@ If multiple versions of Ruby are installed on your system, commands must be run
## Contributing
-Contributions are welcome. Please read the [contributing guidelines](https://github.com/Thibaut/devdocs/blob/master/CONTRIBUTING.md).
-
-DevDocs's own documentation is available on the [wiki](https://github.com/Thibaut/devdocs/wiki).
+Contributions are welcome. Please read the [contributing guidelines](./.github/CONTRIBUTING.md).
+
+## Documentation
+
+* [Adding documentations to DevDocs](./docs/adding-docs.md)
+* [Scraper Reference](./docs/scraper-reference.md)
+* [Filter Reference](./docs/filter-reference.md)
+* [Maintainers’ Guide](./docs/maintainers.md)
+
+## Plugins and Extensions
+
+* [Chrome web app](https://chrome.google.com/webstore/detail/devdocs/mnfehgbmkapmjnhcnbodoamcioleeooe)
+* [Ubuntu Touch app](https://uappexplorer.com/app/devdocsunofficial.berkes)
+* [Sublime Text plugin](https://sublime.wbond.net/packages/DevDocs)
+* [Atom plugin](https://atom.io/packages/devdocs)
+* [Brackets extension](https://github.com/gruehle/dev-docs-viewer)
+* [Fluid](http://fluidapp.com) for turning DevDocs into a real OS X app
+* [GTK shell / Vim integration](https://github.com/naquad/devdocs-shell)
+* [Emacs lookup](https://github.com/skeeto/devdocs-lookup)
+* [Alfred Workflow](https://github.com/yannickglt/alfred-devdocs)
+* [Vim search plugin with Devdocs in its defaults](https://github.com/waiting-for-dev/vim-www) Just set `let g:www_shortcut_engines = { 'devdocs': ['Devdocs', '$
is an alias for jQuery
).\nClick here to see the full list. Feel free to suggest more on GitHub.",
+ "Added search aliases (e.g. $
is an alias for jQuery
).\nClick here to see the full list. Feel free to suggest more on GitHub.",
"Added shift + ↓/↑
shortcut for scrolling (same as alt + ↓/↑
)."
], [
"2015-07-05",
@@ -151,7 +183,7 @@
"New Python 2 documentation"
], [
"2014-11-09",
- "New design\nFeedback welcome on Twitter and GitHub."
+ "New design\nFeedback welcome on Twitter and GitHub."
], [
"2014-10-19",
"New SVG, Marionette.js, and Mongoose documentations"
@@ -236,7 +268,7 @@
"New Ruby documentation"
], [
"2013-10-24",
- "DevDocs is now open source."
+ "DevDocs is now open source."
], [
"2013-10-09",
"DevDocs is now available as a Chrome web app."
diff --git a/assets/javascripts/templates/error_tmpl.coffee b/assets/javascripts/templates/error_tmpl.coffee
index 9dc311d9..9cca1f9d 100644
--- a/assets/javascripts/templates/error_tmpl.coffee
+++ b/assets/javascripts/templates/error_tmpl.coffee
@@ -12,8 +12,8 @@ app.templates.notFoundPage = ->
app.templates.pageLoadError = ->
error """ The page failed to load. """,
- """ It may be missing from the server (try reloading the app) or you could be offline.#{exception.name}: #{exception.message}
"""
when 'cant_open'
- """ An error occured when trying to open the IndexedDB database:#{exception.name}: #{exception.message}
DevDocs is an API documentation browser which supports the following browsers:
- If you're unable to upgrade, I apologize. - I decided to prioritize speed and new features over support for older browsers. + If you're unable to upgrade, we apologize. + We decided to prioritize speed and new features over support for older browsers.
Note: if you're already using one of the browsers above, check your settings and add-ons. The app uses feature detection, not user agent sniffing.
- — Thibaut @DevDocs + — @DevDocs """ diff --git a/assets/javascripts/templates/notice_tmpl.coffee b/assets/javascripts/templates/notice_tmpl.coffee index 75818967..10cc534e 100644 --- a/assets/javascripts/templates/notice_tmpl.coffee +++ b/assets/javascripts/templates/notice_tmpl.coffee @@ -2,7 +2,7 @@ notice = (text) -> """
#{text}
""" app.templates.singleDocNotice = (doc) -> notice """ You're browsing the #{doc.fullName} documentation. To browse all docs, go to - #{app.config.production_host} (or pressesc
). """
+ #{app.config.production_host} (or press esc
). """
app.templates.disabledDocNotice = ->
notice """ This documentation is disabled.
diff --git a/assets/javascripts/templates/notif_tmpl.coffee b/assets/javascripts/templates/notif_tmpl.coffee
index 0cd8531c..0821036e 100644
--- a/assets/javascripts/templates/notif_tmpl.coffee
+++ b/assets/javascripts/templates/notif_tmpl.coffee
@@ -13,10 +13,10 @@ app.templates.notifUpdateReady = ->
"""Reload the page to use the new version."""
app.templates.notifError = ->
- textNotif """ Oops, an error occured. """,
+ textNotif """ Oops, an error occurred. """,
""" Try reloading, and if the problem persists,
resetting the app.DevDocs combines multiple API documentations in a clean and organized web UI with instant search, offline support, mobile version, dark theme, keyboard shortcuts, and more. -
DevDocs combines multiple developer documentations in a clean and organized web UI with instant search, offline support, mobile version, dark theme, keyboard shortcuts, and more. +
DevDocs is free and open source. It was created by Thibaut Courouble and is operated by freeCodeCamp.
To keep up-to-date with the latest news:
If you like DevDocs, please spread the word and consider supporting my work on
- Gratipay. Thanks!
- Copyright 2013–2017 Thibaut Courouble and other contributors
+ Copyright 2013–2019 Thibaut Courouble and other contributors
This software is licensed under the terms of the Mozilla Public License v2.0.
- You may obtain a copy of the source code at github.com/Thibaut/devdocs.
- For more information, see the COPYRIGHT
- and LICENSE files.
+ You may obtain a copy of the source code at github.com/freeCodeCamp/devdocs.
+ For more information, see the COPYRIGHT
+ and LICENSE files.
For anything else, feel free to email me at thibaut@devdocs.io.
Special thanks to:
@@ -57,9 +57,7 @@ app.templates.helpPage = ->
tab
when devdocs.io is autocompleted
in the omnibox (to set a custom keyword, click Manage search engines\u2026 in Chrome's settings).
- Note: the above search features only work for documentations that are enabled. @@ -133,6 +131,9 @@ app.templates.helpPage = ->
alt + s
alt + d
+
Tip: If the cursor is no longer in the search field, press /
or
@@ -153,5 +154,5 @@ app.templates.helpPage = ->
#{("
Feel free to suggest new aliases on GitHub. +
Feel free to suggest new aliases on GitHub. """ diff --git a/assets/javascripts/templates/pages/news_tmpl.coffee.erb b/assets/javascripts/templates/pages/news_tmpl.coffee.erb index f4045bd7..f6760a61 100644 --- a/assets/javascripts/templates/pages/news_tmpl.coffee.erb +++ b/assets/javascripts/templates/pages/news_tmpl.coffee.erb @@ -4,7 +4,7 @@ app.templates.newsPage = -> """
For the latest news, follow @DevDocs.
- For development updates, follow the project on GitHub.
+ For development updates, follow the project on GitHub.
ENABLE_SERVICE_WORKER
environment variable to true
)"
+
+ """ No. Service Workers #{reason}, so loading devdocs.io offline won't work.Thanks for downloading DevDocs. Here are a few things you should know:
thor docs:list
to see all available documentations.
thor docs:download <name>
to download documentations.
thor docs:download --installed
to update all downloaded documentations.
- Happy coding! @@ -39,9 +38,8 @@ app.templates.intro = """
Happy coding! @@ -59,7 +57,7 @@ app.templates.mobileIntro = """
Happy coding! Stop showing this message @@ -71,6 +69,6 @@ app.templates.androidWarning = """
DevDocs is running inside an Android WebView. Some features may not work properly.
If you downloaded an app called DevDocs on the Play Store, please uninstall it — it's made by someone who is using (and profiting from) the name DevDocs without permission. -
To install DevDocs on your phone, visit devdocs.io in Chrome and select "Add to home screen" in the menu. +
To install DevDocs on your phone, visit devdocs.io in Chrome and select "Add to home screen" in the menu. """ diff --git a/assets/javascripts/templates/pages/settings_tmpl.coffee b/assets/javascripts/templates/pages/settings_tmpl.coffee index 1d439edb..94afe3df 100644 --- a/assets/javascripts/templates/pages/settings_tmpl.coffee +++ b/assets/javascripts/templates/pages/settings_tmpl.coffee @@ -15,6 +15,14 @@ app.templates.settingsPage = (settings) -> """ Automatically hide and show the sidebar Tip: drag the edge of the sidebar to resize it. + + diff --git a/assets/javascripts/tracking.js b/assets/javascripts/tracking.js index ca05b218..a68ca493 100644 --- a/assets/javascripts/tracking.js +++ b/assets/javascripts/tracking.js @@ -1,28 +1,32 @@ try { - if (app.config.env == 'production') { - (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ - (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), - m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) - })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); - ga('create', 'UA-5544833-12', 'devdocs.io'); - page.track(function() { - ga('send', 'pageview', { - page: location.pathname + location.search + location.hash, - dimension1: app.router.context && app.router.context.doc && app.router.context.doc.slug_without_version + if (app.config.env === 'production') { + if (Cookies.get('analyticsConsent') === '1') { + (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ + (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), + m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) + })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); + ga('create', 'UA-5544833-12', 'devdocs.io'); + page.track(function() { + ga('send', 'pageview', { + page: location.pathname + location.search + location.hash, + dimension1: app.router.context && app.router.context.doc && app.router.context.doc.slug_without_version + }); }); - }); - page.track(function() { - if (window._gauges) - _gauges.push(['track']); - else - (function() { - var _gauges=_gauges||[];!function(){var a=document.createElement("script"); - a.type="text/javascript",a.async=!0,a.id="gauges-tracker", - a.setAttribute("data-site-id","51c15f82613f5d7819000067"), - a.src="https://secure.gaug.es/track.js";var b=document.getElementsByTagName("script")[0]; - b.parentNode.insertBefore(a,b)}(); - })(); - }); + page.track(function() { + if (window._gauges) + _gauges.push(['track']); + else + (function() { + var _gauges=_gauges||[];!function(){var a=document.createElement("script"); + a.type="text/javascript",a.async=!0,a.id="gauges-tracker", + a.setAttribute("data-site-id","51c15f82613f5d7819000067"), + a.src="https://secure.gaug.es/track.js";var b=document.getElementsByTagName("script")[0]; + b.parentNode.insertBefore(a,b)}(); + })(); + }); + } else { + resetAnalytics(); + } } } catch(e) { } diff --git a/assets/javascripts/vendor/fastclick.js b/assets/javascripts/vendor/fastclick.js index 3af4f9d6..b6f7b40c 100755 --- a/assets/javascripts/vendor/fastclick.js +++ b/assets/javascripts/vendor/fastclick.js @@ -413,7 +413,7 @@ // when the user next taps anywhere else on the page, new touchstart and touchend events are dispatched // with the same identifier as the touch event that previously triggered the click that triggered the alert. // Sadly, there is an issue on iOS 4 that causes some normal touch events to have the same identifier as an - // immediately preceeding touch event (issue #52), so this fix is unavailable on that platform. + // immediately preceding touch event (issue #52), so this fix is unavailable on that platform. // Issue 120: touch.identifier is 0 when Chrome dev tools 'Emulate touch events' is set with an iOS device UA string, // which causes all touch events to be ignored. As this block only applies to iOS, and iOS identifiers are always long, // random integers, it's safe to to continue if the identifier is 0 here. @@ -805,7 +805,7 @@ } } - // IE11: prefixed -ms-touch-action is no longer supported and it's recomended to use non-prefixed version + // IE11: prefixed -ms-touch-action is no longer supported and it's recommended to use non-prefixed version // http://msdn.microsoft.com/en-us/library/windows/apps/Hh767313.aspx if (layer.style.touchAction === 'none' || layer.style.touchAction === 'manipulation') { return true; diff --git a/assets/javascripts/vendor/prism.js b/assets/javascripts/vendor/prism.js index a23384a3..09d6df87 100644 --- a/assets/javascripts/vendor/prism.js +++ b/assets/javascripts/vendor/prism.js @@ -1,4 +1,5 @@ -/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+c+cpp+coffeescript+ruby+d+elixir+erlang+go+java+json+kotlin+lua+nginx+nim+perl+php+python+jsx+crystal+rust+scss+sql+typescript */ +/* PrismJS 1.15.0 +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 */ var _self = (typeof window !== 'undefined') ? window // if in browser : ( @@ -16,11 +17,12 @@ var _self = (typeof window !== 'undefined') var Prism = (function(){ // Private helper vars -var lang = /\blang(?:uage)?-(\w+)\b/i; +var lang = /\blang(?:uage)?-([\w-]+)\b/i; var uniqueId = 0; var _ = _self.Prism = { manual: _self.Prism && _self.Prism.manual, + disableWorkerMessageHandler: _self.Prism && _self.Prism.disableWorkerMessageHandler, util: { encode: function (tokens) { if (tokens instanceof Token) { @@ -44,23 +46,38 @@ var _ = _self.Prism = { }, // Deep clone a language definition (e.g. to extend it) - clone: function (o) { + clone: function (o, visited) { var type = _.util.type(o); + visited = visited || {}; switch (type) { case 'Object': + if (visited[_.util.objId(o)]) { + return visited[_.util.objId(o)]; + } var clone = {}; + visited[_.util.objId(o)] = clone; for (var key in o) { if (o.hasOwnProperty(key)) { - clone[key] = _.util.clone(o[key]); + clone[key] = _.util.clone(o[key], visited); } } return clone; case 'Array': - return o.map(function(v) { return _.util.clone(v); }); + if (visited[_.util.objId(o)]) { + return visited[_.util.objId(o)]; + } + var clone = []; + visited[_.util.objId(o)] = clone; + + o.forEach(function (v, i) { + clone[i] = _.util.clone(v, visited); + }); + + return clone; } return o; @@ -155,6 +172,10 @@ var _ = _self.Prism = { plugins: {}, highlightAll: function(async, callback) { + _.highlightAllUnder(document, async, callback); + }, + + highlightAllUnder: function(container, async, callback) { var env = { callback: callback, selector: 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code' @@ -162,7 +183,7 @@ var _ = _self.Prism = { _.hooks.run("before-highlightall", env); - var elements = env.elements || document.querySelectorAll(env.selector); + var elements = env.elements || container.querySelectorAll(env.selector); for (var i=0, element; element = elements[i++];) { _.highlightElement(element, async === true, env.callback); @@ -185,11 +206,13 @@ var _ = _self.Prism = { // Set language on the element, if not present element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language; - // Set language on the parent, for styling - parent = element.parentNode; + if (element.parentNode) { + // Set language on the parent, for styling + parent = element.parentNode; - if (/pre/i.test(parent.nodeName)) { - parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language; + if (/pre/i.test(parent.nodeName)) { + parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language; + } } var code = element.textContent; @@ -251,8 +274,15 @@ var _ = _self.Prism = { }, highlight: function (text, grammar, language) { - var tokens = _.tokenize(text, grammar); - return Token.stringify(_.util.encode(tokens), language); + var env = { + code: text, + grammar: grammar, + language: language + }; + _.hooks.run('before-tokenize', env); + env.tokens = _.tokenize(env.code, env.grammar); + _.hooks.run('after-tokenize', env); + return Token.stringify(_.util.encode(env.tokens), env.language); }, matchGrammar: function (text, strarr, grammar, index, startPos, oneshot, target) { @@ -300,15 +330,9 @@ var _ = _self.Prism = { continue; } - pattern.lastIndex = 0; - - var match = pattern.exec(str), - delNum = 1; - - // Greedy patterns can override/remove up to two previously matched tokens - if (!match && greedy && i != strarr.length - 1) { + if (greedy && i != strarr.length - 1) { pattern.lastIndex = pos; - match = pattern.exec(text); + var match = pattern.exec(text); if (!match) { break; } @@ -327,11 +351,8 @@ var _ = _self.Prism = { } } - /* - * If strarr[i] is a Token, then the match starts inside another Token, which is invalid - * If strarr[k - 1] is greedy we are in conflict with another greedy pattern - */ - if (strarr[i] instanceof Token || strarr[k - 1].greedy) { + // If strarr[i] is a Token, then the match starts inside another Token, which is invalid + if (strarr[i] instanceof Token) { continue; } @@ -339,6 +360,11 @@ var _ = _self.Prism = { delNum = k - i; str = text.slice(pos, p); match.index -= pos; + } else { + pattern.lastIndex = 0; + + var match = pattern.exec(str), + delNum = 1; } if (!match) { @@ -350,7 +376,7 @@ var _ = _self.Prism = { } if(lookbehind) { - lookbehindLength = match[1].length; + lookbehindLength = match[1] ? match[1].length : 0; } var from = match.index + lookbehindLength, @@ -460,10 +486,6 @@ Token.stringify = function(o, language, parent) { parent: parent }; - if (env.type == 'comment') { - env.attributes['spellcheck'] = 'true'; - } - if (o.alias) { var aliases = _.util.type(o.alias) === 'Array' ? o.alias : [o.alias]; Array.prototype.push.apply(env.classes, aliases); @@ -484,18 +506,21 @@ Token.stringify = function(o, language, parent) { // // in Node.js // return _self.Prism; // } -// // In worker -// _self.addEventListener('message', function(evt) { -// var message = JSON.parse(evt.data), -// lang = message.language, -// code = message.code, -// immediateClose = message.immediateClose; - -// _self.postMessage(_.highlight(code, _.languages[lang], lang)); -// if (immediateClose) { -// _self.close(); -// } -// }, false); + +// if (!_.disableWorkerMessageHandler) { +// // In worker +// _self.addEventListener('message', function (evt) { +// var message = JSON.parse(evt.data), +// lang = message.language, +// code = message.code, +// immediateClose = message.immediateClose; + +// _self.postMessage(_.highlight(code, _.languages[lang], lang)); +// if (immediateClose) { +// _self.close(); +// } +// }, false); +// } // return _self.Prism; // } @@ -539,7 +564,8 @@ Prism.languages.markup = { 'doctype': //i, 'cdata': //i, 'tag': { - pattern: /<\/?(?!\d)[^\s>\/=$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\s\S])*\1|[^\s'">=]+))?)*\s*\/?>/i, + pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+))?)*\s*\/?>/i, + greedy: true, inside: { 'tag': { pattern: /^<\/?[^\s>\/]+/i, @@ -549,9 +575,15 @@ Prism.languages.markup = { } }, 'attr-value': { - pattern: /=(?:('|")[\s\S]*?(\1)|[^\s>]+)/i, + pattern: /=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+)/i, inside: { - 'punctuation': /[=>"']/ + 'punctuation': [ + /^=/, + { + pattern: /(^|[^\\])["']/, + lookbehind: true + } + ] } }, 'punctuation': /\/?>/, @@ -586,25 +618,25 @@ Prism.languages.svg = Prism.languages.markup; Prism.languages.css = { 'comment': /\/\*[\s\S]*?\*\//, 'atrule': { - pattern: /@[\w-]+?.*?(;|(?=\s*\{))/i, + pattern: /@[\w-]+?.*?(?:;|(?=\s*\{))/i, inside: { 'rule': /@[\w-]+/ // See rest below } }, - 'url': /url\((?:(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|.*?)\)/i, - 'selector': /[^\{\}\s][^\{\};]*?(?=\s*\{)/, + 'url': /url\((?:(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|.*?)\)/i, + 'selector': /[^{}\s][^{};]*?(?=\s*\{)/, 'string': { - pattern: /("|')(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, + pattern: /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, greedy: true }, - 'property': /(\b|\B)[\w-]+(?=\s*:)/i, + 'property': /[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i, 'important': /\B!important\b/i, 'function': /[-a-z0-9]+(?=\()/i, 'punctuation': /[(){};:]/ }; -Prism.languages.css['atrule'].inside.rest = Prism.util.clone(Prism.languages.css); +Prism.languages.css['atrule'].inside.rest = Prism.languages.css; if (Prism.languages.markup) { Prism.languages.insertBefore('markup', 'tag', { @@ -612,13 +644,14 @@ if (Prism.languages.markup) { pattern: /( diff --git a/views/index.erb b/views/index.erb index ce743671..4fb96153 100644 --- a/views/index.erb +++ b/views/index.erb @@ -1,5 +1,5 @@ - prefix="og: http://ogp.me/ns#" lang="en" class="_booting"> +
@@ -14,6 +14,7 @@ +DevDocs is an API documentation browser which supports the following browsers:
- If you're unable to upgrade, I apologize. - I decided to prioritize speed and new features over support for older browsers. + If you're unable to upgrade, we apologize. + We decided to prioritize speed and new features over support for older browsers.