Skip to content

Commit 00d35d1

Browse files
committed
Merge branch 'hman61-doohtml-lite-v0.96.1-march-17-2025'
2 parents 1fbe389 + 6f293f4 commit 00d35d1

File tree

7 files changed

+366
-0
lines changed

7 files changed

+366
-0
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>DooHTML</title>
7+
<link rel="shortcut icon" type="image/png" href="./favicon.png" />
8+
<link href="/css/currentStyle.css" rel="preload" as="style"/>
9+
<link href="/css/currentStyle.css" rel="stylesheet"/>
10+
<script type="module" src="./js/doo.html.fn.min.js" defer ></script>
11+
<script type="module" src="./src/main.js" defer ></script>
12+
<template id="table">
13+
<table class="table table-hover table-striped test-data">
14+
<tbody id="tbody"><tr bind="rows"><td class="col-md-1">{{id}}</td><td class="col-md-4"><a>{{label}}</a></td><td class="col-md-1"><a class="remove"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></a></td><td class="col-md-6"></td></tr></tbody>
15+
</table>
16+
</template>
17+
</head>
18+
<body>
19+
<div id="main">
20+
21+
<div class="container">
22+
<div class="jumbotron">
23+
<div class="row">
24+
<div class="col-md-6">
25+
<h1>DooHTML - Lite</h1><span class="ver"></span>
26+
</div>
27+
<div class="col-md-6">
28+
<div class="row">
29+
<div class="col-sm-6 smallpad">
30+
<button type="button" class="btn btn-primary btn-block" id="run">Create 1,000 rows</button>
31+
</div>
32+
<div class="col-sm-6 smallpad">
33+
<button type="button" class="btn btn-primary btn-block" id="runlots">Create 10,000 rows</button>
34+
</div>
35+
<div class="col-sm-6 smallpad">
36+
<button type="button" class="btn btn-primary btn-block" id="add">Append 1,000 rows</button>
37+
</div>
38+
<div class="col-sm-6 smallpad">
39+
<button type="button" class="btn btn-primary btn-block" id="update">Update every 10th row</button>
40+
</div>
41+
<div class="col-sm-6 smallpad">
42+
<button type="button" class="btn btn-primary btn-block" id="clear">Clear</button>
43+
</div>
44+
<div class="col-sm-6 smallpad">
45+
<button type="button" class="btn btn-primary btn-block" id="swaprows">Swap Rows</button>
46+
</div>
47+
</div>
48+
</div>
49+
</div>
50+
</div>
51+
<doo-main
52+
bind="data"
53+
data-key="key"
54+
data-has-html="false"
55+
template="#table"
56+
></doo-main>
57+
</div>
58+
<span class="preloadicon glyphicon glyphicon-remove" aria-hidden="true"></span>
59+
</div>
60+
</body>
61+
</html>

