Skip to content

Commit

Permalink
* refactor(engine): removal of is attr and forceTagName
Browse files Browse the repository at this point in the history
* refactor(engine): removal of is attr and forceTagName
* fix(engine): removing integration test for forceTagName
* fix: remove custom element transformation from CSS (#695)
* fix(compiler): fixing fixtures
* refactor(engine): snabbdom lite - phase 1 (#606)
* refactor(engine): removal of is attr and forceTagName
* refactor(engine): removal of is attr and forceTagName
* fix(engine): removing integration test for forceTagName
* refactor(engine): snabbdom lite - phase 1
* refactor(engine): adding hooks.ts
* refactor(engine): removing global hooks
* refactor(engine): splitting style and class modules into static and dynamic
* test(engine): ready for the final push
* refactor(engine): making hooks mandatory.
* refactor(engine): making all hooks functions
* refactor(engine): dynamic diff vs static diff
* refactor(engine): using two diff algos
* refactor(engine): removing htmlapi in favor of pure patching
* fix(engine): missing argument when determining diff algo
* fix(engine): adding tests for dynamic diff
* fix(engine): clean up
* fix(engine): integration test failures
* refactor(engine): proto chaining
* fix(engine): wrong auto import
* fix(engine): correcting the proto chain
* refactor(engine): implementing the base element proto chain
* test(engine): adding more tests for restrictions on elements
* refactor(engine): rename to BaseBridgeElement
* feat(engine): dom patching (#688)
* feat(engine): dom patching
* fix(engine): cleanup descriptors
* feat(engine): rebase
* fix(engine): linting
* fix(engine): pr feedback
* fix(engine): lint
* fix(compiler): updated snapshot testing to account for shadow dom
* fix(engine): pr feedback
* fix(engine): fixing restrictions on custom elements
* fix(engine): exposing host (#705)
* fix(engine): exposing host
* fix(engine): shadow root
* wip(engine): linting and type errors
* fix(engine): cleaning up shadow root detection
* fix(engine): removing restrictions test
* fix(engine): fixing element from point methods
* fix(engine): disabling some attribute integration test for now
* fix(engine): linting
* fix(engine): upgrade ie11 driver
* fix(engine): compat test fix
* fix(engine): applying elementFromPoint on document
* fix(engine): linting
* fix(engine): reverting unnecessary changes
* fix(engine): removing skip in test
* fix(engine): polyfill readmes
* fix(engine): review feedback
* fix(engine): integration tests for elementFromPoint
* fix(engine): ie11 elementsFromPoint
* fix(engine): feedback
* fix(engine): ts fix
* wip: yarn update
* fix(engine): fixing snapshot test

wip: styles still broken

wip: fix styles
  • Loading branch information
caridy authored and Diego Ferreiro Val committed Oct 19, 2018
1 parent 74545c3 commit 8f7fa7c
Show file tree
Hide file tree
Showing 11 changed files with 61 additions and 222 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 7 additions & 12 deletions packages/lwc-engine/src/faux-shadow/shadow-root.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import assert from "../shared/assert";
import { isFalse, create, isUndefined, getOwnPropertyDescriptor, ArrayReduce, isNull, defineProperties, setPrototypeOf } from "../shared/language";
import { addShadowRootEventListener, removeShadowRootEventListener } from "./events";
<<<<<<< HEAD
import { shadowDomElementFromPoint, shadowRootQuerySelector, shadowRootQuerySelectorAll, shadowRootChildNodes, isNodeOwnedBy, isSlotElement } from "./traverse";
=======
import { shadowDomElementFromPoint, shadowRootQuerySelector, shadowRootQuerySelectorAll, shadowRootChildNodes, isNodeOwnedBy } from "./traverse";
>>>>>>> * refactor(engine): removal of is attr and forceTagName
import { getInternalField, setInternalField, createFieldName } from "../shared/fields";
import { getInnerHTML } from "../3rdparty/polymer/inner-html";
import { getTextContent } from "../3rdparty/polymer/text-content";
Expand Down Expand Up @@ -118,18 +122,9 @@ function activeElementGetter(this: SyntheticShadowRoot): Element | null {
}

// activeElement must be child of the host and owned by it
let node = activeElement;
while (!isNodeOwnedBy(host, node)) {
node = parentElementGetter.call(node);
}

// If we have a slot element here
// That means that we were dealing with an element that was passed to one of our slots
// In this case, activeElement returns null
if (isSlotElement(node)) {
return null;
}
return node;
// TODO: what happen with delegatesFocus is true for a child component?
return (compareDocumentPosition.call(host, activeElement) & DOCUMENT_POSITION_CONTAINED_BY) !== 0 &&
isNodeOwnedBy(host, activeElement) ? activeElement : null;
}

export enum ShadowRootMode {
Expand Down
182 changes: 0 additions & 182 deletions packages/lwc-engine/src/framework/__tests__/api.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,186 +237,4 @@ describe('api', () => {
}).toThrow('Invalid key value "[object Object]" in [object:vm Foo (8)]. Key must be a string or number.');
});
});

