choojs / nanohtml Goto Github PK
View Code? Open in Web Editor NEW:dragon: HTML template strings for the Browser with support for Server Side Rendering in Node.
License: MIT License
:dragon: HTML template strings for the Browser with support for Server Side Rendering in Node.
License: MIT License
Hey folks, I'm crossing my fingers that I'm posting the issue at the right level of the stack here, but I believe I've stumbled upon some unexpected functionality that has me perplexed, and I've attempted to isolate it.
const choo = require('choo')
const html = require('choo/html')
const app = choo()
app.router([
['/', HomeView],
['/about', AboutView]
])
const tree = app.start()
document.body.appendChild(tree)
function HomeView (state, prev, send) {
return html`
<div class="home" onload=${onLoad} onunload=${onUnload}>
Home
<a href="/about">About</a>
</div>
`
function onLoad (el) {
console.log('HomeView loaded', el)
}
function onUnload (el) {
console.log('HomeView unloaded', el)
}
}
function AboutView (state, prev, send) {
return html`
<div class="about">
About
<a href="/">Home</a>
</div>
`
}
Open your console, then click "About," then click "Home." Hover over the elements it logs and you'll see that the final "HomeView loaded" log is passed an el that is not on the screen. In fact the onload handler is still dealing with the original el.
The real trouble, of course, is when you're trying to do something like initialise dragula when the view loads.
What's odd is that the onloadid
s appear to be correct... not sure what's going wrong. Any ideas?
Thank you for your work in bel and yo-yo π
Consider this SVG:
<svg width="140" height="140" viewbox="0 0 70 70">
<circle cx="35" cy="35" r="30" stroke-width="3" fill="red" />
</svg>
The circle
should scale up to fill SVGβs, according to its viewbox
, but when the element is created with bel
, circle
doesnβt scale.
Live example: http://requirebin.com/?gist=32979ca8d3231e3a86ac872260fa3322 β the second element is created manually and scales like it should. In DOM they look identical, must be some SVG behind-the-scenes magic?
Hey @maxogden! You mentioned breaking into separate libs. Would that look something like this?
bel
just creates elements and use morphdom
or diffhtml
to update:
var bel = require('bel')
var morphdom = require('morphdom')
function render (text) {
return bel`<div>${text}</div>`
}
var element = render('hello')
// ... later ...
morphdom(element, render('changed'))
@nrn also mentioned this too in #9. That would make bel
just return pure HTML elements. It doesn't necessarily encourage data down but one could still choose to follow that pattern with the above setup.
bel is a super neat idea!
Is there a way to export the function that is passed into hyperx so that it can be used with other libraries in the ecosystem that work with createElement functions?
So this may not be in the philosophy of bel, but how/should/can I easily create an extensible module for bel/yoyo (the module I use) that allows for custom tags/props that just render functions.
Here is what I'm thinking:
const Button = function (opts) {
return bel`<button>my ${opts.name} button</button>`
}
const Col = function (_yield, opts) {
return bel`<div class="column">${_yield}</div>`
}
const customtagsuse = bel`<div><Button name="Nick" /></div>`
// which is actually just
const customtagsuse = bel`<div>${Button({name: "Nick"})}</div>`
// or
const customtagsuse2 = bel`<div><Col> some cols </Col></div>`
// which is actually
const customtagsuse2 = bel`<div>${Col(" some cols ")}</div>`
Kinda reactish, but all it's doing is regexing the string, and replacing it with the element.
I'm thinking of providing a layer to bel.
so something like:
var extensible = require("bel-custom")
var bel = extensible(require("bel))
bel.customElements = {"Button": Button}; // sort of thing
Any thoughts on design patterns, approaches, potential pitfalls, potential benefits @shama?
As per our twitter convo we should probably investigate the possibilities of adding lifecycle hooks to yo-yo
/ bel
again β¨
Hi! Thanks for the module.
I have an example here: http://requirebin.com/?gist=f2a99cc27c465ed51eb8159830836ca4. In it, each time I call update
and bel
creates a new element, a local network request is made for the base64 inlined image, even though it did not change.
Should this be happening? I guess it makes sense, new element is created, bel
is fetching itβs content. But that results in a poor performance β when I add a relatively large image, like 3mb, the Chrome browser tab can barely function and the interface becomes unusable.
To reproduce: navigate to http://uppy.io/examples/modal/index.html, click βopen modalβ and drag two files to the dragdrop area. Open network tab, click βuploadβ.
What am I doing wrong? Thank you!
say I have a bunch of props to spread like in jsx, how can I achieve that? The following doesn't work
const props = `x=${x} y=${y}`
return bel`<div ${props} />`
In yo-yo
and choo
it's a best practice to have element functions in an
application return the same element given the same input. This mechanism is
commonly referred to as thunking
.
How would we feel about adding a light wrapper that exposes a thunk
function
so that elements can be thunked with little effort. I was thinking of an API
along these lines:
// elements/my-button.js
const thunk = require('bel/thunk')
const html = require('bel')
module.exports = thunk(createMyButton)
// create a cool button that has a different color
function createMyButton (color) {
return html`
<button style="background-color: ${color}">
Click me! :D
</button>
`
}
In a choo
app this could then be consumed as:
const html = require('choo/html')
const choo = require('choo')
const myButton = require('./elements/my-button')
const app = choo()
app.router([ '/', myView ])
app.model({
state: { color: 'blue' }
})
const tree = app.start()
document.body.appendChild(tree)
function myView (state, prev, send) {
return html`
<main>
${myButton(state.color)}
</main>
`
}
What do you think? Would this be a useful addition to bel
, or should we
continue to point people to use an external thing / write it themselves? I was
thinking of including this into choo
, but given that we strongly encourage
people to use bel
for standalone components (yay, reusability) I figured it
might make more sense to include it here first, and then have it propagate
upwards through yo-yo
to choo
. Thanks!
Once we can define the self closing tags in hyperx we can detect if the element is an svg and build one of those instead.
for (var p in ..) { ... p = somethingElse
What do you think of supporting &&
operator-based conditionals in interpolated expressions?
Current syntax:
html`<input type="checkbox" name="reviewed" ${data.reviewed ? 'checked' : ''} />`
Proposed syntax to support:
html`<input type="checkbox" name="reviewed" ${data.reviewed && 'checked'} />`
The proposed syntax is simply more succinct, and I believe it's popular in the react ecosystem. While the above example doesn't save much text, the : ''
gets in the way more when you have multi-line expressions -- it becomes a trailing piece that is often overlooked.
Currently, the proposed syntax works in bel if the first condition is truthy, but if it is falsy, bel renders its falsy value, and you'd end up with <input type="checkbox" name="reviewed" undefined />
. I believe the way around this would be for bel (or maybe hyperx?) to not return anything from an interpolated expression that evaluates to undefined
or false
. I believe this is how JSX does it.
If for some reason you want to render undefined
or false
, I think it would be reasonable to convert it to a string (since it's a string once it's in the DOM anyway). I think the exception to this would be the value 0
-- it may be unexpected to have to convert 0
to a string just to render it to the DOM. 0
comes in to play when you want to do ${rows.length && 'foo'}
vs. ${rows.length > 0 && 'foo'}
.
/cc @yoshuawuyts
The wiki says bel
does diffing, but it looks like it only creates elements and morphdom
is used to diff and update?
bel is a simple element creator. It returns pure DOM elements but still uses efficient DOM diffing to
update.
bel`<div>
<!-- this is a comment -->
</div>`
Throws an InvalidCharacterError
since you can't create an HTML comment via createElement
(but can through createComment
).
It would be awesome if bel either ignored comments or created them.
Happy to create a PR for either scenario
What is the global
dependency used for? Is it just used to get a reference to window.document
, or does it help this to work in the Node.js environment?
βββ¬ [email protected]
βββ¬ [email protected]
β βββ¬ [email protected]
β β βββ¬ [email protected]
β β β βββ [email protected]
β β βββ [email protected]
β βββ¬ [email protected]
β βββ [email protected]
βββ [email protected]
Would be nice if we could reduce this tree to:
βββ¬ [email protected]
βββ¬ [email protected]
β βββ¬ [email protected]
β βββ [email protected]
βββ [email protected]
<input disabled><br>
returns
<input><br></input>
but
<input disabled="true"><br>
returns
<input disabled=disabled><br>
Is this intentional? Un-assigned attributes like the first example are valid in HTML5 (I believe actually valid in everything except XHTML)
(ie the following is valid according to https://validator.w3.org
<!doctype html>
<title>test</title>
<form>
<input disabled>
</form>
)
I'm having problems with bel. I try to use bel to render some markdown content with the help of marked library. With this code
const html = require('yo-yo')
const marked = require('marked')
const post = require('./posts/post.md')
console.log(marked(post))
document.body.appendChild(html(marked(post)))
And this markdown content
# hello world
I'm using stringify to require the .md
file content. When I console log the marked(post)
call, I get
<h1 id="hello-world">hello world</h1>
That's pretty valid html to me, but bel complains with this error.
Uncaught DOMException: Failed to execute 'setAttribute' on 'Element': 'hello-world"' is not a valid attribute name.
at belCreateElement (http://playground-yerkopalma.c9users.io:8080/bundle.js:1447:14)
at http://playground-yerkopalma.c9users.io:8080/bundle.js:1807:12
at http://playground-yerkopalma.c9users.io:8080/bundle.js:1569:45
at Object.1../posts/post.md (http://playground-yerkopalma.c9users.io:8080/bundle.js:7:27)
at s (http://playground-yerkopalma.c9users.io:8080/bundle.js:1:254)
at e (http://playground-yerkopalma.c9users.io:8080/bundle.js:1:425)
at http://playground-yerkopalma.c9users.io:8080/bundle.js:1:443
And the problem is that when the belCreateElement function is called, it is called with wrong attributes
Now why is that happening? I thought about an hyperx error, but tried it with hyperscript and it render correctly. Not sure what could it be, also looked at the hyperscript-attribute-to-property library inside hyperx, but again why would it work with hyperscript, but not with bel?
Any help would be appreciated.
Unfortunately bel
doesn't work with hyperxify but I think we could write a transform that goes even further.
Where it converts:
var title = 'hello'
var element = bel`<div><h1>${title}</h1></div>`
into:
var title = 'hello'
var element = (function (p1) {
var e0 = document.createElement('div')
var e1 = document.createElement('h1')
var t0 = document.createTextNode(p1)
e1.appendChild(t0)
e0.appendChild(e1)
return e0
}(title))
Then we support older browsers and get a significant performance boost.
We could move the hyperx function into it's own library that outputs this stack. In here, it create elements. In the transform, it would create javascript strings.
Is it possible to inject raw a HTML string into a bel element? Right now I can't seem to get that working.
Example:
var bel = require('bel')
var html = '<div>hi</div>'
var body = bel`<div>${html}</div>`
document.body.appendChild(body)
try {
document.body.appendChild(bel`${html}`)
} catch (e) {
document.body.appendChild(bel`<div>${e.message}</div>`)
}
Output:
<div><div>hi</div></div>
<div>Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.</div>
http://requirebin.com/?gist=b7081814ea6465115d84
I'm trying to get this working for friends
(trying out a rewrite of the front-end using yo-yo
). Old method was to convert the html to a vdom element but that doesn't apply in this instance since ain't no vdom around. Here's the part that's causing the issue in friends if you're curious: https://github.com/moose-team/friends/blob/master/lib/elements/messages.js#L44-L58
Is there any solution of implying if..else
logic with templates?
As (as far as I know) we can't put if
statement directly in body of ${ }
, there is probably a need for dedicated if
function e.g. bel.if(condition, onTrue, onFalse)
.
Is something as that envisioned, or maybe already there's some solution (or convention) coined for that?
Unfortunately wiki is very silent on that very common use case.
Getting this error with SVG. I also had this issue with some self closing tags in HTML:
<!-- throws -->
<img src=""></img>
<!-- ok -->
<img src="">
See PR #24 for failing test.
If no one knows how to fix this, I will try tomorrow if I have time.
Hi! Need help with yo-yo/choo build setup. Iβve added yo-yoify to the βbrowserify bundledβ version of my build, but I also have a lib version, where each individual module is transpiled with Babel from ES6, like so: "build:lib": "babel src --source-maps -d lib"
. How would I add yo-yoify to that? Thanks.
Itβs needed, because otherwise this happens https://github.com/shama/bel#note.
Thank you.
I was wondering if its possible to use JSX instead of hyperx to create elements with Bel. I like to use Bel and Yo-yo, but sometimes its convenient to go JSX route, because then components could be re-used between Yo-yo/Choo and React projects.
I tried to set jsx pragma
to h
and then use it like so:
var h = require('bel').createElement
var el = <h1 class="a">Hi</h1>
document.body.appendChild(el)
But children (Hi
) never appear, and if you omit class
, bel complaints: Cannot read property 'namespace' of null
. Got confused, probably missing something.
For example, from an api I might receive some text:
{ story: '<p>Some story</p>' }
When I put that through bel (actually choo.view):
bel`<div>${story}</div>`
I get:
<div><p>Some story</p></div>
But the <p></p>
is just plain text, and not a dom element. I feel like others must have run across this and there's something obvious I'm missing.
I created a requirebin to demonstrate: http://requirebin.com/?gist=d3ac1f22ff3acbd63a1113ddcf560583
Would adding .outerHTML
as a setter to update the element be a good idea? Might make it feel more native.
Running into an error with onload
and onunload
events in Safari. Can verify when removing the load attributes from the element the error is suppressed.
TypeError: Function.caller used to retrieve strict caller
Here is a temp URL:
http://ec2-54-201-45-223.us-west-2.compute.amazonaws.com
Hi I'm sorry this issue might not be a bug of bel but I got a issue while trying to host a static page to gh-pages.
I'm pushing the bundled code to gh-pages branch with a npm module called gh-pages. The code looks fine on the gh-pages branch of the repo, but while visiting the gh-page url, I got the following error from Chrome devtools
I did a few debug and find this line on gh-pages branch is https://github.com/fraserxu/videos/blob/gh-pages/bundle.js#L44
var SVGNS = 'http://www.w3.org/2000/svg'
var BOOL_PROPS = {
autofocus: 1,
checked: 1,
defaultchecked: 1,
disabled: 1,
formnovalidate: 1,
indeterminate: 1,
readonly: 1,
required: 1,
willvalidate: 1
}
but when opening the page and checking from Chrome debug tools the script becomes to
var SVGNS = 'http:var BOOL_PROPS={autofocus:1,checked:1,defaultchecked:1,disabled:1,formnovalidate:1,indeterminate:1,readonly:1,required:1,willvalidate:1}
I have no idea why is breaking on gh-pages, the code works perfectly fine on my local though.
I also tried to push the same code to a tool called surge.sh but the code is the same as on gh-pages.
Sorry again that this is not really a bug with bel but you may have any idea with this problem?
Can you include leaf nodes inside bel components that don't get blown away on re-renders?
const dataVizBiz = (state, prev, send) => {
function load(el) {
d3.select(el)
.selectAll('div')
.data([4, 8, 15, 16, 23, 42])
.enter()
.append('div')
.style('height', (d)=> d + 'px')
}
return html`
<div onload=${load}></div>
`
}
Similar to React's shouldComponentUpdate=${() => false}
it would nice to have a way to be able to add an element on first render, but allow it to persist on re-renders without being touched. Would be great if we can pass data in onupdate
to modify the DOM too.
<div onload=${load} onupdate=${update} leaf></div>
Here's the complete example I'm trying to get working with Choo.
https://github.com/markbrown4/choo-demo/blob/master/7-friends.js
I'm trying to include raw html, including <
:
If do <
it gets double-escaped:
> bel`<div><</div>`.toString()
'<div>&lt;</div>'
But if I just put a raw <
in bel gets super confused:
> bel`<div><</div>`.toString()
'<div></div</div>'
This seems to work for my use case:
> bel`<div>${'<raw>'}</div>`.toString()
'<div><raw></div>'
.. But I only figured that out by guessing. What are the rules around escaping / unescaped literal HTML strings?
Perhaps it would be cool to include a proper .toString()
method - I've found it quite useful when debugging in other packages. Right now it has the following behavior:
const bel = require('bel')
const tree = bel`<div>hello world</div>`
console.log(tree.toString())
// => <div></div>
Thanks!
Similar to shama/base-element#5
Hi,
I'm getting the following error when trying to add an onload handler to a nested element.
TypeError: access to strict mode caller function is censored
Is this expected behavior? The line triggering this error seems to be https://github.com/shama/bel/blob/master/index.js#L68
Tested on Ubuntu / Firefox 48.0
Seems to work fine on Ubuntu / Google Chrome 52.0.2743.116 (64-bit)
Below is a minimal example reproducing the error.
import bel from 'bel'
const renderObj = ({name, x, y}) => {
return bel `<g transform="translate(${x}, ${y})" class="task" onload=${e => console.log(e) }>
<rect width=100 height=100 />
<text>${name}</text>
</g>`
}
const objs = [
{name:'foo', x:100, y:100}
];
const svg = bel`<svg onclick=${onclick}>
${objs.map(t => renderObj(t))}
</svg>`
document.appendChild(svg);
Kind regards,
Melle
Demo: http://requirebin.com/?gist=508e362b4e6a64f7d2ed69697f24e915
Without quotes, it doesn't render the label. With quotes, it renders it as expected, but the callback doesn't appear to work. Any idea why?
import bel from 'bel';
export default class MyApp extends HTMLElement {
createdCallback() {
let greeting = this.getAttribute('greeting');
let html = bel`
<div>
<div id="quotes">
<div class="header" onload=${() => console.log('test')}>
${greeting ? greeting : 'Hello!'}
<content select="my-name"></content>
</div>
<div class="body">
<content select="my-profile"></content>
</div>
</div>
</div>
`;
this.createShadowRoot().appendChild(html);
}
}
Which I use:
<my-app greeting='Hi'>
<my-name>Hello</my-name>
<my-profile>
This is my profile
</my-profile>
</my-app>
The DOM renders fine, but on load there is nothing in the console.
I find myself doing this pattern quite often so knowing when an element has been inserted into the DOM would be useful:
var div = bel`<div>testing</div>`
// ... later ...
div.update(bel`<div>changed</div>`, function (element) {
// element is div and in the dom
})
When working with a more strict layout, whitespace between elements can cause trouble. For example, if I have a couple of spans that need to be flush against each other, there can't be any whitespace between the span tags in the generated HTML. Unfortunately, bel (or hyperx?) preserves the whitespace from the input.
bel`
<p>
<span>one</span>
<span>two</span>
</p>
`.toString()
generates:
<p>\n <span>one</span>\n <span>two</span>\n </p>
To work around this issue, I'd have to
bel`
<p>
<span>one</span><span>two</span>
</p>
`.toString()
Which isn't ideal, especially when multiple tags are involved or if they have attributes.
I like the way React deals with this issue: https://facebook.github.io/react/blog/2014/02/20/react-v0.9.html#jsx-whitespace
Hey! Using yo-yo
in a project with ES6 classes: we have Core and Plugins, and each plugin is inheriting from a Plugin class, which serves a boilerplate. Using super
and extend
keywords, which is relevant, because the issue goes away without those. Everything gets transpiled down to ES5 with Babel.
Sometimes yo-yo
wonβt render an element that was created in a constructor
with this
, like so:
import yo from 'yo-yo'
export class Smth extends Plugin {
constructor (core, opts) {
super(core, opts)
this.strange = yo`<h1>this is strange 1</h1>`
}
render (state) {
const bla = yo`<h2>this is strange 2</h2>`
return yo`
<div class="wow-this-works">
<input type="text" value="hello">
${this.strange}
${bla}
</div>
`
}
install () {
this.getTarget(this.opts.target, this, this.render)
}
}
<h1>this is strange 1</h1>
gets rendered while <h2>this is strange 2</h2>
does not. If you move this.strange
from the constructor to render function, it works. If you console.log
the elements, they always show up in the console. Also, it works if you wrap yo
call in a function, like this.strange = function () { return yo'<h1>this is strange 1</h1>' }
And I would think itβs totally this
and class
issues, except β wait for it β when you replace h2
with h1
, it works. Different elements wonβt render, but if two of the same are used β it works.
Here is a diff of two transpiled examples: https://www.diffchecker.com/ngpc5whl (the one on the left works, the one on the right does not), and are screenshots:
I thought maybe someone who wrote bel
and knows internals will understand whatβs going on here. Where should we even look? Sorry for complicated explanation and thanks in advance.
An idea for handling CSS:
var bel = require('bel')
var css = {
position: 'absolute',
top: 100,
left: 200
}
var element = bel`<div style=${css}>Hello!</div>`
Which would detect the style
key and use dom-css to set the .style[prop]
directly on the elements (CSP safe). It will even do vendor prefixing.
Is it reasonable to expect the same kind of support for style objects as in hyperx
? I'd like to be able to do the following but this seems to only work with hyperx
& virtual-dom/h
at the moment.
var bel = require('bel')
var style = { color: 'red' }
var el = bel`<div style=${style}>`
console.log(el)
// <div style="[object Object]"></div>
see also choojs/hyperx#3
Currently the same logic exists across yo-yoify
and bel
. It would be nice if it could be more shared and driven by this library.
It also means an element created with a specific version of bel
may not be compatible with a specific version of yo-yoify
. So yo-yoify
should really require('bel/appendChild')
and require('bel/attrs')
from the local element it is transforming to ensure compatibility.
I just want to document a little user story wrt the onload
event. I'm new to choo / bel, and wanted to fade in some images after loading. So I added a load
event handler to an image, like this:
html`<img onload=${imgLoaded} src=${small} srcset=${sources}></img>`
And then in the handler, at first I was expecting a 'normal' onload
event:
const imgLoaded = e => e.target.style.opacity = 1
And when I found that e.target
was undefined
, I logged out e
and discovered that it was actually the image object. "Oh... unwrapped for convenience? OK cool, let's continue..."
const imgLoaded = img => img.style.opacity = 1
And of course, that didn't start the fadein after image load, but immediately. I flailed for awhile. I had no idea what was going on. I searched, I played around, and I spent an embarrassing about of time trying to figure it out, and ended up writing this:
const imgLoaded = img => {
const wait = () => {
if (img.complete)
img.style.opacity = 1
else
requestAnimationFrame(wait)
}
requestAnimationFrame(wait)
}
Which gave me the desired behavior, but at unnecessary cost. I was glad it was 'working', and all... but called it a day with this horrible nagging feeling. And then... in the middle of the night, I woke up and realized what was actually going on. (Thanks, subconscious!) So I wrote this:
const imgLoaded = img =>
console.log(img.onload) // DOH!
And finally, this:
const imgLoaded = img =>
img.onload = () => // like, for reals
img.style.opacity = 1
Yay. Let's document this, okay?
Thanks π
It would be neat if an end user could switch out the renderer of an element when needed. Such as:
var bel = require('bel')
var div = bel`<div>testing</div>`
Renders a native DOM element but if the user is using React or virtual-dom, they could do:
var vdom = require('virtual-dom')
var bel = require('bel')({
renderer: vdom.h
})
var div = bel`<div>testing</div>`
Now the div is a VirtualNode
. The only problem is ensuring .update()
works cleanly with those renderers.
Also maybe this should just be left up to the user:
var div = bel`<div>testing</div>`
var vnode = convertToVNode(div)
Even crazier idea, what if there was a global setting. So window.BEL_RENDERER = vdom.h
and then any library using bel
would render to virtual nodes instead?
Any thoughts on trasitioning update to being a function that takes the old element as it's first argument, instead of adding a property to the element? It feels like it would fit better with my expectations approaching the interface. And it seems like you could then update elements not created by bel, which would be nice.
First I thought it was a bug in hyperx
, but virtual-dom
actually throw
, so that leads me to bel
being the issue.
The following code renders incorrectly (as I said, virtual-dom
throws an error):
bel`<div><p>Hello World<p></div>`.toString() // => '<div>pHello World<p></p></div>'
Notice the p
prepended to Hello World
.
I'll leave this here until I need to fix it, unless someone gets to it before me π
Consider this example:
function textarea (value) {
return yo`<textarea>${value}</textarea>`
}
var el = textarea('foo')
yo.update(el, textarea('bar'))
foo will still be displayed in the textarea. This is because morphdom
compares el.value
of textarea nodes and bel
sets it by appendChild(document.createTextNode())
. The browser takes a little bit to compute the textContent
into a value
, so if you update immediately after, morphdom
doesn't get the new el.value
.
I'm not sure what the problem is, but if I have an input field inside a label as recommended by mdn:
bel(`<div>
<label> <input type="checkbox" checked> text </label>
<a>outside</a>
</div>`).toString();
// ->
<div>
<label> <input type="text" type="type" checkbox"="checkbox"" />
<a>outside</a>
</label>
</div>
... The following elements somehow teleport inside the label.
[Edited: Added
checked
to the input tag, which is required to reproduce the bug.]
When a parent renders, the context to a child element is lost. So when that child element needs to .update()
, it must re-find itself in the DOM. This is why we currently require an id
attribute.
It shouldn't be necessary though. There might be a way with morphdom
or diffhtml
to know when a child we previously created has been changed then reconnect that element on .update()
. Or use another method to discover when a child has lost it's way that doesn't involve attributes and DOM lookups.
At the very least, we can detect whether or not a child requires a lookup if (element.parentNode == null)
before falling to the current system.
Error with xmlns attribute.
<svg width="150" height="100" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 3 2">
<rect width="1" height="2" x="0" fill="#008d46" />
</svg>
see #22
Using innerHTML to insert the odd HTML entity such as
as described in the wiki is OK. But when HTML entities are used all over the place, this quickly becomes unwieldy. I wish there was some way to keep using the entities inline.
Is there another reason to escape all text other than prevention of XSS from user entered text? If there isn't, I think the default of escaping everything is wrong and should be changed (if possible).
When writing plain old HTML, people are used their <tags>
being interpreted accordingly, just like their &entities;
, and the rest used as is (i.e. unescaped). I wish bel could mirror that experience.
Hi,
I'm trying to use inline styles using bel and also trying the new server-side rendering capability.
When I compile this template
bel`<h1 style="color: red">Hey ${name.toUpperCase()}, <span style="color: blue">This</span> is a card!!!</h1>`
It returns the following string
<h1 style="0:c;1:o;2:l;3:o;4:r;5::;6: ;7:r;8:e;9:d;">Hey JOHN,
<span style="0:c;1:o;2:l;3:o;4:r;5::;6: ;7:b;8:l;9:u;10:e;">This</span> is a card!!!</h1>
Also if you know how can I use react-like inline styles using objects instead of just strings it will be awesome.
Thanks for this tool!
Hi there,
This is more of a question than a bug, and affects bel and on-load together.
I'm writing a tiny framework where:
yo/bel
on-load
call on the generated viewThe problem I'm having is that the framework's on-load
call will override any prior onload/onunload attributes set within the yo/bel
view:
//View supplied to framework
view = yo`<div onload=${c('view load')} onunload=${c('view unload')}>page1</div>`;
//Frameword sets up view load/unload hooks
onLoad(view, c('framework load'), c('framework unload'));
function c (value) {
return function() {
console.log(value);
}
}
document.body.appendChild(view)
//Output is 'framework load', not 'view load'
Any advice on how to handle this? Ideally, I'd like all onload/onunload functions (supplied by both view and framework) to fire, order irrelevant.
I dug through the bel
and on-load
code and discovered:
bel
: when creating the view in DOM form, bel
makes the appropriate on-load
calls for any onload/onunload attributes specified. But there isn't any easy way to get access to the onload/onunload functions that were added (e.g. to wrap/call them from the framework)on-load
: I believe only one onload/onunload function-pair can be associated with a DOM element. I wondered if I could associate multiple pairs by running multiple instances of on-load
, each with their own data-onloadid
attribute. However this is not possible, as require('on-load')
would point to the same library.This hasn't been an issue for the choo framework so far, as I believe a choo view is expected to handle onload/onunload behaviour, and not the choo framework (so not both).
Any advice appreciated :-)
Greg
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.