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

dom-render

Package Overview
Dependencies
Maintainers
1
Versions
98
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dom-render

dom-render

  • 1.0.59
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
8
decreased by-83.33%
Maintainers
1
Weekly downloads
 
Created
Source

Single Page Application Framworks npm version license Chat Github

Our primary goals are

  • view template engine
  • Dom control and reorder
  • all internal variables are managed by proxy. (DomRenderProxy)

🚀 Quick start

npm install dom-render

😃 examples


📄 Code description

initialized

<!doctype html><html lang="en"><body id="app"></body></html>
const target = document.querySelector('#app');
const data = DomRender.run({name: 'my name is dom-render'}, target);
data.name = 'modify name';

print and call

<div>${this.name}</div>
<div>${this.office.addr.first}, ${this.office.addr.last}, ${this.office.addr.street} (${this.office.name})</div>
<div dr="this.office.addr.street">${this.getOfficeFullAddr()}</div>

dr-if

<div dr-if="true">true</div>
<div dr-if="this.gender==='M'">gender: M</div>

dr-for, dr-for-of

<div dr-for="var i = 0; i < this.friends.length; i++"> friend</div>
<div dr-for-of="this.friends"> ${#it#.name}</div>
<div dr-for-of="$range(10, 20)"><div>${#it#}</div><div>
<div dr-for="var i = 1 ; i <= 9 ; i++" dr-it="i">
    ${#it#} *
    <scope dr-for="var y = 1 ; y <= 9 ; y++" dr-it="y" dr-var="superIt=#it#" dr-strip="true">
        #it# = ${var.superIt * #it#}
    </scope>
</div>

dr-repeat

<div dr-repeat="10"><div>#it#</div></div>
<div dr-repeat="$range(10, 20)"><div>#it#</div></div>
<div dr-repeat="$range(10, 20, 5)"><div>#it#</div></div>
<div dr-repeat="$range('10..5, 2')"><div>#it#</div></div>

dr-inner-text, dr-inner-html

<div dr-inner-text="'<b>aa</b> <button dr-event-click=\'alert(1)\'>aa</button>'"> friend</div>
<div dr-inner-html="'<b>aa</b> <button dr-event-click=\'alert(1)\'>aa</button>'"> friend</div>

event

dr-event-(name)

  • click, mousedown, mouseup, dblclick, mouseover, mouseout, mousemove, mouseenter, mouseleave, contextmenu, keyup, keydown, keypress, change, input, submit, resize, focus, blur
  • ref: element
  • variable: $event, $target
click: <button dr-event-click="this.name = 'name' + new Date()">click</button> <br>
change: <input type="text" dr-event-change="this.name = $target.value"> <br>
input: <input type="text" dr-event-input="this.name = $target.value"> <br>
keyup: <input type="text" dr-event-keyup="this.name = $target.value"> <br>
...
keydown: <input type="text" dr-event-keydown="this.name = $target.value"><br>
submit: <form dr-event-submit="console.log($event); $event.preventDefault();"><input type="text"> <button type="submit">submit</button></form><br>

dr-window-event-popstate

  • ref: window
  • variable: $target
window-event-popstate: <input type="text" dr-window-event-popstate="alert(this.name)"><br>

dr-event

  • other event
  • ref: element
  • variable: $params, $event
<input dr-event:bind='eventName1, eventName2' dr-event="console.log('event', $params, $event)"  type="text">

dr-value

  • The value is assigned the first time.

dr-value-link

  • Value and variable values are referencing each other. It affects each other when changing. (Immediate reflection event: input)
dr-value: <input type="text" dr-value="this.office.name"> <br>
dr-value-link: <input type="text" dr-value-link="this.office.addr.street"> <br>

dr-attr

<textarea dr-attr="{rows: this.age/2, cols: this.age}"></textarea>
<div dr-attr="{wow: '123', good: 123444}"></div>
<div dr-attr="['wow=123', 'good=123444']"></div>
<div dr-attr="'wow=123, good=123444'"></div>

dr-class

<div dr-class="{big: this.age > 50, red: this.age > 50}">
<div dr-class="'big yellow ' + (this.age > 50 ? 'old' : 'young')">
<div dr-class="['small', 'yellow']">

dr-style

<div dr-style="{fontSize: this.age + 'px'}"> style </div>
<div dr-style="{'font-size': '20px'}"> style</div>
<div dr-style="'font-size: ' + this.age +'px; margin: ' + this.age + 'px'"> style </div>
<div dr-style="['font-size: ' + this.age +'px', 'margin: ' + this.age + 'px']"> style </div>

dr-strip

as-is

<div dr-strip="true"><span>hello</span></div>

to-be

<span>hello</span>

dr-on-init

<input dr-on-init="this.onInitElement">

dr-before, dr-after

<div dr-before="console.log('process before')" dr-after="console.log('process after')"></div>

dr-complete

<select dr-value-link="this.currentContry" dr-event-change="this.contryChange($event)">
    <option dr-for-of="this.languages" dr-value="#it#.key" dr-complete="this.currentContry='defaultValue'">${#it#.title}</option>
</select>

LifeCycle

* OnInitRender
  - onInitRender(): init render call

Script

new DomRender.run(obj, target, {
  scripts: {
    concat: function (head: string, tail: string) {
      return head + tail; 
    }
  }
});

using script

const data = config.scripts.concat('head', 'tail')
<div>${$scripts.concat('head', 'tail')}</div>
<div dr-if="$scripts.concat('wow', 'good') === 'wowgood'"> is wowgood</div>

Component

export namespace Profile {
  export const templat = '<div>aaaaa${this.name}aaaaa </div>';
  export const styles = ['p {color: red}', 'div {margin: ${this.margin} + \'px\' }'];
  export class Component {
    public name = 'default name';
    public margin = 5;
    public say() {
        console.log('say!~')
    }
  }
}

new DomRender.run(obj, target, {
  targetElements: [
    RawSet.createComponentTargetElement('my-element', (e, o, r) => new Profile.Component(), Profile.templat, Profile.styles, scripts)
  ],
});

using component

<my-element dr-on-init="$component.say();"></my-element>
  • attribute
    • dr-on-init: component created init call script
      • $component: component instance
      • $element: element instance
      • $attribute: element attribute object
      • $innerHTML: element innerHTML string

dr-form

  • event: change
  • modify change: dr-form:event="input"
class User {
  form = {};
  submit() {
    const form = (this.form as any)
    console.log('submit->', form, form.name, form.age, form.addr);
  }
}
<form dr-form="this.form" dr-event-submit="this.submit(); $event.preventDefault();">
  name: <input name="name">
  age: <input name="age">
  addr: <input dr-form:event="input" name="addr">
  <button type="submit">submit</button>
</form>

validator

class PageValidator extends FormValidator { 
    required = new RequiredValidator();
    notEmpty = new NotEmptyValidator();
    empty = new EmptyValidator();
    regexp = new RegExpTestValidator(/[0-9]/);
    mix = new MultipleValidator([new RequiredValidator(), new NotEmptyValidator()]);

    all = new ValidValidatorArray((v, t, e) => {
        return !((v ?? []).filter(it => !it.checked).length > 0);
    });

    gender = new ValidValidatorArray((v, t, e) => {
        return ((v ?? []).filter(it => it.checked).length > 0);
    });
}
class User {
  form = new PageValidator();
  submit() {
    console.log('submit valid->', this.form.valid());
  }
  
  changeData() {
    this.form.required.value = 'new value';    
  }
}
<form dr-form="this.form" dr-event-submit="this.submit(); $event.preventDefault();">
    <h2>validator</h2>
    required: <input name="required"> <br>
    notEmpty: <input name="notEmpty"> <br>
    empty: <input name="empty"> <br>
    regexp: /[0-9]/ <input name="regexp"> <br>
    <h2>mix validator</h2>
    required, notEmpty: <input name="mix"> <br>
    <h2>all check required</h2>
    <input name="all" type="checkbox" value="a">a <br>
    <input name="all" type="checkbox" value="b">b <br>

    <h2>gender chose one</h2>
    <input name="gender" type="radio" value="male"> Male <br>
    <input name="gender" type="radio" value="female"> Female<br>

    <button type="submit">check valid</button>
</form>

validator

  • Validator (abstract)
  • ValidatorArray (abstract)
  • AllCheckedValidatorArray
  • AllUnCheckedValidatorArray
  • CheckedValidator
  • CountEqualsCheckedValidatorArray
  • CountEqualsUnCheckedValidatorArray
  • CountGreaterThanCheckedValidatorArray
  • CountGreaterThanEqualsCheckedValidatorArray
  • CountGreaterThanEqualsUnCheckedValidatorArray
  • CountGreaterThanUnCheckedValidatorArray
  • CountLessThanCheckedValidatorArray
  • CountLessThanEqualsCheckedValidatorArray
  • CountLessThanEqualsUnCheckedValidatorArray
  • CountLessThanUnCheckedValidatorArray
  • CountUnCheckedValidatorArray
  • EmptyValidator
  • ExcludeCheckedValidatorArray
  • FormValidator
  • IncludeCheckedValidatorArray
  • MultipleValidator
  • NonPassValidator
  • NotEmptyValidator
  • NotRegExpTestValidator
  • PassValidator
  • RegExpTestValidator
  • RequiredValidator
  • UnCheckedValidator
  • ValidMultipleValidator
  • ValidValidator
  • ValidValidatorArray
  • ValueEqualsValidator
  • ValueNotEqualsValidator

Class

Range

const range = new Range(100,55, 10);
for (let data of new Range(100,55, 10)) {
  console.log(data);
}
const rangeArray = new Range(100,55, 10).toArray();

Detect Get, Set

OnBeforeReturnSet

export interface OnBeforeReturnSet {
    onBeforeReturnSet(name: string, value: any, fullPath?: string[]): void;
}

OnBeforeReturnGet

export interface OnBeforeReturnGet {
    onBeforeReturnGet(name: string, value: any, fullPath?: string[]): void;
}

using detect

{
    name: 'dom-render'
    onBeforeReturnSet: (name: string, value: any, fullpath: string[]) => {
        console.log('set name-->', name, value, fullpath);
    }
    onBeforeReturnGet: (name: string, value: any, fullpath: string[]) => {
        console.log('get name-->', name, value, fullpath);
    }
}

exclude detect property: Config

  • proxyExcludeOnBeforeReturnGets: ['propertyName']
  • proxyExcludeOnBeforeReturnSets: ['propertyName']

Proxy

all internal variables are managed by proxy. (DomRenderProxy)

exclude proxy (situation: Maximum call stack error)

exclude detect property: Config

  • proxyExcludeTyps: [Class...]

Code base

// frezz
{name : Object.freeze({...})}

// Shield Object type: {[k: string]: any}
{name : new Shield()}

// DomRenderProxy Final
{name : DomRenderProxy.final({...})}

Config

export type TargetElement = {
    _name: string,
    template?: string,
    styles?: string[],
    callBack: (target: Element, obj: any, rawSet: RawSet) => DocumentFragment,
    complete?: (target: Element, obj: any, rawSet: RawSet) => void
};

export type TargetAttr = {
    name: string,
    callBack: (target: Element, attrValue: string, obj: any, rawSet: RawSet) => DocumentFragment,
    complete?: (target: Element, attrValue: string, obj: any, rawSet: RawSet) => void
};

export interface Config {
    targetElements?: TargetElement[];
    targetAttrs?: TargetAttr[];
    onElementInit?: (name: string, obj: any, rawSet: RawSet) => void;
    onAttrInit?: (name: string, attrValue: string, obj: any, rawSet: RawSet) => void;
    proxyExcludeTyps?: ConstructorType<any>[];
    proxyExcludeOnBeforeReturnSets?: string[];
    proxyExcludeOnBeforeReturnGets?: string[];
    scripts?: { [n: string]: any };
    applyEvents?: { attrName: string, callBack: (elements: Element, attrValue: string, obj: any) => void }[];
}

License

Keywords

FAQs

Package last updated on 20 Oct 2021

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