All Projects → atmajs → Maskjs

atmajs / Maskjs

Licence: mit
Markup | Template | HMVC

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to Maskjs

Automate Everything
这是我准备写的第一本书,其实早些时候已经打算开始写书了,只是苦于没有写书经验,无从下手。写书不同于博客,写书需要将知识,经验等系统化地讲述出来,而我现在恰巧缺乏这种表现能力。因此我决定在这里将项目中零散的东西记录下来,然后后期润色一下,写成一本书。
Stars: ✭ 430 (+383.15%)
Mutual labels:  modules, components
Bit
A tool for component-driven application development.
Stars: ✭ 14,443 (+16128.09%)
Mutual labels:  modules, components
Vitamin Web
Decathlon Design System libraries for web applications
Stars: ✭ 70 (-21.35%)
Mutual labels:  components
Clean Architecture Components Boilerplate
A fork of our clean architecture boilerplate, this time using the Android Architecture Components
Stars: ✭ 1,241 (+1294.38%)
Mutual labels:  components
Postcss Modules Example
How to use postcss-modules plugin
Stars: ✭ 78 (-12.36%)
Mutual labels:  modules
Modules Papers
A collection of papers on modules.
Stars: ✭ 74 (-16.85%)
Mutual labels:  modules
Flow Ui
Flow-UI is a highly customizable UI framework based Seajs/jQuery。
Stars: ✭ 79 (-11.24%)
Mutual labels:  modules
React Native Elements App
Demo app for React Native Elements (w/ React Native Web)
Stars: ✭ 1,159 (+1202.25%)
Mutual labels:  components
Godot Lang Support
A community-maintained list of Language Support Projects for Godot Engine.
Stars: ✭ 86 (-3.37%)
Mutual labels:  modules
Horror
😱 React HTML elements with CSS-in-JS
Stars: ✭ 78 (-12.36%)
Mutual labels:  components
Neumorphic Ui
📚 A library of components based on the concept of neumorphism
Stars: ✭ 82 (-7.87%)
Mutual labels:  components
Kendo React
Issue tracker - KendoReact http://www.telerik.com/kendo-react-ui/
Stars: ✭ 77 (-13.48%)
Mutual labels:  components
Nivo
nivo provides a rich set of dataviz components, built on top of the awesome d3 and React libraries
Stars: ✭ 9,550 (+10630.34%)
Mutual labels:  components
Hub
Android 开发中通过接口获取实现类,可用于module之间的通信,通过注解解决module的依赖初始化问题,良好的多线程环境下的线程安全以及性能。a concise di library which can get implementation class for a interface easily in multiple module app , also avoid check null when want to invoke a implementation by interface.
Stars: ✭ 79 (-11.24%)
Mutual labels:  modules
Nestjs Components
A list of useful components for NestJS applications
Stars: ✭ 72 (-19.1%)
Mutual labels:  components
Nano Style
React functional CSS-in-JS
Stars: ✭ 85 (-4.49%)
Mutual labels:  components
Egeo
EGEO is the open-source UI library used to build Stratio's UI. It includes UI Components, Utilities, Services and much more to build user interfaces quickly and with ease. The library is distributed in AoT mode.
Stars: ✭ 69 (-22.47%)
Mutual labels:  components
Kit
Tools for developing, documenting, and testing React component libraries
Stars: ✭ 1,201 (+1249.44%)
Mutual labels:  components
Vue Mdc
Material web components for Vue.js
Stars: ✭ 1,217 (+1267.42%)
Mutual labels:  components
Ui
React Styled Components with bootstrap grid system
Stars: ✭ 89 (+0%)
Mutual labels:  components


MaskJS — is a markup | template | modular 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:



1 Markup

We support mask and html syntax for writing your templates. And you can even mix them within one template, as each of them has its advantages.

1.1 Mask 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 - Optimizer.
  • DOM Builder [Template → Mask AST → Shadow DOM → Live DOM]
  • HTML Builder (nodejs) [Template → Mask AST → HTML]
import CustomComponent from 'Foo.mask'

.container {
    h4 > 'Title'
    section.content {
        span > 'Hello ~name!'

        if (admins.indexOf(name) > -1) {
            em > 'Admin'
        }
    }
    CustomComponent {
        button x-tap='changeName' >
            '~[bind: name]'

        for (tag of tags) {
            h4 > '~tag.title'
        }
    }
}
1.2 HTML Syntax

Here is nothing new for you. Old good HTML syntax to define the templates. But we highly encourage to use the mask syntax, as the templates are smaller, cleaner and with additional features.

<h4>~[name]</h4>
<Dialog>
	<div>Hello Foo</div>
</Dialog>
1.3 HTML within Mask

You can even use html blocks in a mask syntax

ul {
	<li> Foo
	<li> Bar
}

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.

2 Libaries

📦 All packages are already embedded into MaskJS sources.

2.1 Components

📙 Read more...

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
	}
})

2.2 Bindings

📙 Read more... IE9+

MaskJS itself supports simple interpolations. It means the models are only accessed while render, but with this feature 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';
/*\
 * `dualbind` component also supports much more properties and configurations
\*/

2.3 jMask

