Skip to content

Commit

Permalink
fix(html): fix replacing event listener callback
Browse files Browse the repository at this point in the history
  • Loading branch information
smalluban committed Jan 24, 2020
1 parent e8a4ded commit e2dd413
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 16 deletions.
13 changes: 7 additions & 6 deletions src/template/core.js
Expand Up @@ -250,7 +250,7 @@ export function compileTemplate(rawParts, isSVG, styles) {

if (template !== data.template) {
if (data.template || target.nodeType === Node.ELEMENT_NODE) removeTemplate(target);
data.lastArgs = null;
data.prevArgs = null;

const fragment = document.importNode(applyShadyCSS(template, host.tagName).content, true);

Expand Down Expand Up @@ -306,25 +306,26 @@ export function compileTemplate(rawParts, isSVG, styles) {
}
}

const prevArgs = data.prevArgs;
data.prevArgs = args;

for (let index = 0; index < data.markers.length; index += 1) {
const [node, marker] = data.markers[index];
if (!data.lastArgs || data.lastArgs[index] !== args[index]) {
marker(host, node, args[index], data.lastArgs ? data.lastArgs[index] : undefined);
if (!prevArgs || prevArgs[index] !== args[index]) {
marker(host, node, args[index], prevArgs ? prevArgs[index] : undefined);
}
}

if (target.nodeType !== Node.TEXT_NODE) {
shadyCSS((shady) => {
if (host.shadowRoot) {
if (data.lastArgs) {
if (prevArgs) {
shady.styleSubtree(host);
} else {
shady.styleElement(host);
}
}
});
}

data.lastArgs = args;
};
}
26 changes: 18 additions & 8 deletions src/template/resolvers/event.js
@@ -1,25 +1,35 @@
const eventMap = new WeakMap();
const targets = new WeakMap();

export default function resolveEventListener(eventType) {
return (host, target, value, lastValue) => {
if (lastValue) {
target.removeEventListener(
eventType,
eventMap.get(lastValue),
lastValue.options !== undefined ? lastValue.options : false,
);
const eventMap = targets.get(target);
if (eventMap) {
target.removeEventListener(
eventType,
eventMap.get(lastValue),
lastValue.options !== undefined ? lastValue.options : false,
);
}
}

if (value) {
if (typeof value !== 'function') {
throw Error(`Event listener must be a function: ${typeof value}`);
}

eventMap.set(value, value.bind(null, host));
let eventMap = targets.get(target);
if (!eventMap) {
eventMap = new WeakMap();
targets.set(target, eventMap);
}

const callback = value.bind(null, host);
eventMap.set(value, callback);

target.addEventListener(
eventType,
eventMap.get(value),
callback,
value.options !== undefined ? value.options : false,
);
}
Expand Down
7 changes: 5 additions & 2 deletions test/spec/html.js
Expand Up @@ -239,7 +239,7 @@ describe('html:', () => {
});

describe('event attribute expression', () => {
const render = (value) => html`<button onclick=${value}></button>`;
const render = (value) => html`<button onclick=${value}></button><button onclick=${value}></button>`;
const renderWithQuotes = (value) => html`<button onclick="${value}"></button>`;

const click = () => fragment.children[0].click();
Expand All @@ -249,10 +249,13 @@ describe('html:', () => {
spy = jasmine.createSpy('event callback');
});

it('throws for other type than function', () => {
it('throws for other type than function and attaches event after', () => {
expect(() => {
render({})(fragment);
}).toThrow();
render(spy)(fragment);
click();
expect(spy).toHaveBeenCalledTimes(1);
});

it('attaches event listener', () => {
Expand Down

0 comments on commit e2dd413

Please sign in to comment.