From 756b0361e1f4f09d9c6a9eafc39058518718d6bc Mon Sep 17 00:00:00 2001 From: rittels Date: Wed, 7 Jul 2021 15:16:38 +0200 Subject: [PATCH] Formatted everything to singleQuote --- .prettierrc | 5 +- compiler.js | 511 ++++--- dev/mjs2js.js | 228 ++- dev/shimport.js | 1253 ++++++++--------- dev/utils.js | 275 ++-- dev/variables.less | 316 ++--- dist/plugin.js | 121 +- examples/01-hello-world/config.js | 4 +- examples/01-hello-world/plugin.html | 10 +- examples/02-window-on-left-side/config.js | 8 +- examples/02-window-on-left-side/plugin.html | 12 +- examples/02-window-on-left-side/plugin.less | 2 +- examples/03-window-on-right-side/config.js | 8 +- examples/03-window-on-right-side/plugin.html | 8 +- examples/03-window-on-right-side/plugin.less | 2 +- examples/04-boat-tracker/config.js | 4 +- examples/04-boat-tracker/plugin.html | 28 +- examples/05-use-external-library/config.js | 14 +- examples/05-use-external-library/plugin.html | 40 +- examples/05-use-external-library/plugin.less | 4 +- examples/06-weather-picker/config.js | 4 +- examples/06-weather-picker/plugin.html | 16 +- examples/07-multiple-files-plugin/README.md | 6 +- examples/07-multiple-files-plugin/config.js | 14 +- examples/07-multiple-files-plugin/plugin.html | 24 +- examples/07-multiple-files-plugin/plugin.less | 8 +- .../soundingGraph.mjs | 376 ++--- .../soundingUtils.mjs | 60 +- .../08-display-csv-gpx-kml-formats/config.js | 10 +- .../plugin.html | 22 +- .../plugin.less | 2 +- examples/09-reading-weather-values/config.js | 4 +- .../09-reading-weather-values/plugin.html | 34 +- .../config.js | 8 +- .../plugin.html | 14 +- .../plugin.less | 2 +- examples/11-mobile-demo/config.js | 10 +- examples/11-mobile-demo/plugin.html | 58 +- examples/11-mobile-demo/plugin.less | 2 +- 39 files changed, 1760 insertions(+), 1767 deletions(-) diff --git a/.prettierrc b/.prettierrc index 1494570..d4a79a3 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,9 +1,8 @@ { + "singleQuote": true, "trailingComma": "all", "printWidth": 100, "tabWidth": 4, - "arrowParens": "avoid", "useTabs": false, - "svelteSortOrder": "options-markup-scripts-styles", - "svelteBracketNewLine": true + "arrowParens": "avoid" } diff --git a/compiler.js b/compiler.js index 35c70af..7031e81 100755 --- a/compiler.js +++ b/compiler.js @@ -1,264 +1,247 @@ -#!/usr/bin/env node --no-warnings - -/** - * This is plugin building script. Feel free to modify it - * All is MIT licenced - */ -const prog = require('commander'), - { join } = require('path'), - c = require('consola'), - fs = require('fs-extra'), - { yellow, gray } = require('colorette'), - riot = require('riot-compiler'), - assert = require('assert'), - express = require('express'), - app = express(), - less = require('less'), - chokidar = require('chokidar'), - decache = require('decache'), - https = require('https'), - babel = require('@babel/core'); - -const utils = require('./dev/utils.js'); - -const port = 9999; - -const { - version, - name, - author, - repository, - description, -} = require('./package.json'); - -prog.option( - '-b, --build', - 'Build the plugin in required directory (default src)' -) - .option( - '-w, --watch', - 'Build plugin and watch file changes in required directory' - ) - .option('-s, --serve', `Serve dist directory on port ${port}`) - .option('-p, --prompt', 'Show command line promt with all the examples') - .option('-t, --transpile', 'Transpile your code with Babel') - .parse(process.argv); - -if (!process.argv.slice(2).length) { - prog.outputHelp(); - process.exit(); -} - -let config, - srcDir = 'src'; - -// Main -(async () => { - console.log(`\nBuilding ${yellow(name)}, version ${yellow(version)}`); - - // Beginners example selection - if (prog.prompt) { - srcDir = await utils.prompt(); - } - - c.info(`Compiler will compile ${yellow(`./${srcDir}/plugin.html`)}`); - - await reloadConfig(); - - try { - // Basic assertions - assert( - typeof config === 'object', - 'Missing basic config object. Make sure you have valid ' + - 'config.js in src dir' - ); - - assert( - /^windy-plugin-/.test(name), - 'Your repository (and also your published npm package) ' + - 'must be named "windy-plugin-AnyOfYourName".' + - ' Change the name in your package.json' - ); - - // Tasks - if (prog.watch || prog.build) { - await build(); - } - - if (prog.serve) { - await startServer(); - } - - if (prog.watch) { - c.start(`Staring watch on ${ gray( srcDir )} and ${gray('package.json')}. Build 1 sec after change....`) - chokidar.watch([srcDir], - { awaitWriteFinish: { stabilityThreshold:1000, pollInterval:100 }} - ).on('change', onChange ) - } - } catch (e) { - c.error(`Error\u0007`, e); - } -})(); - -function startServer() { - return new Promise(resolve => { - const httpsOptions = { - // https://www.ibm.com/support/knowledgecenter/en/SSWHYP_4.0.0/com.ibm.apimgmt.cmc.doc/task_apionprem_gernerate_self_signed_openSSL.html - key: fs.readFileSync(join(__dirname, 'dev', 'key.pem'), 'utf8'), - cert: fs.readFileSync( - join(__dirname, 'dev', 'certificate.pem'), - 'utf8' - ), - }; - - app.use(express.static('dist')); - - https.createServer(httpsOptions, app).listen(port, () => { - c.success( -`Your plugin is published at - ${gray( "https://localhost:"+port+"/plugin.js" )}. - Use ${yellow('https://www.windy.com/dev')} to test it.\n` - ); - resolve(); - }); - }); -} - -/* This is main build function - - Feel free to to use your own builder, transpiler, minifier or whatever - The result must be a single .js file with single W.loadPlugin() function - - Make sure to replace import XY from '@windy/XY' with W.require(XY) - -*/ -async function build() { - // Riot parser options - const riotOpts = { - entities: true, - compact: false, - expr: true, - type: null, - template: null, - fileConfig: null, - concat: false, - modular: false, - debug: true, - }; - - // Compile less - feel free to code your SCSS here - let css = await compileLess(); - - // Load source code of a plugin - const tagSrc = await fs.readFile(join(srcDir, 'plugin.html'), 'utf8'); - - // Compile it via riot compiler - // See: https://github.com/riot/compiler - const [compiled] = riot.compile(tagSrc, riotOpts); - let { html, js, imports } = compiled; - - const options = Object.assign( - {}, - { - name, - version, - author, - repository, - description, - }, - config - ); - - const internalModules = {}; - - // - // Rewrite imports into W.require - // - if (imports) { - let match, - importsRegEx = /import\s+(\S+)\s+from\s+['"](@windy\/)?(plugins\/)?([^'"']+)['"]/g; - while ((match = importsRegEx.exec(imports)) !== null) { - let [, lex, isCore, isPlugin, module] = match; - // detect syntax "import graph from './soundingGraph.mjs'" - // and loads external module - if (!isCore) { - module = await utils.externalMjs( - srcDir, - internalModules, - module, - name - ); - } - js = `\tconst ${lex} = W.require('${(isPlugin ? '@plugins/' : '') + module}');\n${js}`; - } - } - - // Stringify output - let output = utils.stringifyPlugin(options, html, css, js); - - // Add external modules - for (let ext in internalModules) { - output += `\n\n${internalModules[ext]}`; - } - - // Save plugin to dest directory - const destination = join(__dirname, 'dist', 'plugin.js'); - - // Babel traspile - if (prog.transpile) { - c.info('Transpiling with babel'); - let res = await babel.transformAsync(output, { - presets: ['@babel/preset-env'], - }); // => Promise<{ code, map, ast }> - output = res.code; - } - - await fs.outputFile(destination, output); - - c.success( - `Your plugin ${gray(name)} has been compiled to ${gray(destination)}` - ); -} - -// -// L E S S compiler -// -async function compileLess() { - const lessOptions = { - cleancss: true, - compress: true, - }; - - const lessFile = join(srcDir, 'plugin.less'); - - if (!fs.existsSync(lessFile)) { - return null; - } - - const lessSrc = await fs.readFile(lessFile, 'utf8'); - - let { css } = await less.render(lessSrc, lessOptions); - - return css; -} - -// -// Reload config -// -async function reloadConfig() { - const dir = join(__dirname, srcDir, 'config.js'); - decache(dir); - config = require(dir); - return; -} - -// -// Watch change of file -// -const onChange = async fullPath => { - c.info(`watch: File changed ${gray(fullPath)}`); - - await reloadConfig(); - - await build(); -}; +#!/usr/bin/env node --no-warnings + +/** + * This is plugin building script. Feel free to modify it + * All is MIT licenced + */ +const prog = require('commander'), + { join } = require('path'), + c = require('consola'), + fs = require('fs-extra'), + { yellow, gray } = require('colorette'), + riot = require('riot-compiler'), + assert = require('assert'), + express = require('express'), + app = express(), + less = require('less'), + chokidar = require('chokidar'), + decache = require('decache'), + https = require('https'), + babel = require('@babel/core'); + +const utils = require('./dev/utils.js'); + +const port = 9999; + +const { version, name, author, repository, description } = require('./package.json'); + +prog.option('-b, --build', 'Build the plugin in required directory (default src)') + .option('-w, --watch', 'Build plugin and watch file changes in required directory') + .option('-s, --serve', `Serve dist directory on port ${port}`) + .option('-p, --prompt', 'Show command line promt with all the examples') + .option('-t, --transpile', 'Transpile your code with Babel') + .parse(process.argv); + +if (!process.argv.slice(2).length) { + prog.outputHelp(); + process.exit(); +} + +let config, + srcDir = 'src'; + +// Main +(async () => { + console.log(`\nBuilding ${yellow(name)}, version ${yellow(version)}`); + + // Beginners example selection + if (prog.prompt) { + srcDir = await utils.prompt(); + } + + c.info(`Compiler will compile ${yellow(`./${srcDir}/plugin.html`)}`); + + await reloadConfig(); + + try { + // Basic assertions + assert( + typeof config === 'object', + 'Missing basic config object. Make sure you have valid ' + 'config.js in src dir', + ); + + assert( + /^windy-plugin-/.test(name), + 'Your repository (and also your published npm package) ' + + 'must be named "windy-plugin-AnyOfYourName".' + + ' Change the name in your package.json', + ); + + // Tasks + if (prog.watch || prog.build) { + await build(); + } + + if (prog.serve) { + await startServer(); + } + + if (prog.watch) { + c.start( + `Staring watch on ${gray(srcDir)} and ${gray( + 'package.json', + )}. Build 1 sec after change....`, + ); + chokidar + .watch([srcDir], { + awaitWriteFinish: { stabilityThreshold: 1000, pollInterval: 100 }, + }) + .on('change', onChange); + } + } catch (e) { + c.error(`Error\u0007`, e); + } +})(); + +function startServer() { + return new Promise(resolve => { + const httpsOptions = { + // https://www.ibm.com/support/knowledgecenter/en/SSWHYP_4.0.0/com.ibm.apimgmt.cmc.doc/task_apionprem_gernerate_self_signed_openSSL.html + key: fs.readFileSync(join(__dirname, 'dev', 'key.pem'), 'utf8'), + cert: fs.readFileSync(join(__dirname, 'dev', 'certificate.pem'), 'utf8'), + }; + + app.use(express.static('dist')); + + https.createServer(httpsOptions, app).listen(port, () => { + c.success( + `Your plugin is published at + ${gray('https://localhost:' + port + '/plugin.js')}. + Use ${yellow('https://www.windy.com/dev')} to test it.\n`, + ); + resolve(); + }); + }); +} + +/* This is main build function + + Feel free to to use your own builder, transpiler, minifier or whatever + The result must be a single .js file with single W.loadPlugin() function + + Make sure to replace import XY from '@windy/XY' with W.require(XY) + +*/ +async function build() { + // Riot parser options + const riotOpts = { + entities: true, + compact: false, + expr: true, + type: null, + template: null, + fileConfig: null, + concat: false, + modular: false, + debug: true, + }; + + // Compile less - feel free to code your SCSS here + let css = await compileLess(); + + // Load source code of a plugin + const tagSrc = await fs.readFile(join(srcDir, 'plugin.html'), 'utf8'); + + // Compile it via riot compiler + // See: https://github.com/riot/compiler + const [compiled] = riot.compile(tagSrc, riotOpts); + let { html, js, imports } = compiled; + + const options = Object.assign( + {}, + { + name, + version, + author, + repository, + description, + }, + config, + ); + + const internalModules = {}; + + // + // Rewrite imports into W.require + // + if (imports) { + let match, + importsRegEx = /import\s+(\S+)\s+from\s+['"](@windy\/)?(plugins\/)?([^'"']+)['"]/g; + while ((match = importsRegEx.exec(imports)) !== null) { + let [, lex, isCore, isPlugin, module] = match; + // detect syntax "import graph from './soundingGraph.mjs'" + // and loads external module + if (!isCore) { + module = await utils.externalMjs(srcDir, internalModules, module, name); + } + js = `\tconst ${lex} = W.require('${(isPlugin ? '@plugins/' : '') + module}');\n${js}`; + } + } + + // Stringify output + let output = utils.stringifyPlugin(options, html, css, js); + + // Add external modules + for (let ext in internalModules) { + output += `\n\n${internalModules[ext]}`; + } + + // Save plugin to dest directory + const destination = join(__dirname, 'dist', 'plugin.js'); + + // Babel traspile + if (prog.transpile) { + c.info('Transpiling with babel'); + let res = await babel.transformAsync(output, { + presets: ['@babel/preset-env'], + }); // => Promise<{ code, map, ast }> + output = res.code; + } + + await fs.outputFile(destination, output); + + c.success(`Your plugin ${gray(name)} has been compiled to ${gray(destination)}`); +} + +// +// L E S S compiler +// +async function compileLess() { + const lessOptions = { + cleancss: true, + compress: true, + }; + + const lessFile = join(srcDir, 'plugin.less'); + + if (!fs.existsSync(lessFile)) { + return null; + } + + const lessSrc = await fs.readFile(lessFile, 'utf8'); + + let { css } = await less.render(lessSrc, lessOptions); + + return css; +} + +// +// Reload config +// +async function reloadConfig() { + const dir = join(__dirname, srcDir, 'config.js'); + decache(dir); + config = require(dir); + return; +} + +// +// Watch change of file +// +const onChange = async fullPath => { + c.info(`watch: File changed ${gray(fullPath)}`); + + await reloadConfig(); + + await build(); +}; diff --git a/dev/mjs2js.js b/dev/mjs2js.js index 4eb22c0..c631c04 100644 --- a/dev/mjs2js.js +++ b/dev/mjs2js.js @@ -1,118 +1,110 @@ -// .mjs -> es6 -> native js -const fs = require('fs-extra'), - { find } = require('./shimport'); - -// Replaces all imports, exports in a file -module.exports = async (fullPath, moduleId, namespace) => { - const body = await fs.readFile(fullPath, 'utf8'), - transformed = transform(fullPath, body, moduleId, namespace); - - return transformed; -}; - -const transform = (file, source, id, namespace) => { - const [importDeclarations, importStatements, exportDeclarations] = find( - source - ); - - var nameBySource = new Map(); - - const externalModules = []; - - importDeclarations.forEach(d => { - if (nameBySource.has(d.source)) { - return; - } - - if (/@windy\//.test(d.source)) { - // Windy's core module - - d.source = d.source.replace(/@windy\/(\S+)/, '$1'); - - if (/plugins\//.test(d.source)) { - d.source = "@" + d.source; - } - - } else if (/\.\/\S+\.mjs/.test(d.source)) { - // Plugin's module - - externalModules.push(d.source); - - d.source = `${namespace}/${d.source.replace( - /\.\/(\S+)\.mjs/, - '$1' - )}`; - } else if ( !/@plugins\//.test(d.source) ) { // "@plugins/xyz" is allowed - throw new Error( - 'Unable to import module. Windy plugin compiler is primitive and' + - ' supports only "@windy/name", or "./filename.mjs" modules' - ); - } - - nameBySource.set(d.source, d.name || '__dep_' + nameBySource.size); - }); - - exportDeclarations.forEach(d => { - if (!d.source) { - return; - } - - if (nameBySource.has(d.source)) { - return; - } - - if (d.name) { - throw new Error( - `mjs2js: Named exports are not supported in ${file}` - ); - } - - nameBySource.set(d.source, d.name || '__dep_' + nameBySource.size); - }); - - var deps = Array.from(nameBySource.keys()) - .map(s => `'${s}'`) - .join(', '); - - var names = Array.from(nameBySource.values()).join(', '); - - var transformed = `/*! */ -// This page was transpiled automatically from ${file} -W.define('${id}', [${deps}], - function(__exports, ${names}) { -`; - - var ranges = importDeclarations - .concat(importStatements, exportDeclarations) - .sort((a, b) => a.start - b.start); - - var c = 0; - - for (var i = 0; i < ranges.length; i += 1) { - var range = ranges[i]; - - transformed += source.slice(c, range.start); - - if (!(range.name && range.source)) { - transformed += range.toString(nameBySource); - } - - // remove trailing \n - transformed = transformed.replace(/\n$/, ''); - - c = range.end; - } - - transformed += source.slice(c); - - - //import like this: import name from "./xyz.mjs" if using: export default whatever; - //or import {name1, name2:yourname} from "./xyz.mjs" if using: export {name1, name2}; - //cannot use default and named exports - - //transformed = transformed.replace('__exports.default =', '\treturn '); //this line removed - - transformed += '\n});\n'; - - return { externalModules, transformed }; -}; +// .mjs -> es6 -> native js +const fs = require('fs-extra'), + { find } = require('./shimport'); + +// Replaces all imports, exports in a file +module.exports = async (fullPath, moduleId, namespace) => { + const body = await fs.readFile(fullPath, 'utf8'), + transformed = transform(fullPath, body, moduleId, namespace); + + return transformed; +}; + +const transform = (file, source, id, namespace) => { + const [importDeclarations, importStatements, exportDeclarations] = find(source); + + var nameBySource = new Map(); + + const externalModules = []; + + importDeclarations.forEach(d => { + if (nameBySource.has(d.source)) { + return; + } + + if (/@windy\//.test(d.source)) { + // Windy's core module + + d.source = d.source.replace(/@windy\/(\S+)/, '$1'); + + if (/plugins\//.test(d.source)) { + d.source = '@' + d.source; + } + } else if (/\.\/\S+\.mjs/.test(d.source)) { + // Plugin's module + + externalModules.push(d.source); + + d.source = `${namespace}/${d.source.replace(/\.\/(\S+)\.mjs/, '$1')}`; + } else if (!/@plugins\//.test(d.source)) { + // "@plugins/xyz" is allowed + throw new Error( + 'Unable to import module. Windy plugin compiler is primitive and' + + ' supports only "@windy/name", or "./filename.mjs" modules', + ); + } + + nameBySource.set(d.source, d.name || '__dep_' + nameBySource.size); + }); + + exportDeclarations.forEach(d => { + if (!d.source) { + return; + } + + if (nameBySource.has(d.source)) { + return; + } + + if (d.name) { + throw new Error(`mjs2js: Named exports are not supported in ${file}`); + } + + nameBySource.set(d.source, d.name || '__dep_' + nameBySource.size); + }); + + var deps = Array.from(nameBySource.keys()) + .map(s => `'${s}'`) + .join(', '); + + var names = Array.from(nameBySource.values()).join(', '); + + var transformed = `/*! */ +// This page was transpiled automatically from ${file} +W.define('${id}', [${deps}], + function(__exports, ${names}) { +`; + + var ranges = importDeclarations + .concat(importStatements, exportDeclarations) + .sort((a, b) => a.start - b.start); + + var c = 0; + + for (var i = 0; i < ranges.length; i += 1) { + var range = ranges[i]; + + transformed += source.slice(c, range.start); + + if (!(range.name && range.source)) { + transformed += range.toString(nameBySource); + } + + // remove trailing \n + transformed = transformed.replace(/\n$/, ''); + + c = range.end; + } + + transformed += source.slice(c); + + //import like this: import name from "./xyz.mjs" if using: export default whatever; + //or import {name1, name2:yourname} from "./xyz.mjs" if using: export {name1, name2}; + //cannot use default and named exports + + //transformed = transformed.replace('__exports.default =', '\treturn '); //this line removed + + transformed += '\n});\n'; + + return { externalModules, transformed }; +}; diff --git a/dev/shimport.js b/dev/shimport.js index 9c70c84..87e6ba3 100644 --- a/dev/shimport.js +++ b/dev/shimport.js @@ -1,648 +1,605 @@ -'use strict'; - -Object.defineProperty(exports, '__esModule', { value: true }); - -function get_alias(specifiers, name) { - var i = specifiers.length; - while (i--) { - if (specifiers[i].name === name) { - return specifiers[i].as; - } - } -} -function importDecl(str, start, end, specifiers, source) { - var name = get_alias(specifiers, '*') || get_alias(specifiers, 'default'); - return { - start: start, - end: end, - source: source, - name: name, - toString: function(nameBySource) { - var name = nameBySource.get(source); - var assignments = specifiers - .sort(function(a, b) { - if (a.name === 'default') { - return 1; - } - if (b.name === 'default') { - return -1; - } - }) - .map(function(s) { - if (s.name === '*') { - return null; - } - if (s.name === 'default' && s.as === name) { - return s.as + ' = ' + name + '.default;'; - } - return 'var ' + s.as + ' = ' + name + '.' + s.name + ';'; - }); - return ( - assignments.join(' ') + - ' /*' + - str.slice(start, end) + - '*/' - ).trim(); - }, - }; -} -function exportDefaultDeclaration(str, start, end) { - while (/\S/.test(str[end])) { - end += 1; - } - return { - start: start, - end: end, - toString: function() { - return '__exports.default ='; - }, - }; -} -function exportSpecifiersDeclaration( - str, - start, - specifiersStart, - specifiersEnd, - end, - source -) { - var specifiers = processSpecifiers( - str.slice(specifiersStart + 1, specifiersEnd - 1).trim() - ); - return { - start: start, - end: end, - source: source, - toString: function(nameBySource) { - var name = nameBySource.get(source); - return ( - specifiers - .map(function(s) { - return ( - '__exports.' + - s.as + - ' = ' + - (name ? name + '.' + s.name : s.name) + - '; ' - ); - }) - .join('') + - ('/*' + str.slice(start, end) + '*/') - ); - }, - }; -} -function exportDecl(str, start, c) { - var end = c; - while (str[c] && /\S/.test(str[c])) { - c += 1; - } - while (str[c] && !/\S/.test(str[c])) { - c += 1; - } - var nameStart = c; - while (str[c] && !punctuatorChars.test(str[c]) && !isWhitespace(str[c])) { - c += 1; - } - var nameEnd = c; - var name = str.slice(nameStart, nameEnd); - return { - start: start, - end: end, - name: name, - toString: function() { - return ''; - }, - }; -} -function exportStarDeclaration(str, start, end, source) { - return { - start: start, - end: end, - source: source, - toString: function(nameBySource) { - return ( - 'Object.assign(__exports, ' + - nameBySource.get(source) + - '); /*' + - str.slice(start, end) + - '*/' - ); - }, - }; -} -var keywords = /\b(case|default|delete|do|else|in|instanceof|new|return|throw|typeof|void)\s*$/; -var punctuators = /(^|\{|\(|\[\.|;|,|<|>|<=|>=|==|!=|===|!==|\+|-|\*%|<<|>>|>>>|&|\||^|!|~|&&|\|\||\?|:|=|\+=|-=|\*=|%=|<<=|>>=|>>>=|&=|\|=|^=|\/=|\/)\s*$/; -var ambiguous = /(\}|\)|\+\+|--)\s*$/; -var punctuatorChars = /[{}()[.;,<>=+\-*%&|^!~?:/]/; -var keywordChars = /[a-z]/; -var whitespace_obj = { - ' ': 1, - '\t': 1, - '\n': 1, - '\r': 1, - '\f': 1, - '\v': 1, - '\u00A0': 1, - '\u2028': 1, - '\u2029': 1, -}; -function isWhitespace(char) { - // this is faster than testing a regex - return char in whitespace_obj; -} -function isQuote(char) { - return char === "'" || char === '"'; -} -var namespaceImport = /^\*\s+as\s+(\w+)$/; -var defaultAndStarImport = /(\w+)\s*,\s*\*\s*as\s*(\w+)$/; -var defaultAndNamedImport = /(\w+)\s*,\s*{(.+)}$/; -function processImportSpecifiers(str) { - var match = namespaceImport.exec(str); - if (match) { - return [{ name: '*', as: match[1] }]; - } - match = defaultAndStarImport.exec(str); - if (match) { - return [{ name: 'default', as: match[1] }, { name: '*', as: match[2] }]; - } - match = defaultAndNamedImport.exec(str); - if (match) { - return [{ name: 'default', as: match[1] }].concat( - processSpecifiers(match[2].trim()) - ); - } - if (str[0] === '{') { - return processSpecifiers(str.slice(1, -1).trim()); - } - if (str) { - return [{ name: 'default', as: str }]; - } - return []; -} -function processSpecifiers(str) { - return str - ? str.split(',').map(function(part) { - var _a = part.trim().split(/[^\S]+/), - name = _a[0], - as = _a[2]; - return { name: name, as: as || name }; - }) - : []; -} -function getImportDeclaration(str, i) { - var start = i; - var specifierStart = (i += 6); - while (str[i] && isWhitespace(str[i])) { - i += 1; - } - while (str[i] && !isQuote(str[i])) { - i += 1; - } - var specifierEnd = i; - var sourceStart = (i += 1); - while (str[i] && !isQuote(str[i])) { - i += 1; - } - var sourceEnd = i++; - return importDecl( - str, - start, - i, - processImportSpecifiers( - str - .slice(specifierStart, specifierEnd) - .replace(/from\s*$/, '') - .trim() - ), - str.slice(sourceStart, sourceEnd) - ); -} -function getImportStatement(i) { - return { - start: i, - end: i + 6, - toString: function() { - return '__import'; - }, - }; -} -function getExportDeclaration(str, i) { - var start = i; - i += 6; - while (str[i] && isWhitespace(str[i])) { - i += 1; - } - var declarationStart = i; - if (str[i] === '{') { - while (str[i] !== '}') { - i += 1; - } - i += 1; - var specifiersEnd = i; - var source = null; - while (isWhitespace(str[i])) { - i += 1; - } - if (/^from[\s\n]/.test(str.slice(i, i + 5))) { - i += 5; - while (str[i] && !isQuote(str[i])) { - i += 1; - } - var sourceStart = (i += 1); - while (str[i] && !isQuote(str[i])) { - i += 1; - } - source = str.slice(sourceStart, i); - i += 1; - } - return exportSpecifiersDeclaration( - str, - start, - declarationStart, - specifiersEnd, - i, - source - ); - } - if (str[i] === '*') { - i += 1; - while (isWhitespace(str[i])) { - i += 1; - } - i += 4; - while (str[i] && !isQuote(str[i])) { - i += 1; - } - var sourceStart = (i += 1); - while (str[i] && !isQuote(str[i])) { - i += 1; - } - var sourceEnd = i++; - return exportStarDeclaration( - str, - start, - i, - str.slice(sourceStart, sourceEnd) - ); - } - if (/default[\s\n]/.test(str.slice(i, i + 8))) { - return exportDefaultDeclaration(str, start, declarationStart); - } - return exportDecl(str, start, declarationStart); -} -function find(str) { - var escapedFrom; - var regexEnabled = true; - var pfixOp = false; - var stack = []; - var lsci = -1; // last significant character index - var lsc = function() { - return str[lsci]; - }; - var parenMatches = {}; - var openingParenPositions = {}; - var parenDepth = 0; - var importDeclarations = []; - var importStatements = []; - var exportDeclarations = []; - function tokenClosesExpression() { - if (lsc() === ')') { - var c = parenMatches[lsci]; - while (isWhitespace(str[c - 1])) { - c -= 1; - } - // if parenthesized expression is immediately preceded by `if`/`while`, it's not closing an expression - return !/(if|while)$/.test(str.slice(c - 5, c)); - } - // TODO handle }, ++ and -- tokens immediately followed by / character - return true; - } - var base = { - pattern: /(?:(\()|(\))|({)|(})|(")|(')|(\/\/)|(\/\*)|(\/)|(`)|(import)|(export)|(\+\+|--))/g, - handlers: [ - // ( - function(i) { - lsci = i; - openingParenPositions[parenDepth++] = i; - }, - // ) - function(i) { - lsci = i; - parenMatches[i] = openingParenPositions[--parenDepth]; - }, - // { - function(i) { - lsci = i; - stack.push(base); - }, - // } - function(i) { - lsci = i; - return stack.pop(); - }, - // " - function(i) { - stack.push(base); - return double_quoted; - }, - // ' - function(i) { - stack.push(base); - return single_quoted; - }, - // // - function(i) { - return line_comment; - }, - // /* - function(i) { - return block_comment; - }, - // / - function(i) { - // could be start of regex literal OR division punctuator. Solution via - // http://stackoverflow.com/questions/5519596/when-parsing-javascript-what-determines-the-meaning-of-a-slash/27120110#27120110 - var b = i; - while (b > 0 && isWhitespace(str[b - 1])) { - b -= 1; - } - if (b > 0) { - var a = b; - if (punctuatorChars.test(str[a - 1])) { - while (a > 0 && punctuatorChars.test(str[a - 1])) { - a -= 1; - } - } else { - while (a > 0 && keywordChars.test(str[a - 1])) { - a -= 1; - } - } - var token = str.slice(a, b); - regexEnabled = token - ? keywords.test(token) || - punctuators.test(token) || - (ambiguous.test(token) && !tokenClosesExpression()) - : false; - } else { - regexEnabled = true; - } - return slash; - }, - // ` - function(i) { - return template_string; - }, - // import - function(i) { - if ( - i === 0 || - isWhitespace(str[i - 1]) || - punctuatorChars.test(str[i - 1]) - ) { - if (/import[\s\n{"']/.test(str.slice(i, i + 7))) { - var d = getImportDeclaration(str, i); - importDeclarations.push(d); - p = d.end; - } else if (str.slice(i, i + 7) === 'import(') { - var s = getImportStatement(i); - importStatements.push(s); - p = s.end; - } - } - }, - // export - function(i) { - if ( - i === 0 || - isWhitespace(str[i - 1]) || - punctuatorChars.test(str[i - 1]) - ) { - if (/export[\s\n{]/.test(str.slice(i, i + 7))) { - var d = getExportDeclaration(str, i); - exportDeclarations.push(d); - p = d.end; - } - } - }, - // ++/-- - function(i) { - pfixOp = !pfixOp && str[i - 1] === '+'; - }, - ], - }; - var slash = { - pattern: /(?:(\[)|(\\)|(.))/g, - handlers: [ - // [ - function(i) { - return regexEnabled ? regex_character : base; - }, - // \\ - function(i) { - return (escapedFrom = regex), escaped; - }, - // anything else - function(i) { - return regexEnabled && !pfixOp ? regex : base; - }, - ], - }; - var regex = { - pattern: /(?:(\[)|(\\)|(\/))/g, - handlers: [ - // [ - function() { - return regex_character; - }, - // \\ - function() { - return (escapedFrom = regex), escaped; - }, - // / - function() { - return base; - }, - ], - }; - var regex_character = { - pattern: /(?:(\])|(\\))/g, - handlers: [ - // ] - function() { - return regex; - }, - // \\ - function() { - return (escapedFrom = regex_character), escaped; - }, - ], - }; - var double_quoted = { - pattern: /(?:(\\)|("))/g, - handlers: [ - // \\ - function() { - return (escapedFrom = double_quoted), escaped; - }, - // " - function() { - return stack.pop(); - }, - ], - }; - var single_quoted = { - pattern: /(?:(\\)|('))/g, - handlers: [ - // \\ - function() { - return (escapedFrom = single_quoted), escaped; - }, - // ' - function() { - return stack.pop(); - }, - ], - }; - var escaped = { - pattern: /(.)/g, - handlers: [ - function() { - return escapedFrom; - }, - ], - }; - var template_string = { - pattern: /(?:(\$)|(\\)|(`))/g, - handlers: [ - // $ - function() { - return template_string_dollar; - }, - // \\ - function() { - return (escapedFrom = template_string), escaped; - }, - // ` - function() { - return base; - }, - ], - }; - var template_string_dollar = { - pattern: /({)/g, - handlers: [ - // { - function() { - stack.push(template_string); - return base; - }, - function() { - return template_string; - }, - ], - }; - var line_comment = { - pattern: /((?:\n|$))/g, - handlers: [ - // \n - function() { - return base; - }, - ], - }; - var block_comment = { - pattern: /(\*\/)/g, - handlers: [ - // \n - function() { - return base; - }, - ], - }; - var state = base; - var p = 0; - while (p < str.length) { - state.pattern.lastIndex = p; - var match = state.pattern.exec(str); - if (!match) { - if (stack.length > 0 || state !== base) { - console.error('Sshimport: Unexpecgted end of file'); - //throw new Error("Unexpected end of file"); - } - break; - } - p = match.index + match[0].length; - for (var j = 1; j < match.length; j += 1) { - if (match[j]) { - state = state.handlers[j - 1](match.index) || state; - break; - } - } - } - return [importDeclarations, importStatements, exportDeclarations]; -} -function transform(source, id) { - var _a = find(source), - importDeclarations = _a[0], - importStatements = _a[1], - exportDeclarations = _a[2]; - var nameBySource = new Map(); - importDeclarations.forEach(function(d) { - if (nameBySource.has(d.source)) { - return; - } - nameBySource.set(d.source, d.name || '__dep_' + nameBySource.size); - }); - exportDeclarations.forEach(function(d) { - if (!d.source) { - return; - } - if (nameBySource.has(d.source)) { - return; - } - nameBySource.set(d.source, d.name || '__dep_' + nameBySource.size); - }); - var deps = Array.from(nameBySource.keys()) - .map(function(s) { - return "'" + s + "'"; - }) - .join(', '); - var names = ['__import', '__exports'] - .concat(Array.from(nameBySource.values())) - .join(', '); - var transformed = - "__shimport__.define('" + - id + - "', [" + - deps + - '], function(' + - names + - '){ '; - var ranges = importDeclarations - .concat(importStatements, exportDeclarations) - .sort(function(a, b) { - return a.start - b.start; - }); - var c = 0; - for (var i = 0; i < ranges.length; i += 1) { - var range = ranges[i]; - transformed += - source.slice(c, range.start) + range.toString(nameBySource); - c = range.end; - } - transformed += source.slice(c); - exportDeclarations.forEach(function(d) { - if (d.name) { - transformed += '\n__exports.' + d.name + ' = ' + d.name + ';'; - } - }); - transformed += '\n});\n//# sourceURL=' + id; - return transformed; -} - -var VERSION = '0.0.12'; - -exports.transform = transform; -exports.find = find; -exports.VERSION = VERSION; +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +function get_alias(specifiers, name) { + var i = specifiers.length; + while (i--) { + if (specifiers[i].name === name) { + return specifiers[i].as; + } + } +} +function importDecl(str, start, end, specifiers, source) { + var name = get_alias(specifiers, '*') || get_alias(specifiers, 'default'); + return { + start: start, + end: end, + source: source, + name: name, + toString: function(nameBySource) { + var name = nameBySource.get(source); + var assignments = specifiers + .sort(function(a, b) { + if (a.name === 'default') { + return 1; + } + if (b.name === 'default') { + return -1; + } + }) + .map(function(s) { + if (s.name === '*') { + return null; + } + if (s.name === 'default' && s.as === name) { + return s.as + ' = ' + name + '.default;'; + } + return 'var ' + s.as + ' = ' + name + '.' + s.name + ';'; + }); + return (assignments.join(' ') + ' /*' + str.slice(start, end) + '*/').trim(); + }, + }; +} +function exportDefaultDeclaration(str, start, end) { + while (/\S/.test(str[end])) { + end += 1; + } + return { + start: start, + end: end, + toString: function() { + return '__exports.default ='; + }, + }; +} +function exportSpecifiersDeclaration(str, start, specifiersStart, specifiersEnd, end, source) { + var specifiers = processSpecifiers(str.slice(specifiersStart + 1, specifiersEnd - 1).trim()); + return { + start: start, + end: end, + source: source, + toString: function(nameBySource) { + var name = nameBySource.get(source); + return ( + specifiers + .map(function(s) { + return ( + '__exports.' + + s.as + + ' = ' + + (name ? name + '.' + s.name : s.name) + + '; ' + ); + }) + .join('') + + ('/*' + str.slice(start, end) + '*/') + ); + }, + }; +} +function exportDecl(str, start, c) { + var end = c; + while (str[c] && /\S/.test(str[c])) { + c += 1; + } + while (str[c] && !/\S/.test(str[c])) { + c += 1; + } + var nameStart = c; + while (str[c] && !punctuatorChars.test(str[c]) && !isWhitespace(str[c])) { + c += 1; + } + var nameEnd = c; + var name = str.slice(nameStart, nameEnd); + return { + start: start, + end: end, + name: name, + toString: function() { + return ''; + }, + }; +} +function exportStarDeclaration(str, start, end, source) { + return { + start: start, + end: end, + source: source, + toString: function(nameBySource) { + return ( + 'Object.assign(__exports, ' + + nameBySource.get(source) + + '); /*' + + str.slice(start, end) + + '*/' + ); + }, + }; +} +var keywords = /\b(case|default|delete|do|else|in|instanceof|new|return|throw|typeof|void)\s*$/; +var punctuators = /(^|\{|\(|\[\.|;|,|<|>|<=|>=|==|!=|===|!==|\+|-|\*%|<<|>>|>>>|&|\||^|!|~|&&|\|\||\?|:|=|\+=|-=|\*=|%=|<<=|>>=|>>>=|&=|\|=|^=|\/=|\/)\s*$/; +var ambiguous = /(\}|\)|\+\+|--)\s*$/; +var punctuatorChars = /[{}()[.;,<>=+\-*%&|^!~?:/]/; +var keywordChars = /[a-z]/; +var whitespace_obj = { + ' ': 1, + '\t': 1, + '\n': 1, + '\r': 1, + '\f': 1, + '\v': 1, + '\u00A0': 1, + '\u2028': 1, + '\u2029': 1, +}; +function isWhitespace(char) { + // this is faster than testing a regex + return char in whitespace_obj; +} +function isQuote(char) { + return char === "'" || char === '"'; +} +var namespaceImport = /^\*\s+as\s+(\w+)$/; +var defaultAndStarImport = /(\w+)\s*,\s*\*\s*as\s*(\w+)$/; +var defaultAndNamedImport = /(\w+)\s*,\s*{(.+)}$/; +function processImportSpecifiers(str) { + var match = namespaceImport.exec(str); + if (match) { + return [{ name: '*', as: match[1] }]; + } + match = defaultAndStarImport.exec(str); + if (match) { + return [ + { name: 'default', as: match[1] }, + { name: '*', as: match[2] }, + ]; + } + match = defaultAndNamedImport.exec(str); + if (match) { + return [{ name: 'default', as: match[1] }].concat(processSpecifiers(match[2].trim())); + } + if (str[0] === '{') { + return processSpecifiers(str.slice(1, -1).trim()); + } + if (str) { + return [{ name: 'default', as: str }]; + } + return []; +} +function processSpecifiers(str) { + return str + ? str.split(',').map(function(part) { + var _a = part.trim().split(/[^\S]+/), + name = _a[0], + as = _a[2]; + return { name: name, as: as || name }; + }) + : []; +} +function getImportDeclaration(str, i) { + var start = i; + var specifierStart = (i += 6); + while (str[i] && isWhitespace(str[i])) { + i += 1; + } + while (str[i] && !isQuote(str[i])) { + i += 1; + } + var specifierEnd = i; + var sourceStart = (i += 1); + while (str[i] && !isQuote(str[i])) { + i += 1; + } + var sourceEnd = i++; + return importDecl( + str, + start, + i, + processImportSpecifiers( + str + .slice(specifierStart, specifierEnd) + .replace(/from\s*$/, '') + .trim(), + ), + str.slice(sourceStart, sourceEnd), + ); +} +function getImportStatement(i) { + return { + start: i, + end: i + 6, + toString: function() { + return '__import'; + }, + }; +} +function getExportDeclaration(str, i) { + var start = i; + i += 6; + while (str[i] && isWhitespace(str[i])) { + i += 1; + } + var declarationStart = i; + if (str[i] === '{') { + while (str[i] !== '}') { + i += 1; + } + i += 1; + var specifiersEnd = i; + var source = null; + while (isWhitespace(str[i])) { + i += 1; + } + if (/^from[\s\n]/.test(str.slice(i, i + 5))) { + i += 5; + while (str[i] && !isQuote(str[i])) { + i += 1; + } + var sourceStart = (i += 1); + while (str[i] && !isQuote(str[i])) { + i += 1; + } + source = str.slice(sourceStart, i); + i += 1; + } + return exportSpecifiersDeclaration(str, start, declarationStart, specifiersEnd, i, source); + } + if (str[i] === '*') { + i += 1; + while (isWhitespace(str[i])) { + i += 1; + } + i += 4; + while (str[i] && !isQuote(str[i])) { + i += 1; + } + var sourceStart = (i += 1); + while (str[i] && !isQuote(str[i])) { + i += 1; + } + var sourceEnd = i++; + return exportStarDeclaration(str, start, i, str.slice(sourceStart, sourceEnd)); + } + if (/default[\s\n]/.test(str.slice(i, i + 8))) { + return exportDefaultDeclaration(str, start, declarationStart); + } + return exportDecl(str, start, declarationStart); +} +function find(str) { + var escapedFrom; + var regexEnabled = true; + var pfixOp = false; + var stack = []; + var lsci = -1; // last significant character index + var lsc = function() { + return str[lsci]; + }; + var parenMatches = {}; + var openingParenPositions = {}; + var parenDepth = 0; + var importDeclarations = []; + var importStatements = []; + var exportDeclarations = []; + function tokenClosesExpression() { + if (lsc() === ')') { + var c = parenMatches[lsci]; + while (isWhitespace(str[c - 1])) { + c -= 1; + } + // if parenthesized expression is immediately preceded by `if`/`while`, it's not closing an expression + return !/(if|while)$/.test(str.slice(c - 5, c)); + } + // TODO handle }, ++ and -- tokens immediately followed by / character + return true; + } + var base = { + pattern: /(?:(\()|(\))|({)|(})|(")|(')|(\/\/)|(\/\*)|(\/)|(`)|(import)|(export)|(\+\+|--))/g, + handlers: [ + // ( + function(i) { + lsci = i; + openingParenPositions[parenDepth++] = i; + }, + // ) + function(i) { + lsci = i; + parenMatches[i] = openingParenPositions[--parenDepth]; + }, + // { + function(i) { + lsci = i; + stack.push(base); + }, + // } + function(i) { + lsci = i; + return stack.pop(); + }, + // " + function(i) { + stack.push(base); + return double_quoted; + }, + // ' + function(i) { + stack.push(base); + return single_quoted; + }, + // // + function(i) { + return line_comment; + }, + // /* + function(i) { + return block_comment; + }, + // / + function(i) { + // could be start of regex literal OR division punctuator. Solution via + // http://stackoverflow.com/questions/5519596/when-parsing-javascript-what-determines-the-meaning-of-a-slash/27120110#27120110 + var b = i; + while (b > 0 && isWhitespace(str[b - 1])) { + b -= 1; + } + if (b > 0) { + var a = b; + if (punctuatorChars.test(str[a - 1])) { + while (a > 0 && punctuatorChars.test(str[a - 1])) { + a -= 1; + } + } else { + while (a > 0 && keywordChars.test(str[a - 1])) { + a -= 1; + } + } + var token = str.slice(a, b); + regexEnabled = token + ? keywords.test(token) || + punctuators.test(token) || + (ambiguous.test(token) && !tokenClosesExpression()) + : false; + } else { + regexEnabled = true; + } + return slash; + }, + // ` + function(i) { + return template_string; + }, + // import + function(i) { + if (i === 0 || isWhitespace(str[i - 1]) || punctuatorChars.test(str[i - 1])) { + if (/import[\s\n{"']/.test(str.slice(i, i + 7))) { + var d = getImportDeclaration(str, i); + importDeclarations.push(d); + p = d.end; + } else if (str.slice(i, i + 7) === 'import(') { + var s = getImportStatement(i); + importStatements.push(s); + p = s.end; + } + } + }, + // export + function(i) { + if (i === 0 || isWhitespace(str[i - 1]) || punctuatorChars.test(str[i - 1])) { + if (/export[\s\n{]/.test(str.slice(i, i + 7))) { + var d = getExportDeclaration(str, i); + exportDeclarations.push(d); + p = d.end; + } + } + }, + // ++/-- + function(i) { + pfixOp = !pfixOp && str[i - 1] === '+'; + }, + ], + }; + var slash = { + pattern: /(?:(\[)|(\\)|(.))/g, + handlers: [ + // [ + function(i) { + return regexEnabled ? regex_character : base; + }, + // \\ + function(i) { + return (escapedFrom = regex), escaped; + }, + // anything else + function(i) { + return regexEnabled && !pfixOp ? regex : base; + }, + ], + }; + var regex = { + pattern: /(?:(\[)|(\\)|(\/))/g, + handlers: [ + // [ + function() { + return regex_character; + }, + // \\ + function() { + return (escapedFrom = regex), escaped; + }, + // / + function() { + return base; + }, + ], + }; + var regex_character = { + pattern: /(?:(\])|(\\))/g, + handlers: [ + // ] + function() { + return regex; + }, + // \\ + function() { + return (escapedFrom = regex_character), escaped; + }, + ], + }; + var double_quoted = { + pattern: /(?:(\\)|("))/g, + handlers: [ + // \\ + function() { + return (escapedFrom = double_quoted), escaped; + }, + // " + function() { + return stack.pop(); + }, + ], + }; + var single_quoted = { + pattern: /(?:(\\)|('))/g, + handlers: [ + // \\ + function() { + return (escapedFrom = single_quoted), escaped; + }, + // ' + function() { + return stack.pop(); + }, + ], + }; + var escaped = { + pattern: /(.)/g, + handlers: [ + function() { + return escapedFrom; + }, + ], + }; + var template_string = { + pattern: /(?:(\$)|(\\)|(`))/g, + handlers: [ + // $ + function() { + return template_string_dollar; + }, + // \\ + function() { + return (escapedFrom = template_string), escaped; + }, + // ` + function() { + return base; + }, + ], + }; + var template_string_dollar = { + pattern: /({)/g, + handlers: [ + // { + function() { + stack.push(template_string); + return base; + }, + function() { + return template_string; + }, + ], + }; + var line_comment = { + pattern: /((?:\n|$))/g, + handlers: [ + // \n + function() { + return base; + }, + ], + }; + var block_comment = { + pattern: /(\*\/)/g, + handlers: [ + // \n + function() { + return base; + }, + ], + }; + var state = base; + var p = 0; + while (p < str.length) { + state.pattern.lastIndex = p; + var match = state.pattern.exec(str); + if (!match) { + if (stack.length > 0 || state !== base) { + console.error('Sshimport: Unexpecgted end of file'); + //throw new Error("Unexpected end of file"); + } + break; + } + p = match.index + match[0].length; + for (var j = 1; j < match.length; j += 1) { + if (match[j]) { + state = state.handlers[j - 1](match.index) || state; + break; + } + } + } + return [importDeclarations, importStatements, exportDeclarations]; +} +function transform(source, id) { + var _a = find(source), + importDeclarations = _a[0], + importStatements = _a[1], + exportDeclarations = _a[2]; + var nameBySource = new Map(); + importDeclarations.forEach(function(d) { + if (nameBySource.has(d.source)) { + return; + } + nameBySource.set(d.source, d.name || '__dep_' + nameBySource.size); + }); + exportDeclarations.forEach(function(d) { + if (!d.source) { + return; + } + if (nameBySource.has(d.source)) { + return; + } + nameBySource.set(d.source, d.name || '__dep_' + nameBySource.size); + }); + var deps = Array.from(nameBySource.keys()) + .map(function(s) { + return "'" + s + "'"; + }) + .join(', '); + var names = ['__import', '__exports'].concat(Array.from(nameBySource.values())).join(', '); + var transformed = "__shimport__.define('" + id + "', [" + deps + '], function(' + names + '){ '; + var ranges = importDeclarations + .concat(importStatements, exportDeclarations) + .sort(function(a, b) { + return a.start - b.start; + }); + var c = 0; + for (var i = 0; i < ranges.length; i += 1) { + var range = ranges[i]; + transformed += source.slice(c, range.start) + range.toString(nameBySource); + c = range.end; + } + transformed += source.slice(c); + exportDeclarations.forEach(function(d) { + if (d.name) { + transformed += '\n__exports.' + d.name + ' = ' + d.name + ';'; + } + }); + transformed += '\n});\n//# sourceURL=' + id; + return transformed; +} + +var VERSION = '0.0.12'; + +exports.transform = transform; +exports.find = find; +exports.VERSION = VERSION; diff --git a/dev/utils.js b/dev/utils.js index 6bde0cd..8eb62eb 100644 --- a/dev/utils.js +++ b/dev/utils.js @@ -1,146 +1,129 @@ -const ucfirst = require('ucfirst'), - prompts = require('prompts'), - { yellow } = require('colorette'), - fs = require('fs-extra'), - { join } = require('path'); - -const mjs2js = require('./mjs2js.js'); - -// -// Funny start up prompt -// -exports.prompt = async () => { - let dir = 'src'; - - const list = fs - .readdirSync(join(__dirname, '..', 'examples')) - .filter(d => /\d\d-/.test(d)); - - console.log(`\nSelect which example you want to test:\n`); - - list.map((d, i) => - console.log( - ` ${yellow(i + 1)}) ${ucfirst( - d.replace(/^\d\d-/, '').replace(/-/g, ' ') - )}` - ) - ); - - console.log( - `\n ${yellow( - 0 - )}) F***K OFF with examples. I am pro. I want to develop ${yellow( - 'my own plugin' - )}.\n` - ); - - let { value } = await prompts({ - type: 'number', - name: 'value', - message: `Which example you want to launch? (press 0 - ${list.length}):`, - validate: value => - value >= 0 && value < list.length + 1 ? true : false, - }); - - if (value > 0) { - dir = join('examples', list[value - 1]); - } else if (value === 0) { - console.log(`---------------------------------------------------- -Please change ${yellow('package.json')} now: - - ${yellow( - 'name' - )}: Must contain name of your plugin in a form windy-plugin-AnyName - ${yellow('description')}: Should be description of what your plugin does - ${yellow('author')}: Should contain your name - ${yellow('repository')}: Should be actual link to your hosting repo - -Also ${yellow( - './README.md' - )} should contain some info about your plugin if you wish - -For faster work use directlly ${yellow('npm run start-dev')} to skip this prompt - -After you will be done use ${yellow('npm publish')} to publish your plugin. ------------------------------------------------------`); - } - - return dir; -}; - -// -// Finally creates W.loadPlugin code -// -exports.stringifyPlugin = (opts, html, css, js) => { - const _q = (s, r) => { - if (!s) { - return "''"; - } - s = "'" + s.replace(/\\/g, '\\\\').replace(/'/g, "\\'") + "'"; - return r && s.indexOf('\n') !== -1 ? s.replace(/\n/g, '\\n') : s; - }; - - return ` -/** - * This is main plugin loading function - * Feel free to write your own compiler - */ -W.loadPlugin( - -/* Mounting options */ -${JSON.stringify(opts, null, 2)}, - -/* HTML */ -${_q(html, 1)}, - -/* CSS */ -${_q(css)}, - -/* Constructor */ -function() {\n\n${js}\n});`; -}; - -/** - * Parses and builds external .mjs files - * @param {Object} internalModules Hask of alredy loade internal modules - * @param {string} module in a form './filename.mjs' - * @return {string} new module name - */ -exports.externalMjs = async (src, internalModules, module, name) => { - const base = module.replace(/\.\/(\S+)\.mjs/, '$1'); - - if (!base) { - throw new Error( - 'Unable to import module. Windy plugin compiler is primitive and' + - ' supports only "@windy/name", or "./filename.mjs" modules' - ); - } - - const moduleId = `${name}/${base}`; - - if (module in internalModules) { - // Module already loaded - - return moduleId; - } else { - const file = join(src, `${base}.mjs`), - { externalModules, transformed } = await mjs2js( - file, - moduleId, - name - ); - - internalModules[module] = transformed; - - for (let internal of externalModules) { - // - // Here circular dep can occur - //// - if (!internalModules[internal]) { - await exports.externalMjs(src, internalModules, internal, name); - } - } - - return moduleId; - } -}; +const ucfirst = require('ucfirst'), + prompts = require('prompts'), + { yellow } = require('colorette'), + fs = require('fs-extra'), + { join } = require('path'); + +const mjs2js = require('./mjs2js.js'); + +// +// Funny start up prompt +// +exports.prompt = async () => { + let dir = 'src'; + + const list = fs.readdirSync(join(__dirname, '..', 'examples')).filter(d => /\d\d-/.test(d)); + + console.log(`\nSelect which example you want to test:\n`); + + list.map((d, i) => + console.log(` ${yellow(i + 1)}) ${ucfirst(d.replace(/^\d\d-/, '').replace(/-/g, ' '))}`), + ); + + console.log( + `\n ${yellow(0)}) F***K OFF with examples. I am pro. I want to develop ${yellow( + 'my own plugin', + )}.\n`, + ); + + let { value } = await prompts({ + type: 'number', + name: 'value', + message: `Which example you want to launch? (press 0 - ${list.length}):`, + validate: value => (value >= 0 && value < list.length + 1 ? true : false), + }); + + if (value > 0) { + dir = join('examples', list[value - 1]); + } else if (value === 0) { + console.log(`---------------------------------------------------- +Please change ${yellow('package.json')} now: + + ${yellow('name')}: Must contain name of your plugin in a form windy-plugin-AnyName + ${yellow('description')}: Should be description of what your plugin does + ${yellow('author')}: Should contain your name + ${yellow('repository')}: Should be actual link to your hosting repo + +Also ${yellow('./README.md')} should contain some info about your plugin if you wish + +For faster work use directlly ${yellow('npm run start-dev')} to skip this prompt + +After you will be done use ${yellow('npm publish')} to publish your plugin. +-----------------------------------------------------`); + } + + return dir; +}; + +// +// Finally creates W.loadPlugin code +// +exports.stringifyPlugin = (opts, html, css, js) => { + const _q = (s, r) => { + if (!s) { + return "''"; + } + s = "'" + s.replace(/\\/g, '\\\\').replace(/'/g, "\\'") + "'"; + return r && s.indexOf('\n') !== -1 ? s.replace(/\n/g, '\\n') : s; + }; + + return ` +/** + * This is main plugin loading function + * Feel free to write your own compiler + */ +W.loadPlugin( + +/* Mounting options */ +${JSON.stringify(opts, null, 2)}, + +/* HTML */ +${_q(html, 1)}, + +/* CSS */ +${_q(css)}, + +/* Constructor */ +function() {\n\n${js}\n});`; +}; + +/** + * Parses and builds external .mjs files + * @param {Object} internalModules Hask of alredy loade internal modules + * @param {string} module in a form './filename.mjs' + * @return {string} new module name + */ +exports.externalMjs = async (src, internalModules, module, name) => { + const base = module.replace(/\.\/(\S+)\.mjs/, '$1'); + + if (!base) { + throw new Error( + 'Unable to import module. Windy plugin compiler is primitive and' + + ' supports only "@windy/name", or "./filename.mjs" modules', + ); + } + + const moduleId = `${name}/${base}`; + + if (module in internalModules) { + // Module already loaded + + return moduleId; + } else { + const file = join(src, `${base}.mjs`), + { externalModules, transformed } = await mjs2js(file, moduleId, name); + + internalModules[module] = transformed; + + for (let internal of externalModules) { + // + // Here circular dep can occur + //// + if (!internalModules[internal]) { + await exports.externalMjs(src, internalModules, internal, name); + } + } + + return moduleId; + } +}; diff --git a/dev/variables.less b/dev/variables.less index 072bd14..54405fd 100644 --- a/dev/variables.less +++ b/dev/variables.less @@ -1,158 +1,158 @@ -// Common variables, functions and mix-ins -// used in main code and also in a plug-ins - -// Fonts -@font: Arial, Helvetica, sans-serif; - -// windy red -@myred: #9d0300; -@lightred: rgba(148, 96, 81, 1); // lighten variant of above - -// Foundation blue -@blue: #2a2448; - -// Background steel gray -@mygray: #4d4d4d; -@mygrayT: rgba(0, 0, 0, 0.6); // transparent version - -// Orange -@darkorange: #d49500; - -// Color used for POIs on a map -@yellow: #ffe29c; - -// UI yellow -@UIyellow: #fff3e1; - -// text-shadow, box-shadow -@myshadow: 1px 1px 1px rgba(0, 0, 0, 0.63); -@uishadow: 0px 0px 4px black; - -// Pastel white for backgrounds -@backgroundWhite: #f8f8f8; -@white: #f8f8f8; - -// Default tooltip color -@tooltipColor: @mygray; - -// Color -@pbColor: #e7e7e7; - -@grayFont: #6b6b6b; -@mobile: 736px; -@tablet: 1024px; -@loginBlue: #337ab7; -@sidebarfonts: Georgia, Times, serif; - -// Height of iOS status bar -@iosBar: 20px; -@iphoneXBar: 32px; -@iphoneXBottom: 18px; - -// Shadows on all sides make font outline -@outline: -1px -1px 0 rgba(0, 0, 0, 0.45), 1px -1px 0 rgba(0, 0, 0, 0.45), - -1px 1px 0 rgba(0, 0, 0, 0.45), 1px 1px 0 rgba(0, 0, 0, 0.45); - -// Height of mobile header -@headerH: 40px; - -// Height of mobile menu -@mmHeight: 45px; - -// Height of mobile bottom -@bottomHeight: 0px; - -// Width of desktop's rh bottom container -@rhBottomW: 300px; - -// Taken from detailClasses -@legendBg: #dedede; -@separationLine: #e5e5e5; // table separation line -@tdWidth: 30px; - -.iconfont2() { - font-family: iconfont; - font-variant: normal; - text-transform: none; - line-height: 1; -} - -.icon(@size:12px;@left:0;@top:0;@position:relative) { - .iconfont2; - position: @position; - font-size: @size; - left: @left; - top: @top; -} - -.boxshadow2() { - box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.8); -} - -.noanim() { - -webkit-transition: none; - transition: none; -} - -.opacity(@time:0.3s;@delay:0s) { - transition: @time opacity @delay; - -webkit-transition: @time opacity @delay; -} - -.disable() { - .opacity(); - opacity: 0.6; - pointer-events: none; -} - -.enable() { - opacity: 1; - pointer-events: all; -} - -// Retina screen -.retina( @content ) { - @media only screen and (-webkit-min-device-pixel-ratio: 2), - only screen and (min--moz-device-pixel-ratio: 2), - only screen and (-o-min-device-pixel-ratio: 2/1), - only screen and (min-device-pixel-ratio: 2), - only screen and (min-resolution: 192dpi), - only screen and (min-resolution: 2dppx) { - @content(); - } -} - -// Mobile phone -.mobile( @content ) { - @media only screen and (max-device-width: @mobile) { - @content(); - } -} - -// Tablet based on CSS in body -.tablet( @content ) { - .tablet-version & { - @content(); - } -} - -// Mobile and tablet together based on @media queries -.mobileTablet( @content ) { - @media screen and (max-device-width: @tablet) { - @content(); - } -} - -// Desktop only -.desktop( @content ) { - @media only screen and (min-device-width: @mobile) { - @content(); - } -} - -// Increasing clickable area -// DO not forget to move element left/top -.increaseClickArea( @size: 10px ) { - border: @size solid transparent; - background-clip: padding-box; -} +// Common variables, functions and mix-ins +// used in main code and also in a plug-ins + +// Fonts +@font: Arial, Helvetica, sans-serif; + +// windy red +@myred: #9d0300; +@lightred: rgba(148, 96, 81, 1); // lighten variant of above + +// Foundation blue +@blue: #2a2448; + +// Background steel gray +@mygray: #4d4d4d; +@mygrayT: rgba(0, 0, 0, 0.6); // transparent version + +// Orange +@darkorange: #d49500; + +// Color used for POIs on a map +@yellow: #ffe29c; + +// UI yellow +@UIyellow: #fff3e1; + +// text-shadow, box-shadow +@myshadow: 1px 1px 1px rgba(0, 0, 0, 0.63); +@uishadow: 0px 0px 4px black; + +// Pastel white for backgrounds +@backgroundWhite: #f8f8f8; +@white: #f8f8f8; + +// Default tooltip color +@tooltipColor: @mygray; + +// Color +@pbColor: #e7e7e7; + +@grayFont: #6b6b6b; +@mobile: 736px; +@tablet: 1024px; +@loginBlue: #337ab7; +@sidebarfonts: Georgia, Times, serif; + +// Height of iOS status bar +@iosBar: 20px; +@iphoneXBar: 32px; +@iphoneXBottom: 18px; + +// Shadows on all sides make font outline +@outline: -1px -1px 0 rgba(0, 0, 0, 0.45), 1px -1px 0 rgba(0, 0, 0, 0.45), + -1px 1px 0 rgba(0, 0, 0, 0.45), 1px 1px 0 rgba(0, 0, 0, 0.45); + +// Height of mobile header +@headerH: 40px; + +// Height of mobile menu +@mmHeight: 45px; + +// Height of mobile bottom +@bottomHeight: 0px; + +// Width of desktop's rh bottom container +@rhBottomW: 300px; + +// Taken from detailClasses +@legendBg: #dedede; +@separationLine: #e5e5e5; // table separation line +@tdWidth: 30px; + +.iconfont2() { + font-family: iconfont; + font-variant: normal; + text-transform: none; + line-height: 1; +} + +.icon(@size:12px;@left:0;@top:0;@position:relative) { + .iconfont2; + position: @position; + font-size: @size; + left: @left; + top: @top; +} + +.boxshadow2() { + box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.8); +} + +.noanim() { + -webkit-transition: none; + transition: none; +} + +.opacity(@time:0.3s;@delay:0s) { + transition: @time opacity @delay; + -webkit-transition: @time opacity @delay; +} + +.disable() { + .opacity(); + opacity: 0.6; + pointer-events: none; +} + +.enable() { + opacity: 1; + pointer-events: all; +} + +// Retina screen +.retina( @content ) { + @media only screen and (-webkit-min-device-pixel-ratio: 2), + only screen and (min--moz-device-pixel-ratio: 2), + only screen and (-o-min-device-pixel-ratio: 2/1), + only screen and (min-device-pixel-ratio: 2), + only screen and (min-resolution: 192dpi), + only screen and (min-resolution: 2dppx) { + @content(); + } +} + +// Mobile phone +.mobile( @content ) { + @media only screen and (max-device-width: @mobile) { + @content(); + } +} + +// Tablet based on CSS in body +.tablet( @content ) { + .tablet-version & { + @content(); + } +} + +// Mobile and tablet together based on @media queries +.mobileTablet( @content ) { + @media screen and (max-device-width: @tablet) { + @content(); + } +} + +// Desktop only +.desktop( @content ) { + @media only screen and (min-device-width: @mobile) { + @content(); + } +} + +// Increasing clickable area +// DO not forget to move element left/top +.increaseClickArea( @size: 10px ) { + border: @size solid transparent; + background-clip: padding-box; +} diff --git a/dist/plugin.js b/dist/plugin.js index 6e9f072..f8ff5f2 100644 --- a/dist/plugin.js +++ b/dist/plugin.js @@ -15,37 +15,116 @@ W.loadPlugin( "url": "git+https://github.com/windycom/windy-plugins" }, "description": "Windy plugin system enables anyone, with basic knowledge of Javascript to enhance Windy with new functionality (default desc).", - "displayName": "Hello world", - "hook": "menu" + "displayName": "drag demo", + "hook": "contextmenu", + "className": "plugin-lhpane", + "classNameMobile": "plugin-mobile-bottom-slide", + "exclusive": "lhpane" }, /* HTML */ -'', +'
Drag demo
Drag demo

