Security News
GitHub Removes Malicious Pull Requests Targeting Open Source Repositories
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
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:
:link: Atma.js
:link: MaskFiddle
:books: Wiki
Examples
Tools
1
Markup
2
Libraries
2.1
Components2.2
Bindings2.3
jMask2.4
jQuery2.5
Dependency Injection3
Performance4
NodeJS5
Browser Support6
Plugins7
Quick Start8
Contribute
9
Changelog1
MarkupWe 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[Template → Mask AST → Shadow DOM → Live DOM]
[Template → Mask AST → HTML]
import CustomComponent from 'Foo.mask'
.container {
h4 > 'Title'
section.content {
span > 'Hello ~name!'
if (admins.includes(name)) {
em > 'Admin'
}
}
CustomComponent {
button x-tap='changeName' >
'~[bind: name]'
for (tag of tags) {
h4 > '~tag.title'
}
}
}
1.2
HTML SyntaxHere 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 MaskYou 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:package: All packages are already embedded into MaskJS sources.
2.1
Components:orange_book: Read more...↵
Core of the HMVC engine. Simple compo sample:
export class CustomComponentCtr {
// slots example
@mask.deco.slot()
onRefreshDate (){
this.model.date = new Date();
}
@mask.deco.slot()
domInsert (){
alert(this.$.innerWidth());
}
// events example
@mask.deco.event('click: button')
onButtonClicked (){
alert(this.model.date);
}
onRenderStart (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 () {
// do some cleanup
}
};
import './CustomComponent.less'
import CustomComponentCtr from './CustomComponentCtr.ts'
define CustomComponent extends CustomComponentCtr {
h1 {
'Date ~[bind: _.formatDate(date)]'
}
button .btn x-tap='onRefreshDate' {
i.material-icons > 'update'
'Refresh'
}
}
2.2
Bindings:orange_book: 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:orange_book: Read more...↵
jMask offers jQuery-alike syntax for the dynamic MaskDOM Manipulations.
2.4
jQueryMaskJS 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:orange_book: 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
PerformanceWe 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.JSMaskJS on the server
:orange_book: Mask.Node ↵ Server.Lib ↵
server
, client
or both
5
Browser Support6
PluginsThere are already many plugins, components and useful utilities. Some of them worth to checking out:
7
Quick StartMost 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='https://unpkg.com/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
Contribute8.1
Build$ git submodule init && git submodule update
$ npm install
$ npm run build
8.2
Test$ npm install
$ npm test
9
Changelog:bookmark: 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
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' }});
:copyright: MIT - 2021 Atma.js Project
FAQs
Template / Markup / HMVC Engine
The npm package maskjs receives a total of 1,339 weekly downloads. As such, maskjs popularity was classified as popular.
We found that maskjs demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
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.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.