diff --git a/.flowconfig b/.flowconfig index cecae58751e..48b53a95fc1 100644 --- a/.flowconfig +++ b/.flowconfig @@ -3,6 +3,9 @@ .*/node_modules/stylelint/.* .*/node_modules/unflowify/.* .*/node_modules/flow-coverage-report/.* +.*/node_modules/babel-plugin-transform-react-remove-prop-types/.* +.*/node_modules/conventional-changelog-core/.* +.*/node_modules/htmltojsx/.* .*/test/unit/style-spec/fixture/invalidjson.input.json [options] diff --git a/.gitignore b/.gitignore index 29dcf10064d..e9f3c8383ae 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,4 @@ -/docs/api -/docs/style-spec/index.html -/_site +/docs/components/api.json /dist/mapbox-gl-dev.js /dist/mapbox-gl.js *.js.map @@ -17,3 +15,5 @@ test/integration/**/index*.html test/integration/**/actual.png test/integration/**/diff.png .eslintcache +_batfish_site +_batfish_tmp diff --git a/_config.mb-pages.yml b/_config.mb-pages.yml deleted file mode 100755 index 5e3a70043cd..00000000000 --- a/_config.mb-pages.yml +++ /dev/null @@ -1,10 +0,0 @@ -env: production -url: https://www.mapbox.com -api: https://www.mapbox.com/core -tileApi: https://api.mapbox.com -source: docs -permalink: /:categories/:title/ -baseurl: https://www.mapbox.com/mapbox-gl-js -excerpt_separator: "" -exclude: [dist] -future: true diff --git a/_config.yml b/_config.yml index d8c0fb1c30f..9765a6579fa 100755 --- a/_config.yml +++ b/_config.yml @@ -1,9 +1,3 @@ -url: https://122e4e-mapbox.global.ssl.fastly.net -api: https://122e4e-mapbox.global.ssl.fastly.net/core -tileApi: https://api-maps-staging.tilestream.net -source: docs -permalink: /:categories/:title/ -baseurl: /mapbox-gl-js -excerpt_separator: "" -mapboxglbase: /mapbox-gl-js/dist -future: true +# When Publisher runs Jekyll (which it always does), it will simply copy this +# source directory to _site. Then Publisher will copy _site to S3. +source: _batfish_site diff --git a/batfish.config.js b/batfish.config.js new file mode 100644 index 00000000000..2c12a095581 --- /dev/null +++ b/batfish.config.js @@ -0,0 +1,51 @@ +const webpack = require('webpack'); + +module.exports = () => { + const config = { + siteBasePath: '/mapbox-gl-js', + siteOrigin: 'https://www.mapbox.com', + pagesDirectory: `${__dirname}/docs/pages`, + stylesheets: [ + `${__dirname}/docs/components/site.css`, + `${__dirname}/docs/components/prism_highlight.css`, + `${__dirname}/vendor/dotcom-page-shell/page-shell-styles.css` + ], + applicationWrapperPath: `${__dirname}/docs/components/application-wrapper.js`, + webpackLoaders: [ + // Use raw loader to get the HTML string contents of examples + { + test: /\.html$/, + use: 'raw-loader' + } + ], + ignoreWithinPagesDirectory: ['example/*.html'], + webpackPlugins: [ + // Make environment variables available within JS that Webpack compiles. + new webpack.DefinePlugin({ + // DEPLOY_ENV is used in config to pick between local/production. + 'process.env.DEPLOY_ENV': `"${process.env.DEPLOY_ENV}"` + }) + ], + inlineJs: [ + { + filename: `${__dirname}/vendor/dotcom-page-shell/page-shell-script.js` + } + ], + dataSelectors: { + examples: ({pages}) => { + return pages + .filter(({path, frontMatter}) => /\/example\//.test(path) && frontMatter.tags) + .map(({frontMatter}) => frontMatter); + } + } + }; + + // Local builds treat the `dist` directory as static assets, allowing you to test examples against the + // local branch build. Non-local builds ignore the `dist` directory, and examples load assets from the CDN. + config.unprocessedPageFiles = ['dist/**/*.*']; + if (process.env.DEPLOY_ENV !== 'local') { + config.ignoreWithinPagesDirectory.push('dist/**/*.*'); + } + + return config; +}; diff --git a/convert-examples.js b/convert-examples.js new file mode 100644 index 00000000000..9fb89f59bdc --- /dev/null +++ b/convert-examples.js @@ -0,0 +1,41 @@ +const fs = require('fs'); +const matter = require('gray-matter'); + +fs.readdirSync(`examples`).forEach((file) => { + if (file[0] === '.') { + return; + } + + const name = /\d\d\d\d-\d\d-\d\d-(.*)\.html$/.exec(file)[1]; + const example = matter(fs.readFileSync(`examples/${file}`, 'utf8')); + + fs.writeFileSync(`docs/pages/example/${name}.html`, example.content); + + delete example.data.layout; + delete example.data.category; + delete example.data.permalink; + + example.data.pathname = `/mapbox-gl-js/example/${name}/`; + + fs.writeFileSync(`docs/pages/example/${name}.js`, +`/*${matter.stringify('', example.data).slice(0, -2)}*/ +import Example from '../../components/example'; +import html from './${name}.html'; +export default Example(html); +`) +}); + +fs.readdirSync(`redirects`).forEach((file) => { + if (file[0] === '.') { + return; + } + + const name = /\d\d\d\d-\d\d-\d\d-(.*)\.html$/.exec(file)[1]; + const example = matter(fs.readFileSync(`redirects/${file}`, 'utf8')); + + fs.writeFileSync(`docs/pages/example/${name}.js`, + `import Redirect from '../../components/redirect'; +import {prefixUrl} from '@mapbox/batfish/modules/prefix-url'; +export default Redirect(prefixUrl('${example.data.redirect}')); +`) +}); diff --git a/docs/README.md b/docs/README.md index 0d9aa18cf62..4f5080905ea 100644 --- a/docs/README.md +++ b/docs/README.md @@ -18,14 +18,15 @@ API documentation is written as [JSDoc comments](http://usejsdoc.org/) and proce ## Writing Examples -Examples are written as Jekyll posts in `docs/_posts/examples`. The Jekyll front matter should include the following items: +Examples are written as [Batfish](https://github.com/mapbox/batfish) pages in `docs/pages/example`. Each example requires two files: an `.html` file containing the source +code for the example, and a `.js` file containing example boilerplate and front matter. The front matter should include the following items: -* `layout`: `example` -* `category`: `example` * `title`: A short title for the example in **sentence case** as a **verb phrase** * `description`: A one sentence description of the example +* `tags`: An array of tags for the example, which determine the sections it is listed in in the sidebar navigation +* `pathname`: The relative path of the example, including leading `/mapbox-gl-js/example/` path -In the post body, write the HTML and JavaScript constituting the example. +In the `.html` file, write the HTML and JavaScript constituting the example. * Use **4 space indentation**. Exception: do not add an initial level of indentation to code within ` - -{% endhighlight html %}{% endcopyable %} - -

