Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | 39x 240x 240x 2x 2x 1x 1x 2x 240x 10x 10x 10x 240x 240x 240x 261x 261x 261x 261x 261x 261x 261x 261x 240x 261x 261x 261x 261x 259x 2x 1x 1x 261x 261x 240x 1x 1x 240x 259x 240x 240x 240x 235x 5x 240x 240x 240x 1x 1x 239x 239x 239x 233x 6x 6x 6x 239x 239x 239x 239x 239x 239x 239x 239x 239x 239x 239x 239x 239x 3x 239x 239x 3x 236x 2x 236x 239x 239x 239x 239x 6x 6x 6x 6x 6x 3x 3x 3x 3x 3x 3x 3x 239x 6x 239x 239x 239x 240x | 'use strict';
import "core-js/modules/es.array.index-of.js";
import "core-js/modules/es.array.is-array.js";
import "core-js/modules/es.array.iterator.js";
import "core-js/modules/es.array.slice.js";
import "core-js/modules/es.function.name.js";
import "core-js/modules/es.map.js";
import "core-js/modules/es.object.assign.js";
import "core-js/modules/es.object.to-string.js";
import "core-js/modules/es.string.iterator.js";
import "core-js/modules/es.string.trim.js";
import "core-js/modules/web.dom-collections.iterator.js";
import { Idiomorph } from 'idiomorph/dist/idiomorph.esm.js';
import { updateTextNodePlaceholders } from './placeholders';
import { directives } from './directives';
import { filters } from './filters';
import { processNode } from './processing';
import { helpers } from './utils';
import { fetchRequest, axiosRequest } from './requests';
import { logError } from './logger';
var defaultRequestHeaders = {};
export function AppBlock(config) {
var _this = this;
// Sets or Updates the data and then calls render()
this.setData = function (newData) {
var replaceData = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
if (replaceData) {
this.data = newData;
} else {
Object.assign(this.data, newData);
}
this.render();
};
// Resets to the default state. Handy before making a request.
this.resetState = function () {
this.state.loading = false;
this.state.error = false;
this.state.success = false;
};
// Requests
this.axiosRequest = function (options, callbacks, delay) {
return axiosRequest(_this, options, callbacks, delay);
};
this.fetchRequest = function (url, options, callbacks, delay) {
return fetchRequest(_this, url, options, callbacks, delay);
};
// Render ============================================================================================================
// This is the heart of an AppBlock. This is where all placeholders and directives get evaluated based on our
// data, and content gets updated.
this.prepareTmpDom = function () {
var comp = this;
var cache = new Map(); // Per-render ephemeral cache
var tmpDOM = comp.template.cloneNode(true);
// Wrap in a div to handle directives on root elements
var wrapper = document.createElement('div');
wrapper.appendChild(tmpDOM);
processNode(comp, wrapper, cache);
updateTextNodePlaceholders(comp, wrapper, null, cache);
return wrapper;
};
this.render = function (callback) {
var comp = this;
if (comp.methods.beforeRender instanceof Function) comp.methods.beforeRender(comp);
var tmpDOM = this.prepareTmpDom();
if (comp.renderEngine === 'Idiomorph') {
comp.idiomorphRender(tmpDOM);
} else if (comp.renderEngine === 'plain') {
comp.plainRender(tmpDOM);
} else {
logError(comp, "".concat(comp.renderEngine, " renderEngine does not exist."));
}
if (comp.methods.afterRender instanceof Function) comp.methods.afterRender(comp);
if (callback instanceof Function) callback();
};
// Render engines
this.plainRender = function (tmpDOM) {
this.el.innerHTML = '';
this.el.appendChild(tmpDOM);
};
this.idiomorphRender = function (tmpDOM) {
Idiomorph.morph(this.el, tmpDOM, {
morphStyle: 'innerHTML'
});
};
// Initialization ====================================================================================================
this.Init = function () {
var comp = this;
if (config.name) {
comp.name = config.name;
} else {
comp.name = "AppBlock";
}
// Initialize all the properties and update them from the config if they are included, or exit if no
// config is provided.
if (config !== undefined) {
Iif (config.el === undefined) {
logError(comp, "el is empty. Please assign a DOM element to el.");
return;
}
if (config.el === null) {
logError(comp, "The element you assigned to el is not present.");
return;
}
comp.el = config.el;
comp.renderEngine = config.renderEngine ? config.renderEngine : "Idiomorph";
// Get or create a document fragment with all the app's contents and pass it to the template.
if (config.template) {
comp.template = config.template.content;
} else {
comp.template = document.createDocumentFragment();
while (comp.el.firstChild) {
comp.template.appendChild(comp.el.firstChild);
}
}
comp.state = {
loading: false,
error: false,
success: false
};
comp.data = {};
if (config.data instanceof Object) comp.data = config.data;
// A set of helper functions.
comp.utils = helpers;
comp.utils['comp'] = comp;
comp.methods = {
Parent: comp,
isLoading: function isLoading(thisApp) {
return thisApp.state.loading;
},
isSuccessful: function isSuccessful(thisApp) {
return thisApp.state.success;
},
hasError: function hasError(thisApp) {
return thisApp.state.error;
},
beforeRender: function beforeRender(thisApp) {},
afterRender: function afterRender(thisApp) {}
};
if (config.methods instanceof Object) Object.assign(comp.methods, config.methods);
comp.directives = directives;
if (config.directives instanceof Object) Object.assign(comp.directives, config.directives);
comp.filters = filters;
if (config.filters instanceof Object) Object.assign(comp.filters, config.filters);
// Expression evaluation built-ins allow-list. Expect an array of strings (default: empty, no built-ins allowed).
comp.allowBuiltins = [];
if (Array.isArray(config.allowBuiltins)) {
comp.allowBuiltins = config.allowBuiltins;
}
// Placeholder delimiters configuration. Expect an array of two non-empty strings.
var defaultDelimiters = ['{', '}'];
if (Array.isArray(config.delimiters) && config.delimiters.length === 2 && typeof config.delimiters[0] === 'string' && typeof config.delimiters[1] === 'string' && config.delimiters[0].length > 0 && config.delimiters[1].length > 0) {
comp.delimiters = config.delimiters;
} else {
if (config.delimiters !== undefined) {
// Developer provided an invalid configuration — log and fallback to default
logError(comp, 'Invalid `delimiters` config provided. Falling back to default [`{`,`}`].');
}
comp.delimiters = defaultDelimiters;
}
// Event handling ------------------------------------------------------------------------------------------------
comp.events = {};
Eif (config.events instanceof Object) {
Object.assign(comp.events, config.events);
// Add event listeners to :el for each event
var _loop = function _loop(ev) {
// Events are in this form "<eventName> <cssSelector>" where the selector may contain spaces.
// Split only on the first space so the remainder is treated as a full selector string.
var firstSpace = ev.indexOf(' ');
Iif (firstSpace === -1) return 1; // continue
// invalid key
var eventName = ev.slice(0, firstSpace);
var eventSelector = ev.slice(firstSpace + 1).trim();
comp.el.addEventListener(eventName, function (e) {
var target = e.target || e.srcElement;
// Use closest to test whether the event originated from within a matching element.
// Ensure the matched element is inside this AppBlock's root.
var matched = null;
try {
Eif (target && target.closest) matched = target.closest(eventSelector);
} catch (err) {
// If the selector is invalid, skip handling to avoid breaking the app.
matched = null;
}
Eif (matched && comp.el.contains(matched)) {
try {
comp.events[ev](e, matched);
} catch (err) {
// swallow handler errors to avoid breaking other handlers
logError(comp, err && err.message ? err.message : String(err));
}
}
});
};
for (var ev in comp.events) {
Iif (_loop(ev)) continue;
}
}
comp.events['Parent'] = comp;
} else E{
return false;
}
comp.render();
return comp;
};
return this.Init();
} |