Veneer Docs
The provided function veneer(tagName, definition) is much comparable to Polymer('proto-element', {...}) or xtag.register(tagName, {...}). It allows the strong-type syncing of properties and attributes, defining the look via css, customizing the behavior via delegated events, and defining default property values for custom properties and attributes. In short, it's enough to build highly flexible and reusable custom tags, without being dogmatic about the details.
Definition Properties
Element definitions can utilize any of the following properties to create the widget:
proto
allows you to set the prototype of the custom element to a clone of any object to incorporate its functionality into your element. Ex: HTMLInputElement, default: HTMLElement
events
The events object allows you to bind lifecycle events (init, insert, update, remove), as well as other self-defined custom events. These properties are fed to a normal addEventListener() call, and utilize normal event features.
defaults
An object of tag property defaults to fill-in any un-provided data for each tag by property name.
css
Defines the look of the tag and sub-tags. Unlike Polymer, these is no poly-filled scoping for CSS (it's very slow), so be sure to use your tag name as a namespace in your CSS rules.
methods
Defines methods inherited by each element instance. You can also define own methods for each tag in the insert event, if you need "private" variables per instance.
props
An object that defines the types of properties auto-bound to attributes. Each value is a primitive constructor, or any normally-returning function to turn a string attrib name into a property that reflects a Number or Boolean, or even a composite Object. Note that true constructors won't work since "new" is not used to invoke. veneer.k and veneer.bool are handy pre-defined functions for defining non-string and boolean (present or not) attributes. You can also use an object for the value to customize the behaviour of the property:
Custom Props
Instead of using a constructor function for a property def (a member of props ), you can use a definition object, which opens up some extra options.
attr
Lets the attribute name differ from the property name (the key of the def)
observe
true or false: should altering this property fire an update event on the element?
type
a constructor function like you would use in a non-object property definition
value
Specifies a default value for the property, over-riding any default value specified in defaults
get/set
Regular getters and setters like the ones used in Object.defineProperty's get functions. The default getter calls the type function on the getAttribute(propName) value. The default setter simply calls elm.setAttribute with the new value.
Set has a special behaviour; by returning true in the setter, instead of the normal nothing, you can prevent the attribute value from updating and the update() event from firing.
You can also define a read-only property by using a non-adjustable setter function. For example, if you set something to use {set: Boolean.bind(null, true)}, the property will always be true.
Utility Methods
There are some common utility methods tacked on to the veneer() function:
veneer._(objCollection) => Array
Turns a lengthy object into a true Array
veneer.$(strCssSelector, optElmRoot) => Array of Elements
Turns a CSS selector into an array. Specify a custom parent by passing an element as the 2nd argument.
veneer.elm(tagName, objAttribs, strInnerHTML)
Create a new HTML element by tag name, passing attributes as an object (optional) and content as a string (optional).
veneer.template(objData, strTemplate) => String (composited)
A very simple/fast template tool to insert object property values by name into a string using {{propertyName}}-style placeholders.
veneer.include(strJsUrl)
Adds a new script to the document by url.
veneer.css(strCSS)
Injects a string of CSS into the document.
veneer.now()
Returns the number of MS since page loaded w/ decimals if available.
veneer.importHTML(strHtmlUrl)
Adds HTML content to the document's head by url.
veneer.ajax(strUrl, fnCallBack)
Loads a file/url and passes the result to a callback function as fnCallBack(x.responseText, x)
veneer.raiseEvent(strEventName, element, objDetails)
Fires a native Custom Event on the Element with the details passed in an optional argument.
veneer.assign(obj, key)
A callback maker for when you need a function to assign it's first argument to some object as a property.
veneer.observe(obj, strProp, fnCallBack)
Given an object and property name, fires a given function when that object's property's value changes.
veneer.pluck(obj)
Given a string this of a property names and an object argument, returns the property value of the object.
ex: veneer.$("a").map(veneer.pluck, "href")
veneer.from(strProperty)
The inversion of pluck. Given a string argument of a property name and an object this, returns the property value of the object. ex: ["title", "className", "bgColor"].map(veneer.from, document.body)
veneer.set(obj)
Given an Array this of a property name and a value, and an object argument, sets the property of the object to the value. ex: veneer.$("a[href]:not([href^='/'])").map(veneer.set, ["title","External Link..."])
veneer.hms(numSeconds)
Turns a number of seconds into a H:M:S-style time string, good for showing duration in templates.
veneer.ref(varNumberOrObject)
Given an object, returns a number. Given the same number, returns an object. Perfect for linking data object to string template output.
veneer.date(varDateOfSomeType)
Given a string date, number epoc time, or Date object proper, returns a new Date object. perfect for templating: {{date|veneer.date|.toTimeString}}
Lifecycle Events
These DOM events are raised on the Element as it progresses through it's life. They all have e.target as the Element, just like all DOM events, so normal event handlers work with them; ex: elm.addEventListener("insert", function(e){ ... }).
init
Fired when the Element is first created, before all other properties, events, and defaults are applied. This should be thought of as a macro-like layer to modify the unknown element instance before everything else happens. More often it's handier to use the insert event to initialize the custom tag in consideration of all it's properties and defaults being applied, but before it's inserted into the document.
insert
Fired when the Element is added to the document's DOM. This is the event most native veneer tags use to parse their content, reconcile attribs (since it runs after defaults are applied), and perform other creation-time tasks.
update
Fired when a property or attribute defined in props changes. It can also be manually fired at runtime by calling element.change().
If you don't define an insert event, update fires upon creation to provide initialize and modify capabilities to a single handler. To prevent update from firing at creation, define events.insert , even if just as "String" or some other do-nothing function.
remove
Fired when the Element is removed from the document's DOM.
Custom Element Tags
<veneer-element> tags define a custom element using html instead of JS. It is essentially sugar on top of the JS interface, but can save you from escaping CSS and HTML inside a JS file. Different parts of the tag and its contents get mapped to a normal veneer() call.
The veneer definition properties are mapped as follows:
tag name
Taken from the veneer-element's name attribute.
proto
Name of constructor given by proto attribute on veneer-element
content
Via a template tag's contents inside of veneer-element.
props
Attributes naming functions on veneer-element tag EXCEPT those matching /^on/ or "name" or "id" or "class".
defaults
Attributes on an inner template tag EXCEPT those matching /^on/ or "name" or "id" or "class" will define a default value (ran through the corresponding props's constructor). You must define a prop on the veneer-element to define a default.
css
via style tag inside of veneer-element.
simple events
Defined by using on+theEventName as 'event attributes' on veneer-element.
complex events
Code in script tag of type=shadow inside of veneer-element runs on creation. Inside the code you can use this.addEventListener() to bind regular and custom events.
Custom Element Demo
<veneer-element
name=veneer-test
value=Number
proto=HTMLInputElement
onclick="this.value=Math.random()"
onupdate="this.innerHTML=veneer.template(this, this._def.content)">
<style>
veneer-test {
border: 1px dotted red;
padding: .1em;
background: yellow;
cursor: pointer;
}
</style>
<template value=0.12345678 title="Click for a new Number" >
Random # {{value}}
</template>
</veneer-element>
Random # {{value}}
New Element Tests:
w/ no value attrib (<veneer-test ></veneer-test>):
should default to 0.12345678
w/ empty value attrib (<veneer-test value ></veneer-test>):
should default to blank
w/ value attrib (<veneer-test value=0.543231 ></veneer-test>):
should default to 0.54321
Change Log
{{#r}}
:: {{description}}
{{/r}}