@cycle/dom
Advanced tools
Comparing version 10.0.0-rc16 to 10.0.0-rc17
@@ -98,3 +98,2 @@ "use strict"; | ||
DOMSource.prototype.events = function (eventType, options) { | ||
var _this = this; | ||
if (options === void 0) { options = {}; } | ||
@@ -108,14 +107,20 @@ if (typeof eventType !== "string") { | ||
var scope = utils_1.getScope(namespace); | ||
var key = eventType + "~" + useCapture + "~" + scope; | ||
var rootElement$ = this._rootElement$.filter(function (rootElement) { | ||
if (scope) { | ||
return !!_this._isolateModule.getIsolatedElement(scope); | ||
} | ||
else { | ||
return rootElement.renderedByCycleDOM; | ||
} | ||
}); | ||
var keyParts = [eventType, useCapture]; | ||
if (scope) { | ||
keyParts.push(scope); | ||
} | ||
var key = keyParts.join('~'); | ||
var domSource = this; | ||
var rootElement$; | ||
if (scope) { | ||
rootElement$ = this._rootElement$ | ||
.filter(function checkRootHasRenderedScope(rootElement) { | ||
return !!domSource._isolateModule.getIsolatedElement(scope); | ||
}).take(1); | ||
} | ||
else { | ||
rootElement$ = this._rootElement$.take(2); | ||
} | ||
var event$ = rootElement$ | ||
.take(1) | ||
.map(function (rootElement) { | ||
.map(function setupEventDelegatorOnTopElement(rootElement) { | ||
// Event listener just for the root element | ||
@@ -126,10 +131,17 @@ if (!namespace || namespace.length === 0) { | ||
// Event listener on the top element as an EventDelegator | ||
if (!_this._delegators.has(key)) { | ||
var top_1 = scope | ||
? _this._isolateModule.getIsolatedElement(scope) | ||
: rootElement; | ||
_this._delegators.set(key, new EventDelegator_1.EventDelegator(top_1, eventType, useCapture, _this._isolateModule)); | ||
var delegators = domSource._delegators; | ||
var top = scope | ||
? domSource._isolateModule.getIsolatedElement(scope) | ||
: rootElement; | ||
var delegator; | ||
if (delegators.has(key)) { | ||
delegator = delegators.get(key); | ||
delegator.updateTopElement(top); | ||
} | ||
else { | ||
delegator = new EventDelegator_1.EventDelegator(top, eventType, useCapture, domSource._isolateModule); | ||
delegators.set(key, delegator); | ||
} | ||
var subject = xstream_1.default.create(); | ||
_this._delegators.get(key).addDestination(subject, namespace); | ||
delegator.addDestination(subject, namespace); | ||
return subject; | ||
@@ -136,0 +148,0 @@ }) |
@@ -12,2 +12,3 @@ import { Stream } from 'xstream'; | ||
export declare class EventDelegator { | ||
private topElement; | ||
eventType: string; | ||
@@ -18,2 +19,3 @@ useCapture: boolean; | ||
private roof; | ||
private domListener; | ||
constructor(topElement: Element, eventType: string, useCapture: boolean, isolateModule: IsolateModule); | ||
@@ -26,2 +28,3 @@ bubble(rawEvent: Event): void; | ||
mutateEventCurrentTarget(event: PatchedEvent, currentTargetElement: Element): void; | ||
updateTopElement(newTopElement: Element): void; | ||
} |
@@ -18,2 +18,3 @@ "use strict"; | ||
var _this = this; | ||
this.topElement = topElement; | ||
this.eventType = eventType; | ||
@@ -25,7 +26,8 @@ this.useCapture = useCapture; | ||
if (useCapture) { | ||
topElement.addEventListener(eventType, function (ev) { return _this.capture(ev); }, useCapture); | ||
this.domListener = function (ev) { return _this.capture(ev); }; | ||
} | ||
else { | ||
topElement.addEventListener(eventType, function (ev) { return _this.bubble(ev); }, useCapture); | ||
this.domListener = function (ev) { return _this.bubble(ev); }; | ||
} | ||
topElement.addEventListener(eventType, this.domListener, useCapture); | ||
} | ||
@@ -89,2 +91,7 @@ EventDelegator.prototype.bubble = function (rawEvent) { | ||
}; | ||
EventDelegator.prototype.updateTopElement = function (newTopElement) { | ||
this.topElement.removeEventListener(this.eventType, this.domListener, this.useCapture); | ||
newTopElement.addEventListener(this.eventType, this.domListener, this.useCapture); | ||
this.topElement = newTopElement; | ||
}; | ||
return EventDelegator; | ||
@@ -91,0 +98,0 @@ }()); |
"use strict"; | ||
var snabbdom_1 = require('snabbdom'); | ||
var xstream_1 = require('xstream'); | ||
var concat_1 = require('xstream/extra/concat'); | ||
var DOMSource_1 = require('./DOMSource'); | ||
@@ -44,8 +46,5 @@ var VNodeWrapper_1 = require('./VNodeWrapper'); | ||
.drop(1) | ||
.map(function (_a) { | ||
var elm = _a.elm; | ||
elm.renderedByCycleDOM = true; | ||
return elm; | ||
}) | ||
.map(function unwrapElementFromVNode(vnode) { return vnode.elm; }) | ||
.startWith(rootElement) | ||
.compose(function (stream) { return concat_1.default(stream, xstream_1.default.never()); }) // don't complete this stream | ||
.remember(); | ||
@@ -52,0 +51,0 @@ /* tslint:disable:no-empty */ |
{ | ||
"name": "@cycle/dom", | ||
"version": "10.0.0-rc16", | ||
"version": "10.0.0-rc17", | ||
"description": "The standard DOM Driver for Cycle.js, based on Snabbdom", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
@@ -125,14 +125,20 @@ import {StreamAdapter} from '@cycle/base'; | ||
const scope = getScope(namespace); | ||
const key = `${eventType}~${useCapture}~${scope}`; | ||
const rootElement$ = this._rootElement$.filter(rootElement => { | ||
if (scope) { | ||
return !!this._isolateModule.getIsolatedElement(scope); | ||
} else { | ||
return (<any> rootElement).renderedByCycleDOM; | ||
} | ||
}); | ||
const keyParts = [eventType, useCapture]; | ||
if (scope) { | ||
keyParts.push(scope); | ||
} | ||
const key = keyParts.join('~'); | ||
const domSource = this; | ||
let rootElement$: Stream<Element>; | ||
if (scope) { | ||
rootElement$ = this._rootElement$ | ||
.filter(function checkRootHasRenderedScope(rootElement) { | ||
return !!domSource._isolateModule.getIsolatedElement(scope); | ||
}).take(1); | ||
} else { | ||
rootElement$ = this._rootElement$.take(2); | ||
} | ||
const event$: Stream<Event> = rootElement$ | ||
.take(1) | ||
.map(rootElement => { | ||
.map(function setupEventDelegatorOnTopElement(rootElement) { | ||
// Event listener just for the root element | ||
@@ -143,12 +149,18 @@ if (!namespace || namespace.length === 0) { | ||
// Event listener on the top element as an EventDelegator | ||
if (!this._delegators.has(key)) { | ||
const top = scope | ||
? this._isolateModule.getIsolatedElement(scope) | ||
: rootElement; | ||
this._delegators.set(key, | ||
new EventDelegator(top, eventType, useCapture, this._isolateModule) | ||
const delegators = domSource._delegators; | ||
const top = scope | ||
? domSource._isolateModule.getIsolatedElement(scope) | ||
: rootElement; | ||
let delegator: EventDelegator; | ||
if (delegators.has(key)) { | ||
delegator = delegators.get(key); | ||
delegator.updateTopElement(top); | ||
} else { | ||
delegator = new EventDelegator( | ||
top, eventType, useCapture, domSource._isolateModule | ||
); | ||
delegators.set(key, delegator); | ||
} | ||
const subject = xs.create<Event>(); | ||
this._delegators.get(key).addDestination(subject, namespace); | ||
delegator.addDestination(subject, namespace); | ||
return subject; | ||
@@ -155,0 +167,0 @@ }) |
@@ -35,4 +35,5 @@ import {Stream} from 'xstream'; | ||
private roof: Element; | ||
private domListener: EventListener; | ||
constructor(topElement: Element, | ||
constructor(private topElement: Element, | ||
public eventType: string, | ||
@@ -43,6 +44,7 @@ public useCapture: boolean, | ||
if (useCapture) { | ||
topElement.addEventListener(eventType, ev => this.capture(ev), useCapture); | ||
this.domListener = (ev: Event) => this.capture(ev); | ||
} else { | ||
topElement.addEventListener(eventType, ev => this.bubble(ev), useCapture); | ||
this.domListener = (ev: Event) => this.bubble(ev); | ||
} | ||
topElement.addEventListener(eventType, this.domListener, useCapture); | ||
} | ||
@@ -111,2 +113,12 @@ | ||
} | ||
updateTopElement(newTopElement: Element) { | ||
this.topElement.removeEventListener( | ||
this.eventType, this.domListener, this.useCapture | ||
); | ||
newTopElement.addEventListener( | ||
this.eventType, this.domListener, this.useCapture | ||
); | ||
this.topElement = newTopElement; | ||
} | ||
} |
import {StreamAdapter} from '@cycle/base'; | ||
import {init} from 'snabbdom'; | ||
import {Stream} from 'xstream'; | ||
import xs, {Stream} from 'xstream'; | ||
import concat from 'xstream/extra/concat'; | ||
import {DOMSource} from './DOMSource'; | ||
@@ -56,7 +57,5 @@ import {VNode} from 'snabbdom'; | ||
.drop(1) | ||
.map(({elm}: any) => { | ||
elm.renderedByCycleDOM = true; | ||
return elm; | ||
}) | ||
.map(function unwrapElementFromVNode(vnode: VNode) { return vnode.elm; }) | ||
.startWith(rootElement) | ||
.compose(stream => concat(stream, xs.never())) // don't complete this stream | ||
.remember(); | ||
@@ -63,0 +62,0 @@ |
@@ -79,2 +79,37 @@ 'use strict'; | ||
it('should setup click detection on a ready DOM element (e.g. from server)', function (done) { | ||
function app() { | ||
return { | ||
DOM: Rx.Observable.never() | ||
}; | ||
} | ||
const containerElement = createRenderTarget(); | ||
let headerElement = document.createElement('H3'); | ||
headerElement.className = 'myelementclass'; | ||
headerElement.textContent = 'Foobar'; | ||
containerElement.appendChild(headerElement); | ||
const {sinks, sources, run} = Cycle(app, { | ||
DOM: makeDOMDriver(containerElement) | ||
}); | ||
let dispose = run(); | ||
sources.DOM.select('.myelementclass').events('click').subscribe(ev => { | ||
assert.strictEqual(ev.type, 'click'); | ||
assert.strictEqual(ev.target.textContent, 'Foobar'); | ||
dispose(); | ||
done(); | ||
}); | ||
// Make assertions | ||
setTimeout(() => { | ||
const myElement = containerElement.querySelector('.myelementclass'); | ||
assert.notStrictEqual(myElement, null); | ||
assert.notStrictEqual(typeof myElement, 'undefined'); | ||
assert.strictEqual(myElement.tagName, 'H3'); | ||
assert.doesNotThrow(function () { | ||
setTimeout(() => myElement.click()) | ||
}); | ||
}, 200); | ||
}); | ||
it('should catch events using id of root element in DOM.select', function (done) { | ||
@@ -81,0 +116,0 @@ function app() { |
@@ -221,2 +221,3 @@ 'use strict'; | ||
.map(els => els[0].innerHTML) | ||
.take(3) | ||
.subscribe((x) => { | ||
@@ -223,0 +224,0 @@ assert.strictEqual(x, expected.shift()); |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
1231739
21616