Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d77ff64ec2 | ||
|
|
ee27cf1e01 | ||
|
|
54c438997f | ||
|
|
a7d180047a | ||
|
|
a224e51c3f | ||
|
|
0482b7ced4 | ||
|
|
ff729d1357 | ||
|
|
9a08666f1f | ||
|
|
2fa6af0636 | ||
|
|
5a4a98fbe4 | ||
|
|
c008dd1f2c | ||
|
|
fb7d8b7839 | ||
|
|
c5f2787284 | ||
|
|
97a862f8e6 | ||
|
|
ac9b0c7c9f | ||
|
|
d33026d12c |
@@ -11,7 +11,6 @@
|
|||||||
},
|
},
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"config/jsdoc/info/api-plugin",
|
"config/jsdoc/info/api-plugin",
|
||||||
"config/jsdoc/info/define-plugin",
|
"config/jsdoc/info/module-plugin"
|
||||||
"config/jsdoc/info/virtual-plugin"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
/**
|
|
||||||
* @fileoverview This plugin extracts info from boolean defines. This only
|
|
||||||
* handles boolean defines with the default value in the description. Default
|
|
||||||
* is assumed to be provided with something like "default is `true`" (case
|
|
||||||
* insensitive, with or without ticks).
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
const DEFAULT_VALUE = /default\s+is\s+`?(true|false)`?/i;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hook to define new tags.
|
|
||||||
* @param {Object} dictionary The tag dictionary.
|
|
||||||
*/
|
|
||||||
exports.defineTags = function(dictionary) {
|
|
||||||
|
|
||||||
dictionary.defineTag('define', {
|
|
||||||
canHaveType: true,
|
|
||||||
mustHaveValue: true,
|
|
||||||
onTagged: function(doclet, tag) {
|
|
||||||
const types = tag.value.type.names;
|
|
||||||
if (types.length === 1 && types[0] === 'boolean') {
|
|
||||||
const match = tag.value.description.match(DEFAULT_VALUE);
|
|
||||||
if (match) {
|
|
||||||
doclet.define = {
|
|
||||||
default: match[1] === 'true'
|
|
||||||
};
|
|
||||||
doclet.description = tag.value.description;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
|
||||||
135
config/jsdoc/info/module-plugin.js
Normal file
135
config/jsdoc/info/module-plugin.js
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const exportLookup = {};
|
||||||
|
const moduleLookup = {};
|
||||||
|
|
||||||
|
const MODULE_PATH = /^module:(.*)~(\w+)$/;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add exports to modules.
|
||||||
|
*/
|
||||||
|
exports.handlers = {
|
||||||
|
|
||||||
|
symbolFound(event) {
|
||||||
|
const filename = event.filename;
|
||||||
|
const node = event.astnode;
|
||||||
|
let local, exported;
|
||||||
|
switch (node.type) {
|
||||||
|
|
||||||
|
case 'ExportDefaultDeclaration': {
|
||||||
|
exported = 'default';
|
||||||
|
|
||||||
|
switch (node.declaration.type) {
|
||||||
|
|
||||||
|
case 'Identifier': {
|
||||||
|
// export default foo;
|
||||||
|
local = node.declaration.name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'FunctionDeclaration': {
|
||||||
|
if (!node.declaration.id) {
|
||||||
|
// export default function() {}
|
||||||
|
local = '';
|
||||||
|
} else {
|
||||||
|
// export default function foo() {}
|
||||||
|
local = node.declaration.id.name;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
local = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'ExportNamedDeclaration': {
|
||||||
|
if (!node.declaration) {
|
||||||
|
// export {foo}
|
||||||
|
// export {foo as bar}
|
||||||
|
// handled below in ExportSpecifier
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (node.declaration.type) {
|
||||||
|
case 'FunctionDeclaration': {
|
||||||
|
if (!node.declaration.id) {
|
||||||
|
throw new Error(`Expected function declaration to have an id in ${filename}`);
|
||||||
|
}
|
||||||
|
const name = node.declaration.id.name;
|
||||||
|
local = name;
|
||||||
|
exported = name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'ExportSpecifier': {
|
||||||
|
if (node.exported.type === 'Identifier') {
|
||||||
|
exported = node.exported.name;
|
||||||
|
if (node.local.type === 'Identifier') {
|
||||||
|
local = node.local.name;
|
||||||
|
if (node.parent.source) {
|
||||||
|
const resolved = path.resolve(path.dirname(filename), node.parent.source.value);
|
||||||
|
local = `module:${resolved}~${local}`;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
local = '';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!(filename in exportLookup)) {
|
||||||
|
exportLookup[filename] = {};
|
||||||
|
}
|
||||||
|
const exports = exportLookup[filename];
|
||||||
|
if (exports.hasOwnProperty(exported)) {
|
||||||
|
throw new Error(`Duplicate export {${local} as ${exported}} in ${filename}`);
|
||||||
|
}
|
||||||
|
exports[exported] = local;
|
||||||
|
},
|
||||||
|
|
||||||
|
newDoclet(event) {
|
||||||
|
const doclet = event.doclet;
|
||||||
|
if (doclet.kind === 'module') {
|
||||||
|
const filepath = path.join(doclet.meta.path, doclet.meta.filename);
|
||||||
|
if (filepath in moduleLookup) {
|
||||||
|
throw new Error(`Duplicate @module annotation in ${filepath}`);
|
||||||
|
}
|
||||||
|
moduleLookup[filepath] = doclet;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
parseComplete(event) {
|
||||||
|
for (const filepath in moduleLookup) {
|
||||||
|
const doclet = moduleLookup[filepath];
|
||||||
|
const exports = exportLookup[filepath];
|
||||||
|
for (const exported in exports) {
|
||||||
|
const local = exports[exported];
|
||||||
|
const match = local.match(MODULE_PATH);
|
||||||
|
if (match) {
|
||||||
|
const filepath = match[1];
|
||||||
|
const mod = moduleLookup[filepath];
|
||||||
|
if (mod) {
|
||||||
|
exports[exported] = `module:${mod.name}~${match[2]}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doclet.exports = exports; // undefined if no exports
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @fileoverview Generates JSON output based on exportable symbols (those with
|
* @fileoverview Generates JSON output based on exportable symbols.
|
||||||
* an api tag) and boolean defines (with a define tag and a default value).
|
|
||||||
*/
|
*/
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
@@ -22,7 +21,7 @@ exports.publish = function(data, opts) {
|
|||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get all doclets with the "api" property or define (excluding events)
|
// get all doclets with the "api" property
|
||||||
const classes = {};
|
const classes = {};
|
||||||
const docs = data(
|
const docs = data(
|
||||||
[
|
[
|
||||||
@@ -34,7 +33,7 @@ exports.publish = function(data, opts) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (typeof this.api == 'boolean' ||
|
return (this.kind === 'module' || typeof this.api == 'boolean' ||
|
||||||
this.meta && (/[\\\/]externs$/).test(this.meta.path));
|
this.meta && (/[\\\/]externs$/).test(this.meta.path));
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -43,9 +42,9 @@ exports.publish = function(data, opts) {
|
|||||||
|
|
||||||
// get symbols data, filter out those that are members of private classes
|
// get symbols data, filter out those that are members of private classes
|
||||||
const symbols = [];
|
const symbols = [];
|
||||||
const defines = [];
|
|
||||||
const typedefs = [];
|
const typedefs = [];
|
||||||
const externs = [];
|
const externs = [];
|
||||||
|
const modules = [];
|
||||||
let base = [];
|
let base = [];
|
||||||
const augments = {};
|
const augments = {};
|
||||||
const symbolsByName = {};
|
const symbolsByName = {};
|
||||||
@@ -59,13 +58,11 @@ exports.publish = function(data, opts) {
|
|||||||
}
|
}
|
||||||
return include;
|
return include;
|
||||||
}).forEach(function(doc) {
|
}).forEach(function(doc) {
|
||||||
const isExterns = (/[\\\/]externs$/).test(doc.meta.path);
|
if (doc.kind == 'module') {
|
||||||
if (doc.define) {
|
modules.push({
|
||||||
defines.push({
|
|
||||||
name: doc.longname,
|
name: doc.longname,
|
||||||
description: doc.description,
|
exports: doc.exports || null,
|
||||||
path: path.join(doc.meta.path, doc.meta.filename),
|
path: path.join(doc.meta.path, doc.meta.filename)
|
||||||
default: doc.define.default
|
|
||||||
});
|
});
|
||||||
} else if (doc.kind == 'typedef' || doc.isEnum === true) {
|
} else if (doc.kind == 'typedef' || doc.isEnum === true) {
|
||||||
typedefs.push({
|
typedefs.push({
|
||||||
@@ -82,6 +79,9 @@ exports.publish = function(data, opts) {
|
|||||||
if (doc.augments) {
|
if (doc.augments) {
|
||||||
symbol.extends = doc.augments[0];
|
symbol.extends = doc.augments[0];
|
||||||
}
|
}
|
||||||
|
if (doc.memberof) {
|
||||||
|
symbol.memberof = doc.memberof;
|
||||||
|
}
|
||||||
if (doc.virtual) {
|
if (doc.virtual) {
|
||||||
symbol.virtual = true;
|
symbol.virtual = true;
|
||||||
}
|
}
|
||||||
@@ -92,7 +92,8 @@ exports.publish = function(data, opts) {
|
|||||||
const params = [];
|
const params = [];
|
||||||
doc.params.forEach(function(param) {
|
doc.params.forEach(function(param) {
|
||||||
const paramInfo = {
|
const paramInfo = {
|
||||||
name: param.name
|
name: param.name,
|
||||||
|
description: param.description
|
||||||
};
|
};
|
||||||
params.push(paramInfo);
|
params.push(paramInfo);
|
||||||
paramInfo.types = getTypes(param.type.names);
|
paramInfo.types = getTypes(param.type.names);
|
||||||
@@ -126,7 +127,7 @@ exports.publish = function(data, opts) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const target = isExterns ? externs : (doc.api ? symbols : base);
|
const target = doc.api ? symbols : base;
|
||||||
const existingSymbol = symbolsByName[symbol.name];
|
const existingSymbol = symbolsByName[symbol.name];
|
||||||
if (existingSymbol) {
|
if (existingSymbol) {
|
||||||
const idx = target.indexOf(existingSymbol);
|
const idx = target.indexOf(existingSymbol);
|
||||||
@@ -155,10 +156,10 @@ exports.publish = function(data, opts) {
|
|||||||
process.stdout.write(
|
process.stdout.write(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
symbols: symbols,
|
symbols: symbols,
|
||||||
defines: defines,
|
|
||||||
typedefs: typedefs,
|
typedefs: typedefs,
|
||||||
externs: externs,
|
externs: externs,
|
||||||
base: base
|
base: base,
|
||||||
|
modules: modules
|
||||||
}, null, 2));
|
}, null, 2));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
/**
|
|
||||||
* Handle the interface and abstract annotations.
|
|
||||||
* @param {Object} dictionary The tag dictionary.
|
|
||||||
*/
|
|
||||||
exports.defineTags = function(dictionary) {
|
|
||||||
|
|
||||||
const classTag = dictionary.lookUp('class');
|
|
||||||
dictionary.defineTag('interface', {
|
|
||||||
mustHaveValue: false,
|
|
||||||
onTagged: function(doclet, tag) {
|
|
||||||
classTag.onTagged.apply(this, arguments);
|
|
||||||
doclet.virtual = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
"serve-examples": "mkdir -p build/examples && webpack --config examples/webpack/config.js --mode development --watch & serve build/examples",
|
"serve-examples": "mkdir -p build/examples && webpack --config examples/webpack/config.js --mode development --watch & serve build/examples",
|
||||||
"build-examples": "webpack --config examples/webpack/config.js --mode production",
|
"build-examples": "webpack --config examples/webpack/config.js --mode production",
|
||||||
"build-index": "node tasks/generate-index",
|
"build-index": "node tasks/generate-index",
|
||||||
|
"build-site": "node tasks/generate-info.js && cd site && npm install && npm run build",
|
||||||
"prebuild": "npm run build-index",
|
"prebuild": "npm run build-index",
|
||||||
"build": "rollup --config config/rollup.js",
|
"build": "rollup --config config/rollup.js",
|
||||||
"presrc-closure": "npm run prebuild",
|
"presrc-closure": "npm run prebuild",
|
||||||
@@ -39,6 +40,7 @@
|
|||||||
"css/ol.css"
|
"css/ol.css"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"babel-eslint": "^8.2.3",
|
||||||
"pbf": "3.1.0",
|
"pbf": "3.1.0",
|
||||||
"pixelworks": "1.1.0",
|
"pixelworks": "1.1.0",
|
||||||
"rbush": "2.0.2"
|
"rbush": "2.0.2"
|
||||||
@@ -52,6 +54,9 @@
|
|||||||
"coveralls": "3.0.1",
|
"coveralls": "3.0.1",
|
||||||
"eslint": "4.19.1",
|
"eslint": "4.19.1",
|
||||||
"eslint-config-openlayers": "^9.2.0",
|
"eslint-config-openlayers": "^9.2.0",
|
||||||
|
"eslint-config-prettier": "^2.9.0",
|
||||||
|
"eslint-plugin-prettier": "^2.6.0",
|
||||||
|
"eslint-plugin-react": "^7.7.0",
|
||||||
"expect.js": "0.3.1",
|
"expect.js": "0.3.1",
|
||||||
"front-matter": "^2.1.2",
|
"front-matter": "^2.1.2",
|
||||||
"fs-extra": "^6.0.0",
|
"fs-extra": "^6.0.0",
|
||||||
@@ -73,6 +78,7 @@
|
|||||||
"mocha": "5.2.0",
|
"mocha": "5.2.0",
|
||||||
"mustache": "^2.3.0",
|
"mustache": "^2.3.0",
|
||||||
"pixelmatch": "^4.0.2",
|
"pixelmatch": "^4.0.2",
|
||||||
|
"prettier": "^1.12.0",
|
||||||
"proj4": "2.4.4",
|
"proj4": "2.4.4",
|
||||||
"recast": "0.15.0",
|
"recast": "0.15.0",
|
||||||
"rollup": "0.60.2",
|
"rollup": "0.60.2",
|
||||||
|
|||||||
1
site/.babelrc
Normal file
1
site/.babelrc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
7
site/.eslintrc
Normal file
7
site/.eslintrc
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"extends": "openlayers/react",
|
||||||
|
"parser": "babel-eslint",
|
||||||
|
"globals": {
|
||||||
|
"graphql": false
|
||||||
|
}
|
||||||
|
}
|
||||||
4
site/.gitignore
vendored
Normal file
4
site/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
/node_modules/
|
||||||
|
/.cache/
|
||||||
|
/public/
|
||||||
|
/build/
|
||||||
30
site/gatsby-config.js
Normal file
30
site/gatsby-config.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const typography = require('./src/utils/typography');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
plugins: [
|
||||||
|
{
|
||||||
|
resolve: 'gatsby-plugin-typography',
|
||||||
|
options: {
|
||||||
|
pathToConfigModule: 'src/utils/typography.js'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'gatsby-plugin-emotion',
|
||||||
|
{
|
||||||
|
resolve: 'gatsby-source-filesystem',
|
||||||
|
options: {
|
||||||
|
name: 'examples',
|
||||||
|
path: path.join(__dirname, 'src', 'examples')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
resolve: 'examples',
|
||||||
|
options: {
|
||||||
|
sourceInstanceName: 'examples',
|
||||||
|
baseCss: typography.toString()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'gatsby-transformer-remark',
|
||||||
|
'gatsby-plugin-react-next'
|
||||||
|
]
|
||||||
|
};
|
||||||
3
site/gatsby-node.js
Normal file
3
site/gatsby-node.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
// exports.onPreBuild = () => {
|
||||||
|
// // TODO: empty public folder
|
||||||
|
// };
|
||||||
15861
site/package-lock.json
generated
Normal file
15861
site/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
32
site/package.json
Normal file
32
site/package.json
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"name": "@ol/site",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"start": "gatsby develop",
|
||||||
|
"build": "gatsby build"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"emotion": "^9.1.3",
|
||||||
|
"emotion-server": "^9.1.3",
|
||||||
|
"gatsby": "1.9.250",
|
||||||
|
"gatsby-link": "1.6.40",
|
||||||
|
"gatsby-plugin-emotion": "^1.1.16",
|
||||||
|
"gatsby-plugin-react-helmet": "2.0.10",
|
||||||
|
"gatsby-plugin-react-next": "^1.0.11",
|
||||||
|
"gatsby-plugin-typography": "1.7.18",
|
||||||
|
"gatsby-source-filesystem": "1.5.31",
|
||||||
|
"gatsby-transformer-remark": "^1.7.40",
|
||||||
|
"prop-types": "15.6.1",
|
||||||
|
"react-emotion": "^9.1.3",
|
||||||
|
"react-helmet": "5.2.0",
|
||||||
|
"react-markdown": "^3.3.2",
|
||||||
|
"rollup": "^0.58.1",
|
||||||
|
"rollup-plugin-commonjs": "^9.1.0",
|
||||||
|
"rollup-plugin-node-resolve": "^3.3.0",
|
||||||
|
"string-template": "^1.0.0",
|
||||||
|
"typography-plugin-code": "^0.16.11",
|
||||||
|
"typography-theme-noriega": "^0.15.10"
|
||||||
|
}
|
||||||
|
}
|
||||||
95
site/plugins/examples/components/Example.js
Normal file
95
site/plugins/examples/components/Example.js
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
import {object} from 'prop-types';
|
||||||
|
import ExampleList from './ExampleList';
|
||||||
|
import React, {Component, Fragment} from 'react';
|
||||||
|
import styled from 'react-emotion';
|
||||||
|
|
||||||
|
const Wrapper = styled('div')({
|
||||||
|
display: 'flex'
|
||||||
|
});
|
||||||
|
|
||||||
|
const Sidebar = styled('div')({
|
||||||
|
marginRight: '1em'
|
||||||
|
});
|
||||||
|
|
||||||
|
const Content = styled('div')({
|
||||||
|
minWidth: 300,
|
||||||
|
flexGrow: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
const Embed = styled('iframe')({
|
||||||
|
margin: 0,
|
||||||
|
padding: 0,
|
||||||
|
height: 350,
|
||||||
|
width: '100%'
|
||||||
|
});
|
||||||
|
|
||||||
|
const Aside = styled('aside')({
|
||||||
|
textAlign: 'right',
|
||||||
|
fontSize: '0.75em'
|
||||||
|
});
|
||||||
|
|
||||||
|
const Block = styled('pre')({
|
||||||
|
overflow: 'auto'
|
||||||
|
});
|
||||||
|
|
||||||
|
class Example extends Component {
|
||||||
|
render() {
|
||||||
|
const example = this.props.data.sitePage.context;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Wrapper>
|
||||||
|
<Sidebar>
|
||||||
|
<ExampleList active={example.slug} />
|
||||||
|
</Sidebar>
|
||||||
|
<Content>
|
||||||
|
<h1>{example.frontmatter.title}</h1>
|
||||||
|
<Embed src={example.embedUrl} frameBorder="0" />
|
||||||
|
<Aside>
|
||||||
|
<p>
|
||||||
|
<a href={example.embedUrl}>stand-alone version</a>
|
||||||
|
</p>
|
||||||
|
</Aside>
|
||||||
|
<h3>script</h3>
|
||||||
|
<Block>
|
||||||
|
<code>{example.js}</code>
|
||||||
|
</Block>
|
||||||
|
<h3>markup</h3>
|
||||||
|
<Block>
|
||||||
|
<code>{example.html}</code>
|
||||||
|
</Block>
|
||||||
|
{example.css && (
|
||||||
|
<Fragment>
|
||||||
|
<h3>style</h3>
|
||||||
|
<Block>
|
||||||
|
<code>{example.css}</code>
|
||||||
|
</Block>
|
||||||
|
</Fragment>
|
||||||
|
)}
|
||||||
|
</Content>
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Example.propTypes = {
|
||||||
|
data: object.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export const query = graphql`
|
||||||
|
query ExampleQuery($slug: String!) {
|
||||||
|
sitePage(context: {slug: {eq: $slug}}) {
|
||||||
|
context {
|
||||||
|
slug
|
||||||
|
frontmatter {
|
||||||
|
title
|
||||||
|
}
|
||||||
|
embedUrl
|
||||||
|
html
|
||||||
|
js
|
||||||
|
css
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default Example;
|
||||||
54
site/plugins/examples/components/ExampleList.js
Normal file
54
site/plugins/examples/components/ExampleList.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import Link from 'gatsby-link';
|
||||||
|
import React, {Component} from 'react';
|
||||||
|
import styled from 'react-emotion';
|
||||||
|
|
||||||
|
const Wrapper = styled('div')({
|
||||||
|
minWidth: '10em'
|
||||||
|
});
|
||||||
|
|
||||||
|
const List = styled('ul')({
|
||||||
|
margin: 0,
|
||||||
|
listStyle: 'none'
|
||||||
|
});
|
||||||
|
|
||||||
|
class ExampleList extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
index: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
fetch('../index.json')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(index => {
|
||||||
|
this.setState({index});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
renderList() {
|
||||||
|
const index = this.state.index;
|
||||||
|
if (!index) {
|
||||||
|
return '...';
|
||||||
|
}
|
||||||
|
|
||||||
|
const list = [];
|
||||||
|
for (const id in index) {
|
||||||
|
const example = index[id];
|
||||||
|
list.push(
|
||||||
|
<li key={id}>
|
||||||
|
<Link to={example.slug}>{example.title}</Link>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return <List>{list}</List>;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return <Wrapper>{this.renderList()}</Wrapper>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ExampleList;
|
||||||
27
site/plugins/examples/embed.html
Normal file
27
site/plugins/examples/embed.html
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charSet="utf-8">
|
||||||
|
<title>{title}</title>
|
||||||
|
<style>{baseCss}</style>
|
||||||
|
<style>{olCss}</style>
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
#map {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style>{exampleCss}</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{html}
|
||||||
|
<script type="module" src="{mainBundleUrl}"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
197
site/plugins/examples/gatsby-node.js
Normal file
197
site/plugins/examples/gatsby-node.js
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const {createFilePath} = require('gatsby-source-filesystem');
|
||||||
|
const rollup = require('rollup');
|
||||||
|
const resolve = require('rollup-plugin-node-resolve');
|
||||||
|
const common = require('rollup-plugin-commonjs');
|
||||||
|
const fse = require('fs-extra');
|
||||||
|
const compileTemplate = require('string-template/compile');
|
||||||
|
|
||||||
|
let rollupCache;
|
||||||
|
const rollupPlugins = [resolve(), common()];
|
||||||
|
|
||||||
|
let olCss;
|
||||||
|
async function getOLCss() {
|
||||||
|
if (olCss) {
|
||||||
|
return olCss;
|
||||||
|
}
|
||||||
|
const cssPath = path.join(__dirname, '..', '..', '..', 'css', 'ol.css');
|
||||||
|
olCss = await fse.readFile(cssPath, {encoding: 'utf8'});
|
||||||
|
return olCss;
|
||||||
|
}
|
||||||
|
|
||||||
|
let embedTemplate;
|
||||||
|
async function getEmbedTemplate() {
|
||||||
|
if (embedTemplate) {
|
||||||
|
return embedTemplate;
|
||||||
|
}
|
||||||
|
const embedPath = path.join(__dirname, 'embed.html');
|
||||||
|
const src = await fse.readFile(embedPath, {encoding: 'utf8'});
|
||||||
|
embedTemplate = compileTemplate(src);
|
||||||
|
return embedTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.onCreateNode = ({node, getNode, boundActionCreators}) => {
|
||||||
|
const {createNodeField} = boundActionCreators;
|
||||||
|
if (node.internal.type === 'MarkdownRemark') {
|
||||||
|
const slug = createFilePath({node, getNode});
|
||||||
|
createNodeField({
|
||||||
|
node,
|
||||||
|
name: 'slug',
|
||||||
|
value: `/examples${slug}` // TODO: get this from options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.createPages = async (
|
||||||
|
{graphql, boundActionCreators},
|
||||||
|
{sourceInstanceName, baseCss = ''}
|
||||||
|
) => {
|
||||||
|
const {createPage, createRedirect} = boundActionCreators;
|
||||||
|
|
||||||
|
createRedirect({
|
||||||
|
fromPath: `/examples/`,
|
||||||
|
isPermanent: true,
|
||||||
|
redirectInBrowser: true,
|
||||||
|
toPath: `/examples/map/`
|
||||||
|
});
|
||||||
|
|
||||||
|
const {data} = await graphql(`
|
||||||
|
{
|
||||||
|
allFile(
|
||||||
|
filter: {sourceInstanceName: {eq: "${sourceInstanceName}"}, extension: {ne: ""}}
|
||||||
|
) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
base
|
||||||
|
name
|
||||||
|
extension
|
||||||
|
absolutePath
|
||||||
|
childMarkdownRemark {
|
||||||
|
frontmatter {
|
||||||
|
title
|
||||||
|
}
|
||||||
|
fields {
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
html
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
|
||||||
|
const rollupInputs = [];
|
||||||
|
|
||||||
|
const examples = {};
|
||||||
|
data.allFile.edges.forEach(({node}) => {
|
||||||
|
const name = node.name;
|
||||||
|
if (!(name in examples)) {
|
||||||
|
examples[name] = {};
|
||||||
|
}
|
||||||
|
examples[name][node.extension] = node;
|
||||||
|
if (node.extension === 'js') {
|
||||||
|
rollupInputs.push(node.absolutePath);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const bundle = await rollup.rollup({
|
||||||
|
input: rollupInputs,
|
||||||
|
plugins: rollupPlugins,
|
||||||
|
experimentalCodeSplitting: true,
|
||||||
|
cache: rollupCache
|
||||||
|
});
|
||||||
|
|
||||||
|
const embedDirName = 'example-embeds';
|
||||||
|
const embedDir = path.join(__dirname, '..', '..', 'public', embedDirName);
|
||||||
|
const exampleDir = path.join(__dirname, '..', '..', 'public', 'examples');
|
||||||
|
|
||||||
|
rollupCache = await bundle.write({
|
||||||
|
format: 'es',
|
||||||
|
sourcemap: true,
|
||||||
|
dir: embedDir
|
||||||
|
});
|
||||||
|
|
||||||
|
const writes = [];
|
||||||
|
const index = {};
|
||||||
|
|
||||||
|
for (const name in examples) {
|
||||||
|
const node = examples[name].md;
|
||||||
|
if (!node) {
|
||||||
|
throw new Error(`Missing ${name}.md`);
|
||||||
|
}
|
||||||
|
const markdownNode = node.childMarkdownRemark;
|
||||||
|
if (!markdownNode) {
|
||||||
|
throw new Error(`Expected a MarkdownRemark node for ${name}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const mainBundleUrl = `${name}.js`;
|
||||||
|
const bundleInfo = rollupCache[mainBundleUrl];
|
||||||
|
if (!bundleInfo) {
|
||||||
|
throw new Error(`Expected a js bundle for ${name}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const jsNode = examples[name].js;
|
||||||
|
if (!jsNode) {
|
||||||
|
throw new Error(`Missing ${name}.js`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const moduleIndex = bundleInfo.map.sources.findIndex(
|
||||||
|
filepath => path.resolve(filepath) === jsNode.absolutePath
|
||||||
|
);
|
||||||
|
if (moduleIndex < 0) {
|
||||||
|
throw new Error(`Could not find ${node.absolutePath} in module list`);
|
||||||
|
}
|
||||||
|
const source = bundleInfo.map.sourcesContent[moduleIndex];
|
||||||
|
if (!source) {
|
||||||
|
throw new Error(`Could not find source for ${jsNode.absolutePath}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
let exampleCss = '';
|
||||||
|
const cssNode = examples[name].css;
|
||||||
|
if (cssNode) {
|
||||||
|
exampleCss = await fse.readFile(cssNode.absolutePath, {encoding: 'utf8'});
|
||||||
|
await fse.writeFile(path.join(embedDir, cssNode.base), exampleCss);
|
||||||
|
}
|
||||||
|
|
||||||
|
const embedTemplate = await getEmbedTemplate();
|
||||||
|
const embed = embedTemplate({
|
||||||
|
title: markdownNode.frontmatter.title,
|
||||||
|
baseCss,
|
||||||
|
olCss: await getOLCss(),
|
||||||
|
exampleCss,
|
||||||
|
html: markdownNode.html,
|
||||||
|
mainBundleUrl
|
||||||
|
});
|
||||||
|
|
||||||
|
const embedName = `${name}.html`;
|
||||||
|
writes.push(fse.writeFile(path.join(embedDir, embedName), embed));
|
||||||
|
|
||||||
|
const slug = markdownNode.fields.slug;
|
||||||
|
index[name] = {
|
||||||
|
title: markdownNode.frontmatter.title,
|
||||||
|
slug
|
||||||
|
};
|
||||||
|
|
||||||
|
createPage({
|
||||||
|
path: slug,
|
||||||
|
component: path.join(__dirname, 'components', 'Example.js'),
|
||||||
|
context: {
|
||||||
|
slug,
|
||||||
|
frontmatter: markdownNode.frontmatter,
|
||||||
|
embedUrl: `/${embedDirName}/${embedName}`,
|
||||||
|
html: markdownNode.html,
|
||||||
|
js: source.replace(/'\.\.\/\.\.\/\.\.\/src\/(.*?)\.js/g, "'$1"),
|
||||||
|
css: exampleCss
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await fse.ensureDir(exampleDir);
|
||||||
|
|
||||||
|
writes.push(
|
||||||
|
fse.writeFile(path.join(exampleDir, 'index.json'), JSON.stringify(index))
|
||||||
|
);
|
||||||
|
|
||||||
|
await Promise.all(writes);
|
||||||
|
};
|
||||||
1
site/plugins/examples/index.js
Normal file
1
site/plugins/examples/index.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
// no-op
|
||||||
4
site/plugins/examples/package.json
Normal file
4
site/plugins/examples/package.json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"name": "examples",
|
||||||
|
"main": "index.js"
|
||||||
|
}
|
||||||
76
site/src/components/doc/Class.js
Normal file
76
site/src/components/doc/Class.js
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import React, {Component, Fragment} from 'react';
|
||||||
|
import {string, array} from 'prop-types';
|
||||||
|
import Markdown from 'react-markdown';
|
||||||
|
import {slugify, getShortName, getShortModuleName} from '../../utils/doc';
|
||||||
|
|
||||||
|
class Class extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
name: string.isRequired,
|
||||||
|
description: string,
|
||||||
|
params: array,
|
||||||
|
exported: string
|
||||||
|
};
|
||||||
|
|
||||||
|
renderArguments() {
|
||||||
|
if (!this.props.params) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<h4>Arguments</h4>
|
||||||
|
<ul>{this.props.params.map(this.renderArgument)}</ul>
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderArgument(arg) {
|
||||||
|
return (
|
||||||
|
<li key={arg.name}>
|
||||||
|
<code>{arg.name}</code>: {arg.description}
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const name = this.props.name;
|
||||||
|
const shortName = getShortName(name);
|
||||||
|
const moduleName = getShortModuleName(name);
|
||||||
|
const slug = slugify(name);
|
||||||
|
const exported = this.props.exported;
|
||||||
|
|
||||||
|
let importSyntax;
|
||||||
|
if (exported) {
|
||||||
|
if (exported === 'default') {
|
||||||
|
importSyntax = `import ${shortName} from '${moduleName}';\n\n`;
|
||||||
|
} else if (exported !== shortName) {
|
||||||
|
importSyntax = `import {${exported} as ${shortName}} from '${moduleName}';\n\n`;
|
||||||
|
} else {
|
||||||
|
importSyntax = `import {${exported}} from '${moduleName}';\n\n`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const params = this.props.params || [];
|
||||||
|
const usage = `new ${shortName}(${params
|
||||||
|
.map(param => param.name)
|
||||||
|
.join(', ')});`;
|
||||||
|
|
||||||
|
const description = this.props.description || '';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<a name={slug} href={`#${slug}`} />
|
||||||
|
<pre>
|
||||||
|
<code>
|
||||||
|
{importSyntax}
|
||||||
|
{usage}
|
||||||
|
</code>
|
||||||
|
</pre>
|
||||||
|
<Markdown source={description} />
|
||||||
|
{this.renderArguments()}
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Class;
|
||||||
76
site/src/components/doc/Func.js
Normal file
76
site/src/components/doc/Func.js
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import React, {Component, Fragment} from 'react';
|
||||||
|
import {string, array} from 'prop-types';
|
||||||
|
import Markdown from 'react-markdown';
|
||||||
|
import {slugify, getShortName, getShortModuleName} from '../../utils/doc';
|
||||||
|
|
||||||
|
class Func extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
name: string.isRequired,
|
||||||
|
description: string,
|
||||||
|
params: array,
|
||||||
|
exported: string
|
||||||
|
};
|
||||||
|
|
||||||
|
renderArguments() {
|
||||||
|
if (!this.props.params) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<h4>Arguments</h4>
|
||||||
|
<ul>{this.props.params.map(this.renderArgument)}</ul>
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderArgument(arg) {
|
||||||
|
return (
|
||||||
|
<li key={arg.name}>
|
||||||
|
<code>{arg.name}</code>: {arg.description}
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const name = this.props.name;
|
||||||
|
const shortName = getShortName(name);
|
||||||
|
const moduleName = getShortModuleName(name);
|
||||||
|
const slug = slugify(name);
|
||||||
|
const exported = this.props.exported;
|
||||||
|
|
||||||
|
let importSyntax;
|
||||||
|
if (exported) {
|
||||||
|
if (exported === 'default') {
|
||||||
|
importSyntax = `import ${shortName} from '${moduleName}';\n\n`;
|
||||||
|
} else if (exported !== shortName) {
|
||||||
|
importSyntax = `import {${exported} as ${shortName}} from '${moduleName}';\n\n`;
|
||||||
|
} else {
|
||||||
|
importSyntax = `import {${exported}} from '${moduleName}';\n\n`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const params = this.props.params || [];
|
||||||
|
const usage = `${shortName}(${params
|
||||||
|
.map(param => param.name)
|
||||||
|
.join(', ')});`;
|
||||||
|
|
||||||
|
const description = this.props.description || '';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<a name={slug} href={`#${slug}`} />
|
||||||
|
<pre>
|
||||||
|
<code>
|
||||||
|
{importSyntax}
|
||||||
|
{usage}
|
||||||
|
</code>
|
||||||
|
</pre>
|
||||||
|
<Markdown source={description} />
|
||||||
|
{this.renderArguments()}
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Func;
|
||||||
57
site/src/components/doc/Module.js
Normal file
57
site/src/components/doc/Module.js
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import React, {Component, Fragment} from 'react';
|
||||||
|
import {string, array} from 'prop-types';
|
||||||
|
import {slugify, getShortModuleName} from '../../utils/doc';
|
||||||
|
import Func from './Func';
|
||||||
|
import Class from './Class';
|
||||||
|
|
||||||
|
class Module extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
name: string.isRequired,
|
||||||
|
classes: array.isRequired,
|
||||||
|
functions: array.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
renderClasses() {
|
||||||
|
if (this.props.classes.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<h3>Classes</h3>
|
||||||
|
{this.props.classes.map(cls => <Class key={cls.name} {...cls} />)}
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderFuncs() {
|
||||||
|
if (this.props.functions.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<h3>Functions</h3>
|
||||||
|
{this.props.functions.map(func => <Func key={func.name} {...func} />)}
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const name = this.props.name;
|
||||||
|
const slug = slugify(name);
|
||||||
|
return (
|
||||||
|
<section>
|
||||||
|
<a name={slug} href={`#${slug}`}>
|
||||||
|
<h1>
|
||||||
|
<code>{getShortModuleName(name)}</code>
|
||||||
|
</h1>
|
||||||
|
</a>
|
||||||
|
{this.renderClasses()}
|
||||||
|
{this.renderFuncs()}
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Module;
|
||||||
10
site/src/examples/.eslintrc
Normal file
10
site/src/examples/.eslintrc
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"rules": {
|
||||||
|
"no-unused-vars": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"varsIgnorePattern": "^map"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
39
site/src/examples/layers.js
Normal file
39
site/src/examples/layers.js
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import Map from '../../../src/ol/Map.js';
|
||||||
|
import View from '../../../src/ol/View.js';
|
||||||
|
import GeoJSON from '../../../src/ol/format/GeoJSON.js';
|
||||||
|
import {
|
||||||
|
Tile as TileLayer,
|
||||||
|
Vector as VectorLayer
|
||||||
|
} from '../../../src/ol/layer.js';
|
||||||
|
import {BingMaps, Vector as VectorSource} from '../../../src/ol/source.js';
|
||||||
|
import {Style, Stroke} from '../../../src/ol/style.js';
|
||||||
|
|
||||||
|
const map = new Map({
|
||||||
|
layers: [
|
||||||
|
new TileLayer({
|
||||||
|
source: new BingMaps({
|
||||||
|
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5',
|
||||||
|
imagerySet: 'Aerial'
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
new VectorLayer({
|
||||||
|
source: new VectorSource({
|
||||||
|
format: new GeoJSON(),
|
||||||
|
url:
|
||||||
|
'https://raw.githubusercontent.com/johan/world.geo.json/master/countries.geo.json'
|
||||||
|
}),
|
||||||
|
opacity: 0.5,
|
||||||
|
style: new Style({
|
||||||
|
stroke: new Stroke({
|
||||||
|
width: 1.25,
|
||||||
|
color: 'lightgrey'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
],
|
||||||
|
target: 'map',
|
||||||
|
view: new View({
|
||||||
|
center: [0, 0],
|
||||||
|
zoom: 2
|
||||||
|
})
|
||||||
|
});
|
||||||
10
site/src/examples/layers.md
Normal file
10
site/src/examples/layers.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
title: Multiple Layers
|
||||||
|
shortdesc: Using layers to compose a map.
|
||||||
|
docs: >
|
||||||
|
Layers control how data is rendered on a map. In this example, a `Vector` layer displays GeoJSON over tiles from a `Tile` layer.
|
||||||
|
cloak:
|
||||||
|
- key: As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5
|
||||||
|
value: Your Bing Maps Key from http://www.bingmapsportal.com/ here
|
||||||
|
---
|
||||||
|
<div id="map"></div>
|
||||||
17
site/src/examples/map.js
Normal file
17
site/src/examples/map.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import Map from '../../../src/ol/Map.js';
|
||||||
|
import View from '../../../src/ol/View.js';
|
||||||
|
import TileLayer from '../../../src/ol/layer/Tile.js';
|
||||||
|
import OSM from '../../../src/ol/source/OSM.js';
|
||||||
|
|
||||||
|
const map = new Map({
|
||||||
|
layers: [
|
||||||
|
new TileLayer({
|
||||||
|
source: new OSM()
|
||||||
|
})
|
||||||
|
],
|
||||||
|
target: 'map',
|
||||||
|
view: new View({
|
||||||
|
center: [0, 0],
|
||||||
|
zoom: 1
|
||||||
|
})
|
||||||
|
});
|
||||||
7
site/src/examples/map.md
Normal file
7
site/src/examples/map.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: My First Map
|
||||||
|
shortdesc: Example of a map with a single layer.
|
||||||
|
docs: >
|
||||||
|
A map with an OSM source.
|
||||||
|
---
|
||||||
|
<div id="map"></div>
|
||||||
44
site/src/layouts/index.js
Normal file
44
site/src/layouts/index.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import {func} from 'prop-types';
|
||||||
|
import Link from 'gatsby-link';
|
||||||
|
import React from 'react';
|
||||||
|
import styled from 'react-emotion';
|
||||||
|
|
||||||
|
const Page = styled('div')({
|
||||||
|
margin: '1em auto',
|
||||||
|
maxWidth: '960px'
|
||||||
|
});
|
||||||
|
|
||||||
|
const Header = styled('header')({
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'baseline',
|
||||||
|
padding: '0 2em',
|
||||||
|
marginBottom: '2em',
|
||||||
|
'& h1': {
|
||||||
|
margin: '0 auto 0 0'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const Main = styled('main')({
|
||||||
|
padding: '0 2em'
|
||||||
|
});
|
||||||
|
|
||||||
|
const Layout = ({children}) => (
|
||||||
|
<Page>
|
||||||
|
<Header>
|
||||||
|
<h1>
|
||||||
|
<Link to="/">OpenLayers</Link>
|
||||||
|
</h1>
|
||||||
|
<div>
|
||||||
|
<Link to="/docs/">docs</Link>
|
||||||
|
<Link to="/examples/">examples</Link>
|
||||||
|
</div>
|
||||||
|
</Header>
|
||||||
|
<Main>{children()}</Main>
|
||||||
|
</Page>
|
||||||
|
);
|
||||||
|
|
||||||
|
Layout.propTypes = {
|
||||||
|
children: func.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Layout;
|
||||||
19
site/src/pages/docs.js
Normal file
19
site/src/pages/docs.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import React, {Component, Fragment} from 'react';
|
||||||
|
import Module from '../components/doc/Module';
|
||||||
|
import {getModules} from '../utils/doc';
|
||||||
|
|
||||||
|
import info from '../../../build/info.json';
|
||||||
|
|
||||||
|
const modules = getModules(info);
|
||||||
|
|
||||||
|
class Docs extends Component {
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
{modules.map(mod => <Module key={mod.name} {...mod} />)}
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Docs;
|
||||||
42
site/src/pages/examples.js
Normal file
42
site/src/pages/examples.js
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import React, {Component} from 'react';
|
||||||
|
import {object} from 'prop-types';
|
||||||
|
import Link from 'gatsby-link';
|
||||||
|
|
||||||
|
class Examples extends Component {
|
||||||
|
renderExample({node}) {
|
||||||
|
const context = node.context;
|
||||||
|
return (
|
||||||
|
<li key={node.id}>
|
||||||
|
<Link to={context.slug}>{context.frontmatter.title}</Link>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return <ul>{this.props.data.allSitePage.edges.map(this.renderExample)}</ul>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Examples.propTypes = {
|
||||||
|
data: object.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export const query = graphql`
|
||||||
|
query ExampleList {
|
||||||
|
allSitePage(filter: {pluginCreator: {name: {eq: "examples"}}}) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
id
|
||||||
|
context {
|
||||||
|
slug
|
||||||
|
frontmatter {
|
||||||
|
title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default Examples;
|
||||||
3
site/src/pages/index.js
Normal file
3
site/src/pages/index.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export default () => <p>This is the home page</p>;
|
||||||
111
site/src/utils/doc.js
Normal file
111
site/src/utils/doc.js
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
function getLongModuleName(name) {
|
||||||
|
return name.split(/[~\.]/).shift();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getShortModuleName(longname) {
|
||||||
|
return getLongModuleName(longname).slice(7);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getShortName(longname) {
|
||||||
|
return longname.split(/[~\.]/).pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function slugify(name) {
|
||||||
|
return name.replace(/[#~\.]/g, '-');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getExported(name, exports) {
|
||||||
|
const local = getShortName(name);
|
||||||
|
for (const exported in exports) {
|
||||||
|
if (exports[exported] === local) {
|
||||||
|
return exported;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getModules(info) {
|
||||||
|
const moduleLookup = {};
|
||||||
|
info.modules.forEach(mod => {
|
||||||
|
moduleLookup[mod.name] = {...mod, functions: [], classes: []};
|
||||||
|
});
|
||||||
|
|
||||||
|
// extract classes
|
||||||
|
const classLookup = {};
|
||||||
|
info.symbols.forEach(symbol => {
|
||||||
|
const name = symbol.name;
|
||||||
|
const parent = symbol.memberof;
|
||||||
|
|
||||||
|
if (symbol.kind === 'class') {
|
||||||
|
const mod = moduleLookup[parent];
|
||||||
|
if (!mod) {
|
||||||
|
throw new Error(
|
||||||
|
`No module found for class ${name} with parent ${parent}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const cls = {
|
||||||
|
...symbol,
|
||||||
|
methods: [],
|
||||||
|
properties: [],
|
||||||
|
exported: getExported(name, mod.exports)
|
||||||
|
};
|
||||||
|
|
||||||
|
mod.classes.push(cls);
|
||||||
|
classLookup[name] = cls;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
info.symbols.forEach(symbol => {
|
||||||
|
const name = symbol.name;
|
||||||
|
const parent = symbol.memberof;
|
||||||
|
|
||||||
|
if (symbol.kind === 'member') {
|
||||||
|
if (parent in classLookup) {
|
||||||
|
classLookup[parent].properties.push(symbol);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// instance property where constructor is not marked @api
|
||||||
|
const moduleId = getLongModuleName(name);
|
||||||
|
const mod = moduleLookup[moduleId];
|
||||||
|
if (!mod) {
|
||||||
|
throw new Error(`Unexpected member: ${name}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const cls = {name: parent, methods: [], properties: [symbol]};
|
||||||
|
mod.classes.push(cls);
|
||||||
|
classLookup[parent] = cls;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (symbol.kind === 'function') {
|
||||||
|
if (parent in moduleLookup) {
|
||||||
|
moduleLookup[parent].functions.push({
|
||||||
|
...symbol,
|
||||||
|
exported: getExported(name, moduleLookup[parent].exports)
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parent in classLookup) {
|
||||||
|
classLookup[parent].methods.push(symbol);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// method where constructor is not marked @api
|
||||||
|
const moduleId = getLongModuleName(name);
|
||||||
|
const mod = moduleLookup[moduleId];
|
||||||
|
if (!mod) {
|
||||||
|
throw new Error(`Unexpected function: ${name}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const cls = {name: parent, methods: [symbol], properties: []};
|
||||||
|
mod.classes.push(cls);
|
||||||
|
classLookup[parent] = cls;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return Object.keys(moduleLookup)
|
||||||
|
.sort()
|
||||||
|
.map(id => moduleLookup[id]);
|
||||||
|
}
|
||||||
14
site/src/utils/typography.js
Normal file
14
site/src/utils/typography.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
const Typography = require('typography');
|
||||||
|
const theme = require('typography-theme-noriega').default;
|
||||||
|
const CodePlugin = require('typography-plugin-code').default;
|
||||||
|
|
||||||
|
theme.plugins = [new CodePlugin()];
|
||||||
|
|
||||||
|
theme.overrideThemeStyles = () => ({
|
||||||
|
a: {
|
||||||
|
color: '#003c88',
|
||||||
|
textDecoration: 'none'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = new Typography(theme);
|
||||||
@@ -99,9 +99,6 @@ function parseOutput(output) {
|
|||||||
if (!Array.isArray(info.symbols)) {
|
if (!Array.isArray(info.symbols)) {
|
||||||
throw new Error('Expected symbols array: ' + output);
|
throw new Error('Expected symbols array: ' + output);
|
||||||
}
|
}
|
||||||
if (!Array.isArray(info.defines)) {
|
|
||||||
throw new Error('Expected defines array: ' + output);
|
|
||||||
}
|
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user