frameworks/keyed/doohtml-lite/js/doo.html.fn.min.js

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frameworks/keyed/doohtml-lite/package-lock.json

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "js-framework-benchmark-doohtml",
3+
"version": "0.96.1",
4+
"description": "DooHTML-lite JS-Benchmark",
5+
"main": "main.js",
6+
"js-framework-benchmark": {
7+
"frameworkVersion": "",
8+
"frameworkHomeURL": "https://doohtml.com",
9+
"issues": [772]
10+
},
11+
"scripts": {
12+
"dev": "exit 0",
13+
"build-prod": "exit 0"
14+
},
15+
"keywords": [],
16+
"author": "Henrik Javen",
17+
"license": "Apache-2.0",
18+
"homepage": "https://doohtml.com",
19+
"repository": {
20+
"type": "git",
21+
"url": "https://github.com/hman61/js-framework-benchmark"
22+
}
23+
}
24+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export default class DooConfig {
2+
static DATA_BIND ='bind'
3+
static TEMPLATE_EXT = '.html'
4+
static COMPONENT_DIR = '/components'
5+
static NAME ='DooHTML'
6+
static TYPE = {DEFAULT:0,ENUM:1,DEEP:2,COMPUTED:3 }
7+
static MATCH = {ANY:-1,STARTS_WITH:0,EXACT:1}
8+
static DELIMITER = {'BEG':'{{','END':'}}'}
9+
static DOCUMENT = 'document'
10+
static PAGE_SIZE = 12
11+
static DATA_STORE='data-store'
12+
static DATA_KEY='data-key'
13+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import Config from './DooConfig.js'
2+
3+
4+
const DooFn = {
5+
6+
version: 'v0.96.1-beta',
7+
define: (klass, alias=null) => {
8+
let name = alias || klass.name.toLowerCase()
9+
customElements.define('doo-' + name, klass)
10+
},
11+
12+
13+
getItemValue(item, prop) {
14+
return item[prop] ? item[prop] : ''
15+
},
16+
17+
renderTable (dataSet,target=this.place[0], start=0) {
18+
let len = dataSet.length
19+
if (len === 0) {
20+
target.textContent = ''
21+
return
22+
// } else if (target.childNodes.length > len) {
23+
// target.textContent = ''
24+
}
25+
this.renderHTML(dataSet, target, start , len - start)
26+
},
27+
28+
renderHTML(data, place, start = 0, pgSize = Config.PAGE_SIZE) {
29+
let dataLen = data.length
30+
,stop = start + pgSize
31+
,newNode
32+
,curNode
33+
if (stop > dataLen) { stop = dataLen }
34+
35+
let len = place.dataSlots.length
36+
37+
const getNode = (node,arr,x) => {
38+
let i=arr[x]
39+
if (node.childNodes[i]) {
40+
return getNode(node.childNodes[i], arr, ++x)
41+
}
42+
return node
43+
}
44+
45+
const setNodeValues = (node,i) => {
46+
for (let x=0; x<len;x++) {
47+
curNode = getNode(node,place.dataSlots[x][1],0)
48+
if (curNode) {
49+
if (place.dataSlots[x][2] === 'textContent') {
50+
curNode.textContent = data[i][place.dataSlots[x][0]]
51+
} else {
52+
curNode.setAttribute(place.dataSlots[x][2], data[i][place.dataSlots[x][0]])
53+
}
54+
} else {
55+
console.info('Field:' + place.dataSlots[x][0] + ' does not exist')
56+
}
57+
}
58+
}
59+
60+
const dataKey = place.dataKey
61+
for (let i = start; i<stop; i++) {
62+
newNode = place.processNode
63+
setNodeValues(newNode, i)
64+
place.appendChild(newNode.cloneNode(true))[Config.DATA_KEY_NAME] = this.getItemValue(data[i],dataKey)
65+
}
66+
},
67+
append(dataSet, target, start=0) {
68+
this.renderHTML(dataSet, target, start , dataSet.length - start)
69+
}
70+
71+
72+
73+
74+
}
75+
76+
export default DooFn
77+
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
'use strict'
2+
3+
4+
const _random = max => Math.random() * max | 0
5+
6+
const adjectives = ["pretty", "large", "big", "small", "tall", "short", "long", "handsome", "plain", "quaint", "clean", "elegant", "easy", "angry", "crazy", "helpful", "mushy", "odd", "unsightly", "adorable", "important", "inexpensive", "cheap", "expensive", "fancy"]
7+
const colours = ["red", "yellow", "blue", "green", "pink", "brown", "purple", "brown", "white", "black", "orange"]
8+
const nouns = ["table", "chair", "house", "bbq", "desk", "car", "pony", "cookie", "sandwich", "burger", "pizza", "mouse", "keyboard"]
9+
10+
const lenA = adjectives.length, lenB = colours.length, lenC = nouns.length
11+
12+
import DooFn from './DooFn.js'
13+
14+
const DEFAULT_SIZE = 1000
15+
const DEFAULT_SIZE_RUN_LOTS = 10000
16+
const SWAP_ROW = 998
17+
const BANG = ' !!!'
18+
19+
20+
21+
Doo.define(class Main extends Doo {
22+
constructor() {
23+
super(100)
24+
this.defaultDataSet = 'rows'
25+
this.ID = 1
26+
this.data = {
27+
[this.defaultDataSet]: []
28+
}
29+
this.add = this.add.bind(this)
30+
this.run = this.run.bind(this)
31+
this.runLots = this.runLots.bind(this)
32+
this.update = this.update.bind(this)
33+
this.clear = this.clear.bind(this)
34+
this.swapRows = this.swapRows.bind(this)
35+
this.addEventListeners()
36+
this.selectedRow = undefined
37+
document.querySelector(".ver").innerHTML += ` ${Doo.version} (keyed)`
38+
document.title += ` ${Doo.version} (keyed)`
39+
}
40+
41+
async dooAfterRender() {
42+
this.tbody = document.querySelector('#tbody')
43+
this.tbody.addEventListener('click', e => {
44+
e.preventDefault()
45+
if (e.target.parentElement.matches('.remove')) {
46+
this.delete(e.target.parentElement)
47+
} else if (e.target.tagName === 'A') {
48+
this.select(e.target)
49+
}
50+
})
51+
}
52+
53+
getParentRow(elem) {
54+
while (elem) {
55+
if (elem.tagName === "TR") {return elem}
56+
elem = elem.parentNode
57+
}
58+
return undefined
59+
}
60+
61+
buildData(count = DEFAULT_SIZE) {
62+
const data = [];
63+
for (let i = 0; i < count; i++) {
64+
data.push({id: this.ID++,label: adjectives[_random(lenA)] + " " + colours[_random(lenB)] + " " + nouns[_random(lenC)]})
65+
}
66+
return data
67+
}
68+
getIndex(row) {
69+
let idx = this.data.rows.findIndex((item, i) => {
70+
if (item.id === row.key) {
71+
return i
72+
}
73+
})
74+
return idx
75+
}
76+
77+
delete(elem) {
78+
let row = this.getParentRow(elem)
79+
if (row) {
80+
this.tbody.removeChild(row)
81+
let idx = this.getIndex(row)
82+
if (idx !== undefined) {
83+
this.data.rows.splice(idx,1)
84+
}
85+
86+
}
87+
}
88+
89+
run() {
90+
this.select(undefined)
91+
if (this.data.rows.length) this.clear()
92+
this.data.rows = this.buildData()
93+
DooFn.renderTable(this.data.rows, this.tbody)
94+
}
95+
96+
add() {
97+
let start = this.data.rows.length
98+
this.data.rows = this.data.rows.concat(this.buildData())
99+
DooFn.append(this.data.rows, this.tbody, start)
100+
}
101+
102+
runLots() {
103+
this.select(undefined)
104+
if (this.data.rows.length) this.clear()
105+
this.data.rows = this.buildData(DEFAULT_SIZE_RUN_LOTS)
106+
DooFn.renderTable(this.data.rows, this.tbody)
107+
}
108+
109+
update() {
110+
const len = this.data.rows.length
111+
for (let i = 0; i < len; i += 10) {
112+
this.data.rows[i].label += BANG
113+
this.tbody.childNodes[i].querySelector('a').firstChild.nodeValue = this.data.rows[i].label
114+
}
115+
}
116+
117+
select(elem) {
118+
if (this.selectedRow) {
119+
this.selectedRow.classList.remove('danger')
120+
this.selectedRow = undefined
121+
}
122+
if (elem) {
123+
this.toggleSelect(this.getParentRow(elem))
124+
}
125+
}
126+
127+
toggleSelect(row) {
128+
if (row) {
129+
row.classList.toggle('danger')
130+
if (row.classList.contains('danger')) {
131+
this.selectedRow = row
132+
}
133+
}
134+
}
135+
136+
clear() {
137+
this.tbody.textContent = null
138+
this.data.rows = []
139+
}
140+
141+
swapRows() {
142+
if (this.data.rows.length > SWAP_ROW) {
143+
let node1 = this.tbody.firstChild.nextSibling,
144+
swapRow = this.tbody.childNodes[SWAP_ROW],
145+
node999 = swapRow.nextSibling,
146+
row1 = this.data.rows[1]
147+
148+
this.data.rows[1] = this.data.rows[SWAP_ROW];
149+
this.data.rows[SWAP_ROW] = row1
150+
151+
this.tbody.insertBefore(node1.parentNode.replaceChild(swapRow, node1), node999)
152+
}
153+
}
154+
addEventListeners() {
155+
const actions = {
156+
'run': this.run,
157+
'runlots': this.runLots,
158+
'add': this.add,
159+
'update': this.update,
160+
'clear': this.clear,
161+
'swaprows': this.swapRows,
162+
runAction: (e) => {
163+
e.preventDefault()
164+
if (actions[e.target.id]) {
165+
actions[e.target.id]()
166+
}
167+
}
168+
}
169+
document.getElementById("main").addEventListener('click', e => actions.runAction(e))
170+
}
171+
172+
async connectedCallback() {
173+
super.connectedCallback()
174+
}
175+
176+
})

0 commit comments

Comments
 (0)