jsmile-browser
v0.0.4
Published
A JavaScript Markup Language implementation with browser integration.
Downloads
3
Readme
JSMiLe-browser J:)
J:)
A JavaScript Markup Language implementation with browser integration.
Installation
Node
npm install jsmile-browser
Browser
A fully bundled and transformed implementation, ready for use in browsers including any version of Internet Explorer or Opera Mini, is provided in the dist/jsmile.js
file.
Including this script will expose the entire package as a global object named jsml
.
<script src="./node_modules/jsmile-browser/dist/jsmile-browser.js"></script>
For generating valid HTML windows and documents when working outside of the browser, check out tools like jsdom
.
Usage
Initialization
jsmile can fully render JavaScript DOM elements, including embedded datasets and event listeners.
Pass a window
object with an associated document
to the library.
It will return a function that takes the same input as jsml-davidystephenosn
), but returns fully rendered DOM elements.
const jsmileBrowser = require('jsmile-Browser')
const render = jsmileBrowser(window)
const div = render({})
console.log(div.tagName)
// DIV
In the browser, or anywhere else where a DOM window with a valid document is globally available, a renderer
instance will be created with it and attached as jsml
.
<script src="./node_modules/jsmile-browser/dist/jsmile-browser.js"></script>
<script>
const span = jml.render({ tag: 'span', child: 'hello world' })
console.log(span.outerHTML)
// '<span>hello world</span>'
const div = jsml({})
console.log(div.outerHTML)
// '<div></div>'
</script>
Strings
Strings return text nodes.
const text = render('hi')
console.log(text.nodeType === Node.TEXT_NODE)
// true
console.log(text.textContent)
// 'hi'
Numbers
Numbers are converted into strings and then returned as a text node.
const seconds = render(24 * 60 * 60)
console.log(seconds.nodeType === Node.TEXT_NODE)
// true
console.log(seconds.textContent)
// '86400'
Functions
Functions are run, and if they return an output, it is rendered and returned.
const q = () => 2 + 2
const a = render(q)
console.log(a.nodeType === Node.TEXT_NODE)
// true
console.log(a.textContent)
// '4'
Arrays
Array elements are converted and rendered individually, and then returned as part of a DocumentFragment
that contains all elements in the array.
const items = ['The ', { tag: 'h1', child: 'big ' }, () => 1 + 2]
const fragment = render(items)
console.log(fragment.nodeType === Node.DOCUMENT_FRAGMENT_NODE)
// true
console.log(fragment.childNodes.length)
// 3
fragment.childNodes.forEach(node => console.log(node.nodeType))
// 3
// 1
// 3
console.log(fragment.textContent)
// The big 3
DocumentFragment
s can be inserted easily into pages vanilla JavaScript or jQuery, using methods like append
.
Objects
Objects return rendered elements. Elements are constructed using the same syntax as build
.
const data = {
tag: 'ul',
child: [
{ tag: 'li', child: 'one' },
{ tag: 'li', child: 2 },
{ tag: 'li', child: () => 2 + 1 }
],
class: 'styled-list'
}
const element = render(data)
console.log(element.nodeType === Node.ELEMENT_NODE)
// true
console.log(element.childNodes.length)
// 3
console.log(element.classList[0])
// 'styled-list'
element.childNodes.forEach(node => console.log(node.tagName, node.textContent))
// LI one
// LI 2
// LI 3
The objects on
property can be used to attach event handlers. Set the property's value to be an object with methods for any events that should be handled.
const greeting = render({
child: 'hello',
on: { click() { console.log('hi') } }
})
greeting.click()
// hi
The data
property can be used to attach data to the elements dataset. Set the value as an object. Each attribute of the value will be added to the dataset.
const record = render({ data: { a: 1, b: 2 } })
console.log(record.dataset.a)
// 1
console.log(record.dataset.b)
// 2
Nodes
DOM nodes return themselves. Nodes will not be modified.
const div = document.createElement('div')
const text = document.createTextNode('hello world')
div.append(text)
const output = render(div)
console.log(output.outerHTML)
// '<div>hello world</div>'
Appending
If multiple arguments are passed, all arguments after the first will be appended to the first. Each argument will be rendered before the appending takes place, including the first.
const container = document.createElement('p')
const hello = document.createTextNode('hello ')
const world = document.createTextNode('world')
render(container, hello, world)
console.log(container.outerHTML)
// '<p>hello world</p>
const message = render({}, document.createTextNode('how are you?'))
console.log(message.outerHTML)
// '<div>how are you?</div>'
const div = document.createElement('div')
const combined = render(
div,
['hello ', { tag: 'span', child: 'world' }],
' how are you?'
)
console.log(combined.outerHTML)
// '<div>hello <span>world</span> how are you?</div>'
const icon = render({ tag: 'i', class: 'icon-delete' })
const button = render(
{ tag: 'button' },
icon,
['Please! ', { tag: 'span', child: "Don't kill me!" }]
)
console.log(button.outerHTML)
// `<button><i class="icon-delete"></i>Please! <span>Don't kill me!</span></button>`
jQuery
render
integrates smoothly with jQuery.
Rendering a jQuery object will return itself.
const $body = $('body')
const output = render($body)
console.log(output.length)
// 1
console.log(output[0].tagName)
// BODY
If the first argument is a jQuery object, subsequent arguments will be appended to each element in the collection.
// <div class="target"><div>
// <span class="target"></span>
render($('.target'), { tag: 'a', href='#', child: 'clicker' })
// <div class="target"><a href="#">clicker</a></div>
// <span class="target"><a href="#">clicker</a></span>
If a later argument is a jQuery object, all elements in the collection will be appended to the first argument.
// <li>1</li>
// <li>2</li>
// <li>3</li>
const list = render({ tag: 'ul' }, $('li'))
console.log(list.outerHTML)
// <ul><li>1</li><li>2</li><li>3</li></ul>