Drag demo

This plugin is:


  • A boilerplate for building plugins for a mobile browser (plugins not accessible in the app).
  • A demonstration on how to use the bottomSlider mechanism to close the plugin pane on mobile.
  • I have also modified the bottomSlider so that the plugin pane can be dragged down partially, to display part of the map and the picker.
  • The Drag class is also demonstrated:
    • You can drag the circle in the box above, or
    • If you drag the open white area the cross hairs will move.
  • The z-index of the plugin is set to 10 so that it appears on top of the picker.
  • The z-index of the bottom element is set to 20, so that the calendar is on top of the plugin.
  • A backdrop (linear-gradient background image) is created for the calendar timecode.
  • The rest of this block is just to demonstrate scrolling. When you scroll down the "mobile-header" class becomes visible.


Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
', /* CSS */ -'', +'.onwindy-plugin-examples .left-border{left:300px}.onwindy-plugin-examples #search{display:none}#windy-plugin-examples{width:300px;height:100%;border-radius:8px}#windy-plugin-examples .section-title{text-align:center}#windy-plugin-examples #dragdemo-container{box-sizing:border-box;position:relative;border-radius:5px;border:1px solid blue;background-color:white;height:300px;margin:5px}#windy-plugin-examples #dragdemo-container .line{position:absolute;border:0px;background-color:black}#windy-plugin-examples #dragdemo-container #dragdemo-x{position:absolute;border:0px;background-color:black;left:30px;height:100%;width:.5px}#windy-plugin-examples #dragdemo-container #dragdemo-y{position:absolute;border:0px;background-color:black;top:30px;height:.5px;width:100%}#windy-plugin-examples #dragdemo-container #dragdemo-box{position:absolute;height:20px;width:20px;border-radius:10px;border:1px solid black;top:40px;left:40px}#windy-plugin-examples .dragdemo-description{border:1px solid blue;border-radius:5px;padding:10px;margin:5px}#windy-plugin-examples .dragdemo-description ul{margin-left:15px}#windy-plugin-examples .plugin-content{border-bottom-left-radius:8px;border-bottom-right-radius:8px}#device-mobile #open-in-app{display:none}#device-mobile .onwindy-plugin-examples #bottom{left:0px;z-index:20}#device-mobile #windy-plugin-examples{bottom:60px;height:auto;width:100%;transition:bottom .3s;z-index:10}#device-mobile #windy-plugin-examples .section-title{display:none}#device-mobile #windy-plugin-examples .calendar-backdrop{bottom:0px;height:40px;width:100%;position:absolute;overflow:hidden}#device-mobile #windy-plugin-examples .plugin-content{padding-bottom:40px}#device-mobile .mobile-calendar-expanded #windy-plugin-examples{bottom:100px}#device-tablet .onwindy-plugin-examples #bottom{margin-left:300px}#device-tablet #logo{left:100%;margin-left:150px}#device-tablet #open-in-app{display:none}', /* Constructor */ function () { - var map = W.require('map'); + var _this = this; - console.log("I am being mounted"); - var popup = null; + var Drag = W.require('Drag'); - this.onopen = function () { - console.log("I am being opened"); - var center = map.getCenter(); + var rs = W.require('rootScope'); - if (popup) { - popup.setLatLng(center); - } else { - popup = L.popup().setLatLng(center).setContent("Hello World").openOn(map); - } + var $ = W.require('$'); + + this.lastOpened = true; + var bgVals = getComputedStyle($('.plugin-content', this.el)).backgroundColor.replace('rgb', 'rgba').match(/[\d\.]+/g); + if (bgVals.length == 3) bgVals.push(1); + $('.calendar-backdrop', this.el).style.backgroundImage = "linear-gradient(rgba(".concat(bgVals.slice(0, 3), ",0), rgba(").concat(bgVals, ") 60%)"); + + if (rs.isMobile) { + this.addMobileSlider = true; + this.closeOnSwipeDown = false; + setTimeout(function () { + var bs = _this.bottomSlider; + bs.el.removeEventListener('mousedown', bs.bindedStart); + + if (bs.supportTouch) { + bs.el.removeEventListener('touchstart', bs.bindedStart); + } + + bs.bindedStart = Drag.startDrag.bind(bs); + bs.el.addEventListener('mousedown', bs.bindedStart); + + if (bs.supportTouch) { + bs.el.addEventListener('touchstart', bs.bindedStart); + } + + bs.origTopOfPlugin = _this.el.offsetTop; + + bs.ondragstart = function () { + bs.startTop = _this.el.offsetTop; + }; + + bs.ondrag = function (x, y) { + var deltaY = y - bs.el.offsetTop; + _this.el.style.top = bs.startTop + deltaY + 'px'; + }; + + bs.ondragend = function () { + if (Math.abs(_this.el.offsetTop < 20)) _this.el.style.top = bs.origTopOfPlugin + 'px'; + + if (_this.el.offsetHeight < 70) { + _this.close(); + + setTimeout(function () { + return _this.el.style.top = bs.origTopOfPlugin + 'px'; + }, 500); + } + }; + }, 0); + } + + this.onOtherPluginOpened = function (plugin) { + console.log("This ".concat(plugin, " has opened")); }; - this.onclose = function () { - console.log("I am being closed"); + var dragDiv = Object.assign({ + el: $('#dragdemo-box'), + ondrag: function ondrag(x, y) { + x = x < 0 ? 0 : x > $('#dragdemo-container').offsetWidth - 22 ? $('#dragdemo-container').offsetWidth - 22 : x; + y = y < 0 ? 0 : y > $('#dragdemo-container').offsetHeight - 22 ? $('#dragdemo-container').offsetHeight - 22 : y; + this.el.style.left = x + 'px'; + this.el.style.top = y + 'px'; + }, + ondragstart: function ondragstart(xy) {}, + ondragend: function ondragend(e) { + console.log('Do something with event:', e); + } + }, Drag); + + dragDiv._init(); - if (popup) { - map.removeLayer(popup); - popup = null; + $('#dragdemo-box').addEventListener('touchstart', function (e) { + return e.stopPropagation(); + }); + $('#dragdemo-box').addEventListener('mousedown', function (e) { + return e.stopPropagation(); + }); + var dragContainer = Object.assign({ + el: $('#dragdemo-container'), + ondrag: function ondrag(x, y) { + $('#dragdemo-x').style.left = x + this.startLeft - this.el.style.left.slice(0, -2) - 1.5 + 'px'; + $('#dragdemo-y').style.top = y + this.startTop - this.el.style.top.slice(0, -2) - 1.5 + 'px'; + }, + ondragstart: function ondragstart(xy) { + var clientRect = this.el.getBoundingClientRect(); + this.startLeft = xy[0] - clientRect.left - this.el.offsetLeft; + this.startTop = xy[1] - clientRect.top - this.el.offsetTop; + this.ondrag(this.el.offsetLeft, this.el.offsetTop); + }, + ondragend: function ondragend(e) { + console.log('Do something with event:', e); } - }; + }, Drag); + + dragContainer._init(); }); \ No newline at end of file diff --git a/examples/01-hello-world/config.js b/examples/01-hello-world/config.js index 9c7e23b..216d36f 100644 --- a/examples/01-hello-world/config.js +++ b/examples/01-hello-world/config.js @@ -12,12 +12,12 @@ module.exports = { Display name of your plugin, as it will appear in the menu */ - displayName: "Hello world", + displayName: 'Hello world', /* Place, where opening link to your plugin will appear. So far only 'contextmenu' and 'menu' is allowed */ - hook: "menu", + hook: 'menu', }; diff --git a/examples/01-hello-world/plugin.html b/examples/01-hello-world/plugin.html index d43b978..f0a7df9 100644 --- a/examples/01-hello-world/plugin.html +++ b/examples/01-hello-world/plugin.html @@ -2,19 +2,19 @@ diff --git a/examples/05-use-external-library/config.js b/examples/05-use-external-library/config.js index 56714c7..8c437e0 100644 --- a/examples/05-use-external-library/config.js +++ b/examples/05-use-external-library/config.js @@ -1,18 +1,18 @@ module.exports = { - displayName: "Hello world", + displayName: 'Hello world', - hook: "contextmenu", + hook: 'contextmenu', // External dependencies - dependencies: ["https://unpkg.com/d3@5.7.0/dist/d3.min.js"], + dependencies: ['https://unpkg.com/d3@5.7.0/dist/d3.min.js'], // Class name applied to your plugin element - className: "drop-down-menu", - classNameMobile: "drop-down-menu down", // for mobile devices + className: 'drop-down-menu', + classNameMobile: 'drop-down-menu down', // for mobile devices // The place in page, where your plugin element // will be mounted to the page. By default all the plugins // are attached to #plugins element - attachPoint: "#map-container .leaflet-popup-pane", - attachPointMobile: "#plugins", // for mobile devices + attachPoint: '#map-container .leaflet-popup-pane', + attachPointMobile: '#plugins', // for mobile devices }; diff --git a/examples/05-use-external-library/plugin.html b/examples/05-use-external-library/plugin.html index 154c1a1..9a7f3d0 100644 --- a/examples/05-use-external-library/plugin.html +++ b/examples/05-use-external-library/plugin.html @@ -8,14 +8,14 @@

