diff --git a/demo-386.scss b/demo-386.scss
index 2ceb4d8..96ffc9d 100644
--- a/demo-386.scss
+++ b/demo-386.scss
@@ -59,6 +59,15 @@ nav {
}
+/**
+ *
+ *
+ */
+main {
+ max-width: 960px;
+ margin: 2em auto 0;
+}
+
/**
* footer
*
@@ -66,10 +75,6 @@ nav {
*/
footer {
- position: absolute;
- bottom: 0;
- z-index: -1;
-
text-align: center;
font-size: 3rem;
width: 100%;
@@ -84,13 +89,15 @@ footer {
/**
- * panel
+ * section
*
*
*/
-.panel {
- padding: 6px 0;
+.section {
+ padding: 4em;
+ margin: 1em 0;
+ line-height: 1.8;
background-color: $background-contrast-color;
}
@@ -190,8 +197,3 @@ footer {
}
}
}
-
-.section {
- padding: 6em;
- line-height: 1.8;
-}
diff --git a/dist/css/demo-386.css b/dist/css/demo-386.css
index 30fceef..1050216 100644
--- a/dist/css/demo-386.css
+++ b/dist/css/demo-386.css
@@ -1,186 +1 @@
-@charset "UTF-8";
-
-/**
- * variables
- *
- */
-
-/**
- * default elements
- *
- */
-
-body {
- color: #000;
- background-color: #000084;
- font-family: "PxPlus IBM VGA8", sans-serif;
- font-style: normal;
- font-size: 1.2rem;
-}
-
-*:first-letter {
- color: #fefe5b;
-}
-
-a {
- color: #000;
- text-decoration: none;
-}
-
-/**
- * navigation
- *
- *
- */
-
-nav ul {
- list-style: none;
- border: 3px solid #000;
- margin: 0;
- padding: 0.6em 0.8em;
-}
-
-nav ul a {
- display: block;
- padding: 0.1em;
- margin: -0.1em;
-}
-
-nav ul a:hover,
-nav ul a.current {
- color: #fff;
- background-color: #000;
-}
-
-/**
- * footer
- *
- *
- */
-
-footer {
- position: absolute;
- bottom: 0;
- z-index: -1;
- text-align: center;
- font-size: 3rem;
- width: 100%;
- background: #000;
- padding: 0.8em 0;
-}
-
-footer i {
- color: #fff !important;
-}
-
-/**
- * panel
- *
- *
- */
-
-.panel {
- padding: 6px 0;
- background-color: #bbbbbb;
-}
-
-/**
- * icons
- *
- *
- */
-
-[class^=icon-tiny],
-[class*=" icon-tiny"] {
- font-family: "PxPlus IBM VGA8", sans-serif !important;
- font-style: normal;
- color: #fefe5b;
-}
-
-.icon-tiny-hamburger-open,
-.icon-tiny-hamburger-close {
- position: absolute;
- top: 3px;
- transition: transform 0.2s;
- margin: 3px;
-}
-
-.icon-tiny-hamburger-open:after,
-.icon-tiny-hamburger-close:after {
- content: "\2BC5";
-}
-
-.icon-tiny-hamburger-open {
- transform: rotate(0deg);
-}
-
-.icon-tiny-hamburger-close {
- transform: rotate(180deg);
-}
-
-/**
- * tiny-tiny-hamburger
- *
- *
- */
-
-.tiny-hamburger__inner {
- padding: 4px 8px 5px;
-}
-
-.tiny-hamburger__modal {
- height: auto;
- max-height: 0;
- overflow: hidden;
- transition: max-height 0.2s;
-}
-
-.tiny-hamburger__button {
- -webkit-appearance: none;
- -moz-appearance: none;
- appearance: none;
- border: none;
- background: transparent;
- padding: 0.3em 0.5em;
-}
-
-.tiny-hamburger__button:hover {
- cursor: pointer;
- outline: none;
- background-color: #bbbbbb;
-}
-
-.tiny-hamburger__button:focus {
- outline: none;
-}
-
-.navbar {
- position: fixed;
- width: 100%;
- text-align: center;
- background-color: white;
-}
-
-.navbar li {
- display: inline-block;
- margin: 0 0.3em;
-}
-
-.navbar li a {
- display: block;
- transition: all 0.1s ease-in-out;
-}
-
-.navbar li a:hover {
- transform: scale(1.3);
-}
-
-.navbar li.current a {
- transform: scale(1.3);
-}
-
-.section {
- padding: 6em;
- line-height: 1.8;
-}
-
+body{color:#000;background-color:#000084;font-family:PxPlus IBM VGA8,sans-serif;font-style:normal;font-size:1.2rem}:first-letter{color:#fefe5b}a{color:#000;text-decoration:none}nav ul{list-style:none;border:3px solid #000;margin:0;padding:.6em .8em}nav ul a{display:block;padding:.1em;margin:-.1em}nav ul a.current,nav ul a:hover{color:#fff;background-color:#000}main{max-width:960px;margin:2em auto 0}footer{text-align:center;font-size:3rem;width:100%;background:#000;padding:.8em 0}footer i{color:#fff!important}.section{padding:4em;margin:1em 0;line-height:1.8;background-color:#bbb}[class*=" icon-tiny"],[class^=icon-tiny]{font-family:PxPlus IBM VGA8,sans-serif!important;font-style:normal;color:#fefe5b}.icon-tiny-hamburger-close,.icon-tiny-hamburger-open{position:absolute;top:3px;transition:transform .2s;margin:3px}.icon-tiny-hamburger-close:after,.icon-tiny-hamburger-open:after{content:"\2BC5"}.icon-tiny-hamburger-open{transform:rotate(0deg)}.icon-tiny-hamburger-close{transform:rotate(180deg)}.tiny-hamburger__inner{padding:4px 8px 5px}.tiny-hamburger__modal{height:auto;max-height:0;overflow:hidden;transition:max-height .2s}.tiny-hamburger__button{-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;background:transparent;padding:.3em .5em}.tiny-hamburger__button:hover{cursor:pointer;outline:none;background-color:#bbb}.tiny-hamburger__button:focus{outline:none}.navbar{position:fixed;width:100%;text-align:center;background-color:#fff}.navbar li{display:inline-block;margin:0 .3em}.navbar li a{display:block;transition:all .1s ease-in-out}.navbar li.current a,.navbar li a:hover{transform:scale(1.3)}
\ No newline at end of file
diff --git a/dist/index.html b/dist/index.html
index c9cb33b..8fc2d5c 100644
--- a/dist/index.html
+++ b/dist/index.html
@@ -11,16 +11,16 @@
-
-
-
-
+
+
+
+
One
@@ -57,9 +57,9 @@
DIY neutra kinfolk cold-pressed. Taxidermy cold-pressed meh glossier disrupt, synth wayfarers portland kogi paleo organic squid. Put a bird on it bicycle rights banh mi biodiesel bitters cornhole gochujang chicharrones umami hell of quinoa kogi tousled cardigan poutine. Jianbing 90's kogi poke, af edison bulb cray hella everyday carry chicharrones bitters tote bag ennui asymmetrical. Salvia listicle etsy taxidermy mlkshk, dreamcatcher humblebrag banjo chambray fanny pack before they sold out ethical. Hot chicken cronut tilde, kale chips fixie ethical waistcoat small batch succulents hella.
-
+
diff --git a/dist/js/demo-386.js b/dist/js/demo-386.js
index 97574c3..789cd1c 100644
--- a/dist/js/demo-386.js
+++ b/dist/js/demo-386.js
@@ -1,2713 +1 @@
-/******/ (function(modules) { // webpackBootstrap
-/******/ // The module cache
-/******/ var installedModules = {};
-/******/
-/******/ // The require function
-/******/ function __webpack_require__(moduleId) {
-/******/
-/******/ // Check if module is in cache
-/******/ if(installedModules[moduleId]) {
-/******/ return installedModules[moduleId].exports;
-/******/ }
-/******/ // Create a new module (and put it into the cache)
-/******/ var module = installedModules[moduleId] = {
-/******/ i: moduleId,
-/******/ l: false,
-/******/ exports: {}
-/******/ };
-/******/
-/******/ // Execute the module function
-/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
-/******/
-/******/ // Flag the module as loaded
-/******/ module.l = true;
-/******/
-/******/ // Return the exports of the module
-/******/ return module.exports;
-/******/ }
-/******/
-/******/
-/******/ // expose the modules object (__webpack_modules__)
-/******/ __webpack_require__.m = modules;
-/******/
-/******/ // expose the module cache
-/******/ __webpack_require__.c = installedModules;
-/******/
-/******/ // define getter function for harmony exports
-/******/ __webpack_require__.d = function(exports, name, getter) {
-/******/ if(!__webpack_require__.o(exports, name)) {
-/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
-/******/ }
-/******/ };
-/******/
-/******/ // define __esModule on exports
-/******/ __webpack_require__.r = function(exports) {
-/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
-/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
-/******/ }
-/******/ Object.defineProperty(exports, '__esModule', { value: true });
-/******/ };
-/******/
-/******/ // create a fake namespace object
-/******/ // mode & 1: value is a module id, require it
-/******/ // mode & 2: merge all properties of value into the ns
-/******/ // mode & 4: return value when already ns object
-/******/ // mode & 8|1: behave like require
-/******/ __webpack_require__.t = function(value, mode) {
-/******/ if(mode & 1) value = __webpack_require__(value);
-/******/ if(mode & 8) return value;
-/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
-/******/ var ns = Object.create(null);
-/******/ __webpack_require__.r(ns);
-/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
-/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
-/******/ return ns;
-/******/ };
-/******/
-/******/ // getDefaultExport function for compatibility with non-harmony modules
-/******/ __webpack_require__.n = function(module) {
-/******/ var getter = module && module.__esModule ?
-/******/ function getDefault() { return module['default']; } :
-/******/ function getModuleExports() { return module; };
-/******/ __webpack_require__.d(getter, 'a', getter);
-/******/ return getter;
-/******/ };
-/******/
-/******/ // Object.prototype.hasOwnProperty.call
-/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
-/******/
-/******/ // __webpack_public_path__
-/******/ __webpack_require__.p = "/";
-/******/
-/******/
-/******/ // Load entry module and return exports
-/******/ return __webpack_require__(__webpack_require__.s = 0);
-/******/ })
-/************************************************************************/
-/******/ ({
-
-/***/ "./demo-386.js":
-/*!*********************!*\
- !*** ./demo-386.js ***!
- \*********************/
-/*! no exports provided */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony import */ var riot__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! riot */ "./node_modules/riot/riot.esm.js");
-/* harmony import */ var _src_TinyOnePage_riot__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./src/TinyOnePage.riot */ "./src/TinyOnePage.riot");
-
-
-riot__WEBPACK_IMPORTED_MODULE_0__["register"]('tiny-one-page', _src_TinyOnePage_riot__WEBPACK_IMPORTED_MODULE_1__["default"]); // adding component with animate object
-
-riot__WEBPACK_IMPORTED_MODULE_0__["mount"]('tiny-one-page');
-
-/***/ }),
-
-/***/ "./demo-386.scss":
-/*!***********************!*\
- !*** ./demo-386.scss ***!
- \***********************/
-/*! no static exports found */
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-
-/***/ "./node_modules/riot/riot.esm.js":
-/*!***************************************!*\
- !*** ./node_modules/riot/riot.esm.js ***!
- \***************************************/
-/*! exports provided: __, component, install, mount, register, uninstall, unmount, unregister, version */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__", function() { return __; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "component", function() { return component; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "install", function() { return install; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mount", function() { return mount; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "register", function() { return register; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "uninstall", function() { return uninstall; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "unmount", function() { return unmount; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "unregister", function() { return unregister; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "version", function() { return version; });
-/* Riot v4.5.0, @license MIT */
-const COMPONENTS_IMPLEMENTATION_MAP = new Map(),
- DOM_COMPONENT_INSTANCE_PROPERTY = Symbol('riot-component'),
- PLUGINS_SET = new Set(),
- IS_DIRECTIVE = 'is',
- VALUE_ATTRIBUTE = 'value',
- ATTRIBUTES_KEY_SYMBOL = Symbol('attributes'),
- TEMPLATE_KEY_SYMBOL = Symbol('template');
-
-var globals = /*#__PURE__*/Object.freeze({
- COMPONENTS_IMPLEMENTATION_MAP: COMPONENTS_IMPLEMENTATION_MAP,
- DOM_COMPONENT_INSTANCE_PROPERTY: DOM_COMPONENT_INSTANCE_PROPERTY,
- PLUGINS_SET: PLUGINS_SET,
- IS_DIRECTIVE: IS_DIRECTIVE,
- VALUE_ATTRIBUTE: VALUE_ATTRIBUTE,
- ATTRIBUTES_KEY_SYMBOL: ATTRIBUTES_KEY_SYMBOL,
- TEMPLATE_KEY_SYMBOL: TEMPLATE_KEY_SYMBOL
-});
-
-/**
- * Remove the child nodes from any DOM node
- * @param {HTMLElement} node - target node
- * @returns {undefined}
- */
-function cleanNode(node) {
- clearChildren(node.childNodes);
-}
-/**
- * Clear multiple children in a node
- * @param {HTMLElement[]} children - direct children nodes
- * @returns {undefined}
- */
-
-
-function clearChildren(children) {
- Array.from(children).forEach(n => n.parentNode && n.parentNode.removeChild(n));
-}
-
-const EACH = 0;
-const IF = 1;
-const SIMPLE = 2;
-const TAG = 3;
-const SLOT = 4;
-var bindingTypes = {
- EACH,
- IF,
- SIMPLE,
- TAG,
- SLOT
-};
-/**
- * Create the template meta object in case of fragments
- * @param {TemplateChunk} componentTemplate - template chunk object
- * @returns {Object} the meta property that will be passed to the mount function of the TemplateChunk
- */
-
-function createTemplateMeta(componentTemplate) {
- const fragment = componentTemplate.dom.cloneNode(true);
- return {
- avoidDOMInjection: true,
- fragment,
- children: Array.from(fragment.childNodes)
- };
-}
-/* get rid of the @ungap/essential-map polyfill */
-
-
-const {
- indexOf: iOF
-} = [];
-
-const append = (get, parent, children, start, end, before) => {
- const isSelect = 'selectedIndex' in parent;
- let noSelection = isSelect;
-
- while (start < end) {
- const child = get(children[start], 1);
- parent.insertBefore(child, before);
-
- if (isSelect && noSelection && child.selected) {
- noSelection = !noSelection;
- let {
- selectedIndex
- } = parent;
- parent.selectedIndex = selectedIndex < 0 ? start : iOF.call(parent.querySelectorAll('option'), child);
- }
-
- start++;
- }
-};
-
-const eqeq = (a, b) => a == b;
-
-const identity = O => O;
-
-const indexOf = (moreNodes, moreStart, moreEnd, lessNodes, lessStart, lessEnd, compare) => {
- const length = lessEnd - lessStart;
- /* istanbul ignore if */
-
- if (length < 1) return -1;
-
- while (moreEnd - moreStart >= length) {
- let m = moreStart;
- let l = lessStart;
-
- while (m < moreEnd && l < lessEnd && compare(moreNodes[m], lessNodes[l])) {
- m++;
- l++;
- }
-
- if (l === lessEnd) return moreStart;
- moreStart = m + 1;
- }
-
- return -1;
-};
-
-const isReversed = (futureNodes, futureEnd, currentNodes, currentStart, currentEnd, compare) => {
- while (currentStart < currentEnd && compare(currentNodes[currentStart], futureNodes[futureEnd - 1])) {
- currentStart++;
- futureEnd--;
- }
-
- return futureEnd === 0;
-};
-
-const next = (get, list, i, length, before) => i < length ? get(list[i], 0) : 0 < i ? get(list[i - 1], -0).nextSibling : before;
-
-const remove = (get, parent, children, start, end) => {
- if (end - start < 2) parent.removeChild(get(children[start], -1));else {
- const range = parent.ownerDocument.createRange();
- range.setStartBefore(get(children[start], -1));
- range.setEndAfter(get(children[end - 1], -1));
- range.deleteContents();
- }
-}; // - - - - - - - - - - - - - - - - - - -
-// diff related constants and utilities
-// - - - - - - - - - - - - - - - - - - -
-
-
-const DELETION = -1;
-const INSERTION = 1;
-const SKIP = 0;
-const SKIP_OND = 50;
-
-const HS = (futureNodes, futureStart, futureEnd, futureChanges, currentNodes, currentStart, currentEnd, currentChanges) => {
- let k = 0;
- /* istanbul ignore next */
-
- let minLen = futureChanges < currentChanges ? futureChanges : currentChanges;
- const link = Array(minLen++);
- const tresh = Array(minLen);
- tresh[0] = -1;
-
- for (let i = 1; i < minLen; i++) tresh[i] = currentEnd;
-
- const keymap = new Map();
-
- for (let i = currentStart; i < currentEnd; i++) keymap.set(currentNodes[i], i);
-
- for (let i = futureStart; i < futureEnd; i++) {
- const idxInOld = keymap.get(futureNodes[i]);
-
- if (idxInOld != null) {
- k = findK(tresh, minLen, idxInOld);
- /* istanbul ignore else */
-
- if (-1 < k) {
- tresh[k] = idxInOld;
- link[k] = {
- newi: i,
- oldi: idxInOld,
- prev: link[k - 1]
- };
- }
- }
- }
-
- k = --minLen;
- --currentEnd;
-
- while (tresh[k] > currentEnd) --k;
-
- minLen = currentChanges + futureChanges - k;
- const diff = Array(minLen);
- let ptr = link[k];
- --futureEnd;
-
- while (ptr) {
- const {
- newi,
- oldi
- } = ptr;
-
- while (futureEnd > newi) {
- diff[--minLen] = INSERTION;
- --futureEnd;
- }
-
- while (currentEnd > oldi) {
- diff[--minLen] = DELETION;
- --currentEnd;
- }
-
- diff[--minLen] = SKIP;
- --futureEnd;
- --currentEnd;
- ptr = ptr.prev;
- }
-
- while (futureEnd >= futureStart) {
- diff[--minLen] = INSERTION;
- --futureEnd;
- }
-
- while (currentEnd >= currentStart) {
- diff[--minLen] = DELETION;
- --currentEnd;
- }
-
- return diff;
-}; // this is pretty much the same petit-dom code without the delete map part
-// https://github.com/yelouafi/petit-dom/blob/bd6f5c919b5ae5297be01612c524c40be45f14a7/src/vdom.js#L556-L561
-
-
-const OND = (futureNodes, futureStart, rows, currentNodes, currentStart, cols, compare) => {
- const length = rows + cols;
- const v = [];
- let d, k, r, c, pv, cv, pd;
-
- outer: for (d = 0; d <= length; d++) {
- /* istanbul ignore if */
- if (d > SKIP_OND) return null;
- pd = d - 1;
- /* istanbul ignore next */
-
- pv = d ? v[d - 1] : [0, 0];
- cv = v[d] = [];
-
- for (k = -d; k <= d; k += 2) {
- if (k === -d || k !== d && pv[pd + k - 1] < pv[pd + k + 1]) {
- c = pv[pd + k + 1];
- } else {
- c = pv[pd + k - 1] + 1;
- }
-
- r = c - k;
-
- while (c < cols && r < rows && compare(currentNodes[currentStart + c], futureNodes[futureStart + r])) {
- c++;
- r++;
- }
-
- if (c === cols && r === rows) {
- break outer;
- }
-
- cv[d + k] = c;
- }
- }
-
- const diff = Array(d / 2 + length / 2);
- let diffIdx = diff.length - 1;
-
- for (d = v.length - 1; d >= 0; d--) {
- while (c > 0 && r > 0 && compare(currentNodes[currentStart + c - 1], futureNodes[futureStart + r - 1])) {
- // diagonal edge = equality
- diff[diffIdx--] = SKIP;
- c--;
- r--;
- }
-
- if (!d) break;
- pd = d - 1;
- /* istanbul ignore next */
-
- pv = d ? v[d - 1] : [0, 0];
- k = c - r;
-
- if (k === -d || k !== d && pv[pd + k - 1] < pv[pd + k + 1]) {
- // vertical edge = insertion
- r--;
- diff[diffIdx--] = INSERTION;
- } else {
- // horizontal edge = deletion
- c--;
- diff[diffIdx--] = DELETION;
- }
- }
-
- return diff;
-};
-
-const applyDiff = (diff, get, parentNode, futureNodes, futureStart, currentNodes, currentStart, currentLength, before) => {
- const live = new Map();
- const length = diff.length;
- let currentIndex = currentStart;
- let i = 0;
-
- while (i < length) {
- switch (diff[i++]) {
- case SKIP:
- futureStart++;
- currentIndex++;
- break;
-
- case INSERTION:
- // TODO: bulk appends for sequential nodes
- live.set(futureNodes[futureStart], 1);
- append(get, parentNode, futureNodes, futureStart++, futureStart, currentIndex < currentLength ? get(currentNodes[currentIndex], 0) : before);
- break;
-
- case DELETION:
- currentIndex++;
- break;
- }
- }
-
- i = 0;
-
- while (i < length) {
- switch (diff[i++]) {
- case SKIP:
- currentStart++;
- break;
-
- case DELETION:
- // TODO: bulk removes for sequential nodes
- if (live.has(currentNodes[currentStart])) currentStart++;else remove(get, parentNode, currentNodes, currentStart++, currentStart);
- break;
- }
- }
-};
-
-const findK = (ktr, length, j) => {
- let lo = 1;
- let hi = length;
-
- while (lo < hi) {
- const mid = (lo + hi) / 2 >>> 0;
- if (j < ktr[mid]) hi = mid;else lo = mid + 1;
- }
-
- return lo;
-};
-
-const smartDiff = (get, parentNode, futureNodes, futureStart, futureEnd, futureChanges, currentNodes, currentStart, currentEnd, currentChanges, currentLength, compare, before) => {
- applyDiff(OND(futureNodes, futureStart, futureChanges, currentNodes, currentStart, currentChanges, compare) || HS(futureNodes, futureStart, futureEnd, futureChanges, currentNodes, currentStart, currentEnd, currentChanges), get, parentNode, futureNodes, futureStart, currentNodes, currentStart, currentLength, before);
-};
-/*! (c) 2018 Andrea Giammarchi (ISC) */
-
-
-const domdiff = (parentNode, // where changes happen
-currentNodes, // Array of current items/nodes
-futureNodes, // Array of future items/nodes
-options // optional object with one of the following properties
-// before: domNode
-// compare(generic, generic) => true if same generic
-// node(generic) => Node
-) => {
- if (!options) options = {};
- const compare = options.compare || eqeq;
- const get = options.node || identity;
- const before = options.before == null ? null : get(options.before, 0);
- const currentLength = currentNodes.length;
- let currentEnd = currentLength;
- let currentStart = 0;
- let futureEnd = futureNodes.length;
- let futureStart = 0; // common prefix
-
- while (currentStart < currentEnd && futureStart < futureEnd && compare(currentNodes[currentStart], futureNodes[futureStart])) {
- currentStart++;
- futureStart++;
- } // common suffix
-
-
- while (currentStart < currentEnd && futureStart < futureEnd && compare(currentNodes[currentEnd - 1], futureNodes[futureEnd - 1])) {
- currentEnd--;
- futureEnd--;
- }
-
- const currentSame = currentStart === currentEnd;
- const futureSame = futureStart === futureEnd; // same list
-
- if (currentSame && futureSame) return futureNodes; // only stuff to add
-
- if (currentSame && futureStart < futureEnd) {
- append(get, parentNode, futureNodes, futureStart, futureEnd, next(get, currentNodes, currentStart, currentLength, before));
- return futureNodes;
- } // only stuff to remove
-
-
- if (futureSame && currentStart < currentEnd) {
- remove(get, parentNode, currentNodes, currentStart, currentEnd);
- return futureNodes;
- }
-
- const currentChanges = currentEnd - currentStart;
- const futureChanges = futureEnd - futureStart;
- let i = -1; // 2 simple indels: the shortest sequence is a subsequence of the longest
-
- if (currentChanges < futureChanges) {
- i = indexOf(futureNodes, futureStart, futureEnd, currentNodes, currentStart, currentEnd, compare); // inner diff
-
- if (-1 < i) {
- append(get, parentNode, futureNodes, futureStart, i, get(currentNodes[currentStart], 0));
- append(get, parentNode, futureNodes, i + currentChanges, futureEnd, next(get, currentNodes, currentEnd, currentLength, before));
- return futureNodes;
- }
- }
- /* istanbul ignore else */
- else if (futureChanges < currentChanges) {
- i = indexOf(currentNodes, currentStart, currentEnd, futureNodes, futureStart, futureEnd, compare); // outer diff
-
- if (-1 < i) {
- remove(get, parentNode, currentNodes, currentStart, i);
- remove(get, parentNode, currentNodes, i + futureChanges, currentEnd);
- return futureNodes;
- }
- } // common case with one replacement for many nodes
- // or many nodes replaced for a single one
-
- /* istanbul ignore else */
-
-
- if (currentChanges < 2 || futureChanges < 2) {
- append(get, parentNode, futureNodes, futureStart, futureEnd, get(currentNodes[currentStart], 0));
- remove(get, parentNode, currentNodes, currentStart, currentEnd);
- return futureNodes;
- } // the half match diff part has been skipped in petit-dom
- // https://github.com/yelouafi/petit-dom/blob/bd6f5c919b5ae5297be01612c524c40be45f14a7/src/vdom.js#L391-L397
- // accordingly, I think it's safe to skip in here too
- // if one day it'll come out like the speediest thing ever to do
- // then I might add it in here too
- // Extra: before going too fancy, what about reversed lists ?
- // This should bail out pretty quickly if that's not the case.
-
-
- if (currentChanges === futureChanges && isReversed(futureNodes, futureEnd, currentNodes, currentStart, currentEnd, compare)) {
- append(get, parentNode, futureNodes, futureStart, futureEnd, next(get, currentNodes, currentEnd, currentLength, before));
- return futureNodes;
- } // last resort through a smart diff
-
-
- smartDiff(get, parentNode, futureNodes, futureStart, futureEnd, futureChanges, currentNodes, currentStart, currentEnd, currentChanges, currentLength, compare, before);
- return futureNodes;
-};
-/**
- * Check if a value is null or undefined
- * @param {*} value - anything
- * @returns {boolean} true only for the 'undefined' and 'null' types
- */
-
-
-function isNil(value) {
- return value === null || value === undefined;
-}
-/**
- * Check if an element is a template tag
- * @param {HTMLElement} el - element to check
- * @returns {boolean} true if it's a
- */
-
-
-function isTemplate(el) {
- return !isNil(el.content);
-}
-
-const EachBinding = Object.seal({
- // dynamic binding properties
- childrenMap: null,
- node: null,
- root: null,
- condition: null,
- evaluate: null,
- template: null,
- isTemplateTag: false,
- nodes: [],
- getKey: null,
- indexName: null,
- itemName: null,
- afterPlaceholder: null,
- placeholder: null,
-
- // API methods
- mount(scope, parentScope) {
- return this.update(scope, parentScope);
- },
-
- update(scope, parentScope) {
- const {
- placeholder
- } = this;
- const collection = this.evaluate(scope);
- const items = collection ? Array.from(collection) : [];
- const parent = placeholder.parentNode; // prepare the diffing
-
- const {
- newChildrenMap,
- batches,
- futureNodes
- } = createPatch(items, scope, parentScope, this); // patch the DOM only if there are new nodes
-
- if (futureNodes.length) {
- domdiff(parent, this.nodes, futureNodes, {
- before: placeholder,
- node: patch(Array.from(this.childrenMap.values()), parentScope)
- });
- } else {
- // remove all redundant templates
- unmountRedundant(this.childrenMap);
- } // trigger the mounts and the updates
-
-
- batches.forEach(fn => fn()); // update the children map
-
- this.childrenMap = newChildrenMap;
- this.nodes = futureNodes;
- return this;
- },
-
- unmount(scope, parentScope) {
- unmountRedundant(this.childrenMap, parentScope);
- this.childrenMap = new Map();
- this.nodes = [];
- return this;
- }
-
-});
-/**
- * Patch the DOM while diffing
- * @param {TemplateChunk[]} redundant - redundant tepmplate chunks
- * @param {*} parentScope - scope of the parent template
- * @returns {Function} patch function used by domdiff
- */
-
-function patch(redundant, parentScope) {
- return (item, info) => {
- if (info < 0) {
- const {
- template,
- context
- } = redundant.pop(); // notice that we pass null as last argument because
- // the root node and its children will be removed by domdiff
-
- template.unmount(context, parentScope, null);
- }
-
- return item;
- };
-}
-/**
- * Unmount the remaining template instances
- * @param {Map} childrenMap - map containing the children template to unmount
- * @param {*} parentScope - scope of the parent template
- * @returns {TemplateChunk[]} collection containing the template chunks unmounted
- */
-
-
-function unmountRedundant(childrenMap, parentScope) {
- return Array.from(childrenMap.values()).map((_ref) => {
- let {
- template,
- context
- } = _ref;
- return template.unmount(context, parentScope, true);
- });
-}
-/**
- * Check whether a template must be filtered from a loop
- * @param {Function} condition - filter function
- * @param {Object} context - argument passed to the filter function
- * @returns {boolean} true if this item should be skipped
- */
-
-
-function mustFilterItem(condition, context) {
- return condition ? Boolean(condition(context)) === false : false;
-}
-/**
- * Extend the scope of the looped template
- * @param {Object} scope - current template scope
- * @param {string} options.itemName - key to identify the looped item in the new context
- * @param {string} options.indexName - key to identify the index of the looped item
- * @param {number} options.index - current index
- * @param {*} options.item - collection item looped
- * @returns {Object} enhanced scope object
- */
-
-
-function extendScope(scope, _ref2) {
- let {
- itemName,
- indexName,
- index,
- item
- } = _ref2;
- scope[itemName] = item;
- if (indexName) scope[indexName] = index;
- return scope;
-}
-/**
- * Loop the current template items
- * @param {Array} items - expression collection value
- * @param {*} scope - template scope
- * @param {*} parentScope - scope of the parent template
- * @param {EeachBinding} binding - each binding object instance
- * @returns {Object} data
- * @returns {Map} data.newChildrenMap - a Map containing the new children template structure
- * @returns {Array} data.batches - array containing the template lifecycle functions to trigger
- * @returns {Array} data.futureNodes - array containing the nodes we need to diff
- */
-
-
-function createPatch(items, scope, parentScope, binding) {
- const {
- condition,
- template,
- childrenMap,
- itemName,
- getKey,
- indexName,
- root,
- isTemplateTag
- } = binding;
- const newChildrenMap = new Map();
- const batches = [];
- const futureNodes = [];
- items.forEach((item, index) => {
- const context = extendScope(Object.create(scope), {
- itemName,
- indexName,
- index,
- item
- });
- const key = getKey ? getKey(context) : index;
- const oldItem = childrenMap.get(key);
-
- if (mustFilterItem(condition, context)) {
- return;
- }
-
- const componentTemplate = oldItem ? oldItem.template : template.clone();
- const el = oldItem ? componentTemplate.el : root.cloneNode();
- const mustMount = !oldItem;
- const meta = isTemplateTag && mustMount ? createTemplateMeta(componentTemplate) : {};
-
- if (mustMount) {
- batches.push(() => componentTemplate.mount(el, context, parentScope, meta));
- } else {
- componentTemplate.update(context, parentScope);
- } // create the collection of nodes to update or to add
- // in case of template tags we need to add all its children nodes
-
-
- if (isTemplateTag) {
- futureNodes.push(...(meta.children || componentTemplate.children));
- } else {
- futureNodes.push(el);
- } // delete the old item from the children map
-
-
- childrenMap.delete(key); // update the children map
-
- newChildrenMap.set(key, {
- template: componentTemplate,
- context,
- index
- });
- });
- return {
- newChildrenMap,
- batches,
- futureNodes
- };
-}
-
-function create(node, _ref3) {
- let {
- evaluate,
- condition,
- itemName,
- indexName,
- getKey,
- template
- } = _ref3;
- const placeholder = document.createTextNode('');
- const parent = node.parentNode;
- const root = node.cloneNode();
- parent.insertBefore(placeholder, node);
- parent.removeChild(node);
- return Object.assign({}, EachBinding, {
- childrenMap: new Map(),
- node,
- root,
- condition,
- evaluate,
- isTemplateTag: isTemplate(root),
- template: template.createDOM(node),
- getKey,
- indexName,
- itemName,
- placeholder
- });
-}
-/**
- * Binding responsible for the `if` directive
- */
-
-
-const IfBinding = Object.seal({
- // dynamic binding properties
- node: null,
- evaluate: null,
- parent: null,
- isTemplateTag: false,
- placeholder: null,
- template: null,
-
- // API methods
- mount(scope, parentScope) {
- this.parent.insertBefore(this.placeholder, this.node);
- this.parent.removeChild(this.node);
- return this.update(scope, parentScope);
- },
-
- update(scope, parentScope) {
- const value = !!this.evaluate(scope);
- const mustMount = !this.value && value;
- const mustUnmount = this.value && !value;
-
- const mount = () => {
- const pristine = this.node.cloneNode();
- this.parent.insertBefore(pristine, this.placeholder);
- this.template = this.template.clone();
- this.template.mount(pristine, scope, parentScope);
- };
-
- switch (true) {
- case mustMount:
- mount();
- break;
-
- case mustUnmount:
- this.unmount(scope);
- break;
-
- default:
- if (value) this.template.update(scope, parentScope);
- }
-
- this.value = value;
- return this;
- },
-
- unmount(scope, parentScope) {
- this.template.unmount(scope, parentScope, true);
- return this;
- }
-
-});
-
-function create$1(node, _ref4) {
- let {
- evaluate,
- template
- } = _ref4;
- return Object.assign({}, IfBinding, {
- node,
- evaluate,
- parent: node.parentNode,
- placeholder: document.createTextNode(''),
- template: template.createDOM(node)
- });
-}
-
-const ATTRIBUTE = 0;
-const EVENT = 1;
-const TEXT = 2;
-const VALUE = 3;
-var expressionTypes = {
- ATTRIBUTE,
- EVENT,
- TEXT,
- VALUE
-};
-/**
- * Check if a value is a Boolean
- * @param {*} value - anything
- * @returns {boolean} true only for the value is a boolean
- */
-
-function isBoolean(value) {
- return typeof value === 'boolean';
-}
-/**
- * Check if a value is an Object
- * @param {*} value - anything
- * @returns {boolean} true only for the value is an object
- */
-
-
-function isObject(value) {
- return typeof value === 'object';
-}
-
-const REMOVE_ATTRIBUTE = 'removeAttribute';
-const SET_ATTIBUTE = 'setAttribute';
-/**
- * Add all the attributes provided
- * @param {HTMLElement} node - target node
- * @param {Object} attributes - object containing the attributes names and values
- * @returns {undefined} sorry it's a void function :(
- */
-
-function setAllAttributes(node, attributes) {
- Object.entries(attributes).forEach((_ref5) => {
- let [name, value] = _ref5;
- return attributeExpression(node, {
- name
- }, value);
- });
-}
-/**
- * Remove all the attributes provided
- * @param {HTMLElement} node - target node
- * @param {Object} attributes - object containing all the attribute names
- * @returns {undefined} sorry it's a void function :(
- */
-
-
-function removeAllAttributes(node, attributes) {
- Object.keys(attributes).forEach(attribute => node.removeAttribute(attribute));
-}
-/**
- * This methods handles the DOM attributes updates
- * @param {HTMLElement} node - target node
- * @param {Object} expression - expression object
- * @param {string} expression.name - attribute name
- * @param {*} value - new expression value
- * @param {*} oldValue - the old expression cached value
- * @returns {undefined}
- */
-
-
-function attributeExpression(node, _ref6, value, oldValue) {
- let {
- name
- } = _ref6;
-
- // is it a spread operator? {...attributes}
- if (!name) {
- // is the value still truthy?
- if (value) {
- setAllAttributes(node, value);
- } else if (oldValue) {
- // otherwise remove all the old attributes
- removeAllAttributes(node, oldValue);
- }
-
- return;
- } // handle boolean attributes
-
-
- if (isBoolean(value) || isObject(value)) {
- node[name] = value;
- }
-
- node[getMethod(value)](name, normalizeValue(name, value));
-}
-/**
- * Get the attribute modifier method
- * @param {*} value - if truthy we return `setAttribute` othewise `removeAttribute`
- * @returns {string} the node attribute modifier method name
- */
-
-
-function getMethod(value) {
- return isNil(value) || value === false || value === '' || isObject(value) ? REMOVE_ATTRIBUTE : SET_ATTIBUTE;
-}
-/**
- * Get the value as string
- * @param {string} name - attribute name
- * @param {*} value - user input value
- * @returns {string} input value as string
- */
-
-
-function normalizeValue(name, value) {
- // be sure that expressions like selected={ true } will be always rendered as selected='selected'
- if (value === true) return name;
- return value;
-}
-
-const RE_EVENTS_PREFIX = /^on/;
-/**
- * Set a new event listener
- * @param {HTMLElement} node - target node
- * @param {Object} expression - expression object
- * @param {string} expression.name - event name
- * @param {*} value - new expression value
- * @param {*} oldValue - old expression value
- * @returns {value} the callback just received
- */
-
-function eventExpression(node, _ref7, value, oldValue) {
- let {
- name
- } = _ref7;
- const normalizedEventName = name.replace(RE_EVENTS_PREFIX, '');
-
- if (oldValue) {
- node.removeEventListener(normalizedEventName, oldValue);
- }
-
- if (value) {
- node.addEventListener(normalizedEventName, value, false);
- }
-
- return value;
-}
-/**
- * This methods handles a simple text expression update
- * @param {HTMLElement} node - target node
- * @param {Object} expression - expression object
- * @param {number} expression.childNodeIndex - index to find the text node to update
- * @param {*} value - new expression value
- * @returns {undefined}
- */
-
-
-function textExpression(node, _ref8, value) {
- let {
- childNodeIndex
- } = _ref8;
- const target = node.childNodes[childNodeIndex];
- const val = normalizeValue$1(value); // replace the target if it's a placeholder comment
-
- if (target.nodeType === Node.COMMENT_NODE) {
- const textNode = document.createTextNode(val);
- node.replaceChild(textNode, target);
- } else {
- target.data = normalizeValue$1(val);
- }
-}
-/**
- * Normalize the user value in order to render a empty string in case of falsy values
- * @param {*} value - user input value
- * @returns {string} hopefully a string
- */
-
-
-function normalizeValue$1(value) {
- return isNil(value) ? '' : value;
-}
-/**
- * This methods handles the input fileds value updates
- * @param {HTMLElement} node - target node
- * @param {Object} expression - expression object
- * @param {*} value - new expression value
- * @returns {undefined}
- */
-
-
-function valueExpression(node, expression, value) {
- node.value = value;
-}
-
-var expressions = {
- [ATTRIBUTE]: attributeExpression,
- [EVENT]: eventExpression,
- [TEXT]: textExpression,
- [VALUE]: valueExpression
-};
-const Expression = Object.seal({
- // Static props
- node: null,
- value: null,
-
- // API methods
-
- /**
- * Mount the expression evaluating its initial value
- * @param {*} scope - argument passed to the expression to evaluate its current values
- * @returns {Expression} self
- */
- mount(scope) {
- // hopefully a pure function
- this.value = this.evaluate(scope); // IO() DOM updates
-
- apply(this, this.value);
- return this;
- },
-
- /**
- * Update the expression if its value changed
- * @param {*} scope - argument passed to the expression to evaluate its current values
- * @returns {Expression} self
- */
- update(scope) {
- // pure function
- const value = this.evaluate(scope);
-
- if (this.value !== value) {
- // IO() DOM updates
- apply(this, value);
- this.value = value;
- }
-
- return this;
- },
-
- /**
- * Expression teardown method
- * @returns {Expression} self
- */
- unmount() {
- // unmount only the event handling expressions
- if (this.type === EVENT) apply(this, null);
- return this;
- }
-
-});
-/**
- * IO() function to handle the DOM updates
- * @param {Expression} expression - expression object
- * @param {*} value - current expression value
- * @returns {undefined}
- */
-
-function apply(expression, value) {
- return expressions[expression.type](expression.node, expression, value, expression.value);
-}
-
-function create$2(node, data) {
- return Object.assign({}, Expression, {}, data, {
- node
- });
-}
-/**
- * Create a flat object having as keys a list of methods that if dispatched will propagate
- * on the whole collection
- * @param {Array} collection - collection to iterate
- * @param {Array} methods - methods to execute on each item of the collection
- * @param {*} context - context returned by the new methods created
- * @returns {Object} a new object to simplify the the nested methods dispatching
- */
-
-
-function flattenCollectionMethods(collection, methods, context) {
- return methods.reduce((acc, method) => {
- return Object.assign({}, acc, {
- [method]: scope => {
- return collection.map(item => item[method](scope)) && context;
- }
- });
- }, {});
-}
-
-function create$3(node, _ref9) {
- let {
- expressions
- } = _ref9;
- return Object.assign({}, flattenCollectionMethods(expressions.map(expression => create$2(node, expression)), ['mount', 'update', 'unmount']));
-}
-
-const SlotBinding = Object.seal({
- // dynamic binding properties
- node: null,
- name: null,
- template: null,
-
- // API methods
- mount(scope, parentScope) {
- const templateData = scope.slots ? scope.slots.find((_ref10) => {
- let {
- id
- } = _ref10;
- return id === this.name;
- }) : false;
- const {
- parentNode
- } = this.node;
- this.template = templateData && create$6(templateData.html, templateData.bindings).createDOM(parentNode);
-
- if (this.template) {
- this.template.mount(this.node, parentScope);
- moveSlotInnerContent(this.node);
- }
-
- parentNode.removeChild(this.node);
- return this;
- },
-
- update(scope, parentScope) {
- if (this.template && parentScope) {
- this.template.update(parentScope);
- }
-
- return this;
- },
-
- unmount(scope, parentScope, mustRemoveRoot) {
- if (this.template) {
- this.template.unmount(parentScope, null, mustRemoveRoot);
- }
-
- return this;
- }
-
-});
-/**
- * Move the inner content of the slots outside of them
- * @param {HTMLNode} slot - slot node
- * @returns {undefined} it's a void function
- */
-
-function moveSlotInnerContent(slot) {
- if (slot.firstChild) {
- slot.parentNode.insertBefore(slot.firstChild, slot);
- moveSlotInnerContent(slot);
- }
-}
-/**
- * Create a single slot binding
- * @param {HTMLElement} node - slot node
- * @param {string} options.name - slot id
- * @returns {Object} Slot binding object
- */
-
-
-function createSlot(node, _ref11) {
- let {
- name
- } = _ref11;
- return Object.assign({}, SlotBinding, {
- node,
- name
- });
-}
-/**
- * Create a new tag object if it was registered before, otherwise fallback to the simple
- * template chunk
- * @param {Function} component - component factory function
- * @param {Array