From 6f85d41788f969173fac044a793c8f24db78da6b Mon Sep 17 00:00:00 2001 From: Evan Carothers Date: Fri, 9 Sep 2016 00:11:44 -0500 Subject: [PATCH] updates to support lint/test/build + slight refactoring --- .jshintrc | 91 +++++++++++++++++ README.md | 10 +- dev/xdomain_cookie.dev.js | 209 ++++++++++++++++++++++++++++++++++++++ dev/xdomain_cookie.html | 69 +++++++++++++ gulpfile.js | 65 ++++++++++++ package.json | 13 ++- src/xdomain_cookie.html | 12 ++- src/xdomain_cookie.js | 19 ++-- src/xdomain_cookie.min.js | 3 + test/test_page.html | 2 +- test/test_s3_bucket.html | 2 +- test/test_webserver.js | 2 +- 12 files changed, 475 insertions(+), 22 deletions(-) create mode 100644 .jshintrc create mode 100644 dev/xdomain_cookie.dev.js create mode 100644 dev/xdomain_cookie.html create mode 100644 gulpfile.js create mode 100644 src/xdomain_cookie.min.js diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..f407ac0 --- /dev/null +++ b/.jshintrc @@ -0,0 +1,91 @@ +{ + // JSHint Default Configuration File (as on JSHint website) + // See http://jshint.com/docs/ for more details + + "maxerr" : 50, // {int} Maximum error before stopping + + // Enforcing + "bitwise" : true, // true: Prohibit bitwise operators (&, |, ^, etc.) + "camelcase" : false, // true: Identifiers must be in camelCase + "curly" : false, // true: Require {} for every new block or scope + "eqeqeq" : true, // true: Require triple equals (===) for comparison + "forin" : false, // true: Require filtering for..in loops with obj.hasOwnProperty() + "freeze" : true, // true: prohibits overwriting prototypes of native objects such as Array, Date etc. + "immed" : false, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());` + "latedef" : false, // true: Require variables/functions to be defined before being used + "newcap" : false, // true: Require capitalization of all constructor functions e.g. `new F()` + "noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee` + "noempty" : true, // true: Prohibit use of empty blocks + "nonbsp" : true, // true: Prohibit "non-breaking whitespace" characters. + "nonew" : false, // true: Prohibit use of constructors for side-effects (without assignment) + "plusplus" : false, // true: Prohibit use of `++` and `--` + "quotmark" : false, // Quotation mark consistency: + // false : do nothing (default) + // true : ensure whatever is used is consistent + // "single" : require single quotes + // "double" : require double quotes + "undef" : true, // true: Require all non-global variables to be declared (prevents global leaks) + "unused" : true, // Unused variables: + // true : all variables, last function parameter + // "vars" : all variables only + // "strict" : all variables, all function parameters + "strict" : true, // true: Requires all functions run in ES5 Strict Mode + "maxparams" : false, // {int} Max number of formal params allowed per function + "maxdepth" : false, // {int} Max depth of nested blocks (within functions) + "maxstatements" : false, // {int} Max number statements per function + "maxcomplexity" : false, // {int} Max cyclomatic complexity per function + "maxlen" : false, // {int} Max number of characters per line + "varstmt" : false, // true: Disallow any var statements. Only `let` and `const` are allowed. + + // Relaxing + "asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons) + "boss" : false, // true: Tolerate assignments where comparisons would be expected + "debug" : false, // true: Allow debugger statements e.g. browser breakpoints. + "eqnull" : false, // true: Tolerate use of `== null` + "esversion" : 5, // {int} Specify the ECMAScript version to which the code must adhere. + "moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features) + // (ex: `for each`, multiple try/catch, function expression…) + "evil" : false, // true: Tolerate use of `eval` and `new Function()` + "expr" : false, // true: Tolerate `ExpressionStatement` as Programs + "funcscope" : false, // true: Tolerate defining variables inside control statements + "globalstrict" : false, // true: Allow global "use strict" (also enables 'strict') + "iterator" : false, // true: Tolerate using the `__iterator__` property + "lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block + "laxbreak" : false, // true: Tolerate possibly unsafe line breakings + "laxcomma" : false, // true: Tolerate comma-first style coding + "loopfunc" : true, // true: Tolerate functions being defined in loops + "multistr" : false, // true: Tolerate multi-line strings + "noyield" : false, // true: Tolerate generator functions with no yield statement in them. + "notypeof" : false, // true: Tolerate invalid typeof operator values + "proto" : false, // true: Tolerate using the `__proto__` property + "scripturl" : false, // true: Tolerate script-targeted URLs + "shadow" : false, // true: Allows re-define variables later in code e.g. `var x=1; x=2;` + "sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation + "supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;` + "validthis" : false, // true: Tolerate using this in a non-constructor function + + // Environments + "browser" : true, // Web Browser (window, document, etc) + "browserify" : false, // Browserify (node.js code in the browser) + "couch" : false, // CouchDB + "devel" : true, // Development/debugging (alert, confirm, etc) + "dojo" : false, // Dojo Toolkit + "jasmine" : false, // Jasmine + "jquery" : false, // jQuery + "mocha" : true, // Mocha + "mootools" : false, // MooTools + "node" : true, // Node.js + "nonstandard" : false, // Widely adopted globals (escape, unescape, etc) + "phantom" : false, // PhantomJS + "prototypejs" : false, // Prototype and Scriptaculous + "qunit" : false, // QUnit + "rhino" : false, // Rhino + "shelljs" : false, // ShellJS + "typed" : false, // Globals for typed array constructions + "worker" : false, // Web Workers + "wsh" : false, // Windows Scripting Host + "yui" : false, // Yahoo User Interface + + // Custom Globals + "globals" : { "_LOG": true} // additional predefined global variables +} \ No newline at end of file diff --git a/README.md b/README.md index 8b2701c..3f81048 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Usage Simply include the script on any page where it's needed, create a new instance of xDomainCookie, and leverage the get/set functions: ```html - + + + \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..8d40c97 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,65 @@ +"use strict"; + +const gulp = require('gulp'), + jshint = require('gulp-jshint'), + rename = require("gulp-rename"), + mocha = require('gulp-mocha'), + runSequence = require('run-sequence'), + insert = require('gulp-insert'), + uglify = require('gulp-uglify'); + +const PACKAGE = require('./package.json'); +const ATTIBUTION = `/* Version ${PACKAGE.version} ${PACKAGE.name} (${PACKAGE.homepage}) from Contently (https://github.com/contently) */`+"\n\n"; + +gulp.task('build', function(cb) { + runSequence( + 'lint', + 'test', + 'build_files', + cb); +}); + +gulp.task('build_files', ['build_js','copy_html']); + +gulp.task('copy_html', function(){ + return gulp.src('./dev/xdomain_cookie.html') + .pipe(gulp.dest('src')); +}); + +gulp.task('build_js', ['build_regular_js', 'build_min_js']); + +gulp.task('build_regular_js', function(){ + return gulp.src('./dev/xdomain_cookie.dev.js') + .pipe(insert.prepend(ATTIBUTION)) + .pipe( rename("xdomain_cookie.js") ) + .pipe(gulp.dest('src')); +}); + +gulp.task('build_min_js', function(){ + return gulp.src('./dev/xdomain_cookie.dev.js') + .pipe(uglify({mangle:false})) + .pipe(insert.prepend(ATTIBUTION)) + .pipe( rename("xdomain_cookie.min.js") ) + .pipe(gulp.dest('src')); +}); + +gulp.task('lint', function(){ + return gulp.src('./dev/**/*') + .pipe(jshint.extract('auto')) + .pipe(jshint()) + .pipe(jshint.reporter('default')) + .pipe(jshint.reporter('fail')); +}); + +gulp.task('test', function(){ + return gulp.src('test/test_suite.js', {read:false} ) + .pipe(mocha({ + reporter:'spec', + fullTrace: true + })) + .on("error", function(err) { + console.log(err.toString()); + this.emit('end'); + process.exit(); + }) +}); \ No newline at end of file diff --git a/package.json b/package.json index 5f601d4..0d4fd17 100644 --- a/package.json +++ b/package.json @@ -1,22 +1,31 @@ { "name": "xdomain-cookies", - "version": "1.0.4", + "version": "1.0.5", "repository": { "type": "git", "url": "git+https://github.com/contently/xdomain-cookies" }, "description": "JS class for cross-domain shared cookie (via iframe shim)", "scripts": { - "test": "node_modules/.bin/mocha test/test_suite.js", + "test": "gulp test", "dev": "node test/test_webserver.js" }, + "homepage": "http://contently.github.io/xdomain-cookies/", "author": "Evan Carothers", "license": "CC", "devDependencies": { "chai": "^3.5.0", "connect": "^3.4.1", "express": "^4.13.4", + "gulp": "^3.9.1", + "gulp-insert": "^0.5.0", + "gulp-jshint": "^2.0.1", + "gulp-mocha": "^3.0.1", + "gulp-rename": "^1.2.2", + "gulp-uglify": "^2.0.0", + "jshint": "^2.9.3", "mocha": "^2.4.5", + "run-sequence": "^1.2.2", "serve-static": "^1.10.2", "zombie": "^4.2.1" } diff --git a/src/xdomain_cookie.html b/src/xdomain_cookie.html index 051b6b2..8644c20 100644 --- a/src/xdomain_cookie.html +++ b/src/xdomain_cookie.html @@ -42,11 +42,13 @@ data = JSON.parse(event.data); }catch(e){} - if(data && typeof data==='object' && 'msg_type' in data && data.msg_type==='xdsc_write' && 'namespace' in data && data.namespace === _namespace){ - _set_local_cookie( data.cookie_name, data.cookie_val, parseInt(data.expires_days,10) ); - //ping down to page again to update values of xdomain cookie data - _send_xdomain_cookie_data_to_page(); - } + if(typeof data !== 'object' || (data instanceof Array)) return; //data is not a non-array object + if(!('msg_type' in data) || data.msg_type !== 'xdsc_write') return; //data is not a xdomainc-cookie payload + if(!('namespace' in data) || data.namespace !== _namespace) return; //wrong namespace for msg + + _set_local_cookie( data.cookie_name, data.cookie_val, parseInt(data.expires_days,10) ); + //ping down to page again to update values of xdomain cookie data + _send_xdomain_cookie_data_to_page(); }); function _send_xdomain_cookie_data_to_page(){ diff --git a/src/xdomain_cookie.js b/src/xdomain_cookie.js index 0537f21..a6b89d7 100644 --- a/src/xdomain_cookie.js +++ b/src/xdomain_cookie.js @@ -1,3 +1,5 @@ +/* Version 1.0.5 xdomain-cookies (http://contently.github.io/xdomain-cookies/) from Contently (https://github.com/contently) */ + (function(exports) { "use strict"; @@ -29,13 +31,14 @@ data = JSON.parse(event.data); }catch(e){} - if(!data) return; - if(typeof data==='object' && !(data instanceof Array) && 'msg_type' in data && data.msg_type==='xdsc_read' && 'namespace' in data && data.namespace === _namespace){ - //NOTE - the only thing iframe postMessages to us is when it's initially loaded, and it includes payload of all cookies set on iframe domain - _xdomain_cookie_data = data.cookies; - _iframe_ready = true; - _fire_pending_callbacks(); - } + if(typeof data !== 'object' || (data instanceof Array)) return; //data is not a non-array object + if(!('msg_type' in data) || data.msg_type !== 'xdsc_read') return; //data is not a xdomainc-cookie payload + if(!('namespace' in data) || data.namespace !== _namespace) return; //wrong namespace for msg + + //NOTE - the only thing iframe postMessages to us is when it's initially loaded, and it includes payload of all cookies set on iframe domain + _xdomain_cookie_data = data.cookies; + _iframe_ready = true; + _fire_pending_callbacks(); } //an error occured loading the iframe from specified source (based on timeout) @@ -98,7 +101,7 @@ //if iframe isn't ready, wait for it to be ready if(!_iframe_ready && !_iframe_load_error){ - return _callbacks.push(function(load_error){ + return _callbacks.push(function(){ _set_xdomain_cookie_value( cookie_name, cookie_value, expires_days); }); } diff --git a/src/xdomain_cookie.min.js b/src/xdomain_cookie.min.js new file mode 100644 index 0000000..9554104 --- /dev/null +++ b/src/xdomain_cookie.min.js @@ -0,0 +1,3 @@ +/* Version 1.0.5 xdomain-cookies (http://contently.github.io/xdomain-cookies/) from Contently (https://github.com/contently) */ + +!function(exports){"use strict";var xDomainCookie=function(iframe_path,namespace,xdomain_only,iframe_load_timeout_ms){function _inbound_postmessage(event){var origin=event.origin||event.originalEvent.origin;if(origin===iframe_path&&"string"==typeof event.data){var data=null;try{data=JSON.parse(event.data)}catch(e){}"object"!=typeof data||data instanceof Array||"msg_type"in data&&"xdsc_read"===data.msg_type&&"namespace"in data&&data.namespace===_namespace&&(_xdomain_cookie_data=data.cookies,_iframe_ready=!0,_fire_pending_callbacks())}}function _iframe_load_error_occured(){_iframe_load_error=!0,_fire_pending_callbacks()}function _on_iframe_ready_or_error(cb){_callbacks.push(cb),_fire_pending_callbacks()}function _fire_pending_callbacks(){if(_iframe_load_error||_iframe_ready)for(;_callbacks.length>0;)_callbacks.pop()(_iframe_load_error)}function _set_cookie_in_iframe(cookie_name,cookie_value,expires_days){var data={namespace:_namespace,msg_type:"xdsc_write",cookie_name:cookie_name,cookie_val:cookie_value,expires_days:expires_days};document.getElementById("xdomain_cookie_"+_id).contentWindow.postMessage(JSON.stringify(data),iframe_path)}function _get_local_cookie(cookie_name){for(var name=cookie_name+"=",ca=document.cookie.split(";"),i=0;i - + +