diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..322554b1d6 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +root = true +[*] +end_of_line = lf +insert_final_newline = true +charset = utf-8 + +[*.js] +indent_style = space +indent_size = 2 diff --git a/.eslintignore b/.eslintignore index a8b1cbe073..7141c2d65c 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,5 +3,8 @@ src/version.js src/sha.js src/util/wigglemaps.js src/util/distanceGrid.js +dist/** +testing/** geo.js **/*.min.js +examples/common/js/jsonlint.js diff --git a/.eslintrc b/.eslintrc index 167e59f2c2..e8e0e518cc 100644 --- a/.eslintrc +++ b/.eslintrc @@ -12,7 +12,8 @@ "key-spacing": 0, "no-unneeded-ternary": 0, "yoda": 0, - "no-useless-call": 0 + "no-useless-call": 0, + "camelcase": 0 }, "env": { "browser": true diff --git a/.gitignore b/.gitignore index 590bc86878..517cafe493 100644 --- a/.gitignore +++ b/.gitignore @@ -12,7 +12,6 @@ /docs/*.py !/docs/conf.py !/docs/parse.py -/dist .eslintcache /lcov /notes diff --git a/.travis.yml b/.travis.yml index 73d875b6f7..0c98c784d6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ before_install: script: - npm run build - - ./node_modules/.bin/grunt docs + - npm run docs - mkdir _build - ctest -S cmake/travis_build.cmake -VV || true - if [ -f _build/test_failed ] ; then false ; fi diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c40f88052..0c9854fc6b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ enable_testing() set(BUILD_TESTING ON CACHE BOOL "Enable geojs testing") set(PHANTOMJS_TESTS ON CACHE BOOL "Generate phantomjs unit tests.") set(ESLINT_TESTS ON CACHE BOOL "Generate eslint style tests for JS source files.") -set(SELENIUM_TESTS OFF CACHE BOOL "Generate selenium unit tests.") +set(SELENIUM_TESTS ON CACHE BOOL "Generate selenium unit tests.") site_name(HOSTNAME) @@ -20,7 +20,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") set(NOTES_PATH "${CMAKE_CURRENT_BINARY_DIR}/build_notes.json") -# set the path where grunt builds the sources +# set the path where webpack builds the sources set(GEOJS_DEPLOY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dist") function(add_geojs_test test_name) diff --git a/Gruntfile.js b/Gruntfile.js deleted file mode 100644 index 709cc24783..0000000000 --- a/Gruntfile.js +++ /dev/null @@ -1,303 +0,0 @@ -/* global module, require, process */ - -module.exports = function (grunt) { - 'use strict'; - - var port; - - port = Number(grunt.option('port') || '8082'); - - /* Pass a "--env=" argument to grunt. Default value is "production" - * --env=dev enables making source maps. */ - var environment = grunt.option('env') || 'production'; - - grunt.config.init({ - env: grunt.option('env') || process.env.GRUNT_ENV || 'development', - - copy: { - plugins: { - files: [ - { - cwd: 'src/', - src: ['plugin/*.js'], - dest: 'dist/', - expand: true - } - ] - }, - examples: { - files: [ - { - src: ['examples/**/*'], - dest: 'dist/', - expand: true - } - ] - }, - redirect: { - files: [{ - src: 'index.html', - dest: 'dist/index.html' - }] - }, - bootstrap: { - files: [ - { - src: ['**'], - dest: 'dist/examples/common/', - expand: true, - cwd: 'node_modules/bootstrap/dist/', - filter: function (src) { - return !src.match(/.*\.css$/); - } - }, - { - src: ['*'], - dest: 'dist/examples/common/css/', - expand: true, - cwd: 'node_modules/bootswatch/flatly' - } - ] - }, - codemirror: { - files: [ - { - src: ['codemirror.css'], - dest: 'dist/examples/common/css/', - cwd: 'node_modules/codemirror/lib/', - expand: true - }, - { - src: ['lint.css'], - dest: 'dist/examples/common/css/', - cwd: 'node_modules/codemirror/addon/lint/', - expand: true - }, - { - src: ['foldgutter.css'], - dest: 'dist/examples/common/css/', - cwd: 'node_modules/codemirror/addon/fold/', - expand: true - } - ] - } - }, - - uglify: { - options: { - sourceMap: environment === 'dev', - sourceMapIncludeSources: true, - report: 'min', - beautify: { - ascii_only: true, - beautify: false - }, - mangle: false - }, - - codemirror: { - files: { - 'dist/examples/common/js/codemirror.js': [ - 'node_modules/jsonlint/lib/jsonlint.js', - 'node_modules/codemirror/lib/codemirror.js', - 'node_modules/codemirror/mode/javascript/javascript.js', - 'node_modules/codemirror/mode/javascript/javascript.js', - 'node_modules/codemirror/addon/lint/lint.js', - 'node_modules/codemirror/addon/lint/json-lint.js', - 'node_modules/codemirror/addon/fold/brace-fold.js', - 'node_modules/codemirror/addon/fold/foldcode.js', - 'node_modules/codemirror/addon/fold/foldgutter.js', - 'node_modules/codemirror/addon/edit/matchbrackets.js' - ] - } - } - }, - - express: { - server: { - options: { - port: port, - server: 'testing/test-runners/server.js', - bases: ['dist'] - } - } - }, - - jade: { - options: { - pretty: true - } - } - }); - - grunt.loadNpmTasks('grunt-contrib-jade'); - grunt.loadNpmTasks('grunt-contrib-copy'); - grunt.loadNpmTasks('grunt-contrib-uglify'); - grunt.loadNpmTasks('grunt-express'); - grunt.loadNpmTasks('grunt-docco'); - - var findExamples = function () { - // create tasks for examples - var examples = grunt.file.expand('examples/*/example.json'); - var exlist = examples.map(function (ex) { - var path = require('path'); - var dir = path.dirname(ex); - var exname = path.basename(dir); - var data = grunt.file.readJSON(ex); - - // Use geo.js unless using the production environment. - var geolib = '../../built/geo.js'; - if (grunt.config('env') === 'production') { - geolib = '../../built/geo.min.js'; - } - - if (data.exampleJs.length) { - data.docHTML = path.join( - 'doc', - path.basename(data.exampleJs[0].replace('.js', '.html')) - ); - } - var target = { - files: [ - { - src: [ - path.join(dir, 'index.jade') - ], - dest: path.join('dist', dir, 'index.html'), - expand: false - } - ], - options: { - data: function () { - data.defaultCss = [ - '../common/css/bootstrap.min.css', - '../common/css/examples.css' - ]; - data.defaultJs = [ - { - src: '../../built/geo.ext.min.js', - charset: 'UTF-8', - type: 'text/javascript' - }, - geolib, - '../common/js/bootstrap.min.js', - '../common/js/examples.js' - ]; - return data; - } - } - }; - grunt.config(['jade', exname], target); - - if (data.docHTML) { - grunt.config(['docco', exname], { - src: data.exampleJs.map(function (p) { - return 'examples/' + exname + '/' + p; - }), - options: { - output: path.join('dist', dir, 'doc'), - layout: 'classic' - } - }); - } - - return data; - }); - - // configure the main examples page - grunt.config(['jade', 'examples'], { - files: [ - { - src: ['examples/index.jade'], - dest: 'dist/examples/index.html' - } - ], - options: { - data: { - hideNavbar: false, - defaultCss: [ - 'common/css/bootstrap.min.css', - 'common/css/examples.css' - ], - defaultJs: [ - {src: '../built/geo.min.js', charset: 'UTF-8', type: 'text/javascript'}, // for jquery - 'common/js/bootstrap.min.js', - 'common/js/examples.js' - ], - exampleCss: ['main.css'], - exampleJs: ['main.js'], - examples: exlist, - title: 'GeoJS', - about: { - hidden: true - } - } - } - }); - }; - - grunt.registerTask('docs', 'Build documentation', function () { - var done = this.async(); - - grunt.util.spawn({ - cmd: './node_modules/.bin/jsdoc', - args: [ - '--pedantic', - '-d', - 'dist/apidocs', - '-r', - 'src' - ] - }, function (error, result, code) { - if (error) { - grunt.fail.warn('Could not build documentation:\n' + result.stderr); - } - - done(code === 0); - }); - }); - - findExamples(); - grunt.registerTask('examples', [ - 'copy:redirect', - 'copy:bootstrap', - 'copy:codemirror', - 'copy:examples', - 'uglify:codemirror', - 'jade', - 'docco' - ]); - - grunt.registerTask('default', [ - 'copy:plugins', - 'examples' - ]); - - grunt.registerTask( - 'serve', - 'Serve the content at http://localhost:8082, ' + - 'use the --port option to override the default port', - ['express', 'express-keepalive'] - ); - - grunt.registerTask( - 'serve-test', - 'Serve the content for testing. This starts on port 30100 by ' + - 'default and does not rebuild sources automatically.', - function () { - grunt.config.set('express.server.options.hostname', '0.0.0.0'); - if (!grunt.option('port')) { - grunt.config.set('express.server.options.port', 30100); - } - // make sure express doesn't change the port - var test_port = grunt.config.get('express.server.options.port'); - grunt.event.on('express:server:started', function () { - if (grunt.config.get('express.server.options.port') !== test_port) { - grunt.fail.fatal('Port ' + test_port + ' unavailable.'); - } - }); - - grunt.task.run(['express', 'express-keepalive']); - } - ); -}; diff --git a/cmake/travis_build.cmake b/cmake/travis_build.cmake index 2b4a0ad4fc..8c6f9be3c4 100644 --- a/cmake/travis_build.cmake +++ b/cmake/travis_build.cmake @@ -8,7 +8,9 @@ set(CTEST_CMAKE_GENERATOR "Unix Makefiles") set(coverage_file "${CTEST_SOURCE_DIRECTORY}/dist/cobertura/phantomjs/coverage.xml") ctest_start("Continuous") -ctest_configure() +ctest_configure( + OPTIONS "-DSELENIUM_TESTS=OFF" +) ctest_build() ctest_test(PARALLEL_LEVEL 1 RETURN_VALUE res) if(EXISTS "${coverage_file}") diff --git a/dist/.gitignore b/dist/.gitignore new file mode 100644 index 0000000000..6b6c5928fd --- /dev/null +++ b/dist/.gitignore @@ -0,0 +1,3 @@ +* +!index.html +!.gitignore diff --git a/index.html b/dist/index.html similarity index 100% rename from index.html rename to dist/index.html diff --git a/docs/developers.rst b/docs/developers.rst index f9749f2341..d9f58aef70 100644 --- a/docs/developers.rst +++ b/docs/developers.rst @@ -11,7 +11,7 @@ The selenium testing infrastructure of Geojs is run via CTest, it assumes that the testing "server" is started prior to execution. To start the server, just run :: - grunt default serve-test + npm run start-test This will start a server on the default port of ``30100``. The port and selenium host names are configurable with cmake. For example inside @@ -29,8 +29,8 @@ IP address reachable by the selenium node. Typically, CMake is used to build outside of the source tree. This means you would create a new directory somewhare and point cmake - to the geojs source directory. You may need to rerun ``cmake``, ``make``, - and ``grunt`` after making changes to your code for everything to + to the geojs source directory. You may need to rerun ``cmake`` and + ``make`` after making changes to your code for everything to build correctly. Try running ``ccmake /path/to/geojs`` for a full list of configuration options. diff --git a/docs/quickstart.rst b/docs/quickstart.rst index c57ba4e8cc..f06985b177 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -22,11 +22,6 @@ and testing of geojs. * `Requests `_ * `Selenium `_ -These docs assume that the `Grunt `_ command line interface -has been installed globally, which can be done with the following command: :: - - npm install -g grunt-cli - Getting the source code ----------------------- @@ -94,7 +89,7 @@ and creating a basic full map using the `osmLayer` class. You can save this page into a new file at ``dist/mymap.html``. To view your new creation, start up a web server with the command :: - grunt serve + npm run examples Now, if you open up ``_ in your favorite webgl enabled browser, you should see a map like the following: @@ -103,4 +98,4 @@ browser, you should see a map like the following: :align: center Additionally, you will be able to see all of the built-in examples at -``_ after building them by running ``grunt``. +``_ with the example server running. diff --git a/examples/.eslintrc b/examples/.eslintrc new file mode 100644 index 0000000000..5658e66999 --- /dev/null +++ b/examples/.eslintrc @@ -0,0 +1,9 @@ +{ + "globals": { + "d3": true, + "geo": true, + "$": true, + "CodeMirror": true, + "jsonlint": true + } +} diff --git a/examples/build.js b/examples/build.js new file mode 100644 index 0000000000..31659e4f4f --- /dev/null +++ b/examples/build.js @@ -0,0 +1,73 @@ +var path = require('path'); +var glob = require('glob').sync; +var fs = require('fs-extra'); +var docco = require('docco').document; +var jade = require('jade'); + +// generate the examples +fs.ensureDirSync('dist/examples'); +var examples = glob('examples/*/example.json') + .map(function (f) { + // /path/to/example.json + f = path.resolve(f); + + // content of example.json + var json = fs.readJSONSync(path.resolve(f)); + + // directory of the example + var dir = path.dirname(f); + + // the main js file for the example + var main = path.resolve(dir, json.exampleJs[0]); + + // the output directory where the example will be compiled + var output = path.resolve('dist', 'examples', json.path); + + // create, empty, and copy the source directory + fs.emptyDirSync(output); + fs.copySync(dir, output); + + // make docco documentation in: + // dist/examples//docs/ + docco({ + args: [main], + output: path.resolve(output, 'docs'), + layout: 'classic' + }, function () { + // simplify the docco output to reduce the output size by + // removing the unnecessary public/ directory + fs.removeSync(path.resolve(output, 'docs', 'public')); + }); + + json.docHTML = 'docs/' + path.basename(main).replace(/js$/, 'html'); + json.bundle = '../bundle.js'; + + var fn = jade.compileFile(path.relative('.', path.resolve(dir, 'index.jade')), {pretty: true}); + fs.writeFileSync(path.resolve(output, 'index.html'), fn(json)); + return json; + }); + +// copy common files +fs.copySync('examples/common', 'dist/examples/common'); + +// create the main example page +var data = { + hideNavbar: false, + exampleCss: ['main.css'], + exampleJs: ['main.js'], + examples: examples, + bundle: './bundle.js', + about: {hidden: true}, + title: 'GeoJS' +}; + +// copy assets for the main page +fs.copySync('examples/main.js', 'dist/examples/main.js'); +fs.copySync('examples/main.css', 'dist/examples/main.css'); + +var fn = jade.compileFile('./examples/index.jade', {pretty: true}); +fs.writeFileSync( + path.resolve('dist', 'examples', 'index.html'), + fn(data) +); + diff --git a/examples/choropleth/main.js b/examples/choropleth/main.js index 8b1c1d040b..905bd9e8b7 100644 --- a/examples/choropleth/main.js +++ b/examples/choropleth/main.js @@ -1,7 +1,7 @@ // Run after the DOM loads $(function () { 'use strict'; - + // Define a function we will use to generate contours. function makeChoropleth(geoData, scalarData, layer) { /* There are two example data sets. One has a position array which @@ -9,9 +9,9 @@ $(function () { * array which just has our contour values. */ var choropleth = layer .createFeature('choropleth') - .data(geoData) + .data(geoData) .scalar(scalarData) - .choropleth({}); + .choropleth({}); return choropleth; } @@ -47,10 +47,11 @@ $(function () { var mockScalarData = geoData .features - .map(function(feature){ - //create some mock value for each state - return { - value: Math.random()*10, + .map(function (feature) { + + //create some mock value for each state + return { + value: Math.random() * 10, id: feature.properties.GEO_ID }; }); @@ -58,16 +59,16 @@ $(function () { var choropleth = makeChoropleth(geoData.features, mockScalarData, vglLayer); - setTimeout(function(){ + setTimeout(function () { var mockScalarData2 = geoData .features - .map(function(feature){ + .map(function (feature) { return { - value: Math.random()*10, + value: Math.random() * 10, id: feature.properties.GEO_ID }; }); - + choropleth .scalar(mockScalarData2); diff --git a/examples/common/js/jsonlint.js b/examples/common/js/jsonlint.js new file mode 100644 index 0000000000..79659515f1 --- /dev/null +++ b/examples/common/js/jsonlint.js @@ -0,0 +1,423 @@ +/* Jison generated parser */ +/** + * https://github.com/zaach/jsonlint + * @license MIT + * @copyright 2012 Zachary Carter + */ +var jsonlint = (function(){ +var parser = {trace: function trace() { }, +yy: {}, +symbols_: {"error":2,"JSONString":3,"STRING":4,"JSONNumber":5,"NUMBER":6,"JSONNullLiteral":7,"NULL":8,"JSONBooleanLiteral":9,"TRUE":10,"FALSE":11,"JSONText":12,"JSONValue":13,"EOF":14,"JSONObject":15,"JSONArray":16,"{":17,"}":18,"JSONMemberList":19,"JSONMember":20,":":21,",":22,"[":23,"]":24,"JSONElementList":25,"$accept":0,"$end":1}, +terminals_: {2:"error",4:"STRING",6:"NUMBER",8:"NULL",10:"TRUE",11:"FALSE",14:"EOF",17:"{",18:"}",21:":",22:",",23:"[",24:"]"}, +productions_: [0,[3,1],[5,1],[7,1],[9,1],[9,1],[12,2],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[15,2],[15,3],[20,3],[19,1],[19,3],[16,2],[16,3],[25,1],[25,3]], +performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) { + +var $0 = $$.length - 1; +switch (yystate) { +case 1: // replace escaped characters with actual character + this.$ = yytext.replace(/\\(\\|")/g, "$"+"1") + .replace(/\\n/g,'\n') + .replace(/\\r/g,'\r') + .replace(/\\t/g,'\t') + .replace(/\\v/g,'\v') + .replace(/\\f/g,'\f') + .replace(/\\b/g,'\b'); + +break; +case 2:this.$ = Number(yytext); +break; +case 3:this.$ = null; +break; +case 4:this.$ = true; +break; +case 5:this.$ = false; +break; +case 6:return this.$ = $$[$0-1]; +break; +case 13:this.$ = {}; +break; +case 14:this.$ = $$[$0-1]; +break; +case 15:this.$ = [$$[$0-2], $$[$0]]; +break; +case 16:this.$ = {}; this.$[$$[$0][0]] = $$[$0][1]; +break; +case 17:this.$ = $$[$0-2]; $$[$0-2][$$[$0][0]] = $$[$0][1]; +break; +case 18:this.$ = []; +break; +case 19:this.$ = $$[$0-1]; +break; +case 20:this.$ = [$$[$0]]; +break; +case 21:this.$ = $$[$0-2]; $$[$0-2].push($$[$0]); +break; +} +}, +table: [{3:5,4:[1,12],5:6,6:[1,13],7:3,8:[1,9],9:4,10:[1,10],11:[1,11],12:1,13:2,15:7,16:8,17:[1,14],23:[1,15]},{1:[3]},{14:[1,16]},{14:[2,7],18:[2,7],22:[2,7],24:[2,7]},{14:[2,8],18:[2,8],22:[2,8],24:[2,8]},{14:[2,9],18:[2,9],22:[2,9],24:[2,9]},{14:[2,10],18:[2,10],22:[2,10],24:[2,10]},{14:[2,11],18:[2,11],22:[2,11],24:[2,11]},{14:[2,12],18:[2,12],22:[2,12],24:[2,12]},{14:[2,3],18:[2,3],22:[2,3],24:[2,3]},{14:[2,4],18:[2,4],22:[2,4],24:[2,4]},{14:[2,5],18:[2,5],22:[2,5],24:[2,5]},{14:[2,1],18:[2,1],21:[2,1],22:[2,1],24:[2,1]},{14:[2,2],18:[2,2],22:[2,2],24:[2,2]},{3:20,4:[1,12],18:[1,17],19:18,20:19},{3:5,4:[1,12],5:6,6:[1,13],7:3,8:[1,9],9:4,10:[1,10],11:[1,11],13:23,15:7,16:8,17:[1,14],23:[1,15],24:[1,21],25:22},{1:[2,6]},{14:[2,13],18:[2,13],22:[2,13],24:[2,13]},{18:[1,24],22:[1,25]},{18:[2,16],22:[2,16]},{21:[1,26]},{14:[2,18],18:[2,18],22:[2,18],24:[2,18]},{22:[1,28],24:[1,27]},{22:[2,20],24:[2,20]},{14:[2,14],18:[2,14],22:[2,14],24:[2,14]},{3:20,4:[1,12],20:29},{3:5,4:[1,12],5:6,6:[1,13],7:3,8:[1,9],9:4,10:[1,10],11:[1,11],13:30,15:7,16:8,17:[1,14],23:[1,15]},{14:[2,19],18:[2,19],22:[2,19],24:[2,19]},{3:5,4:[1,12],5:6,6:[1,13],7:3,8:[1,9],9:4,10:[1,10],11:[1,11],13:31,15:7,16:8,17:[1,14],23:[1,15]},{18:[2,17],22:[2,17]},{18:[2,15],22:[2,15]},{22:[2,21],24:[2,21]}], +defaultActions: {16:[2,6]}, +parseError: function parseError(str, hash) { + throw new Error(str); +}, +parse: function parse(input) { + var self = this, + stack = [0], + vstack = [null], // semantic value stack + lstack = [], // location stack + table = this.table, + yytext = '', + yylineno = 0, + yyleng = 0, + recovering = 0, + TERROR = 2, + EOF = 1; + + //this.reductionCount = this.shiftCount = 0; + + this.lexer.setInput(input); + this.lexer.yy = this.yy; + this.yy.lexer = this.lexer; + if (typeof this.lexer.yylloc == 'undefined') + this.lexer.yylloc = {}; + var yyloc = this.lexer.yylloc; + lstack.push(yyloc); + + if (typeof this.yy.parseError === 'function') + this.parseError = this.yy.parseError; + + function popStack (n) { + stack.length = stack.length - 2*n; + vstack.length = vstack.length - n; + lstack.length = lstack.length - n; + } + + function lex() { + var token; + token = self.lexer.lex() || 1; // $end = 1 + // if token isn't its numeric value, convert + if (typeof token !== 'number') { + token = self.symbols_[token] || token; + } + return token; + } + + var symbol, preErrorSymbol, state, action, a, r, yyval={},p,len,newState, expected; + while (true) { + // retreive state number from top of stack + state = stack[stack.length-1]; + + // use default actions if available + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol == null) + symbol = lex(); + // read action for current state and first input + action = table[state] && table[state][symbol]; + } + + // handle parse error + _handle_error: + if (typeof action === 'undefined' || !action.length || !action[0]) { + + if (!recovering) { + // Report error + expected = []; + for (p in table[state]) if (this.terminals_[p] && p > 2) { + expected.push("'"+this.terminals_[p]+"'"); + } + var errStr = ''; + if (this.lexer.showPosition) { + errStr = 'Parse error on line '+(yylineno+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+expected.join(', ') + ", got '" + this.terminals_[symbol]+ "'"; + } else { + errStr = 'Parse error on line '+(yylineno+1)+": Unexpected " + + (symbol == 1 /*EOF*/ ? "end of input" : + ("'"+(this.terminals_[symbol] || symbol)+"'")); + } + this.parseError(errStr, + {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected}); + } + + // just recovered from another error + if (recovering == 3) { + if (symbol == EOF) { + throw new Error(errStr || 'Parsing halted.'); + } + + // discard current lookahead and grab another + yyleng = this.lexer.yyleng; + yytext = this.lexer.yytext; + yylineno = this.lexer.yylineno; + yyloc = this.lexer.yylloc; + symbol = lex(); + } + + // try to recover from error + while (1) { + // check for error recovery rule in this state + if ((TERROR.toString()) in table[state]) { + break; + } + if (state == 0) { + throw new Error(errStr || 'Parsing halted.'); + } + popStack(1); + state = stack[stack.length-1]; + } + + preErrorSymbol = symbol; // save the lookahead token + symbol = TERROR; // insert generic error symbol as new lookahead + state = stack[stack.length-1]; + action = table[state] && table[state][TERROR]; + recovering = 3; // allow 3 real symbols to be shifted before reporting a new error + } + + // this shouldn't happen, unless resolve defaults are off + if (action[0] instanceof Array && action.length > 1) { + throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol); + } + + switch (action[0]) { + + case 1: // shift + //this.shiftCount++; + + stack.push(symbol); + vstack.push(this.lexer.yytext); + lstack.push(this.lexer.yylloc); + stack.push(action[1]); // push state + symbol = null; + if (!preErrorSymbol) { // normal execution/no error + yyleng = this.lexer.yyleng; + yytext = this.lexer.yytext; + yylineno = this.lexer.yylineno; + yyloc = this.lexer.yylloc; + if (recovering > 0) + recovering--; + } else { // error just occurred, resume old lookahead f/ before error + symbol = preErrorSymbol; + preErrorSymbol = null; + } + break; + + case 2: // reduce + //this.reductionCount++; + + len = this.productions_[action[1]][1]; + + // perform semantic action + yyval.$ = vstack[vstack.length-len]; // default to $$ = $1 + // default location, uses first token for firsts, last for lasts + yyval._$ = { + first_line: lstack[lstack.length-(len||1)].first_line, + last_line: lstack[lstack.length-1].last_line, + first_column: lstack[lstack.length-(len||1)].first_column, + last_column: lstack[lstack.length-1].last_column + }; + r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack); + + if (typeof r !== 'undefined') { + return r; + } + + // pop off stack + if (len) { + stack = stack.slice(0,-1*len*2); + vstack = vstack.slice(0, -1*len); + lstack = lstack.slice(0, -1*len); + } + + stack.push(this.productions_[action[1]][0]); // push nonterminal (reduce) + vstack.push(yyval.$); + lstack.push(yyval._$); + // goto new state = table[STATE][NONTERMINAL] + newState = table[stack[stack.length-2]][stack[stack.length-1]]; + stack.push(newState); + break; + + case 3: // accept + return true; + } + + } + + return true; +}}; +/* Jison generated lexer */ +var lexer = (function(){ +var lexer = ({EOF:1, +parseError:function parseError(str, hash) { + if (this.yy.parseError) { + this.yy.parseError(str, hash); + } else { + throw new Error(str); + } + }, +setInput:function (input) { + this._input = input; + this._more = this._less = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ''; + this.conditionStack = ['INITIAL']; + this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0}; + return this; + }, +input:function () { + var ch = this._input[0]; + this.yytext+=ch; + this.yyleng++; + this.match+=ch; + this.matched+=ch; + var lines = ch.match(/\n/); + if (lines) this.yylineno++; + this._input = this._input.slice(1); + return ch; + }, +unput:function (ch) { + this._input = ch + this._input; + return this; + }, +more:function () { + this._more = true; + return this; + }, +less:function (n) { + this._input = this.match.slice(n) + this._input; + }, +pastInput:function () { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, ""); + }, +upcomingInput:function () { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20-next.length); + } + return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, ""); + }, +showPosition:function () { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c+"^"; + }, +next:function () { + if (this.done) { + return this.EOF; + } + if (!this._input) this.done = true; + + var token, + match, + tempMatch, + index, + col, + lines; + if (!this._more) { + this.yytext = ''; + this.match = ''; + } + var rules = this._currentRules(); + for (var i=0;i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (!this.options.flex) break; + } + } + if (match) { + lines = match[0].match(/\n.*/g); + if (lines) this.yylineno += lines.length; + this.yylloc = {first_line: this.yylloc.last_line, + last_line: this.yylineno+1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length-1].length-1 : this.yylloc.last_column + match[0].length} + this.yytext += match[0]; + this.match += match[0]; + this.yyleng = this.yytext.length; + this._more = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]); + if (this.done && this._input) this.done = false; + if (token) return token; + else return; + } + if (this._input === "") { + return this.EOF; + } else { + this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(), + {text: "", token: null, line: this.yylineno}); + } + }, +lex:function lex() { + var r = this.next(); + if (typeof r !== 'undefined') { + return r; + } else { + return this.lex(); + } + }, +begin:function begin(condition) { + this.conditionStack.push(condition); + }, +popState:function popState() { + return this.conditionStack.pop(); + }, +_currentRules:function _currentRules() { + return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules; + }, +topState:function () { + return this.conditionStack[this.conditionStack.length-2]; + }, +pushState:function begin(condition) { + this.begin(condition); + }}); +lexer.options = {}; +lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) { + +var YYSTATE=YY_START +switch($avoiding_name_collisions) { +case 0:/* skip whitespace */ +break; +case 1:return 6 +break; +case 2:yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2); return 4 +break; +case 3:return 17 +break; +case 4:return 18 +break; +case 5:return 23 +break; +case 6:return 24 +break; +case 7:return 22 +break; +case 8:return 21 +break; +case 9:return 10 +break; +case 10:return 11 +break; +case 11:return 8 +break; +case 12:return 14 +break; +case 13:return 'INVALID' +break; +} +}; +lexer.rules = [/^(?:\s+)/,/^(?:(-?([0-9]|[1-9][0-9]+))(\.[0-9]+)?([eE][-+]?[0-9]+)?\b)/,/^(?:"(?:\\[\\"bfnrt/]|\\u[a-fA-F0-9]{4}|[^\\\0-\x09\x0a-\x1f"])*")/,/^(?:\{)/,/^(?:\})/,/^(?:\[)/,/^(?:\])/,/^(?:,)/,/^(?::)/,/^(?:true\b)/,/^(?:false\b)/,/^(?:null\b)/,/^(?:$)/,/^(?:.)/]; +lexer.conditions = {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13],"inclusive":true}}; + + +; +return lexer;})() +parser.lexer = lexer; +return parser; +})(); +if (typeof require !== 'undefined' && typeof exports !== 'undefined') { +exports.parser = jsonlint; +exports.parse = function () { return jsonlint.parse.apply(jsonlint, arguments); } +} diff --git a/examples/common/templates/index.jade b/examples/common/templates/index.jade index b314e4a9f5..0d1102d334 100644 --- a/examples/common/templates/index.jade +++ b/examples/common/templates/index.jade @@ -5,15 +5,10 @@ html(lang="en") link(rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon") title= title - // Include common files - each css in defaultCss - link(rel="stylesheet" href="#{css}") - each src in defaultJs - if(typeof src == "string") - script(type="text/javascript" src="#{src}") - else - script&attributes(src) + // include the main bundle + script(type='text/javascript' src='#{bundle}' charset='UTF-8') + // include example sources block exampleHeader // Include example specific files each css in exampleCss diff --git a/examples/dynamicData/main.js b/examples/dynamicData/main.js index baccf30239..0ebff4ee19 100644 --- a/examples/dynamicData/main.js +++ b/examples/dynamicData/main.js @@ -15,7 +15,7 @@ $(function () { .state('play'); // Add an OSM layer with MapQuest satellite image tiles - var osm = map.createLayer('osm', { + map.createLayer('osm', { baseUrl: 'http://otile1.mqcdn.com/tiles/1.0.0/sat' }); diff --git a/examples/geoJSON/example.json b/examples/geoJSON/example.json index 59c0ee7429..ed22cca2aa 100644 --- a/examples/geoJSON/example.json +++ b/examples/geoJSON/example.json @@ -1,8 +1,8 @@ { "path": "geoJSON", "title": "GeoJSON file reader", - "exampleCss": ["main.css", "../common/css/codemirror.css", "../common/css/lint.css", "../common/css/foldgutter.css"], - "exampleJs": ["main.js", "../common/js/codemirror.js"], + "exampleCss": ["main.css"], + "exampleJs": ["main.js"], "about": { "text": "Shows how to use the included geoJSON reader, and how to use the properties to adjust the style of the features. In this example, you can edit the json file while the features on the map update in response. You can also drop a new geoJSON file onto the text editor to load it." } diff --git a/examples/geoJSON/main.js b/examples/geoJSON/main.js index 452a07d563..161514e110 100644 --- a/examples/geoJSON/main.js +++ b/examples/geoJSON/main.js @@ -1,4 +1,3 @@ -/* global CodeMirror, jsonlint */ // Run after the DOM loads $(function () { 'use strict'; diff --git a/examples/heatmap/main.js b/examples/heatmap/main.js index fb0f376082..a27b5c9d73 100644 --- a/examples/heatmap/main.js +++ b/examples/heatmap/main.js @@ -1,5 +1,3 @@ -/* globals geo, $ */ - // Run after the DOM loads $(function () { 'use strict'; @@ -142,7 +140,7 @@ $(function () { rows.splice(rows.length - 1, 1); rows = rows.map(function (r) { var fields = r.split('","'); - return ['' + fields[0].replace(/(^\s+|\s+$|^\"|\"$)/g, '').length, fields[2].replace(/(^\s+|\s+$|^\"|\"$)/g, ''), fields[3].replace(/(^\s+|\s+$|^\"|\"$)/g, '')].map(parseFloat); + return ['' + fields[0].replace(/(^\s+|\s+$|^"|"$)/g, '').length, fields[2].replace(/(^\s+|\s+$|^"|"$)/g, ''), fields[3].replace(/(^\s+|\s+$|^"|"$)/g, '')].map(parseFloat); }); break; case 'earthquakes': diff --git a/examples/index.js b/examples/index.js new file mode 100644 index 0000000000..1780b29d32 --- /dev/null +++ b/examples/index.js @@ -0,0 +1,26 @@ +require('../src/vendor'); +window.geo = require('../src/index'); + +// bootstrap and themes +require('bootstrap/dist/css/bootstrap.css'); +require('bootswatch/flatly/bootstrap.css'); +require('bootstrap'); + +// codemirror and plugins +require('codemirror/lib/codemirror.css'); +require('codemirror/addon/lint/lint.css'); +require('codemirror/addon/fold/foldgutter.css'); + +require('./common/js/jsonlint'); +require('codemirror'); +require('codemirror/mode/javascript/javascript'); +require('codemirror/addon/lint/lint'); +require('codemirror/addon/lint/json-lint'); +require('codemirror/addon/fold/brace-fold'); +require('codemirror/addon/fold/foldcode'); +require('codemirror/addon/fold/foldgutter'); +require('codemirror/addon/edit/matchbrackets'); + +// common example code +require('./common/css/examples.css'); +require('./common/js/examples'); diff --git a/examples/legend/main.js b/examples/legend/main.js index 9592f8d34e..7416142475 100644 --- a/examples/legend/main.js +++ b/examples/legend/main.js @@ -27,7 +27,6 @@ $(function () { } }); - // Add rows to the legend // // The categories are displayed in the order passed as @@ -113,7 +112,6 @@ $(function () { } ]); - // Draw the map map.draw(); }); diff --git a/examples/picking/main.js b/examples/picking/main.js index 8c2bca453f..c57d128cc1 100644 --- a/examples/picking/main.js +++ b/examples/picking/main.js @@ -4,14 +4,14 @@ $(function () { // Create a map object with the OpenStreetMaps base layer. var map = geo.map({ - node: '#map', - center: { - x: -98.0, - y: 39.5 - }, - zoom: 4 - }), - over = 0; + node: '#map', + center: { + x: -98.0, + y: 39.5 + }, + zoom: 4 + }), + over = 0; // Create an osm layer map.createLayer('osm'); diff --git a/examples/points/main.js b/examples/points/main.js index 76a2f9d684..e7140ac29c 100644 --- a/examples/points/main.js +++ b/examples/points/main.js @@ -5,7 +5,6 @@ $(function () { // Define a function we will use to generate points. function makePoints(data, layer, color) { - // The API for creating features is similar to d3's data API. // The data is an array of arbitrary objects. Each object in // the array is assumed to be a "point". You provide accessors diff --git a/examples/reprojection/main.js b/examples/reprojection/main.js index 306a17254a..be1b913d2c 100644 --- a/examples/reprojection/main.js +++ b/examples/reprojection/main.js @@ -12,26 +12,26 @@ $(function () { // renderer, but may have problems as the tile density is not uniform or // regular. var gcsTable = { - 'EPSG:3857': 'EPSG:3857', + 'EPSG:3857': 'EPSG:3857' }; var gcsBounds = {}; var gcsList = [ - 'EPSG:3857', 'EPSG:3031', 'EPSG:3032', 'EPSG:3033', 'EPSG:3294', - 'EPSG:3408', 'EPSG:3409', 'EPSG:3410', 'EPSG:3411', 'EPSG:3412', - 'EPSG:3413', 'EPSG:3571', 'EPSG:3572', 'EPSG:3573', 'EPSG:3574', - 'EPSG:3575', 'EPSG:3576', 'EPSG:3786', 'EPSG:32661', 'EPSG:32662', - 'ESRI:53002', 'ESRI:53003', 'ESRI:53008', 'ESRI:53009', 'ESRI:53021', - 'ESRI:53027', 'ESRI:54002', 'ESRI:54003', 'ESRI:54009', 'ESRI:54021', - 'ESRI:54026', 'ESRI:54027', 'ESRI:102005', 'ESRI:102010', 'ESRI:102011', - 'ESRI:102016', 'ESRI:102017', 'ESRI:102018', 'ESRI:102019', - 'ESRI:102020', 'ESRI:102021', 'ESRI:102023', 'ESRI:102026', - 'ESRI:102029', 'ESRI:102031', 'ESRI:102032', 'IAU2000:39914', - 'IAU2000:39918', 'IAU2000:39920', 'IAU2000:39962', 'IAU2000:39972', - 'SR-ORG:7', 'SR-ORG:22', 'SR-ORG:4695', 'SR-ORG:6661', 'SR-ORG:6842', - 'SR-ORG:6882', 'SR-ORG:6888', 'SR-ORG:6890', 'SR-ORG:6891', - 'SR-ORG:6892', 'SR-ORG:6893', 'SR-ORG:6894', 'SR-ORG:6895', - 'SR-ORG:6896', 'SR-ORG:6897', 'SR-ORG:6898', 'SR-ORG:7250', - 'SR-ORG:8209', 'SR-ORG:8287' + 'EPSG:3857', 'EPSG:3031', 'EPSG:3032', 'EPSG:3033', 'EPSG:3294', + 'EPSG:3408', 'EPSG:3409', 'EPSG:3410', 'EPSG:3411', 'EPSG:3412', + 'EPSG:3413', 'EPSG:3571', 'EPSG:3572', 'EPSG:3573', 'EPSG:3574', + 'EPSG:3575', 'EPSG:3576', 'EPSG:3786', 'EPSG:32661', 'EPSG:32662', + 'ESRI:53002', 'ESRI:53003', 'ESRI:53008', 'ESRI:53009', 'ESRI:53021', + 'ESRI:53027', 'ESRI:54002', 'ESRI:54003', 'ESRI:54009', 'ESRI:54021', + 'ESRI:54026', 'ESRI:54027', 'ESRI:102005', 'ESRI:102010', 'ESRI:102011', + 'ESRI:102016', 'ESRI:102017', 'ESRI:102018', 'ESRI:102019', + 'ESRI:102020', 'ESRI:102021', 'ESRI:102023', 'ESRI:102026', + 'ESRI:102029', 'ESRI:102031', 'ESRI:102032', 'IAU2000:39914', + 'IAU2000:39918', 'IAU2000:39920', 'IAU2000:39962', 'IAU2000:39972', + 'SR-ORG:7', 'SR-ORG:22', 'SR-ORG:4695', 'SR-ORG:6661', 'SR-ORG:6842', + 'SR-ORG:6882', 'SR-ORG:6888', 'SR-ORG:6890', 'SR-ORG:6891', + 'SR-ORG:6892', 'SR-ORG:6893', 'SR-ORG:6894', 'SR-ORG:6895', + 'SR-ORG:6896', 'SR-ORG:6897', 'SR-ORG:6898', 'SR-ORG:7250', + 'SR-ORG:8209', 'SR-ORG:8287' ]; var capitals; diff --git a/examples/tiles/main.js b/examples/tiles/main.js index a1ab64e4bc..9785a2d1f1 100644 --- a/examples/tiles/main.js +++ b/examples/tiles/main.js @@ -1,4 +1,3 @@ -/* globals $, geo */ // This example should be tried with different query strings. /* Many parameters can be adjusted via url query parameters: diff --git a/examples/widgets/chart.js b/examples/widgets/chart.js index 1833e59eff..6201182b39 100644 --- a/examples/widgets/chart.js +++ b/examples/widgets/chart.js @@ -6,7 +6,7 @@ $(function () { width = 710 - margin.left - margin.right, height = 410 - margin.top - margin.bottom; - var parseDate = d3.time.format("%Y%m%d").parse; + var parseDate = d3.time.format('%Y%m%d').parse; var x = d3.time.scale() .range([0, width]); @@ -18,79 +18,79 @@ $(function () { var xAxis = d3.svg.axis() .scale(x) - .tickFormat(d3.time.format("%b")) - .orient("bottom"); + .tickFormat(d3.time.format('%b')) + .orient('bottom'); var yAxis = d3.svg.axis() .scale(y) - .orient("left"); + .orient('left'); var line = d3.svg.line() - .interpolate("basis") - .x(function(d) { return x(d.date); }) - .y(function(d) { return y(d.temperature); }); + .interpolate('basis') + .x(function (d) { return x(d.date); }) + .y(function (d) { return y(d.temperature); }); - var svg = d3.select("#svg-container").append("svg") - .attr("width", 710 + margin.right + margin.left) - .attr("height", height + margin.top + margin.bottom) - .append("g") - .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); + var svg = d3.select('#svg-container').append('svg') + .attr('width', 710 + margin.right + margin.left) + .attr('height', height + margin.top + margin.bottom) + .append('g') + .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); - d3.tsv("../../data/temperature_data.tsv", function(error, data) { + d3.tsv('../../data/temperature_data.tsv', function (error, data) { if (error) throw error; - color.domain(d3.keys(data[0]).filter(function(key) { return key !== "date"; })); + color.domain(d3.keys(data[0]).filter(function (key) { return key !== 'date'; })); - data.forEach(function(d) { + data.forEach(function (d) { d.date = parseDate(d.date); }); - var cities = color.domain().map(function(name) { + var cities = color.domain().map(function (name) { return { name: name, - values: data.map(function(d) { + values: data.map(function (d) { return {date: d.date, temperature: +d[name]}; }) }; }); - x.domain(d3.extent(data, function(d) { return d.date; })); + x.domain(d3.extent(data, function (d) { return d.date; })); y.domain([ - d3.min(cities, function(c) { return d3.min(c.values, function(v) { return v.temperature; }); }), - d3.max(cities, function(c) { return d3.max(c.values, function(v) { return v.temperature; }); }) + d3.min(cities, function (c) { return d3.min(c.values, function (v) { return v.temperature; }); }), + d3.max(cities, function (c) { return d3.max(c.values, function (v) { return v.temperature; }); }) ]); - svg.append("g") - .attr("class", "x axis") - .attr("transform", "translate(0," + height + ")") + svg.append('g') + .attr('class', 'x axis') + .attr('transform', 'translate(0,' + height + ')') .call(xAxis); - svg.append("g") - .attr("class", "y axis") + svg.append('g') + .attr('class', 'y axis') .call(yAxis) - .append("text") - .attr("transform", "rotate(-90)") - .attr("y", 6) - .attr("dy", ".71em") - .style("text-anchor", "end") - .text("Temperature (ºF)"); - - var city = svg.selectAll(".city") + .append('text') + .attr('transform', 'rotate(-90)') + .attr('y', 6) + .attr('dy', '.71em') + .style('text-anchor', 'end') + .text('Temperature (ºF)'); + + var city = svg.selectAll('.city') .data(cities) - .enter().append("g") - .attr("class", "city"); - - city.append("path") - .attr("class", "line") - .attr("d", function(d) { return line(d.values); }) - .style("stroke", function(d) { return color(d.name); }); - - city.append("text") - .datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; }) - .attr("transform", function(d) { return "translate(" + x(d.value.date) + "," + y(d.value.temperature) + ")"; }) - .attr("x", 3) - .attr("dy", ".35em") - .text(function(d) { return d.name; }); + .enter().append('g') + .attr('class', 'city'); + + city.append('path') + .attr('class', 'line') + .attr('d', function (d) { return line(d.values); }) + .style('stroke', function (d) { return color(d.name); }); + + city.append('text') + .datum(function (d) { return {name: d.name, value: d.values[d.values.length - 1]}; }) + .attr('transform', function (d) { return 'translate(' + x(d.value.date) + ',' + y(d.value.temperature) + ')'; }) + .attr('x', 3) + .attr('dy', '.35em') + .text(function (d) { return d.name; }); }); }); diff --git a/external.config.js b/external.config.js index ccb89c0691..93de2eb858 100644 --- a/external.config.js +++ b/external.config.js @@ -14,7 +14,6 @@ module.exports = { }, resolve: { alias: { - jquery: 'jquery/dist/jquery', d3: 'd3/d3.js' } }, @@ -28,8 +27,6 @@ module.exports = { module: { loaders: [{ test: require.resolve('d3'), loader: 'expose?d3' - }, { - test: require.resolve('jquery'), loader: 'expose?$!expose?jQuery' }] } }; diff --git a/package.json b/package.json index d923acc2d4..426452adfb 100644 --- a/package.json +++ b/package.json @@ -20,57 +20,65 @@ "bootstrap": "^3.3.6", "bootswatch": "^3.3.6", "codecov.io": "^0.1.6", - "codemirror": "^4.7.0", + "codemirror": "^5.15.2", + "css-loader": "^0.23.1", + "docco": "^0.7.0", "earcut": "^2.1.1", - "eslint": "^1.10.3", - "eslint-config-semistandard": "^5.0.1", - "eslint-config-standard": "^4.4.0", + "eslint": "^2.10.2", + "eslint-config-semistandard": "^6.0.2", + "eslint-config-standard": "^5.3.1", + "eslint-plugin-promise": "^1.3.0", "eslint-plugin-standard": "^1.3.2", "exports-loader": "^0.6.3", "expose-loader": "^0.7.1", "express": "^4.13.4", + "file-loader": "^0.8.5", + "forever": "^0.15.2", "gl-mat3": "^1.0.0", "gl-mat4": "^1.1.4", "gl-vec2": "^1.0.0", "gl-vec3": "^1.0.3", "gl-vec4": "^1.0.1", - "grunt": "~0.4", - "grunt-cli": "~0.1", - "grunt-contrib-copy": "~1.0", - "grunt-contrib-jade": "~1.0.0", - "grunt-contrib-uglify": "~1.0", - "grunt-docco": "^0.4.0", - "grunt-express": "~1.4", + "glob": "^7.0.3", "imports-loader": "^0.6.5", "istanbul-instrumenter-loader": "^0.2.0", + "jade": "^1.11.0", + "jade-loader": "^0.8.0", "jasmine-core": "^2.4.1", "jquery": "~2.2.1", "jsdoc": "^3.4", "json-loader": "^0.5.4", - "jsonlint": "^1.6.2", "karma": "^0.13.22", - "karma-coverage": "^0.5.5", - "karma-jasmine": "^0.3.8", + "karma-coverage": "^1.0.0", + "karma-jasmine": "^1.0.2", "karma-jasmine-html-reporter": "^0.2.0", "karma-phantomjs-launcher": "^1.0.0", "karma-sinon": "^1.0.4", "karma-sourcemap-loader": "^0.3.7", "karma-webpack": "^1.7.0", + "node-fs-extra": "^0.8.1", "phantomjs-prebuilt": "^2.1.5", "proj4": "^2.3.14", "raw-body": "^2.1.6", - "sinon": "^1.17.3", + "sinon": "1.17.3", + "style-loader": "^0.13.1", + "url-loader": "^0.5.7", "vgl": "0.3.6", "webpack": "^1.12.14", - "xmlbuilder": "^5.0.1" + "webpack-dev-server": "^1.14.1", + "xmlbuilder": "^8.2.2" }, "scripts": { "build": "webpack --config webpack.config.js && webpack --config external.config.js", - "lint": "eslint --cache src Gruntfile.js tests", + "lint": "eslint --cache .", "test": "karma start karma-cov.conf.js --single-run", "start": "karma start karma.conf.js", "ci": "karma start karma-cov.conf.js --single-run --browsers PhantomJS", - "codecov": "cat lcov/*/lcov.info | codecov" + "codecov": "cat lcov/*/lcov.info | codecov", + "examples": "webpack-dev-server --config webpack-examples.config.js --port 8082 --content-base dist/", + "start-test": "node examples/build.js; forever start ./testing/test-runners/server.js", + "stop-test": "forever stop ./testing/test-runners/server.js", + "docs": "jsdoc --pedantic -d dist/apidocs -r src" }, "keywords": [ "map", diff --git a/src/camera.js b/src/camera.js index fc35b8d263..11e3fcc3ea 100644 --- a/src/camera.js +++ b/src/camera.js @@ -214,11 +214,11 @@ var mat; if (this._display === null) { mat = camera.affine( - {x: 1, y: 1}, // translate to: [0, 2] x [0, 2] - { - x: this.viewport.width / 2, - y: this.viewport.height / -2 - } // scale to: [0, width] x [-height, 0] + {x: 1, y: 1}, // translate to: [0, 2] x [0, 2] + { + x: this.viewport.width / 2, + y: this.viewport.height / -2 + } // scale to: [0, width] x [-height, 0] ); // applies mat to the transform (world -> normalized) diff --git a/src/choroplethFeature.js b/src/choroplethFeature.js index da368ef6d2..35eef95f7d 100644 --- a/src/choroplethFeature.js +++ b/src/choroplethFeature.js @@ -31,36 +31,36 @@ var choroplethFeature = function (arg) { m_this = this, s_init = this._init, m_choropleth = $.extend({}, - { - /* 9-step based on paraview bwr colortable */ - colorRange: [ - {r: 0.07514311, g: 0.468049805, b: 1}, - {r: 0.468487184, g: 0.588057293, b: 1}, - {r: 0.656658579, g: 0.707001303, b: 1}, - {r: 0.821573924, g: 0.837809045, b: 1}, - {r: 0.943467973, g: 0.943498599, b: 0.943398095}, - {r: 1, g: 0.788626485, b: 0.750707739}, - {r: 1, g: 0.6289553, b: 0.568237474}, - {r: 1, g: 0.472800903, b: 0.404551679}, - {r: 0.916482116, g: 0.236630659, b: 0.209939162} - ], - scale: d3.scale.quantize(), - accessors: { - //accessor for ID on geodata feature - geoId: function (geoFeature) { - return geoFeature.properties.GEO_ID; - }, - //accessor for ID on scalar element - scalarId: function (scalarElement) { - return scalarElement.id; - }, - //accessor for value on scalar element - scalarValue: function (scalarElement) { - return scalarElement.value; - } + { + /* 9-step based on paraview bwr colortable */ + colorRange: [ + {r: 0.07514311, g: 0.468049805, b: 1}, + {r: 0.468487184, g: 0.588057293, b: 1}, + {r: 0.656658579, g: 0.707001303, b: 1}, + {r: 0.821573924, g: 0.837809045, b: 1}, + {r: 0.943467973, g: 0.943498599, b: 0.943398095}, + {r: 1, g: 0.788626485, b: 0.750707739}, + {r: 1, g: 0.6289553, b: 0.568237474}, + {r: 1, g: 0.472800903, b: 0.404551679}, + {r: 0.916482116, g: 0.236630659, b: 0.209939162} + ], + scale: d3.scale.quantize(), + accessors: { + //accessor for ID on geodata feature + geoId: function (geoFeature) { + return geoFeature.properties.GEO_ID; + }, + //accessor for ID on scalar element + scalarId: function (scalarElement) { + return scalarElement.id; + }, + //accessor for value on scalar element + scalarValue: function (scalarElement) { + return scalarElement.value; } - }, - arg.choropleth); + } + }, + arg.choropleth); //////////////////////////////////////////////////////////////////////////// /** diff --git a/src/contourFeature.js b/src/contourFeature.js index 45dddcaf28..efba6fa6cc 100644 --- a/src/contourFeature.js +++ b/src/contourFeature.js @@ -68,26 +68,26 @@ var contourFeature = function (arg) { } if (arg2 === undefined) { var contour = $.extend( - {}, - { - gridWidth: function () { - if (arg1.gridHeight) { - return Math.floor(m_this.data().length / arg1.gridHeight); - } - return Math.floor(Math.sqrt(m_this.data().length)); - }, - gridHeight: function () { - if (arg1.gridWidth) { - return Math.floor(m_this.data().length / arg1.gridWidth); - } - return Math.floor(Math.sqrt(m_this.data().length)); - }, - minColor: 'black', - minOpacity: 0, - maxColor: 'black', - maxOpacity: 0, - /* 9-step based on paraview bwr colortable */ - colorRange: [ + {}, + { + gridWidth: function () { + if (arg1.gridHeight) { + return Math.floor(m_this.data().length / arg1.gridHeight); + } + return Math.floor(Math.sqrt(m_this.data().length)); + }, + gridHeight: function () { + if (arg1.gridWidth) { + return Math.floor(m_this.data().length / arg1.gridWidth); + } + return Math.floor(Math.sqrt(m_this.data().length)); + }, + minColor: 'black', + minOpacity: 0, + maxColor: 'black', + maxOpacity: 0, + /* 9-step based on paraview bwr colortable */ + colorRange: [ {r: 0.07514311, g: 0.468049805, b: 1}, {r: 0.468487184, g: 0.588057293, b: 1}, {r: 0.656658579, g: 0.707001303, b: 1}, @@ -97,8 +97,8 @@ var contourFeature = function (arg) { {r: 1, g: 0.6289553, b: 0.568237474}, {r: 1, g: 0.472800903, b: 0.404551679}, {r: 0.916482116, g: 0.236630659, b: 0.209939162} - ] - }, + ] + }, m_contour, arg1 ); @@ -366,16 +366,16 @@ var contourFeature = function (arg) { s_init.call(m_this, arg); var defaultStyle = $.extend( - {}, - { - opacity: 1.0, - position: function (d) { - return {x: d.x, y: d.y, z: d.z}; - }, - value: function (d) { - return m_this.position()(d).z; - } + {}, + { + opacity: 1.0, + position: function (d) { + return {x: d.x, y: d.y, z: d.z}; }, + value: function (d) { + return m_this.position()(d).z; + } + }, arg.style === undefined ? {} : arg.style ); diff --git a/src/graphFeature.js b/src/graphFeature.js index e36918847b..86f96994b9 100644 --- a/src/graphFeature.js +++ b/src/graphFeature.js @@ -47,18 +47,18 @@ var graphFeature = function (arg) { s_init.call(m_this, arg); var defaultStyle = $.extend(true, {}, - { - nodes: { - radius: 5.0, - fill: true, - fillColor: { r: 1.0, g: 0.0, b: 0.0 }, - strokeColor: { r: 0, g: 0, b: 0 } - }, - links: { - strokeColor: { r: 0.0, g: 0.0, b: 0.0 } - }, - linkType: 'path' /* 'path' || 'line' */ + { + nodes: { + radius: 5.0, + fill: true, + fillColor: { r: 1.0, g: 0.0, b: 0.0 }, + strokeColor: { r: 0, g: 0, b: 0 } }, + links: { + strokeColor: { r: 0.0, g: 0.0, b: 0.0 } + }, + linkType: 'path' /* 'path' || 'line' */ + }, arg.style === undefined ? {} : arg.style ); diff --git a/src/heatmapFeature.js b/src/heatmapFeature.js index 8b13675cef..fa1d7aac7b 100644 --- a/src/heatmapFeature.js +++ b/src/heatmapFeature.js @@ -216,16 +216,16 @@ var heatmapFeature = function (arg) { var defaultStyle = $.extend( {}, - { - radius: 10, - blurRadius: 10, - gaussian: true, - color: {0: {r: 0, g: 0, b: 0.0, a: 0.0}, - 0.25: {r: 0, g: 0, b: 1, a: 0.5}, - 0.5: {r: 0, g: 1, b: 1, a: 0.6}, - 0.75: {r: 1, g: 1, b: 0, a: 0.7}, - 1: {r: 1, g: 0, b: 0, a: 0.8}} - }, + { + radius: 10, + blurRadius: 10, + gaussian: true, + color: {0: {r: 0, g: 0, b: 0.0, a: 0.0}, + 0.25: {r: 0, g: 0, b: 1, a: 0.5}, + 0.5: {r: 0, g: 1, b: 1, a: 0.6}, + 0.75: {r: 1, g: 1, b: 0, a: 0.7}, + 1: {r: 1, g: 0, b: 0, a: 0.8}} + }, arg.style === undefined ? {} : arg.style ); diff --git a/src/lineFeature.js b/src/lineFeature.js index 890565ab3f..ece37e003e 100644 --- a/src/lineFeature.js +++ b/src/lineFeature.js @@ -101,11 +101,11 @@ var lineFeature = function (arg) { if (t < 0) { return dist2(q, u); } if (t > 1) { return dist2(q, v); } return dist2( - q, - { - x: u.x + t * (v.x - u.x), - y: u.y + t * (v.y - u.y) - } + q, + { + x: u.x + t * (v.x - u.x), + y: u.y + t * (v.y - u.y) + } ); } @@ -200,16 +200,16 @@ var lineFeature = function (arg) { s_init.call(m_this, arg); var defaultStyle = $.extend( - {}, - { - 'strokeWidth': 1.0, - // Default to gold color for lines - 'strokeColor': { r: 1.0, g: 0.8431372549, b: 0.0 }, - 'strokeStyle': 'solid', - 'strokeOpacity': 1.0, - 'line': function (d) { return d; }, - 'position': function (d) { return d; } - }, + {}, + { + 'strokeWidth': 1.0, + // Default to gold color for lines + 'strokeColor': { r: 1.0, g: 0.8431372549, b: 0.0 }, + 'strokeStyle': 'solid', + 'strokeOpacity': 1.0, + 'line': function (d) { return d; }, + 'position': function (d) { return d; } + }, arg.style === undefined ? {} : arg.style ); diff --git a/src/mapInteractor.js b/src/mapInteractor.js index 1285175a52..58612d9c78 100644 --- a/src/mapInteractor.js +++ b/src/mapInteractor.js @@ -58,54 +58,54 @@ var mapInteractor = function (args) { // copy the options object with defaults m_options = $.extend( - true, - {}, - { - throttle: 30, - discreteZoom: false, - panMoveButton: 'left', - panMoveModifiers: {}, - zoomMoveButton: 'right', - zoomMoveModifiers: {}, - rotateMoveButton: 'left', - rotateMoveModifiers: {'ctrl': true}, - panWheelEnabled: false, - panWheelModifiers: {}, - zoomWheelEnabled: true, - zoomWheelModifiers: {}, - rotateWheelEnabled: true, - rotateWheelModifiers: {'ctrl': true}, - wheelScaleX: 1, - wheelScaleY: 1, - zoomScale: 1, - rotateWheelScale: 6 * Math.PI / 180, - selectionButton: 'left', - selectionModifiers: {'shift': true}, - momentum: { - enabled: true, - maxSpeed: 2.5, - minSpeed: 0.01, - stopTime: 250, - drag: 0.01, - actions: ['pan', 'zoom'] - }, - spring: { - enabled: false, - springConstant: 0.00005 - }, - click: { - enabled: true, - buttons: {left: true, right: true, middle: true}, - duration: 0, - cancelOnMove: true - }, - zoomAnimation: { - enabled: true, - duration: 500, - ease: function (t) { return (2 - t) * t; } - } + true, + {}, + { + throttle: 30, + discreteZoom: false, + panMoveButton: 'left', + panMoveModifiers: {}, + zoomMoveButton: 'right', + zoomMoveModifiers: {}, + rotateMoveButton: 'left', + rotateMoveModifiers: {'ctrl': true}, + panWheelEnabled: false, + panWheelModifiers: {}, + zoomWheelEnabled: true, + zoomWheelModifiers: {}, + rotateWheelEnabled: true, + rotateWheelModifiers: {'ctrl': true}, + wheelScaleX: 1, + wheelScaleY: 1, + zoomScale: 1, + rotateWheelScale: 6 * Math.PI / 180, + selectionButton: 'left', + selectionModifiers: {'shift': true}, + momentum: { + enabled: true, + maxSpeed: 2.5, + minSpeed: 0.01, + stopTime: 250, + drag: 0.01, + actions: ['pan', 'zoom'] + }, + spring: { + enabled: false, + springConstant: 0.00005 }, - m_options + click: { + enabled: true, + buttons: {left: true, right: true, middle: true}, + duration: 0, + cancelOnMove: true + }, + zoomAnimation: { + enabled: true, + duration: 500, + ease: function (t) { return (2 - t) * t; } + } + }, + m_options ); // options supported: @@ -1400,24 +1400,24 @@ var mapInteractor = function (args) { options.wheelDelta = options.wheelDelta || {}; evt = $.Event( - type, - { - pageX: page.x, - pageY: page.y, - which: which, - altKey: options.modifiers.indexOf('alt') >= 0, - ctrlKey: options.modifiers.indexOf('ctrl') >= 0, - metaKey: options.modifiers.indexOf('meta') >= 0, - shiftKey: options.modifiers.indexOf('shift') >= 0, - originalEvent: { - deltaX: options.wheelDelta.x, - deltaY: options.wheelDelta.y, - deltaMode: options.wheelMode, - preventDefault: function () {}, - stopPropagation: function () {}, - stopImmediatePropagation: function () {} - } + type, + { + pageX: page.x, + pageY: page.y, + which: which, + altKey: options.modifiers.indexOf('alt') >= 0, + ctrlKey: options.modifiers.indexOf('ctrl') >= 0, + metaKey: options.modifiers.indexOf('meta') >= 0, + shiftKey: options.modifiers.indexOf('shift') >= 0, + originalEvent: { + deltaX: options.wheelDelta.x, + deltaY: options.wheelDelta.y, + deltaMode: options.wheelMode, + preventDefault: function () {}, + stopPropagation: function () {}, + stopImmediatePropagation: function () {} } + } ); $node.trigger(evt); }; diff --git a/src/pathFeature.js b/src/pathFeature.js index b2048d97e0..7bd659ab10 100644 --- a/src/pathFeature.js +++ b/src/pathFeature.js @@ -55,11 +55,11 @@ var pathFeature = function (arg) { s_init.call(m_this, arg); var defaultStyle = $.extend( - {}, - { - 'strokeWidth': function () { return 1; }, - 'strokeColor': function () { return { r: 1.0, g: 1.0, b: 1.0 }; } - }, + {}, + { + 'strokeWidth': function () { return 1; }, + 'strokeColor': function () { return { r: 1.0, g: 1.0, b: 1.0 }; } + }, arg.style === undefined ? {} : arg.style ); diff --git a/src/pointFeature.js b/src/pointFeature.js index 5bd48994ca..36d7e3fd43 100644 --- a/src/pointFeature.js +++ b/src/pointFeature.js @@ -380,20 +380,20 @@ var pointFeature = function (arg) { s_init.call(m_this, arg); var defaultStyle = $.extend( - {}, - { - radius: 5.0, - stroke: true, - strokeColor: { r: 0.851, g: 0.604, b: 0.0 }, - strokeWidth: 1.25, - strokeOpacity: 1.0, - fillColor: { r: 1.0, g: 0.839, b: 0.439 }, - fill: true, - fillOpacity: 0.8, - sprites: false, - sprites_image: null, - position: function (d) { return d; } - }, + {}, + { + radius: 5.0, + stroke: true, + strokeColor: { r: 0.851, g: 0.604, b: 0.0 }, + strokeWidth: 1.25, + strokeOpacity: 1.0, + fillColor: { r: 1.0, g: 0.839, b: 0.439 }, + fill: true, + fillOpacity: 0.8, + sprites: false, + sprites_image: null, + position: function (d) { return d; } + }, arg.style === undefined ? {} : arg.style ); diff --git a/src/polygonFeature.js b/src/polygonFeature.js index 3cdc7fd4af..8d704d9873 100644 --- a/src/polygonFeature.js +++ b/src/polygonFeature.js @@ -168,12 +168,12 @@ var polygonFeature = function (arg) { s_init.call(m_this, arg); var defaultStyle = $.extend( - {}, - { - 'fillColor': { r: 0.0, g: 0.5, b: 0.5 }, - 'fillOpacity': 1.0 - }, - arg.style === undefined ? {} : arg.style + {}, + { + 'fillColor': { r: 0.0, g: 0.5, b: 0.5 }, + 'fillOpacity': 1.0 + }, + arg.style === undefined ? {} : arg.style ); m_this.style(defaultStyle); diff --git a/src/quadFeature.js b/src/quadFeature.js index b7a72477e7..41fe4eeac8 100644 --- a/src/quadFeature.js +++ b/src/quadFeature.js @@ -399,18 +399,18 @@ var quadFeature = function (arg) { m_cacheQuads = (arg.cacheQuads !== false); var style = $.extend( - {}, - { - color: { r: 1.0, g: 1, b: 1 }, - opacity: 1, - depth: 0, - drawOnAsyncResourceLoaded: true, - previewColor: null, - previewImage: null, - image: function (d) { return d.image; }, - position: function (d) { return d; } - }, - arg.style === undefined ? {} : arg.style + {}, + { + color: { r: 1.0, g: 1, b: 1 }, + opacity: 1, + depth: 0, + drawOnAsyncResourceLoaded: true, + previewColor: null, + previewImage: null, + image: function (d) { return d.image; }, + position: function (d) { return d; } + }, + arg.style === undefined ? {} : arg.style ); if (arg.position !== undefined) { diff --git a/src/vectorFeature.js b/src/vectorFeature.js index cdcec0faa4..a8350bded2 100644 --- a/src/vectorFeature.js +++ b/src/vectorFeature.js @@ -75,17 +75,17 @@ var vectorFeature = function (arg) { s_init.call(m_this, arg); var defaultStyle = $.extend( - {}, - { - strokeColor: 'black', - strokeWidth: 2.0, - strokeOpacity: 1.0, - originStyle: 'none', - endStyle: 'arrow', - origin: {x: 0, y: 0, z: 0}, - delta: function (d) { return d; }, - scale: null // size scaling factor (null -> renderer decides) - }, + {}, + { + strokeColor: 'black', + strokeWidth: 2.0, + strokeOpacity: 1.0, + originStyle: 'none', + endStyle: 'arrow', + origin: {x: 0, y: 0, z: 0}, + delta: function (d) { return d; }, + scale: null // size scaling factor (null -> renderer decides) + }, arg.style === undefined ? {} : arg.style ); diff --git a/testing/test-runners/aggregate-json-reporter.js.in b/testing/test-runners/aggregate-json-reporter.js.in deleted file mode 100644 index 91004b0724..0000000000 --- a/testing/test-runners/aggregate-json-reporter.js.in +++ /dev/null @@ -1,69 +0,0 @@ -/*global $, blanket, window*/ - -(function () { - 'use strict'; - - var ncalls = 0; - - function setStatus() { - $('body').attr('class', 'reporter-done'); - } - - /** - * Wait for jasmine to be done, then do the setStatus - */ - function wait() { - ncalls += 1; - if (!window.jsApiReporter || window.jsApiReporter.finished === true) { - setStatus(); - return; - } - if (ncalls > 15) { - throw new Error('Jasmine test did not complete in time.'); - } - window.setTimeout(wait, 1000); - } - - function reporter(cov) { - - // convert sparse arrays into objects - var coverage = { - 'files': {} - }; - $.each(cov.files, function (fname, arr) { - var f = fname.split('/').slice(3).join('/'); - - // delete the source key - delete arr.source; - - coverage.files[f] = $.extend({}, arr); - }); - - // post coverage results to the server - $.ajax({ - url: '/coverage', - data: JSON.stringify(coverage), - dataType: 'json', - type: 'PUT', - contentType: 'application/json', - error: function (xhr, status, error) { - console.log('status:' + status); - console.log('error:' + error); - console.log('Failed to post coverage data to the server'); - wait(); - }, - success: function () { - console.log('Posted data to server successfully.'); - wait(); - } - }); - } - - var blanket = window.blanket; - if (blanket) { - blanket.options('reporter', reporter); - } else { - $(wait); - } - -}()); diff --git a/testing/test-runners/selenium-template.html.in b/testing/test-runners/selenium-template.html.in index bddaa93b77..ed743f325a 100644 --- a/testing/test-runners/selenium-template.html.in +++ b/testing/test-runners/selenium-template.html.in @@ -4,7 +4,6 @@ -