📙 Read more...

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

2.4 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.

2.5 Dependency Injection

📙 Read more...

You can annotate arguments for define declaration or for its constructor and if you don't provide the values on initialization MaskJS will do it for you using registered IoC container.

The library is not include, you can use any other DI library. MaskJS only requires an IoC container with a single method: .resolve(Type):Any.

import * as IStore from services;

define UserList (store: IStore) {
	
	foreach (user of store.getUsers()) {
		div > '~user.username'
	}

	// or in constructor
	function constructor (store: IStore) {
		this.store = store;
	}
}

3 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:

4 Node.JS

MaskJS on the server

📙 Mask.Node Server.Lib

  • HMVC benefits
  • Models serialization/de-serialization
  • Components render mode - server, client or both
  • HTML rendered output with further 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

5 Browser Support

  • IE7+

6 Plugins

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

7 Quick Start

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

<!DOCTYPE html>
<html>
	<body>
		<script type='text/mask' data-run='auto'>
			import Counter from './Counter';

			h4 > 'Counter with 1 second step'
			Counter x-interval=1;

			h4 > 'Counter with 5 seconds step'
			Counter x-interval=5;
		</script>		
		<script src='http://cdn.jsdelivr.net/g/maskjs'></script>
	</body>
</html>
// Create the file `Counter.mask`
define Counter {
	var meta = {
		attributes: {
			'x-interval': 'number'
		}
	};

	var scope = {
		counter: 0,
		timer: null
	};

	slot domInsert () {
		this.scope.timer = setTimeout(() => {
			++this.scope.counter;						
		}, this.xInterval)
	}

	function dispose () {
		clearTimeout(this.scope.timer);
	}

	div > '~[bind: this.scope.counter]
}

8 Contribute

8.1 Build

$ git submodule init && git submodule update
$ npm install
$ npm run build

8.2 Test

$ npm install
$ npm test

9 Changelog


🔖 View complete list... @latest

  • 0.64.0

  • Properties

     div [style.backgroundColor] = 'red';
    

@latest

  • 0.60.0

  • Await statements, components and also modules

     define Foo {
     	function async onRenderStart () {
     		this.model = await LoadUserExample();
     	}
     	h4 > '~userName'
     }
    
     // Component
     await Foo {
     	@progress > i > 'Loading user';
     }
    
     // Promises
     await (this.getCurrentUser()) {
     	@progress > i > 'Loading user';
     	@done (user) {
     		h4 > '~user.userName'
     	}
     	@fail (error) {
     		.danger > '~error.message'
     	}
     }
    
     // Modules 
     import async Foo from './Foo';
    
     heading > 'Some heading'
     await Foo {
     	@progress > 'Loading and initilizing the module'
     }
    
  • 0.58.0

  • Decorators for methods and nodes

     [IsAuthorized]
     div > 'Hello ~user'
    
     [LogCall]
     function doSmth () {
     	// ...
     }
    
  • Async and Private methods. For browsers which do not yet support async/await es2017 feature, please use postmask-babel plugin.

     slot private async upload () {
     	await MyService.doSmth();
     } 
    
  • 0.57.13

  • Modules

    • Namespace routing

       import FooService from services;
      
       h4 > '~FooService.doSmth()'
      

      You can also configurate the base path for the routing, e.g. mask.Module.cfg('baseNs', '/src/')

      If the module is not loaded or not set to the namespace repository, we will load it for you by the resolved path, e.g. '/src/services/FooService.js'

    • Prefix routing

       import MyButton from '@controls/MyButton';
       MyButton x-tap='clicked';
      

      You have to configurate the prefix first, e.g.:

       mask.Module.cfg('prefixes.controls', '/src/controls/{0}/{1}.mask');
      
  • 0.57.0

  • Typa annotations for arguments: (argumentName: argumentType, ...)

     import * as IFoo from '/service/IFoo.js';
     import * as IBar from '/service/IBar.js';
     define MyCompo (foo: IFoo) {
     	function constructor (bar: IBar) { 
     		this.bar = bar;
     	}
     	span > `~[foo.someMethod()]`
     }
    
  • 0.56.5

  • Function scope: imports and define arguments

     import * as Service from '/services/UserService.js';
     define UserEditor (user) {
     	
     	slot save () {
     		Service
     			.changeUserName(user.id, user.name)
     			.then(() => console.log('saved!'));
     	}
    
     	input > dualbind value='user.name';
     	button x-tap=save > 'Save'
     }
    
  • sync imports, as import loading for better performance is parallel, but bundles should be loaded in sync, as they register all resources then.

import sync from './MyComponentsBundle';
import FooCompo from './Foo';
// ...
  • 0.55.1

    • HTML markup within Mask templates
  • 0.55.0

    • Async imports.

       import async Foo from './Foo.mask';
       h4 > 'MyHeader'
       await Foo;
      

      h4 header is rendered during the Foo may still being loaded.

    • define and let support arguments

       define Foo (user) {
       	h4 > '~user.name'
       }
      
       Foo(me);
      
       mask.render(template, { me: { name: 'TestUser' }});
      

©️ MIT - 2017 Atma.js Project

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].