Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(compiler): update structure in get template method #62

Merged
merged 7 commits into from
Apr 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 59 additions & 27 deletions packages/pwc-compiler/__tests__/compileScript.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ const multipleKindsOfUsingBindingsComponent = `
attr3="{{this.data3.arr1[0]}}"
attr4="{{this['data-five']}}"
@click="{{this.#fn}}"
onevent="{{this.#fn}}"
@input="{{this.methods.fn2}}"
>
<div>{{ this.#data1 }}</div>
Expand Down Expand Up @@ -146,7 +147,11 @@ export default class CustomElement extends HTMLElement {
const result = compileScript(descriptor);

expect(result.content).toContain(`get template() {
return [\"\\n <p><!--?pwc_t--></p>\\n\", [this.#text]];
return {
templateString: \"\\n <p><!--?pwc_t--></p>\\n\",
templateData: [this.#text],
template: true
};
}`);
});

Expand All @@ -169,7 +174,11 @@ export default class CustomElement extends HTMLElement {
data = {};

get template() {
return ["\\n <p><!--?pwc_t--></p>\\n", [this.#text]];
return {
templateString: "\\n <p><!--?pwc_t--></p>\\n",
templateData: [this.#text],
template: true
};
}

}`);
Expand All @@ -196,7 +205,11 @@ export default class CustomElement extends HTMLElement {
};

get template() {
return ["\\n <p><!--?pwc_t--></p>\\n <p><!--?pwc_t--></p>\\n <p><!--?pwc_t--></p>\\n", [this.data.name, this.arr[0], this.nestedData.obj1.obj2.age]];
return {
templateString: "\\n <p><!--?pwc_t--></p>\\n <p><!--?pwc_t--></p>\\n <p><!--?pwc_t--></p>\\n",
templateData: [this.data.name, this.arr[0], this.nestedData.obj1.obj2.age],
template: true
};
}

}`);
Expand All @@ -214,7 +227,11 @@ export default class CustomElement extends HTMLElement {
accessor insideName = '';

get template() {
return ["\\n <p><!--?pwc_t--></p>\\n <p><!--?pwc_t--></p>\\n", [outsideName, this.insideName]];
return {
templateString: "\\n <p><!--?pwc_t--></p>\\n <p><!--?pwc_t--></p>\\n",
templateData: [outsideName, this.insideName],
template: true
};
}

}`);
Expand All @@ -228,7 +245,11 @@ export default class CustomElement extends HTMLElement {
@customElement(\"custom-element\")
export default class CustomElement extends HTMLElement {
get template() {
return [\"\\n <p>hello</p>\\n\", []];
return {
templateString: "\\n <p>hello</p>\\n",
templateData: [],
template: true
};
}

}`);
Expand All @@ -242,7 +263,11 @@ export default class CustomElement extends HTMLElement {
@customElement('custom-element')
export default class CustomElement extends HTMLElement {
get template() {
return [\"\\n <p>hello</p>\\n\", []];
return {
templateString: "\\n <p>hello</p>\\n",
templateData: [],
template: true
};
}

}`);
Expand Down Expand Up @@ -279,27 +304,34 @@ export default class CustomElement extends HTMLElement {
};

get template() {
return ["\\n <!--?pwc_p--><div>\\n <div><!--?pwc_t--></div>\\n <div><!--?pwc_t--></div>\\n <div><!--?pwc_t--></div>\\n <div><!--?pwc_t--></div>\\n <div><!--?pwc_t--></div>\\n </div>\\n", [[{
name: "attr1",
value: this.#data1
}, {
name: "attr2",
value: this.#data2.name1
}, {
name: "attr3",
value: this.data3.arr1[0]
}, {
name: "attr4",
value: this['data-five']
}, {
name: "onclick",
value: this.#fn,
capture: false
}, {
name: "oninput",
value: this.methods.fn2,
capture: false
}], this.#data1, this.#data2.name1, this.data3.arr1[0], this.data4.obj1.name2, this['data-five']]];
return {
templateString: "\\n <!--?pwc_p--><div>\\n <div><!--?pwc_t--></div>\\n <div><!--?pwc_t--></div>\\n <div><!--?pwc_t--></div>\\n <div><!--?pwc_t--></div>\\n <div><!--?pwc_t--></div>\\n </div>\\n",
templateData: [[{
name: "attr1",
value: this.#data1
}, {
name: "attr2",
value: this.#data2.name1
}, {
name: "attr3",
value: this.data3.arr1[0]
}, {
name: "attr4",
value: this['data-five']
}, {
name: "onclick",
handler: this.#fn,
capture: false
}, {
name: "onevent",
value: this.#fn
}, {
name: "oninput",
handler: this.methods.fn2,
capture: false
}], this.#data1, this.#data2.name1, this.data3.arr1[0], this.data4.obj1.name2, this['data-five']],
template: true
};
}

}`);
Expand Down
29 changes: 23 additions & 6 deletions packages/pwc-compiler/__tests__/compileTemplate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ describe('compileTemplate', () => {
[
{
name: 'onclick',
value: 'handleClick',
handler: 'handleClick',
capture: false,
}
],
Expand All @@ -51,7 +51,7 @@ describe('compileTemplate', () => {
[
{
name: 'onclick',
value: 'this.handleClick',
handler: 'this.handleClick',
capture: false,
}
],
Expand All @@ -68,14 +68,31 @@ describe('compileTemplate', () => {
[
{
name: 'onclick',
value: 'handleClick',
handler: 'handleClick',
capture: true,
}
],
'text'
]);
});

it('compile a template with an attribute start with on', () => {
const { descriptor } = parse('<template><custom-component onevent="{{handleEvent}}">{{text}}</custom-component></template>');
const { templateString, values} = compileTemplateAST(descriptor.template.ast);

expect(templateString).toBe('<!--?pwc_p--><custom-component><!--?pwc_t--></custom-component>');
expect(values).toEqual([
[
{
name: 'onevent',
value: 'handleEvent'
}
],
'text'
]);
});


it('compile a template with attributes', () => {
const { descriptor } = parse('<template><p class="{{className}}">{{text}}</p></template>');
const { templateString, values} = compileTemplateAST(descriptor.template.ast);
Expand Down Expand Up @@ -166,7 +183,7 @@ describe('compileTemplate', () => {
[
{
name: 'onclick',
value: '() => (count++)',
handler: '() => (count++)',
capture: false
}
],
Expand All @@ -182,7 +199,7 @@ describe('compileTemplate', () => {
[
{
name: 'onclick',
value: `() => (say('hello'))`,
handler: `() => (say('hello'))`,
capture: false
}
],
Expand All @@ -198,7 +215,7 @@ describe('compileTemplate', () => {
[
{
name: 'onclick',
value: `(event) => warn('', event)`,
handler: `(event) => warn('', event)`,
capture: false
}
],
Expand Down
1 change: 1 addition & 0 deletions packages/pwc-compiler/build.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export default defineConfig({
sourceMaps: 'inline',

transform: {
formats: ['cjs', 'es2017', 'esm'],
excludes: ['**/__tests__/**'],
},
});
3 changes: 2 additions & 1 deletion packages/pwc-compiler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
"author": "Rax Team",
"homepage": "https://github.com/raxjs/pwc#readme",
"license": "MIT",
"main": "esm/index.js",
"main": "cjs/index.js",
"module": "esm/index.js",
"exports": {
".": {
"es": "./esm/index.js",
"es2017": "./es2017/index.js",
"require": "./cjs/index.js",
"default": "./esm/index.js"
},
"./compileTemplateInRuntime": {
Expand Down
16 changes: 11 additions & 5 deletions packages/pwc-compiler/src/compileTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,19 @@ import * as parse5 from 'parse5';
import type { SFCDescriptor, ElementNode } from './parse';
import { dfs, isEventNameInTemplate, isBindings, isMemberExpression, getEventInfo, BINDING_REGEXP, INTERPOLATION_REGEXP } from './utils';

export interface AttributeDescriptor {
export interface NormalAttributeDescriptor {
name: string;
value: string;
capture?: boolean;
}

export interface EventAttributeDescriptor {
name: string;
handler: string;
capture: boolean;
}

export type AttributeDescriptor = NormalAttributeDescriptor | EventAttributeDescriptor;

export type ValueDescriptor = Array<string | Array<AttributeDescriptor>>;

export interface CompileTemplateResult {
Expand Down Expand Up @@ -35,7 +42,7 @@ function createTextNode(value) {

// with side effect in changing node structure
function extractAttributeBindings(node: ElementNode): Array<AttributeDescriptor> {
const tempAttributeDescriptor = [];
const tempAttributeDescriptor: Array<AttributeDescriptor> = [];
// Extract attribute bindings
if (node.attrs?.length > 0) {
let hasInsertComment = false; // Should only insert comment node before current node once
Expand Down Expand Up @@ -68,13 +75,12 @@ function extractAttributeBindings(node: ElementNode): Array<AttributeDescriptor>

tempAttributeDescriptor.push({
name: `on${eventName}`,
value: expression,
handler: expression,
capture: isCapture,
});
} else {
// attributes
let expression = attr.value.replace(BINDING_REGEXP, '$1').trim();

tempAttributeDescriptor.push({
name: attr.name,
value: expression,
Expand Down
48 changes: 34 additions & 14 deletions packages/pwc-compiler/src/transform/genGetTemplateMethod.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import type { File } from '@babel/types';
import * as t from '@babel/types';
import babelTraverse from '@babel/traverse';
import { isBoolean } from '../utils';

import type { CompileTemplateResult, AttributeDescriptor } from '../compileTemplate';
import type { CompileTemplateResult } from '../compileTemplate';

function createObjectProperty(key, value) {
if (key === 'value') {
return t.objectProperty(t.identifier(key), createIdentifier(value));
} else if (key === 'name') {
return t.objectProperty(t.identifier(key), t.stringLiteral(value));
} else if (key === 'capture') {
return t.objectProperty(t.identifier(key), t.booleanLiteral(value));
}
interface objectExpression {
[key: string]: t.Expression;
}

function createObjectExpression(obj: AttributeDescriptor) {
function createObjectProperty(key: string, value: t.Expression) {
return t.objectProperty(t.identifier(key), value);
}

function createObjectExpression(obj: objectExpression) {
return t.objectExpression(Object.entries(obj).map(([key, value]) => {
return createObjectProperty(key, value);
}));
Expand Down Expand Up @@ -45,6 +44,8 @@ function cretateGetTemplateClassMethod(returnExpression) {
);
}

const templateFlag = t.booleanLiteral(true);

export default function genGetTemplateMethod(ast: File, templateResult: CompileTemplateResult): void {
babelTraverse(ast, {
ClassDeclaration(path) {
Expand All @@ -66,7 +67,7 @@ export default function genGetTemplateMethod(ast: File, templateResult: CompileT
[
{
name: 'onclick',
value: 'onClick',
handler: 'onClick',
capture: true,
},
{
Expand All @@ -76,11 +77,30 @@ export default function genGetTemplateMethod(ast: File, templateResult: CompileT
]
*/
return createArrayExpression(val.map(attr => {
return createObjectExpression(attr);
}));
const attributeEntries = Object.entries(attr).map(([key, val]) => {
let expression;
if (key === 'name') {
expression = t.stringLiteral(val);
} else if (key === 'value' || key === 'handler') {
expression = createIdentifier(val);
} else if (key === 'capture') {
expression = t.booleanLiteral(val);
}
return [key, expression];
});
const attributeObjectExpression = Object.fromEntries(attributeEntries);
return createObjectExpression(attributeObjectExpression);
},
));
}
}));
const returnExpression = createArrayExpression([templateStringExpression, templateValuesExpression]);

const returnExpression = createObjectExpression({
templateString: templateStringExpression,
templateData: templateValuesExpression,
template: templateFlag,
});

node.body.body.push(cretateGetTemplateClassMethod(returnExpression));
}
}
Expand Down
4 changes: 4 additions & 0 deletions packages/pwc-compiler/src/utils/is.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,7 @@ export function isMemberExpression(path: string): boolean {
}
return !currentOpenBracketCount && !currentOpenParensCount;
}

export function isBoolean(val: unknown): boolean {
return typeof val === 'boolean';
}
Loading