-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* bump next version * fix format * deprecate executables for dynamic value - deprecate executables for dynamic values - improve logic of handling template - fixe bugs related to state order update * optimize and simplify
- Loading branch information
1 parent
7c08de7
commit 4e18b87
Showing
51 changed files
with
2,229 additions
and
1,509 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import esbuild, { Plugin } from 'esbuild' | ||
|
||
const emptyParserDoc = { | ||
name: 'empty-parser-Doc-plugin', | ||
setup(build) { | ||
build.onResolve({ filter: /Doc$/ }, (args) => { | ||
if (args.importer.includes('@beforesemicolon/html-parser')) { | ||
return { | ||
path: args.path, | ||
namespace: 'empty-Doc', | ||
} | ||
} | ||
}) | ||
build.onLoad({ filter: /.*/, namespace: 'empty-Doc' }, () => { | ||
return { | ||
contents: '', | ||
} | ||
}) | ||
}, | ||
} as Plugin | ||
|
||
await esbuild.build({ | ||
entryPoints: ['src/client.ts'], | ||
outfile: 'dist/client.js', | ||
bundle: true, | ||
keepNames: true, | ||
sourcemap: true, | ||
target: 'esnext', | ||
minify: true, | ||
plugins: [emptyParserDoc], | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,242 @@ | ||
import { DocumentLike, parse } from "@beforesemicolon/html-parser"; | ||
import { Doc } from "./Doc"; | ||
|
||
describe("Doc", () => { | ||
const dynamicValueCollector = jest.fn(); | ||
let refs: Record<string, Set<Element>> = {}; | ||
|
||
beforeEach(() => { | ||
jest.clearAllMocks(); | ||
refs = {}; | ||
}); | ||
|
||
it("should parse plain html", () => { | ||
const res = parse( | ||
"<p>simple</p>", | ||
Doc([], refs, dynamicValueCollector) as unknown as DocumentLike | ||
); | ||
|
||
expect(res.childNodes.length).toBe(1); | ||
expect(res.childNodes[0]).toBeInstanceOf(HTMLParagraphElement); | ||
expect((res.childNodes[0] as HTMLParagraphElement).outerHTML).toBe("<p>simple</p>"); | ||
expect(dynamicValueCollector).not.toHaveBeenCalled(); | ||
}); | ||
|
||
it("should parse comment", () => { | ||
const res = parse( | ||
"<!-- <p>simple</p> -->", | ||
Doc([], refs, dynamicValueCollector) as unknown as DocumentLike | ||
); | ||
|
||
expect(res.childNodes.length).toBe(1); | ||
expect(res.childNodes[0]).toBeInstanceOf(Comment); | ||
expect((res.childNodes[0] as Comment).nodeValue).toBe(" <p>simple</p> "); | ||
expect(dynamicValueCollector).not.toHaveBeenCalled(); | ||
}); | ||
|
||
it("should parse plain html with static injected value", () => { | ||
const res = parse( | ||
"<p>$val0</p>", | ||
Doc(["simple"], refs, dynamicValueCollector) as unknown as DocumentLike | ||
); | ||
|
||
expect(res.childNodes.length).toBe(1); | ||
expect(res.childNodes[0]).toBeInstanceOf(HTMLParagraphElement); | ||
expect((res.childNodes[0] as HTMLParagraphElement).outerHTML).toBe("<p>simple</p>"); | ||
expect(dynamicValueCollector).not.toHaveBeenCalled(); | ||
}); | ||
|
||
it("should parse plain html with dynamic injected value", () => { | ||
const fn = () => "simple"; | ||
const res = parse( | ||
"<p>$val0</p>", | ||
Doc([fn], refs, dynamicValueCollector) as unknown as DocumentLike | ||
); | ||
|
||
expect(res.childNodes.length).toBe(1); | ||
expect(res.childNodes[0]).toBeInstanceOf(HTMLParagraphElement); | ||
expect((res.childNodes[0] as HTMLParagraphElement).outerHTML).toBe("<p>$val0</p>"); | ||
expect(dynamicValueCollector).toHaveBeenCalledWith({ | ||
data: null, | ||
name: "nodeValue", | ||
value: fn, | ||
rawValue: "$val0", | ||
prop: null, | ||
}); | ||
}); | ||
|
||
it("should parse event attribute", () => { | ||
const handler = () => { | ||
}; | ||
const res = parse( | ||
"<button type=\"button\" onclick=\"$val0\">click me</button>", | ||
Doc([handler], {}, dynamicValueCollector) as unknown as DocumentLike | ||
); | ||
|
||
expect(res.childNodes.length).toBe(1); | ||
expect(res.childNodes[0]).toBeInstanceOf(HTMLButtonElement); | ||
expect((res.childNodes[0] as HTMLButtonElement).outerHTML).toBe("<button type=\"button\">click me</button>"); | ||
expect(dynamicValueCollector).toHaveBeenCalledTimes(1); | ||
expect(dynamicValueCollector).toHaveBeenCalledWith({ | ||
"data": null, | ||
"name": "onclick", | ||
"prop": "click", | ||
"rawValue": "$val0", | ||
"value": [handler] | ||
}); | ||
}); | ||
|
||
it("should parse event attribute with option", () => { | ||
const handler = () => { | ||
}; | ||
const res = parse( | ||
'<button type="button" onclick="$val0, $val1">click me</button>', | ||
Doc([handler, {once: true}], {}, dynamicValueCollector) as unknown as DocumentLike | ||
); | ||
|
||
expect(res.childNodes.length).toBe(1); | ||
expect(res.childNodes[0]).toBeInstanceOf(HTMLButtonElement); | ||
expect((res.childNodes[0] as HTMLButtonElement).outerHTML).toBe("<button type=\"button\">click me</button>"); | ||
expect(dynamicValueCollector).toHaveBeenCalledTimes(1); | ||
expect(dynamicValueCollector).toHaveBeenCalledWith({ | ||
"data": null, | ||
"name": "onclick", | ||
"prop": "click", | ||
"rawValue": "$val0, $val1", | ||
"value": [handler, ", ", {once: true}] | ||
}); | ||
}); | ||
|
||
it("should parse and ignore unknown event attribute", () => { | ||
const handler = () => { | ||
}; | ||
const res = parse( | ||
"<button type=\"button\" onval=\"$val0\">click me</button>", | ||
Doc([handler], {}, dynamicValueCollector) as unknown as DocumentLike | ||
); | ||
|
||
expect(res.childNodes.length).toBe(1); | ||
expect(res.childNodes[0]).toBeInstanceOf(HTMLButtonElement); | ||
expect((res.childNodes[0] as HTMLButtonElement).outerHTML).toBe("<button type=\"button\">click me</button>"); | ||
expect(dynamicValueCollector).toHaveBeenCalledTimes(1); | ||
expect(dynamicValueCollector).toHaveBeenCalledWith({ | ||
"data": null, | ||
"name": "onval", | ||
"prop": null, | ||
"rawValue": "$val0", | ||
"value": [handler] | ||
}); | ||
}); | ||
|
||
it("should parse event attribute for webComponent", () => { | ||
class MyButton extends HTMLElement { | ||
} | ||
|
||
customElements.define("my-button", MyButton); | ||
|
||
const handler = () => { | ||
}; | ||
const res = parse( | ||
"<my-button type=\"button\" onval=\"$val0\">click me</my-button>", | ||
Doc([handler], {}, dynamicValueCollector) as unknown as DocumentLike | ||
); | ||
|
||
expect(res.childNodes.length).toBe(1); | ||
expect(res.childNodes[0]).toBeInstanceOf(MyButton); | ||
expect((res.childNodes[0] as MyButton).outerHTML).toBe("<my-button type=\"button\">click me</my-button>"); | ||
expect(dynamicValueCollector).toHaveBeenCalledTimes(1); | ||
expect(dynamicValueCollector).toHaveBeenCalledWith({ | ||
"data": null, | ||
"name": "onval", | ||
"prop": "val", | ||
"rawValue": "$val0", | ||
"value": [handler] | ||
}); | ||
}); | ||
|
||
it("should parse ref attribute", () => { | ||
const res = parse( | ||
"<button type=\"button\" ref=\"btn\">click me</button>", | ||
Doc([], refs, dynamicValueCollector) as unknown as DocumentLike | ||
); | ||
|
||
expect(res.childNodes.length).toBe(1); | ||
expect(res.childNodes[0]).toBeInstanceOf(HTMLButtonElement); | ||
expect((res.childNodes[0] as HTMLButtonElement).outerHTML).toBe("<button type=\"button\">click me</button>"); | ||
expect(dynamicValueCollector).not.toHaveBeenCalled(); | ||
expect(refs["btn"].size).toBe(1); | ||
expect(refs["btn"].has(res.childNodes[0] as HTMLButtonElement)).toBeTruthy(); | ||
}); | ||
|
||
it("should handle boolean, class, style and data attributes", () => { | ||
const active = () => true; | ||
const loading = () => false; | ||
const disabled = () => true; | ||
const sample = () => false; | ||
|
||
|
||
const res = parse( | ||
"<button type=\"button\" class=\"btn\" class.active=\"$val0\" style.loading=\"color: blue; | $val1\" disabled=\"$val2\" data.sample=\"$val3\">click me</button>", | ||
Doc([active, loading, disabled, sample], refs, dynamicValueCollector) as unknown as DocumentLike | ||
); | ||
|
||
expect(res.childNodes.length).toBe(1); | ||
expect(res.childNodes[0]).toBeInstanceOf(HTMLButtonElement); | ||
expect((res.childNodes[0] as HTMLButtonElement).outerHTML).toBe('<button type="button" class="btn">click me</button>'); | ||
expect(dynamicValueCollector).toHaveBeenCalledTimes(4); | ||
|
||
|
||
expect(dynamicValueCollector.mock.calls[0][0]).toEqual({ | ||
"data": null, | ||
"name": "class", | ||
"prop": "active", | ||
"rawValue": "$val0", | ||
"value": [active] | ||
}); | ||
expect(dynamicValueCollector.mock.calls[1][0]).toEqual({ | ||
"data": null, | ||
"name": "style", | ||
"prop": "loading", | ||
"rawValue": "color: blue; | $val1", | ||
"value": ["color: blue; | ", loading] | ||
}); | ||
expect(dynamicValueCollector.mock.calls[2][0]).toEqual({ | ||
"data": null, | ||
"name": "disabled", | ||
"prop": "", | ||
"rawValue": "$val2", | ||
"value": [disabled] | ||
}); | ||
expect(dynamicValueCollector.mock.calls[3][0]).toEqual({ | ||
"data": null, | ||
"name": "data", | ||
"prop": "sample", | ||
"rawValue": "$val3", | ||
"value": [sample] | ||
}); | ||
}); | ||
|
||
it("should parse and ignore boolean attributes with false value", () => { | ||
const res = parse( | ||
"<button type=\"button\" disabled=\"false\">click me</button>", | ||
Doc([], refs, dynamicValueCollector) as unknown as DocumentLike | ||
); | ||
|
||
expect(res.childNodes.length).toBe(1); | ||
expect(res.childNodes[0]).toBeInstanceOf(HTMLButtonElement); | ||
expect((res.childNodes[0] as HTMLButtonElement).outerHTML).toBe("<button type=\"button\">click me</button>"); | ||
expect(dynamicValueCollector).not.toHaveBeenCalled(); | ||
}); | ||
|
||
it("should parse and ignore injected value names", () => { | ||
const res = parse( | ||
'<button type="button" $val0="true">click me</button>', | ||
Doc(['disabled'], refs, dynamicValueCollector) as unknown as DocumentLike | ||
); | ||
|
||
expect(res.childNodes.length).toBe(1); | ||
expect(res.childNodes[0]).toBeInstanceOf(HTMLButtonElement); | ||
expect((res.childNodes[0] as HTMLButtonElement).outerHTML).toBe("<button type=\"button\">click me</button>"); | ||
expect(dynamicValueCollector).not.toHaveBeenCalled(); | ||
}); | ||
}); |
Oops, something went wrong.