describe('#ti()', () => {
it('should return 0 when value is not 0 or -1', () => {
let normalized;
function html($api) {
normalized = $api.ti(2);
return [];
}
class Foo extends LightningElement {
render() {
return html;
}
}
const elm = createElement('x-foo', { is: Foo });
expect(() => {
document.body.appendChild(elm);
}).toLogWarning('Invalid tabindex value `2` in template for [object:vm Foo (9)]. This attribute can only be set to 0 or -1.');
expect(normalized).toBe(0);
});

it('should return null when value is null', () => {
let normalized;
function html($api) {
normalized = $api.ti(null);
return [];
}
class Foo extends LightningElement {
render() {
return html;
}
}
const elm = createElement('x-foo', { is: Foo });
document.body.appendChild(elm);
expect(normalized).toBe(null);
});

it('should return undefined when value is undefined', () => {
let normalized;
function html($api) {
normalized = $api.ti(undefined);
return [];
}
class Foo extends LightningElement {
render() {
return html;
}
}
const elm = createElement('x-foo', { is: Foo });
document.body.appendChild(elm);
expect(normalized).toBe(undefined);
});

it('should return 0 when value is "3"', () => {
let normalized;
function html($api) {
normalized = $api.ti('3');
return [];
}
class Foo extends LightningElement {
render() {
return html;
}
}
const elm = createElement('x-foo', { is: Foo });
expect(() => {
document.body.appendChild(elm);
}).toLogWarning('Invalid tabindex value `3` in template for [object:vm Foo (12)]. This attribute can only be set to 0 or -1.');
expect(normalized).toBe(0);
});

it('should return -3 when value is -3', () => {
let normalized;
function html($api) {
normalized = $api.ti(-3);
return [];
}
class Foo extends LightningElement {
render() {
return html;
}
}
const elm = createElement('x-foo', { is: Foo });
document.body.appendChild(elm);
expect(normalized).toBe(-3);
});

it('should return 0 when value is 0', () => {
let normalized;
function html($api) {
normalized = $api.ti(0);
return [];
}
class Foo extends LightningElement {
render() {
return html;
}
}
const elm = createElement('x-foo', { is: Foo });
document.body.appendChild(elm);
expect(normalized).toBe(0);
});

it('should return -1 when value is -1', () => {
let normalized;
function html($api) {
normalized = $api.ti(-1);
return [];
}
class Foo extends LightningElement {
render() {
return html;
}
}
const elm = createElement('x-foo', { is: Foo });
document.body.appendChild(elm);
expect(normalized).toBe(-1);
});

it('should return NaN when value is NaN', () => {
let normalized;
function html($api) {
normalized = $api.ti(NaN);
return [];
}
class Foo extends LightningElement {
render() {
return html;
}
}
const elm = createElement('x-foo', { is: Foo });
document.body.appendChild(elm);
expect(normalized).toBe(NaN);
});

it('should return empty string when value is empty string', () => {
let normalized;
function html($api) {
normalized = $api.ti('');
return [];
}
class Foo extends LightningElement {
render() {
return html;
}
}
const elm = createElement('x-foo', { is: Foo });
document.body.appendChild(elm);
expect(normalized).toBe('');
});

it('should return true when value is true', () => {
let normalized;
function html($api) {
normalized = $api.ti(true);
return [];
}
class Foo extends LightningElement {
render() {
return html;
}
}
const elm = createElement('x-foo', { is: Foo });
document.body.appendChild(elm);
expect(normalized).toBe(true);
});

it('should return false when value is false', () => {
let normalized;
function html($api) {
normalized = $api.ti(false);
return [];
}
class Foo extends LightningElement {
render() {
return html;
}
}
const elm = createElement('x-foo', { is: Foo });
document.body.appendChild(elm);
expect(normalized).toBe(false);
});
});
});
37 changes: 13 additions & 24 deletions packages/lwc-engine/src/framework/api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import assert from "../shared/assert";
import { vmBeingRendered, invokeEventListener } from "./invoker";
<<<<<<< HEAD
import { isArray, isUndefined, isNull, isFunction, isObject, isString, ArrayPush, create as ObjectCreate, forEach, StringCharCodeAt, isNumber, isTrue, isFalse, toString } from "../shared/language";
=======
import { isArray, isUndefined, isNull, isFunction, isObject, isString, ArrayPush, create as ObjectCreate, forEach, StringCharCodeAt, isNumber, isTrue } from "../shared/language";
>>>>>>> * refactor(engine): removal of is attr and forceTagName
import { EmptyArray, resolveCircularModuleDependency, isCircularModuleDependency, EmptyObject } from "./utils";
import { VM, SlotSet } from "./vm";
import { ComponentConstructor } from "./component";
Expand Down Expand Up @@ -72,11 +76,7 @@ function noop() { /* do nothing */ }

