diff --git a/.gitignore b/.gitignore
index 9ac0ec3d0..07b06cbdb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,5 @@ bin
obj
# mstest test results
-TestResults
\ No newline at end of file
+TestResults
+node_modules
diff --git a/Jakefile.js b/Jakefile.js
new file mode 100644
index 000000000..db873d44f
--- /dev/null
+++ b/Jakefile.js
@@ -0,0 +1,67 @@
+var build = require('./build/build.js'),
+ lint = require('./build/hint.js');
+
+var COPYRIGHT = '/*\n Copyright (c) 2012, Smartrak, David Leaver\n' +
+ ' Leaflet.markercluster is an open-source JavaScript library for Marker Clustering on leaflet powered maps.\n' +
+ ' https://github.com/danzel/Leaflet.markercluster\n*/\n';
+
+desc('Check Leaflet.markercluster source for errors with JSHint');
+task('lint', function () {
+
+ var files = build.getFiles();
+
+ console.log('Checking for JS errors...');
+
+ var errorsFound = lint.jshint(files);
+
+ if (errorsFound > 0) {
+ console.log(errorsFound + ' error(s) found.\n');
+ fail();
+ } else {
+ console.log('\tCheck passed');
+ }
+});
+
+desc('Combine and compress Leaflet.markercluster source files');
+task('build', ['lint'], function (compsBase32, buildName) {
+
+ var files = build.getFiles(compsBase32);
+
+ console.log('Concatenating ' + files.length + ' files...');
+
+ var content = build.combineFiles(files),
+ newSrc = COPYRIGHT + content,
+
+ pathPart = 'dist/leaflet.markercluster' + (buildName ? '-' + buildName : ''),
+ srcPath = pathPart + '-src.js',
+
+ oldSrc = build.load(srcPath),
+ srcDelta = build.getSizeDelta(newSrc, oldSrc);
+
+ console.log('\tUncompressed size: ' + newSrc.length + ' bytes (' + srcDelta + ')');
+
+ if (newSrc === oldSrc) {
+ console.log('\tNo changes');
+ } else {
+ build.save(srcPath, newSrc);
+ console.log('\tSaved to ' + srcPath);
+ }
+
+ console.log('Compressing...');
+
+ var path = pathPart + '.js',
+ oldCompressed = build.load(path),
+ newCompressed = COPYRIGHT + build.uglify(content),
+ delta = build.getSizeDelta(newCompressed, oldCompressed);
+
+ console.log('\tCompressed size: ' + newCompressed.length + ' bytes (' + delta + ')');
+
+ if (newCompressed === oldCompressed) {
+ console.log('\tNo changes');
+ } else {
+ build.save(path, newCompressed);
+ console.log('\tSaved to ' + path);
+ }
+});
+
+task('default', ['build']);
diff --git a/build/build.html b/build/build.html
new file mode 100644
index 000000000..bf94db3fd
--- /dev/null
+++ b/build/build.html
@@ -0,0 +1,243 @@
+
+
+
+ Leaflet.markercluster Build Helper
+
+
+
+
+
+
+
+
Leaflet.markercluster Build Helper
+
+
+ Select All |
+ Deselect All
+
+
+
+
+
Building using Node and UglifyJS
+
+ - Download and install Node
+ - Run this in the command line:
+ npm install -g jake
+npm install jshint
+npm install uglify-js
+ - Run this command inside the Leaflet.markercluster directory:
+
+
Building using Closure Compiler
+
+ - Download Closure Compiler, extract it into
closure-compiler directory
+ - Run this command in the root Leaflet directory:
+
+
+
+
+
+
diff --git a/build/build.js b/build/build.js
new file mode 100644
index 000000000..355e740fe
--- /dev/null
+++ b/build/build.js
@@ -0,0 +1,79 @@
+var fs = require('fs'),
+ uglifyjs = require('uglify-js'),
+ deps = require('./deps.js').deps;
+
+exports.getFiles = function (compsBase32) {
+ var memo = {},
+ comps;
+
+ if (compsBase32) {
+ comps = parseInt(compsBase32, 32).toString(2).split('');
+ console.log('Managing dependencies...')
+ }
+
+ function addFiles(srcs) {
+ for (var j = 0, len = srcs.length; j < len; j++) {
+ memo[srcs[j]] = true;
+ }
+ }
+
+ for (var i in deps) {
+ if (comps) {
+ if (parseInt(comps.pop(), 2) === 1) {
+ console.log('\t* ' + i);
+ addFiles(deps[i].src);
+ } else {
+ console.log('\t ' + i);
+ }
+ } else {
+ addFiles(deps[i].src);
+ }
+ }
+
+ var files = [];
+
+ for (var src in memo) {
+ files.push('src/' + src);
+ }
+
+ return files;
+};
+
+exports.uglify = function (code) {
+ var pro = uglifyjs.uglify;
+
+ var ast = uglifyjs.parser.parse(code);
+ ast = pro.ast_mangle(ast, {mangle: true});
+ ast = pro.ast_squeeze(ast);
+ ast = pro.ast_squeeze_more(ast);
+
+ return pro.gen_code(ast) + ';';
+};
+
+exports.combineFiles = function (files) {
+ var content = '(function (window, undefined) {\n\n';
+ for (var i = 0, len = files.length; i < len; i++) {
+ content += fs.readFileSync(files[i], 'utf8') + '\n\n';
+ }
+ return content + '\n\n}(this));';
+};
+
+exports.save = function (savePath, compressed) {
+ return fs.writeFileSync(savePath, compressed, 'utf8');
+};
+
+exports.load = function (loadPath) {
+ try {
+ return fs.readFileSync(loadPath, 'utf8');
+ } catch (e) {
+ return null;
+ }
+};
+
+exports.getSizeDelta = function (newContent, oldContent) {
+ if (!oldContent) {
+ return 'new';
+ }
+ var delta = newContent.length - oldContent.length;
+ return (delta >= 0 ? '+' : '') + delta;
+};
\ No newline at end of file
diff --git a/build/deps.js b/build/deps.js
new file mode 100644
index 000000000..be2f9e006
--- /dev/null
+++ b/build/deps.js
@@ -0,0 +1,30 @@
+var deps = {
+ Core: {
+ src: ['MarkerClusterGroup.js',
+ 'MarkerCluster.js'],
+ desc: 'The core of the library.'
+ },
+
+ QuickHull: {
+ src: ['MarkerCluster.QuickHull.js'],
+ desc: 'ConvexHull generation. Used to show the area outline of the markers within a cluster.',
+ heading: 'QuickHull'
+ },
+
+ Spiderfier: {
+ src: ['MarkerCluster.Spiderfier.js'],
+ desc: 'Provides the ability to show all of the child markers of a cluster.',
+ heading: 'Spiderfier'
+ },
+
+ Defaults: {
+ src: ['MarkerCluster.Default.js'],
+ deps: ['QuickHull', 'Spiderfier'],
+ desc: 'Provides sensible defaults for the Cluster.',
+ heading: 'Sensible Defaults'
+ }
+};
+
+if (typeof exports !== 'undefined') {
+ exports.deps = deps;
+}
diff --git a/build/hint.js b/build/hint.js
new file mode 100644
index 000000000..464bbe115
--- /dev/null
+++ b/build/hint.js
@@ -0,0 +1,30 @@
+var jshint = require('jshint').JSHINT,
+ fs = require('fs'),
+ config = require('./hintrc.js').config;
+
+function jshintSrc(path, src) {
+ jshint(src, config);
+
+ var errors = jshint.errors,
+ i, len, e, line;
+
+ for (i = 0, len = errors.length; i < len; i++) {
+ e = errors[i];
+ //console.log(e.evidence);
+ console.log(path + '\tline ' + e.line + '\tcol ' + e.character + '\t ' + e.reason);
+ }
+
+ return len;
+}
+
+exports.jshint = function (files) {
+ var errorsFound = 0;
+
+ for (var i = 0, len = files.length; i < len; i++) {
+ var src = fs.readFileSync(files[i], 'utf8');
+
+ errorsFound += jshintSrc(files[i], src);
+ }
+
+ return errorsFound;
+};
\ No newline at end of file
diff --git a/build/hintrc.js b/build/hintrc.js
new file mode 100644
index 000000000..d05d406ac
--- /dev/null
+++ b/build/hintrc.js
@@ -0,0 +1,47 @@
+exports.config = {
+ "browser": true,
+ "node": true,
+ "predef": ["L"],
+
+ "debug": false,
+ "devel": false,
+
+ "es5": false,
+ "strict": false,
+ "globalstrict": false,
+
+ "asi": false,
+ "laxbreak": false,
+ "bitwise": true,
+ "boss": false,
+ "curly": true,
+ "eqnull": false,
+ "evil": false,
+ "expr": false,
+ "forin": true,
+ "immed": true,
+ "latedef": true,
+ "loopfunc": false,
+ "noarg": true,
+ "regexp": true,
+ "regexdash": false,
+ "scripturl": false,
+ "shadow": false,
+ "supernew": false,
+ "undef": true,
+ "funcscope": false,
+
+ "newcap": true,
+ "noempty": true,
+ "nonew": true,
+ "nomen": false,
+ "onevar": false,
+ "plusplus": false,
+ "sub": false,
+ "indent": 4,
+
+ "eqeqeq": true,
+ "trailing": true,
+ "white": true,
+ "smarttabs": true
+};