git @ Cat's Eye Technologies DAM / develop-0.2
For version 0.2, build dist/dam-plus-widgets-web.js from src. Chris Pressey 1 year, 3 days ago
12 changed file(s) with 103 addition(s) and 231 deletion(s). Raw diff Collapse all Expand all
0 node_modules/
1 package-lock.json
1010 **DAM** is a tiny library for creating bits of an HTML5 document.
1111 (I'd say "for creating user interfaces" but that may be overstating
1212 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
13 by most modern web browsers, or it can included as part of a modern
1414 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.
15 ships along with a "standard widget library" that bloats it to about 6K.
1616
17 The current version of DAM is 0.1.
17 The current version of DAM is 0.2.
1818
1919 Basic usage
2020 -----------
2121
22 If you want to just drop DAM's basic functionality into a web page,
23 you can use it like this:
22 The simplest way to use DAM is to simply load it directly on a web page,
23 which will work for most modern browsers, and to use it like so:
2424
2525 <script src="dam.js"></script>
2626 <script>
3333 );
3434 document.getElementById('container').appendChild(d);
3535 </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.)
4036
4137 `DAM.maker` is a function that takes a tag string and returns a function that
4238 creates and returns a DOM Element with that tag.
115111 import { makeCheckbox, makePanel } from "./dam-widgets.js"
116112
117113 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
114 you can load in a web page, DAM ships with `dist/dam-plus-widgets-web.js` for
119115 this purpose. Just:
120116
121117 <script src="dam-plus-widgets-web.js"></script>
122118
123119 and then you will have `DAM` as well as all the standard widget makers (nested
124120 under `DAM`) at your fingertips.
121
122 Note that, for convenience, `dist/dam-plus-widgets-web.js` is built from
123 `src/dam-plus-widgets-web.js`, and minified for production, with some node.js
124 tooling (browserify and so forth) defined in the `package.json` in this repo.
125 But in a pinch, it could easily be constructed by hand from the files
126 `src/dam.js` and `src/dam-widgets.js`.
125127
126128 ### Advanced widget creation
127129
141143 * [Cyclobots](https://catseye.tc/installation/Cyclobots)
142144 * [Chzrxl](https://catseye.tc/installation/Chzrxl)
143145 * [Maze Clouds](https://catseye.tc/installation/Maze_Clouds)
146 * [Erratic Turtle Graphics](https://catseye.tc/installation/Erratic_Turtle_Graphics)
147 * [Latcarf](https://catseye.tc/installation/Latcarf)
144148
145149 Related work
146150 ------------
1111
1212 <div id="installation"></div>
1313
14 <script src="../src/dam-plus-widgets-web.js"></script>
14 <script src="../dist/dam-plus-widgets-web.js"></script>
1515 <script>
1616 var div=DAM.maker('div'), span=DAM.maker('span');
1717 var understood = false;
2323
2424 <div id="installation"></div>
2525
26 <script src="../src/dam-plus-widgets-web.js"></script>
26 <script src="../dist/dam-plus-widgets-web.js"></script>
2727 <script>
2828 var div=DAM.maker("div"), p=DAM.maker("p"), span=DAM.maker("span"), button=DAM.maker("button");
2929 var statusBar = span();
1111
1212 <div id="installation"></div>
1313
14 <script src="../src/dam-plus-widgets-web.js"></script>
14 <script src="../dist/dam-plus-widgets-web.js"></script>
1515 <script>
1616 var div=DAM.maker("div"), p=DAM.maker("p"), span=DAM.maker("span"), button=DAM.maker("button");
1717 document.getElementById('installation').appendChild(
1111
1212 <div id="installation"></div>
1313
14 <script src="../src/dam-plus-widgets-web.js"></script>
14 <script src="../dist/dam-plus-widgets-web.js"></script>
1515 <script>
1616 var div=DAM.maker("div"), p=DAM.maker("p"), span=DAM.maker("span"), button=DAM.maker("button");
1717 document.getElementById('installation').appendChild(
1313
1414 <div id="installation"></div>
1515
16 <script src="../src/dam-plus-widgets-web.js"></script>
16 <script src="../dist/dam-plus-widgets-web.js"></script>
1717
1818 <script>var module = {};</script>
1919 <script src="https://unpkg.com/storeon@0.8.2/index.js"></script>
0 !function e(t,n,a){function o(u,r){if(!n[u]){if(!t[u]){var i="function"==typeof require&&require;if(!r&&i)return i(u,!0);if(l)return l(u,!0);var c=new Error("Cannot find module '"+u+"'");throw c.code="MODULE_NOT_FOUND",c}var f=n[u]={exports:{}};t[u][0].call(f.exports,function(e){return o(t[u][1][e]||e)},f,f.exports,e,t,n,a)}return n[u].exports}for(var l="function"==typeof require&&require,u=0;u<a.length;u++)o(a[u]);return o}({1:[function(e,t,n){"use strict";var a,o=(a=e("./dam.js"))&&a.__esModule?a:{default:a},l=e("./dam-widgets.js");window.DAM=o.default,o.default.makeCheckbox=l.makeCheckbox,o.default.makePanel=l.makePanel,o.default.makeSelect=l.makeSelect,o.default.makeRange=l.makeRange},{"./dam-widgets.js":2,"./dam.js":3}],2:[function(e,t,n){"use strict";var a,o=(a=e("./dam.js"))&&a.__esModule?a:{default:a};void 0!==t&&(t.exports={makeCheckbox:function(e){void 0===o.default.makeCheckboxCounter&&(o.default.makeCheckboxCounter=0);for(var t="cfzzzb_"+o.default.makeCheckboxCounter++,n=e.onchange||function(e){},a=new Array(arguments.length),l=0;l<a.length;++l)a[l]=arguments[l];return a[0]={for:t,class:"dam-widget dam-checkbox"},o.default.makeElem("span",[o.default.makeElem("input",[{type:"checkbox",id:t,onchange:function(e){n(e.target.checked)}},e.checkboxAttrs||{}]),o.default.makeElem("label",a)])},makePanel:function(e){var t=!!e.isOpen,n=e.title||"";function a(){return(t?"∇":"⊳")+" "+n}for(var l=new Array(arguments.length),u=0;u<l.length;++u)l[u]=arguments[u];l[0]={};var r=o.default.makeElem("div",l);r.style.display=t?"block":"none";var i=o.default.makeElem("button",[a(),{onclick:function(e){t=!t,i.textContent=a(),r.style.display=t?"block":"none"}}]);return o.default.makeElem("div",[{class:"dam-widget dam-panel"},i,r])},makeSelect:function(e){for(var t=e.title||"",n=e.options||[],a=e.onchange||function(e){},l=o.default.makeElem("select"),u=0;u<n.length;u++){var r=o.default.makeElem("option");r.value=n[u].value,r.text=n[u].text,r.selected=!!n[u].selected,l.options.add(r)}return l.addEventListener("change",function(e){a(n[l.selectedIndex])}),o.default.makeElem("label",[{class:"dam-widget dam-select"},t,l])},makeRange:function(e){var t,n,a=e.title||"",l=e.min,u=e.max,r=e.value||l,i=e.onchange||function(e){},c=e.textInputSize||5;n=o.default.makeElem("input",[{type:"range",min:l,max:u,value:r,onchange:function(e){var a=parseInt(n.value,10);isNaN(a)||(t.value=""+a,i(a))}}]),t=o.default.makeElem("input",[{size:""+c,value:""+r,onchange:function(e){var a=parseInt(t.value,10);!isNaN(a)&&a>=l&&a<=u&&(n.value=""+a,i(a))}}]);var f=o.default.makeElem("button",["+",{onclick:function(e){var a=parseInt(t.value,10);!isNaN(a)&&a<u&&(a++,t.value=""+a,n.value=""+a,i(a))}}]),d=o.default.makeElem("button",["-",{onclick:function(e){var a=parseInt(t.value,10);!isNaN(a)&&a>l&&(a--,t.value=""+a,n.value=""+a,i(a))}}]);return o.default.makeElem("span",[{class:"dam-widget dam-range"},o.default.makeElem("label",[a,n]),t,d,f])}})},{"./dam.js":3}],3:[function(e,t,n){"use strict";function a(e){return(a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var o;o={makeElem:function(e,t){t=t||[];for(var n=document.createElement(e),o=0;o<t.length;o++){var l=t[o];l instanceof Element?n.appendChild(l):"string"==typeof l||l instanceof String?n.appendChild(document.createTextNode(l)):"object"===a(l)&&null!==l?Object.keys(l).forEach(function(e){"on"===e.substring(0,2)?n.addEventListener(e.substring(2),l[e]):null===l[e]?n.removeAttribute(e):n.setAttribute(e,l[e])}):console.log(l)}return n},maker:function(e){return function(){return o.makeElem(e,arguments)}}},void 0!==t?t.exports=o:"undefined"!=typeof window&&(window.DAM=o)},{}]},{},[1]);
0 /* dam.js version 0.1. This file is in the public domain. */
1
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 }
26 }
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;
38 }
39 })();
0 {
1 "name": "catseye-DAM",
2 "version": "0.2.0",
3 "description": "You've tried the Document Object Model, now try the Document *Awesome* Model",
4 "repository": "https://github.com/catseye/DAM.git",
5 "license": "UNLICENSE",
6 "scripts": {
7 "build:dam": "mkdir -p dist && cp src/dam.js dist/dam.js",
8 "build:dam-plus-widgets-web": "mkdir -p dist && browserify src/dam-plus-widgets-web.js -t [ babelify --presets [ @babel/preset-env ] ] -g [ envify --NODE_ENV production ] -g uglifyify | terser --compress --mangle | uglifyjs > dist/dam-plus-widgets-web.js",
9 "build:all": "npm run build:dam && npm run build:dam-plus-widgets-web"
10 },
11 "devDependencies": {
12 "@babel/core": "^7.5.4",
13 "@babel/preset-env": "^7.5.4",
14 "babelify": "^10.0.0",
15 "browserify": "^16.3.0",
16 "envify": "^4.1.0",
17 "terser": "^4.1.2",
18 "uglify-js": "^3.6.0",
19 "uglifyify": "^5.0.1"
20 }
21 }
0 /* dam-plus-widgets-web.js version 0.1. This file is in the public domain. */
0 /* dam-plus-widgets-web.js version 0.2. This file is in the public domain. */
11
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. */
2 import DAM from './dam.js'
3 import { makeCheckbox, makePanel, makeSelect, makeRange} from './dam-widgets.js'
64
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;
5 window.DAM = DAM;
6 DAM.makeCheckbox = makeCheckbox;
7 DAM.makePanel = makePanel;
8 DAM.makeSelect = makeSelect;
9 DAM.makeRange = makeRange;
0 /* dam-widgets.js version 0.1. This file is in the public domain. */
0 /* dam-widgets.js version 0.2. This file is in the public domain. */
11
22 /* if you want to use this file in an ES5 context, either remove the following line
33 and ensure dam.js has already been loaded, or just use `dam-plus-widgets-web.js`
55
66 import DAM from './dam.js'
77
8 (function(DAM) { // ENTER-SCOPE
9
108 /*
119 * A labelled checkbox, where the checkbox appears to the left of the label.
1210 * Arguments after the first (config) argument will be applied to the label element.
1311 */
14 DAM.makeCheckbox = function(config) {
12 function makeCheckbox(config) {
1513 if (typeof DAM.makeCheckboxCounter === 'undefined') DAM.makeCheckboxCounter = 0;
1614 var checkboxId = 'cfzzzb_' + (DAM.makeCheckboxCounter++);
1715
4341 * A collapsible panel.
4442 * Arguments after the first (config) argument will be applied to the inner container div element.
4543 */
46 DAM.makePanel = function(config) {
44 function makePanel(config) {
4745 var isOpen = !!(config.isOpen);
4846 var title = config.title || "";
4947
7876 /*
7977 * A select dropdown.
8078 */
81 DAM.makeSelect = function(config) {
79 function makeSelect(config) {
8280 var title = config.title || "";
8381 var options = config.options || [];
8482 var onchange = config.onchange || function(v) {};
10098 /*
10199 * A range control.
102100 */
103 DAM.makeRange = function(config) {
101 function makeRange(config) {
104102 var title = config.title || "";
105103 var min_ = config['min'];
106104 var max_ = config['max'];
168166 return DAM.makeElem('span', [{ 'class': "dam-widget dam-range" }, DAM.makeElem('label', [title, slider]), textInput, decButton, incButton]);
169167 };
170168
171 })(DAM); // EXIT-SCOPE
172
173 if (typeof module !== 'undefined') module.exports = DAM;
169 if (typeof module !== 'undefined') module.exports = {
170 'makeCheckbox': makeCheckbox,
171 'makePanel': makePanel,
172 'makeSelect': makeSelect,
173 'makeRange': makeRange
174 };