Include the following code in the <body> of your HTML file.

-
-{% copyable %}{% highlight html %} -
- -{% endhighlight html %}{% endcopyable %} -
diff --git a/docs/_includes/quickstart-csp.html b/docs/_includes/quickstart-csp.html deleted file mode 100644 index 1b504130e6d..00000000000 --- a/docs/_includes/quickstart-csp.html +++ /dev/null @@ -1,17 +0,0 @@ -

CSP Directives

- -

As a mitigation for Cross-Site Scripting and other types of web security vulnerabilities, you may use a - Content Security Policy (CSP) - to specify security policies for your website. If you do, Mapbox GL JS requires the following CSP - directives:

-
-child-src blob: ;
-img-src data: blob: ;
-script-src 'unsafe-eval' ;
-
- -

Requesting styles from Mapbox or other services will require additional - directives. For Mapbox, you can use this connect-src directive:

-
-connect-src https://*.tiles.mapbox.com https://api.mapbox.com
-
diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html deleted file mode 100644 index f40fde28449..00000000000 --- a/docs/_layouts/default.html +++ /dev/null @@ -1,139 +0,0 @@ - - - - -{% if page.prehead %}{{page.prehead}}{% endif %} -{% if page.description %}{% endif %} -{% if page.title == 'Mapbox' %}{{page.title}} | Design and publish beautiful maps{% else %}{{page.title}} | Mapbox{% endif %} - - - - -{% if page.date and site.baseurl == '/blog' %} -{% endif %}{% if page.tags %} -{% for tags in page.tags %} -{% endfor %}{% endif %}{% if page.category and page.category !='none' %} -{% endif %}{% if page.author %} -{% endif %}{% if page.excerpt or page.description %} -{% endif %} -{% if site.baseurl == '/mapbox.js' %}{% if site.mapboxjs != page.version and page.version != 'latest' %}{% endif %}{% endif %} -{% if page.card or layout.card %} - - - - - - - - -{% if page.video or layout.video %} - - - - - - - - -{% elsif page.image or layout.image %} - - - - - -{% endif %} -{% endif %} - -{% if site.assembly %} - - -{% else %} -{% if site.localbase == true %} - -{% else %} - -{% endif %} - -{% endif %} - - - -{% unless page.nomapboxjs %} - -{% endunless %} - - - -{% unless page.nomapboxjs %} - -{% endunless %} - - - -{% if site.test %}{% endif %} -{% if page.lightBackground or layout.lightBackground %} - -{% endif %} -{% if page.head %}{{page.head}}{% endif %}{% if layout.head %}{{layout.head}}{% endif %} - -
{{content}}
\ No newline at end of file diff --git a/docs/_layouts/example.html b/docs/_layouts/example.html deleted file mode 100644 index 518d2cb2db2..00000000000 --- a/docs/_layouts/example.html +++ /dev/null @@ -1,82 +0,0 @@ ---- -layout: pages ---- - -
- - - -
-
{{ page.title }}
{{ page.description }}
- -
- - - - - - -
- -
{% highlight html %} - - - - - {{ page.exampletitle }} - - - - - - - -{{content | insert_token}} - -{% endhighlight %} -
- - Copy example -
- -
diff --git a/docs/_layouts/pages.html b/docs/_layouts/pages.html deleted file mode 100644 index c25b5705405..00000000000 --- a/docs/_layouts/pages.html +++ /dev/null @@ -1,91 +0,0 @@ ---- -layout: wrapper -hasdocnav: true -class: fill-light -options: full -section: Mapbox GL JS -examples: - - name: Styles - id: styles - - name: Layers - id: layers - - name: Sources - id: sources - - name: User interaction - id: user-interaction - - name: Camera - id: camera - - name: Controls and overlays - id: controls-and-overlays - - name: Browser support - id: browser-support - - name: Internationalization support - id: internationalization ---- - - - - - -
-
-
- -
-
-
- -
- {% include navigation.html %} - -
- {{ content }} -
-
- - diff --git a/docs/_layouts/redirect.html b/docs/_layouts/redirect.html deleted file mode 100644 index 979122776e0..00000000000 --- a/docs/_layouts/redirect.html +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/docs/_layouts/wrapper.html b/docs/_layouts/wrapper.html deleted file mode 100644 index 27bd3249f9d..00000000000 --- a/docs/_layouts/wrapper.html +++ /dev/null @@ -1,8 +0,0 @@ ---- -layout: default -hasdocnav: true ---- - -
- {{content}} -
diff --git a/docs/_plugins/copyable.rb b/docs/_plugins/copyable.rb deleted file mode 100644 index ec7f7c51229..00000000000 --- a/docs/_plugins/copyable.rb +++ /dev/null @@ -1,19 +0,0 @@ -class CopyableBlock < Liquid::Block - - @@nextId = 0 - - def initialize(tag_name, text, tokens) - super - @id = @@nextId - @@nextId = @@nextId + 1 - end - - def render(context) - "
\ - \ -
#{super}
\ -
" - end -end - -Liquid::Template.register_tag('copyable', CopyableBlock) diff --git a/docs/_plugins/insert_token.rb b/docs/_plugins/insert_token.rb deleted file mode 100644 index b9a191e9467..00000000000 --- a/docs/_plugins/insert_token.rb +++ /dev/null @@ -1,7 +0,0 @@ -module InsertToken - def insert_token(input) - input.sub(" diff --git a/docs/_posts/examples/3400-02-01-local-ideographs.html b/docs/_posts/examples/3400-02-01-local-ideographs.html deleted file mode 100644 index 65e60a1883d..00000000000 --- a/docs/_posts/examples/3400-02-01-local-ideographs.html +++ /dev/null @@ -1,21 +0,0 @@ ---- -layout: example -category: example -title: Use locally generated ideographs -description: Rendering Chinese/Japanese/Korean (CJK) ideographs and precomposed Hangul Syllables requires downloading large amounts of font data, which can significantly slow map load times. Use the 'localIdeographFontFamily' setting to speed up map load times by using locally available fonts instead of font data fetched from the server. This setting defines a CSS 'font-family' for locally overriding generation of glyphs in the 'CJK Unified Ideographs' and 'Hangul Syllables' Unicode ranges. In these ranges, font settings from the map's style will be ignored in favor of the locally available font. Keywords in the fontstack defined in the map's style (light/regular/medium/bold) will be translated into a CSS 'font-weight'. When using this setting, keep in mind that the fonts you select may not be available on all users' devices. It is best to specify at least one broadly available fallback font class such as 'sans-serif'. -tags: - - internationalization ---- -
- - diff --git a/docs/_posts/redirects/3400-01-05-featuresat.html b/docs/_posts/redirects/3400-01-05-featuresat.html deleted file mode 100644 index f5c67d3c1fd..00000000000 --- a/docs/_posts/redirects/3400-01-05-featuresat.html +++ /dev/null @@ -1,5 +0,0 @@ ---- -layout: redirect -permalink: /example/featuresat/ -redirect: /example/queryrenderedfeatures/ ---- diff --git a/docs/_posts/redirects/3400-01-05-heatmap.html b/docs/_posts/redirects/3400-01-05-heatmap.html deleted file mode 100644 index bb80fb82676..00000000000 --- a/docs/_posts/redirects/3400-01-05-heatmap.html +++ /dev/null @@ -1,5 +0,0 @@ ---- -layout: redirect -permalink: /example/heatmap/ -redirect: /example/heatmap-layer/ ---- diff --git a/docs/_posts/redirects/3400-01-05-mapbox-gl-supported.html b/docs/_posts/redirects/3400-01-05-mapbox-gl-supported.html deleted file mode 100644 index 84df4978f89..00000000000 --- a/docs/_posts/redirects/3400-01-05-mapbox-gl-supported.html +++ /dev/null @@ -1,5 +0,0 @@ ---- -layout: redirect -permalink: /example/mapbox-gl-supported/ -redirect: /example/check-for-support/ ---- diff --git a/docs/_posts/redirects/3400-01-05-marker-popup.html b/docs/_posts/redirects/3400-01-05-marker-popup.html deleted file mode 100644 index 35ee8bf3336..00000000000 --- a/docs/_posts/redirects/3400-01-05-marker-popup.html +++ /dev/null @@ -1,5 +0,0 @@ ---- -layout: redirect -permalink: /example/marker-popup/ -redirect: /example/popup-on-click/ ---- diff --git a/docs/_posts/redirects/3400-01-19-using-featuresin.html b/docs/_posts/redirects/3400-01-19-using-featuresin.html deleted file mode 100644 index bb7daa13e08..00000000000 --- a/docs/_posts/redirects/3400-01-19-using-featuresin.html +++ /dev/null @@ -1,5 +0,0 @@ ---- -layout: redirect -permalink: /example/using-featuresin/ -redirect: /example/using-box-queryrenderedfeatures/ ---- diff --git a/docs/_theme/README.md b/docs/_theme/README.md deleted file mode 100644 index 883227f8442..00000000000 --- a/docs/_theme/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# documentation-theme-default - -[![Circle CI](https://circleci.com/gh/documentationjs/documentation-theme-default.svg?style=svg)](https://circleci.com/gh/documentationjs/documentation-theme-default) - -![](screenshot.png) - -This is the default theme for [documentationjs](https://github.com/documentationjs): -it consists of Handlebars templates and a few assets: a [highlight.js](https://highlightjs.org/) -theme and [basscss](http://www.basscss.com/) as a basic CSS framework. - -This is bundled by default in documentation: it is the default theme. - -The contents are the following: - -* `index.hbs`, the main template that defines the document structure -* `section.hbs`, a partial used to render each chunk of documentation -* `assets/*`, any assets, including CSS & JS - -# Helpers - -* `{{format_params}}`: format function parameters, including the types - included within. -* `{{permalink}}`: in the context of a documentation chunk, - return the chunk's permalink -* `{{autolink TEXT}}`: given a chunk of text that may be a reference to a - method, property, or other namespaced item, link the text to the item -* `{{md TEXT}}`: render Markdown-formatted text, parsing additional - JSDoc inline tag syntax and linking links when necessary -* `{{format_type}}`: format a type definition, like `{string}` within a - param definition. diff --git a/docs/_theme/assets/anchor.js b/docs/_theme/assets/anchor.js deleted file mode 100644 index 47d871ad400..00000000000 --- a/docs/_theme/assets/anchor.js +++ /dev/null @@ -1,197 +0,0 @@ -/*! - * AnchorJS - v1.2.1 - 2015-07-02 - * https://github.com/bryanbraun/anchorjs - * Copyright (c) 2015 Bryan Braun; Licensed MIT - */ - -function AnchorJS(options) { - 'use strict'; - - this.options = options || {}; - - this._applyRemainingDefaultOptions = function(opts) { - this.options.icon = this.options.hasOwnProperty('icon') ? opts.icon : '\ue9cb'; // Accepts characters (and also URLs?), like '#', '¶', '❡', or '§'. - this.options.visible = this.options.hasOwnProperty('visible') ? opts.visible : 'hover'; // Also accepts 'always' - this.options.placement = this.options.hasOwnProperty('placement') ? opts.placement : 'right'; // Also accepts 'left' - this.options.class = this.options.hasOwnProperty('class') ? opts.class : ''; // Accepts any class name. - }; - - this._applyRemainingDefaultOptions(options); - - this.add = function(selector) { - var elements, - elsWithIds, - idList, - elementID, - i, - roughText, - tidyText, - index, - count, - newTidyText, - readableID, - anchor; - - this._applyRemainingDefaultOptions(this.options); - - // Provide a sensible default selector, if none is given. - if (!selector) { - selector = 'h1, h2, h3, h4, h5, h6'; - } else if (typeof selector !== 'string') { - throw new Error('The selector provided to AnchorJS was invalid.'); - } - - elements = document.querySelectorAll(selector); - if (elements.length === 0) { - return false; - } - - this._addBaselineStyles(); - - // We produce a list of existing IDs so we don't generate a duplicate. - elsWithIds = document.querySelectorAll('[id]'); - idList = [].map.call(elsWithIds, function assign(el) { - return el.id; - }); - - for (i = 0; i < elements.length; i++) { - - if (elements[i].hasAttribute('id')) { - elementID = elements[i].getAttribute('id'); - } else { - roughText = elements[i].textContent; - - // Refine it so it makes a good ID. Strip out non-safe characters, replace - // spaces with hyphens, truncate to 32 characters, and make toLowerCase. - // - // Example string: // '⚡⚡⚡ Unicode icons are cool--but they definitely don't belong in a URL fragment.' - tidyText = roughText.replace(/[^\w\s-]/gi, '') // ' Unicode icons are cool--but they definitely dont belong in a URL fragment' - .replace(/\s+/g, '-') // '-Unicode-icons-are-cool--but-they-definitely-dont-belong-in-a-URL-fragment' - .replace(/-{2,}/g, '-') // '-Unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-URL-fragment' - .substring(0, 64) // '-Unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-URL' - .replace(/^-+|-+$/gm, '') // 'Unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-URL' - .toLowerCase(); // 'unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-url' - - // Compare our generated ID to existing IDs (and increment it if needed) - // before we add it to the page. - newTidyText = tidyText; - count = 0; - do { - if (index !== undefined) { - newTidyText = tidyText + '-' + count; - } - // .indexOf is supported in IE9+. - index = idList.indexOf(newTidyText); - count += 1; - } while (index !== -1); - index = undefined; - idList.push(newTidyText); - - // Assign it to our element. - // Currently the setAttribute element is only supported in IE9 and above. - elements[i].setAttribute('id', newTidyText); - - elementID = newTidyText; - } - - readableID = elementID.replace(/-/g, ' '); - - // The following code builds the following DOM structure in a more effiecient (albeit opaque) way. - // ''; - anchor = document.createElement('a'); - anchor.className = 'anchorjs-link ' + this.options.class; - anchor.href = '#' + elementID; - anchor.setAttribute('aria-label', 'Anchor link for: ' + readableID); - anchor.setAttribute('data-anchorjs-icon', this.options.icon); - - if (this.options.visible === 'always') { - anchor.style.opacity = '1'; - } - - if (this.options.icon === '\ue9cb') { - anchor.style.fontFamily = 'anchorjs-icons'; - anchor.style.fontStyle = 'normal'; - anchor.style.fontVariant = 'normal'; - anchor.style.fontWeight = 'normal'; - anchor.style.lineHeight = 1; - } - - if (this.options.placement === 'left') { - anchor.style.position = 'absolute'; - anchor.style.marginLeft = '-1em'; - anchor.style.paddingRight = '0.5em'; - elements[i].insertBefore(anchor, elements[i].firstChild); - } else { // if the option provided is `right` (or anything else). - anchor.style.paddingLeft = '0.375em'; - elements[i].appendChild(anchor); - } - } - - return this; - }; - - this.remove = function(selector) { - var domAnchor, - elements = document.querySelectorAll(selector); - for (var i = 0; i < elements.length; i++) { - domAnchor = elements[i].querySelector('.anchorjs-link'); - if (domAnchor) { - elements[i].removeChild(domAnchor); - } - } - return this; - }; - - this._addBaselineStyles = function() { - // We don't want to add global baseline styles if they've been added before. - if (document.head.querySelector('style.anchorjs') !== null) { - return; - } - - var style = document.createElement('style'), - linkRule = - ' .anchorjs-link {' + - ' opacity: 0;' + - ' text-decoration: none;' + - ' -webkit-font-smoothing: antialiased;' + - ' -moz-osx-font-smoothing: grayscale;' + - ' }', - hoverRule = - ' *:hover > .anchorjs-link,' + - ' .anchorjs-link:focus {' + - ' opacity: 1;' + - ' }', - anchorjsLinkFontFace = - ' @font-face {' + - ' font-family: "anchorjs-icons";' + - ' font-style: normal;' + - ' font-weight: normal;' + // Icon from icomoon; 10px wide & 10px tall; 2 empty below & 4 above - ' src: url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBTUAAAC8AAAAYGNtYXAWi9QdAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5Zgq29TcAAAF4AAABNGhlYWQEZM3pAAACrAAAADZoaGVhBhUDxgAAAuQAAAAkaG10eASAADEAAAMIAAAAFGxvY2EAKACuAAADHAAAAAxtYXhwAAgAVwAAAygAAAAgbmFtZQ5yJ3cAAANIAAAB2nBvc3QAAwAAAAAFJAAAACAAAwJAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADpywPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6cv//f//AAAAAAAg6cv//f//AAH/4xY5AAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAACADEARAJTAsAAKwBUAAABIiYnJjQ/AT4BMzIWFxYUDwEGIicmND8BNjQnLgEjIgYPAQYUFxYUBw4BIwciJicmND8BNjIXFhQPAQYUFx4BMzI2PwE2NCcmNDc2MhcWFA8BDgEjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAEAAAABAACiToc1Xw889QALBAAAAAAA0XnFFgAAAADRecUWAAAAAAJTAsAAAAAIAAIAAAAAAAAAAQAAA8D/wAAABAAAAAAAAlMAAQAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAACAAAAAoAAMQAAAAAACgAUAB4AmgABAAAABQBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAADgCuAAEAAAAAAAEADgAAAAEAAAAAAAIABwCfAAEAAAAAAAMADgBLAAEAAAAAAAQADgC0AAEAAAAAAAUACwAqAAEAAAAAAAYADgB1AAEAAAAAAAoAGgDeAAMAAQQJAAEAHAAOAAMAAQQJAAIADgCmAAMAAQQJAAMAHABZAAMAAQQJAAQAHADCAAMAAQQJAAUAFgA1AAMAAQQJAAYAHACDAAMAAQQJAAoANAD4YW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzVmVyc2lvbiAxLjAAVgBlAHIAcwBpAG8AbgAgADEALgAwYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzUmVndWxhcgBSAGUAZwB1AGwAYQByYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzRm9udCBnZW5lcmF0ZWQgYnkgSWNvTW9vbi4ARgBvAG4AdAAgAGcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAASQBjAG8ATQBvAG8AbgAuAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==) format("truetype");' + - ' }', - pseudoElContent = - ' [data-anchorjs-icon]::after {' + - ' content: attr(data-anchorjs-icon);' + - ' }', - firstStyleEl; - - style.className = 'anchorjs'; - style.appendChild(document.createTextNode('')); // Necessary for Webkit. - - // We place it in the head with the other style tags, if possible, so as to - // not look out of place. We insert before the others so these styles can be - // overridden if necessary. - firstStyleEl = document.head.querySelector('[rel="stylesheet"], style'); - if (firstStyleEl === undefined) { - document.head.appendChild(style); - } else { - document.head.insertBefore(style, firstStyleEl); - } - - style.sheet.insertRule(linkRule, style.sheet.cssRules.length); - style.sheet.insertRule(hoverRule, style.sheet.cssRules.length); - style.sheet.insertRule(pseudoElContent, style.sheet.cssRules.length); - style.sheet.insertRule(anchorjsLinkFontFace, style.sheet.cssRules.length); - }; -} - -var anchors = new AnchorJS(); diff --git a/docs/_theme/assets/site.js b/docs/_theme/assets/site.js deleted file mode 100644 index 646cd243e73..00000000000 --- a/docs/_theme/assets/site.js +++ /dev/null @@ -1,74 +0,0 @@ -/* global anchors */ - -// add anchor links to headers -anchors.options.placement = 'left'; -anchors.add('h3'); - -function toggleSibling() { - var stepSibling = this.parentNode.getElementsByClassName('toggle-target')[0]; - toggleHidden(stepSibling.classList); - - var icon = this.parentNode.getElementsByClassName('rcon')[0]; - toggleCaret(icon.classList); -} - -var items = document.getElementsByClassName('toggle-sibling'); -for (var j = 0; j < items.length; j++) { - items[j].addEventListener('click', toggleSibling); -} - -function toggleCaret(classList) { - if (classList.contains('caret-right')) { - classList.remove('caret-right'); - classList.add('caret-down', 'strong'); - } else { - classList.add('caret-right'); - classList.remove('caret-down', 'strong'); - } -} - -function toggleHidden(classList) { - if (classList.contains('hidden')) { - classList.remove('hidden'); - } else { - classList.add('hidden'); - } -} - -function showHashTarget(hash) { - var targetId = hash && hash.substring(1); - if (!targetId) return; - var hashTarget = document.getElementById(targetId); - if (!hashTarget) return; - var toggleInside = hashTarget.querySelector('.hidden.toggle-target'); - var toggleSibling = hashTarget.querySelector('.toggle-sibling'); - if (toggleInside && toggleSibling) { - toggleSibling.click(); - } -} - -window.addEventListener('hashchange', function() { - showHashTarget(location.hash); -}); - -showHashTarget(location.hash); - -var quickstartCDN = document.getElementById('quickstart-cdn'); -var quickstartBundler = document.getElementById('quickstart-bundler'); -var toggles = document.getElementsByClassName('method-toggle'); -for (var i = 0; i < toggles.length; i++) { - toggles[i].onclick = exampleToggle; -} -function exampleToggle(e) { - for (var i = 0; i < toggles.length; i++) { - toggles[i].className = this === toggles[i] ? 'method-toggle active' : 'method-toggle'; - } - if (this.getAttribute('data-target') === 'quickstart-cdn') { - quickstartCDN.className = ''; - quickstartBundler.className = 'hidden'; - } else { - quickstartCDN.className = 'hidden'; - quickstartBundler.className = ''; - } - e.preventDefault(); -} diff --git a/docs/_theme/assets/style.css b/docs/_theme/assets/style.css deleted file mode 100644 index e4154628708..00000000000 --- a/docs/_theme/assets/style.css +++ /dev/null @@ -1,122 +0,0 @@ -.documentation { - font-family: Helvetica, sans-serif; - color: #666; - line-height: 1.5; -} - -.black { - color: #666; -} - -h4 { - margin: 20px 0 10px 0; -} - -.documentation h3 { - color: #000; -} - -.keyline-top { - border-top: 1px solid #ccc; -} - -.keyline-top-not { - border-top: 1px solid #ccc; -} - -.keyline-top-not:first-child { - border-top: none; -} - -.keyline-right { - border-right: 1px solid #ccc; -} - -a { - color: #1184CE; - text-decoration: none; -} - -.documentation a[href]:hover { - text-decoration: underline; -} - -a:hover { - cursor: pointer; -} - -.py1-ul li { - padding: 5px 0; -} - -.max-height-100 { - max-height: 100%; -} - -section:target h3 { - font-weight:700; -} - -.documentation td, -.documentation th { - padding: .25rem .25rem; -} - -h1:hover .anchorjs-link, -h2:hover .anchorjs-link, -h3:hover .anchorjs-link, -h4:hover .anchorjs-link { - opacity: 1; -} - -.fix-3 { - width: 25%; - max-width: 244px; -} - -.fix-3 { - width: 25%; - max-width: 244px; -} - -@media (min-width: 52em) { - .fix-margin-3 { - margin-left: 25%; - } -} - -.pre, pre, code { - font-family: Source Code Pro,Menlo,Consolas,Liberation Mono,monospace; - font-size: 14px; -} - -.fill-light { - background: #F9F9F9; -} - -.width2 { - width: 1rem; -} - -ol { - padding-left: 2rem; -} - -ul { - padding-left: 1rem; -} - -.input { - font-family: inherit; - display: block; - width: 100%; - height: 2rem; - padding: .5rem; - margin-bottom: 1rem; - border: 1px solid #ccc; - font-size: .875rem; - border-radius: 3px; - box-sizing: border-box; -} - - diff --git a/docs/_theme/index.hbs b/docs/_theme/index.hbs deleted file mode 100644 index 4b04f48cd18..00000000000 --- a/docs/_theme/index.hbs +++ /dev/null @@ -1,151 +0,0 @@ ---- -layout: wrapper -title: Mapbox GL JS API -class: fill-light -options: full -category: api ---- - -
-
-
- -
-
-
- -
- {% include navigation.html %} -
-
-
-

