From c337ce792a8ea39239be01aea200eca2194de0e1 Mon Sep 17 00:00:00 2001 From: himynameisdave Date: Mon, 20 Jan 2020 17:46:42 -0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A8=20Hammer=20out=20some=20final=20is?= =?UTF-8?q?sues?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/compiler/compile/nodes/Element.ts | 4 ++-- .../render_dom/wrappers/Element/index.ts | 18 +++++++--------- .../compile/render_ssr/handlers/Element.ts | 4 ++-- src/compiler/compile/utils/__test__.ts | 17 +++++++-------- src/compiler/compile/utils/contenteditable.ts | 21 ++++++++----------- .../contenteditable-missing/errors.json | 4 ++-- 6 files changed, 30 insertions(+), 38 deletions(-) diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts index 458ebc9112..3a682cea88 100644 --- a/src/compiler/compile/nodes/Element.ts +++ b/src/compiler/compile/nodes/Element.ts @@ -10,7 +10,7 @@ import Class from './Class'; import Text from './Text'; import { namespaces } from '../../utils/namespaces'; import map_children from './shared/map_children'; -import { isBindingContenteditable, getContenteditableAttr } from '../utils/contenteditable'; +import { isNameContenteditable, getContenteditableAttr } from '../utils/contenteditable'; import { dimensions } from '../../utils/patterns'; import fuzzymatch from '../../utils/fuzzymatch'; import list from '../../utils/list'; @@ -770,7 +770,7 @@ export default class Element extends Node { }); } } else if ( - isBindingContenteditable(binding) + isNameContenteditable(name) ) { const contenteditable = getContenteditableAttr(this); if (!contenteditable) { diff --git a/src/compiler/compile/render_dom/wrappers/Element/index.ts b/src/compiler/compile/render_dom/wrappers/Element/index.ts index b21a1aa24b..5124006235 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/index.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/index.ts @@ -26,6 +26,7 @@ import Action from '../../../nodes/Action'; import MustacheTagWrapper from '../MustacheTag'; import RawMustacheTagWrapper from '../RawMustacheTag'; import is_dynamic from '../shared/is_dynamic'; +import { isNameContenteditable, hasContentEditableAttr } from '../../../utils/contenteditable'; interface BindingGroup { events: string[]; @@ -42,8 +43,8 @@ const events = [ { event_names: ['input'], filter: (node: Element, name: string) => - (name === 'textContent' || name === 'innerHTML') && - node.attributes.some(attribute => attribute.name === 'contenteditable') + isNameContenteditable(name) && + hasContentEditableAttr(node) }, { event_names: ['change'], @@ -544,14 +545,11 @@ export default class ElementWrapper extends Wrapper { const should_initialise = ( this.node.name === 'select' || - binding_group.bindings.find(binding => { - return ( - binding.node.name === 'indeterminate' || - binding.node.name === 'textContent' || - binding.node.name === 'innerHTML' || - binding.is_readonly_media_attribute() - ); - }) + binding_group.bindings.find(binding => ( + binding.node.name === 'indeterminate' || + isNameContenteditable(binding.node.name) || + binding.is_readonly_media_attribute() + )) ); if (should_initialise) { diff --git a/src/compiler/compile/render_ssr/handlers/Element.ts b/src/compiler/compile/render_ssr/handlers/Element.ts index a74783f880..ee93e31ede 100644 --- a/src/compiler/compile/render_ssr/handlers/Element.ts +++ b/src/compiler/compile/render_ssr/handlers/Element.ts @@ -1,5 +1,5 @@ import { is_void } from '../../../utils/names'; -import { isBindingContenteditable, isContenteditable } from '../../utils/contenteditable'; +import { isNameContenteditable, isContenteditable } from '../../utils/contenteditable'; import { get_attribute_value, get_class_attribute_value } from './shared/get_attribute_value'; import { boolean_attributes } from './shared/boolean_attributes'; import Renderer, { RenderOptions } from '../Renderer'; @@ -102,7 +102,7 @@ export default function(node: Element, renderer: Renderer, options: RenderOption if (name === 'group') { // TODO server-render group bindings - } else if (contenteditable && isBindingContenteditable(binding)) { + } else if (contenteditable && isNameContenteditable(name)) { node_contents = expression.node; // TODO where was this used? diff --git a/src/compiler/compile/utils/__test__.ts b/src/compiler/compile/utils/__test__.ts index 8a8a653345..a2138765d0 100644 --- a/src/compiler/compile/utils/__test__.ts +++ b/src/compiler/compile/utils/__test__.ts @@ -5,14 +5,13 @@ import { isInputOrTextarea, isAttrContentEditable, hasContentEditableAttr, - isBindingContenteditable, + isNameContenteditable, getContenteditableAttr, CONTENTEDITABLE_ATTR, CONTENTEDITABLE_BINDINGS, } from './contenteditable'; import Element from '../nodes/Element'; import Attribute from '../nodes/Attribute'; -import Binding from '../nodes/Binding'; describe('get_name_from_filename', () => { it('uses the basename', () => { @@ -90,17 +89,15 @@ describe('contenteditable', () => { }); }); - describe('isBindingContenteditable', () => { - it('returns true if binding is a contenteditable type', () => { - const binding = { name: CONTENTEDITABLE_BINDINGS[0] } as Binding; - assert.equal(isBindingContenteditable(binding), true); + describe('isNameContenteditable', () => { + it('returns true if name is a contenteditable type', () => { + assert.equal(isNameContenteditable(CONTENTEDITABLE_BINDINGS[0]), true); }); - it('returns false if attribute is not contenteditable type', () => { - const binding = { name: 'value' } as Binding; - assert.equal(isBindingContenteditable(binding), false); + it('returns false if name is not contenteditable type', () => { + assert.equal(isNameContenteditable('value'), false); }); }); - + describe('getContenteditableAttr', () => { it('returns the contenteditable Attribute if it exists', () => { const attr = { name: CONTENTEDITABLE_ATTR } as Attribute; diff --git a/src/compiler/compile/utils/contenteditable.ts b/src/compiler/compile/utils/contenteditable.ts index ae27f20798..6d5da614af 100644 --- a/src/compiler/compile/utils/contenteditable.ts +++ b/src/compiler/compile/utils/contenteditable.ts @@ -1,6 +1,5 @@ // Utilities for managing contenteditable nodes import Attribute from '../nodes/Attribute'; -import Binding from '../nodes/Binding'; import Element from '../nodes/Element'; @@ -13,7 +12,7 @@ export const CONTENTEDITABLE_BINDINGS = [ ]; /** - * Returns true if node is an 'input' or 'textarea' + * Returns true if node is an 'input' or 'textarea'. * @param {Element} node The element to be checked */ export function isInputOrTextarea(node: Element): boolean { @@ -21,7 +20,7 @@ export function isInputOrTextarea(node: Element): boolean { } /** - * Check if a given attribute is 'contenteditable' + * Check if a given attribute is 'contenteditable'. * @param {Attribute} attribute A node.attribute */ export function isAttrContentEditable(attribute: Attribute): boolean { @@ -29,7 +28,7 @@ export function isAttrContentEditable(attribute: Attribute): boolean { } /** - * Check if any of a node's attributes are 'contentenditable' + * Check if any of a node's attributes are 'contentenditable'. * @param {Element} node The element to be checked */ export function hasContentEditableAttr(node: Element): boolean { @@ -37,7 +36,7 @@ export function hasContentEditableAttr(node: Element): boolean { } /** - * Returns true if node is not textarea or input, but has 'contenteditable' attribute + * Returns true if node is not textarea or input, but has 'contenteditable' attribute. * @param {Element} node The element to be tested */ export function isContenteditable(node: Element): boolean { @@ -45,17 +44,15 @@ export function isContenteditable(node: Element): boolean { } /** - * Returns true if a given bindings should be contenteditable - * - * @param {Binding} binding A node's binding to be checked + * Returns true if a given binding/node is contenteditable. + * @param {string} name A binding or node name to be checked */ -export function isBindingContenteditable(binding: Binding): boolean { - return CONTENTEDITABLE_BINDINGS.includes(binding.name); +export function isNameContenteditable(name: string): boolean { + return CONTENTEDITABLE_BINDINGS.includes(name); } /** - * Returns the contenteditable attribute from the node (if it exists) - * + * Returns the contenteditable attribute from the node (if it exists). * @param {Element} node The element to get the attribute from */ export function getContenteditableAttr(node: Element): Attribute | undefined { diff --git a/test/validator/samples/contenteditable-missing/errors.json b/test/validator/samples/contenteditable-missing/errors.json index 53d5af4928..b188dd6a12 100644 --- a/test/validator/samples/contenteditable-missing/errors.json +++ b/test/validator/samples/contenteditable-missing/errors.json @@ -1,6 +1,6 @@ [{ "code": "missing-contenteditable-attribute", - "message": "'contenteditable' attribute is required for textContent and innerHTML two-way bindings", + "message": "'contenteditable' attribute is required for textContent/innerHTML/innerText two-way bindings", "start": { "line": 4, "column": 8, @@ -12,4 +12,4 @@ "character": 71 }, "pos": 48 -}] \ No newline at end of file +}]