const TextHook: Hooks = {
create: (vnode: VNode) => {
if (isUndefined(vnode.elm)) {
// supporting the ability to inject an element via a vnode
// this is used mostly for caching in compiler
vnode.elm = createTextNode.call(document, vnode.text);
}
vnode.elm = createTextNode.call(document, vnode.text);
createTextHook(vnode);
},
update: updateNodeHook,
Expand All @@ -87,11 +87,7 @@ const TextHook: Hooks = {

const CommentHook: Hooks = {
create: (vnode: VComment) => {
if (isUndefined(vnode.elm)) {
// supporting the ability to inject an element via a vnode
// this is used mostly for caching in compiler
vnode.elm = createComment.call(document, vnode.text);
}
vnode.elm = createComment.call(document, vnode.text);
createCommentHook(vnode);
},
update: updateNodeHook,
Expand All @@ -107,15 +103,11 @@ const CommentHook: Hooks = {
// Custom Element that is inserted via a template.
const ElementHook: Hooks = {
create: (vnode: VElement) => {
const { data, sel, elm } = vnode;
const { data, sel } = vnode;
const { ns, create } = data;
if (isUndefined(elm)) {
// supporting the ability to inject an element via a vnode
// this is used mostly for caching in compiler and style tags
vnode.elm = isUndefined(ns)
? createElement.call(document, sel)
: createElementNS.call(document, ns, sel);
}
vnode.elm = isUndefined(ns)
? createElement.call(document, sel)
: createElementNS.call(document, ns, sel);
createElmHook(vnode);
create(vnode);
},
Expand All @@ -137,12 +129,9 @@ const ElementHook: Hooks = {

const CustomElementHook: Hooks = {
create: (vnode: VCustomElement) => {
const { sel, data: { create }, elm } = vnode;
if (isUndefined(elm)) {
// supporting the ability to inject an element via a vnode
// this is used mostly for caching in compiler and style tags
vnode.elm = createElement.call(document, sel);
}
const { sel, data: { create } } = vnode;
vnode.elm = createElement.call(document, sel);
createElmHook(vnode);
createCustomElmHook(vnode);
allocateChildrenHook(vnode);
create(vnode);
Expand Down
2 changes: 1 addition & 1 deletion packages/lwc-engine/src/framework/html-properties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { defaultDefHTMLPropertyNames } from "./attributes";
import { ElementPrototypeAriaPropertyNames } from '../polyfills/aria-properties/polyfill';

// Initialization Routines
import "../polyfills/document-shadow/main";
import "../polyfills/document-element-from-point/main";
import "../polyfills/shadow-root/main";
import "../polyfills/proxy-concat/main";
import "../polyfills/click-event-composed/main"; // must come before event-composed
Expand Down
2 changes: 1 addition & 1 deletion packages/lwc-engine/src/framework/patch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { elementTagNameGetter } from "./dom-api";
import { updateDynamicChildren, updateStaticChildren } from "../3rdparty/snabbdom/snabbdom";
import { setPrototypeOf, getPrototypeOf, create, isUndefined } from "../shared/language";
import { ComponentDef } from "./def";
import { HTMLElementConstructor } from "./base-bridge-element";
import { HTMLElementConstructor } from "lwc-engine/src/framework/base-bridge-element";
import { ElementPatchDescriptors, SlotPatchDescriptors, NodePatchDescriptors, IframeDescriptors } from "../faux-shadow/traverse";

// Using a WeakMap instead of a WeakSet because this one works in IE11 :(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# document.elementFromPoint polyfill

This polyfill is needed to make `document.elementFromPoint` aware of our synthetic shadow roots.

- Polyfill will only return root nodes from LWC trees
- Polyfill works correctly in both Synthetic and Native Shadow Dom modes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function detect(): boolean {
return true;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import detect from './detect';
import apply from './polyfill';

if (detect()) {
apply();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { elementsFromPoint } from "../../faux-shadow/document";
import { getNodeOwnerKey } from "../../framework/vm";
import { isUndefined } from "../../shared/language";

export default function apply() {
function elemFromPoint(left: number, top: number): Element | null {
const elements = elementsFromPoint.call(document, left, top);
const { length } = elements;
let match = null;
for (let i = length - 1; i >= 0; i -= 1) {
const el = elements[i];
const ownerKey = getNodeOwnerKey(el);
if (isUndefined(ownerKey)) {
match = elements[i];
}
}
return match;
}

// https://github.com/Microsoft/TypeScript/issues/14139
document.elementFromPoint = elemFromPoint as (left: number, top: number) => Element;
}

0 comments on commit 8f7fa7c

Please sign in to comment.