Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

maskjs

Package Overview
Dependencies
Maintainers
1
Versions
252
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

maskjs

Template / Markup / HMVC Engine

  • 0.12.13
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
1.6K
decreased by-20.5%
Maintainers
1
Weekly downloads
 
Created
Source


[MaskJS](http://atmajs.com/mask' target='_blank'>mask.js) — is a markup | template | HMVC engine for modern and fast web(Browser), server(NodeJS) or mobile(PhoneGap) applications. Component-based architecture simplifies defining, implementing and composing loosely coupled independent elements into a single application.

Resources:




Syntax
  • Component and element-based markup
  • Statements, Expressions, Interpolations
  • Performance. No precompilation is required
  • Small size. ~30% smaller than HTML Additionaly, there is a minification tool - mask-minify.
  • DOM Builder [Template → Mask DOM → Shadow DOM → Live DOM]
  • HTML Builder (nodejs) [Template → Mask DOM → HTML]
import :customComponent from './foo'

.container {
    h4 > 'Title'
    section.content data-id='myID' {
        span > 'Hello ~[name]!'
        
        if (admins.indexOf(name) > -1) {
            em > 'Admin'
        }
    }
    :customComponent {
        button x-tap='changeName' >
            '~[bind: name]'
            
        for (tag of tags) {
            h4 > '~[tag.title]'
        }
    }
}

MaskJS has extremely extendable API based on interfaces and contracts. It supports Custom Tag Handlers, Custom Attribute Handlers, Model Utils.

MaskJS default build contains sub projects: CompoJS, Bindings, jMask.

Components Library

Documentation

Core of the HMVC engine. Simple compo sample:

mask.registerHandler(':customComponent', mask.Compo({
	slots: {
		refreshDate: function(){
			this.model.date = new Date();
		},
		domInsert: function(){
			alert(this.$.innerWidth());
		}
	},
	events: {
		'click: button': function(){
			alert(this.model.date);
		}
	},
	onRenderStart: function(model, ctx){
		// override model
		this.model = { date: new Date(); }
	},
	onRenderEnd: function(elements, model, ctx){
		this.$ // is a domLibrary (jQuery-lite, jQuery/Zepto/Kimbo) wrapper over `elements`
	},
	dispose: function(){
		// do some cleanup
	}
})
Bindings Library

Documentation (IE9+)

MaskJS itself supports simple interpolations. It means the models are only accessed while render, but with this library you can define single or dual bindings. As MaskJS is a DOM based engine, the bindings are instant.

Simple bindings sample:

h4 > '~[bind: fooDate.getSeconds() * barAge ]'

input type=date >
	:dualbind value='fooDate';

input type=number >
	:dualbind
		value='barAge'
		x-signal='dom: ageChanged';
/*
 * `ageChanged` is emitted in this sample each time `barAge` changes
 * `:dualbind` component also supports much more properties and configurations
 */
jMask Library

Documentation

jMask offers jQuery-alike syntax for the dynamic MaskDOM Manipulations.

jQuery

MaskJS is loosely coupled with the DOM Library, like jQuery-Zepto-Kimbo. It means, that it does not depend on any DOM library, but it is highly recommended to use one. Additionally there are some extensions, like

$.fn.appendMask
$.fn.prependMask
$.fn.beforeMask
$.fn.afterMask
$.fn.emptyAndDispose
$.fn.removeAndDispose
//e.g.
$('.foo').appendMask('h4 > "~[title]"', { title: 'Hello' });

So you would never need to use the HTML.

Performance

We thoroughly pay attention to the performance, especially on the mobile CPU. The DOM based and the Shadow DOM approach is the fastest way to create hierarchical component structure.

Some benchmarks:

Node.JS

MaskJS on the server - mask.node. (server)

  • HMVC benefits
  • Models serialization/de-serialization
  • Components render mode - Server, Client, Both
  • HTML rendered output with the Bootstrapping on the client, so that the components are initialized, all events and bindings are attached
  • Application start performance: browser receives ready html for rendering.
  • SEO
Browser Support
  • IE7+
Plugins

There are already many plugins, components and useful utilities. Some of them worth checking out:

Quick Start
Quick start and examples

Most simple MaskJS sample to show where you could start from:

<!DOCTYPE html>
<html>
	<body>
		<header>
			<!-- e.g add menu into header -->
			<script type='text/mask' data-run='true'>
				ul {
					for(page of pages) {
						log('>> Log current:', page);
						li > a
							href='/~[page].html'
							x-signal='click: fooAction' > '~[page]'
					}
					// nested components
					:bazCompo > :quxCompo;
					
					debugger;
				}
			</script>
		</header>
		<!-- ... other html, or mask blocks -->
		<!--
			usually you would have only one Mask block, which is the entry point
			for the app, and you would use nested component composition to
			encapsulate logic, models, templates and the behaviour
		-->
		<script src='http://cdn.jsdelivr.net/g/maskjs'></script>
		<script type='text/javascript'>
			var App = mask.Compo({
				model: {
					pages: [ 'blog', 'about', 'contact' ]
				},
				slots: {
					fooAction: function(event){
						event.preventDefault();
						console.log(this instanceof App);
						// ...
					}
				}
			});
			mask.registerHandler(':bazCompo', mask.Compo({/*implement*/}));
			mask.registerHandler(':quxCompo', mask.Compo({/*implement*/}));
			mask.run(App);
		</script>
	</body>
</html>

Contribute

Build
$ npm install
$ npm run build
Test
$ npm install
$ npm test

Changelog


  • 0.12.2

    • slot and event javascript handlers (handler)
    • style node syntax support with (style)
      • :host, :host() support
      • scoped css support (IE6+)
      section {
      	style scoped {
      		span {
      			color: red;
      		}
      	}
      	span > 'Hello World'
      }
      
  • 0.9.6

    • Merge feature for better encapsulation, e.g:
    	define :dialog {
    		.wrapper > .modal {
    			.modal-header {
    				@title;
    				.close;
    			}
    			.modal-content > @body;
    		}
    	}
    	// ..
    	:dialog {
    		@title > 'Hello'
    		@body  > 'World!'
    	}
    
  • 0.9.1

    • Expressions:

      • Accessors with Bracket notation: ~[foo[bar]],~[foo["key"]]
    • VarStatement:

      	ul {
      		var list = ['foo', 'bar'];
      		for(key of list){
      			li > '~[key]'
      		}
      	}
      	/* renders to:
      	 * <ul><li>foo</li><li>bar</li></ul>
      	 */
      
  • 0.9.0

    • Syntax: (statements)
      • if (expression) { ... } else if (expr) {} else {}
      • for (el of array) { ... }
      • for ((el,index) of array) { ... }
      • for (key in object) { ... }
      • for ((key, value) in object) { ... }
      • each (array) { ... }
      • with (obj.property.value) { ... }
      • switch (value) { case (expression) { ... } /*...*/ }
    • Controllers scoped model
    • IncludeJS integration
    	include ("./UserTemplate.mask") { 
    		for(user in users) {
    			import('UserTemplate');
    		}
    	}
    
  • 0.8.1

    • To get components/context property values use special symbols:

      • '~[$c.compoName]' // component's property sample
      • '~[$a.id]' // component attribute's property sample
      • '~[$ctx.page.id]' // context's property sample
  • 0.8.0

    • Async components. If a components needs to accomplish any async task, it can be done in renderStart/onRenderStart function using Compo.pause(this, ctx) / Compo.resume(this, ctx)
      	mask.registerHandler(':asyncCompo', mask.Compo({
      		onRenderStart: function(model, ctx){
      			var resume = Compo.pause(this, ctx);
      			
      			someAsyncJob(function(){
      				resume();
      			});
      		}
      	}));
      
  • 0.7.5

    • Binded Percent Handler - if, `each
  • 0.7.0

    • Expressions parser. Samples:

      • ~[:controllerFunction(userName.toUpperCase()) + ';']
      • ~[:user && user.id || "Log in"]
    • Variables/Functions look up (deprecated) upd: removed:

      1. model

      2. ctx

      3. controller

      4. up in controllers tree

  • 0.6.95

    • Use ~[] for string interpolation instead of #{}, as mask templates are already overloaded with '#','{' and '}' usage

      mask.setInterpolationQuotes('#{','}') - for fallback (or any other start/end, caution - start should be of 2 chars and the end of 1


:copyright: MIT - 2015 Atma.js Project

FAQs

Package last updated on 01 Apr 2015

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc