UNPKG

toloframework

Version:

Javascript/HTML/CSS compiler for Firefox OS or nodewebkit apps using modules in the nodejs style.

194 lines (170 loc) 5.13 kB
"use strict"; var $ = require("dom"); var PM = require("tfw.binding.property-manager"); var Hammer = require("external.hammer"); var Converters = require('tfw.binding.converters'); exports.Tag = function(tagName, attribs) { tagName = tagName.trim().toLowerCase(); var elem = tagName === 'svg' ? $.svgRoot() : newTag(tagName); Object.defineProperty(this, '$', { value: elem, writable: false, enumerable: true, configurable: false }); if( Array.isArray(attribs) ) { var that = this; attribs.forEach(function (attName) { switch( attName.toLowerCase() ) { case 'value': defineAttribValue.call( that, elem ); break; case 'focus': defineAttribFocus.call( that, elem ); break; case 'textcontent': defineAttribTextContent.call( that, elem ); break; case 'innerhtml': defineAttribInnerHTML.call( that, elem ); break; default: defineStandardAttrib.call( that, elem, attName ); } }); } }; var SVG_TAGS = ["g", "rect", "circle", "line", "path", "defs"]; function newTag( name ) { if( SVG_TAGS.indexOf( name.toLowerCase() ) !== -1 ) return $.svg( name ); return $.tag( name ); } function defineAttribValue( elem ) { var that = this; var lastSettedValue = null; PM( this ).create('value', { get: function() { return lastSettedValue; }, set: function(v) { elem.value = v; lastSettedValue = v; } }); elem.addEventListener( "input", function(evt) { PM( that ).change( 'value', evt.target.value ); }, false); } function defineAttribFocus( elem ) { var that = this; PM( this ).create('focus', { cast: Converters.get('boolean')(), delay: 1 }); PM( this ).on( "focus", function(v) { if( v ) elem.focus(); else elem.blur(); }); elem.addEventListener( "focus", function() { that.focus = true; }, false); elem.addEventListener( "blur", function() { that.focus = false; }, false); } function defineAttribTextContent( elem ) { ["textContent", "textcontent"].forEach(function (name) { PM( this ).create(name, { get: function() { return elem.textContent; }, set: function(v) { elem.textContent = v; } }); }, this); } function defineAttribInnerHTML( elem ) { ["innerHTML", "innerhtml"].forEach(function (name) { PM( this ).create(name, { get: function() { return elem.innerHTML; }, set: function(v) { elem.innerHTML = v; } }); }, this); } function defineStandardAttrib( elem, attName ) { PM( this ).create(attName, { get: function() { return elem.getAttribute( attName ); }, set: function(v) { elem.setAttribute( attName, v ); } }); } /** * Apply a set of CSS classes after removing the previously applied * one for the same `id`. */ exports.Tag.prototype.applyClass = function( newClasses, id ) { var elem = this.$; if( typeof id === 'undefined' ) id = 0; if( typeof this._applyer === 'undefined' ) this._applyer = {}; if( !Array.isArray( newClasses ) ) newClasses = [newClasses]; var oldClasses = this._applyer[id]; if( Array.isArray( oldClasses ) ) { oldClasses.forEach( $.removeClass.bind( $, elem ) ); } this._applyer[id] = newClasses; newClasses.forEach( $.addClass.bind( $, elem ) ); }; /** * Check if all needed function from code behind are defined. */ exports.ensureCodeBehind = function( code_behind ) { if( typeof code_behind === 'undefined' ) throw "Missing mandatory global variable CODE_BEHIND!"; var i, funcName; for( i = 1; i < arguments.length ; i++ ) { funcName = arguments[i]; if( typeof code_behind[funcName] !== 'function' ) throw "Expected CODE_BEHIND." + funcName + " to be a function!"; } }; var GESTURES = [ "tap", "doubletap", "press", 'pan panstart panmove panup pandown panleft panright panend pancancel', "swipe", "swipeleft", "swipteright", "swipetop", "swipebottom", "pinch", "pinchin", "pinchout", "pinchstart", "pinchmove", "pinchend", "pinchcancel", "rotate", "rotatestart", "rotatemove", "rotateend", "rotatecancel" ]; /** * @param {function} event.tap * @param {function} event.press * @param {function} event.pan * @param {function} event.swipe * * @example * ``` * var View = require("tfw.view"); * View.events( div, { * "tap": function( evt ) {...}, * "press": function( evt ) {...} * }); * ``` */ exports.events = function( target, events ) { var elem = $(target); var gestures = {}; var hasGestures = 0; Object.keys( events ).forEach(function (eventName) { eventName = eventName.toLowerCase(); var eventSlot = events[eventName]; if( GESTURES.indexOf( eventName ) > -1 ) { gestures[eventName] = eventSlot; hasGestures = true; } else { elem.addEventListener( eventName, eventSlot, false ); } }); if( hasGestures ) { var gestureHandler = new Hammer( elem ); Object.keys( gestures ).forEach(function (eventName) { var eventSlot = events[eventName]; gestureHandler.on( eventName, eventSlot ); }); } };