From ac1be5def27953c8398d8d121b8d68e1f31de3fd Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 23 Nov 2018 21:00:25 -0500 Subject: [PATCH] fix for contextual bindings --- src/compile/render-dom/wrappers/Element/Binding.ts | 14 ++++++++------ .../render-dom/wrappers/InlineComponent/index.ts | 2 -- src/compile/render-ssr/handlers/InlineComponent.ts | 4 ++-- .../{getTailSnippet.ts => get_tail_snippet.ts} | 13 ++++++++----- 4 files changed, 18 insertions(+), 15 deletions(-) rename src/utils/{getTailSnippet.ts => get_tail_snippet.ts} (50%) diff --git a/src/compile/render-dom/wrappers/Element/Binding.ts b/src/compile/render-dom/wrappers/Element/Binding.ts index 3b423fde86..7b787b0d4f 100644 --- a/src/compile/render-dom/wrappers/Element/Binding.ts +++ b/src/compile/render-dom/wrappers/Element/Binding.ts @@ -6,7 +6,7 @@ import Block from '../../Block'; import Node from '../../../nodes/shared/Node'; import Renderer from '../../Renderer'; import flattenReference from '../../../../utils/flattenReference'; -import getTailSnippet from '../../../../utils/getTailSnippet'; +import { get_tail } from '../../../../utils/get_tail_snippet'; // TODO this should live in a specific binding const readOnlyMediaAttributes = new Set([ @@ -99,7 +99,7 @@ export default class BindingWrapper { // view to model const valueFromDom = getValueFromDom(renderer, this.parent, this); - const handler = getEventHandler(this, block, name, contextless_snippet, valueFromDom); + const handler = getEventHandler(this, renderer, block, name, contextless_snippet, valueFromDom); // model to view let updateDom = getDomUpdater(parent, this, snippet); @@ -161,7 +161,6 @@ export default class BindingWrapper { needsLock: !isReadOnly && needsLock, updateCondition: updateConditions.length ? updateConditions.join(' && ') : undefined, isReadOnlyMediaAttribute: this.isReadOnlyMediaAttribute(), - // dependencies: this.node.expression.dependencies, dependencies, contextual_dependencies: this.node.expression.contextual_dependencies }; @@ -215,15 +214,18 @@ function getBindingGroup(renderer: Renderer, value: Node) { function getEventHandler( binding: BindingWrapper, + renderer: Renderer, block: Block, name: string, snippet: string, value: string ) { if (binding.node.isContextual) { - const tail = binding.node.expression.node.type === 'MemberExpression' - ? getTailSnippet(binding.node.expression.node) - : ''; + let tail = ''; + if (binding.node.expression.node.type === 'MemberExpression') { + const { start, end } = get_tail(binding.node.expression.node); + tail = renderer.component.source.slice(start, end); + } const { object, property, snippet } = block.bindings.get(name)(); diff --git a/src/compile/render-dom/wrappers/InlineComponent/index.ts b/src/compile/render-dom/wrappers/InlineComponent/index.ts index 9ff12ba996..2769ab9573 100644 --- a/src/compile/render-dom/wrappers/InlineComponent/index.ts +++ b/src/compile/render-dom/wrappers/InlineComponent/index.ts @@ -9,10 +9,8 @@ import stringifyProps from '../../../../utils/stringifyProps'; import addToSet from '../../../../utils/addToSet'; import deindent from '../../../../utils/deindent'; import Attribute from '../../../nodes/Attribute'; -import CodeBuilder from '../../../../utils/CodeBuilder'; import getObject from '../../../../utils/getObject'; import Binding from '../../../nodes/Binding'; -import getTailSnippet from '../../../../utils/getTailSnippet'; export default class InlineComponentWrapper extends Wrapper { var: string; diff --git a/src/compile/render-ssr/handlers/InlineComponent.ts b/src/compile/render-ssr/handlers/InlineComponent.ts index 1d0cea385a..7f693d5519 100644 --- a/src/compile/render-ssr/handlers/InlineComponent.ts +++ b/src/compile/render-ssr/handlers/InlineComponent.ts @@ -1,6 +1,6 @@ import { escape, escapeTemplate, stringify } from '../../../utils/stringify'; import getObject from '../../../utils/getObject'; -import getTailSnippet from '../../../utils/getTailSnippet'; +import { get_tail_snippet } from '../../../utils/get_tail_snippet'; import { quoteNameIfNecessary, quotePropIfNecessary } from '../../../utils/quoteIfNecessary'; import deindent from '../../../utils/deindent'; @@ -18,7 +18,7 @@ export default function(node, renderer, options) { const bindingProps = node.bindings.map(binding => { const { name } = getObject(binding.value.node); const tail = binding.value.node.type === 'MemberExpression' - ? getTailSnippet(binding.value.node) + ? get_tail_snippet(binding.value.node) : ''; return `${quoteNameIfNecessary(binding.name)}: ctx${quotePropIfNecessary(name)}${tail}`; diff --git a/src/utils/getTailSnippet.ts b/src/utils/get_tail_snippet.ts similarity index 50% rename from src/utils/getTailSnippet.ts rename to src/utils/get_tail_snippet.ts index df4d7b1ab4..8fc38c5be1 100644 --- a/src/utils/getTailSnippet.ts +++ b/src/utils/get_tail_snippet.ts @@ -1,9 +1,12 @@ import { Node } from '../interfaces'; -export default function getTailSnippet(node: Node) { - const end = node.end; - while (node.type === 'MemberExpression') node = node.object; - const start = node.end; - +export function get_tail_snippet(node: Node) { + const { start, end } = get_tail(node); return `[✂${start}-${end}✂]`; } + +export function get_tail(node: Node) { + const end = node.end; + while (node.type === 'MemberExpression') node = node.object; + return { start: node.end, end }; +} \ No newline at end of file