cross-domain-events
Advanced tools
Comparing version 0.0.3 to 0.0.4
@@ -1,20 +0,62 @@ | ||
module.exports = function (config) { | ||
config.set({ | ||
basePath: '', | ||
frameworks: ['mocha', 'sinon', 'referee'], | ||
module.exports = function(config) { | ||
var settings = { | ||
basePath: '', | ||
frameworks: ['mocha', 'es5-shim', 'sinon', 'referee'], | ||
plugins: ['karma-*'], | ||
files: [ | ||
files: [{ | ||
pattern: 'test/fixtures/childIframe.html', | ||
included: false, | ||
served: true | ||
}, | ||
'node_modules/eventlistener/eventlistener.js', | ||
'lib/**/*.js', | ||
'test/**/*.js', | ||
'test/helpers/helpers.js', | ||
'lib/xde.js', | ||
'test/*.test.js' | ||
], | ||
reporters: ['progress'], | ||
browsers: ['PhantomJS'], | ||
singleRun: false, | ||
autoWatch: true, | ||
colors: true, | ||
logLevel: config.LOG_INFO, | ||
client: { | ||
mocha: { | ||
ui: 'tdd' | ||
} | ||
captureConsole: true | ||
} | ||
}); | ||
}; | ||
}; | ||
if (!process.env.SAUCE_USERNAME || !process.env.SAUCE_ACCESS_KEY) { | ||
// keep | ||
} else { | ||
settings.browserDisconnectTimeout = 60000 * 2; | ||
settings.browserNoActivityTimeout = 60000 * 2; | ||
//settings.browserDisconnectTolerance = 1; | ||
settings.captureTimeout = 60000 * 3; | ||
settings.sauceLabs = { | ||
testName: 'XDE', | ||
tags: ['xde'] | ||
}; | ||
settings.reporters = ['dots', 'saucelabs']; | ||
settings.customLaunchers = {}; | ||
// only 3 vmms / browsers per run because of | ||
// https://github.com/karma-runner/karma-sauce-launcher/issues/40 | ||
// should either add better setup for running max currently or | ||
var key = process.env.BROWSER_TYPE; | ||
var target = require('./ci-browsers.js')[key]; | ||
if (!target) { | ||
console.error('Missing / Unknown BROWSER_TYPE ' + process.env.BROWSER_TYPE); | ||
process.exit(1); | ||
} | ||
Object.keys(target).forEach(function(key){ | ||
settings.customLaunchers[key] = target[key]; | ||
}); | ||
console.log('Running CI tests on', Object.keys(settings.customLaunchers).join(', ')); | ||
settings.browsers = Object.keys(settings.customLaunchers); | ||
} | ||
return config.set(settings); | ||
}; |
@@ -1,5 +0,5 @@ | ||
(function (win, events) { | ||
(function(win, events) { | ||
var xde; | ||
var DEFAULT_ORIGIN = '*'; | ||
var xde, eventListeners; | ||
var onlyStrings; | ||
var eventListeners = {}; | ||
@@ -14,3 +14,3 @@ function onMessage(evt) { | ||
parsedData = evt.data; | ||
if (typeof evt.data == 'string') { | ||
if (typeof evt.data == 'string' && evt.data[0] === '{') { | ||
try { | ||
@@ -30,3 +30,3 @@ parsedData = JSON.parse(evt.data); | ||
if (listeners && listeners.length > 0) { | ||
listeners.forEach(function(fn){ | ||
listeners.forEach(function(fn) { | ||
fn(parsedData); | ||
@@ -37,13 +37,17 @@ }); | ||
function validateName (name) { | ||
if (!name || typeof name != 'string') { throw new Error('Event name has to be a string'); }; | ||
function validateName(name) { | ||
if (!name || typeof name != 'string') { | ||
throw new Error('Event name has to be a string'); | ||
} | ||
} | ||
function validateNameAndFn (name, fn) { | ||
function validateNameAndFn(name, fn) { | ||
validateName(name); | ||
if (typeof fn != "function" ) { throw new Error('Callback function has to be given'); } | ||
if (typeof fn != 'function') { | ||
throw new Error('Callback function has to be given'); | ||
} | ||
} | ||
xde = { | ||
on: function (name, fn) { | ||
on: function(name, fn) { | ||
validateNameAndFn(name, fn); | ||
@@ -57,3 +61,3 @@ | ||
off: function (name, fn) { | ||
off: function(name, fn) { | ||
validateNameAndFn(name, fn); | ||
@@ -64,3 +68,3 @@ var listeners = eventListeners[name]; | ||
} | ||
eventListeners[name] = listeners.filter(function (listener) { | ||
eventListeners[name] = listeners.filter(function(listener) { | ||
return listener !== fn; | ||
@@ -70,3 +74,3 @@ }); | ||
sendTo: function (otherWindow, name, data) { | ||
sendTo: function(otherWindow, name, data) { | ||
validateName(name); | ||
@@ -77,4 +81,4 @@ try { | ||
} | ||
} catch(e) {} | ||
if ( !otherWindow || !otherWindow.postMessage ) { | ||
} catch (e) {} | ||
if (!otherWindow || !otherWindow.postMessage) { | ||
throw new TypeError('otherWindow does not support postMessage'); | ||
@@ -84,10 +88,10 @@ } | ||
var msg = { | ||
name : name, | ||
data : data, | ||
__xde : true | ||
name: name, | ||
data: data, | ||
__xde: true | ||
}; | ||
if (onlyStrings) { | ||
if (xde.onlyStringSupport) { | ||
msg = JSON.stringify(msg); | ||
} | ||
otherWindow.postMessage(msg, this.targetOrigin); // TODO fix security issue | ||
otherWindow.postMessage(msg, xde.targetOrigin); // TODO fix security issue | ||
}, | ||
@@ -97,14 +101,25 @@ | ||
_reset: function (forceStringify) { | ||
onlyStringSupport: false, | ||
_reset: function() { | ||
eventListeners = {}; | ||
this.targetOrigin = DEFAULT_ORIGIN; | ||
onlyStrings = forceStringify || false; | ||
try{win.postMessage({toString:function(){onlyStrings=true;}},"*");}catch(e){} | ||
} | ||
}; | ||
xde._reset(); | ||
function featureTestObjectTransportSupport() { | ||
try { | ||
win.postMessage({ | ||
toString: function() { | ||
xde.onlyStringSupport = true; | ||
} | ||
}, DEFAULT_ORIGIN); | ||
} catch (e) {} | ||
} | ||
featureTestObjectTransportSupport(); | ||
events.add(win, 'message', onMessage, false); | ||
if(typeof exports === 'object') { | ||
if (typeof exports === 'object') { | ||
module.exports = xde; | ||
@@ -114,2 +129,2 @@ } else { | ||
} | ||
})(this.window || (typeof global !== "undefined" ? global : this), this.eventListener || require('eventlistener')); | ||
})(this.window || (typeof global !== 'undefined' ? global : this), this.eventListener || require('eventlistener')); |
{ | ||
"name": "cross-domain-events", | ||
"version": "0.0.3", | ||
"version": "0.0.4", | ||
"description": "Event-like api for postMessage to send objects between cross-domain frames", | ||
@@ -27,20 +27,22 @@ "license": "MIT", | ||
"scripts": { | ||
"test": "./node_modules/karma/bin/karma start --single-run" | ||
"test": "./node_modules/karma/bin/karma start --single-run", | ||
"test-ci": "BROWSER_TYPE=android npm test && BROWSER_TYPE=ios npm test && BROWSER_TYPE=ienew npm test && BROWSER_TYPE=ie npm test && BROWSER_TYPE=firefox npm test && BROWSER_TYPE=chrome npm test", | ||
"validate": "finn-js-code-style lib && jscs -c node_modules/finn-js-code-style/.jscsrc lib" | ||
}, | ||
"main": "lib/xde.js", | ||
"devDependencies": { | ||
"karma-script-launcher": "~0.1.0", | ||
"karma-chrome-launcher": "~0.1.1", | ||
"karma-html2js-preprocessor": "~0.1.0", | ||
"karma-firefox-launcher": "~0.1.2", | ||
"requirejs": "~2.1.9", | ||
"karma-requirejs": "~0.2.0", | ||
"karma-phantomjs-launcher": "~0.1.1", | ||
"karma": "0.12.21", | ||
"mocha": "~1.15.1", | ||
"karma-mocha": "~0.1.1", | ||
"karma-commonjs": "0.0.3", | ||
"finn-js-code-style": "^4.3.0", | ||
"jscs": "^1.12.0", | ||
"karma": "^0.12.31", | ||
"karma-es5-shim": "0.0.4", | ||
"karma-mocha": "^0.1.10", | ||
"karma-phantomjs-launcher": "^0.1.4", | ||
"karma-referee": "^0.4.2", | ||
"karma-sauce-launcher": "^0.2.10", | ||
"karma-sinon": "~1.0.0", | ||
"karma-referee": "~0.2.0" | ||
"mocha": "^2.2.4", | ||
"referee": "^1.1.1", | ||
"referee-sinon": "^1.0.2", | ||
"sinon": "^1.14.1" | ||
} | ||
} |
@@ -8,2 +8,5 @@ cross-domain-events | ||
[![Sauce Test Status](https://saucelabs.com/browser-matrix/cross-domain-events.svg)](https://saucelabs.com/u/cross-domain-events) | ||
postMessage was implemented in Internet Explorer 8, but only supports sending text strings. Modern browsers can send objects, but if you want to listen for different kind of objects you have to implement your own delegation. | ||
@@ -10,0 +13,0 @@ |
@@ -1,6 +0,12 @@ | ||
suite('xde', function () { | ||
var iframe, childXde, postMessage; | ||
var miniEvtListener = function (el, n, m, u) {el.addEventListener(n, m, u);}; | ||
var iframeContent = '<!DOCTYPE html><html><head><script>var eventListener={add:'+miniEvtListener.toString()+'};</script><script src=\'/base/lib/xde.js?'+new Date().getTime()+'\'></script><script>parent.setChildXde(xde);</script></head><body>test</body></html>'; | ||
function cleanupSpy(){ | ||
if (this.spy) { | ||
this.spy.restore(); | ||
this.spy = null; | ||
} | ||
} | ||
describe('xde', function () { | ||
var iframeElem; | ||
var iframeWindow; | ||
function async(fn, done) { | ||
@@ -12,2 +18,3 @@ return function () { | ||
} catch (e) { | ||
console.error(e); | ||
done(e); | ||
@@ -18,42 +25,52 @@ } | ||
function dispatchMessageEvt (msg, origin, source) { | ||
var evt; | ||
try { | ||
evt = new MessageEvent('message', {data: msg, origin: origin, source: source}); | ||
} catch (e) { | ||
evt = document.createEvent('MessageEvent'); | ||
evt.initMessageEvent('message', true, true, msg, origin, 1, source); | ||
function asyncAssert(fn, done) { | ||
return setTimeout(async(fn, done), 50); | ||
} | ||
function sendPostMessage(data, cb) { | ||
var name = data.name || 'test'; | ||
if (cb) { | ||
window.xde.on(name, cb); | ||
} | ||
window.dispatchEvent(evt); | ||
iframeWindow.xde.sendTo(window, name, data); | ||
} | ||
setup(function (done) { | ||
window.setChildXde = function (xde) { | ||
window.setChildXde = null; | ||
childXde = xde; | ||
beforeEach(function (done) { | ||
this.timeout(20000); // saucelabs may need more time to load the iframe | ||
// var time = 0; | ||
// var timer = setInterval(function(){ | ||
// time += 1; | ||
// console.log('time:', time); | ||
// }, 1000); | ||
window.initXde = function (_win) { | ||
// clearTimeout(timer); | ||
iframeWindow = _win.window; //accessing window.window for IE8 | ||
done(); | ||
}; | ||
iframe = document.createElement('iframe'); | ||
document.body.appendChild(iframe); | ||
var doc = iframe.contentWindow.document; | ||
doc.open('text/html', 'replace'); | ||
doc.write(iframeContent); | ||
doc.close(); | ||
postMessage = sinon.spy(iframe.contentWindow, 'postMessage'); | ||
iframeElem = document.createElement('iframe'); | ||
iframeElem.width = '300px'; | ||
iframeElem.height = '100px'; | ||
iframeElem.style.width = '300px'; | ||
iframeElem.style.height = '100px'; | ||
iframeElem.style.backgroundColor = 'red'; | ||
setTimeout(function(){ | ||
// we get more stable tests on saucelabs if we wait some | ||
document.body.appendChild(iframeElem); | ||
iframeElem.src = '/base/test/fixtures/childIframe.html?' + (+new Date()); | ||
}, 100); | ||
}); | ||
teardown(function teardown () { | ||
document.body.removeChild(iframe); | ||
childXde = undefined; | ||
postMessage.restore(); | ||
xde._reset(); | ||
afterEach(function teardown () { | ||
iframeWindow = null; | ||
window.xde._reset(); | ||
document.body.removeChild(iframeElem); | ||
cleanupSpy.call(this); | ||
}); | ||
suite('on', function() { | ||
test('should be defined', function () { | ||
describe('on', function() { | ||
it('should be defined', function () { | ||
assert.defined(xde.on); | ||
}); | ||
test('should throw if event name is not given', function () { | ||
it('should throw if event name is not given', function () { | ||
assert.exception(function () { | ||
@@ -64,3 +81,3 @@ xde.on(); | ||
test('should throw if event name is empty string', function () { | ||
it('should throw if event name is empty string', function () { | ||
assert.exception(function () { | ||
@@ -71,3 +88,3 @@ xde.on(''); | ||
test('should throw if callback is not a function', function () { | ||
it('should throw if callback is not a function', function () { | ||
assert.exception(function () { | ||
@@ -78,3 +95,3 @@ xde.on('test'); | ||
test('should not throw when calling with right arguments', function () { | ||
it('should not throw when calling with right arguments', function () { | ||
refute.exception(function () { | ||
@@ -85,6 +102,6 @@ xde.on('test', function () {}); | ||
test('should not trigger listener sync', function () { | ||
var eventName = 'foo', | ||
eventData = 'bar', | ||
spy = sinon.spy(); | ||
it('should not trigger listener sync', function () { | ||
var eventName = 'foo'; | ||
var eventData = 'bar'; | ||
var spy = sinon.spy(); | ||
@@ -95,34 +112,49 @@ xde.on(eventName, spy); | ||
test('should not use JSON.parse when message data is an object', function () { | ||
var spy = sinon.spy(JSON, "parse"); | ||
dispatchMessageEvt({foo: 'bar'}); | ||
sinon.assert.notCalled(spy); | ||
spy.restore(); | ||
// add if | ||
// cleanup somewhere missing | ||
it('should not use JSON.parse when message data is an object', function (done) { | ||
var spy = wrapAndSpy(JSON, "parse"); | ||
sendPostMessage({foo: 'bar'}, function() { | ||
if (xde.onlyStringSupport === false) { | ||
assert.equals(spy.callCount, 0, 'JSON parse should NOT be called'); | ||
} else { | ||
assert.equals(spy.callCount, 1, 'JSON parse should be called when string'); | ||
} | ||
spy.restore(); | ||
done(); | ||
}); | ||
}); | ||
test('should try JSON.parse when message data is a string', function () { | ||
var spy = sinon.spy(JSON, "parse"); | ||
dispatchMessageEvt('{"foo":"bar"}'); | ||
sinon.assert.calledOnce(spy); | ||
spy.restore(); | ||
it('should try JSON.parse when message data is a string', function (done) { | ||
var spy = wrapAndSpy(JSON, "parse"); | ||
var orig = iframeWindow.xde.onlyStringSupport; | ||
iframeWindow.xde.onlyStringSupport = true; | ||
sendPostMessage({"foo":"bar"}, function() { | ||
iframeWindow.xde.onlyStringSupport = orig; | ||
assert.equals(spy.callCount, 1, 'JSON parse should be called'); | ||
spy.restore(); | ||
done(); | ||
}); | ||
}); | ||
test('should pass source and origin to the event object', function (done) { | ||
var source = window; | ||
var origin = location.href; | ||
it('should pass source and origin to the event object', function (done) { | ||
var origin = 'http://'+iframeWindow.location.host; | ||
xde.on('test', function (evt) { | ||
assert.equals(source, evt.source); | ||
assert.equals(origin, evt.origin); | ||
assert.equals(evt.origin, origin); | ||
assert.equals(evt.source, iframeWindow); | ||
done(); | ||
}); | ||
dispatchMessageEvt({ | ||
__xde: true, | ||
name: 'test' | ||
}, origin, source); | ||
sendPostMessage({}); | ||
}); | ||
}); | ||
suite('sendTo', function() { | ||
test('should throw if otherWindow is not valid postMessage target', function () { | ||
describe('sendTo', function() { | ||
it('should throw if otherWindow is not valid postMessage target', function () { | ||
assert.exception(function () { | ||
@@ -133,34 +165,46 @@ xde.sendTo('test', 'name'); | ||
test('should not throw when calling with iframe as otherWindow', function () { | ||
it('should not throw when calling with iframeElem as otherWindow', function () { | ||
refute.exception(function () { | ||
xde.sendTo(iframe, 'test'); | ||
xde.sendTo(iframeWindow, 'test'); | ||
}); | ||
}); | ||
test('should not throw when calling with window.top as otherWindow', function () { | ||
it('should not throw when calling with window.top as otherWindow', function () { | ||
refute.exception(function () { | ||
childXde.sendTo(window, 'test'); | ||
iframeWindow.xde.sendTo(window, 'test'); | ||
}); | ||
}); | ||
test('should throw if event name is not given', function () { | ||
it('should throw if event name is not given', function () { | ||
assert.exception(function(){ | ||
xde.sendTo(iframe); | ||
xde.sendTo(iframeWindow); | ||
}); | ||
}); | ||
test('should throw if event name is empty string', function () { | ||
it('should throw if event name is empty string', function () { | ||
assert.exception(function () { | ||
xde.sendTo(iframe, ''); | ||
xde.sendTo(iframeWindow, ''); | ||
}); | ||
}); | ||
test('should call postMessage only once', function () { | ||
xde.sendTo(iframe, 'test'); | ||
assert(postMessage.calledOnce); | ||
it('should call postMessage only once', function (done) { | ||
var spy = wrapAndSpy(window, 'postMessage'); | ||
assert.equals(iframeWindow.spy.callCount, 0); | ||
window.xde.on('test321', function() { | ||
spy.restore(); | ||
assert.equals(iframeWindow.spy.callCount, 0, 'iframeSpy should not be called'); | ||
assert.equals(spy.callCount, 1); | ||
done(); | ||
}); | ||
iframeWindow.xde.sendTo(window, 'test321', {payload: 'asd'}); | ||
}); | ||
test('should trigger listener on the other side', function (done) { | ||
it('should trigger listener on the other side', function (done) { | ||
var eventName = 'foo'; | ||
childXde.on(eventName, async(function (evt) { | ||
iframeWindow.xde.on(eventName, async(function (evt) { | ||
assert.defined(evt); | ||
@@ -170,6 +214,6 @@ assert.equals(evt.name, eventName); | ||
xde.sendTo(iframe, eventName); | ||
xde.sendTo(iframeWindow, eventName); | ||
}); | ||
test('should send event data to the listener', function (done) { | ||
it('should send event data to the listener', function (done) { | ||
var eventName = 'foo', | ||
@@ -180,86 +224,91 @@ eventData = { | ||
}; | ||
childXde.on(eventName, async(function (evt) { | ||
iframeWindow.xde.on(eventName, async(function (evt) { | ||
assert.equals(evt.data, eventData); | ||
}, done)); | ||
xde.sendTo(iframe, eventName, eventData); | ||
xde.sendTo(iframeWindow, eventName, eventData); | ||
}); | ||
test('should not throw exception on non-JSON message events', function (done) { | ||
it('should not throw exception on non-JSON message events', function (done) { | ||
var spy = sinon.spy(); | ||
iframe.contentWindow.onerror = spy; | ||
iframe.contentWindow.postMessage('not serialized JSON', '*'); | ||
iframeWindow.onerror = spy; | ||
iframeWindow.postMessage('not serialized JSON', '*'); | ||
setTimeout(async(function () { | ||
asyncAssert(function () { | ||
sinon.assert.notCalled(spy); | ||
}, done), 50); | ||
}, done); | ||
}); | ||
test('should ignore json messages not sent by xde', function (done) { | ||
it('should ignore json messages not sent by xde', function (done) { | ||
var spy = sinon.spy(); | ||
var data = {data : 'foo', name : 'bar'}; | ||
childXde.on(data.name, spy); | ||
iframe.contentWindow.postMessage(JSON.stringify(data), '*'); | ||
iframeWindow.xde.on(data.name, spy); | ||
iframeWindow.postMessage(JSON.stringify(data), '*'); | ||
setTimeout(async(function () { | ||
asyncAssert(function () { | ||
sinon.assert.notCalled(spy); | ||
}, done), 50); | ||
}, done); | ||
}); | ||
test('should allow multiple listeners for same event name', function (done) { | ||
it('should allow multiple listeners for same event name', function (done) { | ||
var spy1 = sinon.spy(), spy2 = sinon.spy(); | ||
var evtName = 'multiple'; | ||
childXde.on(evtName, spy1); | ||
childXde.on(evtName, spy2); | ||
xde.sendTo(iframe, evtName); | ||
setTimeout(async(function () { | ||
iframeWindow.xde.on(evtName, spy1); | ||
iframeWindow.xde.on(evtName, spy2); | ||
xde.sendTo(iframeWindow, evtName); | ||
asyncAssert(function () { | ||
sinon.assert.calledOnce(spy1); | ||
sinon.assert.calledOnce(spy2); | ||
}, done), 50); | ||
}, done); | ||
}); | ||
test('should only trigger listeners for the sent event name', function (done) { | ||
it('should only trigger listeners for the sent event name', function (done) { | ||
var spy1 = sinon.spy(), spy2 = sinon.spy(); | ||
var evtName1 = 'foo'; | ||
var evtName2 = 'bar'; | ||
childXde.on(evtName1, spy1); | ||
childXde.on(evtName2, spy2); | ||
xde.sendTo(iframe, evtName1); | ||
setTimeout(async(function () { | ||
iframeWindow.xde.on(evtName1, spy1); | ||
iframeWindow.xde.on(evtName2, spy2); | ||
xde.sendTo(iframeWindow, evtName1); | ||
asyncAssert(function () { | ||
sinon.assert.calledOnce(spy1); | ||
sinon.assert.notCalled(spy2); | ||
}, done), 50); | ||
}, done); | ||
}); | ||
test('should not throw error or call any callbacks if no listners for an event name', function (done) { | ||
it('should not throw error or call any callbacks if no listners for an event name', function (done) { | ||
var spy = sinon.spy(); | ||
iframe.contentWindow.onerror = spy; | ||
childXde.on('foo', spy); | ||
xde.sendTo(iframe, 'bar'); | ||
setTimeout(async(function () { | ||
iframeWindow.onerror = spy; | ||
iframeWindow.xde.on('foo', spy); | ||
xde.sendTo(iframeWindow, 'bar'); | ||
asyncAssert(function () { | ||
sinon.assert.notCalled(spy); | ||
}, done), 50); | ||
}, done); | ||
}); | ||
test('should not stringify to JSON when browser supports postMessage with objects', function () { | ||
var spy = sinon.spy(JSON, 'stringify'); | ||
xde.sendTo(iframe, 'test', {a: 1}); | ||
sinon.assert.notCalled(spy); | ||
spy.restore(); | ||
}); | ||
if (xde.onlyStringSupport === false) { | ||
after(cleanupSpy); | ||
test('should stringify to JSON when browser doesn\'t support postMessage with objects', function () { | ||
xde._reset(true); | ||
var spy = sinon.spy(JSON, 'stringify'); | ||
xde.sendTo(iframe, 'test', {a: 1}); | ||
sinon.assert.calledOnce(spy); | ||
spy.restore(); | ||
}); | ||
it('should not stringify to JSON when browser supports postMessage with objects', function () { | ||
var spy = sinon.spy(JSON, 'stringify'); | ||
xde.sendTo(iframeWindow, 'test', {a: 1}); | ||
sinon.assert.notCalled(spy); | ||
}); | ||
} | ||
if (xde.onlyStringSupport === true) { | ||
after(cleanupSpy); | ||
it('should stringify to JSON when browser doesn\'t support postMessage with objects', function () { | ||
var spy = this.spy = sinon.spy(JSON, 'stringify'); | ||
xde.sendTo(iframeWindow, 'test', {a: 1}); | ||
sinon.assert.calledOnce(spy); | ||
}); | ||
} | ||
}); | ||
suite('off', function () { | ||
test('should not throw exception when no listeners for given event name', function () { | ||
describe('off', function () { | ||
it('should not throw exception when no listeners for given event name', function () { | ||
refute.exception(function () { | ||
@@ -270,30 +319,31 @@ xde.off('foo', function () {}); | ||
test('should remove listener for given event name', function (done) { | ||
it('should remove listener for given event name', function (done) { | ||
var spy = sinon.spy(); | ||
var eventName = 'foo'; | ||
childXde.on(eventName, spy); | ||
childXde.off(eventName, spy); | ||
iframeWindow.xde.on(eventName, spy); | ||
iframeWindow.xde.off(eventName, spy); | ||
xde.sendTo(iframe, eventName); | ||
setTimeout(async(function () { | ||
xde.sendTo(iframeWindow, eventName); | ||
asyncAssert(function () { | ||
sinon.assert.notCalled(spy); | ||
}, done), 50); | ||
}, done); | ||
}); | ||
test('should only remove the given listener on a particular event name', function (done) { | ||
var spy1 = sinon.spy(), spy2 = sinon.spy(); | ||
it('should only remove the given listener on a particular event name', function (done) { | ||
var spy1 = sinon.spy(); | ||
var spy2 = sinon.spy(); | ||
var eventName = 'foo'; | ||
childXde.on(eventName, spy1); | ||
childXde.on(eventName, spy2); | ||
iframeWindow.xde.on(eventName, spy1); | ||
iframeWindow.xde.on(eventName, spy2); | ||
childXde.off(eventName, spy1); | ||
iframeWindow.xde.off(eventName, spy1); | ||
xde.sendTo(iframe, eventName); | ||
xde.sendTo(iframeWindow, eventName); | ||
setTimeout(async(function () { | ||
asyncAssert(function () { | ||
sinon.assert.calledOnce(spy2); | ||
sinon.assert.notCalled(spy1); | ||
}, done), 50); | ||
}, done); | ||
@@ -303,28 +353,40 @@ }); | ||
suite('targetOrigin', function () { | ||
test('should pass * targetOrigin to postMessage as default', function () { | ||
xde.sendTo(iframe, 'test'); | ||
assert.equals(postMessage.getCall(0).args[1], '*'); | ||
describe('targetOrigin', function () { | ||
it('should pass * targetOrigin to postMessage as default', function () { | ||
xde.sendTo(iframeWindow, 'test'); | ||
assert.equals(iframeWindow.spy.getCall(0).args[1], '*'); | ||
}); | ||
test('should pass specified targetOrigin to postMessage', function () { | ||
var TARGET_ORIGIN = 'http://test.com'; | ||
xde.targetOrigin = TARGET_ORIGIN; | ||
xde.sendTo(iframe, 'test'); | ||
assert.equals(postMessage.getCall(0).args[1], TARGET_ORIGIN); | ||
before(cleanupSpy); | ||
after(cleanupSpy); | ||
it('should pass specified targetOrigin to postMessage', function (done) { | ||
var spy = this.spy = wrapAndSpy(window, 'postMessage'); | ||
iframeWindow.xde.targetOrigin = 'http://test.com'; | ||
iframeWindow.xde.sendTo(window, 'test', {payload: Math.random()}); | ||
asyncAssert(function(){ | ||
iframeWindow.xde.targetOrigin = '*'; | ||
assert.equals(spy.callCount, 1); | ||
assert.equals(spy.getCall(0).args[1], 'http://test.com'); | ||
spy.restore(); | ||
}, done); | ||
}); | ||
test('should ignore messages from unknown origins', function (done) { | ||
it('should ignore messages from unknown origins', function (done) { | ||
var TARGET_ORIGIN = 'http://test.com'; | ||
var EVENT_NAME = 'test'; | ||
var spy = sinon.spy(); | ||
childXde.targetOrigin = TARGET_ORIGIN; | ||
childXde.on(EVENT_NAME, spy); | ||
xde.sendTo(iframe, EVENT_NAME); | ||
setTimeout(async(function() { | ||
iframeWindow.xde.targetOrigin = TARGET_ORIGIN; | ||
iframeWindow.xde.on(EVENT_NAME, spy); | ||
xde.sendTo(iframeWindow, EVENT_NAME); | ||
asyncAssert(function() { | ||
refute.called(spy); | ||
}, done), 50); | ||
}, done); | ||
}); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
29632
16
657
35
4