git @ Cat's Eye Technologies DAM / 0.1
Merge pull request #1 from catseye/develop-0.1 Develop 0.1 Chris Pressey authored 2 years ago GitHub committed 2 years ago
15 changed file(s) with 342 addition(s) and 49 deletion(s). Raw diff Collapse all Expand all
88 ------------
99
1010 **DAM** is a tiny library for creating bits of an HTML5 document.
11 (I'd say "for creating UIs" but that may be overstating it a tad.)
12 It's written in ES5 Javascript (so it can be used directly by most
13 modern web browsers) and it's about 1K in size (uncompressed).
11 (I'd say "for creating user interfaces" but that may be overstating
12 it a tad.) It's written in ES5 Javascript, so it can be used directly
13 by most modern web browsers, or it can be transpiled to ES6 in a
14 frontend build process. It's about 1K in size (uncompressed), and it
15 comes with a "standard widget library" that bloats it to about 6K.
1416
15 *NOTE: this is version 0.0: everything is subject to change*
17 The current version of DAM is 0.1.
1618
1719 Basic usage
1820 -----------
1921
20 Basically you can use it like this:
22 If you want to just drop DAM's basic functionality into a web page,
23 you can use it like this:
2124
2225 <script src="dam.js"></script>
2326 <script>
3033 );
3134 document.getElementById('container').appendChild(d);
3235 </script>
36
37 (You can also import DAM as an ES6 module in a frontend build process.
38 See the [demo/es6build/](demo/es6build/) directory of this repository
39 for an example of this.)
3340
3441 `DAM.maker` is a function that takes a tag string and returns a function that
3542 creates and returns a DOM Element with that tag.
101108 * [Select widget](demo/select.html)
102109 * [Range widget](demo/range.html)
103110
111 Unlike the other files, `dam-widgets.js` is written in ES6. If you want to
112 use it in an ES6 project, you can, for example,
113
114 import DAM from "./dam.js"
115 import { makeCheckbox, makePanel } from "./dam-widgets.js"
116
117 However, you're not required to do this. If you just want an ES5 file that
118 you can drop onto a web page, DAM ships with `dam-plus-widgets-web.js` for
119 this purpose. Just:
120
121 <script src="dam-plus-widgets-web.js"></script>
122
123 and then you will have `DAM` as well as all the standard widget makers (nested
124 under `DAM`) at your fingertips.
125
104126 ### Advanced widget creation
105127
106128 The function returned by `DAM.maker` is simply `DAM.makeElem` with some
1111
1212 <div id="installation"></div>
1313
14 <script src="../src/dam.js"></script>
15 <script src="../src/dam-widgets.js"></script>
14 <script src="../src/dam-plus-widgets-web.js"></script>
1615 <script>
1716 var div=DAM.maker('div'), span=DAM.maker('span');
1817 var understood = false;
0 node_modules/
1 package-lock.json
2 demo/*.js
0 <!DOCTYPE html>
1 <head>
2 <meta charset="utf-8">
3 <title>Zlerp</title>
4 </head>
5 <body>
6
7 <h1>Zlerp</h1>
8
9 <div id="zlerp"></div>
10
11 <script src="zlerp.js"></script>
12
13 </body>
0 {
1 "name": "zlerp",
2 "version": "0.1.0",
3 "description": "Demonstration of using DAM in an ES6 project transpiled to ES5 with Browserify and Babel.",
4 "scripts": {
5 "build:dev": "browserify src/index.js -t [ babelify --presets [ @babel/preset-env ] ] > demo/zlerp.js",
6 "build": "browserify src/index.js -t [ babelify --presets [ @babel/preset-env ] ] -g [ envify --NODE_ENV production ] -g uglifyify | terser --compress --mangle | uglifyjs > demo/zlerp.js"
7 },
8 "devDependencies": {
9 "@babel/core": "^7.5.4",
10 "@babel/preset-env": "^7.5.4",
11 "babelify": "^10.0.0",
12 "browserify": "^16.3.0",
13 "envify": "^4.1.0",
14 "terser": "^4.1.2",
15 "uglify-js": "^3.6.0",
16 "uglifyify": "^5.0.1"
17 }
18 }
0 ../../../src/
0 import DAM from './DAM/dam.js'
1 import { makePanel, makeCheckbox } from './DAM/dam-widgets.js'
2
3
4 const div = DAM.maker('div')
5
6 document.getElementById('zlerp').appendChild(
7 div(
8 {style: "border: 1px solid blue"},
9 makePanel(
10 { title: "Options", isOpen: false },
11 makeCheckbox({ onchange: function(b) { console.log('understood:' + b) } }, "I understand"),
12 makeCheckbox({ onchange: function(b) { console.log('great:' + b) } }, "It's great")
13 )
14 )
15 )
1414 <div id="installation"></div>
1515
1616 <script src="../src/dam.js"></script>
17 <script src="../src/dam-widgets.js"></script>
1817 <script>
1918 var div=DAM.maker("div"), p=DAM.maker("p"), span=DAM.maker("span"), button=DAM.maker("button"),
2019 canvas=DAM.maker("canvas"), label=DAM.maker("label"), br=DAM.maker("br"), input=DAM.maker("input"),
2323
2424 <div id="installation"></div>
2525
26 <script src="../src/dam.js"></script>
27 <script src="../src/dam-widgets.js"></script>
26 <script src="../src/dam-plus-widgets-web.js"></script>
2827 <script>
2928 var div=DAM.maker("div"), p=DAM.maker("p"), span=DAM.maker("span"), button=DAM.maker("button");
3029 var statusBar = span();
1111
1212 <div id="installation"></div>
1313
14 <script src="../src/dam.js"></script>
15 <script src="../src/dam-widgets.js"></script>
14 <script src="../src/dam-plus-widgets-web.js"></script>
1615 <script>
1716 var div=DAM.maker("div"), p=DAM.maker("p"), span=DAM.maker("span"), button=DAM.maker("button");
1817 document.getElementById('installation').appendChild(
1111
1212 <div id="installation"></div>
1313
14 <script src="../src/dam.js"></script>
15 <script src="../src/dam-widgets.js"></script>
14 <script src="../src/dam-plus-widgets-web.js"></script>
1615 <script>
1716 var div=DAM.maker("div"), p=DAM.maker("p"), span=DAM.maker("span"), button=DAM.maker("button");
1817 document.getElementById('installation').appendChild(
1313
1414 <div id="installation"></div>
1515
16 <script src="../src/dam.js"></script>
17 <script src="../src/dam-widgets.js"></script>
16 <script src="../src/dam-plus-widgets-web.js"></script>
1817
1918 <script>var module = {};</script>
2019 <script src="https://unpkg.com/storeon@0.8.2/index.js"></script>
0 /* dam-plus-widgets-web.js version 0.1. This file is in the public domain. */
1
2 /* This file is recommended if you just want to use DAM and its standard
3 widget library on an HTML page without bothering with JS build stuff.
4 It consists of dam.js followed by dam-widgets.js, both with only small
5 hand modifications to make them load as-is in ES5. */
6
7 var DAM = (function() {
8 var DAM = {};
9 DAM.makeElem = function(tag, args) {
10 args = args || [];
11 var elem = document.createElement(tag);
12 for (var i = 0; i < args.length; i++) {
13 var arg = args[i];
14 if (arg instanceof Element) {
15 elem.appendChild(arg);
16 } else if (typeof arg === 'string' || arg instanceof String) {
17 elem.appendChild(document.createTextNode(arg));
18 } else if (typeof arg === 'object' && arg !== null) {
19 Object.keys(arg).forEach(function(key) {
20 if (key.substring(0, 2) === 'on') {
21 elem.addEventListener(key.substring(2), arg[key]);
22 } else if (arg[key] === null) {
23 elem.removeAttribute(key);
24 } else {
25 elem.setAttribute(key, arg[key]);
26 }
27 });
28 } else {
29 console.log(arg);
30 }
31 }
32 return elem;
33 };
34 DAM.maker = function(tag) {
35 return function() {
36 return DAM.makeElem(tag, arguments);
37 };
38 };
39 return DAM;
40 })();
41
42 (function(DAM) { // ENTER-SCOPE
43
44 /*
45 * A labelled checkbox, where the checkbox appears to the left of the label.
46 * Arguments after the first (config) argument will be applied to the label element.
47 */
48 DAM.makeCheckbox = function(config) {
49 if (typeof DAM.makeCheckboxCounter === 'undefined') DAM.makeCheckboxCounter = 0;
50 var checkboxId = 'cfzzzb_' + (DAM.makeCheckboxCounter++);
51
52 var onchange = config.onchange || function(b) {};
53
54 // config label: make copy of arguments, replace first with a bespoke config
55 var args = new Array(arguments.length);
56 for(var i = 0; i < args.length; ++i) {
57 args[i] = arguments[i];
58 }
59 args[0] = { 'for': checkboxId, 'class': "dam-widget dam-checkbox" }
60
61 return DAM.makeElem('span', [
62 DAM.makeElem('input', [
63 {
64 type: 'checkbox',
65 id: checkboxId,
66 onchange: function(e) {
67 onchange(e.target.checked);
68 }
69 },
70 config.checkboxAttrs || {}
71 ]),
72 DAM.makeElem('label', args)
73 ]);
74 };
75
76 /*
77 * A collapsible panel.
78 * Arguments after the first (config) argument will be applied to the inner container div element.
79 */
80 DAM.makePanel = function(config) {
81 var isOpen = !!(config.isOpen);
82 var title = config.title || "";
83
84 function getLabel() {
85 return (isOpen ? "∇" : "⊳") + " " + title;
86 }
87
88 // config inner container
89 var args = new Array(arguments.length);
90 for(var i = 0; i < args.length; ++i) {
91 args[i] = arguments[i];
92 }
93 args[0] = {}
94
95 var innerContainer = DAM.makeElem('div', args);
96 innerContainer.style.display = isOpen ? "block" : "none";
97
98 var button = DAM.makeElem('button', [
99 getLabel(),
100 {
101 onclick: function(e) {
102 isOpen = !isOpen;
103 button.textContent = getLabel();
104 innerContainer.style.display = isOpen ? "block" : "none";
105 }
106 }
107 ]);
108
109 return DAM.makeElem("div", [{ 'class': "dam-widget dam-panel" }, button, innerContainer]);
110 };
111
112 /*
113 * A select dropdown.
114 */
115 DAM.makeSelect = function(config) {
116 var title = config.title || "";
117 var options = config.options || [];
118 var onchange = config.onchange || function(v) {};
119
120 var select = DAM.makeElem('select');
121 for (var i = 0; i < options.length; i++) {
122 var op = DAM.makeElem('option');
123 op.value = options[i].value;
124 op.text = options[i].text;
125 op.selected = !!(options[i].selected);
126 select.options.add(op);
127 }
128 select.addEventListener('change', function(e) {
129 onchange(options[select.selectedIndex]);
130 });
131 return DAM.makeElem('label', [{ 'class': "dam-widget dam-select" }, title, select]);
132 };
133
134 /*
135 * A range control.
136 */
137 DAM.makeRange = function(config) {
138 var title = config.title || "";
139 var min_ = config['min'];
140 var max_ = config['max'];
141 var value = config.value || min_;
142 var onchange = config.onchange || function(v) {};
143 var textInputSize = config.textInputSize || 5;
144
145 var textInput; var slider;
146
147 slider = DAM.makeElem('input', [
148 {
149 type: "range", min: min_, max: max_, value: value,
150 onchange: function(e) {
151 var v = parseInt(slider.value, 10);
152 if (!isNaN(v)) {
153 textInput.value = "" + v;
154 onchange(v);
155 }
156 }
157 }
158 ]);
159
160 textInput = DAM.makeElem('input', [
161 {
162 size: "" + textInputSize,
163 value: "" + value,
164 onchange: function(e) {
165 var v = parseInt(textInput.value, 10);
166 if (!isNaN(v) && v >= min_ && v <= max_) {
167 slider.value = "" + v;
168 onchange(v);
169 }
170 }
171 }
172 ]);
173
174 var incButton = DAM.makeElem('button', ['+',
175 {
176 onclick: function(e) {
177 var v = parseInt(textInput.value, 10);
178 if ((!isNaN(v)) && v < max_) {
179 v++;
180 textInput.value = "" + v;
181 slider.value = "" + v;
182 onchange(v);
183 }
184 }
185 }
186 ]);
187
188 var decButton = DAM.makeElem('button', ['-',
189 {
190 onclick: function(e) {
191 var v = parseInt(textInput.value, 10);
192 if ((!isNaN(v)) && v > min_) {
193 v--;
194 textInput.value = "" + v;
195 slider.value = "" + v;
196 onchange(v);
197 }
198 }
199 }
200 ]);
201
202 return DAM.makeElem('span', [{ 'class': "dam-widget dam-range" }, DAM.makeElem('label', [title, slider]), textInput, decButton, incButton]);
203 };
204
205 })(DAM); // EXIT-SCOPE
206
207 if (typeof module !== 'undefined') module.exports = DAM;
0 /* dam-widgets.js version 0.0. This file is in the public domain. */
0 /* dam-widgets.js version 0.1. This file is in the public domain. */
11
2 /* dam.js should be included before this source. */
2 /* if you want to use this file in an ES5 context, either remove the following line
3 and ensure dam.js has already been loaded, or just use `dam-plus-widgets-web.js`
4 instead of this file, it's probably easier to do that, just do that instead. */
5
6 import DAM from './dam.js'
7
8 (function(DAM) { // ENTER-SCOPE
39
410 /*
511 * A labelled checkbox, where the checkbox appears to the left of the label.
161167
162168 return DAM.makeElem('span', [{ 'class': "dam-widget dam-range" }, DAM.makeElem('label', [title, slider]), textInput, decButton, incButton]);
163169 };
170
171 })(DAM); // EXIT-SCOPE
172
173 if (typeof module !== 'undefined') module.exports = DAM;
0 /* dam.js version 0.0. This file is in the public domain. */
0 /* dam.js version 0.1. This file is in the public domain. */
11
2 if (typeof window === 'undefined' || window.DAM === undefined) DAM = {};
3
4 DAM.makeElem = function(tag, args) {
5 args = args || [];
6 var elem = document.createElement(tag);
7 for (var i = 0; i < args.length; i++) {
8 var arg = args[i];
9 if (arg instanceof Element) {
10 elem.appendChild(arg);
11 } else if (typeof arg === 'string' || arg instanceof String) {
12 elem.appendChild(document.createTextNode(arg));
13 } else if (typeof arg === 'object' && arg !== null) {
14 Object.keys(arg).forEach(function(key) {
15 if (key.substring(0, 2) === 'on') {
16 elem.addEventListener(key.substring(2), arg[key]);
17 } else if (arg[key] === null) {
18 elem.removeAttribute(key);
19 } else {
20 elem.setAttribute(key, arg[key]);
21 }
22 });
23 } else {
24 console.log(arg);
2 (function() {
3 var DAM = {};
4 DAM.makeElem = function(tag, args) {
5 args = args || [];
6 var elem = document.createElement(tag);
7 for (var i = 0; i < args.length; i++) {
8 var arg = args[i];
9 if (arg instanceof Element) {
10 elem.appendChild(arg);
11 } else if (typeof arg === 'string' || arg instanceof String) {
12 elem.appendChild(document.createTextNode(arg));
13 } else if (typeof arg === 'object' && arg !== null) {
14 Object.keys(arg).forEach(function(key) {
15 if (key.substring(0, 2) === 'on') {
16 elem.addEventListener(key.substring(2), arg[key]);
17 } else if (arg[key] === null) {
18 elem.removeAttribute(key);
19 } else {
20 elem.setAttribute(key, arg[key]);
21 }
22 });
23 } else {
24 console.log(arg);
25 }
2526 }
27 return elem;
28 };
29 DAM.maker = function(tag) {
30 return function() {
31 return DAM.makeElem(tag, arguments);
32 };
33 };
34 if (typeof module !== 'undefined') {
35 module.exports = DAM;
36 } else if (typeof window !== 'undefined') {
37 window.DAM = DAM;
2638 }
27 return elem;
28 };
29 DAM.maker = function(tag) {
30 return function() {
31 return DAM.makeElem(tag, arguments);
32 };
33 };
39 })();