Mapbox GL JS

- -
-

Mapbox GL JS is a JavaScript library that uses WebGL to render interactive maps - from vector tiles and Mapbox styles. - It is part of the Mapbox GL ecosystem, which includes Mapbox Mobile, a compatible renderer written in C++ with bindings - for desktop and mobile platforms. To see what new features our team is working on, take a look at our roadmap.

-
-
-
-
- Project on Github - View source code and contribute -
-
-
-
-
- GL JS - Fundamentals - Essential functions and common patterns -
-
-
-
-
- Gallery - Project showcase -
-
- -
-

Quickstart

-
To get started, you need to obtain an access token and a style URL. You can choose from one of our professionally designed styles or create - your own using Mapbox Studio. -
- -
{% include quickstart-cdn.html %}
- - {% include quickstart-csp.html %} -
-
-
- -
- <% docs.forEach(function(s) { %> - <% if (s.kind !== 'note') { %> - <%=renderSection({ - section: s, - renderSection: renderSection, - renderSectionList: renderSectionList - })%> - <% } else { %> -
<%=renderNote({ note: s })%>
- <% } %> - <% }) %> -
-
-
- - - - - - diff --git a/docs/_theme/index.js b/docs/_theme/index.js deleted file mode 100644 index 5fde623e95b..00000000000 --- a/docs/_theme/index.js +++ /dev/null @@ -1,110 +0,0 @@ -'use strict'; - -var fs = require('fs'), - path = require('path'), - File = require('vinyl'), - vfs = require('vinyl-fs'), - template = require('lodash').template, - concat = require('concat-stream'), - GithubSlugger = require('github-slugger'), - createFormatters = require('documentation').util.createFormatters, - createLinkerStack = require('documentation').util.createLinkerStack, - hljs = require('highlight.js'); - -module.exports = function (comments, options, callback) { - - var linkerStack = createLinkerStack(options) - .namespaceResolver(comments, function (namespace) { - var slugger = new GithubSlugger(); - return '#' + slugger.slug(namespace); - }); - - var formatters = createFormatters(linkerStack.link); - - hljs.configure(options.hljs || {}); - - var imports = { - shortSignature: function (section, hasSectionName) { - var prefix = ''; - if (section.kind === 'class') { - prefix = 'new '; - } - if (section.kind !== 'function' && !hasSectionName) { - return ''; - } - if (hasSectionName) { - return prefix + section.name + formatters.parameters(section, true); - } else if (!hasSectionName && formatters.parameters(section)) { - return formatters.parameters(section, true); - } else { - return '()'; - } - }, - signature: function (section, hasSectionName) { - var returns = ''; - var prefix = ''; - if (section.kind === 'class') { - prefix = 'new '; - } else if (section.kind !== 'function') { - return section.name; - } - if (section.returns) { - returns = ': ' + - formatters.type(section.returns[0].type); - } - if (hasSectionName) { - return prefix + section.name + formatters.parameters(section) + returns; - } else if (!hasSectionName && formatters.parameters(section)) { - return section.name + formatters.parameters(section) + returns; - } else { - return section.name + '()' + returns; - } - }, - md: function (ast, inline) { - if (inline && ast && ast.children.length && ast.children[0].type === 'paragraph') { - ast = { - type: 'root', - children: ast.children[0].children.concat(ast.children.slice(1)) - }; - } - return formatters.markdown(ast); - }, - formatType: formatters.type, - autolink: formatters.autolink, - highlight: function (example) { - if (options.hljs && options.hljs.highlightAuto) { - return hljs.highlightAuto(example).value; - } - return hljs.highlight('js', example).value; - } - }; - - var pageTemplate = template(fs.readFileSync(path.join(__dirname, 'index.hbs'), 'utf8'), { - imports: { - renderSection: template(fs.readFileSync(path.join(__dirname, 'section.hbs'), 'utf8'), { - imports: imports - }), - renderNote: template(fs.readFileSync(path.join(__dirname, 'note.hbs'), 'utf8'), { - imports: imports - }), - renderSectionList: template(fs.readFileSync(path.join(__dirname, 'section_list.hbs'), 'utf8'), { - imports: imports - }), - highlight: function (str) { - return highlight(str); - } - } - }); - - // push assets into the pipeline as well. - vfs.src([__dirname + '/assets/**'], { base: __dirname }) - .pipe(concat(function (files) { - callback(null, files.concat(new File({ - path: 'index.html', - contents: new Buffer(pageTemplate({ - docs: comments, - options: options - }), 'utf8') - }))); - })); -}; diff --git a/docs/_theme/note.hbs b/docs/_theme/note.hbs deleted file mode 100644 index 0c5b1d9e9f5..00000000000 --- a/docs/_theme/note.hbs +++ /dev/null @@ -1,12 +0,0 @@ -
- -
- <%- note.name %> -
- - <% if (note.description) { %> -
- <%= md(note.description) %> -
- <% } %> -
diff --git a/docs/_theme/screenshot.png b/docs/_theme/screenshot.png deleted file mode 100644 index ad2cf5b6a53..00000000000 Binary files a/docs/_theme/screenshot.png and /dev/null differ diff --git a/docs/_theme/section.hbs b/docs/_theme/section.hbs deleted file mode 100644 index 90599b2a1f3..00000000000 --- a/docs/_theme/section.hbs +++ /dev/null @@ -1,146 +0,0 @@ -
- - <% if (typeof nested === 'undefined') { %> -
-

- <%- section.name %> -

- <% if (section.context && section.context.github) { %> - - <%= section.context.path %> - - <% } %> -
- <% } %> - - <%= md(section.description) %> - - <% if (section.augments) { %> -

Extends <%= section.augments.map(function(tag) { return autolink(tag.name); }).join(', ') %>.

- <% } %> - - <% if (section.kind === 'class' && !section.interface) { %> -
<%= signature(section, true) %>
- <% } %> - - <% if (section.version) { %>
Version: <%- section.version %>
<% }%> - <% if (section.license) { %>
License: <%- section.license %>
<% }%> - <% if (section.author) { %>
Author: <%- section.author %>
<% }%> - <% if (section.copyright) { %>
Copyright: <%- section.copyright %>
<% }%> - <% if (section.since) { %>
Since: <%- section.since %>
<% }%> - - <% if (section.params && !(section.kind === 'class' && section.interface)) { %> -
Parameters
-
- <% section.params.forEach(function(param) { %> -
-
- <%- param.name%> (<%= formatType(param.type) %><% if (param.default) { %> - (default <%- param.default %>) - <% } %>) <%= md(param.description, true) %> -
- <% if (param.properties) { %> - - - - - - - - - - - - - <% param.properties.forEach(function(property) { %> - - - - - <% }) %> - -
NameDescription
<%- property.name %> <%= formatType(property.type) %> - <% if (property.default) { %> - (default <%- property.default %>) - <% } %><%= md(property.description, true) %>
- <% } %> -
- <% }) %> -
- <% } %> - - <% if (section.properties) { %> -
Properties
-
- <% section.properties.forEach(function(property) { %> -
- <%- property.name%> (<%= formatType(property.type) %>) - <% if (property.default) { %> - (default <%- property.default %>) - <% } %><% if (property.description) { - %>: <%= md(property.description, true) %><% - } %> - <% if (property.properties) { %> -
    - <% property.properties.forEach(function(property) { %> -
  • <%- name%> <%= formatType(property.type) %> - <% if (property.default) { %> - (default <%- property.default %>) - <% } %> - <%= md(property.description) %>
  • - <% }) %> -
- <% } %> -
- <% }) %> -
- <% } %> - - <% if (section.returns) { %> - <% section.returns.forEach(function(ret) { %> -
Returns
- <%= formatType(ret.type) %><% if (ret.description) { %>: - <%= md(ret.description, true) %> - <% }%> - <% }) %> - <% } %> - - <% if (section.throws) { %> -
Throws
- - <% } %> - - <% if (section.examples) { %> -
Example
- <% section.examples.forEach(function(example) { %> - <% if (example.caption) { %>

<%= md(example.caption) %>

<% } %> -
<%= highlight(example.description) %>
- <% }) %> - <% } %> - - <% if (section.members.static && section.members.static.length) { %> -
Static Members
- <%= renderSectionList({ members: section.members.static, renderSection: renderSection, noun: 'Static Member' }) %> - <% } %> - - <% if (section.members.instance && section.members.instance.length) { %> -
Instance Members
- <%= renderSectionList({ members: section.members.instance, renderSection: renderSection, noun: 'Instance Member' }) %> - <% } %> - - <% if (section.members.events && section.members.events.length) { %> -
Events
- <%= renderSectionList({ members: section.members.events, renderSection: renderSection, noun: 'Event' }) %> - <% } %> - - <% if (section.sees) { %> -
Related
- - <% } %> -
diff --git a/docs/_theme/section_list.hbs b/docs/_theme/section_list.hbs deleted file mode 100644 index 0ad2a35a784..00000000000 --- a/docs/_theme/section_list.hbs +++ /dev/null @@ -1,20 +0,0 @@ -
- <% members.forEach(function(member) { %> -
-
-
- - <%= member.name%> - <%= shortSignature(member, false) %> -
-
- -
- <% }) %> -
diff --git a/docs/components/application-wrapper.js b/docs/components/application-wrapper.js new file mode 100644 index 00000000000..8c83097fa0b --- /dev/null +++ b/docs/components/application-wrapper.js @@ -0,0 +1,19 @@ +import React from 'react'; + +// Disable Raven if this isn't a production build, so we don't send development +// errors to Sentry. +if (process.env.DEPLOY_ENV !== 'production' && typeof window !== 'undefined') { + window.MapboxPageShell.disableRaven(); +} + +if (typeof window !== 'undefined') { + window.MapboxPageShellProduction = true; +} + +class ApplicationWrapper extends React.Component { + render() { + return this.props.children; + } +} + +export default ApplicationWrapper; diff --git a/docs/components/copyable.js b/docs/components/copyable.js new file mode 100644 index 00000000000..1e1beaeb1cb --- /dev/null +++ b/docs/components/copyable.js @@ -0,0 +1,27 @@ +import React from 'react'; +import {copy} from 'execcommand-copy'; + +export default class extends React.Component { + constructor(props) { + super(props); + this.state = {copied: false}; + } + + render() { + return ( +
+ this.copy(e)}>{this.state.copied && 'Copied to clipboard!'} +
{ this.ref = ref; }}>{this.props.children}
+
+ ); + } + + copy(e) { + e.preventDefault(); + copy(this.ref.innerText); + analytics.track('Copied example with clipboard'); + this.setState({copied: true}); + setTimeout(() => this.setState({copied: false}), 1000); + } +} diff --git a/docs/components/example.js b/docs/components/example.js new file mode 100644 index 00000000000..379abfcef1c --- /dev/null +++ b/docs/components/example.js @@ -0,0 +1,159 @@ +import React from 'react'; +import {prefixUrl} from '@mapbox/batfish/modules/prefix-url'; +import urls from './urls'; +import PageShell from './page_shell'; +import LeftNav from './left_nav'; +import TopNav from './top_nav'; +import {highlightMarkup} from './prism_highlight'; +import supported from 'mapbox-gl-supported'; +import {copy} from 'execcommand-copy'; +import examples from '@mapbox/batfish/data/examples'; +import entries from 'object.entries'; + +const tags = { + "styles": "Styles", + "layers": "Layers", + "sources": "Sources", + "user-interaction": "User interaction", + "camera": "Camera", + "controls-and-overlays": "Controls and overlays", + "browser-support": "Browser support", + "internationalization": "Internationalization support" +}; + +export default function (html) { + html = html.replace(/{{site.baseurl}}/g, prefixUrl('')); + return class extends React.Component { + constructor(props) { + super(props); + this.state = { + filter: '', + copied: false, + token: '' + }; + } + + // Display HTML with production URLs and the logged-in user's access token (if available). + // Render HTML with possibly-local URLs and a Mapbox access token (don't bill the user for looking at examples). + + displayHTML() { + return ` + + + + ${this.props.frontMatter.title} + + + + + + + +${html.replace(" + + + + + +${html} + +`; + } + + render() { + const {frontMatter} = this.props; + const filter = this.state.filter.toLowerCase().trim(); + return ( + this.setState({token})}> + +
+ this.setState({filter: e.target.value})} + type='text' className='space-bottom' name='filter' placeholder='Filter examples' /> +
+ {entries(tags).map(([tag, title], i) => +
+ {!filter &&

{title}

} + {examples + .filter(({tags, title}) => + tags.indexOf(tag) !== -1 && title.toLowerCase().indexOf(filter) !== -1) + .map(({pathname, title}, i) => + {title} + )} +
+ )} +
+ +
+ + +
+
+ + +
+
{frontMatter.title}
{frontMatter.description}
+ + {!supported() && +
+
+
Mapbox GL unsupported
+
Mapbox GL requires WebGL support. Please check that you are using a supported browser and that WebGL is enabled.
+
+
} +
+ + {supported() && +