From c2a356128d3625282ac732ae7f5a0cf04d4f3c96 Mon Sep 17 00:00:00 2001 From: Yukino Song Date: Wed, 14 Oct 2020 01:53:01 +0800 Subject: [PATCH 1/3] Update build script --- config/rollup.dev.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/config/rollup.dev.js b/config/rollup.dev.js index 2acfd89..e84bf64 100644 --- a/config/rollup.dev.js +++ b/config/rollup.dev.js @@ -8,8 +8,7 @@ import browsersync from 'rollup-plugin-browsersync' base.output.file = `${base.devPath}/${base.bundle}.dev.js` base.plugins.push(browsersync(bsConfig)) base.watch = { - chokidar: true, - include: 'src/' + include: ['src/**/*.*'] } delete base.bundle From 16af00b04ae6b1a367f2a0f512eeac33e917ff83 Mon Sep 17 00:00:00 2001 From: Yukino Song Date: Wed, 14 Oct 2020 01:53:59 +0800 Subject: [PATCH 2/3] Upgrade depencies --- package-lock.json | 22 +++++++++++----------- package.json | 6 +++--- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 503fffb..964abfb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "ef.js", - "version": "0.12.0", + "version": "0.12.2", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -758,9 +758,9 @@ "dev": true }, "chokidar": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", - "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", + "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", "dev": true, "requires": { "anymatch": "~3.1.1", @@ -770,7 +770,7 @@ "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.4.0" + "readdirp": "~3.5.0" } }, "cli-cursor": { @@ -1030,9 +1030,9 @@ "dev": true }, "ef-core": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/ef-core/-/ef-core-0.12.0.tgz", - "integrity": "sha512-vbHCOBwNr5/Ef19YpGmSrIq+692b+Sy802RxDnRt7pc52y44pH6STOSMXWeiceUabYSJD5PgtItN83PNOdTCbQ==" + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/ef-core/-/ef-core-0.12.2.tgz", + "integrity": "sha512-iUjYGUxKNuWjrqNkcS9F6TcaxkovM/DUOYkZrTH2nJsfTNE+wOzIbd/BZCZc+wniuUajBiBwFvIlZqe9JnsaWw==" }, "eft-parser": { "version": "0.10.6", @@ -2434,9 +2434,9 @@ } }, "readdirp": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", - "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", "dev": true, "requires": { "picomatch": "^2.2.1" diff --git a/package.json b/package.json index 826376e..bacaed2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ef.js", - "version": "0.12.0", + "version": "0.12.2", "description": "(maybe) An elegant HTML template engine & basic framework", "main": "dist/ef.min.js", "module": "src/ef.js", @@ -35,7 +35,7 @@ "@rollup/plugin-node-resolve": "^9.0.0", "@rollup/plugin-replace": "^2.3.3", "chalk": "^4.1.0", - "chokidar": "^3.4.2", + "chokidar": "^3.4.3", "cross-env": "^7.0.2", "eslint": "^7.11.0", "jsdoc": "^3.6.6", @@ -46,7 +46,7 @@ "rollup-plugin-terser": "^7.0.2" }, "dependencies": { - "ef-core": "^0.12.0", + "ef-core": "^0.12.2", "eft-parser": "^0.10.6" } } From eed939dc9262505836c1b4c803776e502258681f Mon Sep 17 00:00:00 2001 From: Yukino Song Date: Wed, 14 Oct 2020 01:54:18 +0800 Subject: [PATCH 3/3] Update document --- README.md | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 115 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7a733d4..47def3c 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ ef.js is a static template framework for browsers, with which you can write your ef.js also provides a simple template-engine which helps you create component modules with data binding at ease, but you can also use your favourite template-engine which is compatible with ef.js's AST. +ef.js is well compatible with [WebComponents](https://www.webcomponents.org/), and is probably the only existing front-end framework that handles XML namespaces properly. + [Official Website (WIP)](https://ef.js.org) Demo: @@ -15,6 +17,9 @@ Demo: + [dbmon](https://classicoldsong.github.io/js-repaint-perfs/ef/opt.html) - [repo](https://github.com/ClassicOldSong/js-repaint-perfs) + The [official website](https://github.com/ClassicOldSong/ef.js.org) is also written with ef.js +Playground: ++ [CodeSandbox](https://codesandbox.io/s/github/TheNeuronProject/ef-starter-template) + Related projects: + [ef-core](https://github.com/TheNeuronProject/ef-core) - Core of ef.js (without parser) + [Neonclear](https://neon.atm.re) - An ef.js based progressive UI framework (WIP) @@ -251,6 +256,19 @@ app.$refs.root // DOM object app.$refs.myComponent // ef component ``` +Scoping can also be used to replace some tags. Like: +```js +const scope = { + MyComponent: 'div', + MyOtherComponent: { + tag: 'div', + is: 'my-web-component' + } +} +``` + +`MyComponent` will be rendered as a normal `div` element, while `MyOtherComonent` will be rendered as a `my-web-component`. + ### Attributes Attributes on custom components are mapped to `component[key]`, single way: @@ -351,6 +369,102 @@ MyComponent.eft +children ``` +## XML Namespaces + +ef.js now handles custom XML namespaces since v0.12.0, which allows ef.js to be able to handle svg fragments easily. + +### Namespace Usage + +Just like what you do in XML: +```efml +Render this `div` tag under a given namespaceURI +>div + #xmlns = http://some.namespace.example.com/myns +``` +```efml +Render these tags with given namespaceURI by local prefix +>myns:div + #xmlns:myns = http://some.namespace.example.com/myns + >myns:h1 + >myns:table +``` +```efml +Render only parts of an SVG element +>svg:path +``` +```efml +Render only parts of an MathML element +>math:matcion +``` + +You must declare your namespace prefix before using your prefix either [globally](#global-namespaces) or [locally](#local-namespaces). + + +### Global Namespaces + +ef.js has 4 [built-in global namespaces](https://github.com/TheNeuronProject/ef-core/blob/master/src/lib/utils/namespaces.js#L2-L5), which are `html` for HTML elements, `svg` for SVG elements, `math` for MathML elements and `xlink` for `xlink` attributes. You can register custom global namespaces using `declareNamespace`: +```js +import {declareNamespace} from 'ef.js' + +declareNamespace('myns', 'http://some.namespace.example.com/myns') +``` + +Then you can use it everywhere across the whole project. + +**Note:** +1. Using global namespaces with prefix will make it's children also inherit it's namespace. +1. Re-declareation the same prefix will throw out an error. + +### Local Namespaces + +ef.js supports a XML-like local namespace declaration: +```efml +>myns:div + #xmlns:myns = http://some.namespace.example.com/myns +``` + +Then you can use the namespace across the whole template. + +**Note:** +1. What efml namespaces differs from actual XML local namespaces is that in XML it works only for itself or it's children, while in efml this declaration works across the whole template no matter where you define it. +1. Local defined namespaces only works when a tag is prefixed with the defined prefix. Children of it will not inherit the namespace. +1. Re-declaration will NOT give en error. + +### Namespacing in Scopes + +When an tag is scoped, it will use the scoped tag's namespace, if the tag has no prefix, it will use the original `xmlns` instead if only `namespaceURI` is not set on scope option. Scoped prefix has higher priority than `namespaceURI`. For example: +```efml +template.eft +>div + .This tag will be scoped. +``` +```js +import Tpl from './template.eft' + +const scope1 = { + div: 'myns:div' +} + +const component1 = new Tpl(null, scope1) // in this case it will render a `div` under `myns` + +const scope2 = { + div: { + tag: 'myns:div', + namespaceURI: 'http://some.other.ns/myns' + } +} + +const component2 = new Tpl(null, scope2) // in this case the `namespaceURI` is completely ignored, element is rendered under `myns` + +const scope3 = { + div: { + namespaceURI: 'http://some.other.ns/myns' + } +} + +const component3 = new Tpl(null, scope3) // in this case the `namespaceURI` is not ignored, element is rendered under `http://some.other.ns/myns` +``` + ## JSX ef.js now comes with JSX support since v0.9.0. Demo [here](https://codepan.net/gist/192a1870d23e05d775d3667389162e63). @@ -365,7 +479,7 @@ ef.js supports JSX fragments. You can create fragments just like what you do in ``` -Note that JSX fragments are not always the same from ef fragments. No ef bindings can be set on JSX fragments in the meantime. +**Note:** JSX fragments are not always the same from ef fragments. No ef bindings can be set on JSX fragments in the meantime. ### With Transpilers