Security News
Supply Chain Attack Detected in Solana's web3.js Library
A supply chain attack has been detected in versions 1.95.6 and 1.95.7 of the popular @solana/web3.js library.
dom-render
Advanced tools
<script src="https://cdn.jsdelivr.net/npm/dom-render@1.0.83/dist/bundle.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body id="app">
${this.name}$
<script src="https://cdn.jsdelivr.net/npm/dom-render@1.0.83/dist/bundle.js"></script>
<script>
let data = {
name: 'my name is dom-render'
};
data = DomRender.run(data , document.querySelector('#app'));
</script>
</body>
</html>
<body id="app">
${this.name}$ <!-- outout: <i>my name is dom-render</i> -->
#{this.name}# <!-- outout text is italic: my name is dom-render -->
<script>
let data = {
name: '<i>my name is dom-render</i>'
};
data = DomRender.run(data , document.querySelector('#app'));
</script>
</body>
<body id="app">
<input type="text" value="${this.name}$" style="${'color: '+this.color}$">
<button dr-event-click="this.changeData();">change</button>
</body>
class Data {
name = 'my name is dom-render';
color = '#ff0000';
changeData() {
this.name = RandomUtils.getRandomString(10);
this.color = RandomUtils.getRandomColor();
}
}
const data = DomRender.run(new Data(), document.querySelector('#app')!);
<body id="app">
<div dr-if="true">true</div> <!-- render -->
<div dr-if="this.gender === 'M'">gender: M</div> <!-- No Render -->
<script>
let data = {
gender: 'F'
};
data = DomRender.run(data , document.querySelector('#app'));
</script>
</body>
<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>
<h3>appender</h3>
<ul>
<li dr-appender="this.appender">
${#it#}$
</li>
</ul>
<button dr-event-click="this.append()">appending</button>
<button dr-event-click="this.modifyAppender(0)">idx 0 modify</button>
<button dr-event-click="this.clearAppend()">appender clear</button>
class Data {
appender = new Appender();
constructor() {
this.appender.push('init' + RandomUtils.uuid(), 'init' + RandomUtils.uuid());
}
append() {
this.appender.push(RandomUtils.uuid(), RandomUtils.uuid());
}
clearAppend() {
this.appender.clear()
}
modifyAppender(idx: number) {
this.appender[idx][0] = RandomUtils.uuid();
}
}
<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>
<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>
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>
window-event-popstate: <input type="text" dr-window-event-popstate="alert(this.name)"><br>
<input dr-event:bind='eventName1, eventName2' dr-event="console.log('event', $params, $event)" type="text">
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>
<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>
<div dr-class="{big: this.age > 50, red: this.age > 50}"></div>
<div dr-class="'big yellow ' + (this.age > 50 ? 'old' : 'young')"></div>
<div dr-class="['small', 'yellow']"></div>
<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>
<div dr-strip="true"><span>hello</span></div> <!-- output html : <span>hello</span> -->
<div dr-before="console.log('process before')" dr-after="console.log('process after')"></div>
<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>
<body id="app">
<form dr-form="this.form" dr-event-submit="this.submit(); $event.preventDefault();">
name: <input name="name">
age: <input name="age">
<button type="submit">submit</button>
</form>
<script>
let data = {
form: {},
submit() {
console.log(this.form);
}
};
data = DomRender.run(data , document.querySelector('#app'));
</script>
</body>
<!-- 💥 submit call -->
<!-- console: {name: 'name data', age: 'age data'} -->
<body id="app">
<form dr-form="this.form" dr-event-submit="this.submit(); $event.preventDefault();">
name: <input name="name">
age: <input name="age">
<button type="submit">submit</button>
</form>
<script>
const form = new FormValidator();
form.name = new NotEmptyValidator();
form.age = new NotEmptyValidator();
let data = {
form,
submit() {
if (this.form.valid()){
console.log('valid');
} else {
console.log('inValid');
}
}
};
data = DomRender.run(data , document.querySelector('#app'));
</script>
</body>
validator
// Config
const config: Config = {
window
};
config.targetElements = [
DomRender.createComponent({type: Main, tagName: 'page-main', template: MainTemplate}, config),
DomRender.createComponent({type: Second, tagName: 'page-second', template: SecondTemplate}, config),
DomRender.createComponent({type: Detail, tagName: 'page-detail', template: DetailTemplate}, config)
]
config.routerType = 'hash'; // 'hash' | 'path' | 'none';
const data = DomRender.run(new Data(), document.querySelector('#app')!, config);
<header>
<button dr-event-click="$router.go('/')">main</button>
<button dr-event-click="$router.go('/second', {secondata: 555})">second</button>
<button dr-event-click="$router.go('/detail/25?name=zzz')">detail</button>
</div>
</header>
<main>
<page-main dr-if="$router.test('/')"></page-main>
<page-second dr-if="$router.test('/second')"></page-second>
<page-detail url='/detail/{id:[0-9]+}' dr-if="$router.test($attribute.url)" dr-on-create="$router.getRouteData($attribute.url)"></page-detail>
</main>
import {RouteData} from 'dom-render/routers/Router';
import {OnCreateRender} from 'dom-render/lifecycle/OnCreateRender';
export class Detail implements OnCreateRender {
name = 'Detail';
onCreateRender(routeData: RouteData) {
console.log('routeData->', routeData);
}
}
// RouteData type
type RouteData = {
path: string;
url: string;
data?: any;
searchParams: URLSearchParams;
pathData?: any;
}
export class Home implements OnProxyDomRender {
private channel?: Channel;
sendIndexMessage() {
const rtn = this.channel?.publish(Index, {
name: this.name,
age: this.age,
title: this.title
});
console.log('sendIndexMessage return value: ', rtn);
}
onProxyDomRender({messenger}: Config): void {
this.channel = messenger?.createChannel(Home);
}
}
class Index implements OnProxyDomRender {
onProxyDomRender({messenger}: Config): void {
messenger?.createChannel(this).filter((data) => (data.age ?? 0) > 5).subscribe((data) => {
this.rcvData = data;
return {data: 'good', action: 'actionGood'}
});
// messenger?.createChannel(this).subscribe((data) => {
// this.rcvData = data;
// return {data: 'good', action: 'actionGood'}
// });
}
}
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();
const appender = new Appender<number>([1, 2]);
appender.push(3, 4)
for (const data of appender) {
console.log('----appender item--->', data);
}
{
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
export interface OnBeforeReturnSet {
onBeforeReturnSet(name: string, value: any, fullPath?: string[]): void;
}
export interface OnBeforeReturnGet {
onBeforeReturnGet(name: string, value: any, fullPath?: string[]): void;
}
all internal variables are managed by proxy. (DomRenderProxy)
exclude detect property: Config
Code base
// frezz
{name : Object.freeze({...})}
// Shield Object type: {[k: string]: any}
{name : new Shield()}
// DomRenderProxy Final
{name : DomRenderProxy.final({...})}
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>
<body id="app">
${this.name}$
<h1>component</h1>
<profile dr-on-component-init="$component.name='jhone'; $component.age=55;"><b>${#component#.details}$</b></profile>
<profile dr-on-component-init="$component.name='cal'; $component.age=56;"><b>detail-2</b></profile>
<profile dr-on-component-init="$component.name='rose'; $component.age=57;">
<profile dr-on-component-init="$component.name='rose-sub'; $component.age=156;">
<b>${this.name}$</b>
</profile>
</profile>
<h3>component data link and detect</h3>
<Profile dr-if="this.toggle" dr-detect="$component.age = this.age" dr-on-component-init="$component.name='papa'; $component.age=58;">
<b>${this.name}$</b>
</Profile>
<button dr-event-click="this.name = new Date().toString();">change name</button>
<button dr-event-click="this.age = Date.now();">change age</button>
<button dr-event-click="this.toggle = !this.toggle;">change toggle</button>
<j1>component constructor, on-create, dr-on-component-init</j1>
<home dr-constructor="[this.name, this.age, 'home welcom']" dr-on-create="{type: 'onCreate', data: 'datadata'}" dr-on-component-init="$component.onInit('data')"></home>
<h1>scripts</h1>
<div>
${$scripts.concat('hello', 'tail')}$
</div>
<h1>attr</h1>
<button link="this.link">
link attribute
</button>
<h1>attrCallBack</h1>
<input id="callback" type="text" wow>
</body>
config.targetElements = [
DomRender.createComponent({type: Profile, template: ProfileTemplate}, config),
DomRender.createComponent({type: Home, template: HomeTemplate, styles: HomeStyle}, config)
]
config.targetAttrs = [
DomRender.createAttribute('link',
(element: Element, attrValue: string, obj: any, rawSet: RawSet) => {
return obj;
},
(element: Element, attrValue: string, obj: any, rawSet: RawSet) => {
const fag = window.document.createDocumentFragment();
if (attrValue) {
const n = element.cloneNode(true) as Element;
attrValue = ScriptUtils.eval(`return ${attrValue}`, obj)
n.addEventListener('click', () => {
location.href = attrValue;
});
fag.append(n);
}
return fag;
}
)
]
config.applyEvents = [
{
attrName: 'wow',
callBack: (e, a, o) => {
e.addEventListener('click', (event) => {
alert((event.target as any).value);
})
}
}
]
const data = DomRender.run(new Data(), document.querySelector('#app')!, config);
using component
<my-element dr-on-component-init="$component.say();"></my-element>
<home value="${this.name}$" wow="${this.color}$">
${#component#.homeName}$
<home value="${#component#.homeName}$" wow="${#component#.homeColor}$" dr-component-name="sub_component" dr-component-inner-html-name="innerHTML">
${#sub_component#.homeName}$
</home>
</home>
FAQs
html view template engine
We found that dom-render demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers 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
A supply chain attack has been detected in versions 1.95.6 and 1.95.7 of the popular @solana/web3.js library.
Research
Security News
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Security News
Research
Socket researchers have discovered malicious npm packages targeting crypto developers, stealing credentials and wallet data using spyware delivered through typosquats of popular cryptographic libraries.