- commit
- 7eba03f70b04c8feb854d0fc3f1bf5824881f6a2
- parent
- f4287dfb6c4aa08e899947fa2611444db635d893
- Author
- Tobias Bengfort <tobias.bengfort@gmx.net>
- Date
- 2015-08-28 09:06
change dist layout - dist files are in dist/ - minification is done by closure compiler instead of uglify.js - UML instead of pure AMD - only the muu module is made available
Diffstat
| A | .build/externs.js | 13 | +++++++++++++ |
| A | .build/template.js | 45 | +++++++++++++++++++++++++++++++++++++++++++++ |
| M | Makefile | 29 | +++++++++++++++++++++++++---- |
| D | build.js | 8 | -------- |
| A | dist/muu.js | 1244 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | dist/muu.min.js | 19 | +++++++++++++++++++ |
| M | examples/example/example.js | 8 | ++++---- |
| M | examples/example/index.html | 1 | - |
| M | examples/phonecat/index.html | 1 | - |
| M | examples/phonecat/phonecat.js | 4 | ++-- |
| D | muu.min.js | 3 | --- |
| D | muu.min.js.map | 2 | -- |
12 files changed, 1352 insertions, 25 deletions
diff --git a/.build/externs.js b/.build/externs.js
@@ -0,0 +1,13 @@
-1 1 /** @type {Object} */
-1 2 var history;
-1 3
-1 4 /**
-1 5 * @param {string} name
-1 6 * @param {Array.<string>} deps
-1 7 * @param {Function} factory
-1 8 * @return {*}
-1 9 */
-1 10 var define = function(name, deps, factory) {};
-1 11
-1 12 /** @type {boolean} */
-1 13 define.amd = false;
diff --git a/.build/template.js b/.build/template.js
@@ -0,0 +1,45 @@
-1 1 (function(window, document, undefined) {
-1 2 var name = 'muu';
-1 3
-1 4 (function(factory) {
-1 5 if (typeof define === 'function' && define.amd) {
-1 6 define(name, ['lodash'], factory);
-1 7 } else {
-1 8 window[name] = factory(_);
-1 9 }
-1 10 })(function() {
-1 11 var modules = {};
-1 12
-1 13 var map = function(a, fn) {
-1 14 var b = [];
-1 15 for (var i = 0; i < a.length; i++) {
-1 16 b.push(fn(a[i]));
-1 17 }
-1 18 return b;
-1 19 };
-1 20
-1 21 var _define = function(name, deps, factory) {
-1 22 modules[name] = {
-1 23 deps: deps,
-1 24 factory: factory
-1 25 };
-1 26 };
-1 27
-1 28 var _require = function(name) {
-1 29 if (!modules[name]) {
-1 30 return undefined;
-1 31 }
-1 32
-1 33 if (!modules[name].instance) {
-1 34 var deps = modules[name].deps;
-1 35 var factory = modules[name].factory;
-1 36
-1 37 modules[name].instance = factory.apply(undefined, map(deps, _require));
-1 38 }
-1 39
-1 40 return modules[name].instance;
-1 41 };
-1 42
-1 43 return _require(name);
-1 44 });
-1 45 })(window, document, void 0);
diff --git a/Makefile b/Makefile
@@ -1,13 +1,34 @@1 -1 muu.min.js: build.js src/*.js node_modules/requirejs/bin/r.js2 -1 ./node_modules/requirejs/bin/r.js -o build.js-1 1 dist/muu.min.js: dist/muu.js node_modules/closure-compiler-jar/compiler.jar .build/externs.js -1 2 java -jar node_modules/closure-compiler-jar/compiler.jar \ -1 3 --compilation_level SIMPLE_OPTIMIZATIONS \ -1 4 --use_types_for_optimization \ -1 5 --warning_level=VERBOSE \ -1 6 --jscomp_warning=missingProperties \ -1 7 --jscomp_warning=checkTypes \ -1 8 --externs .build/externs.js \ -1 9 --js $< \ -1 10 --js_output_file $@ -1 11 -1 12 dist/muu.js: .build/template.js src/*.js -1 13 mkdir -p dist -1 14 head -n -3 $< > .build/head.js -1 15 tail -n 4 $< > .build/tail.js -1 16 cat src/*.js |\ -1 17 sed 's/^/ /g' |\ -1 18 sed 's/ *$$//g' |\ -1 19 sed 's/define(/_define(/g' > .build/modules.js -1 20 cat .build/head.js .build/modules.js .build/tail.js > $@ -1 21 rm .build/head.js -1 22 rm .build/tail.js -1 23 rm .build/modules.js 3 24 4 25 doc: doc/.touch 5 26 6 27 doc/.touch: src/*.js node_modules/jsdoc/jsdoc.js .doc/conf.json .doc/styles/* .doc/tutorials/*.md bower.json README.md 7 28 ./node_modules/jsdoc/jsdoc.js --pedantic --package bower.json -u .doc/tutorials -c .doc/conf.json README.md src/*.js && touch doc/.touch 8 299 -1 node_modules/requirejs/bin/r.js:10 -1 npm install requirejs-1 30 node_modules/closure-compiler-jar/compiler.jar: -1 31 npm install closure-compiler-jar 11 32 12 33 node_modules/jsdoc/jsdoc.js: 13 34 npm install jsdoc
diff --git a/build.js b/build.js
@@ -1,8 +0,0 @@1 -1 ({2 -1 "baseUrl": "src",3 -1 "optimize": "uglify2",4 -1 "generateSourceMaps": true,5 -1 "preserveLicenseComments": false,6 -1 "name": "muu",7 -1 "out": "muu.min.js"8 -1 })
diff --git a/dist/muu.js b/dist/muu.js
@@ -0,0 +1,1244 @@
-1 1 (function(window, document, undefined) {
-1 2 (function(factory) {
-1 3 if (typeof define === 'function' && define.amd) {
-1 4 define('muu', [], factory);
-1 5 } else {
-1 6 window['muu'] = factory();
-1 7 }
-1 8 })(function() {
-1 9 var modules = {};
-1 10
-1 11 var map = function(a, fn) {
-1 12 var b = [];
-1 13 for (var i = 0; i < a.length; i++) {
-1 14 b.push(fn(a[i]));
-1 15 }
-1 16 return b;
-1 17 };
-1 18
-1 19 var _define = function(name, deps, factory) {
-1 20 modules[name] = {
-1 21 deps: deps,
-1 22 factory: factory
-1 23 };
-1 24 };
-1 25
-1 26 var _require = function(name) {
-1 27 if (!modules[name]) {
-1 28 return undefined;
-1 29 }
-1 30
-1 31 if (!modules[name].instance) {
-1 32 var deps = modules[name].deps;
-1 33 var factory = modules[name].factory;
-1 34
-1 35 modules[name].instance = factory.apply(undefined, map(deps, _require));
-1 36 }
-1 37
-1 38 return modules[name].instance;
-1 39 };
-1 40
-1 41 /**
-1 42 * Exports the {@link Directive} class.
-1 43 * @module muu-directive
-1 44 * @ignore
-1 45 */
-1 46 _define('muu-directive', ['muu-dom-helpers', 'muu-js-helpers', 'muu-update-dom'], function($, _, updateDOM) {
-1 47 "use strict";
-1 48
-1 49 /**
-1 50 * A directive is linked to a Element and manages the DOM tree below
-1 51 * that element (excluding any isolated subtrees, e.g. those managed by
-1 52 * subdirectives).
-1 53 *
-1 54 * It provides a set of methods to interact with the managed part of the
-1 55 * DOM. This is separated into three distinct parts:
-1 56 *
-1 57 * - You can push data to the DOM using the {@link Directive#update}
-1 58 * method. The DOM will than be updated using the template that was
-1 59 * provided at construction.
-1 60 * - You can get data from the DOM using the {@link Directive#getModel}
-1 61 * method. This is however restricted to form field by design.
-1 62 * - You can react to DOM events by specifying an alias for them. In the
-1 63 * template, you might for example add the attribute
-1 64 * `data-onclick="custom"` to an element. When there is `click` event on
-1 65 * that element, a `muu-custom` event will be triggered on the
-1 66 * directive's root element.
-1 67 *
-1 68 * Directives are typically not created directly but via {@link
-1 69 * Registry#link}.
-1 70 *
-1 71 * @constructs Directive
-1 72 * @param {Element} root
-1 73 * @param {string} template
-1 74 * @param {Registry} registry
-1 75 */
-1 76 var Directive = function(root, template, registry) {
-1 77 var self = this;
-1 78
-1 79 root.innerHTML = '';
-1 80
-1 81 var eventCallback = function(originalEvent) {
-1 82 var attrName = 'data-on' + originalEvent.type;
-1 83 if (originalEvent.target.hasAttribute(attrName)) {
-1 84 var eventName = originalEvent.target.getAttribute(attrName);
-1 85 var event = $.createEvent('muu-' + eventName, originalEvent);
-1 86 root.dispatchEvent(event);
-1 87 }
-1 88 };
-1 89
-1 90 /**
-1 91 * Rerender `template` with `data` and push the changes to the DOM.
-1 92 *
-1 93 * @param {Object.<string, *>} data
-1 94 * @see {@link module:muu-update-dom} for details.
-1 95 * @see The templating system can be defined in the {@link Registry}.
-1 96 */
-1 97 this.update = function(data) {
-1 98 var tmp = document.createElement('div');
-1 99 tmp.innerHTML = registry.renderer(template, data);
-1 100
-1 101 updateDOM(root, tmp);
-1 102
-1 103 _.forEach(['keydown', 'keyup', 'click', 'change', 'search'], function(eventType) {
-1 104 var selector = '[data-on' + eventType + ']';
-1 105 _.forEach(self.querySelectorAll(selector), function(element) {
-1 106 element.addEventListener(eventType, eventCallback, false);
-1 107 });
-1 108 });
-1 109
-1 110 var updateEvent = $.createEvent('muu-parent-update');
-1 111 var subDirectives = this.querySelectorAll('muu.muu-initialised');
-1 112 _.forEach(subDirectives, function(element) {
-1 113 element.dispatchEvent(updateEvent);
-1 114 });
-1 115
-1 116 registry.linkAll(self);
-1 117 };
-1 118
-1 119 /**
-1 120 * A variant of `querySelectorAll` that returns only elements from
-1 121 * the managed part of the DOM.
-1 122 *
-1 123 * @private
-1 124 * @param {string} selector
-1 125 * @return {Array.<Element>} All child elements that match the given
-1 126 * selector and are not isolated.
-1 127 */
-1 128 this.querySelectorAll = function(selector) {
-1 129 var hits = root.querySelectorAll(selector);
-1 130
-1 131 // NOTE: querySelectorAll returns all elements in the tree that
-1 132 // match the given selector. findAll does the same with *relative
-1 133 // selectors* but does not seem to be available yet.
-1 134 var isolations = root.querySelectorAll('.muu-isolate');
-1 135 var isolated = _.union(_.map(isolations, function(isolation) {
-1 136 return isolation.querySelectorAll(selector);
-1 137 }));
-1 138
-1 139 return _.difference(hits, isolated);
-1 140 };
-1 141
-1 142 /**
-1 143 * A variant of `querySelector` that returns only elements from the
-1 144 * managed part of the DOM.
-1 145 *
-1 146 * @private
-1 147 * @param {String} selector
-1 148 * @return {Element} First child element that matches the given
-1 149 * selector and is not isolated.
-1 150 * @suppress {missingReturn}
-1 151 */
-1 152 this.querySelector = function(selector) {
-1 153 var all = self.querySelectorAll(selector);
-1 154 if (all.length > 0) {
-1 155 return all[0];
-1 156 }
-1 157 };
-1 158
-1 159 /**
-1 160 * Get all model data as a flat object.
-1 161 *
-1 162 * @return {Object.<string, string|number|boolean>}
-1 163 *//**
-1 164 * Get the value of a form input by name.
-1 165 *
-1 166 * In case of a checkbox, returns `boolean`.
-1 167 * In case of radioboxes, returns the value of the selected box.
-1 168 *
-1 169 * @param {string} name
-1 170 * @param {*} [_default]
-1 171 * @return {string|number|boolean|*}
-1 172 */
-1 173 this.getModel = function(name, _default) {
-1 174 if (name === undefined) {
-1 175 var model = {};
-1 176 _.forEach(self.querySelectorAll('[name]'), function(element) {
-1 177 model[element.name] = self.getModel(element.name);
-1 178 });
-1 179 return model;
-1 180 } else {
-1 181 var element = self.querySelector('[name=' + name + ']');
-1 182 if (element === undefined) {
-1 183 return _default;
-1 184 } else if (element.type === 'checkbox') {
-1 185 return element.checked;
-1 186 } else if (element.type === 'radio') {
-1 187 var options = self.querySelectorAll('[name=' + name + ']');
-1 188 return $.getRadio(options) || _default;
-1 189 } else {
-1 190 return element.value;
-1 191 }
-1 192 }
-1 193 };
-1 194
-1 195 /**
-1 196 * Set the value of a form input by name.
-1 197 *
-1 198 * In case of a checkbox, sets `element.checked`.
-1 199 * In case of radioboxes, selects the box with matching value.
-1 200 *
-1 201 * @param {string} name
-1 202 * @param {string|number|boolean} value
-1 203 */
-1 204 this.setModel = function(name, value) {
-1 205 var element = self.querySelector('[name=' + name + ']');
-1 206 if (element.type === 'checkbox') {
-1 207 element.checked = value;
-1 208 } else if (element.type === 'radio') {
-1 209 var options = self.querySelectorAll('[name=' + name + ']');
-1 210 $.setRadio(options, value);
-1 211 } else {
-1 212 element.value = value;
-1 213 }
-1 214 };
-1 215 };
-1 216
-1 217 return Directive;
-1 218 });
-1 219 /**
-1 220 * DOM related helper functions
-1 221 * @module muu-dom-helpers
-1 222 */
-1 223 _define("muu-dom-helpers", ['muu-js-helpers'], function(_) {
-1 224 "use strict";
-1 225
-1 226 var entityMap = {
-1 227 '&': '&',
-1 228 '<': '<',
-1 229 '>': '>',
-1 230 '"': '"',
-1 231 "'": ''',
-1 232 '/': '/'
-1 233 };
-1 234
-1 235 /** @lends module:muu-dom-helpers */
-1 236 var $ = {};
-1 237
-1 238 $.DELAY = 1000;
-1 239
-1 240 /**
-1 241 * @param {string} string
-1 242 * @return {string} - escaped HTML
-1 243 */
-1 244 $.escapeHtml = function(string) {
-1 245 return String(string).replace(/[&<>"'\/]/g, function(s) {
-1 246 return entityMap[s];
-1 247 });
-1 248 };
-1 249
-1 250 /**
-1 251 * Cross browser custom events.
-1 252 *
-1 253 * *Note*: IE does not seem to like it when you use existing event names
-1 254 * with this.
-1 255 *
-1 256 * @param {string} type
-1 257 * @param {*} detail
-1 258 * @return {Event}
-1 259 * @see https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
-1 260 */
-1 261 $.createEvent = function(type, detail) {
-1 262 if (typeof CustomEvent === 'function') {
-1 263 return new CustomEvent(type, {
-1 264 detail: detail
-1 265 });
-1 266 } else {
-1 267 var event = document.createEvent('CustomEvent');
-1 268 event.initCustomEvent(type, false, true, detail);
-1 269 return event;
-1 270 }
-1 271 };
-1 272
-1 273 /**
-1 274 * @param {EventTarget} element
-1 275 * @param {string} eventName
-1 276 * @param {Function} callback
-1 277 * @return {function()} An unregister function
-1 278 */
-1 279 $.on = function(element, eventName, callback) {
-1 280 element.addEventListener(eventName, callback, false);
-1 281 return function() {
-1 282 element.removeEventListener(eventName, callback, false);
-1 283 };
-1 284 };
-1 285
-1 286 /**
-1 287 * @param {Function} fn
-1 288 * @return {function()} An unregister function
-1 289 */
-1 290 $.ready = function(fn) {
-1 291 var _fn = _.once(fn);
-1 292 if (document.readyState === 'complete') {
-1 293 _fn();
-1 294 return function() {};
-1 295 } else {
-1 296 var u1 = $.on(document, 'DOMContentLoaded', _fn);
-1 297 var u2 = $.on(window, 'load', _fn);
-1 298 return function() {
-1 299 u1();
-1 300 u2();
-1 301 };
-1 302 }
-1 303 };
-1 304
-1 305 /**
-1 306 * @param {Node} desc
-1 307 * @param {Node} root
-1 308 * @return {boolean}
-1 309 */
-1 310 $.isDescendant = function(desc, root) {
-1 311 return !!desc && (desc === root || $.isDescendant(desc.parentNode, root));
-1 312 };
-1 313
-1 314 /**
-1 315 * Execute a function when `element` is removed from the DOM.
-1 316 *
-1 317 * *Note*: The callback is not executed directly when (or even before) the
-1 318 * element is removed but with a slight delay. So the only way to test this
-1 319 * is to use a timeout in the test.
-1 320 *
-1 321 * @param {Element} element
-1 322 * @param {Function} fn
-1 323 * @return {function()} An unregister function
-1 324 */
-1 325 $.destroy = function(element, fn) {
-1 326 var unregister;
-1 327
-1 328 if (!!window.MutationObserver) {
-1 329 var observer = new MutationObserver(function() {
-1 330 if (!$.isDescendant(element, document)) {
-1 331 fn();
-1 332 unregister();
-1 333 }
-1 334 });
-1 335
-1 336 observer.observe(document, {
-1 337 childList: true,
-1 338 subtree: true
-1 339 });
-1 340
-1 341 unregister = _.once(function() {
-1 342 observer.disconnect();
-1 343 observer = undefined;
-1 344 });
-1 345 } else {
-1 346 var intervalID = setInterval(function() {
-1 347 if (!$.isDescendant(element, document)) {
-1 348 fn();
-1 349 unregister();
-1 350 }
-1 351 }, $.DELAY);
-1 352
-1 353 unregister = function() {
-1 354 clearInterval(intervalID);
-1 355 };
-1 356 }
-1 357
-1 358 return unregister;
-1 359 };
-1 360
-1 361 /**
-1 362 * @param {Array.<Element>} options
-1 363 * @return {string}
-1 364 * @suppress {missingReturn}
-1 365 */
-1 366 $.getRadio = function(options) {
-1 367 for (var i = 0; i < options.length; i++) {
-1 368 if (options[i].checked) {
-1 369 return options[i].value;
-1 370 }
-1 371 }
-1 372 };
-1 373
-1 374 /**
-1 375 * @param {Array.<Element>} options
-1 376 * @param {string} value
-1 377 */
-1 378 $.setRadio = function(options, value) {
-1 379 for (var i = 0; i < options.length; i++) {
-1 380 if (options[i].value === value) {
-1 381 options[i].checked = true;
-1 382 } else {
-1 383 options[i].checked = false;
-1 384 }
-1 385 }
-1 386 };
-1 387
-1 388 return $;
-1 389 });
-1 390 /**
-1 391 * Minimal implementation of an underscore/lodash subset.
-1 392 * @module muu-js-helpers
-1 393 */
-1 394 _define('muu-js-helpers', [], function() {
-1 395 "use strict";
-1 396
-1 397 /** @lends module:muu-js-helpers */
-1 398 var _ = {};
-1 399
-1 400 /**
-1 401 * @param {Object} value
-1 402 * @return {string}
-1 403 */
-1 404 var objToString = function(value) {
-1 405 return Object.prototype.toString.call(value);
-1 406 };
-1 407
-1 408 /**
-1 409 * @param {*} value
-1 410 * @return {boolean}
-1 411 */
-1 412 _.isString = function(value) {
-1 413 return typeof value === 'string' || objToString(value) === '[object String]';
-1 414 };
-1 415
-1 416 /**
-1 417 * @function
-1 418 * @param {*} value
-1 419 * @return {boolean}
-1 420 */
-1 421 _.isArray = Array.isArray;
-1 422
-1 423 /**
-1 424 * @param {*} value
-1 425 * @return {boolean}
-1 426 */
-1 427 _.isFunction = function(value) {
-1 428 return typeof value === 'function';
-1 429 };
-1 430
-1 431 /**
-1 432 * @param {Function} fn
-1 433 * @return {Function}
-1 434 */
-1 435 _.once = function(fn) {
-1 436 var result;
-1 437 var called = false;
-1 438
-1 439 return function() {
-1 440 if (!called) {
-1 441 result = fn.apply(this, arguments);
-1 442 called = true;
-1 443 }
-1 444 return result;
-1 445 };
-1 446 };
-1 447
-1 448 /**
-1 449 * @param {Array} array
-1 450 * @param {*} value
-1 451 * @return {number}
-1 452 */
-1 453 _.indexOf = function(array, value) {
-1 454 if ('indexOf' in array) {
-1 455 return array.indexOf(value);
-1 456 }
-1 457
-1 458 for (var i = 0; i < array.length; i++) {
-1 459 if (array[i] === value) {
-1 460 return i;
-1 461 }
-1 462 }
-1 463 return -1;
-1 464 };
-1 465
-1 466 /**
-1 467 * @param {Array} array
-1 468 * @param {Function} fn
-1 469 */
-1 470 _.forEach = function(array, fn) {
-1 471 if ('forEach' in array) {
-1 472 return array.forEach(fn);
-1 473 }
-1 474
-1 475 for (var i = 0; i < array.length; i++) {
-1 476 fn(array[i]);
-1 477 }
-1 478 };
-1 479
-1 480 /**
-1 481 * @param {Array} array
-1 482 * @param {Function} fn
-1 483 * @return {Array}
-1 484 */
-1 485 _.map = function(array, fn) {
-1 486 if ('map' in array) {
-1 487 return array.map(fn);
-1 488 }
-1 489
-1 490 var results = [];
-1 491 for (var i = 0; i < array.length; i++) {
-1 492 results.push(fn(array[i]));
-1 493 }
-1 494 return results;
-1 495 };
-1 496
-1 497 /**
-1 498 * @param {Array} array
-1 499 * @param {Function} fn
-1 500 * @return {Array}
-1 501 */
-1 502 _.filter = function(array, fn) {
-1 503 if ('filter' in array) {
-1 504 return array.filter(fn);
-1 505 }
-1 506
-1 507 var results = [];
-1 508 for (var i = 0; i < array.length; i++) {
-1 509 if (fn(array[i])) {
-1 510 results.push(array[i]);
-1 511 }
-1 512 }
-1 513 return results;
-1 514 };
-1 515
-1 516 /**
-1 517 * @param {Array.<Array>} arrays
-1 518 * @return {Array}
-1 519 */
-1 520 _.union = function(arrays) {
-1 521 var results = [];
-1 522 for (var i = 0; i < arrays.length; i++) {
-1 523 for (var j = 0; j < arrays[i].length; j++) {
-1 524 if (_.indexOf(results, arrays[i][j]) === -1) {
-1 525 results.push(arrays[i][j]);
-1 526 }
-1 527 }
-1 528 }
-1 529 return results;
-1 530 };
-1 531
-1 532 /**
-1 533 * @param {Array} a
-1 534 * @param {Array} b
-1 535 * @return {Array}
-1 536 */
-1 537 _.difference = function(a, b) {
-1 538 var results = [];
-1 539 for (var i = 0; i < a.length; i++) {
-1 540 if (_.indexOf(b, a[i]) === -1) {
-1 541 results.push(a[i]);
-1 542 }
-1 543 }
-1 544 return results;
-1 545 };
-1 546
-1 547 /**
-1 548 * @param {Array} a
-1 549 * @return {Array}
-1 550 */
-1 551 _.flatten = function(a) {
-1 552 var o = [];
-1 553 _.forEach(a, function(item) {
-1 554 if (_.isArray(item)) {
-1 555 o = o.concat(_.flatten(item));
-1 556 } else {
-1 557 o.push(item);
-1 558 }
-1 559 });
-1 560 return o;
-1 561 };
-1 562
-1 563 return _;
-1 564 });
-1 565 /**
-1 566 * angular inspired location service.
-1 567 * @module muu-location
-1 568 */
-1 569 _define('muu-location', ['muu-search'], function(q) {
-1 570 "use strict";
-1 571
-1 572 /** @lends module:muu-location */
-1 573 var loc = {};
-1 574
-1 575 /**
-1 576 * @return {string}
-1 577 */
-1 578 loc.absUrl = function() {
-1 579 return location.href;
-1 580 };
-1 581
-1 582 /**
-1 583 * @return {string}
-1 584 *//**
-1 585 * @param {string} value
-1 586 * @param {boolean} [replace]
-1 587 * @return {muu-location}
-1 588 */
-1 589 loc.url = function(value, replace) {
-1 590 if (value === undefined) {
-1 591 return location.pathname + location.search + location.hash;
-1 592 } else if (replace) {
-1 593 history.replaceState(null, null, value);
-1 594 } else {
-1 595 history.pushState(null, null, value);
-1 596 }
-1 597 return loc;
-1 598 };
-1 599
-1 600 /**
-1 601 * @return {string}
-1 602 */
-1 603 loc.protocol = function() {
-1 604 return location.protocol;
-1 605 };
-1 606
-1 607 /**
-1 608 * @return {string}
-1 609 */
-1 610 loc.host = function() {
-1 611 return location.host;
-1 612 };
-1 613
-1 614 /**
-1 615 * @return {string}
-1 616 */
-1 617 loc.port = function() {
-1 618 return location.port;
-1 619 };
-1 620
-1 621 /**
-1 622 * @return {string}
-1 623 *//**
-1 624 * @param {string} value
-1 625 * @param {boolean} [replace]
-1 626 * @return {muu-location}
-1 627 */
-1 628 loc.path = function(value, replace) {
-1 629 if (value === undefined) {
-1 630 return location.pathname;
-1 631 } else {
-1 632 var url = value + location.search + location.hash;
-1 633 loc.url(url, replace);
-1 634 return loc;
-1 635 }
-1 636 };
-1 637
-1 638 var _search = function(value, replace) {
-1 639 if (value === undefined) {
-1 640 return location.search;
-1 641 } else {
-1 642 if (value && value[0] !== '?') {
-1 643 value = '?' + value;
-1 644 }
-1 645 if (value.length === 1) {
-1 646 value = '';
-1 647 }
-1 648
-1 649 var url = location.pathname + value + location.hash;
-1 650 loc.url(url, replace);
-1 651 return loc;
-1 652 }
-1 653 };
-1 654
-1 655 /**
-1 656 * @return {Object}
-1 657 *//**
-1 658 * @param {string|object} value
-1 659 * @return {muu-location}
-1 660 *//**
-1 661 * @param {string} key
-1 662 * @param {*} value
-1 663 * @param {boolean} [replace]
-1 664 * @return {muu-location}
-1 665 */
-1 666 loc.search = function(key, value, replace) {
-1 667 if (key !== undefined) {
-1 668 if (value !== undefined) {
-1 669 var search = q.parse(_search());
-1 670 search[key] = value;
-1 671 return _search(q.unparse(search), replace);
-1 672 } else {
-1 673 return _search(q.unparse(key), replace);
-1 674 }
-1 675 } else {
-1 676 return q.parse(_search());
-1 677 }
-1 678 };
-1 679
-1 680 /**
-1 681 * @return {string}
-1 682 *//**
-1 683 * @param {string} value
-1 684 * @param {boolean} [replace]
-1 685 * @return {muu-location}
-1 686 */
-1 687 loc.hash = function(value, replace) {
-1 688 if (value === undefined) {
-1 689 if (location.hash) {
-1 690 return location.hash.slice(1);
-1 691 } else {
-1 692 return '';
-1 693 }
-1 694 } else {
-1 695 var url = location.pathname + location.search + '#' + value;
-1 696 loc.url(url, replace);
-1 697 return loc;
-1 698 }
-1 699 };
-1 700
-1 701 /**
-1 702 * @param {string} eventName
-1 703 * @param {Function} fn
-1 704 * @return {muu-location}
-1 705 */
-1 706 loc.addEventListener = function(eventName, fn) {
-1 707 if (eventName === 'change') {
-1 708 window.addEventListener('popstate', fn, false);
-1 709 }
-1 710 return loc;
-1 711 };
-1 712
-1 713 /**
-1 714 * @param {string} eventName
-1 715 * @param {Function} fn
-1 716 * @return {muu-location}
-1 717 */
-1 718 loc.removeEventListener = function(eventName, fn) {
-1 719 if (eventName === 'change') {
-1 720 window.removeEventListener('popstate', fn, false);
-1 721 }
-1 722 return loc;
-1 723 };
-1 724
-1 725 return loc;
-1 726 });
-1 727 /**
-1 728 * Exports the {@link Registry} class.
-1 729 * @module muu-registry
-1 730 * @ignore
-1 731 */
-1 732 _define('muu-registry', ['muu-template', 'muu-directive', 'muu-js-helpers', 'muu-dom-helpers'], function(muuTemplate, Directive, _, $) {
-1 733 "use strict";
-1 734
-1 735 /**
-1 736 * @constructs Registry
-1 737 * @param {Object} config The config object may have following properties:
-1 738 *
-1 739 * - **debug** - `{boolean}` - Enable debug mode. In debug mode,
-1 740 * directive objects are available as properties from the DOM as
-1 741 * `element.directive`.
-1 742 * - **renderer** - `{function(string, Object)}` - The template renderer
-1 743 * to be used. Defaults to {@link module:muu-template}.
-1 744 */
-1 745 var Registry = function(config) {
-1 746 var self = this;
-1 747 var directives = {};
-1 748
-1 749 this.config = config || {};
-1 750 this.renderer = self.config.renderer || muuTemplate;
-1 751
-1 752 /**
-1 753 * Register a new type of {@link Directive}
-1 754 *
-1 755 * @param {string} type
-1 756 * @param {string} template
-1 757 * @param {function(Directive, Element): Function} link The link
-1 758 * function is called with an instance of {@link Directive} and a
-1 759 * Element when {@link Registry#link} is executed.
-1 760 *
-1 761 * It is the only place where you can access a directive and
-1 762 * therefore the place where you define its behavior.
-1 763 *
-1 764 * This typically means to make an initial call to {@link
-1 765 * Directive#update} and to add some event listeners. You should also
-1 766 * return an *unlink* function that clears all external references in
-1 767 * order to avoid memory leaks.
-1 768 * @return {Registry} this
-1 769 */
-1 770 this.registerDirective = function(type, template, link) {
-1 771 directives[type] = {
-1 772 template: template,
-1 773 link: link
-1 774 };
-1 775 return self;
-1 776 };
-1 777
-1 778 /**
-1 779 * Shortcut for wrapping calls to {@link Registry} in a function.
-1 780 *
-1 781 * This can be esepcially helpful if that function is defined in a
-1 782 * different module.
-1 783 *
-1 784 * ```.js
-1 785 * _define('foobar', [], function() {
-1 786 * return function(registry) {
-1 787 * registry
-1 788 * .registerDirective('foo', '...', function() {...})
-1 789 * .registerDirective('bar', '...', function() {...});
-1 790 * };
-1 791 * });
-1 792 *
-1 793 * require(['foobar'], function(foobar) {
-1 794 * var registry = new Registry();
-1 795 * registry.registerModule(foobar);
-1 796 * });
-1 797 * ```
-1 798 *
-1 799 * @param {function(Registry)} module
-1 800 * @return {Registry} this
-1 801 */
-1 802 this.registerModule = function(module) {
-1 803 module(self);
-1 804 return self;
-1 805 };
-1 806
-1 807 /**
-1 808 * Create and initialise a {@link Directive} for `element`.
-1 809 *
-1 810 * @param {Element} element
-1 811 * @param {string} type
-1 812 * @return {Directive}
-1 813 */
-1 814 this.link = function(element, type) {
-1 815 if (type === undefined) {
-1 816 type = element.getAttribute('type');
-1 817 }
-1 818
-1 819 if (!directives.hasOwnProperty(type)) {
-1 820 throw new Error('Unknown directive type: ' + type);
-1 821 }
-1 822
-1 823 var template = directives[type].template;
-1 824 var link = directives[type].link;
-1 825
-1 826 var directive = new Directive(element, template, self);
-1 827 var unlink = link(directive, element);
-1 828 element.classList.add('muu-isolate');
-1 829 element.classList.add('muu-initialised');
-1 830
-1 831 if (self.config.debug) {
-1 832 element.directive = directive;
-1 833 }
-1 834
-1 835 if (unlink !== undefined) {
-1 836 $.destroy(element, unlink);
-1 837 }
-1 838
-1 839 return directive;
-1 840 };
-1 841
-1 842 /**
-1 843 * Link all directives that can be found inside `root`.
-1 844 *
-1 845 * @param {Element} root
-1 846 * @return {Array.<Directive>}
-1 847 */
-1 848 this.linkAll = function(root) {
-1 849 // NOTE: root may be a DOM Node or a directive
-1 850 var elements = _.filter(root.querySelectorAll('muu'), function(element) {
-1 851 return !element.classList.contains('muu-initialised');
-1 852 });
-1 853 return _.map(elements, function(element) {
-1 854 return self.link(element);
-1 855 });
-1 856 };
-1 857 };
-1 858
-1 859 return Registry;
-1 860 });
-1 861 _define('muu-search', ['muu-js-helpers'], function(_) {
-1 862 "use strict";
-1 863
-1 864 var q = {};
-1 865
-1 866 q.parse = function(s) {
-1 867 var q = {};
-1 868
-1 869 var set = function(key, value) {
-1 870 if (!q.hasOwnProperty(key)) {
-1 871 q[key] = value;
-1 872 } else if (_.isArray(q[key])) {
-1 873 q[key].push(value);
-1 874 } else {
-1 875 q[key] = [q[key], value];
-1 876 }
-1 877 };
-1 878
-1 879 _.forEach(s.substring(1).split('&'), function(item) {
-1 880 var i = _.map(item.split('='), decodeURIComponent);
-1 881 if (i.length === 2) {
-1 882 set(i[0], i[1]);
-1 883 } else if (i[0]) {
-1 884 set(i[0], true);
-1 885 }
-1 886 });
-1 887 return q;
-1 888 };
-1 889
-1 890 var unparseItem = function(key, value) {
-1 891 if (value === undefined || value === null || value === false) {
-1 892 return [];
-1 893 } else if (_.isArray(value)) {
-1 894 return _.flatten(_.map(value, function(v) {
-1 895 return unparseItem(key, v);
-1 896 }));
-1 897 } else if (value === true) {
-1 898 return [encodeURIComponent(key)];
-1 899 } else {
-1 900 return [encodeURIComponent(key) + '=' + encodeURIComponent(value)];
-1 901 }
-1 902 };
-1 903
-1 904 q.unparse = function(q) {
-1 905 if (_.isString(q)) {
-1 906 return q;
-1 907 }
-1 908
-1 909 var a = []
-1 910 for (var key in q) {
-1 911 if (q.hasOwnProperty(key)) {
-1 912 a = a.concat(unparseItem(key, q[key]));
-1 913 }
-1 914 }
-1 915 if (a.length > 0) {
-1 916 return '?' + a.join('&');
-1 917 } else {
-1 918 return '';
-1 919 }
-1 920 };
-1 921
-1 922 return q;
-1 923 });
-1 924 /**
-1 925 * minimal mustache insipred templating
-1 926 *
-1 927 * ## Variables
-1 928 *
-1 929 * Variables are created with a `{{name}}` tag. These are always escaped.
-1 930 *
-1 931 * ## Loops
-1 932 *
-1 933 * Loops render blocks of text a number of times, depending on the value of
-1 934 * the key in the current context.
-1 935 *
-1 936 * A loop begins with a pound and ends with a slash. That is, `{{#person}}`
-1 937 * begins a "person" section while `{{/person}}` ends it.
-1 938 *
-1 939 * If the value is an array, the block is repeated for each item in that array.
-1 940 * In any other case, the block is rendered with the outer scope, but only if
-1 941 * the value is truthy.
-1 942 *
-1 943 * ## Inverted loops
-1 944 *
-1 945 * Inverted loops render blocks of test if the value of the key is falsy. They
-1 946 * begin with a caret.
-1 947 *
-1 948 * ## Comments
-1 949 *
-1 950 * Comments begin with a bang and are ignored.
-1 951 *
-1 952 * ## Pairs
-1 953 *
-1 954 * Pairs look like JSON objects. The result is a space separated list of all
-1 955 * keys with truthy values.
-1 956 *
-1 957 * ```
-1 958 * muuTemplate('{{foo: var1, bar: var2, baz: var3}}', {
-1 959 * var1: true,
-1 960 * var2: false,
-1 961 * var3: true
-1 962 * }); // 'foo baz'
-1 963 * ```
-1 964 *
-1 965 * ## Special variable `this`
-1 966 *
-1 967 * `this` always refers to the current context. So the following expressions
-1 968 * are equivalent:
-1 969 *
-1 970 * ```
-1 971 * muuTemplate('{{#items}}{{content}}{{/items}}', {
-1 972 * item: [{
-1 973 * content: 1
-1 974 * }, {
-1 975 * content: 2
-1 976 * }]
-1 977 * });
-1 978 *
-1 979 * muuTemplate('{{#this}}{{this}}{{/this}}', [1, 2]);
-1 980 * ```
-1 981 *
-1 982 * @module muu-template
-1 983 * @param {string} template
-1 984 * @param {Object} data
-1 985 * @return {string}
-1 986 */
-1 987 _define('muu-template', ['muu-js-helpers', 'muu-dom-helpers'], function(_, $) {
-1 988 "use strict";
-1 989
-1 990 var openTag = '{{';
-1 991 var closeTag = '}}';
-1 992
-1 993 var getValue = function(key, data) {
-1 994 return key === 'this' ? data : data[key];
-1 995 };
-1 996
-1 997 var parseVariableTemplate = function(template) {
-1 998 var content = template.slice(2, -2);
-1 999
-1 1000 if (template.indexOf(':') === -1) {
-1 1001 return function(data) {
-1 1002 return $.escapeHtml(getValue(content, data) || '');
-1 1003 };
-1 1004 } else {
-1 1005 var pairs = content.split(',').map(function(pair) {
-1 1006 var v = pair.split(':');
-1 1007 var key = v[0].trim();
-1 1008 var value = v.slice(1).join(':').trim();
-1 1009 return [key, value];
-1 1010 });
-1 1011
-1 1012 return function(data) {
-1 1013 var results = [];
-1 1014
-1 1015 for (var i = 0; i < pairs.length; i++) {
-1 1016 var key = pairs[i][0];
-1 1017 var value = pairs[i][1];
-1 1018
-1 1019 if (getValue(value, data)) {
-1 1020 results.push(key);
-1 1021 }
-1 1022 }
-1 1023
-1 1024 return $.escapeHtml(results.join(' '));
-1 1025 };
-1 1026 }
-1 1027 };
-1 1028
-1 1029 var parseLoopTemplate = function(tag, afterTag, inverted) {
-1 1030 var tagName = tag.slice(3, -2);
-1 1031
-1 1032 var v = parseTemplate(afterTag, tagName);
-1 1033 var inner = v[0];
-1 1034 var afterLoop = v[1];
-1 1035
-1 1036 var render = function(data) {
-1 1037 if (inverted) {
-1 1038 if (getValue(tagName, data)) {
-1 1039 return '';
-1 1040 } else {
-1 1041 return inner(data);
-1 1042 }
-1 1043 } else {
-1 1044 if (_.isArray(getValue(tagName, data))) {
-1 1045 var result = '';
-1 1046 for (var i = 0; i < getValue(tagName, data).length; i++) {
-1 1047 result += inner(getValue(tagName, data)[i]);
-1 1048 }
-1 1049 return result;
-1 1050 } else if (getValue(tagName, data)) {
-1 1051 return inner(data);
-1 1052 } else {
-1 1053 return '';
-1 1054 }
-1 1055 }
-1 1056 };
-1 1057
-1 1058 return [render, afterLoop];
-1 1059 };
-1 1060
-1 1061 var concat = function(a) {
-1 1062 var last = a.pop();
-1 1063
-1 1064 if (_.isArray(last)) {
-1 1065 a.push(last[0]);
-1 1066 return [concat(a), last[1]];
-1 1067 } else {
-1 1068 a.push(last);
-1 1069
-1 1070 return function(data) {
-1 1071 return a.map(function(item) {
-1 1072 if (_.isString(item)) {
-1 1073 return item;
-1 1074 } else if (_.isFunction(item)) {
-1 1075 return item(data);
-1 1076 }
-1 1077 }).join('');
-1 1078 };
-1 1079 }
-1 1080 };
-1 1081
-1 1082 var parseTemplate = function(template, loopName) {
-1 1083 var openIndex = template.indexOf(openTag);
-1 1084 if (openIndex === -1) {
-1 1085 if (loopName === undefined) {
-1 1086 return function() {
-1 1087 return template;
-1 1088 };
-1 1089 } else {
-1 1090 throw new Error('unclosed loop: ' + loopName);
-1 1091 }
-1 1092 } else {
-1 1093 var beforeTag = template.slice(0, openIndex);
-1 1094 var tmp = template.slice(openIndex);
-1 1095
-1 1096 var closeIndex = tmp.indexOf(closeTag) + 2;
-1 1097 if (closeIndex === 1) {
-1 1098 throw new Error('unclosed tag: ' + tmp);
-1 1099 }
-1 1100 var tag = tmp.slice(0, closeIndex);
-1 1101 var afterTag = tmp.slice(closeIndex);
-1 1102
-1 1103 if (tag.lastIndexOf('{{#', 0) === 0) {
-1 1104 var v = parseLoopTemplate(tag, afterTag);
-1 1105 var loop = v[0];
-1 1106 var after = parseTemplate(v[1], loopName);
-1 1107 return concat([beforeTag, loop, after]);
-1 1108 } else if (tag.lastIndexOf('{{^', 0) === 0) {
-1 1109 var v = parseLoopTemplate(tag, afterTag, true);
-1 1110 var loop = v[0];
-1 1111 var after = parseTemplate(v[1], loopName);
-1 1112 return concat([beforeTag, loop, after]);
-1 1113 } else if (tag.lastIndexOf('{{!', 0) === 0) {
-1 1114 var after = parseTemplate(afterTag, loopName);
-1 1115 return concat([beforeTag, after]);
-1 1116 } else if (tag.lastIndexOf('{{/', 0) === 0) {
-1 1117 if (tag.slice(3, -2) === loopName) {
-1 1118 var render = function() {
-1 1119 return beforeTag;
-1 1120 };
-1 1121 return [render, afterTag];
-1 1122 } else {
-1 1123 throw new Error('unexpected closing loop: ' + tag);
-1 1124 }
-1 1125 } else {
-1 1126 var render = parseVariableTemplate(tag);
-1 1127 var after = parseTemplate(afterTag, loopName);
-1 1128 return concat([beforeTag, render, after]);
-1 1129 }
-1 1130 }
-1 1131 };
-1 1132
-1 1133 return function(template, data) {
-1 1134 return parseTemplate(template)(data);
-1 1135 };
-1 1136 });
-1 1137 /**
-1 1138 * Recreate children of `source` in `target` by making only small adjustments.
-1 1139 *
-1 1140 * *The following section explains details about the current implementation.
-1 1141 * These are likely to change in the future.*
-1 1142 *
-1 1143 * The algorithms is relatively simple. It just iterates through all top level
-1 1144 * nodes. If a node has a different `nodeType` (e.g. text or element) or a
-1 1145 * different `nodeName` (e.g. div or ul) it is replaced completely and the
-1 1146 * algorithm proceeds with the node's children recursively. Otherwise, only
-1 1147 * the nodes's attributes are updated.
-1 1148 *
-1 1149 * Note that non-attribute properties (e.g. value) are lost in the first case
-1 1150 * and preserved in the second.
-1 1151 *
-1 1152 * If the algorithm encounters an element with the class `muu-isolate` it does
-1 1153 * not recurse into its children. This way, you can protect dynamically
-1 1154 * generated content from being overwritten.
-1 1155 *
-1 1156 * @module muu-update-dom
-1 1157 * @param {Element} target
-1 1158 * @param {Element} source
-1 1159 */
-1 1160 _define('muu-update-dom', ['muu-js-helpers'], function(_) {
-1 1161 "use strict";
-1 1162
-1 1163 var updateAttributes = function(target, source) {
-1 1164 var targetAttrNames = _.map(target.attributes, function(item) {
-1 1165 return item.name;
-1 1166 });
-1 1167 var sourceAttrNames = _.map(source.attributes, function(item) {
-1 1168 return item.name;
-1 1169 });
-1 1170
-1 1171 _.forEach(targetAttrNames, function(name) {
-1 1172 // NOTE: ie8.js creates some attribute
-1 1173 if (!source.hasAttribute(name) && name.substr(0, 7) !== '__IE8__') {
-1 1174 target.removeAttribute(name);
-1 1175 }
-1 1176 });
-1 1177 _.forEach(sourceAttrNames, function(name) {
-1 1178 if (target.getAttribute(name) !== source.getAttribute(name)) {
-1 1179 target.setAttribute(name, source.getAttribute(name));
-1 1180 }
-1 1181 });
-1 1182 };
-1 1183
-1 1184 var updateDOM = function(target, source) {
-1 1185 var nt = target.childNodes.length;
-1 1186 var ns = source.childNodes.length;
-1 1187
-1 1188 for (var i = ns; i < nt; i++) {
-1 1189 target.removeChild(target.childNodes[ns]);
-1 1190 }
-1 1191 for (i = nt; i < ns; i++) {
-1 1192 target.appendChild(source.childNodes[nt]);
-1 1193 }
-1 1194 for (i = 0; i < nt && i < ns; i++) {
-1 1195 var tchild = target.childNodes[i];
-1 1196 var schild = source.childNodes[i];
-1 1197
-1 1198 if (tchild.nodeType === schild.nodeType && tchild.nodeName === schild.nodeName && tchild.type === schild.type) {
-1 1199 if (tchild.nodeType === 1) {
-1 1200 var muuClasses = _.filter(tchild.classList, function(cls) {
-1 1201 return cls.lastIndexOf('muu-', 0) === 0;
-1 1202 });
-1 1203 updateAttributes(tchild, schild);
-1 1204 _.forEach(muuClasses, function(cls) {
-1 1205 tchild.classList.add(cls);
-1 1206 });
-1 1207 } else if (tchild.nodeType === 3) {
-1 1208 tchild.nodeValue = schild.nodeValue;
-1 1209 }
-1 1210 if (tchild.nodeType !== 3 && !tchild.classList.contains('muu-isolate')) {
-1 1211 updateDOM(tchild, schild);
-1 1212 }
-1 1213 } else {
-1 1214 tchild.parentNode.replaceChild(schild, tchild);
-1 1215 }
-1 1216 }
-1 1217 };
-1 1218
-1 1219 return updateDOM;
-1 1220 });
-1 1221 /**
-1 1222 * This module gives access to the following objects:
-1 1223 *
-1 1224 * - `Registry` - {@link Registry}
-1 1225 * - `$` - {@link module:muu-dom-helpers}
-1 1226 * - `$location` - {@link module:muu-location}
-1 1227 *
-1 1228 * @module muu
-1 1229 */
-1 1230 _define('muu', ['muu-registry', 'muu-dom-helpers', 'muu-location'], function(Registry, $, $location) {
-1 1231 "use strict";
-1 1232
-1 1233 var module = {};
-1 1234
-1 1235 module.Registry = Registry;
-1 1236 module.$ = $;
-1 1237 module.$location = $location;
-1 1238
-1 1239 return module;
-1 1240 });
-1 1241
-1 1242 return _require('muu');
-1 1243 });
-1 1244 })(window, document, void 0);
diff --git a/dist/muu.min.js b/dist/muu.min.js
@@ -0,0 +1,19 @@
-1 1 (function(r,p,h){(function(h){"function"===typeof define&&define.amd?define("muu",[],h):r.muu=h()})(function(){var q={},v=function(c,b){for(var e=[],a=0;a<c.length;a++)e.push(b(c[a]));return e},m=function(c,b,e){q[c]={deps:b,factory:e}},t=function(c){if(!q[c])return h;q[c].instance||(q[c].instance=q[c].factory.apply(h,v(q[c].deps,t)));return q[c].instance};m("muu-directive",["muu-dom-helpers","muu-js-helpers","muu-update-dom"],function(c,b,e){return function(a,d,g){var f=this;a.innerHTML="";var k=
-1 2 function(d){var b="data-on"+d.type;d.target.hasAttribute(b)&&(b=d.target.getAttribute(b),d=c.createEvent("muu-"+b,d),a.dispatchEvent(d))};this.update=function(s){var u=p.createElement("div");u.innerHTML=g.renderer(d,s);e(a,u);b.forEach(["keydown","keyup","click","change","search"],function(a){b.forEach(f.querySelectorAll("[data-on"+a+"]"),function(d){d.addEventListener(a,k,!1)})});var n=c.createEvent("muu-parent-update");s=this.querySelectorAll("muu.muu-initialised");b.forEach(s,function(a){a.dispatchEvent(n)});
-1 3 g.linkAll(f)};this.querySelectorAll=function(d){var k=a.querySelectorAll(d),c=a.querySelectorAll(".muu-isolate"),c=b.union(b.map(c,function(a){return a.querySelectorAll(d)}));return b.difference(k,c)};this.querySelector=function(a){a=f.querySelectorAll(a);if(0<a.length)return a[0]};this.getModel=function(a,d){if(a===h){var k={};b.forEach(f.querySelectorAll("[name]"),function(a){k[a.name]=f.getModel(a.name)});return k}var e=f.querySelector("[name="+a+"]");return e===h?d:"checkbox"===e.type?e.checked:
-1 4 "radio"===e.type?(e=f.querySelectorAll("[name="+a+"]"),c.getRadio(e)||d):e.value};this.setModel=function(a,d){var b=f.querySelector("[name="+a+"]");"checkbox"===b.type?b.checked=d:"radio"===b.type?(b=f.querySelectorAll("[name="+a+"]"),c.setRadio(b,d)):b.value=d}}});m("muu-dom-helpers",["muu-js-helpers"],function(c){var b={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},e={DELAY:1E3,escapeHtml:function(a){return String(a).replace(/[&<>"'\/]/g,function(a){return b[a]})},createEvent:function(a,
-1 5 d){if("function"===typeof CustomEvent)return new CustomEvent(a,{detail:d});var b=p.createEvent("CustomEvent");b.initCustomEvent(a,!1,!0,d);return b},on:function(a,d,b){a.addEventListener(d,b,!1);return function(){a.removeEventListener(d,b,!1)}},ready:function(a){a=c.once(a);if("complete"===p.readyState)return a(),function(){};var d=e.on(p,"DOMContentLoaded",a),b=e.on(r,"load",a);return function(){d();b()}},isDescendant:function(a,d){return!!a&&(a===d||e.isDescendant(a.parentNode,d))},destroy:function(a,
-1 6 d){var b;if(r.MutationObserver){var f=new MutationObserver(function(){e.isDescendant(a,p)||(d(),b())});f.observe(p,{childList:!0,subtree:!0});b=c.once(function(){f.disconnect();f=h})}else{var k=setInterval(function(){e.isDescendant(a,p)||(d(),b())},e.DELAY);b=function(){clearInterval(k)}}return b},getRadio:function(a){for(var d=0;d<a.length;d++)if(a[d].checked)return a[d].value},setRadio:function(a,d){for(var b=0;b<a.length;b++)a[b].checked=a[b].value===d?!0:!1}};return e});m("muu-js-helpers",[],
-1 7 function(){var c={isString:function(b){return"string"===typeof b||"[object String]"===Object.prototype.toString.call(b)}};c.isArray=Array.isArray;c.isFunction=function(b){return"function"===typeof b};c.once=function(b){var e,a=!1;return function(){a||(e=b.apply(this,arguments),a=!0);return e}};c.indexOf=function(b,e){if("indexOf"in b)return b.indexOf(e);for(var a=0;a<b.length;a++)if(b[a]===e)return a;return-1};c.forEach=function(b,e){if("forEach"in b)return b.forEach(e);for(var a=0;a<b.length;a++)e(b[a])};
-1 8 c.map=function(b,e){if("map"in b)return b.map(e);for(var a=[],d=0;d<b.length;d++)a.push(e(b[d]));return a};c.filter=function(b,e){if("filter"in b)return b.filter(e);for(var a=[],d=0;d<b.length;d++)e(b[d])&&a.push(b[d]);return a};c.union=function(b){for(var e=[],a=0;a<b.length;a++)for(var d=0;d<b[a].length;d++)-1===c.indexOf(e,b[a][d])&&e.push(b[a][d]);return e};c.difference=function(b,e){for(var a=[],d=0;d<b.length;d++)-1===c.indexOf(e,b[d])&&a.push(b[d]);return a};c.flatten=function(b){var e=[];
-1 9 c.forEach(b,function(a){c.isArray(a)?e=e.concat(c.flatten(a)):e.push(a)});return e};return c});m("muu-location",["muu-search"],function(c){var b={absUrl:function(){return location.href},url:function(a,d){if(a===h)return location.pathname+location.search+location.hash;d?history.replaceState(null,null,a):history.pushState(null,null,a);return b},protocol:function(){return location.protocol},host:function(){return location.host},port:function(){return location.port},path:function(a,d){if(a===h)return location.pathname;
-1 10 b.url(a+location.search+location.hash,d);return b}},e=function(a,d){if(a===h)return location.search;a&&"?"!==a[0]&&(a="?"+a);1===a.length&&(a="");b.url(location.pathname+a+location.hash,d);return b};b.search=function(a,b,g){if(a!==h){if(b!==h){var f=c.parse(e());f[a]=b;return e(c.unparse(f),g)}return e(c.unparse(a),g)}return c.parse(e())};b.hash=function(a,d){if(a===h)return location.hash?location.hash.slice(1):"";b.url(location.pathname+location.search+"#"+a,d);return b};b.addEventListener=function(a,
-1 11 d){"change"===a&&r.addEventListener("popstate",d,!1);return b};b.removeEventListener=function(a,d){"change"===a&&r.removeEventListener("popstate",d,!1);return b};return b});m("muu-registry",["muu-template","muu-directive","muu-js-helpers","muu-dom-helpers"],function(c,b,e,a){return function(d){var g=this,f={};this.config=d||{};this.renderer=g.config.renderer||c;this.registerDirective=function(a,b,d){f[a]={template:b,link:d};return g};this.registerModule=function(a){a(g);return g};this.link=function(d,
-1 12 e){e===h&&(e=d.getAttribute("type"));if(!f.hasOwnProperty(e))throw Error("Unknown directive type: "+e);var c=f[e].link,n=new b(d,f[e].template,g),c=c(n,d);d.classList.add("muu-isolate");d.classList.add("muu-initialised");g.config.debug&&(d.directive=n);c!==h&&a.destroy(d,c);return n};this.linkAll=function(a){a=e.filter(a.querySelectorAll("muu"),function(a){return!a.classList.contains("muu-initialised")});return e.map(a,function(a){return g.link(a)})}}});m("muu-search",["muu-js-helpers"],function(c){var b=
-1 13 {parse:function(a){var d={},b=function(a,b){d.hasOwnProperty(a)?c.isArray(d[a])?d[a].push(b):d[a]=[d[a],b]:d[a]=b};c.forEach(a.substring(1).split("&"),function(a){a=c.map(a.split("="),decodeURIComponent);2===a.length?b(a[0],a[1]):a[0]&&b(a[0],!0)});return d}},e=function(a,b){return b===h||null===b||!1===b?[]:c.isArray(b)?c.flatten(c.map(b,function(b){return e(a,b)})):!0===b?[encodeURIComponent(a)]:[encodeURIComponent(a)+"="+encodeURIComponent(b)]};b.unparse=function(a){if(c.isString(a))return a;var b=
-1 14 [],g;for(g in a)a.hasOwnProperty(g)&&(b=b.concat(e(g,a[g])));return 0<b.length?"?"+b.join("&"):""};return b});m("muu-template",["muu-js-helpers","muu-dom-helpers"],function(c,b){var e=function(a,b){return"this"===a?b:b[a]},a=function(a){var d=a.slice(2,-2);if(-1===a.indexOf(":"))return function(a){return b.escapeHtml(e(d,a)||"")};var c=d.split(",").map(function(a){var b=a.split(":");a=b[0].trim();b=b.slice(1).join(":").trim();return[a,b]});return function(a){for(var d=[],k=0;k<c.length;k++){var f=
-1 15 c[k][0];e(c[k][1],a)&&d.push(f)}return b.escapeHtml(d.join(" "))}},d=function(a,b,d){var g=a.slice(3,-2);a=f(b,g);var l=a[0];return[function(a){if(d)return e(g,a)?"":l(a);if(c.isArray(e(g,a))){for(var b="",k=0;k<e(g,a).length;k++)b+=l(e(g,a)[k]);return b}return e(g,a)?l(a):""},a[1]]},g=function(a){var b=a.pop();if(c.isArray(b))return a.push(b[0]),[g(a),b[1]];a.push(b);return function(b){return a.map(function(a){if(c.isString(a))return a;if(c.isFunction(a))return a(b)}).join("")}},f=function(b,e){var c=
-1 16 b.indexOf("{{");if(-1===c){if(e===h)return function(){return b};throw Error("unclosed loop: "+e);}var n=b.slice(0,c),l=b.slice(c),m=l.indexOf("}}")+2;if(1===m)throw Error("unclosed tag: "+l);c=l.slice(0,m);l=l.slice(m);if(0===c.lastIndexOf("{{#",0))return l=d(c,l),c=l[0],l=f(l[1],e),g([n,c,l]);if(0===c.lastIndexOf("{{^",0))return l=d(c,l,!0),c=l[0],l=f(l[1],e),g([n,c,l]);if(0===c.lastIndexOf("{{!",0))return l=f(l,e),g([n,l]);if(0===c.lastIndexOf("{{/",0)){if(c.slice(3,-2)===e)return[function(){return n},
-1 17 l];throw Error("unexpected closing loop: "+c);}c=a(c);l=f(l,e);return g([n,c,l])};return function(a,b){return f(a)(b)}});m("muu-update-dom",["muu-js-helpers"],function(c){var b=function(a,b){var e=c.map(a.attributes,function(a){return a.name}),f=c.map(b.attributes,function(a){return a.name});c.forEach(e,function(c){b.hasAttribute(c)||"__IE8__"===c.substr(0,7)||a.removeAttribute(c)});c.forEach(f,function(c){a.getAttribute(c)!==b.getAttribute(c)&&a.setAttribute(c,b.getAttribute(c))})},e=function(a,
-1 18 d){for(var g=a.childNodes.length,f=d.childNodes.length,k=f;k<g;k++)a.removeChild(a.childNodes[f]);for(k=g;k<f;k++)a.appendChild(d.childNodes[g]);for(k=0;k<g&&k<f;k++){var h=a.childNodes[k],m=d.childNodes[k];if(h.nodeType===m.nodeType&&h.nodeName===m.nodeName&&h.type===m.type){if(1===h.nodeType){var n=c.filter(h.classList,function(a){return 0===a.lastIndexOf("muu-",0)});b(h,m);c.forEach(n,function(a){h.classList.add(a)})}else 3===h.nodeType&&(h.nodeValue=m.nodeValue);3===h.nodeType||h.classList.contains("muu-isolate")||
-1 19 e(h,m)}else h.parentNode.replaceChild(m,h)}};return e});m("muu",["muu-registry","muu-dom-helpers","muu-location"],function(c,b,e){var a={};a.Registry=c;a.$=b;a.$location=e;return a});return t("muu")})})(window,document,void 0);
diff --git a/examples/example/example.js b/examples/example/example.js
@@ -1,9 +1,9 @@ 1 1 requirejs.config({2 -1 baseUrl: '../../src/',3 2 paths: {4 -1 xhr: '../lib/promise-xhr/promise-xhr',5 -1 moment: '../lib/moment/moment',6 -1 'muu-moment': '../examples/example/muu-moment'-1 3 muu: '../../dist/muu.min', -1 4 xhr: '../../lib/promise-xhr/promise-xhr', -1 5 moment: '../../lib/moment/moment', -1 6 'muu-moment': './muu-moment' 7 7 } 8 8 }); 9 9
diff --git a/examples/example/index.html b/examples/example/index.html
@@ -1,7 +1,6 @@ 1 1 <html> 2 2 <head> 3 3 <script src="../../lib/requirejs/require.js"></script>4 -1 <script src="../../muu.min.js"></script>5 4 <script src="example.js"></script> 6 5 </head> 7 6 <body>
diff --git a/examples/phonecat/index.html b/examples/phonecat/index.html
@@ -1,7 +1,6 @@ 1 1 <html> 2 2 <head> 3 3 <script src="../../lib/requirejs/require.js"></script>4 -1 <script src="../../muu.min.js"></script>5 4 <script src="phonecat.js"></script> 6 5 </head> 7 6 <body>
diff --git a/examples/phonecat/phonecat.js b/examples/phonecat/phonecat.js
@@ -1,7 +1,7 @@ 1 1 requirejs.config({2 -1 baseUrl: '../../src/',3 2 paths: {4 -1 xhr: '../lib/promise-xhr/promise-xhr'-1 3 muu: '../../dist/muu.min', -1 4 xhr: '../../lib/promise-xhr/promise-xhr' 5 5 } 6 6 }); 7 7
diff --git a/muu.min.js b/muu.min.js
@@ -1,2 +0,0 @@1 -1 define("muu-js-helpers",[],function(){"use strict";var e={},t=function(e){return Object.prototype.toString.call(e)};return e.isString=function(e){return"string"==typeof e||"[object String]"===t(e)},e.isArray=Array.isArray,e.isFunction=function(e){return"function"==typeof e},e.once=function(e){var t,n=!1;return function(){return n||(t=e.apply(this,arguments),n=!0),t}},e.indexOf=function(e,t){if("indexOf"in e)return e.indexOf(t);for(var n=0;n<e.length;n++)if(e[n]===t)return n;return-1},e.forEach=function(e,t){if("forEach"in e)return e.forEach(t);for(var n=0;n<e.length;n++)t(e[n])},e.map=function(e,t){if("map"in e)return e.map(t);for(var n=[],r=0;r<e.length;r++)n.push(t(e[r]));return n},e.filter=function(e,t){if("filter"in e)return e.filter(t);for(var n=[],r=0;r<e.length;r++)t(e[r])&&n.push(e[r]);return n},e.union=function(t){for(var n=[],r=0;r<t.length;r++)for(var i=0;i<t[r].length;i++)-1===e.indexOf(n,t[r][i])&&n.push(t[r][i]);return n},e.difference=function(t,n){for(var r=[],i=0;i<t.length;i++)-1===e.indexOf(n,t[i])&&r.push(t[i]);return r},e.flatten=function(t){var n=[];return e.forEach(t,function(t){e.isArray(t)?n=n.concat(e.flatten(t)):n.push(t)}),n},e}),define("muu-dom-helpers",["muu-js-helpers"],function(e){"use strict";var t={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},n={};return n.DELAY=1e3,n.escapeHtml=function(e){return String(e).replace(/[&<>"'\/]/g,function(e){return t[e]})},n.createEvent=function(e,t){if("function"==typeof CustomEvent)return new CustomEvent(e,{detail:t});var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,!1,!0,t),n},n.on=function(e,t,n){return e.addEventListener(t,n,!1),function(){e.removeEventListener(t,n,!1)}},n.ready=function(t){var r=e.once(t);if("complete"===document.readyState)return r(),function(){};var i=n.on(document,"DOMContentLoaded",r),u=n.on(window,"load",r);return function(){i(),u()}},n.isDescendant=function(e,t){return!!e&&(e===t||n.isDescendant(e.parentNode,t))},n.destroy=function(e,t){var r,i=setInterval(function(){n.isDescendant(e,document)||(t(),r())},n.DELAY);return r=function(){clearInterval(i)}},n.getRadio=function(e){for(var t=0;t<e.length;t++)if(e[t].checked)return e[t].value},n.setRadio=function(e,t){for(var n=0;n<e.length;n++)e[n].value===t?e[n].checked=!0:e[n].checked=!1},n}),define("muu-template",["muu-js-helpers","muu-dom-helpers"],function(e,t){"use strict";var n="{{",r="}}",i=function(e){var n=e.slice(2,-2);if(-1===e.indexOf(":"))return function(e){return t.escapeHtml(e[n]||"")};var r=n.split(",").map(function(e){var t=e.split(":"),n=t[0].trim(),r=t.slice(1).join(":").trim();return[n,r]});return function(e){for(var n=[],i=0;i<r.length;i++){var u=r[i][0],o=r[i][1];e[o]&&n.push(u)}return t.escapeHtml(n.join(" "))}},u=function(t,n){var r=t.slice(3,-2),i=c(n,r),u=i[0],o=i[1],a=function(t){if(e.isArray(t[r])){for(var n="",i=0;i<t[r].length;i++)n+=u(t[r][i]);return n}return t[r]?u(t):""};return[a,o]},o=function(t){var n=t.pop();return e.isArray(n)?(t.push(n[0]),[o(t),n[1]]):(t.push(n),function(n){return t.map(function(t){return e.isString(t)?t:e.isFunction(t)?t(n):void 0}).join("")})},c=function(e,t){var a=e.indexOf(n);if(-1===a){if(void 0===t)return function(){return e};throw new Error("unclosed loop: "+t)}var f=e.slice(0,a),l=e.slice(a),s=l.indexOf(r)+2;if(1===s)throw new Error("unclosed tag: "+l);var d=l.slice(0,s),v=l.slice(s);if(0===d.lastIndexOf("{{#",0)){var h=u(d,v),m=h[0],p=c(h[1],t);return o([f,m,p])}if(0===d.lastIndexOf("{{!",0)){var p=c(v,t);return o([f,p])}if(0===d.lastIndexOf("{{/",0)){if(d.slice(3,-2)===t){var y=function(){return f};return[y,v]}throw new Error("unexpected closing loop: "+d)}var y=i(d),p=c(v,t);return o([f,y,p])};return function(e,t){return c(e)(t)}}),define("muu-update-dom",["muu-js-helpers"],function(e){"use strict";var t=function(t,n){var r=e.map(t.attributes,function(e){return e.name}),i=e.map(n.attributes,function(e){return e.name});e.forEach(r,function(e){n.hasAttribute(e)||"__IE8__"===e.substr(0,7)||t.removeAttribute(e)}),e.forEach(i,function(e){t.getAttribute(e)!==n.getAttribute(e)&&t.setAttribute(e,n.getAttribute(e))})},n=function(r,i){var u=r.childNodes.length,o=i.childNodes.length;if(r.nodeType===i.nodeType&&r.nodeName===i.nodeName&&r.type===i.type){if(1===r.nodeType){var c=e.filter(r.classList,function(e){return 0===e.lastIndexOf("muu-",0)});t(r,i),e.forEach(c,function(e){r.classList.add(e)})}else 3===r.nodeType&&(r.nodeValue=i.nodeValue);if(1!==r.nodeType||!r.classList.contains("muu-isolate")){for(var a=o;u>a;a++)r.removeChild(r.childNodes[o]);for(a=u;o>a;a++)r.appendChild(i.childNodes[u]);for(a=0;u>a&&o>a;a++)n(r.childNodes[a],i.childNodes[a])}}else r.parentNode.replaceChild(i,r)};return n}),define("muu-directive",["muu-dom-helpers","muu-js-helpers","muu-update-dom"],function(e,t,n){"use strict";var r=function(r,i,u){var o=this;r.innerHTML="<div></div>";var c=function(t){var n="data-on"+t.type;if(t.target.hasAttribute(n)){var i=t.target.getAttribute(n),u=e.createEvent("muu-"+i,t);r.dispatchEvent(u)}};this.update=function(a){var f=document.createElement("div");f.innerHTML=u.renderer(i,a),n(r.children[0],f),t.forEach(["keydown","keyup","click","change","search"],function(e){var n="[data-on"+e+"]";t.forEach(o.querySelectorAll(n),function(t){t.addEventListener(e,c,!1)})});var l=e.createEvent("muu-parent-update"),s=this.querySelectorAll("muu.muu-initialised");t.forEach(s,function(e){e.dispatchEvent(l)}),u.linkAll(o)},this.querySelectorAll=function(e){var n=r.querySelectorAll(e),i=r.querySelectorAll(".muu-isolate"),u=t.union(t.map(i,function(t){return t.querySelectorAll(e)}));return t.difference(n,u)},this.querySelector=function(e){var t=o.querySelectorAll(e);return t.length>0?t[0]:void 0},this.getModel=function(n,r){if(void 0===n){var i={};return t.forEach(o.querySelectorAll("[name]"),function(e){i[e.name]=o.getModel(e.name)}),i}var u=o.querySelector("[name="+n+"]");if(void 0===u)return r;if("checkbox"===u.type)return u.checked;if("radio"===u.type){var c=o.querySelectorAll("[name="+n+"]");return e.getRadio(c)||r}return u.value},this.setModel=function(t,n){var r=o.querySelector("[name="+t+"]");if("checkbox"===r.type)r.checked=n;else if("radio"===r.type){var i=o.querySelectorAll("[name="+t+"]");e.setRadio(i,n)}else r.value=n}};return r}),define("muu",["muu-template","muu-directive","muu-js-helpers","muu-dom-helpers"],function(e,t,n,r){"use strict";var i=function(i){var u=this,o={};this.config=i||{},this.renderer=u.config.renderer||e,this.registerDirective=function(e,t,n){return o[e]={template:t,link:n},u},this.registerModule=function(e){return e(u),u},this.link=function(e,n){if(void 0===n&&(n=e.getAttribute("type")),!o.hasOwnProperty(n))throw new Error("Unknown directive type: "+n);var i=o[n].template,c=o[n].link,a=new t(e,i,u),f=c(a,e);return e.classList.add("muu-isolate"),e.classList.add("muu-initialised"),u.config.debug&&(e.directive=a),void 0!==f&&r.destroy(e,f),a},this.linkAll=function(e){var t=n.filter(e.querySelectorAll("muu"),function(e){return!e.classList.contains("muu-initialised")});return n.map(t,function(e){return u.link(e)})}};return i});2 -1 //# sourceMappingURL=muu.min.js.ma2 -1 \ No newline at end of file
diff --git a/muu.min.js.map b/muu.min.js.map
@@ -1 +0,0 @@1 -1 {"version":3,"file":"muu.min.js","sources":["muu-js-helpers.js","muu-dom-helpers.js","muu-template.js","muu-update-dom.js","muu-directive.js","muu.js"],"names":["define","_","objToString","value","Object","prototype","toString","call","isString","isArray","Array","isFunction","once","fn","result","called","apply","this","arguments","indexOf","array","i","length","forEach","map","results","push","filter","union","arrays","j","difference","a","b","flatten","o","item","concat","entityMap","&","<",">","\"","'","/","$","DELAY","escapeHtml","string","String","replace","s","createEvent","type","detail","CustomEvent","event","document","initCustomEvent","on","element","eventName","callback","addEventListener","removeEventListener","ready","_fn","readyState","u1","u2","window","isDescendant","desc","root","parentNode","destroy","unregister","intervalID","setInterval","clearInterval","getRadio","options","checked","setRadio","openTag","closeTag","parseVariableTemplate","template","content","slice","data","pairs","split","pair","v","key","trim","join","parseLoopTemplate","tag","afterTag","tagName","parseTemplate","inner","afterLoop","render","last","pop","loopName","openIndex","Error","beforeTag","tmp","closeIndex","lastIndexOf","loop","after","updateAttributes","target","source","targetAttrNames","attributes","name","sourceAttrNames","hasAttribute","substr","removeAttribute","getAttribute","setAttribute","updateDOM","nt","childNodes","ns","nodeType","nodeName","muuClasses","classList","cls","add","nodeValue","contains","removeChild","appendChild","replaceChild","Directive","registry","self","innerHTML","eventCallback","originalEvent","attrName","dispatchEvent","update","createElement","renderer","children","eventType","selector","querySelectorAll","updateEvent","subDirectives","linkAll","hits","isolations","isolated","isolation","querySelector","all","getModel","_default","model","setModel","muuTemplate","Registry","config","directives","registerDirective","link","registerModule","module","hasOwnProperty","directive","unlink","debug","elements"],"mappings":"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B,KAAArH,MAKA,OAAAiH;ALlIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC/KA,ADgLA;AC/KA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,ACnKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,AC/KA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClFA,ADmFA;AClFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,AClLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","sourcesContent":["/**\n * Minimal implementation of an underscore/lodash subset.\n * @module muu-js-helpers\n */\ndefine('muu-js-helpers',[],function() {\n \"use strict\";\n\n /** @lends module:muu-js-helpers */\n var _ = {};\n\n /**\n * @param {object} value\n * @return {string}\n */\n var objToString = function(value) {\n return Object.prototype.toString.call(value);\n };\n\n /**\n * @param {*} value\n * @return {boolean}\n */\n _.isString = function(value) {\n return typeof value === 'string' || objToString(value) === '[object String]';\n };\n\n /**\n * @function\n * @param {*} value\n * @return {boolean}\n */\n _.isArray = Array.isArray;\n\n /**\n * @param {*} value\n * @return {boolean}\n */\n _.isFunction = function(value) {\n return typeof value === 'function';\n };\n\n /**\n * @param {function} fn\n * @return {function}\n */\n _.once = function(fn) {\n var result;\n var called = false;\n\n return function() {\n if (!called) {\n result = fn.apply(this, arguments);\n called = true;\n }\n return result;\n };\n };\n\n /**\n * @param {array} array\n * @param {*} value\n * @return {number}\n */\n _.indexOf = function(array, value) {\n if ('indexOf' in array) {\n return array.indexOf(value);\n }\n\n for (var i = 0; i < array.length; i++) {\n if (array[i] === value) {\n return i;\n }\n }\n return -1;\n };\n\n /**\n * @param {array} array\n * @param {function} fn\n */\n _.forEach = function(array, fn) {\n if ('forEach' in array) {\n return array.forEach(fn);\n }\n\n for (var i = 0; i < array.length; i++) {\n fn(array[i]);\n }\n };\n\n /**\n * @param {array} array\n * @param {function} fn\n * @return {array}\n */\n _.map = function(array, fn) {\n if ('map' in array) {\n return array.map(fn);\n }\n\n var results = [];\n for (var i = 0; i < array.length; i++) {\n results.push(fn(array[i]));\n }\n return results;\n };\n\n /**\n * @param {array} array\n * @param {function} fn\n * @return {array}\n */\n _.filter = function(array, fn) {\n if ('filter' in array) {\n return array.filter(fn);\n }\n\n var results = [];\n for (var i = 0; i < array.length; i++) {\n if (fn(array[i])) {\n results.push(array[i]);\n }\n }\n return results;\n };\n\n /**\n * @param {array[]} arrays\n * @return {array}\n */\n _.union = function(arrays) {\n var results = [];\n for (var i = 0; i < arrays.length; i++) {\n for (var j = 0; j < arrays[i].length; j++) {\n if (_.indexOf(results, arrays[i][j]) === -1) {\n results.push(arrays[i][j]);\n }\n }\n }\n return results;\n };\n\n /**\n * @param {array} a\n * @param {array} b\n * @return {array}\n */\n _.difference = function(a, b) {\n var results = [];\n for (var i = 0; i < a.length; i++) {\n if (_.indexOf(b, a[i]) === -1) {\n results.push(a[i]);\n }\n }\n return results;\n };\n\n /**\n * @param {array} a\n * @return {array}\n */\n _.flatten = function(a) {\n var o = [];\n _.forEach(a, function(item) {\n if (_.isArray(item)) {\n o = o.concat(_.flatten(item));\n } else {\n o.push(item);\n }\n });\n return o;\n };\n\n return _;\n});\n\n","/**\n * DOM related helper functions\n * @module muu-dom-helpers\n */\ndefine('muu-dom-helpers',['muu-js-helpers'], function(_) {\n \"use strict\";\n\n var entityMap = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n '/': '/'\n };\n\n /** @lends module:muu-dom-helpers */\n var $ = {};\n\n $.DELAY = 1000;\n\n /**\n * @param {string} string\n * @return {string} - escaped HTML\n */\n $.escapeHtml = function(string) {\n return String(string).replace(/[&<>\"'\\/]/g, function(s) {\n return entityMap[s];\n });\n };\n\n /**\n * Cross browser custom events.\n *\n * See https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events\n *\n * *Note*: IE does not seem to like it when you use existing event names\n * with this.\n *\n * @param {string} type\n * @param {*} detail\n * @return {DOMEvent}\n */\n $.createEvent = function(type, detail) {\n if (typeof CustomEvent === 'function') {\n return new CustomEvent(type, {\n detail: detail\n });\n } else {\n var event = document.createEvent('CustomEvent');\n event.initCustomEvent(type, false, true, detail);\n return event;\n }\n };\n\n /**\n * @param {DOMElement} element\n * @param {string} eventName\n * @param {function} callback\n * @return {Function()} An unregister function\n */\n $.on = function(element, eventName, callback) {\n element.addEventListener(eventName, callback, false);\n return function() {\n element.removeEventListener(eventName, callback, false);\n };\n };\n\n /**\n * @param {function} fn\n * @return {Function()} An unregister function\n */\n $.ready = function(fn) {\n var _fn = _.once(fn);\n if (document.readyState === 'complete') {\n _fn();\n return function() {};\n } else {\n var u1 = $.on(document, 'DOMContentLoaded', _fn);\n var u2 = $.on(window, 'load', _fn);\n return function() {\n u1();\n u2();\n };\n }\n };\n\n $.isDescendant = function(desc, root) {\n return !!desc && (desc === root || $.isDescendant(desc.parentNode, root));\n };\n\n /**\n * Execute a function when `element` is removed from the DOM.\n *\n * @param {DOMElement} element\n * @param {function} fn\n * @return {Function()} An unregister function\n */\n $.destroy = function(element, fn) {\n var unregister;\n\n if (false) {\n var observer = new MutationObserver(function() {\n if (!$.isDescendant(element, document)) {\n fn();\n unregister();\n }\n });\n\n observer.observe(document, {\n childList: true,\n subtree: true\n });\n\n unregister = _.once(function() {\n observer.disconnect();\n observer = undefined;\n });\n } else {\n var intervalID = setInterval(function() {\n if (!$.isDescendant(element, document)) {\n fn();\n unregister();\n }\n }, $.DELAY);\n\n unregister = function() {\n clearInterval(intervalID);\n };\n }\n\n return unregister;\n };\n\n /**\n * @param {DOMElement[]} options\n * @return {string}\n */\n $.getRadio = function(options) {\n for (var i = 0; i < options.length; i++) {\n if (options[i].checked) {\n return options[i].value;\n }\n }\n };\n\n /**\n * @param {DOMElement[]} options\n * @param {string} value\n */\n $.setRadio = function(options, value) {\n for (var i = 0; i < options.length; i++) {\n if (options[i].value === value) {\n options[i].checked = true;\n } else {\n options[i].checked = false;\n }\n }\n };\n\n return $;\n});\n\n","/**\n * minimal mustache insipred templating\n *\n * ## Variables\n *\n * Variables are created with a `{{name}}` tag. These are always escaped.\n *\n * ## Loops\n *\n * Loops render blocks of text a number of times, depending on the value of\n * the key in the current context.\n *\n * A loop begins with a pound and ends with a slash. That is, {{#person}}\n * begins a \"person\" section while {{/person}} ends it.\n *\n * If the value is an array, the block is repeated for each item in that array.\n * In any other case, the block is rendered with the outer scope, but only if\n * the value is truthy.\n *\n * ## Comments\n *\n * Comments begin with a bang and are ignored.\n *\n * ## Pairs\n *\n * Pairs look like JSON objects. The result is a space separated list of all\n * keys with truthy values.\n *\n * ```\n * muuTemplate('{{foo: var1, bar: var2, baz: var3}}', {\n * var1: true,\n * var2: false,\n * var3: true\n * }); // 'foo baz'\n * ```\n *\n * @module muu-template\n * @param {string} template\n * @param {object} data\n * @return {string}\n */\ndefine('muu-template',['muu-js-helpers', 'muu-dom-helpers'], function(_, $) {\n \"use strict\";\n\n var openTag = '{{';\n var closeTag = '}}';\n\n var parseVariableTemplate = function(template) {\n var content = template.slice(2, -2);\n\n if (template.indexOf(':') === -1) {\n return function(data) {\n return $.escapeHtml(data[content] || '');\n };\n } else {\n var pairs = content.split(',').map(function(pair) {\n var v = pair.split(':');\n var key = v[0].trim();\n var value = v.slice(1).join(':').trim();\n return [key, value];\n });\n\n return function(data) {\n var results = [];\n\n for (var i = 0; i < pairs.length; i++) {\n var key = pairs[i][0];\n var value = pairs[i][1];\n\n if (data[value]) {\n results.push(key);\n }\n }\n\n return $.escapeHtml(results.join(' '));\n };\n }\n };\n\n var parseLoopTemplate = function(tag, afterTag) {\n var tagName = tag.slice(3, -2);\n\n var v = parseTemplate(afterTag, tagName);\n var inner = v[0];\n var afterLoop = v[1];\n\n var render = function(data) {\n if (_.isArray(data[tagName])) {\n var result = '';\n for (var i = 0; i < data[tagName].length; i++) {\n result += inner(data[tagName][i]);\n }\n return result;\n } else if (data[tagName]) {\n return inner(data);\n } else {\n return '';\n }\n };\n\n return [render, afterLoop];\n };\n\n var concat = function(a) {\n var last = a.pop();\n\n if (_.isArray(last)) {\n a.push(last[0]);\n return [concat(a), last[1]];\n } else {\n a.push(last);\n\n return function(data) {\n return a.map(function(item) {\n if (_.isString(item)) {\n return item;\n } else if (_.isFunction(item)) {\n return item(data);\n }\n }).join('');\n };\n }\n };\n\n var parseTemplate = function(template, loopName) {\n var openIndex = template.indexOf(openTag);\n if (openIndex === -1) {\n if (loopName === void 0) {\n return function() {\n return template;\n };\n } else {\n throw new Error('unclosed loop: ' + loopName);\n }\n } else {\n var beforeTag = template.slice(0, openIndex);\n var tmp = template.slice(openIndex);\n\n var closeIndex = tmp.indexOf(closeTag) + 2;\n if (closeIndex === 1) {\n throw new Error('unclosed tag: ' + tmp);\n }\n var tag = tmp.slice(0, closeIndex);\n var afterTag = tmp.slice(closeIndex);\n\n if (tag.lastIndexOf('{{#', 0) === 0) {\n var v = parseLoopTemplate(tag, afterTag);\n var loop = v[0];\n var after = parseTemplate(v[1], loopName);\n return concat([beforeTag, loop, after]);\n } else if (tag.lastIndexOf('{{!', 0) === 0) {\n var after = parseTemplate(afterTag, loopName);\n return concat([beforeTag, after]);\n } else if (tag.lastIndexOf('{{/', 0) === 0) {\n if (tag.slice(3, -2) === loopName) {\n var render = function() {\n return beforeTag;\n };\n return [render, afterTag];\n } else {\n throw new Error('unexpected closing loop: ' + tag);\n }\n } else {\n var render = parseVariableTemplate(tag);\n var after = parseTemplate(afterTag, loopName);\n return concat([beforeTag, render, after]);\n }\n }\n };\n\n return function(template, data) {\n return parseTemplate(template)(data);\n };\n});\n\n","/**\n * Recreate DOM `source` in `target` by making only small adjustments.\n *\n * *The following section explains details about the current implementation.\n * These are likely to change in the future.*\n *\n * The algorithms is relatively simple. It just iterates through all top level\n * nodes. If a node has a different `nodeType` (e.g. text or element) or a\n * different `nodeName` (e.g. div or ul) it is replaced completely and the\n * algorithm proceeds with the node's children recursively. Otherwise, only\n * the nodes's attributes are updated.\n *\n * Note that non-attribute properties (e.g. value) are lost in the first case\n * and preserved in the second.\n *\n * If the algorithm encounters an element with the class `muu-isolate` it does\n * not recurse into its children. This way, you can protect dynamically\n * generated content from being overwritten.\n *\n * @module muu-update-dom\n * @param {DOMElement} target\n * @param {DOMElement} source\n */\ndefine('muu-update-dom',['muu-js-helpers'], function(_) {\n \"use strict\";\n\n var updateAttributes = function(target, source) {\n var targetAttrNames = _.map(target.attributes, function(item) {\n return item.name;\n });\n var sourceAttrNames = _.map(source.attributes, function(item) {\n return item.name;\n });\n\n _.forEach(targetAttrNames, function(name) {\n // NOTE: ie8.js creates some attribute\n if (!source.hasAttribute(name) && name.substr(0, 7) !== '__IE8__') {\n target.removeAttribute(name);\n }\n });\n _.forEach(sourceAttrNames, function(name) {\n if (target.getAttribute(name) !== source.getAttribute(name)) {\n target.setAttribute(name, source.getAttribute(name));\n }\n });\n };\n\n var updateDOM = function(target, source) {\n var nt = target.childNodes.length;\n var ns = source.childNodes.length;\n\n if (target.nodeType === source.nodeType && target.nodeName === source.nodeName && target.type === source.type) {\n if (target.nodeType === 1) {\n var muuClasses = _.filter(target.classList, function(cls) {\n return cls.lastIndexOf('muu-', 0) === 0;\n });\n updateAttributes(target, source);\n _.forEach(muuClasses, function(cls) {\n target.classList.add(cls);\n });\n } else if (target.nodeType === 3) {\n target.nodeValue = source.nodeValue;\n }\n\n if (target.nodeType !== 1 || !target.classList.contains('muu-isolate')) {\n for (var i = ns; i < nt; i++) {\n target.removeChild(target.childNodes[ns]);\n }\n for (i = nt; i < ns; i++) {\n target.appendChild(source.childNodes[nt]);\n }\n for (i = 0; i < nt && i < ns; i++) {\n updateDOM(target.childNodes[i], source.childNodes[i]);\n }\n }\n } else {\n target.parentNode.replaceChild(source, target);\n }\n };\n\n return updateDOM;\n});\n\n","/**\n * Exports the {@link Directive} class.\n * @module muu-directive\n */\ndefine('muu-directive',['muu-dom-helpers', 'muu-js-helpers', 'muu-update-dom'], function($, _, updateDOM) {\n \"use strict\";\n\n /**\n * A directive is linked to a DOMElement and manages the DOM tree below\n * that element (excluding any isolated subtrees, e.g. those managed by\n * subdirectives).\n *\n * It provides a set of methods to interact with the managed part of the\n * DOM. This is separated into three distinct parts:\n *\n * - You can push data to the DOM using the {@link Directive#update}\n * method. The DOM will than be updated using the template that was\n * provided at construction.\n * - You can get data from the DOM using the {@link Directive#getModel}\n * method. This is however restricted to form field by design.\n * - You can react to DOM events by specifying an alias for them. In the\n * template, you might for example add the attribute\n * `data-onclick=\"custom\"` to an element. When there is `click` event on\n * that element, a `muu-custom` event will be triggered on the\n * directive's root element.\n *\n * Directives are typically not created directly but via {@link\n * Registry#link}.\n *\n * @constructs Directive\n * @param {DOMElement} root\n * @param {string} template\n * @param {Muu} registry\n */\n var Directive = function(root, template, registry) {\n var self = this;\n\n root.innerHTML = '<div></div>';\n\n var eventCallback = function(originalEvent) {\n var attrName = 'data-on' + originalEvent.type;\n if (originalEvent.target.hasAttribute(attrName)) {\n var eventName = originalEvent.target.getAttribute(attrName);\n var event = $.createEvent('muu-' + eventName, originalEvent);\n root.dispatchEvent(event);\n }\n };\n\n /**\n * Rerender `template` with `data` and push the changes to the DOM.\n *\n * See {@link module:muu-update-dom} for details. The templating system\n * can be defined in the {@link Registry}.\n *\n * @param {Object.<string, *>} data\n */\n this.update = function(data) {\n var tmp = document.createElement('div');\n tmp.innerHTML = registry.renderer(template, data);\n\n updateDOM(root.children[0], tmp);\n\n _.forEach(['keydown', 'keyup', 'click', 'change', 'search'], function(eventType) {\n var selector = '[data-on' + eventType + ']';\n _.forEach(self.querySelectorAll(selector), function(element) {\n element.addEventListener(eventType, eventCallback, false);\n });\n });\n\n var updateEvent = $.createEvent('muu-parent-update');\n var subDirectives = this.querySelectorAll('muu.muu-initialised');\n _.forEach(subDirectives, function(element) {\n element.dispatchEvent(updateEvent);\n });\n\n registry.linkAll(self);\n };\n\n /**\n * A variant of `querySelectorAll` that returns only elements from\n * the managed part of the DOM.\n *\n * @private\n * @param {string} selector\n * @return {DOMElement[]} All child elements that match the given\n * selector and are not isolated.\n */\n this.querySelectorAll = function(selector) {\n var hits = root.querySelectorAll(selector);\n\n // NOTE: querySelectorAll returns all elements in the tree that\n // match the given selector. findAll does the same with *relative\n // selectors* but does not seem to be available yet.\n var isolations = root.querySelectorAll('.muu-isolate');\n var isolated = _.union(_.map(isolations, function(isolation) {\n return isolation.querySelectorAll(selector);\n }));\n\n return _.difference(hits, isolated);\n };\n\n /**\n * A variant of `querySelector` that returns only elements from the\n * managed part of the DOM.\n *\n * @private\n * @param {String} selector\n * @return {DOMElement} First child element that matches the given\n * selector and is not isolated.\n */\n this.querySelector = function(selector) {\n var all = self.querySelectorAll(selector);\n if (all.length > 0) {\n return all[0];\n }\n };\n\n /**\n * Get all model data as a flat object.\n *\n * @return {Object.<string, string|number|boolean>}\n *//**\n * Get the value of a form input by name.\n *\n * In case of a checkbox, returns `boolean`.\n * In case of radioboxes, returns the value of the selected box.\n *\n * @param {string} name\n * @param {*} [_default]\n * @return {string|number|boolean|*}\n */\n this.getModel = function(name, _default) {\n if (name === void 0) {\n var model = {};\n _.forEach(self.querySelectorAll('[name]'), function(element) {\n model[element.name] = self.getModel(element.name);\n });\n return model;\n } else {\n var element = self.querySelector('[name=' + name + ']');\n if (element === void 0) {\n return _default;\n } else if (element.type === 'checkbox') {\n return element.checked;\n } else if (element.type === 'radio') {\n var options = self.querySelectorAll('[name=' + name + ']');\n return $.getRadio(options) || _default;\n } else {\n return element.value;\n }\n }\n };\n\n /**\n * Set the value of a form input by name.\n *\n * In case of a checkbox, sets `element.checked`.\n * In case of radioboxes, selects the box with matching value.\n *\n * @param {string} name\n * @param {string|number|boolean} value\n */\n this.setModel = function(name, value) {\n var element = self.querySelector('[name=' + name + ']');\n if (element.type === 'checkbox') {\n element.checked = value;\n } else if (element.type === 'radio') {\n var options = self.querySelectorAll('[name=' + name + ']');\n $.setRadio(options, value);\n } else {\n element.value = value;\n }\n };\n };\n\n return Directive;\n});\n\n","/**\n * Exports the {@link Registry} class.\n * @module muu\n */\ndefine('muu',['muu-template', 'muu-directive', 'muu-js-helpers', 'muu-dom-helpers'], function(muuTemplate, Directive, _, $) {\n \"use strict\";\n\n /**\n * @constructs Registry\n * @param {object} config The config object may have following properties:\n *\n * - **debug** - `{boolean}` - Enable debug mode. In debug mode,\n * directive objects are available as properties from the DOM as\n * `element.directive`.\n * - **renderer** - `{Function(string, object)}` - The template renderer\n * to be used. Defaults to {@link module:muu-template}.\n */\n var Registry = function(config) {\n var self = this;\n var directives = {};\n\n this.config = config || {};\n this.renderer = self.config.renderer || muuTemplate;\n\n /**\n * Register a new type of {@link Directive}\n *\n * @param {string} type\n * @param {string} template\n * @param {Function(Directive, DOMElement): function} link The link\n * function is called with an instance of {@link Directive} and a\n * DOMElement when {@link Registry#link} is executed.\n *\n * It is the only place where you can access a directive and\n * therefore the place where you define its behavior.\n *\n * This typically means to make an initial call to {@link\n * Directive#update} and to add some event listeners. You should also\n * return an *unlink* function that clears all external references in\n * order to avoid memory leaks.\n * @return {Registry} this\n */\n this.registerDirective = function(type, template, link) {\n directives[type] = {\n template: template,\n link: link\n };\n return self;\n };\n\n /**\n * Shortcut for wrapping calls to {@link Registry} in a function.\n *\n * This can be esepcially helpful if that function is defined in a\n * different module.\n *\n * ```.js\n * define('foobar', [], function() {\n * return function(registry) {\n * registry\n * .registerDirective('foo', '...', function() {...})\n * .registerDirective('bar', '...', function() {...});\n * };\n * });\n *\n * require(['foobar'], function(foobar) {\n * var registry = new Registry();\n * registry.registerModule(foobar);\n * });\n * ```\n *\n * @param {Function(Registry)}\n * @return {Registry} this\n */\n this.registerModule = function(module) {\n module(self);\n return self;\n };\n\n /**\n * Create and initialise a {@link Directive} for `element`.\n *\n * @param {DOMElement} element\n * @param {string} type\n * @return {Directive}\n */\n this.link = function(element, type) {\n if (type === void 0) {\n type = element.getAttribute('type');\n }\n\n if (!directives.hasOwnProperty(type)) {\n throw new Error('Unknown directive type: ' + type);\n }\n\n var template = directives[type].template;\n var link = directives[type].link;\n\n var directive = new Directive(element, template, self);\n var unlink = link(directive, element);\n element.classList.add('muu-isolate');\n element.classList.add('muu-initialised');\n\n if (self.config.debug) {\n element.directive = directive;\n }\n\n if (unlink !== void 0) {\n $.destroy(element, unlink);\n }\n\n return directive;\n };\n\n /**\n * Link all directives that can be found inside `root`.\n *\n * @param {DOMElement} root\n * @return {Directive[]}\n */\n this.linkAll = function(root) {\n // NOTE: root may be a DOM Node or a directive\n var elements = _.filter(root.querySelectorAll('muu'), function(element) {\n return !element.classList.contains('muu-initialised');\n });\n return _.map(elements, function(element) {\n return self.link(element);\n });\n };\n };\n\n return Registry;\n});\n\n"]1 -1 \ No newline at end of file