My graph

diff --git a/examples/05-use-external-library/plugin.less b/examples/05-use-external-library/plugin.less index a75a3e8..79211c8 100644 --- a/examples/05-use-external-library/plugin.less +++ b/examples/05-use-external-library/plugin.less @@ -1,4 +1,4 @@ -@import "dev/variables.less"; +@import 'dev/variables.less'; #windy-plugin-examples { font-size: 12px; @@ -26,6 +26,6 @@ .mobile() is handy less function replacing complex media query */ .mobile( - {display: block; left: 0; top: 0; right: 0; width: ~"calc(100% - 20px)" ; margin: 10px;} + {display: block; left: 0; top: 0; right: 0; width: ~'calc(100% - 20px)' ; margin: 10px;} ); } diff --git a/examples/06-weather-picker/config.js b/examples/06-weather-picker/config.js index 2a4cab5..015bfec 100644 --- a/examples/06-weather-picker/config.js +++ b/examples/06-weather-picker/config.js @@ -1,4 +1,4 @@ module.exports = { - displayName: "Picker example", - hook: "menu", + displayName: 'Picker example', + hook: 'menu', }; diff --git a/examples/06-weather-picker/plugin.html b/examples/06-weather-picker/plugin.html index 354d53d..695c6ce 100644 --- a/examples/06-weather-picker/plugin.html +++ b/examples/06-weather-picker/plugin.html @@ -1,15 +1,15 @@ diff --git a/examples/07-multiple-files-plugin/README.md b/examples/07-multiple-files-plugin/README.md index 815e3dc..4d36575 100755 --- a/examples/07-multiple-files-plugin/README.md +++ b/examples/07-multiple-files-plugin/README.md @@ -13,11 +13,11 @@ Usage: ```js // Windy's core modules -import map from "@windy/map"; -import _ from "@windy/utils"; +import map from '@windy/map'; +import _ from '@windy/utils'; // Your own modules -import graph from "./soundingGraph.mjs"; +import graph from './soundingGraph.mjs'; // ..your code diff --git a/examples/07-multiple-files-plugin/config.js b/examples/07-multiple-files-plugin/config.js index 9b54b27..0df049b 100755 --- a/examples/07-multiple-files-plugin/config.js +++ b/examples/07-multiple-files-plugin/config.js @@ -2,20 +2,20 @@ This is configuration file for your plugin */ module.exports = { - displayName: "Graph as a plugin", + displayName: 'Graph as a plugin', - hook: "contextmenu", + hook: 'contextmenu', // External dependencies - dependencies: ["https://unpkg.com/d3@5.7.0/dist/d3.min.js"], + dependencies: ['https://unpkg.com/d3@5.7.0/dist/d3.min.js'], // Class name applied to your plugin element - className: "drop-down-window ", - classNameMobile: "drop-down-window down", // for mobile devices + className: 'drop-down-window ', + classNameMobile: 'drop-down-window down', // for mobile devices // The place in page, where your plugin element // will be mounted to the page. By default all the plugins // are attached to #plugins element - attachPoint: ".leaflet-popup-pane", - attachPointMobile: "#plugins", // for mobile devices + attachPoint: '.leaflet-popup-pane', + attachPointMobile: '#plugins', // for mobile devices }; diff --git a/examples/07-multiple-files-plugin/plugin.html b/examples/07-multiple-files-plugin/plugin.html index 186e865..42921ae 100755 --- a/examples/07-multiple-files-plugin/plugin.html +++ b/examples/07-multiple-files-plugin/plugin.html @@ -14,17 +14,17 @@

This is my plugin (not official Windy's graph)