├── .eslintignore ├── .eslintrc.cjs ├── .github └── workflows │ └── build.yml ├── .gitignore ├── .prettierignore ├── Inter.png ├── LICENSE ├── README.md ├── builder.js ├── builderconfig.js ├── core ├── ajax │ ├── errors.js │ └── index.js ├── helpers.js ├── ref │ ├── errors.js │ └── index.js ├── renderif │ ├── errors.js │ └── index.js ├── renderlist │ ├── errors.js │ └── index.js ├── template │ ├── errors.js │ └── index.js └── toattrs │ ├── errors.js │ └── index.js ├── inter.js ├── inter.m.d.ts ├── inter.m.js ├── inter.min.js ├── mitpic.svg ├── package-lock.json ├── package.json ├── prettierrc.json └── types ├── ajax.d.ts ├── ref.d.ts ├── renderif.d.ts ├── renderlist.d.ts ├── template.d.ts └── toattrs.d.ts /.eslintignore: -------------------------------------------------------------------------------- 1 | # The files which will be ignored by Eslint. 2 | 3 | inter.js 4 | inter.min.js 5 | inter-test.js 6 | test.js 7 | .eslintrc.js 8 | node_modules 9 | .vscode -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es6: true, 5 | node: true, 6 | }, 7 | extends: "eslint:recommended", 8 | rules: { 9 | quotes: ["warn", "double"], 10 | "no-var": "error", 11 | "no-alert": "error", 12 | camelcase: "error", 13 | "prefer-const": "warn", 14 | "prefer-template": "error", 15 | "getter-return": "error", 16 | "no-inner-declarations": "off", 17 | }, 18 | parserOptions: { 19 | ecmaVersion: "latest", 20 | sourceType: "module", 21 | }, 22 | }; 23 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: 3 | push: 4 | branches: [main] 5 | 6 | jobs: 7 | build: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout version 11 | uses: actions/checkout@v3 12 | - name: Use Node.js 13 | uses: actions/setup-node@v4 14 | with: 15 | node-version: "20" 16 | cache: "npm" 17 | - name: Install Dependencies 18 | run: npm install 19 | - name: Lint 20 | run: npm run lint 21 | - name: Build Inter 22 | run: npm run build 23 | - name: Prettify 24 | run: npm run prettify 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | inter-test.js 3 | test.js 4 | inter-test.html 5 | Thumbs.db 6 | node_modules 7 | .vscode 8 | 9 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Files which won't be formated 2 | 3 | inter.min.js 4 | -------------------------------------------------------------------------------- /Inter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/interjs/inter/bbcf69ca6d4e66b35a9091b9fd0776a7d879003b/Inter.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 DenisPower1 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | 6 | 7 | 8 |

9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | 29 | 30 |
31 | 32 |

Interjs

33 | 34 | **WARNING**: The v3 is being pushed on the [v3 branch](https://github.com/interjs/inter/tree/v3/core) check it out. 35 | 36 | Inter is a Javascript framework designed to build highly interactive front-end web applications. 37 | It's: **simple**, **intuitive** and **powerful**. 38 | 39 | # No complex setup 40 | 41 | You will not need to do any complex configuration to start working with Inter, just import the 42 | framework in top of your page in a script tag, and start building even the most complex web apps. 43 | 44 | ```html 45 | 46 | ``` 47 | 48 | # Small 49 | 50 | It does not mean that it is less capable, it means that it is easy to learn and cheaper to parse and download. 51 | 52 | # You rarely touch in the _DOM_ 53 | 54 | Almost every dom manipulation in an Inter app are handled by Inter, you must just focus in your application logic, this way your code base will be: **simpler** and **more maintainable** 55 | 56 | # Reactivity 57 | 58 | _Inter_ is super reactive, it means that, when there's a change it just updates the necessary part of the interface. 59 | 60 | # Compatibility 61 | 62 | _Inter_ just supports the modern browsers, it means that no Internet Explorer support. 63 | 64 | # License 65 | 66 | _Inter_ was realesed under the MIT LICENSE. 67 | 68 | # Guide 69 | 70 | To get an in-depth guide just read the official tutorial at [tutorial](http://interjs.github.io/v2/tutorial/pt/instalacao). 71 | -------------------------------------------------------------------------------- /builder.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Written by Denis Power. 3 | * 4 | * builderconfig options. 5 | * 6 | * { 7 | * files: string[], 8 | * dir: "./core", 9 | * types: { 10 | * dir: "./types", 11 | * files: string[] 12 | * } 13 | * } 14 | * 15 | * 16 | * 17 | */ 18 | 19 | console.log("Building..."); 20 | 21 | import builderconfig from "./builderconfig.js"; 22 | import { writeFileSync, readFileSync, readdirSync } from "node:fs"; 23 | import { format } from "prettier"; 24 | 25 | const { 26 | version, 27 | year, 28 | files, 29 | dir, 30 | types: { dir: typeDir, version: typeVersion }, 31 | } = builderconfig; 32 | 33 | const Package = JSON.parse(readFileSync("./package.json")); 34 | const packageLock = JSON.parse(readFileSync("./package-lock.json")); 35 | 36 | class Inter { 37 | #source; 38 | #token; 39 | #peaceOfCode; 40 | #parsingExport = false; 41 | #parsingImport = false; 42 | #reStartTheLoop = false; 43 | #importConfig = { 44 | body: "", 45 | }; 46 | #exportConfig = { 47 | name: void 0, 48 | Default: false, 49 | }; 50 | #removeExportDeclaration = () => { 51 | const { name, Default } = this.#exportConfig; 52 | 53 | const pattern1 = new RegExp(`export\\s*${name}`, "g"); 54 | const pattern2 = new RegExp(`export(?:\\s*)default(?:\\s*)${name}`, "g"); 55 | const pattern = Default ? pattern2 : pattern1; 56 | this.#source = this.#source.replace(pattern, name); 57 | this.#parsingExport = false; 58 | this.#reStartTheLoop = true; 59 | }; 60 | 61 | #removeImportDeclaration = () => { 62 | const { body } = this.#importConfig; 63 | this.#source = this.#source.replace(body, ""); 64 | this.#importConfig.body = ""; 65 | this.#parsingImport = false; 66 | this.#reStartTheLoop = true; 67 | }; 68 | 69 | constructor(codeString) { 70 | this.#source = codeString; 71 | } 72 | 73 | removeImport() {} 74 | 75 | removeExportAndImportDeclaration(module) { 76 | for (let i = 0; i < this.#source.length; i++) { 77 | if (this.#reStartTheLoop) { 78 | this.#reStartTheLoop = false; 79 | i = 0; 80 | } 81 | 82 | this.#peaceOfCode = this.#source[i]; 83 | 84 | if (!isBlankSpace(this.#peaceOfCode) && !this.#parsingImport) 85 | this.#token += this.#peaceOfCode; 86 | else if (this.#parsingImport) { 87 | this.#importConfig.body += this.#peaceOfCode; 88 | 89 | if (this.#importConfig.body.endsWith(";")) { 90 | this.#removeImportDeclaration(); 91 | } 92 | } else if (isBlankSpace(this.#peaceOfCode) && this.#token) { 93 | if ( 94 | this.#token == "import" && 95 | !this.#parsingImport && 96 | !this.#parsingExport 97 | ) { 98 | this.#parsingImport = true; 99 | this.#importConfig.body += "import "; 100 | } else if ( 101 | this.#token == "export" && 102 | !this.#parsingExport && 103 | !this.#parsingImport && 104 | module !== true 105 | ) { 106 | this.#parsingExport = true; 107 | } else if (this.#parsingExport) { 108 | const { name } = this.#exportConfig; 109 | 110 | if (!name) { 111 | if (this.#token !== "default") { 112 | this.#exportConfig.name = this.#token; 113 | this.#removeExportDeclaration(); 114 | } else this.#exportConfig.Default = true; 115 | } 116 | } 117 | 118 | this.#token = ""; 119 | } 120 | } 121 | 122 | return this.#source; 123 | } 124 | } 125 | 126 | function isBlankSpace(code) { 127 | return /\s/.test(code); 128 | } 129 | 130 | if (!files) throw new Error("No `builderconfing.js` file found"); 131 | 132 | function buildTsDeclaration() { 133 | let body = ""; 134 | const typeFiles = readdirSync(typeDir); 135 | 136 | for (const file of typeFiles) { 137 | const fileString = readFileSync(`${typeDir}/${file}`); 138 | body += fileString; 139 | } 140 | 141 | body = ` 142 | /*** 143 | * MIT LICENSED BY - Denis Power(Inter creator) 144 | * Typescript declaration file for Inter version ${version} 145 | * Version - ${typeVersion} 146 | * Repo - https://github.com/interjs/inter/types 147 | * GENERATED BY INTER BUILDER 148 | */ 149 | 150 | ${body} 151 | 152 | `; 153 | 154 | writeFileSync("inter.m.d.ts", body); 155 | } 156 | 157 | function build(buildType) { 158 | const isModuleBuild = buildType == "module"; 159 | const isGlobalBuild = buildType == "global"; 160 | 161 | let body = ""; 162 | 163 | for (const file of files) { 164 | let fileString = readFileSync(dir ? `${dir}/${file}` : file); 165 | /** 166 | * In module build, the exports declaration won't be removed in regular 167 | * files which contain the Inter core, but the export declaration from 168 | * the helpers and errors files must be removed, that's why here we're 169 | * considering them as special. 170 | */ 171 | const specialFiles = new Set([ 172 | "helpers.js", 173 | "template/errors.js", 174 | "renderList/errors.js", 175 | "ajax/errors.js", 176 | "ref/errors.js", 177 | "renderif/errors.js", 178 | "toattrs/errors.js", 179 | ]); 180 | if (specialFiles.has(file) && isModuleBuild) { 181 | let fileStringBody = ""; 182 | fileStringBody += fileString; 183 | const frame = new Inter(fileStringBody); 184 | fileString = frame.removeExportAndImportDeclaration(); 185 | } 186 | 187 | body += fileString; 188 | } 189 | 190 | const frame = new Inter(body); 191 | let builtCode; 192 | 193 | if (isGlobalBuild) builtCode = frame.removeExportAndImportDeclaration(); 194 | else if (isModuleBuild) 195 | builtCode = frame.removeExportAndImportDeclaration(true); 196 | 197 | if (isGlobalBuild) { 198 | body = ` 199 | 200 | /** 201 | * Interjs 202 | * Version - ${version} 203 | * MIT LICENSED BY - Denis Power 204 | * Repo - https://github.com/interjs/inter 205 | * 2021 - ${year} 206 | * GENERATED BY INTER BUILDER 207 | * 208 | */ 209 | 210 | (function () { 211 | 212 | ${builtCode}; 213 | 214 | window.Ref = Ref; 215 | window.renderIf = renderIf; 216 | window.renderList = renderList; 217 | window.template = template; 218 | window.toAttrs = toAttrs; 219 | window.Backend = Backend; 220 | console.log("The global version ${version} of Inter was loaded successfully.") 221 | 222 | })(); 223 | 224 | `; 225 | } else if (isModuleBuild) { 226 | body = ` 227 | 228 | /** 229 | * Interjs 230 | * Version - ${version} 231 | * MIT LICENSED BY - Denis Power 232 | * Repo - https://github.com/interjs/inter 233 | * 2021 - ${year} 234 | * GENERATED BY INTER BUILDER 235 | * Module version 236 | */ 237 | 238 | export const interVersion = "${version}"; 239 | ${builtCode} 240 | `; 241 | } 242 | 243 | if (isGlobalBuild) writeFileSync("inter.js", format(body)); 244 | else if (isModuleBuild) writeFileSync("inter.m.js", format(body)); 245 | 246 | Package.version = version; 247 | packageLock.version = version; 248 | 249 | writeFileSync("package.json", JSON.stringify(Package)); 250 | writeFileSync("package-lock.json", JSON.stringify(packageLock)); 251 | } 252 | 253 | buildTsDeclaration(); 254 | build("global"); 255 | build("module"); 256 | 257 | console.log("Inter Built Successfully"); 258 | -------------------------------------------------------------------------------- /builderconfig.js: -------------------------------------------------------------------------------- 1 | export default { 2 | version: "2.2.4", 3 | year: "2025", 4 | files: [ 5 | "template/errors.js", 6 | "renderList/errors.js", 7 | "ajax/errors.js", 8 | "ref/errors.js", 9 | "renderif/errors.js", 10 | "toattrs/errors.js", 11 | "helpers.js", 12 | "ref/index.js", 13 | "toattrs/index.js", 14 | "renderif/index.js", 15 | "template/index.js", 16 | "renderList/index.js", 17 | "ajax/index.js", 18 | ], 19 | dir: "./core", 20 | types: { 21 | dir: "./types", 22 | version: "1.0.0", 23 | }, 24 | }; 25 | -------------------------------------------------------------------------------- /core/ajax/errors.js: -------------------------------------------------------------------------------- 1 | import { syErr, err, consW, valueType } from "../helpers.js"; 2 | 3 | export function runIvalidRequestArgumentError(arg) { 4 | syErr(`The argument of [Backend instance].request method 5 | must be a plain javascript object, and you defined "${valueType(arg)}" 6 | as its argument.`); 7 | } 8 | 9 | export function runInvalidTypeOptionError() { 10 | syErr(`You must define the type(method) of request, in Ajax with the "type" option and 11 | it must be a string.`); 12 | } 13 | 14 | export function runInvalidPathOptionError() { 15 | syErr(`You must define the path where the request will be sent, with the "path" option and 16 | it must be a string.`); 17 | } 18 | 19 | export function runUnsupportedRequestTypeWarning(type) { 20 | err(`"${type}" is an unsupported request type in Ajax.`); 21 | } 22 | 23 | export function runInvalidAjaxEventWarning(name) { 24 | consW(`There's not any event named "${name}" in Ajax request.`); 25 | } 26 | 27 | export function runInvalidSecurityObjectWarning() { 28 | consW(`Invalid "security" object, security object must have the username and passoword 29 | properties.`); 30 | } 31 | 32 | export function runInvalidCallBackError() { 33 | syErr(`The arguments of "okay", "error" and "response" methods must be 34 | functions.`); 35 | } 36 | 37 | export function runInvalidResponseArgumentNumberError(argNumber) { 38 | syErr(`The response method must have two arguments and you only 39 | defined ${argNumber} argument.`); 40 | } 41 | 42 | export function runInvalidHeadersOptionError(headers) { 43 | syErr(`the "headers" property must be an object, and 44 | you defined it as : ${valueType(headers)}.`); 45 | } 46 | 47 | export function runInvalidAjaxEventsOptionError(events) { 48 | syErr(`the "events" property must be an object, and 49 | you defined it as : ${valueType(events)}.`); 50 | } 51 | -------------------------------------------------------------------------------- /core/ajax/index.js: -------------------------------------------------------------------------------- 1 | import { 2 | err, 3 | isObj, 4 | isCallable, 5 | isDefined, 6 | isEmptyObj, 7 | isBool, 8 | } from "../helpers.js"; 9 | 10 | import { 11 | runInvalidCallBackError, 12 | runInvalidAjaxEventWarning, 13 | runInvalidHeadersOptionError, 14 | runInvalidPathOptionError, 15 | runInvalidResponseArgumentNumberError, 16 | runInvalidSecurityObjectWarning, 17 | runInvalidTypeOptionError, 18 | runIvalidRequestArgumentError, 19 | runUnsupportedRequestTypeWarning, 20 | runInvalidAjaxEventsOptionError, 21 | } from "./errors.js"; 22 | 23 | function toObj(obj) { 24 | if (obj !== void 0) { 25 | try { 26 | return JSON.parse(obj); 27 | } catch (e) { 28 | return obj; 29 | } 30 | } 31 | } 32 | 33 | function openRequest(req, method, path, username, userpassword) { 34 | req.open(method, path, true, username, userpassword); 35 | } 36 | 37 | function createHeaders(headers, req) { 38 | Object.entries(headers).forEach(([header, value]) => { 39 | req.setRequestHeader(header, value); 40 | }); 41 | } 42 | 43 | function createAjaxEvents(req, events, allowedEvents) { 44 | Object.entries(events).forEach(([name, handler]) => { 45 | if (allowedEvents.has(name)) { 46 | if (name !== "onprogress") { 47 | req[name] = () => { 48 | handler(); 49 | }; 50 | } else { 51 | req.onprogress = (ev) => { 52 | const Arg = { 53 | abort: () => req.abort(), 54 | progress: (ev.loaded * 100) / ev.total, 55 | }; 56 | 57 | handler(Arg); 58 | }; 59 | } 60 | } else runInvalidAjaxEventWarning(name); 61 | }); 62 | } 63 | 64 | function convertStringToObj(string, reqObj) { 65 | function createGetter(obj, prop) { 66 | //At first we must define the property this way 67 | // so that the methods Object.keys and Object.values 68 | //work fine. 69 | obj[prop] = void 0; 70 | Object.defineProperty(obj, prop, { 71 | get() { 72 | return reqObj.getResponseHeader(prop); 73 | }, 74 | }); 75 | } 76 | 77 | const pattern = /(:?[\S]+):/g; 78 | const headers = {}; 79 | 80 | string.replace(pattern, (match) => { 81 | match = match.replace(":", ""); 82 | if (reqObj.getResponseHeader(match)) createGetter(headers, match); 83 | }); 84 | 85 | return Object.freeze(headers); 86 | } 87 | 88 | function createRequestBody(body) { 89 | if (!isDefined(body)) return null; 90 | else if (body instanceof FormData || typeof body == "string") return body; 91 | else return JSON.stringify(body); 92 | } 93 | 94 | function isJSON(data) { 95 | try { 96 | const parsed = JSON.parse(data); 97 | 98 | return isObj(parsed); 99 | } catch (e) { 100 | return false; 101 | } 102 | } 103 | 104 | export function Backend() { 105 | if (new.target === void 0) { 106 | err("Backend is a constructor, call it with the new keyword."); 107 | } 108 | } 109 | 110 | Backend.prototype = { 111 | get [Symbol.toStringTag]() { 112 | return "Ajax"; 113 | }, 114 | 115 | request(obj) { 116 | if (!isObj(obj)) runIvalidRequestArgumentError(obj); 117 | 118 | const { 119 | type, 120 | path, 121 | events = {}, 122 | timeout, 123 | withCredentials, 124 | body = null, 125 | headers = {}, 126 | security, 127 | } = obj; 128 | 129 | const unSupportedRequestType = new Set(["connect", "trace"]); 130 | 131 | if (!isDefined(type) || typeof type !== "string") 132 | runInvalidTypeOptionError(); 133 | 134 | if (!isDefined(path) || typeof path !== "string") 135 | runInvalidPathOptionError(); 136 | 137 | if (unSupportedRequestType.has(path.toLowerCase())) 138 | runUnsupportedRequestTypeWarning(type); 139 | 140 | const responseHandlers = new Map(); 141 | let requestOpened = false; 142 | 143 | function call() { 144 | const req = new XMLHttpRequest(); 145 | const method = type.toUpperCase(); 146 | const allowedEvents = new Set(["onprogress", "ontimeout", "onabort"]); 147 | 148 | const AjaxResponse = { 149 | get status() { 150 | return req.status; 151 | }, 152 | 153 | get statusText() { 154 | return req.statusText; 155 | }, 156 | 157 | get headers() { 158 | const stringifiedHeaders = req.getAllResponseHeaders(); 159 | 160 | return convertStringToObj(stringifiedHeaders, req); 161 | }, 162 | 163 | get data() { 164 | return toObj(req.responseText); 165 | }, 166 | 167 | get [Symbol.toStringTag]() { 168 | return "AjaxResponse"; 169 | }, 170 | 171 | isObj() { 172 | return isJSON(req.responseText); 173 | }, 174 | }; 175 | 176 | if (isObj(security) && Object.keys(security).length >= 2) { 177 | if (security.username && security.password) { 178 | openRequest(req, method, path, security.username, security.password); 179 | 180 | requestOpened = true; 181 | } else runInvalidSecurityObjectWarning(); 182 | } 183 | 184 | if (!requestOpened) { 185 | openRequest(req, method, path); 186 | 187 | requestOpened = true; 188 | } 189 | 190 | if (!isObj(headers)) runInvalidHeadersOptionError(headers); 191 | if (!isObj(events)) runInvalidAjaxEventsOptionError(events); 192 | 193 | if (!isEmptyObj(headers)) createHeaders(headers, req); 194 | if (!isEmptyObj(events)) createAjaxEvents(req, events, allowedEvents); 195 | 196 | req.onreadystatechange = function () { 197 | if (this.readyState == 4) { 198 | if (this.status >= 200 && this.status < 300) { 199 | if (responseHandlers.has("okay")) 200 | responseHandlers.get("okay")(AjaxResponse); 201 | } else { 202 | if (responseHandlers.has("error")) 203 | responseHandlers.get("error")(AjaxResponse); 204 | } 205 | } 206 | }; 207 | 208 | if (isBool(withCredentials)) { 209 | req.withCredentials = withCredentials; 210 | } 211 | 212 | if (typeof timeout !== "number") { 213 | req.timeout = timeout; 214 | } 215 | 216 | req.send(createRequestBody(body)); 217 | } 218 | 219 | const responseMethods = { 220 | okay(callBack) { 221 | if (!isCallable(callBack)) runInvalidCallBackError(); 222 | 223 | responseHandlers.set("okay", callBack); 224 | //Starting the request... 225 | call(); 226 | }, 227 | 228 | error(callBack) { 229 | if (!isCallable(callBack)) runInvalidCallBackError(); 230 | 231 | responseHandlers.set("error", callBack); 232 | //Starting the request... 233 | call(); 234 | }, 235 | 236 | response(okay, error) { 237 | const argNumber = arguments.length; 238 | if (argNumber < 2) runInvalidResponseArgumentNumberError(argNumber); 239 | if (!isCallable(okay) && !isCallable(error)) runInvalidCallBackError(); 240 | 241 | responseHandlers.set("okay", okay); 242 | responseHandlers.set("error", error); 243 | //Starting the request... 244 | call(); 245 | }, 246 | }; 247 | 248 | return responseMethods; 249 | }, 250 | }; 251 | 252 | Object.freeze(Backend.prototype); 253 | -------------------------------------------------------------------------------- /core/helpers.js: -------------------------------------------------------------------------------- 1 | // Helpers functions. 2 | 3 | export function isValidTemplateReturn(arg) { 4 | return isObj(arg) && arg.element && arg[Symbol.for("template")]; 5 | } 6 | 7 | export function isNotConfigurable(obj) { 8 | return ( 9 | Object.isFrozen(obj) || Object.isSealed(obj) || !Object.isExtensible(obj) 10 | ); 11 | } 12 | 13 | export function isObj(arg) { 14 | // For plain objects. 15 | 16 | return Object.prototype.toString.apply(arg, void 0) == "[object Object]"; 17 | } 18 | 19 | export function getTagName(elementNode) { 20 | return elementNode.nodeName.toLowerCase(); 21 | } 22 | 23 | export function isSet(arg) { 24 | return arg instanceof Set; 25 | } 26 | 27 | export function hasOwnProperty(target, prop) { 28 | const hasOwn = Object.prototype.hasOwnProperty.call(target, prop); 29 | 30 | return hasOwn; 31 | } 32 | 33 | export function isMap(arg) { 34 | return arg instanceof Map; 35 | } 36 | 37 | export function isDefined(arg) { 38 | return arg != void 0; 39 | } 40 | 41 | /** 42 | * Indirect boolean value checking can cause 43 | * unexpected result, that's why I am using direct 44 | * checking here. 45 | * 46 | */ 47 | 48 | export function isTrue(v) { 49 | return Object.is(v, true); 50 | } 51 | 52 | export function isFalse(v) { 53 | return Object.is(v, false); 54 | } 55 | 56 | /**/ 57 | 58 | export function isCallable(fn) { 59 | return typeof fn == "function"; 60 | } 61 | 62 | export function isEmptyObj(obj) { 63 | return Object.keys(obj).length == 0; 64 | } 65 | 66 | export function isAtag(tag) { 67 | return tag instanceof HTMLElement; 68 | } 69 | 70 | export function validDomEvent(eventName) { 71 | return eventName in HTMLElement.prototype; 72 | } 73 | 74 | export function validStyleName(styeName) { 75 | return styeName in document.createElement("p").style; 76 | } 77 | 78 | export function createText(text) { 79 | return document.createTextNode(text); 80 | } 81 | 82 | export function validTagOption(option) { 83 | return typeof option == "string"; 84 | } 85 | 86 | export function validObjectOptions(option1, option2, option3) { 87 | //For the styles, attrs and events options 88 | 89 | return isObj(option1) && isObj(option2) && isObj(option3); 90 | } 91 | 92 | export function getId(id) { 93 | if (typeof id !== "string") 94 | syErr("The value of the id attribute must be a string."); 95 | 96 | const el = document.getElementById(id); 97 | 98 | if (el == void 0) 99 | err(`There's not an element on the document with id "${id}".`); 100 | else return el; 101 | } 102 | 103 | export function valueType(val) { 104 | if ( 105 | typeof val == "undefined" || 106 | typeof val == "symbol" || 107 | typeof val == "bigint" || 108 | typeof val == "boolean" || 109 | typeof val == "function" || 110 | typeof val == "number" || 111 | typeof val == "string" 112 | ) { 113 | return typeof val; 114 | } else { 115 | /** 116 | * 117 | * @val may be an array, a plain object or even 118 | * a native Javascript object, 119 | * let's check with the type() function. 120 | * 121 | */ 122 | 123 | return type(val); 124 | } 125 | } 126 | 127 | // WARNINGS HELPERS 128 | 129 | export function syErr(err) { 130 | throw new Error(`Inter syntaxError : ${err}`); 131 | } 132 | 133 | export function err(e) { 134 | throw new Error(`Inter error: ${e}`); 135 | } 136 | 137 | export function consW(w) { 138 | console.warn(`Inter warning: ${w}`); 139 | } 140 | 141 | export function ParserWarning(w) { 142 | console.error(`Inter parser error: ${w}`); 143 | } 144 | 145 | // 146 | 147 | export function isArray(arg) { 148 | return Array.isArray(arg); 149 | } 150 | 151 | function type(val) { 152 | // All Javascript objects. 153 | 154 | const isAnobject = 155 | isDefined(val) && Object.prototype.toString.call(val).startsWith("[object"); 156 | 157 | if (isAnobject) { 158 | return Object.prototype.toString 159 | .call(val) 160 | .replace("[object", "") 161 | .replace("]", "") 162 | .replace(/\s/g, "") 163 | .toLowerCase(); 164 | } else { 165 | /** 166 | * @val is null. 167 | * 168 | */ 169 | 170 | return "null"; 171 | } 172 | } 173 | 174 | export function isBool(val) { 175 | /** 176 | * 177 | * Don't use typeof val==="boolean"; due to 1 and 0. 178 | * 179 | */ 180 | 181 | return val == true || val == false; 182 | } 183 | 184 | //Just for renderList. 185 | 186 | export function validInProperty(IN) { 187 | return typeof IN == "string"; 188 | } 189 | 190 | export function validEachProperty(each) { 191 | return ( 192 | each instanceof Array || 193 | isObj(each) || 194 | each instanceof Map || 195 | each instanceof Set || 196 | typeof each === "number" 197 | ); 198 | } 199 | 200 | function toIterable(data) { 201 | const iterable = { 202 | values: new Array(), 203 | type: void 0, 204 | }; 205 | 206 | if (isArray(data)) { 207 | iterable.values = data; 208 | iterable.type = "array"; 209 | } else if (isObj(data)) { 210 | iterable.values = Object.entries(data); 211 | iterable.type = "object"; 212 | } else if (data instanceof Map) { 213 | data.forEach((value, key) => { 214 | iterable.values.push([key, value]); 215 | }); 216 | 217 | iterable.type = "object"; 218 | } else if (data instanceof Set) { 219 | iterable.values = Array.from(data); 220 | iterable.type = "set"; 221 | } else if (typeof data === "number") { 222 | for (let i = 0; i < data; i++) { 223 | iterable.values.push(i); 224 | } 225 | 226 | iterable.type = "number"; 227 | } 228 | 229 | return iterable; 230 | } 231 | 232 | export function Iterable(data) { 233 | this.source = toIterable(data); 234 | this.break = !1; 235 | } 236 | 237 | Iterable.prototype.each = function (callBack) { 238 | let index = -1; 239 | 240 | for (const data of this.source.values) { 241 | index++; 242 | 243 | callBack(data, index, this.source.type); 244 | 245 | if (this.break) break; 246 | } 247 | }; 248 | 249 | export function isNegativeValue(value) { 250 | value = typeof value == "string" ? value.trim() : value; 251 | const nevagativeValues = new Set([0, false, null, undefined, ""]); 252 | 253 | return nevagativeValues.has(value); 254 | } 255 | 256 | export function isPositiveValue(value) { 257 | return !isNegativeValue(value); 258 | } 259 | 260 | export function isTringOrNumber(value) { 261 | typeof value == "string" || typeof value == "number"; 262 | } 263 | 264 | // 265 | -------------------------------------------------------------------------------- /core/ref/errors.js: -------------------------------------------------------------------------------- 1 | import { consW, syErr, valueType } from "../helpers.js"; 2 | 3 | export function runReservedRefNameWarning(refName) { 4 | consW(`"${refName}" is a reserved reference name, use other name.`); 5 | } 6 | 7 | export function runInvalidSetRefsValueError(arg) { 8 | syErr(`"${valueType(arg)}" is not a valid value for the "setRefs" property. 9 | The value of the setRefs property must be a plain Javascript object.`); 10 | } 11 | 12 | export function runInvalidRefArgument() { 13 | syErr("The argument of the Ref function must be a plain Javascript object."); 14 | } 15 | 16 | export function runInvalidRefInProperty() { 17 | syErr("The value of the 'in' property on the Ref function must be a string."); 18 | } 19 | 20 | export function runInvalidRefDataProperty() { 21 | syErr( 22 | "The value of the 'data' property on the Ref function must be a plain Javascript object. " 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /core/ref/index.js: -------------------------------------------------------------------------------- 1 | import { isObj, syErr, isCallable, getId, hasOwnProperty } from "../helpers.js"; 2 | 3 | import { 4 | runInvalidSetRefsValueError, 5 | runInvalidRefDataProperty, 6 | runInvalidRefInProperty, 7 | runInvalidRefArgument, 8 | runReservedRefNameWarning, 9 | } from "./errors.js"; 10 | 11 | function hasProp(object) { 12 | return Object.keys(object).length > 0; 13 | } 14 | 15 | function hasRefs(text) { 16 | return /{\s*.*\s*}/.test(text); 17 | } 18 | 19 | function getRefs(text) { 20 | /** 21 | * 22 | * @text must be a string containing refs. 23 | * 24 | * This function is used in reference computation, 25 | * it helps Inter making an eficient reference computation. 26 | * 27 | */ 28 | 29 | const ref = /{\s*(:?[\w-\s]+)\s*}/g; 30 | 31 | const refs = new Set(); 32 | 33 | text.replace(ref, (plainRef) => { 34 | const refName = plainRef.replace("{", "").replace("}", "").trim(); 35 | 36 | refs.add(refName); 37 | }); 38 | 39 | return Array.from(refs); 40 | } 41 | 42 | function hasRefNamed(text, refName) { 43 | const pattern = new RegExp(`{\\s*${refName}\\s*}`); 44 | 45 | return pattern.test(text); 46 | } 47 | 48 | /** 49 | * 50 | * We are considering them as special attributes 51 | * because we must not use the setAttribute method 52 | * to set them. 53 | * 54 | */ 55 | 56 | const specialAttrs = new Set(["currentTime", "value"]); 57 | 58 | function runRefParsing(rootElement, refs, refCache) { 59 | function getTextNodes(el) { 60 | const _childNodes = new Set(); 61 | 62 | if (el.hasChildNodes()) 63 | for (const child of el.childNodes) { 64 | if ( 65 | child.nodeType == 3 && 66 | child.textContent.trim().length > 0 && 67 | hasRefs(child.textContent) 68 | ) { 69 | _childNodes.add(child); 70 | } 71 | } 72 | 73 | return Array.from(_childNodes); 74 | } 75 | 76 | const children = rootElement.getElementsByTagName("*"); 77 | 78 | function runTextRefParsing(parentNode) { 79 | function parseRefsInText(node) { 80 | for (const ref in refs) { 81 | if ( 82 | node.textContent.trim().length > 0 && 83 | hasRefNamed(node.textContent, ref) 84 | ) { 85 | const setting = { 86 | target: node, 87 | text: node.textContent, 88 | }; 89 | 90 | refCache.add(setting); 91 | 92 | break; 93 | } 94 | } 95 | } 96 | 97 | if (parentNode.nodeType == 1) { 98 | for (const node of parentNode.childNodes) { 99 | if (node.hasChildNodes() && node.nodeType == 1) { 100 | runTextRefParsing(node); 101 | continue; 102 | } 103 | 104 | parseRefsInText(node); 105 | } 106 | } else if (parentNode.nodeType == 3) { 107 | // Parsing the references 108 | // in the main container 109 | // text nodes. 110 | 111 | parseRefsInText(parentNode); 112 | } 113 | } 114 | 115 | function parseRefsInAttrs(elementNode) { 116 | const setting = { 117 | target: elementNode, 118 | attrs: Object.create(null), 119 | refs: refs, 120 | }; 121 | 122 | for (const attr of elementNode.attributes) { 123 | for (const ref in refs) { 124 | if (hasRefNamed(attr.value, ref)) { 125 | if (!specialAttrs.has(attr.name)) { 126 | setting.attrs[attr.name] = attr.value; 127 | } else { 128 | refCache.specialAttrs.add({ 129 | target: elementNode, 130 | attr: { 131 | [attr.name]: attr.value, 132 | }, 133 | }); 134 | 135 | elementNode.removeAttribute(attr.name); 136 | } 137 | 138 | break; 139 | } 140 | } 141 | } 142 | 143 | if (hasProp(setting.attrs)) { 144 | // The true argument says to the parser 145 | // to register the reference as an attribute reference. 146 | refCache.add(setting, true); 147 | } 148 | } 149 | 150 | const textNodes = getTextNodes(rootElement); 151 | 152 | if (textNodes.length > 0) { 153 | for (const text of textNodes) { 154 | runTextRefParsing(text); 155 | } 156 | } 157 | 158 | for (const child of children) { 159 | runTextRefParsing(child); 160 | parseRefsInAttrs(child); 161 | } 162 | 163 | refCache.updateRefs(); 164 | } 165 | export function Ref(obj) { 166 | if (new.target != void 0) { 167 | syErr("Do not call the Ref function with the new keyword."); 168 | } else if (!isObj(obj)) runInvalidRefArgument(); 169 | else { 170 | const { in: IN, data } = obj; 171 | 172 | if (!(typeof IN === "string")) runInvalidRefInProperty(); 173 | 174 | if (!isObj(data)) runInvalidRefDataProperty(); 175 | 176 | const reservedRefNames = new Set(["setRefs", "observe"]); 177 | 178 | for (const refName in data) { 179 | if (reservedRefNames.has(refName)) { 180 | runReservedRefNameWarning(refName); 181 | delete data[refName]; 182 | 183 | continue; 184 | } 185 | 186 | if (isCallable(data[refName])) { 187 | data[refName] = data[refName].call(data); 188 | } 189 | } 190 | 191 | const proxyTarget = Object.assign({}, data); 192 | const refParser = { 193 | attrs: new Set(), // Attribute reference. 194 | texts: new Set(), // Text reference. 195 | specialAttrs: new Set(), 196 | observed: new Map(), 197 | refs: proxyTarget, 198 | hadIteratedOverSpecialAttrs: false, 199 | add(setting, attr) { 200 | // if attr, the parser must register the reference 201 | // as an attribute reference. 202 | 203 | if (attr) { 204 | this.attrs.add(setting); 205 | } else { 206 | this.texts.add(setting); 207 | } 208 | }, 209 | 210 | updateSpecialAttrs() { 211 | for (const special of this.specialAttrs) { 212 | const { target } = special; 213 | 214 | // eslint-disable-next-line prefer-const 215 | let [attrName, attrValue] = Object.entries(special.attr)[0]; 216 | 217 | const refs = getRefs(attrValue); 218 | 219 | for (const ref of refs) { 220 | if (reservedRefNames.has(ref)) continue; 221 | if (ref in this.refs) { 222 | const pattern = new RegExp(`{\\s*(:?${ref})\\s*}`, "g"); 223 | attrValue = attrValue.replace(pattern, this.refs[ref]); 224 | 225 | if (!hasRefs(attrValue)) break; 226 | } 227 | } 228 | 229 | target[attrName] = attrValue; 230 | } 231 | }, 232 | updateAttrRef() { 233 | for (const attributeRef of this.attrs) { 234 | const { target, attrs } = attributeRef; 235 | 236 | // eslint-disable-next-line prefer-const 237 | for (let [name, value] of Object.entries(attrs)) { 238 | const refNames = getRefs(value); 239 | 240 | for (const refName of refNames) { 241 | if (reservedRefNames.has(refName)) continue; 242 | if (refName in this.refs) { 243 | const pattern = new RegExp(`{\\s*(:?${refName})\\s*}`, "g"); 244 | 245 | value = value.replace(pattern, this.refs[refName]); 246 | 247 | if (!hasRefs(value)) break; 248 | } 249 | } 250 | 251 | if (target.getAttribute(name) !== value) { 252 | target.setAttribute(name, value); 253 | } 254 | } 255 | } 256 | }, 257 | updateTextRef() { 258 | if (this.texts.size > 0) { 259 | for (const textRef of this.texts) { 260 | // eslint-disable-next-line prefer-const 261 | let { target, text } = textRef; 262 | 263 | // Returns the ref Names 264 | // on the "text" string. 265 | const refNames = getRefs(text); 266 | 267 | for (const refName of refNames) { 268 | if (reservedRefNames.has(refName)) continue; 269 | if (refName in this.refs) { 270 | const pattern = new RegExp(`{\\s*(:?${refName})\\s*}`, "g"); 271 | 272 | text = text.replace(pattern, this.refs[refName]); 273 | 274 | if (!hasRefs(text)) break; 275 | } 276 | } 277 | 278 | if (target.textContent !== text) { 279 | target.textContent = text; 280 | } 281 | } 282 | } 283 | }, 284 | 285 | updateRefs() { 286 | if (this.texts.size > 0) this.updateTextRef(); 287 | if (this.attrs.size > 0) this.updateAttrRef(); 288 | if (this.specialAttrs.size > 0) this.updateSpecialAttrs(); 289 | }, 290 | }; 291 | 292 | runRefParsing(getId(IN), proxyTarget, refParser); 293 | 294 | function runObserveCallBack(refName, value, oldValue) { 295 | if (refParser.observed.size == 1 && !reservedRefNames.has(refName)) { 296 | const callBack = refParser.observed.get("callBack"); 297 | 298 | callBack(refName, value, oldValue); 299 | } 300 | } 301 | 302 | const reactor = new Proxy(proxyTarget, { 303 | set(target, key, value, proxy) { 304 | if (key in target && target[key] == value) return false; 305 | 306 | const oldValue = target[key]; 307 | 308 | if (isCallable(value)) { 309 | value = value.call(proxy); 310 | } 311 | Reflect.set(...arguments); 312 | runObserveCallBack(key, value, oldValue); 313 | if (!(key in proxy)) { 314 | // Dynamic ref. 315 | 316 | runRefParsing(getId(IN), proxyTarget, refParser); 317 | } else { 318 | refParser.updateRefs(); 319 | return true; 320 | } 321 | }, 322 | 323 | get(...args) { 324 | return Reflect.get(...args); 325 | }, 326 | }); 327 | 328 | Object.defineProperties(reactor, { 329 | setRefs: { 330 | set(o) { 331 | if (isObj(o)) { 332 | let hasNewRefName = false; 333 | 334 | for (const [refName, refValue] of Object.entries(o)) { 335 | if (reservedRefNames.has(refName)) { 336 | runReservedRefNameWarning(refName); 337 | 338 | continue; 339 | } 340 | 341 | if (!hasOwnProperty(this, refName)) hasNewRefName = true; 342 | if (hasOwnProperty(this, refName) && this[refName] == refValue) 343 | continue; 344 | 345 | const oldRefValue = proxyTarget[refName]; 346 | 347 | if (isCallable(refValue)) { 348 | proxyTarget[refName] = refValue.call(this); 349 | } else { 350 | proxyTarget[refName] = refValue; 351 | } 352 | 353 | runObserveCallBack(refName, refValue, oldRefValue); 354 | } 355 | 356 | if (hasNewRefName) runRefParsing(getId(IN), proxyTarget, refParser); 357 | } else runInvalidSetRefsValueError(o); 358 | }, 359 | enumerable: !1, 360 | }, 361 | observe: { 362 | value(callBack) { 363 | if (!isCallable(callBack)) { 364 | syErr( 365 | "The argument of [Reference reactor].observe() must be a function." 366 | ); 367 | } 368 | 369 | if (refParser.observed.size === 0) { 370 | refParser.observed.set("callBack", callBack); 371 | 372 | return true; 373 | } 374 | 375 | return false; 376 | }, 377 | enumerable: !1, 378 | writable: !1, 379 | }, 380 | }); 381 | 382 | return reactor; 383 | } 384 | } 385 | -------------------------------------------------------------------------------- /core/renderif/errors.js: -------------------------------------------------------------------------------- 1 | import { 2 | syErr, 3 | err, 4 | ParserWarning, 5 | valueType, 6 | consW, 7 | getTagName, 8 | } from "../helpers.js"; 9 | 10 | export function runInvalidRenderIfInOptionError() { 11 | syErr(`The value of the "in" property in the renderIf function 12 | must be a string.`); 13 | } 14 | 15 | export function runInvalidRenderIfDataOptionError() { 16 | syErr(`The value of the "data" property in the renderIf function 17 | must be a plain Javascript object.`); 18 | } 19 | 20 | export function runNotDefinedConditionalPropWarning(prop) { 21 | consW(`"${prop}" was not defined as a conditional property.`); 22 | } 23 | 24 | export function runAlreadyUsedPropInConditionalGroupError(prop) { 25 | err(` 26 | Two elements in the conditional group can not have the same conditional property. 27 | Property: "${prop}" 28 | `); 29 | } 30 | 31 | export function runInvalidRenderIfObserveArgumentError() { 32 | syErr(`The argument of [renderIf reactor].observe() 33 | must be a function.`); 34 | } 35 | 36 | export function runInvalidRenderIfArgError() { 37 | syErr("The argument of renderIf must be a plain Javascript object."); 38 | } 39 | 40 | export function runInvalidConditionalPropValueError(prop) { 41 | err(`The value of a conditional property must be boolean(true/false), 42 | and the value of "${prop}" property is not boolean.`); 43 | } 44 | 45 | export function runHasMoreThanOneCondtionalAttributeError(child) { 46 | ParserWarning(`The conditional rendering parser found a/an "${getTagName( 47 | child 48 | )}" 49 | element which has more than one conditional atribute, it's forbidden.`); 50 | } 51 | 52 | export function runNotDefinedIfNotPropWarning( 53 | child, 54 | _ifNot /*propValue*/, 55 | data 56 | ) { 57 | if (_ifNot.trim().length == 0) { 58 | runInvalidConditionalAttrs("_ifNot"); 59 | return; 60 | } 61 | ParserWarning(` 62 | 63 | The conditional rendering parser found 64 | an element with the "_ifNot" attribute and the value 65 | of this attribute is not a conditional property. 66 | 67 | { 68 | element: ${child.nodeName.toLowerCase()}, 69 | _ifNot: ${_ifNot}, 70 | data: { ${Object.keys(data)} } 71 | } 72 | 73 | `); 74 | } 75 | 76 | function runInvalidConditionalAttrs(attrName) { 77 | ParserWarning(`The conditional rendering parser found an ${attrName} attribute that does not 78 | have a value assigned to it. Assign a value to the ${attrName} attribute. 79 | `); 80 | } 81 | 82 | export function runNotDefinedElseIfPropWarning(propValue) { 83 | if (propValue.trim().length == 0) { 84 | runInvalidConditionalAttrs("_elseIf"); 85 | return; 86 | } 87 | 88 | ParserWarning(`The conditional rendering parser found an element which has the "_elseIf" 89 | conditional property whose the value is: "${propValue}", 90 | but you did not define any conditional property with that name. 91 | 92 | `); 93 | } 94 | 95 | export function runInvalidElseAttributeError() { 96 | ParserWarning(`The parser found an element with the "_else" attribute, 97 | but there is not an element with the "_if" or a valid "_elseIf" attribute before it.`); 98 | } 99 | 100 | export function runInvalidElseIfAttributeError(child) { 101 | ParserWarning(`a/an "${getTagName( 102 | child 103 | )}" element has the "_elseIf" attribute, 104 | but it does not come after an element with the "_if" or a valid "_elseIf" attribute.`); 105 | } 106 | 107 | export function runInvalidSetCondsValueError(arg) { 108 | syErr(`The value of [renderIf reactor].setConds must be 109 | a plain Javascript object, and you defined ${valueType(arg)} 110 | as its value.`); 111 | } 112 | 113 | export function runNotDefinedIfPropWarning(propValue, child, data) { 114 | if (propValue.trim().length == 0) { 115 | runInvalidConditionalAttrs("_if"); 116 | return; 117 | } 118 | ParserWarning(` 119 | The conditional rendering parser found 120 | an element which has the "_if" attribute and the value 121 | of this attribute is not a conditional property. 122 | 123 | { 124 | element: ${child.nodeName.toLowerCase()}, 125 | _if: ${propValue}, 126 | data: { ${Object.keys(data)} } 127 | } 128 | 129 | `); 130 | } 131 | -------------------------------------------------------------------------------- /core/renderif/index.js: -------------------------------------------------------------------------------- 1 | import { 2 | isFalse, 3 | isObj, 4 | getId, 5 | consW, 6 | err, 7 | isCallable, 8 | isBool, 9 | isTrue, 10 | isDefined, 11 | isAtag, 12 | hasOwnProperty, 13 | } from "../helpers.js"; 14 | 15 | import { 16 | runAlreadyUsedPropInConditionalGroupError, 17 | runHasMoreThanOneCondtionalAttributeError, 18 | runInvalidConditionalPropValueError, 19 | runInvalidElseAttributeError, 20 | runInvalidElseIfAttributeError, 21 | runInvalidRenderIfArgError, 22 | runInvalidRenderIfDataOptionError, 23 | runInvalidRenderIfInOptionError, 24 | runInvalidRenderIfObserveArgumentError, 25 | runInvalidSetCondsValueError, 26 | runNotDefinedConditionalPropWarning, 27 | runNotDefinedElseIfPropWarning, 28 | runNotDefinedIfNotPropWarning, 29 | runNotDefinedIfPropWarning, 30 | } from "./errors.js"; 31 | 32 | function getChildNodes(root) { 33 | const nodes = new Array(); 34 | 35 | root.childNodes.forEach((node) => { 36 | if ( 37 | node.nodeType == 1 || 38 | (node.nodeType == 3 && !node.textContent.trim().length == 0) 39 | ) { 40 | nodes.push(node); 41 | } 42 | }); 43 | 44 | return nodes; 45 | } 46 | 47 | function runReservedPropWarning(prop) { 48 | consW( 49 | `"${prop}" is a reserved property, you can not use it as a conditional property.` 50 | ); 51 | } 52 | 53 | const conditionalAttributeCounter = { 54 | store: new Set(), 55 | set(keys) { 56 | for (const key of keys) { 57 | if (isDefined(key)) this.store.add(key); 58 | } 59 | }, 60 | 61 | getSize() { 62 | const size = this.store.size; 63 | 64 | this.store.clear(); 65 | 66 | return size; 67 | }, 68 | }; 69 | 70 | function hasMoreThanOneConditionalAttribute(elementNode) { 71 | const _ifAttrValue = elementNode.getAttribute("_if"), 72 | _elseIfAttrValue = elementNode.getAttribute("_elseIf"), 73 | _ifNotAttrValue = elementNode.getAttribute("_ifNot"), 74 | _elseAttr = elementNode.hasAttribute("_else") ? true : void 0; 75 | 76 | conditionalAttributeCounter.set([ 77 | _ifAttrValue, 78 | _elseIfAttrValue, 79 | _ifNotAttrValue, 80 | _elseAttr, 81 | ]); 82 | 83 | return conditionalAttributeCounter.getSize() > 1; 84 | } 85 | 86 | function hasNoConditionalAttr(elementNode) { 87 | const _ifAttr = elementNode.hasAttribute("_if"), 88 | _elseIfAttr = elementNode.hasAttribute("_elseIf"), 89 | _ifNotAttr = elementNode.hasAttribute("_ifNot"), 90 | _elseAttr = elementNode.hasAttribute("_else"); 91 | 92 | return !_ifAttr && !_elseIfAttr && !_ifNotAttr && !_elseAttr; 93 | } 94 | 95 | export function renderIf(obj) { 96 | if (!isObj(obj)) runInvalidRenderIfArgError(); 97 | 98 | if (new.target !== void 0) { 99 | err(`renderIf is not a constructor, do not call it with 100 | the new keyword.`); 101 | } else { 102 | const { in: IN, data } = obj; 103 | 104 | const reservedProps = new Set(["setConds", "observe"]); 105 | const theContainer = getId(IN); 106 | const conditionalRenderingCache = new Array(); 107 | 108 | // eslint-disable-next-line no-inner-declarations 109 | function parseAttrs(rootElement) { 110 | let index = -1; 111 | 112 | const parserOptions = { 113 | target: void 0, 114 | if: void 0, 115 | else: void 0, 116 | ifNot: void 0, 117 | elseIfs: new Set(), 118 | index: void 0, 119 | lastRendered: { 120 | target: void 0, 121 | prop: void 0, 122 | }, 123 | conditionalProps: new Set(), 124 | rootElement: rootElement, 125 | set setOptions(obj) { 126 | for (const [option, value] of Object.entries(obj)) { 127 | this[option] = value; 128 | 129 | if (option == "if" && isDefined(value)) 130 | this.conditionalProps.add(value); 131 | } 132 | }, 133 | 134 | canCache() { 135 | return this.if != void 0; 136 | }, 137 | 138 | addElseIf(elseIfOptions) { 139 | const { elseIf: prop } = elseIfOptions; 140 | 141 | if (!this.conditionalProps.has(prop)) { 142 | this.elseIfs.add(elseIfOptions); 143 | this.conditionalProps.add(prop); 144 | } else runAlreadyUsedPropInConditionalGroupError(prop); 145 | }, 146 | 147 | deleteData() { 148 | this.setOptions = { 149 | target: void 0, 150 | if: void 0, 151 | else: void 0, 152 | ifNot: void 0, 153 | index: void 0, 154 | }; 155 | 156 | this.elseIfs.clear(); 157 | this.conditionalProps.clear(); 158 | }, 159 | 160 | getOptions() { 161 | const options = Object.assign({}, this); 162 | options.elseIfs = Array.from(this.elseIfs); 163 | options.conditionalProps = Array.from(this.conditionalProps); 164 | 165 | this.deleteData(); 166 | 167 | return options; 168 | }, 169 | }; 170 | 171 | const cacheParserOptions = () => { 172 | const conditionalGroup = parserOptions.elseIfs.size; 173 | const options = parserOptions.getOptions(); 174 | if (conditionalGroup) conditionalRenderingCache.unshift(options); 175 | else conditionalRenderingCache.push(options); 176 | }; 177 | 178 | const rootElementChildNodes = getChildNodes(rootElement); 179 | const rootElementInitialLength = rootElementChildNodes.length; 180 | for (const child of rootElementChildNodes) { 181 | index++; 182 | child.index = index; 183 | 184 | const isTheLastIteration = rootElementInitialLength - 1 == index; 185 | 186 | if (child.nodeType == 3) { 187 | if (parserOptions.canCache()) cacheParserOptions(); 188 | 189 | continue; 190 | } 191 | 192 | if (!hasNoConditionalAttr(child)) child.parentNode.removeChild(child); 193 | 194 | if (child.children.length > 0) { 195 | parseAttrs(child); 196 | } 197 | 198 | if (hasMoreThanOneConditionalAttribute(child)) { 199 | runHasMoreThanOneCondtionalAttributeError(child); 200 | 201 | continue; 202 | } 203 | 204 | if (hasNoConditionalAttr(child) && parserOptions.canCache()) { 205 | cacheParserOptions(); 206 | 207 | continue; 208 | } 209 | 210 | if (child.hasAttribute("_ifNot")) { 211 | const _ifNot = child.getAttribute("_ifNot"); 212 | 213 | if (hasOwnProperty(data, _ifNot)) { 214 | child.removeAttribute("_ifNot"); 215 | 216 | if (parserOptions.canCache()) cacheParserOptions(); 217 | 218 | parserOptions.setOptions = { 219 | ifNot: _ifNot, 220 | target: child, 221 | index: index, 222 | }; 223 | 224 | cacheParserOptions(); 225 | 226 | continue; 227 | } else runNotDefinedIfNotPropWarning(child, _ifNot, data); 228 | } else if (child.hasAttribute("_else")) { 229 | if (!parserOptions.if) runInvalidElseAttributeError(); 230 | else { 231 | parserOptions.else = child; 232 | child.removeAttribute("_else"); 233 | cacheParserOptions(); 234 | } 235 | } else if (child.hasAttribute("_elseIf")) { 236 | const elseIf = child.getAttribute("_elseIf"); 237 | child.removeAttribute("_elseIf"); 238 | 239 | if (!parserOptions.if) runInvalidElseIfAttributeError(child); 240 | else if (!hasOwnProperty(data, elseIf)) 241 | runNotDefinedElseIfPropWarning(elseIf); 242 | else { 243 | parserOptions.addElseIf({ 244 | target: child, 245 | index: index, 246 | elseIf: elseIf, 247 | }); 248 | } 249 | } else if (child.hasAttribute("_if")) { 250 | if (parserOptions.canCache()) cacheParserOptions(); 251 | 252 | const _if = child.getAttribute("_if"); 253 | 254 | child.removeAttribute("_if"); 255 | 256 | if (!hasOwnProperty(data, _if)) { 257 | runNotDefinedIfPropWarning(_if, child, data); 258 | 259 | continue; 260 | } 261 | 262 | parserOptions.setOptions = { 263 | if: _if, 264 | target: child, 265 | index: index, 266 | }; 267 | } 268 | 269 | if (isTheLastIteration && parserOptions.canCache()) 270 | cacheParserOptions(); 271 | } 272 | } 273 | 274 | if (!(typeof IN === "string")) runInvalidRenderIfInOptionError(); 275 | 276 | if (!isObj(data)) runInvalidRenderIfDataOptionError(); 277 | 278 | // eslint-disable-next-line prefer-const 279 | for (let [prop, value] of Object.entries(data)) { 280 | if (reservedProps.has(prop)) { 281 | runReservedPropWarning(prop); 282 | continue; 283 | } 284 | 285 | value = isCallable(value) ? value.call(data) : value; 286 | 287 | if (!isBool(value)) runInvalidConditionalPropValueError(prop); 288 | 289 | data[prop] = value; 290 | } 291 | 292 | parseAttrs(theContainer); 293 | 294 | const reactor = runRenderingSystem(conditionalRenderingCache, data); 295 | return reactor; 296 | } 297 | } 298 | 299 | function runRenderingSystem(ArrayOfOptions, data) { 300 | function falsefyProps(conditionalProps, changedProp) { 301 | if (isFalse(proxyTarget[changedProp]) || conditionalProps.length < 2) 302 | return; 303 | 304 | for (const prop of conditionalProps) { 305 | const hasTrueValue = isTrue(proxyTarget[prop]); 306 | 307 | if (hasTrueValue && prop !== changedProp) { 308 | proxyTarget[prop] = false; 309 | } 310 | } 311 | } 312 | 313 | function renderElseIf(elseIfs, options) { 314 | function lastRenderedHasParent() { 315 | return options.lastRendered.target.parentNode != null; 316 | } 317 | 318 | let rendered = false; 319 | 320 | for (const { target, elseIf } of elseIfs) { 321 | const lastRendered = options.lastRendered; 322 | 323 | if (lastRendered.target && isTrue(proxyTarget[lastRendered.prop])) { 324 | rendered = true; 325 | 326 | break; 327 | } 328 | 329 | if ( 330 | lastRendered.target && 331 | isFalse(proxyTarget[lastRendered.prop]) && 332 | lastRenderedHasParent() 333 | ) { 334 | options.rootElement.removeChild(lastRendered.target); 335 | options.lastRendered = { prop: void 0, target: void 0 }; 336 | } 337 | 338 | if (isTrue(proxyTarget[elseIf])) { 339 | insertBefore(options.rootElement, target); 340 | 341 | options.lastRendered = { 342 | prop: elseIf, 343 | target: target, 344 | }; 345 | 346 | rendered = true; 347 | if ( 348 | lastRendered.target && 349 | !isDefined(lastRendered.prop) && 350 | lastRenderedHasParent() 351 | ) { 352 | /*The last rendered element was the one with the _else attribute*/ 353 | 354 | options.rootElement.removeChild(lastRendered.target); 355 | } 356 | } 357 | } 358 | 359 | return rendered; 360 | } 361 | 362 | function checkWhatToRender(source, changedProp) { 363 | for (const options of ArrayOfOptions) { 364 | const { 365 | target, 366 | if: IF, 367 | elseIfs, 368 | else: ELSE, 369 | ifNot, 370 | rootElement, 371 | } = options; 372 | const conditionalProps = options.conditionalProps; 373 | const isInConditionalGroup = new Set(conditionalProps).has(changedProp); 374 | 375 | if (isDefined(changedProp) && isInConditionalGroup) 376 | falsefyProps(conditionalProps, changedProp); 377 | 378 | if (ifNot) { 379 | if (isFalse(source[ifNot]) && target.parentNode == null) { 380 | if (rootElement.textContent.trim().length > 0) { 381 | insertBefore(rootElement, target); 382 | } else { 383 | rootElement.appendChild(target); 384 | } 385 | } else { 386 | if (target.parentNode == rootElement && isTrue(source[ifNot])) { 387 | rootElement.removeChild(target); 388 | } 389 | } 390 | } else if (isFalse(source[IF])) { 391 | if (target.parentNode == rootElement && !ELSE) { 392 | rootElement.removeChild(target); 393 | renderElseIf(elseIfs, options); 394 | } else if (ELSE || elseIfs.length > 0) { 395 | const rendered = renderElseIf(elseIfs, options); 396 | 397 | if (target.parentNode != null) rootElement.removeChild(target); 398 | if (rendered && ELSE && ELSE.parentNode != null) { 399 | ELSE.parentNode.removeChild(ELSE); 400 | } else if (!rendered && ELSE && ELSE.parentNode == null) { 401 | insertBefore(rootElement, ELSE); 402 | options.lastRendered = { 403 | target: ELSE, 404 | prop: void 0, 405 | }; 406 | } 407 | } 408 | } else if (isTrue(source[IF])) { 409 | if (target.parentNode == null) { 410 | if (ELSE && ELSE.parentNode != null) { 411 | rootElement.removeChild(ELSE); 412 | insertBefore(rootElement, target); 413 | } else { 414 | insertBefore(rootElement, target); 415 | } 416 | 417 | const { target: _target } = options.lastRendered; 418 | 419 | if ( 420 | isAtag(_target) && 421 | _target.parentNode != null && 422 | !_target.isSameNode(target) 423 | ) { 424 | _target.parentNode.removeChild(_target); 425 | } 426 | 427 | options.lastRendered = { 428 | target: target, 429 | prop: IF, 430 | }; 431 | } 432 | } 433 | } 434 | } 435 | function insertBefore(root, target) { 436 | const children = getChildNodes(root), 437 | lastChild = children[children.length - 1]; 438 | 439 | if (target && target.parentNode == null) { 440 | if (lastChild && lastChild.index > target.index) { 441 | for (const child of children) { 442 | if (child.index > target.index) { 443 | root.insertBefore(target, child); 444 | 445 | break; 446 | } 447 | } 448 | } else { 449 | root.appendChild(target); 450 | } 451 | } 452 | } 453 | 454 | function runObserveCallBack(prop, value) { 455 | if (observer.size == 1) { 456 | const callBack = observer.get("callBack"); 457 | 458 | callBack(prop, value); 459 | } 460 | } 461 | 462 | const reservedProps = new Set(["setConds", "observe"]); 463 | const observer = new Map(); 464 | const proxyTarget = Object.assign({}, data); 465 | 466 | checkWhatToRender(proxyTarget); 467 | 468 | const reactor = new Proxy(proxyTarget, { 469 | set(target, prop, value) { 470 | if (prop in target && target[prop] == value) return false; 471 | if (!(prop in data) && !reservedProps.has(prop)) { 472 | runNotDefinedConditionalPropWarning(prop); 473 | 474 | return false; 475 | } 476 | 477 | if (!isBool(value) && !reservedProps.has(prop)) { 478 | runInvalidConditionalPropValueError(prop); 479 | 480 | return false; 481 | } 482 | 483 | Reflect.set(target, prop, value); 484 | 485 | if (!reservedProps.has(prop)) { 486 | checkWhatToRender(proxyTarget, prop); 487 | 488 | runObserveCallBack(prop, value); 489 | } 490 | 491 | return true; 492 | }, 493 | 494 | deleteProperty() { 495 | return false; 496 | }, 497 | }); 498 | 499 | Object.defineProperties(reactor, { 500 | observe: { 501 | value(fn) { 502 | if (!isCallable(fn)) runInvalidRenderIfObserveArgumentError(); 503 | 504 | if (observer.size == 0) { 505 | observer.set("callBack", fn); 506 | 507 | return true; 508 | } 509 | 510 | return false; 511 | }, 512 | enumerable: !1, 513 | writable: !1, 514 | }, 515 | setConds: { 516 | set(conditions) { 517 | if (!isObj(conditions)) runInvalidSetCondsValueError(conditions); 518 | 519 | // eslint-disable-next-line prefer-const 520 | for (let [prop, cond] of Object.entries(conditions)) { 521 | if (reservedProps.has(prop)) { 522 | runReservedPropWarning(prop); 523 | continue; 524 | } 525 | 526 | cond = isCallable(cond) ? cond.call(data) : cond; 527 | 528 | if (!isBool(cond)) runInvalidConditionalPropValueError(prop); 529 | 530 | if (!hasOwnProperty(this, prop)) { 531 | runNotDefinedConditionalPropWarning(prop); 532 | continue; 533 | } 534 | 535 | if (this[prop] == cond) continue; 536 | 537 | proxyTarget[prop] = cond; 538 | 539 | runObserveCallBack(prop, cond); 540 | } 541 | 542 | checkWhatToRender(proxyTarget); 543 | }, 544 | enumerable: !1, 545 | }, 546 | }); 547 | 548 | return reactor; 549 | } 550 | -------------------------------------------------------------------------------- /core/renderlist/errors.js: -------------------------------------------------------------------------------- 1 | import { consW, syErr, valueType, err } from "../helpers.js"; 2 | 3 | export function runCanNotDefineReactivePropWarning() { 4 | consW(`Inter failed to define reactivity 5 | in a plain Javascript object, because it is not configurable.`); 6 | } 7 | 8 | export function runDetecteReservedPropdWarnig(prop) { 9 | consW( 10 | `"${prop}" is a reserved property, do not create a property with this name.` 11 | ); 12 | } 13 | 14 | export function runInvalidDefinePropsValueError(props) { 15 | syErr(`The value of "defineProps" must be a plain Javascript object, and you 16 | defined "${valueType(props)}" as its value`); 17 | } 18 | 19 | export function runInvalidSetPropsValueError(props) { 20 | syErr(`The value of "setProps" must be a plain Javascript object, and you 21 | defined "${valueType(props)}" as its value`); 22 | } 23 | 24 | export function runInvalidDeletePropsValueError(props) { 25 | syErr(`The value of "deleteProps" must be an Array object, and you 26 | defined "${valueType(props)}" as its value`); 27 | } 28 | 29 | export function runNotConfigurableArrayError() { 30 | err(`Inter failed to define the reactivity, 31 | because the Array of the each option is not configurable.`); 32 | } 33 | 34 | export function runUnsupportedEachValueError(value) { 35 | syErr(`"${valueType( 36 | value 37 | )}" is not a valid value for the "each" option in renderList. 38 | The values that are accepted in "each" option, are: 39 | Array. 40 | Plain js object. 41 | Number. 42 | Map. 43 | Set.`); 44 | } 45 | 46 | export function runInvalidAddItemsSecodArgumentError() { 47 | syErr("The second argument of [LIST REACTOR].addItems must be a number."); 48 | } 49 | 50 | export function runInvalidAddItemsFirstArgumentError() { 51 | syErr("The first argument of [LIST REACTOR ].addItems must be an Array."); 52 | } 53 | 54 | export function runInvalidTemplateReturnError() { 55 | syErr(`The template function is not being returned inside the "do" method in 56 | renderList(reactive listing), just return the template function.`); 57 | } 58 | -------------------------------------------------------------------------------- /core/renderlist/index.js: -------------------------------------------------------------------------------- 1 | import { 2 | syErr, 3 | isObj, 4 | isCallable, 5 | validInProperty, 6 | validEachProperty, 7 | Iterable, 8 | isAtag, 9 | getId, 10 | consW, 11 | isArray, 12 | isDefined, 13 | isMap, 14 | isSet, 15 | isFalse, 16 | isNotConfigurable, 17 | validStyleName, 18 | validDomEvent, 19 | isValidTemplateReturn, 20 | isPositiveValue, 21 | isNegativeValue, 22 | hasOwnProperty, 23 | isTrue, 24 | isTringOrNumber, 25 | } from "../helpers.js"; 26 | 27 | import { 28 | runCanNotDefineReactivePropWarning, 29 | runDetecteReservedPropdWarnig, 30 | runInvalidAddItemsFirstArgumentError, 31 | runInvalidAddItemsSecodArgumentError, 32 | runInvalidDefinePropsValueError, 33 | runInvalidDeletePropsValueError, 34 | runInvalidSetPropsValueError, 35 | runInvalidTemplateReturnError, 36 | runNotConfigurableArrayError, 37 | runUnsupportedEachValueError, 38 | } from "./errors.js"; 39 | 40 | import { toDOM } from "../template/index.js"; 41 | 42 | import { 43 | runIllegalAttrsPropWarning, 44 | runInvalidEventHandlerWarning, 45 | runInvalidEventWarning, 46 | runInvalidStyleWarning, 47 | runInvalidStyleValue, 48 | } from "../template/errors.js"; 49 | 50 | /** 51 | * Reactive system for listing. 52 | * 53 | */ 54 | 55 | function checkType(arg, call, _, indexObj) { 56 | if (isObj(arg)) defineReactiveObj(arg, call, indexObj); 57 | else if (isArray(arg)) defineReactiveArray(arg, call, indexObj); 58 | else if (isMap(arg)) defineReactiveMap(arg, call); 59 | else if (isSet(arg)) defineReactiveSet(arg, call, false, null, indexObj); 60 | } 61 | 62 | function defineReactiveSymbol(obj) { 63 | if (hasReactiveSymbol(obj)) return false; 64 | const symbol = Symbol.for("reactive"); 65 | 66 | Object.defineProperty(obj, symbol, { 67 | get: () => true, 68 | }); 69 | } 70 | 71 | function hasReactiveSymbol(obj) { 72 | const symbol = Symbol.for("reactive"); 73 | 74 | return hasOwnProperty(obj, symbol); 75 | } 76 | 77 | function defineReactiveObj(obj, renderingSystem, indexObj) { 78 | const reservedProps = new Set(["setProps", "defineProps", "deleteProps"]); 79 | 80 | function defineReservedProps(props) { 81 | for (const { name, setHandler } of props) { 82 | Object.defineProperty(obj, name, { 83 | set: setHandler, 84 | }); 85 | } 86 | } 87 | 88 | const indexSymbol = Symbol.for("index"); 89 | if (isObj(indexObj)) { 90 | obj[indexSymbol] = indexObj; 91 | } 92 | 93 | function defineReactiveProp(prop) { 94 | let readValue = obj[prop]; 95 | 96 | obj[prop] = void 0; 97 | Object.defineProperty(obj, prop, { 98 | set(newValue) { 99 | readValue = newValue; 100 | 101 | if (isTringOrNumber(newValue) && readValue == newValue) return; 102 | 103 | if (obj[indexSymbol]) { 104 | const index = obj[indexSymbol].index; 105 | renderingSystem(index); 106 | } else renderingSystem(); 107 | 108 | const hasIndexObj = isObj(indexObj); 109 | 110 | checkType( 111 | newValue, 112 | renderingSystem, 113 | null, 114 | hasIndexObj ? indexObj : null 115 | ); 116 | }, 117 | 118 | get() { 119 | return readValue; 120 | }, 121 | configurable: !0, 122 | }); 123 | } 124 | 125 | function deleteProps(props) { 126 | if (!isArray(props)) runInvalidDeletePropsValueError(props); 127 | const index = isObj(indexObj) ? indexObj.index : void 0; 128 | for (const prop of props) { 129 | if (typeof prop !== "string") continue; 130 | else if (!hasOwnProperty(obj, prop)) continue; 131 | else if (!reservedProps.has(prop)) delete obj[prop]; 132 | } 133 | 134 | renderingSystem(index); 135 | } 136 | 137 | function defineProps(props) { 138 | if (!isObj(props)) runInvalidDefinePropsValueError(props); 139 | const index = isObj(indexObj) ? indexObj.index : void 0; 140 | for (const [prop, value] of Object.entries(props)) { 141 | if (!(prop in this) && !reservedProps.has(prop)) { 142 | obj[prop] = value; 143 | defineReactiveProp(prop); 144 | checkType(obj[prop], renderingSystem, null, indexObj); 145 | } 146 | 147 | renderingSystem(index); 148 | } 149 | } 150 | 151 | function setProps(props) { 152 | if (!isObj(props)) runInvalidSetPropsValueError(props); 153 | 154 | for (const [prop, value] of Object.entries(props)) { 155 | if (!reservedProps.has(prop)) obj[prop] = value; 156 | } 157 | } 158 | 159 | if (hasReactiveSymbol(obj)) { 160 | //The object is already reactive 161 | //So, we must skip all the task. 162 | 163 | return true; 164 | } 165 | 166 | if (isNotConfigurable(obj)) { 167 | runCanNotDefineReactivePropWarning(); 168 | return false; 169 | } 170 | 171 | for (const prop of Object.keys(obj)) { 172 | if (reservedProps.has(prop)) runDetecteReservedPropdWarnig(prop); 173 | 174 | defineReactiveProp(prop); 175 | 176 | checkType(obj[prop], renderingSystem, null, indexObj); 177 | } 178 | 179 | const reservedPropsSetting = [ 180 | { name: "defineProps", setHandler: defineProps }, 181 | { name: "setProps", setHandler: setProps }, 182 | { name: "deleteProps", setHandler: deleteProps }, 183 | ]; 184 | 185 | defineReservedProps(reservedPropsSetting); 186 | defineReactiveSymbol(obj); 187 | } 188 | 189 | function exactElToRemove(obj) { 190 | if (isObj(obj)) _inObj(...arguments); 191 | else if (isSet(obj)) _inSet(...arguments); 192 | else _inMap(...arguments); 193 | } 194 | 195 | function _inObj(obj, key, root) { 196 | const keys = Object.keys(obj); 197 | 198 | keys.some((prop, i) => { 199 | if (prop == key) _exactRemove(root, i); 200 | }); 201 | } 202 | 203 | function _inSet(set, key, root) { 204 | const obj = Array.from(set); 205 | 206 | obj.some((item, i) => { 207 | if (item == key) _exactRemove(root, i); 208 | }); 209 | } 210 | 211 | function _inMap(obj, key, root) { 212 | let i = -1; 213 | 214 | obj.forEach(() => { 215 | i++; 216 | const prop = arguments[1]; 217 | 218 | if (prop == key) _exactRemove(root, i); 219 | }); 220 | } 221 | 222 | function _exactRemove(root, i) { 223 | const elToRmove = root.children[i]; 224 | 225 | if (isAtag(elToRmove)) root.removeChild(elToRmove); 226 | } 227 | 228 | function runObserveCallBack(each, proxy) { 229 | const observe = Symbol.for("observe"); 230 | if (typeof each[observe] === "function") 231 | each[observe](isDefined(proxy) ? proxy : each); 232 | } 233 | 234 | function createArrayReactor(each, renderingSystem) { 235 | if (isNotConfigurable(each)) runNotConfigurableArrayError(); 236 | 237 | const customProps = new Set(["addItems", "setEach"]); 238 | 239 | return new Proxy(each, { 240 | set(target, prop, value, proxy) { 241 | if (customProps.has(prop)) { 242 | Reflect.set(...arguments); 243 | return true; 244 | } 245 | 246 | Reflect.set(...arguments); 247 | 248 | runObserveCallBack(each, proxy); 249 | 250 | renderingSystem(); 251 | 252 | if (typeof value !== "number" && validEachProperty(value)) 253 | checkType(value, renderingSystem); 254 | 255 | return true; 256 | }, 257 | 258 | get(target, prop) { 259 | /** 260 | * Note: Don't use Reflet.get(...arguments) here, because if 261 | * it's an Array of objects it will return an empty object. 262 | * 263 | */ 264 | 265 | return target[prop]; 266 | }, 267 | }); 268 | } 269 | 270 | function defineListReactorSetProps(obj, renderingSystem) { 271 | Object.defineProperty(obj, "setProps", { 272 | set(props) { 273 | if (!isObj(props)) runInvalidSetPropsValueError(); 274 | 275 | for (const [prop, value] of Object.entries(props)) { 276 | if (isObj(obj)) this[prop] = value; 277 | else if (isMap(obj)) obj.set(prop, value); 278 | 279 | checkType(value, renderingSystem); 280 | } 281 | 282 | if (isObj(obj)) renderingSystem(); 283 | }, 284 | }); 285 | } 286 | 287 | function createObjReactor(each, renderingSystem, root) { 288 | if (isNotConfigurable(each)) runNotConfigurableArrayError(); 289 | 290 | defineListReactorSetProps(each, renderingSystem); 291 | 292 | const specialProps = new Set(["observe"]); 293 | const settableRservedProps = new Set(["setEach", "setProps"]); 294 | 295 | function isNotReservedSettableProp(prop) { 296 | return !settableRservedProps.has(prop); 297 | } 298 | defineReactiveSymbol(each); 299 | 300 | return new Proxy(each, { 301 | set(target, prop, value, proxy) { 302 | if (specialProps.has(prop)) return false; 303 | if (isTringOrNumber(value) && value == target[prop]) return false; 304 | 305 | Reflect.set(...arguments); 306 | 307 | if (isNotReservedSettableProp(prop)) { 308 | renderingSystem(); 309 | runObserveCallBack(each, proxy); 310 | 311 | if (typeof value !== "number" && validEachProperty(value)) 312 | checkType(value, renderingSystem); 313 | } 314 | 315 | return true; 316 | }, 317 | 318 | get() { 319 | return Reflect.get(...arguments); 320 | }, 321 | 322 | deleteProperty(target, prop, proxy) { 323 | if (prop in target) { 324 | exactElToRemove(target, prop, root); 325 | Reflect.deleteProperty(...arguments); 326 | renderingSystem(); 327 | runObserveCallBack(each, proxy); 328 | 329 | return true; 330 | } 331 | 332 | consW(`You are trying to delete the "${prop}" property in the list 333 | reactor, but that property does not exist in the list reactor.`); 334 | }, 335 | }); 336 | } 337 | 338 | function mutateArrayMap(array) { 339 | Object.defineProperty(array, "map", { 340 | value(callBack) { 341 | const newArray = new Array(); 342 | newArray.reactor = this; 343 | let index = -1; 344 | 345 | for (const item of this) { 346 | index++; 347 | 348 | const returnValue = callBack(item, index, this); 349 | newArray.push(returnValue); 350 | } 351 | 352 | return newArray; 353 | }, 354 | }); 355 | } 356 | 357 | function defineReactiveArray(array, renderingSystem, indexObj) { 358 | if (hasReactiveSymbol(array)) return false; 359 | 360 | const mutationMethods = [ 361 | "push", 362 | "unshift", 363 | "pop", 364 | "shift", 365 | "splice", 366 | "sort", 367 | "reverse", 368 | ]; 369 | 370 | for (const method of mutationMethods) { 371 | Object.defineProperty(array, method, { 372 | value(start, deleteCount, ...items) { 373 | if (method == "pop") 374 | this.mutationInfo = { 375 | method: "pop", 376 | renderingSystem: renderingSystem, 377 | }; 378 | else if (method == "shift") 379 | this.mutationInfo = { 380 | method: "shift", 381 | renderingSystem: renderingSystem, 382 | }; 383 | else if (method == "push") 384 | this.mutationInfo = { 385 | method: "push", 386 | itemsLength: arguments.length, 387 | renderingSystem: renderingSystem, 388 | }; 389 | else if (method == "unshift") 390 | this.mutationInfo = { 391 | method: "unshift", 392 | itemsLength: arguments.length, 393 | renderingSystem: renderingSystem, 394 | }; 395 | else if (method == "splice") { 396 | this.mutationInfo = { 397 | method: "splice", 398 | start: start, 399 | deleteCount: deleteCount, 400 | itemsLength: isDefined(items) ? items.length : 0, 401 | renderingSystem: renderingSystem, 402 | }; 403 | } 404 | 405 | const ArrayPrototypeMethodReturn = Array.prototype[method].apply( 406 | this, 407 | arguments 408 | ); 409 | 410 | renderingSystem(); 411 | 412 | this.mutationInfo = void 0; 413 | 414 | if (method === "push" || method === "unshift") { 415 | for (const arg of arguments) { 416 | checkType(arg, renderingSystem, null, indexObj); 417 | } 418 | } else if (method === "splice" && isDefined(items)) { 419 | for (const item of items) { 420 | checkType(item, renderingSystem, null, indexObj); 421 | } 422 | } 423 | 424 | return ArrayPrototypeMethodReturn; 425 | }, 426 | }); 427 | } 428 | 429 | walkArray(array, renderingSystem, indexObj); 430 | defineReactiveSymbol(array); 431 | mutateArrayMap(array); 432 | } 433 | 434 | function defineReactiveMap(map, renderingSystem, listReactor, root) { 435 | if (hasReactiveSymbol(map)) return false; 436 | 437 | const mutationMethods = ["set", "delete", "clear"]; 438 | 439 | for (const method of mutationMethods) { 440 | Object.defineProperty(map, method, { 441 | value() { 442 | if (method == "delete" && listReactor) 443 | exactElToRemove(this, arguments[0], root); 444 | const MapPrototypeMethodReturn = Map.prototype[method].apply( 445 | this, 446 | arguments 447 | ); 448 | if (listReactor) runObserveCallBack(this); 449 | renderingSystem(); 450 | 451 | if (method == "set") { 452 | const value = arguments[1]; 453 | 454 | checkType(value, renderingSystem); 455 | } 456 | 457 | return MapPrototypeMethodReturn; 458 | }, 459 | }); 460 | } 461 | 462 | walkMap(map, renderingSystem); 463 | defineReactiveSymbol(map); 464 | if (listReactor) defineListReactorSetProps(map, renderingSystem); 465 | } 466 | 467 | function defineReactiveSet(set, renderingSystem, listReactor, root, indexObj) { 468 | if (hasReactiveSymbol(set)) return false; 469 | 470 | const mutationMethods = ["add", "clear", "delete"]; 471 | 472 | for (const method of mutationMethods) { 473 | Object.defineProperty(set, method, { 474 | value() { 475 | if (method == "delete" && listReactor) 476 | exactElToRemove(this, arguments[0], root); 477 | const SetPrototypeMethodReturn = Set.prototype[method].apply( 478 | this, 479 | arguments 480 | ); 481 | renderingSystem(); 482 | if (listReactor) runObserveCallBack(this); 483 | if (method === "add") { 484 | checkType(arguments[0], renderingSystem); 485 | } 486 | 487 | return SetPrototypeMethodReturn; 488 | }, 489 | }); 490 | } 491 | 492 | walkSet(set, renderingSystem, indexObj); 493 | defineReactiveSymbol(set); 494 | } 495 | 496 | function walkMap(map, call) { 497 | /** 498 | * The goal here is to iterate through the map collection 499 | * and if we found an object, an array, a set or even a map, we must make it reactive. 500 | * 501 | */ 502 | 503 | map.forEach((value) => { 504 | checkType(value, call); 505 | }); 506 | } 507 | 508 | function walkArray(array, call, indexObj) { 509 | for (const item of array) { 510 | checkType(item, call, null, indexObj); 511 | } 512 | } 513 | 514 | function walkSet(set, call, indexObj) { 515 | set.forEach((value) => { 516 | checkType(value, call, null, indexObj); 517 | }); 518 | } 519 | 520 | function redefineArrayMutationMethods(array, htmlEl, renderingSystem, DO, pro) { 521 | function render(item, i, start, secondI) { 522 | const temp = DO.call(pro, item, i, pro); 523 | const newChild = toDOM(temp.element); 524 | const domChild = htmlEl.children[start]; 525 | 526 | if (!isValidTemplateReturn(temp)) runInvalidTemplateReturnError(); 527 | 528 | if (newChild && isDefined(start)) { 529 | htmlEl.insertBefore(newChild, domChild); 530 | } else { 531 | htmlEl.appendChild(newChild); 532 | } 533 | 534 | if (isDefined(secondI)) i = secondI; 535 | 536 | renderingSystem(i, true); 537 | } 538 | 539 | function ArrayPrototypeShiftHandler() { 540 | const ArrayPrototypeShiftReturn = Array.prototype.shift.apply( 541 | array, 542 | void 0 543 | ); 544 | const firstNodeElement = htmlEl.children[0]; 545 | 546 | if (firstNodeElement) { 547 | htmlEl.removeChild(firstNodeElement); 548 | 549 | renderingSystem(); 550 | runObserveCallBack(array); 551 | } 552 | 553 | return ArrayPrototypeShiftReturn; 554 | } 555 | 556 | function ArrayPrototypePopHandler() { 557 | const ArrayPrototypePopReturn = Array.prototype.pop.apply(array, arguments); 558 | const children = htmlEl.children; 559 | const lastNodeElement = children[children.length - 1]; 560 | 561 | if (lastNodeElement) { 562 | htmlEl.removeChild(lastNodeElement); 563 | renderingSystem(); 564 | runObserveCallBack(array); 565 | } 566 | 567 | return ArrayPrototypePopReturn; 568 | } 569 | 570 | function ArrayPrototypePushHandler() { 571 | const ArrayPrototypePushReturn = Array.prototype.push.apply( 572 | array, 573 | arguments 574 | ); 575 | 576 | if (arguments.length == 1) render(...arguments, array.length - 1); 577 | else if (arguments.length > 1) { 578 | let length = arguments.length; 579 | for (const item of arguments) render(item, array.length - length--); 580 | } 581 | 582 | renderingSystem(); 583 | runObserveCallBack(array); 584 | 585 | return ArrayPrototypePushReturn; 586 | } 587 | 588 | function ArrayPrototypeUnshiftHandler() { 589 | const ArrayPrototypeUnshiftReturn = Array.prototype.unshift.apply( 590 | array, 591 | arguments 592 | ); 593 | 594 | if (arguments.length > 1) { 595 | let i = arguments.length; 596 | 597 | for (let index = i - 1; index > -1; index--) 598 | render(arguments[--i], 0, 0, i); 599 | } else if (arguments.length == 1) render(...arguments, 0, 0); 600 | 601 | renderingSystem(); 602 | runObserveCallBack(array); 603 | 604 | return ArrayPrototypeUnshiftReturn; 605 | } 606 | 607 | function ArrayPrototypeSpliceHandler(start, deleteCount, ...items) { 608 | const ArrayPrototypeSpliceReturn = Array.prototype.splice.apply( 609 | array, 610 | arguments 611 | ); 612 | 613 | function deleteChildren() { 614 | const length = deleteCount; 615 | for (let i = 0; i < length; i++) { 616 | const child = htmlEl.children[start]; 617 | 618 | if (child) htmlEl.removeChild(child); 619 | } 620 | } 621 | 622 | function insertBehind() { 623 | for (let i = items.length - 1; i > -1; i--) render(items[i], i, start); 624 | } 625 | 626 | if (deleteCount > 0 && items.length > 0) { 627 | deleteChildren(); 628 | insertBehind(); 629 | } 630 | 631 | if (items.length == 0) deleteChildren(); 632 | else if (deleteCount == 0 && items.length > 0) insertBehind(); 633 | 634 | renderingSystem(); 635 | 636 | runObserveCallBack(array); 637 | 638 | return ArrayPrototypeSpliceReturn; 639 | } 640 | 641 | const mutatedMethods = [ 642 | { name: "unshift", handler: ArrayPrototypeUnshiftHandler }, 643 | { name: "shift", handler: ArrayPrototypeShiftHandler }, 644 | { name: "push", handler: ArrayPrototypePushHandler }, 645 | { name: "pop", handler: ArrayPrototypePopHandler }, 646 | { name: "splice", handler: ArrayPrototypeSpliceHandler }, 647 | ]; 648 | 649 | if (isNotConfigurable(array)) return false; 650 | 651 | //It is already reactive array. 652 | if (hasReactiveSymbol(array)) return false; 653 | 654 | for (const { name, handler } of mutatedMethods) { 655 | Object.defineProperty(array, name, { 656 | value: handler, 657 | }); 658 | } 659 | } 660 | 661 | export function renderList(options) { 662 | function defineListReactor(each, renderingSystem, root) { 663 | if (isArray(each)) { 664 | defineCustomArrayProps(each); 665 | return createArrayReactor(each, renderingSystem); 666 | } else if (isObj(each)) { 667 | return createObjReactor(each, renderingSystem, root); 668 | } else if (isSet(each)) { 669 | defineReactiveSet(each, renderingSystem, true, root); 670 | 671 | return each; 672 | } else { 673 | if (isMap(each)) { 674 | defineReactiveMap(each, renderingSystem, true, root); 675 | 676 | return each; 677 | } 678 | } 679 | } 680 | 681 | if (new.target !== void 0) { 682 | syErr(`renderList is not a constructor, do not call 683 | it with the "new" keyword.`); 684 | } 685 | 686 | if (!isObj(options)) { 687 | syErr( 688 | "The options(the argument of renderList) must be a plain Javascript object." 689 | ); 690 | } 691 | 692 | /*eslint-disable prefer-const*/ 693 | 694 | let { in: IN, each, do: DO, optimize } = options; 695 | 696 | /*eslint-enable prefer-const*/ 697 | 698 | const root = getId(IN); 699 | 700 | if (!validInProperty(IN)) { 701 | syErr("The 'in' option in renderList must be a string."); 702 | } 703 | 704 | if (!validEachProperty(each)) runUnsupportedEachValueError(each); 705 | 706 | if (!isCallable(DO)) { 707 | syErr( 708 | "The value of the 'do' option in renderList must be only a function." 709 | ); 710 | } 711 | 712 | if (isDefined(optimize) && !isTrue(optimize)) { 713 | syErr("The value of the 'optimize' option in renderList must be only true"); 714 | } 715 | 716 | if (isDefined(optimize) && !isArray(each)) { 717 | syErr( 718 | "The 'optimize' option can only be enabled when the each's value is an Array." 719 | ); 720 | } 721 | 722 | let pro, 723 | firstRender = true; 724 | 725 | function setEachHandler(newEach) { 726 | if (!validEachProperty(newEach)) runUnsupportedEachValueError(newEach); 727 | 728 | const observeSymbol = Symbol.for("observe"); 729 | newEach[observeSymbol] = each[observeSymbol]; 730 | each = newEach; 731 | 732 | if (!hasReactiveSymbol(newEach)) proSetup(); 733 | 734 | renderingSystem(); 735 | runObserveCallBack(each); 736 | 737 | if (typeof each !== "number") { 738 | const iterable = new Iterable(each); 739 | 740 | iterable.each((data, index, type) => { 741 | if (type == "object") checkType(data[1], renderingSystem); 742 | else if (type == "array" || type == "set") 743 | checkType(data, renderingSystem); 744 | }); 745 | } 746 | } 747 | 748 | function proSetup() { 749 | if (hasReactiveSymbol(each)) return false; 750 | Object.defineProperties(each, { 751 | setEach: { set: setEachHandler }, 752 | observe: { 753 | value(callBack) { 754 | const observe = Symbol.for("observe"); 755 | if (typeof this[observe] === "function") return false; 756 | if (!isCallable(callBack)) 757 | syErr("The argument of the observe method must be a function."); 758 | else { 759 | Object.defineProperty(this, observe, { 760 | value: callBack, 761 | configurable: !1, 762 | }); 763 | 764 | return true; 765 | } 766 | }, 767 | }, 768 | }); 769 | 770 | pro = defineListReactor(each, renderingSystem, root, true); 771 | 772 | if (isArray(each)) 773 | redefineArrayMutationMethods(each, root, renderingSystem, DO, pro); 774 | 775 | defineReactiveSymbol(each); 776 | } 777 | 778 | function defineProp(obj, prop, descriptiors) { 779 | Object.defineProperty(obj, prop, descriptiors); 780 | } 781 | 782 | function defineCustomArrayProps(array) { 783 | if (hasReactiveSymbol(array)) return false; 784 | 785 | function addItemsHandler(items, position) { 786 | if (isDefined(position) && typeof position !== "number") 787 | runInvalidAddItemsSecodArgumentError(); 788 | 789 | if (!isArray(items)) runInvalidAddItemsFirstArgumentError(); 790 | if (!isDefined(position) || position > this.length - 1) { 791 | for (const item of items) { 792 | this.push(item); 793 | } 794 | } else if (position == 0 || position < 0) { 795 | for (let i = items.length - 1; i > -1; i--) { 796 | this.unshift(items[i]); 797 | } 798 | } else { 799 | for (let i = items.length - 1; i > -1; i--) { 800 | this.splice(position, 0, items[i]); 801 | } 802 | } 803 | } 804 | 805 | const customProps = [{ name: "addItems", handler: addItemsHandler }]; 806 | 807 | for (const { name, handler } of customProps) 808 | defineProp(array, name, { value: handler }); 809 | } 810 | 811 | if (typeof each !== "number") proSetup(); 812 | 813 | function renderingSystem(__index__, perfOptimization) { 814 | const iterable = new Iterable(each); 815 | 816 | synchronizeRootChildrenLengthAndSourceLength(root, iterable); 817 | 818 | iterable.each((data, index, type) => { 819 | let newTemp, indexObj; 820 | 821 | if (type == "array") { 822 | if (isDefined(__index__)) { 823 | data = pro[__index__]; 824 | index = __index__; 825 | iterable.break = true; 826 | } 827 | 828 | const indexSymbol = Symbol.for("index"); 829 | const canOptimize = () => 830 | isTrue(optimize) && 831 | (isObj(data) || isArray(data) || isSet(data)) && 832 | !hasOwnProperty(data, indexSymbol); 833 | indexObj = { 834 | index: index, 835 | sourceLength: pro.length, 836 | }; 837 | 838 | if (canOptimize()) data[indexSymbol] = indexObj; 839 | else if ( 840 | (isObj(data) || isArray(data) || isSet(data)) && 841 | hasOwnProperty(data, indexSymbol) 842 | ) { 843 | const hasDifferentSourceLength = () => 844 | data[indexSymbol].sourceLength !== indexObj.sourceLength; 845 | if (hasDifferentSourceLength()) 846 | shareProps(data[indexSymbol], indexObj); 847 | } 848 | } 849 | 850 | if (firstRender || perfOptimization) { 851 | checkType( 852 | type !== "object" ? data : data[1] /*obj prop*/, 853 | renderingSystem, 854 | DO, 855 | isTrue(optimize) ? indexObj : null 856 | ); 857 | } 858 | 859 | if (perfOptimization) return; 860 | 861 | function checkIterationSourceType() { 862 | if (type === "array") { 863 | newTemp = DO.call(pro, data, index, pro); 864 | } else if (type === "object") { 865 | newTemp = DO.call(pro, data[0] /*prop*/, data[1] /*value*/, pro); 866 | } else if (type === "number") { 867 | newTemp = DO(data); 868 | } else { 869 | //The type is set. 870 | 871 | newTemp = DO.call(pro, data, pro); 872 | } 873 | } 874 | 875 | checkIterationSourceType(); 876 | 877 | // The function is returning the template. 878 | if (isValidTemplateReturn(newTemp)) { 879 | const currentEl = root.children[index]; 880 | 881 | if (!isAtag(currentEl)) { 882 | root.appendChild(toDOM(newTemp.element)); 883 | } else { 884 | if (!currentEl.template) { 885 | consW("Avoid manipulating what Inter manipulates."); 886 | 887 | /** 888 | * currentEl was not rendered by Inter, in 889 | * this case we must replace it with an element 890 | * rendered by Inter to avoid diffing problems. 891 | */ 892 | 893 | root.replaceChild(toDOM(newTemp.element), currentEl); 894 | } else { 895 | runDiff(newTemp.element, currentEl.template, currentEl); 896 | } 897 | } 898 | } else runInvalidTemplateReturnError(); 899 | }); 900 | } 901 | 902 | renderingSystem(); 903 | 904 | firstRender = false; 905 | 906 | return pro; 907 | } 908 | 909 | function runDiff(newTemp, oldTemp, oldRoot) { 910 | const diff = { 911 | children: true, 912 | continue: true, 913 | }; 914 | 915 | runContainerDiffing(newTemp, oldTemp, diff); 916 | 917 | if (diff.children && newTemp.children && newTemp.children.length > 0) { 918 | runChildrenDiffing(newTemp.children, oldTemp.children, oldRoot, diff); 919 | } 920 | } 921 | 922 | function isOneAnArrayAndOtherNot(first, second) { 923 | return ( 924 | (isArray(first) && !isArray(second)) || (!isArray(first) && isArray(second)) 925 | ); 926 | } 927 | 928 | function AreBothArray(first, second) { 929 | return isArray(first) && isArray(second); 930 | } 931 | 932 | function getValue(text) { 933 | if (typeof text === "function") text = text(); 934 | return text; 935 | } 936 | 937 | function runNestedListDiffing(reactor, target, newChildren, oldChildren) { 938 | if (reactor.mutationInfo == void 0) return; 939 | const { 940 | mutationInfo: { method, start, deleteCount, itemsLength }, 941 | } = reactor; 942 | 943 | function addByPush() { 944 | let i = itemsLength; 945 | 946 | for (; i > 0; i--) { 947 | const child = newChildren[newChildren.length - i]; 948 | 949 | target.appendChild(toDOM(child, true, child.index)); 950 | oldChildren.push(child); 951 | } 952 | } 953 | 954 | function AddByUnShiftOrSplice(mutationMethod) { 955 | function insertBehind(start, itemsLength) { 956 | for (let i = itemsLength - 1; i > -1; i--) { 957 | const child = target.children[start]; 958 | const virtualChild = newChildren[i]; 959 | const newChild = toDOM(virtualChild, true, virtualChild.index); 960 | 961 | if (child) target.insertBefore(newChild, child); 962 | else target.appendChild(newChild); 963 | 964 | addedtems.unshift(virtualChild); 965 | } 966 | } 967 | 968 | const addedtems = new Array(); 969 | 970 | if (mutationMethod == "splice" && deleteCount == 0 && itemsLength > 0) { 971 | insertBehind(start, itemsLength); 972 | oldChildren.splice(start, deleteCount, ...addedtems); 973 | } else if (mutationMethod == "splice" && deleteCount > 0) { 974 | for (let i = 0; i < deleteCount; i++) { 975 | const child = target.children[start]; 976 | 977 | if (child) target.removeChild(child); 978 | } 979 | 980 | insertBehind(start, itemsLength); 981 | 982 | oldChildren.splice(start, deleteCount, addedtems); 983 | } else if (mutationMethod == "unshift") { 984 | insertBehind(0, itemsLength); 985 | 986 | oldChildren.unshift(...addedtems); 987 | } 988 | } 989 | 990 | function deleteBySplice() { 991 | let i = start; 992 | for (; newChildren.length < target.children.length; i++) { 993 | const elToRemove = target.children[start]; 994 | if (elToRemove) target.removeChild(elToRemove); 995 | } 996 | 997 | oldChildren.splice(start, deleteCount); 998 | } 999 | 1000 | const lastNodeElement = target.children[target.children.length - 1]; 1001 | const firstNodeElement = target.children[0]; 1002 | if (method == "pop" && lastNodeElement) { 1003 | target.removeChild(lastNodeElement); 1004 | oldChildren.pop(); 1005 | } else if (method == "shift" && firstNodeElement) { 1006 | target.removeChild(firstNodeElement); 1007 | oldChildren.shift(); 1008 | } else if (method == "push") addByPush(); 1009 | else if (method == "unshift") AddByUnShiftOrSplice(method); 1010 | else if (method == "splice") { 1011 | if ( 1012 | typeof start == "number" && 1013 | typeof deleteCount == "number" && 1014 | itemsLength == 0 1015 | ) 1016 | deleteBySplice(); 1017 | else if (itemsLength > 0) AddByUnShiftOrSplice(method); 1018 | else if (deleteCount == void 0) { 1019 | const data = { 1020 | source: { 1021 | values: newChildren, 1022 | }, 1023 | }; 1024 | 1025 | synchronizeRootChildrenLengthAndSourceLength(target, data); 1026 | } 1027 | } 1028 | } 1029 | 1030 | function runContainerDiffing(newContainer, oldContainer, diff) { 1031 | const { 1032 | attrs: newAttrs = {}, 1033 | events: newEvents = {}, 1034 | styles: newStyles = {}, 1035 | children: newChildren, 1036 | } = newContainer; 1037 | 1038 | const { 1039 | attrs: oldAttrs = {}, 1040 | events: oldEvents = {}, 1041 | styles: oldStyles = {}, 1042 | children: oldChildren, 1043 | target, 1044 | } = oldContainer; 1045 | 1046 | let reactor; 1047 | 1048 | if (isArray(newChildren)) reactor = newChildren.reactor; 1049 | 1050 | if (reactor != void 0) 1051 | runNestedListDiffing(reactor, target, newChildren, oldChildren); 1052 | 1053 | const rootEL = target.parentNode; 1054 | const newText = getValue(newContainer.text); 1055 | const oldText = getValue(oldContainer.text); 1056 | const newTag = getValue(newContainer.tag); 1057 | const oldTag = getValue(oldContainer.tag); 1058 | 1059 | if (newTag !== oldTag) { 1060 | const newElement = toDOM(newContainer); 1061 | 1062 | rootEL.replaceChild(newElement, target); 1063 | 1064 | diff.children = false; 1065 | 1066 | shareProps(oldContainer, newContainer); 1067 | oldContainer.target = newElement; 1068 | } else if (isOneAnArrayAndOtherNot(newChildren, oldChildren)) { 1069 | const newElement = toDOM(newContainer); 1070 | 1071 | rootEL.replaceChild(newElement, target); 1072 | 1073 | diff.children = false; 1074 | shareProps(oldContainer, newContainer); 1075 | oldContainer.target = newElement; 1076 | } else if ( 1077 | AreBothArray(newChildren, oldChildren) && 1078 | newChildren.length !== oldChildren.length 1079 | ) { 1080 | const newElement = toDOM(newContainer); 1081 | 1082 | rootEL.replaceChild(newElement, target); 1083 | 1084 | diff.children = false; 1085 | shareProps(oldContainer, newContainer); 1086 | oldContainer.target = newElement; 1087 | } else if (!isDefined(newChildren) && !isDefined(oldChildren)) { 1088 | if (newText !== oldText) { 1089 | target.textContent = newText; 1090 | 1091 | shareProps(oldContainer, newContainer); 1092 | } 1093 | } 1094 | 1095 | runAttributeDiffing(target, oldAttrs, newAttrs); 1096 | runEventDiffing(target, oldEvents, newEvents); 1097 | runStyleDiffing(target, oldStyles, newStyles); 1098 | } 1099 | 1100 | function shareProps(target, source) { 1101 | Object.assign(target, source); 1102 | } 1103 | 1104 | function getGreater(firstArray, secondArray) { 1105 | return firstArray.length > secondArray.length ? firstArray : secondArray; 1106 | } 1107 | 1108 | function runAttributeDiffing(target, oldAttributes, newAttributes) { 1109 | function removeAttr(attr) { 1110 | if (target.hasAttribute(attr)) { 1111 | target.removeAttribute(attr); 1112 | } else if (specialAttrs.has(attr)) { 1113 | if (attr === "checked") target.checked = false; 1114 | else target[attr] = ""; 1115 | } 1116 | } 1117 | 1118 | const oldAttrsArray = Object.keys(oldAttributes), 1119 | newAttrsArray = Object.keys(newAttributes), 1120 | greater = getGreater(oldAttrsArray, newAttrsArray), 1121 | specialAttrs = new Set(["value", "currentTime", "checked"]); 1122 | 1123 | for (let i = 0; greater.length > i; i++) { 1124 | const oldAttrName = oldAttrsArray[i], 1125 | newAttrName = newAttrsArray[i], 1126 | oldAttrValue = getValue(oldAttributes[oldAttrName]), 1127 | newAttrValue = getValue(newAttributes[newAttrName]); 1128 | 1129 | if (!(oldAttrName in newAttributes)) removeAttr(oldAttrName); 1130 | else if (!isDefined(newAttrValue) || isFalse(newAttrValue)) 1131 | removeAttr(newAttrName); 1132 | else if (isDefined(newAttrValue) && !isFalse(newAttrValue)) { 1133 | if ( 1134 | (newAttrName.startsWith("on") && validDomEvent(newAttrName)) || 1135 | newAttrName == "style" 1136 | ) 1137 | runIllegalAttrsPropWarning(newAttrName); 1138 | else if (newAttrName !== oldAttrName || newAttrValue !== oldAttrValue) { 1139 | if (specialAttrs.has(newAttrName)) target[newAttrName] = newAttrValue; 1140 | else target.setAttribute(newAttrName, newAttrValue); 1141 | } 1142 | } 1143 | 1144 | oldAttributes[oldAttrName] = newAttrValue; 1145 | } 1146 | } 1147 | 1148 | function runStyleDiffing(target, oldStyles, newStyles) { 1149 | const oldStylesArray = Object.keys(oldStyles), 1150 | newStylesArray = Object.keys(newStyles), 1151 | greater = getGreater(oldStylesArray, newStylesArray); 1152 | 1153 | for (let i = 0; greater.length > i; i++) { 1154 | const oldStyleName = oldStylesArray[i], 1155 | newStyleName = newStylesArray[i], 1156 | oldStyleValue = getValue(oldStyles[oldStyleName]), 1157 | newStyleValue = getValue(newStyles[newStyleName]); 1158 | 1159 | if (!(oldStyleName in newStyles) || !isDefined(newStyleValue)) { 1160 | const styleValue = target.style[oldStyleName]; 1161 | const styleAttr = target.getAttribute("style"); 1162 | if (isDefined(styleValue) && styleValue.trim().length !== 0) { 1163 | target.style[oldStyleName] = null; 1164 | } 1165 | 1166 | if (styleAttr && styleAttr.trim().length == 0) 1167 | target.removeAttribute("style"); 1168 | } else if (isDefined(newStyleValue)) { 1169 | if (newStyleValue !== oldStyleValue) { 1170 | if (validStyleName(newStyleName)) { 1171 | target.style[newStyleName] = newStyleValue; 1172 | 1173 | if (!target.style[newStyleName]) 1174 | runInvalidStyleValue(newStyleName, newStyleValue); 1175 | } else runInvalidStyleWarning(newStyleName); 1176 | } 1177 | } 1178 | 1179 | oldStyles[oldStyleName] = newStyleValue; 1180 | } 1181 | } 1182 | 1183 | function runEventDiffing(target, oldEvents, newEvents) { 1184 | const oldEventsArray = Object.keys(oldEvents), 1185 | newEventsArray = Object.keys(newEvents), 1186 | greater = getGreater(oldEventsArray, newEventsArray); 1187 | 1188 | for (let i = 0; greater.length > i; i++) { 1189 | const oldEventName = oldEventsArray[i], 1190 | newEventName = newEventsArray[i]; 1191 | 1192 | if (!(oldEventName in newEvents) || !isDefined(newEvents[oldEventName])) 1193 | target[oldEventName] = void 0; 1194 | if (!isCallable(newEvents[newEventName]) && validDomEvent(newEventName)) { 1195 | target[oldEventName] = void 0; 1196 | 1197 | runInvalidEventHandlerWarning(newEventName); 1198 | 1199 | continue; 1200 | } 1201 | 1202 | if (isDefined(newEvents[newEventName])) { 1203 | if (validDomEvent(newEventName)) { 1204 | target[newEventName] = newEvents[newEventName]; 1205 | } else runInvalidEventWarning(newEventName); 1206 | } 1207 | } 1208 | } 1209 | 1210 | function insertBefore(root, index, virtualElement) { 1211 | for (let i = 0; i < root.children.length; i++) { 1212 | const realElement = root.children[i]; 1213 | if (realElement.index > index) { 1214 | root.insertBefore(virtualElement, realElement); 1215 | break; 1216 | } 1217 | } 1218 | } 1219 | 1220 | function runChildrenDiffing(__new, __old, realParent) { 1221 | const newContainer = Array.from(__new), 1222 | oldContainer = Array.from(__old); 1223 | 1224 | for (let i = 0; i < newContainer.length; i++) { 1225 | const newChild = newContainer[i], 1226 | oldChild = oldContainer[i]; 1227 | let hasChildren = false; 1228 | 1229 | const { 1230 | children: newChildren = [], 1231 | events: newEvents = {}, 1232 | attrs: newAttrs = {}, 1233 | styles: newStyles = {}, 1234 | renderIf: newRenderIf, 1235 | } = newChild; 1236 | 1237 | const { 1238 | children: oldChildren = [], 1239 | events: oldEvents = {}, 1240 | attrs: oldAttrs = {}, 1241 | styles: oldStyles = {}, 1242 | target, 1243 | index, 1244 | } = oldChild; 1245 | 1246 | let theLastElement; 1247 | const newText = getValue(newChild.text); 1248 | const oldText = getValue(oldChild.text); 1249 | const newTag = getValue(newChild.tag); 1250 | const oldTag = getValue(oldChild.tag); 1251 | function insertConditionally() { 1252 | const newELement = toDOM(newChild, true, index); 1253 | 1254 | Object.assign(oldChild, newChild); 1255 | 1256 | oldChild.target = newELement; 1257 | 1258 | if (theLastElement && theLastElement.index > index) { 1259 | insertBefore(realParent, index, newELement); 1260 | } else { 1261 | realParent.appendChild(newELement); 1262 | } 1263 | } 1264 | 1265 | if (realParent) { 1266 | theLastElement = realParent.children[realParent.children.length - 1]; 1267 | } 1268 | if (newChildren.length !== oldChildren.length) { 1269 | const { reactor } = newChildren; 1270 | 1271 | if (reactor != void 0) { 1272 | runNestedListDiffing(reactor, target, newChildren, oldChildren); 1273 | } else if (target && target.parentNode != null) { 1274 | const newElement = toDOM(newChild, true, index); 1275 | 1276 | realParent.replaceChild(newElement, target); 1277 | 1278 | Object.assign(oldChild, newChild); 1279 | oldChild.target = newElement; 1280 | 1281 | continue; 1282 | } 1283 | } 1284 | 1285 | if (newTag !== oldTag) { 1286 | const newELement = toDOM(newChild, true, index); 1287 | 1288 | Object.assign(oldChild, newChild); 1289 | 1290 | if (target && target.parentNode != null) { 1291 | realParent.replaceChild(newELement, target); 1292 | oldChild.target = newELement; 1293 | } 1294 | continue; 1295 | } else if ( 1296 | isNegativeValue(newRenderIf) && 1297 | hasOwnProperty(newChild, "renderIf") 1298 | ) { 1299 | if (target && target.parentNode != null) { 1300 | realParent.removeChild(target); 1301 | } 1302 | } else if (isPositiveValue(newRenderIf)) { 1303 | if (target && target.parentNode == null) insertConditionally(); 1304 | else if (!target) insertConditionally(); 1305 | } 1306 | 1307 | if (newChildren.length == oldChildren.length && newChildren.length !== 0) { 1308 | hasChildren = true; 1309 | 1310 | runChildrenDiffing(newChildren, oldChildren, target); 1311 | } 1312 | 1313 | if (oldText !== newText && target && !hasChildren) { 1314 | target.textContent = newText; 1315 | oldChild.text = newText; 1316 | } 1317 | 1318 | oldChild.tag = newTag; 1319 | 1320 | if (target) { 1321 | runAttributeDiffing(target, oldAttrs, newAttrs); 1322 | runStyleDiffing(target, oldStyles, newStyles); 1323 | runEventDiffing(target, oldEvents, newEvents); 1324 | } 1325 | } 1326 | } 1327 | 1328 | function synchronizeRootChildrenLengthAndSourceLength(root, iterable) { 1329 | if (root.children.length > iterable.source.values.length) { 1330 | let length = root.children.length - iterable.source.values.length; 1331 | 1332 | while (length--) { 1333 | const lastElementIndex = root.children.length - 1; 1334 | const lastElement = root.children[lastElementIndex]; 1335 | root.removeChild(lastElement); 1336 | } 1337 | } 1338 | } 1339 | 1340 | /** 1341 | *
1342 | *

Olá

1343 | *

Olá

1344 | *

Olá

1345 | * 1346 | *

Olá

1347 | *
1348 | * 1349 | *
1350 | *

Olá

1351 | *

Olá

1352 | *

Olá

1353 | * 1354 | *
1355 | * 1356 | */ 1357 | -------------------------------------------------------------------------------- /core/template/errors.js: -------------------------------------------------------------------------------- 1 | import { syErr, ParserWarning, valueType, consW } from "../helpers.js"; 2 | 3 | export function runInvalidTemplateArgumentError(arg) { 4 | syErr(`The argument of the template function must be a plain Javascript object, 5 | but you defined "${valueType(arg)}" as its argument. 6 | 7 | `); 8 | } 9 | 10 | export function runInvalidEventHandlerWarning(eventName) { 11 | ParserWarning(`The "${eventName}" event was not created because 12 | its handler is not a function, in the tempate function.`); 13 | } 14 | 15 | export function runIllegalTextWarning() { 16 | ParserWarning(`The template parser found an element 17 | with both the text property and the children property, 18 | and in this case Inter ignores the text property.`); 19 | } 20 | 21 | export function runInvalidEventWarning(eventName) { 22 | ParserWarning(`"${eventName}" doesn't seem to be a valid dom event.`); 23 | } 24 | 25 | export function runInvalidStyleWarning(styleName) { 26 | ParserWarning(`"${styleName}" doesn't seem to be a valid style name.`); 27 | } 28 | 29 | export function runCanNotRenderConditionallyWarning() { 30 | ParserWarning(`You can not conditionally render the main 31 | container in the template function.`); 32 | } 33 | 34 | export function runInvalidTagOptionError(tag) { 35 | syErr(`"${valueType(tag)}" is an invalid tag name, 36 | in the template function.`); 37 | } 38 | 39 | export function runInvalidObjectOptionsError() { 40 | syErr(`The "events", "attrs" and "styles" options in the template function 41 | must be plain Javascript objects, and you didn't define 42 | one or more of those options as plain Javascript object.`); 43 | } 44 | 45 | export function runIllegalAttrsPropWarning(prop) { 46 | const styleProp = `You should not use the style attribute(in attrs object) to create styles for the element, 47 | use the "styles" object instead, like: 48 | 49 | { 50 | tag: "p", text: "Some text", styles: { color: "green" } 51 | } 52 | `; 53 | 54 | const event = `You shoud not use "${prop}" as an attribute name, it seems to be a dom event, 55 | use it as property of the "events" object, like: 56 | 57 | { 58 | tag: "button", text: "Some text", events: { ${prop}: () => { //Some code here } } 59 | } 60 | `; 61 | 62 | consW(prop.startsWith("on") ? event : styleProp); 63 | } 64 | 65 | export function runInvalidStyleValue(name, value) { 66 | ParserWarning(`"${value}" is an invalid value for the "${name}" style.`); 67 | } 68 | -------------------------------------------------------------------------------- /core/template/index.js: -------------------------------------------------------------------------------- 1 | import { 2 | createText, 3 | validTagOption, 4 | validObjectOptions, 5 | isCallable, 6 | isDefined, 7 | isObj, 8 | validDomEvent, 9 | validStyleName, 10 | isFalse, 11 | isNegativeValue, 12 | hasOwnProperty, 13 | } from "../helpers.js"; 14 | 15 | import { 16 | runCanNotRenderConditionallyWarning, 17 | runIllegalAttrsPropWarning, 18 | runIllegalTextWarning, 19 | runInvalidEventHandlerWarning, 20 | runInvalidEventWarning, 21 | runInvalidObjectOptionsError, 22 | runInvalidStyleWarning, 23 | runInvalidTagOptionError, 24 | runInvalidTemplateArgumentError, 25 | runInvalidStyleValue, 26 | } from "./errors.js"; 27 | 28 | function createEvents(events, container) { 29 | Object.entries(events).forEach((event) => { 30 | const [name, handler] = event; 31 | 32 | if (validDomEvent(name)) { 33 | if (isCallable(handler)) { 34 | container[name] = handler; 35 | } else runInvalidEventHandlerWarning(name); 36 | } else runInvalidEventWarning(name); 37 | }); 38 | } 39 | 40 | function createAttrs(attrs, container) { 41 | Object.entries(attrs).forEach((attr) => { 42 | // eslint-disable-next-line prefer-const 43 | let [name, value] = attr; 44 | let hasWarning = false; 45 | const specialAttrs = new Set(["value", "currentTime", "checked"]); 46 | 47 | if ((name.startsWith("on") && validDomEvent(name)) || name == "style") { 48 | runIllegalAttrsPropWarning(name); 49 | hasWarning = true; 50 | } 51 | 52 | const setAttr = (attrValue) => { 53 | if (isDefined(attrValue) && !isFalse(attrValue)) { 54 | if (!specialAttrs.has(name)) container.setAttribute(name, attrValue); 55 | else container[name] = attrValue; 56 | } 57 | container.template.attrs[name] = attrValue; 58 | }; 59 | 60 | if (!hasWarning) { 61 | if (isCallable(value)) { 62 | value = value(); 63 | 64 | setAttr(value); 65 | } else { 66 | setAttr(value); 67 | } 68 | } 69 | }); 70 | } 71 | 72 | function createStyles(styles, container) { 73 | Object.entries(styles).forEach((style) => { 74 | const [name, value] = style; 75 | 76 | if (validStyleName(name)) { 77 | const styleValue = isCallable(value) ? value() : value; 78 | 79 | if (isDefined(styleValue)) { 80 | container.style[name] = styleValue; 81 | container.template.styles[name] = styleValue; 82 | if (!container.style[name]) runInvalidStyleValue(name, styleValue); 83 | } 84 | } else runInvalidStyleWarning(name); 85 | }); 86 | } 87 | 88 | function createTextOrChildren(text, children, container) { 89 | if (isDefined(text) && children.length == 0) { 90 | const textContent = isCallable(text) 91 | ? createText(text()) 92 | : createText(text); 93 | 94 | if (isDefined(textContent)) container.appendChild(textContent); 95 | } else if (isDefined(text) && children.length > 0) { 96 | runIllegalTextWarning(); 97 | createChildren(container, children); 98 | } else { 99 | if (children.length > 0) { 100 | createChildren(container, children); 101 | } 102 | } 103 | } 104 | 105 | export function template(obj) { 106 | if (isObj(obj)) { 107 | const temp = Symbol.for("template"); 108 | 109 | return { 110 | [temp]: !0, 111 | element: obj, 112 | }; 113 | } else runInvalidTemplateArgumentError(obj); 114 | } 115 | 116 | export function toDOM(obj, isChild, index) { 117 | /* eslint-disable prefer-const */ 118 | let { tag, text, attrs = {}, events = {}, styles = {}, children = [] } = obj; 119 | 120 | /*eslint-enable prefer-const*/ 121 | 122 | tag = isCallable(tag) ? tag() : tag; 123 | text = isCallable(text) ? text() : text; 124 | const hasRenderIfProp = hasOwnProperty(obj, "renderIf"); 125 | 126 | if (hasRenderIfProp && !isChild) { 127 | runCanNotRenderConditionallyWarning(); 128 | } 129 | 130 | if (!validTagOption(tag)) runInvalidTagOptionError(tag); 131 | if (!validObjectOptions(attrs, styles, events)) 132 | runInvalidObjectOptionsError(); 133 | 134 | const container = document.createElement(tag); 135 | container.template = Object.assign(obj, { 136 | target: container, 137 | tag: tag, 138 | text: text, 139 | }); // For diffing task. 140 | 141 | if (isChild) { 142 | container.index = index; 143 | } 144 | 145 | createAttrs(attrs, container); 146 | createEvents(events, container); 147 | createStyles(styles, container); 148 | createTextOrChildren(text, children, container); 149 | 150 | return container; 151 | } 152 | 153 | function createChildren(root, children) { 154 | let index = -1; 155 | 156 | for (const child of children) { 157 | /* eslint-disable prefer-const */ 158 | let { 159 | tag, 160 | text, 161 | attrs = {}, 162 | events = {}, 163 | styles = {}, 164 | children = [], 165 | renderIf, 166 | } = child; 167 | 168 | /* eslint-enable prefer-const */ 169 | 170 | index++; 171 | child.index = index; 172 | 173 | tag = isCallable(tag) ? tag() : tag; 174 | text = isCallable(text) ? text() : text; 175 | 176 | if (isNegativeValue(renderIf) && hasOwnProperty(child, "renderIf")) 177 | continue; 178 | 179 | if (!validTagOption(tag)) runInvalidTagOptionError(tag); 180 | 181 | if (!validObjectOptions(attrs, styles, events)) 182 | runInvalidObjectOptionsError(); 183 | 184 | const container = document.createElement(tag); 185 | container.index = index; 186 | container.template = Object.assign(child, { 187 | target: container, 188 | tag: tag, 189 | text: text, 190 | }); //For diffing task. 191 | 192 | createAttrs(attrs, container); 193 | createEvents(events, container); 194 | createStyles(styles, container); 195 | createTextOrChildren(text, children, container); 196 | root.appendChild(container); 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /core/toattrs/errors.js: -------------------------------------------------------------------------------- 1 | import { ParserWarning, syErr, consW, valueType } from "../helpers.js"; 2 | 3 | export function runNotDefinedManagerError(name) { 4 | ParserWarning(` 5 | The attribute manager parser found an attribute manager 6 | named "${name}", but you did not define it in the "data" object. 7 | `); 8 | } 9 | 10 | export function runInvalidEventHandlerError(name, handler) { 11 | syErr(` 12 | "${valueType(handler)}" is an invalid 13 | handler for the "${name}" event, you must 14 | define only a function as the handler of a dom event. 15 | `); 16 | } 17 | 18 | export function runCanNotGetTheValueOfAnEventWarning(name) { 19 | consW(` 20 | you are trying to get the value of "${name}", 21 | it's an event, and you can not get the value of an event. 22 | `); 23 | } 24 | 25 | export function runInvalidSetAttrsValueError(props) { 26 | syErr(` 27 | "${valueType(props)}" is an invalid value for the "setAttrs" property. 28 | The "setAttrs" property only accepts a plain Javascript object as its 29 | value. 30 | `); 31 | } 32 | 33 | export function runUnexpectedPropWarning(prop) { 34 | consW(` 35 | The "${prop}" property was not defined in the manager object. 36 | `); 37 | } 38 | 39 | export function runNotCallebleError(arg) { 40 | syErr(`The argument of the observe method must be a function, 41 | and you defined ${valueType(arg)} as its argument.`); 42 | } 43 | -------------------------------------------------------------------------------- /core/toattrs/index.js: -------------------------------------------------------------------------------- 1 | import { 2 | getId, 3 | hasOwnProperty, 4 | isCallable, 5 | isDefined, 6 | isObj, 7 | syErr, 8 | validDomEvent, 9 | valueType, 10 | } from "../helpers.js"; 11 | 12 | import { 13 | runCanNotGetTheValueOfAnEventWarning, 14 | runInvalidEventHandlerError, 15 | runInvalidSetAttrsValueError, 16 | runNotCallebleError, 17 | runNotDefinedManagerError, 18 | runUnexpectedPropWarning, 19 | } from "./errors.js"; 20 | 21 | function isNull(value) { 22 | return value == null; 23 | } 24 | 25 | function getManagerName(attr) { 26 | const name = attr.replace("{...", "").replace("}", ""); 27 | 28 | return name; 29 | } 30 | 31 | function isADefinedManager(dataObject, manager) { 32 | return hasOwnProperty(dataObject, manager); 33 | } 34 | 35 | function isAValidAttrManagerSyntax(attr) { 36 | const pattern = /{(:?\.){3}(:?\S+)}/; 37 | 38 | return pattern.test(attr); 39 | } 40 | 41 | function mayBeAnAttrManager(attr) { 42 | const pattern = /{(:?[\s\S]+)}/; 43 | 44 | return pattern.test(attr); 45 | } 46 | 47 | function parse(rootElement, dataObject) { 48 | const children = rootElement.getElementsByTagName("*"); 49 | 50 | for (const child of children) { 51 | if (child.attributes.length == 1) { 52 | const { name: attr } = child.attributes[0]; 53 | if (mayBeAnAttrManager(attr) && isAValidAttrManagerSyntax(attr)) { 54 | const managerName = getManagerName(attr); 55 | 56 | child.removeAttribute(attr); 57 | 58 | if (isADefinedManager(dataObject, managerName)) 59 | spreadAttrs(child, dataObject[managerName]); 60 | else runNotDefinedManagerError(managerName); 61 | } 62 | } 63 | } 64 | } 65 | 66 | function spreadAttrs(Element, managerObject) { 67 | const special = new Set(["value", "currentTime"]); 68 | const isNotSpecial = (name) => !special.has(name); 69 | const isAnEvent = (name) => name.startsWith("on") && validDomEvent(name); 70 | const isSpecial = (name) => !isNotSpecial(name); 71 | const observerCache = new Map(); 72 | 73 | for (const [attrName, attrValue] of Object.entries(managerObject)) { 74 | if (isNotSpecial(attrName) && !isAnEvent(attrName) && !isNull(attrValue)) 75 | setAttr(Element, attrName, attrValue); 76 | else if (isSpecial(attrName) && !isNull(attrValue)) 77 | setSpecialAttr(Element, attrName, attrValue); 78 | else if (isAnEvent(attrName) && !isNull(attrValue)) 79 | defineEvent(Element, attrName, attrValue, managerObject); 80 | 81 | defineReactiveProp( 82 | managerObject, 83 | attrName, 84 | attrValue, 85 | Element, 86 | observerCache 87 | ); 88 | } 89 | 90 | definesetAttrsProp(managerObject); 91 | defineObserveProp(managerObject, observerCache); 92 | } 93 | 94 | function setAttr(Element, name, value) { 95 | const hasTheAttr = () => Element.hasAttribute(name); 96 | const attrValue = () => Element.getAttribute(name); 97 | 98 | if (!isNull(value) && value !== attrValue) Element.setAttribute(name, value); 99 | else if (isNull(value) && hasTheAttr()) Element.removeAttribute(name); 100 | } 101 | 102 | function setSpecialAttr(Element, name, value) { 103 | if (isDefined(value)) Element[name] = value; 104 | else if (isNull(value)) Element[name] = ""; 105 | } 106 | 107 | function defineEvent(Element, eventName, handler, managerObject) { 108 | if (isDefined(handler) && !isCallable(handler)) 109 | runInvalidEventHandlerError(eventName, handler); 110 | else if (isNull(handler)) Element[eventName] = void 0; 111 | else Element[eventName] = (event) => handler.call(managerObject, event); 112 | } 113 | 114 | function defineReactiveProp(object, name, value, Element, observerCache) { 115 | const special = new Set(["value", "currentTime", "checked"]); 116 | const isNotSpecial = () => !special.has(name); 117 | const isAnEvent = () => name.startsWith("on") && validDomEvent(name); 118 | const isSpecial = () => !isNotSpecial(name); 119 | let propValue = value; 120 | 121 | Object.defineProperty(object, name, { 122 | set(newValue) { 123 | if (isAnEvent()) defineEvent(Element, name, newValue, this); 124 | else if (isNotSpecial()) setAttr(Element, name, newValue); 125 | else if (isSpecial()) setSpecialAttr(Element, name, newValue); 126 | propValue = newValue; 127 | const callBack = observerCache.get("observeCallBack"); 128 | 129 | if (observerCache.has("observeCallBack")) callBack(name, newValue); 130 | }, 131 | 132 | get() { 133 | if (isSpecial()) return Element[name]; 134 | if (!isAnEvent()) return propValue; 135 | else runCanNotGetTheValueOfAnEventWarning(name); 136 | return false; 137 | }, 138 | }); 139 | } 140 | 141 | function definesetAttrsProp(object) { 142 | Object.defineProperty(object, "setAttrs", { 143 | set(props) { 144 | if (!isObj(props)) runInvalidSetAttrsValueError(props); 145 | 146 | for (const [prop, value] of Object.entries(props)) { 147 | if (!hasOwnProperty(this, prop)) { 148 | runUnexpectedPropWarning(prop); 149 | continue; 150 | } 151 | 152 | this[prop] = value; 153 | } 154 | }, 155 | }); 156 | } 157 | 158 | function defineObserveProp(object, map) { 159 | Object.defineProperty(object, "observe", { 160 | value(callBack) { 161 | if (map.size !== 0) return false; 162 | if (!isCallable(callBack)) runNotCallebleError(callBack); 163 | 164 | map.set("observeCallBack", callBack); 165 | 166 | return true; 167 | }, 168 | }); 169 | } 170 | 171 | export function toAttrs(options) { 172 | if (new.target !== void 0) { 173 | syErr(`the "toAttrs" function is not a constructor, do not call it with the 174 | new keyword.`); 175 | } else if (!isObj(options)) { 176 | syErr(`"${valueType(options)}" is an invalid argument for 177 | "toAttrs" function, the argument must be a plain Javascript object.`); 178 | } else { 179 | const { in: IN, data } = options; 180 | 181 | const rootElement = getId(IN); 182 | 183 | parse(rootElement, data); 184 | 185 | return data; 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /inter.m.d.ts: -------------------------------------------------------------------------------- 1 | /*** 2 | * MIT LICENSED BY - Denis Power(Inter creator) 3 | * Typescript declaration file for Inter version 2.2.4 4 | * Version - 1.0.0 5 | * Repo - https://github.com/interjs/inter/types 6 | * GENERATED BY INTER BUILDER 7 | */ 8 | 9 | interface backendInterface { 10 | new (): backendInstance; 11 | } 12 | 13 | interface backendInstance { 14 | request(options: ajaxOptions): ajaxReactorInterface; 15 | } 16 | 17 | /*** 18 | * These are the most commonly used HTTP request methods, the others 19 | * ones are not supported in Ajax request. 20 | * 21 | */ 22 | 23 | type httpRequestMethods = 24 | | "GET" 25 | | "POST" 26 | | "PUT" 27 | | "HEAD" 28 | | "DELETE" 29 | | "OPTIONS" 30 | | "PATCH"; 31 | 32 | interface ajaxOptions { 33 | type: httpRequestMethods; 34 | path: string; 35 | headers?: object; 36 | timeout?: number; 37 | events?: { 38 | onprogress?(args: { readonly progress: number; abort(): void }): void; 39 | onabort?(): void; 40 | ontimeout?(): void; 41 | }; 42 | security?: { 43 | username: string; 44 | password: string; 45 | }; 46 | body?: any; 47 | } 48 | 49 | type ajaxResponseCallBack = (response: ajaxResponse) => void; 50 | interface ajaxReactorInterface { 51 | okay(callBack: ajaxResponseCallBack): void; 52 | error(callBack: ajaxResponseCallBack): void; 53 | response( 54 | okayCallBack: ajaxResponseCallBack, 55 | errorCallBack: ajaxResponseCallBack 56 | ): void; 57 | } 58 | 59 | interface ajaxResponse { 60 | readonly data: any; 61 | readonly status: number; 62 | readonly statusText: string; 63 | readonly headers: object; 64 | isObj(): boolean; 65 | } 66 | 67 | export declare var Backend: backendInterface; 68 | type refValueType = string | number | null | void; 69 | type refMethods = { 70 | setRefs?: { 71 | [ref in keyof T]?: refValueType; 72 | }; 73 | observe( 74 | ref: string, 75 | value: refValueType, 76 | previousValue: refValueType 77 | ): boolean; 78 | }; 79 | 80 | interface refOptionsInterface { 81 | in: string; 82 | data: T; 83 | } 84 | 85 | export declare function Ref( 86 | options: refOptionsInterface 87 | ): refMethods & T; 88 | type refValueType = boolean; 89 | type renderIfMethods = { 90 | setConds: { 91 | [prop in keyof T]?: refValueType; 92 | }; 93 | observe(ref: keyof T, value: refValueType): boolean; 94 | }; 95 | 96 | interface renderIfOptionsInterface { 97 | in: string; 98 | data: { 99 | [prop: string]: boolean; 100 | } & T; 101 | } 102 | 103 | export declare function renderIf( 104 | options: renderIfOptionsInterface 105 | ): renderIfMethods & T; 106 | import { templateReturn } from "./template"; 107 | 108 | interface renderListOptionsInterface { 109 | in: string; 110 | each: T; 111 | optimize?: boolean; 112 | do: doOptionsType; 113 | } 114 | 115 | type universalReactorPropsType = { 116 | obserseve(callBack: (reactor: T) => void): boolean; 117 | setEach: eachTypes; 118 | }; 119 | 120 | interface ArrayReactor extends universalReactorPropsType { 121 | addItems(items: any[], index?: number): boolean; 122 | } 123 | 124 | interface ObjectReactor extends universalReactorPropsType { 125 | setProps?: T; 126 | } 127 | 128 | interface objectProps { 129 | setProps?: T; 130 | defineProps?: object; 131 | deleteProps?: Array; 132 | } 133 | 134 | type eachTypes = any[] | Object | Set | Map | number; 135 | type PropValueType = T[keyof T]; 136 | type doOptionsType = T extends any[] 137 | ? ( 138 | this: returnReactorType, 139 | item: Item, 140 | index: number, 141 | reactor: T 142 | ) => templateReturn 143 | : T extends object 144 | ? ( 145 | this: returnReactorType, 146 | prop: string, 147 | value: PropValueType, 148 | reactor: returnReactorType 149 | ) => templateReturn 150 | : templateReturn; 151 | type Item = T[any] extends object ? T[any] & objectProps : T[any]; 152 | type returnReactorType = T extends any[] 153 | ? Item[] & ArrayReactor 154 | : T extends object 155 | ? T & ObjectReactor 156 | : null; 157 | 158 | export declare function renderList( 159 | renderListOption: renderListOptionsInterface 160 | ): returnReactorType; 161 | type HTMLTags = keyof HTMLElementTagNameMap; 162 | type textTypes = string | number | null | void; 163 | interface templateOptionsInterface { 164 | tag: HTMLTags | ((this: void) => HTMLTags); 165 | text?: textTypes | ((this: void) => textTypes); 166 | renderIf?: boolean; 167 | events?: { 168 | [event in keyof GlobalEventHandlers]?: ( 169 | this: Document, 170 | event: Event 171 | ) => void; 172 | }; 173 | attrs?: object; 174 | styles?: { 175 | [style in keyof CSSStyleDeclaration]?: CSSStyleDeclaration[style]; 176 | }; 177 | children?: templateOptionsInterface[]; 178 | } 179 | 180 | export interface templateReturn { 181 | element: templateOptionsInterface; 182 | } 183 | 184 | export declare function template( 185 | options: templateOptionsInterface 186 | ): templateReturn; 187 | type attrType = string | number | null; 188 | type attrs = T[keyof T]; 189 | interface toAttrsMethods { 190 | setAttrs?: T[keyof T]; 191 | observe?(attr: string, value: attrType): boolean; 192 | } 193 | 194 | interface toAttrsOptionsInterface { 195 | in: string; 196 | data: T; 197 | } 198 | 199 | export declare function toAttrs( 200 | options: toAttrsOptionsInterface 201 | ): { 202 | [prop in keyof T]: toAttrsMethods & T[prop]; 203 | }; 204 | -------------------------------------------------------------------------------- /inter.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Interjs 3 | * Version - 2.2.4 4 | * MIT LICENSED BY - Denis Power 5 | * Repo - https://github.com/interjs/inter 6 | * 2021 - 2024 7 | * GENERATED BY INTER BUILDER 8 | * 9 | */ 10 | 11 | !function(){function e(e){q(`The "${e}" event was not created because\n its handler is not a function, in the tempate function.`)}function t(e){q(`"${e}" doesn't seem to be a valid dom event.`)}function n(e){q(`"${e}" doesn't seem to be a valid style name.`)}function o(e){B(`"${J(e)}" is an invalid tag name,\n in the template function.`)}function r(){B('The "events", "attrs" and "styles" options in the template function\n must be plain Javascript objects, and you didn\'t define\n one or more of those options as plain Javascript object.')}function i(e){const t=`You shoud not use "${e}" as an attribute name, it seems to be a dom event,\n use it as property of the "events" object, like:\n\n {\n tag: "button", text: "Some text", events: { ${e}: () => { //Some code here } }\n }\n `;H(e.startsWith("on")?t:'You should not use the style attribute(in attrs object) to create styles for the element,\n use the "styles" object instead, like:\n\n {\n tag: "p", text: "Some text", styles: { color: "green" }\n }\n')}function s(e,t){q(`"${t}" is an invalid value for the "${e}" style.`)}function a(e){B(`The value of "setProps" must be a plain Javascript object, and you\n defined "${J(e)}" as its value`)}function c(){M("Inter failed to define the reactivity,\n because the Array of the each option is not configurable.")}function l(e){B(`"${J(e)}" is not a valid value for the "each" option in renderList.\n The values that are accepted in "each" option, are:\n Array.\n Plain js object.\n Number.\n Map.\n Set.`)}function f(){B('The template function is not being returned inside the "do" method in\n renderList(reactive listing), just return the template function.')}function u(){B('The arguments of "okay", "error" and "response" methods must be\n functions.')}function d(e){H(`"${e}" is a reserved reference name, use other name.`)}function h(e){H(`"${e}" was not defined as a conditional property.`)}function p(e){M(`The value of a conditional property must be boolean(true/false),\n and the value of "${e}" property is not boolean.`)}function m(e,t,n){0!=t.trim().length?q(`\n \n The conditional rendering parser found\n an element with the "_ifNot" attribute and the value\n of this attribute is not a conditional property.\n \n {\n element: ${e.nodeName.toLowerCase()},\n _ifNot: ${t},\n data: { ${Object.keys(n)} }\n }\n \n `):b("_ifNot")}function b(e){q(`The conditional rendering parser found an ${e} attribute that does not\n have a value assigned to it. Assign a value to the ${e} attribute.\n `)}function g(e){q(`a/an "${O(e)}" element has the "_elseIf" attribute,\n but it does not come after an element with the "_if" or a valid "_elseIf" attribute.`)}function y(e,t,n){0!=e.trim().length?q(`\n The conditional rendering parser found\n an element which has the "_if" attribute and the value\n of this attribute is not a conditional property.\n \n {\n element: ${t.nodeName.toLowerCase()},\n _if: ${e},\n data: { ${Object.keys(n)} }\n }\n \n `):b("_if")}function v(e){return w(e)&&e.element&&e[Symbol.for("template")]}function j(e){return Object.isFrozen(e)||Object.isSealed(e)||!Object.isExtensible(e)}function w(e){return"[object Object]"==Object.prototype.toString.apply(e,void 0)}function O(e){return e.nodeName.toLowerCase()}function x(e){return e instanceof Set}function A(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function T(e){return e instanceof Map}function C(e){return void 0!=e}function S(e){return Object.is(e,!0)}function I(e){return Object.is(e,!1)}function $(e){return"function"==typeof e}function k(e){return 0==Object.keys(e).length}function N(e){return e instanceof HTMLElement}function P(e){return e in HTMLElement.prototype}function R(e){return e in document.createElement("p").style}function E(e){return document.createTextNode(e)}function _(e){return"string"==typeof e}function L(e,t,n){return w(e)&&w(t)&&w(n)}function z(e){"string"!=typeof e&&B("The value of the id attribute must be a string.");const t=document.getElementById(e);if(void 0!=t)return t;M(`There's not an element on the document with id "${e}".`)}function J(e){return void 0===e||"symbol"==typeof e||"bigint"==typeof e||"boolean"==typeof e||"function"==typeof e||"number"==typeof e||"string"==typeof e?typeof e:function(e){return C(e)&&Object.prototype.toString.call(e).startsWith("[object")?Object.prototype.toString.call(e).replace("[object","").replace("]","").replace(/\s/g,"").toLowerCase():"null"}(e)}function B(e){throw Error(`Inter syntaxError : ${e}`)}function M(e){throw Error(`Inter error: ${e}`)}function H(e){console.warn(`Inter warning: ${e}`)}function q(e){console.error(`Inter parser error: ${e}`)}function W(e){return Array.isArray(e)}function Y(e){return 1==e||0==e}function D(e){return e instanceof Array||w(e)||e instanceof Map||e instanceof Set||"number"==typeof e}function F(e){this.source=function(e){const t={values:[],type:void 0};if(W(e))t.values=e,t.type="array";else if(w(e))t.values=Object.entries(e),t.type="object";else if(e instanceof Map)e.forEach((e,n)=>{t.values.push([n,e])}),t.type="object";else if(e instanceof Set)t.values=Array.from(e),t.type="set";else if("number"==typeof e){for(let n=0;e>n;n++)t.values.push(n);t.type="number"}return t}(e),this.break=!1}function U(e){return e="string"==typeof e?e.trim():e,new Set([0,!1,null,void 0,""]).has(e)}function X(e){return/{\s*.*\s*}/.test(e)}function G(e){const t=new Set;return e.replace(/{\s*(:?[\w-\s]+)\s*}/g,e=>{const n=e.replace("{","").replace("}","").trim();t.add(n)}),Array.from(t)}function K(e,t){return RegExp(`{\\s*${t}\\s*}`).test(e)}function Q(e,t,n){function o(e){function r(e){for(const o in t)if(e.textContent.trim().length>0&&K(e.textContent,o)){const t={target:e,text:e.textContent};n.add(t);break}}if(1==e.nodeType)for(const t of e.childNodes)t.hasChildNodes()&&1==t.nodeType?o(t):r(t);else 3==e.nodeType&&r(e)}function r(e){const o={target:e,attrs:Object.create(null),refs:t};for(const r of e.attributes)for(const i in t)if(K(r.value,i)){Me.has(r.name)?(n.specialAttrs.add({target:e,attr:{[r.name]:r.value}}),e.removeAttribute(r.name)):o.attrs[r.name]=r.value;break}var r;r=o.attrs,Object.keys(r).length>0&&n.add(o,!0)}const i=e.getElementsByTagName("*"),s=function(e){const t=new Set;if(e.hasChildNodes())for(const n of e.childNodes)3==n.nodeType&&n.textContent.trim().length>0&&X(n.textContent)&&t.add(n);return Array.from(t)}(e);if(s.length>0)for(const e of s)o(e);for(const e of i)o(e),r(e);n.updateRefs()}function V(e){return null==e}function Z(e){return e.replace("{...","").replace("}","")}function ee(e,t){return A(e,t)}function te(e){return/{(:?\.){3}(:?\S+)}/.test(e)}function ne(e,t){const n=new Set(["value","currentTime"]),o=e=>!n.has(e),r=e=>e.startsWith("on")&&P(e),i=e=>!o(e),s=new Map;for(const[n,a]of Object.entries(t))!o(n)||r(n)||V(a)?i(n)&&!V(a)?re(e,n,a):r(n)&&!V(a)&&ie(e,n,a,t):oe(e,n,a),se(t,n,a,e,s);Object.defineProperty(t,"setAttrs",{set(e){w(e)||function(e){B(`\n "${J(e)}" is an invalid value for the "setAttrs" property.\n The "setAttrs" property only accepts a plain Javascript object as its\n value.\n `)}(e);for(const[t,n]of Object.entries(e))A(this,t)?this[t]=n:H(` \n The "${t}" property was not defined in the manager object.\n `)}}),function(e,t){Object.defineProperty(e,"observe",{value:e=>0===t.size&&($(e)||B(`The argument of the observe method must be a function,\n and you defined ${J(e)} as its argument.`),t.set("observeCallBack",e),!0)})}(t,s)}function oe(e,t,n){V(n)||n===(()=>e.getAttribute(t))?V(n)&&(()=>e.hasAttribute(t))()&&e.removeAttribute(t):e.setAttribute(t,n)}function re(e,t,n){C(n)?e[t]=n:V(n)&&(e[t]="")}function ie(e,t,n,o){C(n)&&!$(n)?function(e,t){B(`\n "${J(t)}" is an invalid\n handler for the "${e}" event, you must\n define only a function as the handler of a dom event.\n `)}(t,n):V(n)?e[t]=void 0:e[t]=(e=>n.call(o,e))}function se(e,t,n,o,r){const i=new Set(["value","currentTime","checked"]),s=()=>!i.has(t),a=()=>t.startsWith("on")&&P(t),c=()=>!s();let l=n;Object.defineProperty(e,t,{set(e){a()?ie(o,t,e,this):s()?oe(o,t,e):c()&&re(o,t,e),l=e;const n=r.get("observeCallBack");r.has("observeCallBack")&&n(t,e)},get:()=>c()?o[t]:a()?(function(e){H(`\n you are trying to get the value of "${e}",\n it's an event, and you can not get the value of an event.\n `)}(t),!1):l})}function ae(e){const t=[];return e.childNodes.forEach(e=>{(1==e.nodeType||3==e.nodeType&&0==!e.textContent.trim().length)&&t.push(e)}),t}function ce(e){H(`"${e}" is a reserved property, you can not use it as a conditional property.`)}function le(e){const t=e.getAttribute("_if"),n=e.getAttribute("_elseIf"),o=e.getAttribute("_ifNot"),r=!!e.hasAttribute("_else")||void 0;return He.set([t,n,o,r]),He.getSize()>1}function fe(e){const t=e.hasAttribute("_if"),n=e.hasAttribute("_elseIf"),o=e.hasAttribute("_ifNot"),r=e.hasAttribute("_else");return!(t||n||o||r)}function ue(n,o){Object.entries(n).forEach(n=>{const[r,i]=n;P(r)?$(i)?o[r]=i:e(r):t(r)})}function de(e,t){Object.entries(e).forEach(e=>{let[n,o]=e,r=!1;const s=new Set(["value","currentTime","checked"]);(n.startsWith("on")&&P(n)||"style"==n)&&(i(n),r=!0);const a=e=>{C(e)&&!I(e)&&(s.has(n)?t[n]=e:t.setAttribute(n,e)),t.template.attrs[n]=e};r||($(o)?a(o=o()):a(o))})}function he(e,t){Object.entries(e).forEach(e=>{const[o,r]=e;if(R(o)){const e=$(r)?r():r;C(e)&&(t.style[o]=e,t.template.styles[o]=e,t.style[o]||s(o,e))}else n(o)})}function pe(e,t,n){if(C(e)&&0==t.length){const t=$(e)?E(e()):E(e);C(t)&&n.appendChild(t)}else C(e)&&t.length>0?(q("The template parser found an element \n with both the text property and the children property,\n and in this case Inter ignores the text property."),be(n,t)):t.length>0&&be(n,t)}function me(e,t,n){let{tag:i,text:s,attrs:a={},events:c={},styles:l={},children:f=[]}=e;i=$(i)?i():i,s=$(s)?s():s,A(e,"renderIf")&&!t&&q("You can not conditionally render the main\n container in the template function."),_(i)||o(i),L(a,l,c)||r();const u=document.createElement(i);return u.template=Object.assign(e,{target:u,tag:i,text:s}),t&&(u.index=n),de(a,u),ue(c,u),he(l,u),pe(s,f,u),u}function be(e,t){let n=-1;for(const i of t){let{tag:t,text:s,attrs:a={},events:c={},styles:l={},children:f=[],renderIf:u}=i;if(n++,i.index=n,t=$(t)?t():t,s=$(s)?s():s,U(u)&&A(i,"renderIf"))continue;_(t)||o(t),L(a,l,c)||r();const d=document.createElement(t);d.index=n,d.template=Object.assign(i,{target:d,tag:t,text:s}),de(a,d),ue(c,d),he(l,d),pe(s,f,d),e.appendChild(d)}}function ge(e,t,n,o){w(e)?function(e,t,n){function o(o){let r=e[o];e[o]=void 0,Object.defineProperty(e,o,{set(o){if(r=o,e[i]){const n=e[i].index;t(n)}else t();const s=w(n);ge(o,t,null,s?n:null)},get:()=>r,configurable:!0})}const r=new Set(["setProps","defineProps","deleteProps"]);const i=Symbol.for("index");w(n)&&(e[i]=n);if(ve(e))return!0;if(j(e))return H("Inter failed to define reactivity\n in a plain Javascript object, because it is not configurable."),!1;for(const i of Object.keys(e))r.has(i)&&H(`"${i}" is a reserved property, do not create a property with this name.`),o(i),ge(e[i],t,null,n);(function(t){for(const{name:n,setHandler:o}of t)Object.defineProperty(e,n,{set:o})})([{name:"defineProps",setHandler:function(i){w(i)||function(e){B(`The value of "defineProps" must be a plain Javascript object, and you\n defined "${J(e)}" as its value`)}(i);const s=w(n)?n.index:void 0;for(const[a,c]of Object.entries(i))a in this||r.has(a)||(e[a]=c,o(a),ge(e[a],t,null,n)),t(s)}},{name:"setProps",setHandler:function(t){w(t)||a(t);for(const[n,o]of Object.entries(t))r.has(n)||(e[n]=o)}},{name:"deleteProps",setHandler:function(o){W(o)||function(e){B(`The value of "deleteProps" must be an Array object, and you\n defined "${J(e)}" as its value`)}(o);const i=w(n)?n.index:void 0;for(const t of o)"string"==typeof t&&A(e,t)&&(r.has(t)||delete e[t]);t(i)}}]),ye(e)}(e,t,o):W(e)?function(e,t,n){if(ve(e))return!1;const o=["push","unshift","pop","shift","splice","sort","reverse"];for(const r of o)Object.defineProperty(e,r,{value(e,o,...i){"pop"==r?this.mutationInfo={method:"pop",renderingSystem:t}:"shift"==r?this.mutationInfo={method:"shift",renderingSystem:t}:"push"==r?this.mutationInfo={method:"push",itemsLength:arguments.length,renderingSystem:t}:"unshift"==r?this.mutationInfo={method:"unshift",itemsLength:arguments.length,renderingSystem:t}:"splice"==r&&(this.mutationInfo={method:"splice",start:e,deleteCount:o,itemsLength:C(i)?i.length:0,renderingSystem:t});const s=Array.prototype[r].apply(this,arguments);if(t(),this.mutationInfo=void 0,"push"===r||"unshift"===r)for(const e of arguments)ge(e,t,null,n);else if("splice"===r&&C(i))for(const e of i)ge(e,t,null,n);return s}});(function(e,t,n){for(const o of e)ge(o,t,null,n)})(e,t,n),ye(e),function(e){Object.defineProperty(e,"map",{value(e){const t=[];t.reactor=this;let n=-1;for(const o of this){const r=e(o,++n,this);t.push(r)}return t}})}(e)}(e,t,o):T(e)?Te(e,t):x(e)&&Ce(e,t,!1,null,o)}function ye(e){if(ve(e))return!1;const t=Symbol.for("reactive");Object.defineProperty(e,t,{get:()=>!0})}function ve(e){return A(e,Symbol.for("reactive"))}function je(e){w(e)?function(e,t,n){Object.keys(e).some((e,o)=>{e==t&&we(n,o)})}(...arguments):x(e)?function(e,t,n){Array.from(e).some((e,o)=>{e==t&&we(n,o)})}(...arguments):function(e,t,n){let o=-1;e.forEach(()=>{o++;const e=arguments[1];e==t&&we(n,o)})}(...arguments)}function we(e,t){const n=e.children[t];N(n)&&e.removeChild(n)}function Oe(e,t){const n=Symbol.for("observe");"function"==typeof e[n]&&e[n](C(t)?t:e)}function xe(e,t){Object.defineProperty(e,"setProps",{set(n){w(n)||a();for(const[o,r]of Object.entries(n))w(e)?this[o]=r:T(e)&&e.set(o,r),ge(r,t);w(e)&&t()}})}function Ae(e,t,n){j(e)&&c(),xe(e,t);const o=new Set(["observe"]),r=new Set(["setEach","setProps"]);return ye(e),new Proxy(e,{set(n,i,s,a){return!o.has(i)&&(Reflect.set(...arguments),function(e){return!r.has(e)}(i)&&(t(),Oe(e,a),"number"!=typeof s&&D(s)&&ge(s,t)),!0)},get(){return Reflect.get(...arguments)},deleteProperty(o,r,i){if(r in o)return je(o,r,n),Reflect.deleteProperty(...arguments),t(),Oe(e,i),!0;H(`You are trying to delete the "${r}" property in the list\n reactor, but that property does not exist in the list reactor.`)}})}function Te(e,t,n,o){if(ve(e))return!1;const r=["set","delete","clear"];for(const i of r)Object.defineProperty(e,i,{value(){"delete"==i&&n&&je(this,arguments[0],o);const e=Map.prototype[i].apply(this,arguments);if(n&&Oe(this),t(),"set"==i){ge(arguments[1],t)}return e}});!function(e,t){e.forEach(e=>{ge(e,t)})}(e,t),ye(e),n&&xe(e,t)}function Ce(e,t,n,o,r){if(ve(e))return!1;const i=["add","clear","delete"];for(const r of i)Object.defineProperty(e,r,{value(){"delete"==r&&n&&je(this,arguments[0],o);const e=Set.prototype[r].apply(this,arguments);return t(),n&&Oe(this),"add"===r&&ge(arguments[0],t),e}});!function(e,t,n){e.forEach(e=>{ge(e,t,0,n)})}(e,t,r),ye(e)}function Se(e){return"function"==typeof e&&(e=e()),e}function Ie(e,t,n,o){function r(e){function r(e,o){for(let r=o-1;r>-1;r--){const o=t.children[e],s=n[r],a=me(s,!0,s.index);o?t.insertBefore(a,o):t.appendChild(a),i.unshift(s)}}const i=[];if("splice"==e&&0==a&&c>0)r(s,c),o.splice(s,a,...i);else if("splice"==e&&a>0){for(let e=0;a>e;e++){const e=t.children[s];e&&t.removeChild(e)}r(s,c),o.splice(s,a,i)}else"unshift"==e&&(r(0,c),o.unshift(...i))}if(void 0==e.mutationInfo)return;const{mutationInfo:{method:i,start:s,deleteCount:a,itemsLength:c}}=e,l=t.children[t.children.length-1],f=t.children[0];if("pop"==i&&l)t.removeChild(l),o.pop();else if("shift"==i&&f)t.removeChild(f),o.shift();else if("push"==i)!function(){let e=c;for(;e>0;e--){const r=n[n.length-e];t.appendChild(me(r,!0,r.index)),o.push(r)}}();else if("unshift"==i)r(i);else if("splice"==i)if("number"==typeof s&&"number"==typeof a&&0==c)!function(){let e=s;for(;n.length0)r(i);else if(void 0==a){_e(t,{source:{values:n}})}}function $e(e,t){Object.assign(e,t)}function ke(e,t){return e.length>t.length?e:t}function Ne(e,t,n){function o(t){e.hasAttribute(t)?e.removeAttribute(t):c.has(t)&&("checked"===t?e.checked=!1:e[t]="")}const r=Object.keys(t),s=Object.keys(n),a=ke(r,s),c=new Set(["value","currentTime","checked"]);for(let l=0;a.length>l;l++){const a=r[l],f=s[l],u=Se(t[a]),d=Se(n[f]);a in n?!C(d)||I(d)?o(f):C(d)&&!I(d)&&(f.startsWith("on")&&P(f)||"style"==f?i(f):f===a&&d===u||(c.has(f)?e[f]=d:e.setAttribute(f,d))):o(a),t[a]=d}}function Pe(e,t,o){const r=Object.keys(t),i=Object.keys(o),a=ke(r,i);for(let c=0;a.length>c;c++){const a=r[c],l=i[c],f=Se(t[a]),u=Se(o[l]);if(a in o&&C(u))C(u)&&u!==f&&(R(l)?(e.style[l]=u,e.style[l]||s(l,u)):n(l));else{const t=e.style[a],n=e.getAttribute("style");C(t)&&0!==t.trim().length&&(e.style[a]=null),n&&0==n.trim().length&&e.removeAttribute("style")}t[a]=u}}function Re(n,o,r){const i=Object.keys(o),s=Object.keys(r),a=ke(i,s);for(let o=0;a.length>o;o++){const a=i[o],c=s[o];a in r&&C(r[a])||(n[a]=void 0),$(r[c])||!P(c)?C(r[c])&&(P(c)?n[c]=r[c]:t(c)):(n[a]=void 0,e(c))}}function Ee(e,t,n){for(let o=0;ot){e.insertBefore(n,r);break}}}function _e(e,t){if(e.children.length>t.source.values.length){let n=e.children.length-t.source.values.length;for(;n--;){const t=e.children.length-1,n=e.children[t];e.removeChild(n)}}}function Le(e,t,n,o,r){e.open(t,n,!0,o,r)}function ze(e,t,n){Object.entries(t).forEach(([t,o])=>{n.has(t)?"onprogress"!==t?e[t]=(()=>{o()}):e.onprogress=(t=>{const n={abort:()=>e.abort(),progress:100*t.loaded/t.total};o(n)}):H(`There's not any event named "${t}" in Ajax request.`)})}function Je(e,t){const n={};var o,r;return e.replace(/(:?[\S]+):/g,e=>{e=e.replace(":",""),t.getResponseHeader(e)&&((o=n)[r=e]=void 0,Object.defineProperty(o,r,{get:()=>t.getResponseHeader(r)}))}),Object.freeze(n)}function Be(){void 0===new.target&&M("Backend is a constructor, call it with the new keyword.")}F.prototype.each=function(e){let t=-1;for(const n of this.source.values)if(e(n,++t,this.source.type),this.break)break};const Me=new Set(["currentTime","value"]),He={store:new Set,set(e){for(const t of e)C(t)&&this.store.add(t)},getSize(){const e=this.store.size;return this.store.clear(),e}};Be.prototype={get[Symbol.toStringTag](){return"Ajax"},request(e){function t(){const e=new XMLHttpRequest,t=n.toUpperCase(),f=new Set(["onprogress","ontimeout","onabort"]),u={get status(){return e.status},get statusText(){return e.statusText},get headers(){return Je(e.getAllResponseHeaders(),e)},get data(){return function(e){if(void 0!==e)try{return JSON.parse(e)}catch(t){return e}}(e.responseText)},get[Symbol.toStringTag](){return"AjaxResponse"},isObj:()=>(function(e){try{return w(JSON.parse(e))}catch(e){return!1}})(e.responseText)};w(l)&&Object.keys(l).length>=2&&(l.username&&l.password?(Le(e,t,o,l.username,l.password),h=!0):H('Invalid "security" object, security object must have the username and passoword \n properties.')),h||(Le(e,t,o),h=!0),w(c)||function(e){B(`the "headers" property must be an object, and\n you defined it as : ${J(e)}.`)}(c),w(r)||function(e){B(`the "events" property must be an object, and\n you defined it as : ${J(e)}.`)}(r),k(c)||function(e,t){Object.entries(e).forEach(([e,n])=>{t.setRequestHeader(e,n)})}(c,e),k(r)||ze(e,r,f),e.onreadystatechange=function(){4==this.readyState&&(this.status>=200&&300>this.status?d.has("okay")&&d.get("okay")(u):d.has("error")&&d.get("error")(u))},Y(s)&&(e.withCredentials=s),"number"!=typeof i&&(e.timeout=i),e.send(function(e){return C(e)?e instanceof FormData||"string"==typeof e?e:JSON.stringify(e):null}(a))}w(e)||B(`The argument of [Backend instance].request method\n must be a plain javascript object, and you defined "${J(e)}"\n as its argument.`);const{type:n,path:o,events:r={},timeout:i,withCredentials:s,body:a=null,headers:c={},security:l}=e,f=new Set(["connect","trace"]);C(n)&&"string"==typeof n||B('You must define the type(method) of request, in Ajax with the "type" option and\n it must be a string.'),C(o)&&"string"==typeof o||B('You must define the path where the request will be sent, with the "path" option and \n it must be a string.'),f.has(o.toLowerCase())&&function(e){M(`"${e}" is an unsupported request type in Ajax.`)}(n);const d=new Map;let h=!1;return{okay(e){$(e)||u(),d.set("okay",e),t()},error(e){$(e)||u(),d.set("error",e),t()},response(e,n){const o=arguments.length;2>o&&function(e){B(`The response method must have two arguments and you only\n defined ${e} argument.`)}(o),$(e)||$(n)||u(),d.set("okay",e),d.set("error",n),t()}}}},Object.freeze(Be.prototype),window.Ref=function(e){if(void 0!=new.target)B("Do not call the Ref function with the new keyword.");else{if(w(e)){const{in:n,data:o}=e;"string"!=typeof n&&B("The value of the 'in' property on the Ref function must be a string."),w(o)||B("The value of the 'data' property on the Ref function must be a plain Javascript object. ");const r=new Set(["setRefs","observe"]);for(const e in o)r.has(e)?(d(e),delete o[e]):$(o[e])&&(o[e]=o[e].call(o));const i=Object.assign({},o),s={attrs:new Set,texts:new Set,specialAttrs:new Set,observed:new Map,refs:i,hadIteratedOverSpecialAttrs:!1,add(e,t){t?this.attrs.add(e):this.texts.add(e)},updateSpecialAttrs(){for(const e of this.specialAttrs){const{target:t}=e;let[n,o]=Object.entries(e.attr)[0];const i=G(o);for(const e of i)if(!r.has(e)&&e in this.refs){const t=RegExp(`{\\s*(:?${e})\\s*}`,"g");if(!X(o=o.replace(t,this.refs[e])))break}t[n]=o}},updateAttrRef(){for(const e of this.attrs){const{target:t,attrs:n}=e;for(let[e,o]of Object.entries(n)){const n=G(o);for(const e of n)if(!r.has(e)&&e in this.refs){const t=RegExp(`{\\s*(:?${e})\\s*}`,"g");if(!X(o=o.replace(t,this.refs[e])))break}t.getAttribute(e)!==o&&t.setAttribute(e,o)}}},updateTextRef(){if(this.texts.size>0)for(const e of this.texts){let{target:t,text:n}=e;const o=G(n);for(const e of o)if(!r.has(e)&&e in this.refs){const t=RegExp(`{\\s*(:?${e})\\s*}`,"g");if(!X(n=n.replace(t,this.refs[e])))break}t.textContent!==n&&(t.textContent=n)}},updateRefs(){this.texts.size>0&&this.updateTextRef(),this.attrs.size>0&&this.updateAttrRef(),this.specialAttrs.size>0&&this.updateSpecialAttrs()}};function t(e,t,n){1!=s.observed.size||r.has(e)||s.observed.get("callBack")(e,t,n)}Q(z(n),i,s);const a=new Proxy(i,{set(e,o,r,a){if(o in e&&e[o]==r)return!1;const c=e[o];if($(r)&&(r=r.call(a)),Reflect.set(...arguments),t(o,r,c),o in a)return s.updateRefs(),!0;Q(z(n),i,s)},get:(...e)=>Reflect.get(...e)});return Object.defineProperties(a,{setRefs:{set(e){if(w(e)){let o=!1;for(const[n,s]of Object.entries(e)){if(r.has(n)){d(n);continue}if(A(this,n)||(o=!0),A(this,n)&&this[n]==s)continue;const e=i[n];$(s)?i[n]=s.call(this):i[n]=s,t(n,s,e)}o&&Q(z(n),i,s)}else B(`"${J(e)}" is not a valid value for the "setRefs" property.\n The value of the setRefs property must be a plain Javascript object.`)},enumerable:!1},observe:{value:e=>($(e)||B("The argument of [Reference reactor].observe() must be a function."),0===s.observed.size&&(s.observed.set("callBack",e),!0)),enumerable:!1,writable:!1}}),a}B("The argument of the Ref function must be a plain Javascript object.")}},window.renderIf=function(e){if(w(e)||B("The argument of renderIf must be a plain Javascript object."),void 0===new.target){const{in:t,data:n}=e,o=new Set(["setConds","observe"]),r=z(t),i=[];"string"!=typeof t&&B('The value of the "in" property in the renderIf function\n must be a string.'),w(n)||B('The value of the "data" property in the renderIf function \n must be a plain Javascript object.');for(let[e,t]of Object.entries(n))o.has(e)?ce(e):(Y(t=$(t)?t.call(n):t)||p(e),n[e]=t);return function e(t){let o=-1;const r={target:void 0,if:void 0,else:void 0,ifNot:void 0,elseIfs:new Set,index:void 0,lastRendered:{target:void 0,prop:void 0},conditionalProps:new Set,rootElement:t,set setOptions(e){for(const[t,n]of Object.entries(e))this[t]=n,"if"==t&&C(n)&&this.conditionalProps.add(n)},canCache(){return void 0!=this.if},addElseIf(e){const{elseIf:t}=e;this.conditionalProps.has(t)?function(e){M(`\n Two elements in the conditional group can not have the same conditional property.\n Property: "${e}"\n `)}(t):(this.elseIfs.add(e),this.conditionalProps.add(t))},deleteData(){this.setOptions={target:void 0,if:void 0,else:void 0,ifNot:void 0,index:void 0},this.elseIfs.clear(),this.conditionalProps.clear()},getOptions(){const e=Object.assign({},this);return e.elseIfs=Array.from(this.elseIfs),e.conditionalProps=Array.from(this.conditionalProps),this.deleteData(),e}},s=()=>{const e=r.elseIfs.size,t=r.getOptions();e?i.unshift(t):i.push(t)},a=ae(t),c=a.length;for(const t of a){o++,t.index=o;const i=c-1==o;if(3!=t.nodeType)if(fe(t)||t.parentNode.removeChild(t),t.children.length>0&&e(t),le(t))q(`The conditional rendering parser found a/an "${O(t)}"\n element which has more than one conditional atribute, it's forbidden.`);else if(fe(t)&&r.canCache())s();else{if(t.hasAttribute("_ifNot")){const e=t.getAttribute("_ifNot");if(A(n,e)){t.removeAttribute("_ifNot"),r.canCache()&&s(),r.setOptions={ifNot:e,target:t,index:o},s();continue}m(t,e,n)}else if(t.hasAttribute("_else"))r.if?(r.else=t,t.removeAttribute("_else"),s()):q('The parser found an element with the "_else" attribute,\n but there is not an element with the "_if" or a valid "_elseIf" attribute before it.');else if(t.hasAttribute("_elseIf")){const e=t.getAttribute("_elseIf");t.removeAttribute("_elseIf"),r.if?A(n,e)?r.addElseIf({target:t,index:o,elseIf:e}):0!=(l=e).trim().length?q(`The conditional rendering parser found an element which has the "_elseIf"\n conditional property whose the value is: "${l}",\n but you did not define any conditional property with that name.\n \n `):b("_elseIf"):g(t)}else if(t.hasAttribute("_if")){r.canCache()&&s();const e=t.getAttribute("_if");if(t.removeAttribute("_if"),!A(n,e)){y(e,t,n);continue}r.setOptions={if:e,target:t,index:o}}i&&r.canCache()&&s()}else r.canCache()&&s()}var l}(r),function(e,t){function n(e,t){if(!I(l[t])&&e.length>=2)for(const n of e){const e=S(l[n]);e&&n!==t&&(l[n]=!1)}}function o(e,t){function n(){return null!=t.lastRendered.target.parentNode}let o=!1;for(const{target:r,elseIf:s}of e){const e=t.lastRendered;if(e.target&&S(l[e.prop])){o=!0;break}e.target&&I(l[e.prop])&&n()&&(t.rootElement.removeChild(e.target),t.lastRendered={prop:void 0,target:void 0}),S(l[s])&&(i(t.rootElement,r),t.lastRendered={prop:s,target:r},o=!0,e.target&&!C(e.prop)&&n()&&t.rootElement.removeChild(e.target))}return o}function r(t,r){for(const s of e){const{target:e,if:a,elseIfs:c,else:l,ifNot:f,rootElement:u}=s,d=s.conditionalProps,h=new Set(d).has(r);if(C(r)&&h&&n(d,r),f)I(t[f])&&null==e.parentNode?u.textContent.trim().length>0?i(u,e):u.appendChild(e):e.parentNode==u&&S(t[f])&&u.removeChild(e);else if(I(t[a]))if(e.parentNode!=u||l){if(l||c.length>0){const t=o(c,s);null!=e.parentNode&&u.removeChild(e),t&&l&&null!=l.parentNode?l.parentNode.removeChild(l):!t&&l&&null==l.parentNode&&(i(u,l),s.lastRendered={target:l,prop:void 0})}}else u.removeChild(e),o(c,s);else if(S(t[a])&&null==e.parentNode){l&&null!=l.parentNode?(u.removeChild(l),i(u,e)):i(u,e);const{target:t}=s.lastRendered;N(t)&&null!=t.parentNode&&!t.isSameNode(e)&&t.parentNode.removeChild(t),s.lastRendered={target:e,prop:a}}}}function i(e,t){const n=ae(e),o=n[n.length-1];if(t&&null==t.parentNode)if(o&&o.index>t.index){for(const o of n)if(o.index>t.index){e.insertBefore(t,o);break}}else e.appendChild(t)}function s(e,t){if(1==c.size){const n=c.get("callBack");n(e,t)}}const a=new Set(["setConds","observe"]),c=new Map,l=Object.assign({},t);r(l);const f=new Proxy(l,{set:(e,n,o)=>!(n in e&&e[n]==o||(n in t||a.has(n)?Y(o)||a.has(n)?(Reflect.set(e,n,o),a.has(n)||(r(l,n),s(n,o)),0):(p(n),1):(h(n),1))),deleteProperty:()=>!1});return Object.defineProperties(f,{observe:{value:e=>($(e)||B("The argument of [renderIf reactor].observe()\n must be a function."),0==c.size&&(c.set("callBack",e),!0)),enumerable:!1,writable:!1},setConds:{set(e){w(e)||B(`The value of [renderIf reactor].setConds must be\n a plain Javascript object, and you defined ${J(e)}\n as its value.`);for(let[n,o]of Object.entries(e))a.has(n)?ce(n):(Y(o=$(o)?o.call(t):o)||p(n),A(this,n)?this[n]!=o&&(l[n]=o,s(n,o)):h(n));r(l)},enumerable:!1}}),f}(i,n)}M("renderIf is not a constructor, do not call it with\n the new keyword.")},window.renderList=function(e){function t(e,t,n){return W(e)?(function(e){if(ve(e))return!1;const t=[{name:"addItems",handler:function(e,t){if(C(t)&&"number"!=typeof t&&B("The second argument of [LIST REACTOR].addItems must be a number."),W(e)||B("The first argument of [LIST REACTOR ].addItems must be an Array."),!C(t)||t>this.length-1)for(const t of e)this.push(t);else if(0==t||0>t)for(let t=e.length-1;t>-1;t--)this.unshift(e[t]);else for(let n=e.length-1;n>-1;n--)this.splice(t,0,e[n])}}];for(const{name:n,handler:o}of t)Object.defineProperty(e,n,{value:o})}(e),function(e,t){j(e)&&c();const n=new Set(["addItems","setEach"]);return new Proxy(e,{set(o,r,i,s){return n.has(r)?(Reflect.set(...arguments),!0):(Reflect.set(...arguments),Oe(e,s),t(),"number"!=typeof i&&D(i)&&ge(i,t),!0)},get:(e,t)=>e[t]})}(e,t)):w(e)?Ae(e,t,n):x(e)?(Ce(e,t,!0,n),e):T(e)?(Te(e,t,!0,n),e):void 0}function n(e){D(e)||l(e);const t=Symbol.for("observe");e[t]=s[t],s=e,ve(e)||o(),r(),Oe(s),"number"!=typeof s&&new F(s).each((e,t,n)=>{"object"==n?ge(e[1],r):"array"!=n&&"set"!=n||ge(e,r)})}function o(){if(ve(s))return!1;Object.defineProperties(s,{setEach:{set:n},observe:{value(e){const t=Symbol.for("observe");return"function"!=typeof this[t]&&($(e)?(Object.defineProperty(this,t,{value:e,configurable:!1}),!0):void B("The argument of the observe method must be a function."))}}}),h=t(s,r,d),W(s)&&function(e,t,n,o,r){function i(e,i,s,a){const c=o.call(r,e,i,r),l=me(c.element),u=t.children[s];v(c)||f(),l&&C(s)?t.insertBefore(l,u):t.appendChild(l),C(a)&&(i=a),n(i,!0)}const s=[{name:"unshift",handler:function(){const t=Array.prototype.unshift.apply(e,arguments);if(arguments.length>1){let e=arguments.length;for(let t=e-1;t>-1;t--)i(arguments[--e],0,0,e)}else 1==arguments.length&&i(...arguments,0,0);return n(),Oe(e),t}},{name:"shift",handler:function(){const o=Array.prototype.shift.apply(e,void 0),r=t.children[0];return r&&(t.removeChild(r),n(),Oe(e)),o}},{name:"push",handler:function(){const t=Array.prototype.push.apply(e,arguments);if(1==arguments.length)i(...arguments,e.length-1);else if(arguments.length>1){let t=arguments.length;for(const n of arguments)i(n,e.length-t--)}return n(),Oe(e),t}},{name:"pop",handler:function(){const o=Array.prototype.pop.apply(e,arguments),r=t.children,i=r[r.length-1];return i&&(t.removeChild(i),n(),Oe(e)),o}},{name:"splice",handler:function(o,r,...s){function a(){const e=r;for(let n=0;e>n;n++){const e=t.children[o];e&&t.removeChild(e)}}function c(){for(let e=s.length-1;e>-1;e--)i(s[e],e,o)}const l=Array.prototype.splice.apply(e,arguments);return r>0&&s.length>0&&(a(),c()),0==s.length?a():0==r&&s.length>0&&c(),n(),Oe(e),l}}];if(j(e))return!1;if(ve(e))return!1;for(const{name:t,handler:n}of s)Object.defineProperty(e,t,{value:n})}(s,d,r,a,h),ye(s)}function r(e,t){const n=new F(s);_e(d,n),n.each((o,i,s)=>{let c,l;if("array"==s){C(e)&&(o=h[e],i=e,n.break=!0);const t=Symbol.for("index"),r=()=>S(u)&&(w(o)||W(o)||x(o))&&!A(o,t);l={index:i,sourceLength:h.length},r()?o[t]=l:(w(o)||W(o)||x(o))&&A(o,t)&&(()=>o[t].sourceLength!==l.sourceLength)()&&$e(o[t],l)}if((p||t)&&ge("object"!==s?o:o[1],r,0,S(u)?l:null),!t)if(v(c="array"===s?a.call(h,o,i,h):"object"===s?a.call(h,o[0],o[1],h):"number"===s?a(o):a.call(h,o,h))){const e=d.children[i];N(e)?e.template?function(e,t,n){const o={ 12 | children:!0,continue:!0};(function(e,t,n){const{attrs:o={},events:r={},styles:i={},children:s}=e,{attrs:a={},events:c={},styles:l={},children:f,target:u}=t;let d;W(s)&&(d=s.reactor),void 0!=d&&Ie(d,u,s,f);const h=u.parentNode,p=Se(e.text),m=Se(t.text),b=Se(e.tag),g=Se(t.tag);if(b!==g){const o=me(e);h.replaceChild(o,u),n.children=!1,$e(t,e),t.target=o}else if(v=f,W(y=s)&&!W(v)||!W(y)&&W(v)){const o=me(e);h.replaceChild(o,u),n.children=!1,$e(t,e),t.target=o}else if(function(e,t){return W(e)&&W(t)}(s,f)&&s.length!==f.length){const o=me(e);h.replaceChild(o,u),n.children=!1,$e(t,e),t.target=o}else C(s)||C(f)||p!==m&&(u.textContent=p,$e(t,e));var y,v;Ne(u,a,o),Re(u,c,r),Pe(u,l,i)})(e,t,o),o.children&&e.children&&e.children.length>0&&function e(t,n,o){const r=Array.from(t),i=Array.from(n);for(let t=0;tv?Ee(o,v,e):o.appendChild(e)}if(o&&(j=o.children[o.children.length-1]),l.length!==p.length){const{reactor:e}=l;if(void 0!=e)Ie(e,y,l,p);else if(y&&null!=y.parentNode){const e=me(n,!0,v);o.replaceChild(e,y),Object.assign(a,n),a.target=e;continue}}if(x===T)U(h)&&A(n,"renderIf")?y&&null!=y.parentNode&&o.removeChild(y):U(h)||(y&&null==y.parentNode?s():y||s()),l.length==p.length&&0!==l.length&&(c=!0,e(l,p,y)),O!==w&&y&&!c&&(y.textContent=w,a.text=w),a.tag=x,y&&(Ne(y,b,u),Pe(y,g,d),Re(y,m,f));else{const e=me(n,!0,v);Object.assign(a,n),y&&null!=y.parentNode&&(o.replaceChild(e,y),a.target=e)}}}(e.children,t.children,n)}(c.element,e.template,e):(H("Avoid manipulating what Inter manipulates."),d.replaceChild(me(c.element),e)):d.appendChild(me(c.element))}else f()})}void 0!==new.target&&B('renderList is not a constructor, do not call\n it with the "new" keyword.'),w(e)||B("The options(the argument of renderList) must be a plain Javascript object.");let{in:i,each:s,do:a,optimize:u}=e;const d=z(i);(function(e){return"string"==typeof e})(i)||B("The 'in' option in renderList must be a string."),D(s)||l(s),$(a)||B("The value of the 'do' option in renderList must be only a function."),C(u)&&!S(u)&&B("The value of the 'optimize' option in renderList must be only true"),C(u)&&!W(s)&&B("The 'optimize' option can only be enabled when the each's value is an Array.");let h,p=!0;return"number"!=typeof s&&o(),r(),p=!1,h},window.template=function(e){if(w(e))return{[Symbol.for("template")]:!0,element:e};B(`The argument of the template function must be a plain Javascript object,\n but you defined "${J(e)}" as its argument.\n \n `)},window.toAttrs=function(e){if(void 0!==new.target)B('the "toAttrs" function is not a constructor, do not call it with the\n new keyword.');else{if(w(e)){const{in:t,data:n}=e;return function(e,t){const n=e.getElementsByTagName("*");for(const e of n)if(1==e.attributes.length){const{name:n}=e.attributes[0];if(/{(:?[\s\S]+)}/.test(n)&&te(n)){const o=Z(n);e.removeAttribute(n),ee(t,o)?ne(e,t[o]):q(`\n The attribute manager parser found an attribute manager\n named "${o}", but you did not define it in the "data" object.\n `)}}}(z(t),n),n}B(`"${J(e)}" is an invalid argument for\n "toAttrs" function, the argument must be a plain Javascript object.`)}},window.Backend=Be,console.log("The global version 2.2.4 of Inter was loaded successfully.")}(); -------------------------------------------------------------------------------- /mitpic.svg: -------------------------------------------------------------------------------- 1 | license: MITlicenseMIT -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "inter", 3 | "version": "2.2.4", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "inter", 9 | "version": "2.2.4", 10 | "license": "MIT", 11 | "devDependencies": { 12 | "eslint": "^8.56.0", 13 | "prettier": "^2.8.3", 14 | "typescript": "^5.8.2" 15 | } 16 | }, 17 | "node_modules/@aashutoshrathi/word-wrap": { 18 | "version": "1.2.6", 19 | "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", 20 | "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", 21 | "dev": true, 22 | "engines": { 23 | "node": ">=0.10.0" 24 | } 25 | }, 26 | "node_modules/@eslint-community/eslint-utils": { 27 | "version": "4.4.0", 28 | "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", 29 | "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", 30 | "dev": true, 31 | "dependencies": { 32 | "eslint-visitor-keys": "^3.3.0" 33 | }, 34 | "engines": { 35 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 36 | }, 37 | "peerDependencies": { 38 | "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" 39 | } 40 | }, 41 | "node_modules/@eslint-community/regexpp": { 42 | "version": "4.10.0", 43 | "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", 44 | "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", 45 | "dev": true, 46 | "engines": { 47 | "node": "^12.0.0 || ^14.0.0 || >=16.0.0" 48 | } 49 | }, 50 | "node_modules/@eslint/eslintrc": { 51 | "version": "2.1.4", 52 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", 53 | "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", 54 | "dev": true, 55 | "dependencies": { 56 | "ajv": "^6.12.4", 57 | "debug": "^4.3.2", 58 | "espree": "^9.6.0", 59 | "globals": "^13.19.0", 60 | "ignore": "^5.2.0", 61 | "import-fresh": "^3.2.1", 62 | "js-yaml": "^4.1.0", 63 | "minimatch": "^3.1.2", 64 | "strip-json-comments": "^3.1.1" 65 | }, 66 | "engines": { 67 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 68 | }, 69 | "funding": { 70 | "url": "https://opencollective.com/eslint" 71 | } 72 | }, 73 | "node_modules/@eslint/js": { 74 | "version": "8.56.0", 75 | "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", 76 | "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", 77 | "dev": true, 78 | "engines": { 79 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 80 | } 81 | }, 82 | "node_modules/@humanwhocodes/config-array": { 83 | "version": "0.11.14", 84 | "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", 85 | "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", 86 | "deprecated": "Use @eslint/config-array instead", 87 | "dev": true, 88 | "dependencies": { 89 | "@humanwhocodes/object-schema": "^2.0.2", 90 | "debug": "^4.3.1", 91 | "minimatch": "^3.0.5" 92 | }, 93 | "engines": { 94 | "node": ">=10.10.0" 95 | } 96 | }, 97 | "node_modules/@humanwhocodes/module-importer": { 98 | "version": "1.0.1", 99 | "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", 100 | "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", 101 | "dev": true, 102 | "engines": { 103 | "node": ">=12.22" 104 | }, 105 | "funding": { 106 | "type": "github", 107 | "url": "https://github.com/sponsors/nzakas" 108 | } 109 | }, 110 | "node_modules/@humanwhocodes/object-schema": { 111 | "version": "2.0.2", 112 | "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", 113 | "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", 114 | "deprecated": "Use @eslint/object-schema instead", 115 | "dev": true 116 | }, 117 | "node_modules/@nodelib/fs.scandir": { 118 | "version": "2.1.5", 119 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 120 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 121 | "dev": true, 122 | "dependencies": { 123 | "@nodelib/fs.stat": "2.0.5", 124 | "run-parallel": "^1.1.9" 125 | }, 126 | "engines": { 127 | "node": ">= 8" 128 | } 129 | }, 130 | "node_modules/@nodelib/fs.stat": { 131 | "version": "2.0.5", 132 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 133 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 134 | "dev": true, 135 | "engines": { 136 | "node": ">= 8" 137 | } 138 | }, 139 | "node_modules/@nodelib/fs.walk": { 140 | "version": "1.2.8", 141 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 142 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 143 | "dev": true, 144 | "dependencies": { 145 | "@nodelib/fs.scandir": "2.1.5", 146 | "fastq": "^1.6.0" 147 | }, 148 | "engines": { 149 | "node": ">= 8" 150 | } 151 | }, 152 | "node_modules/@ungap/structured-clone": { 153 | "version": "1.2.0", 154 | "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", 155 | "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", 156 | "dev": true 157 | }, 158 | "node_modules/acorn": { 159 | "version": "8.11.3", 160 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", 161 | "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", 162 | "dev": true, 163 | "bin": { 164 | "acorn": "bin/acorn" 165 | }, 166 | "engines": { 167 | "node": ">=0.4.0" 168 | } 169 | }, 170 | "node_modules/acorn-jsx": { 171 | "version": "5.3.2", 172 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", 173 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", 174 | "dev": true, 175 | "peerDependencies": { 176 | "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" 177 | } 178 | }, 179 | "node_modules/ajv": { 180 | "version": "6.12.6", 181 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 182 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 183 | "dev": true, 184 | "dependencies": { 185 | "fast-deep-equal": "^3.1.1", 186 | "fast-json-stable-stringify": "^2.0.0", 187 | "json-schema-traverse": "^0.4.1", 188 | "uri-js": "^4.2.2" 189 | }, 190 | "funding": { 191 | "type": "github", 192 | "url": "https://github.com/sponsors/epoberezkin" 193 | } 194 | }, 195 | "node_modules/ansi-regex": { 196 | "version": "5.0.1", 197 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 198 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 199 | "dev": true, 200 | "engines": { 201 | "node": ">=8" 202 | } 203 | }, 204 | "node_modules/ansi-styles": { 205 | "version": "4.3.0", 206 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 207 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 208 | "dev": true, 209 | "dependencies": { 210 | "color-convert": "^2.0.1" 211 | }, 212 | "engines": { 213 | "node": ">=8" 214 | }, 215 | "funding": { 216 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 217 | } 218 | }, 219 | "node_modules/argparse": { 220 | "version": "2.0.1", 221 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 222 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 223 | "dev": true 224 | }, 225 | "node_modules/balanced-match": { 226 | "version": "1.0.2", 227 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 228 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 229 | "dev": true 230 | }, 231 | "node_modules/brace-expansion": { 232 | "version": "1.1.11", 233 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 234 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 235 | "dev": true, 236 | "dependencies": { 237 | "balanced-match": "^1.0.0", 238 | "concat-map": "0.0.1" 239 | } 240 | }, 241 | "node_modules/callsites": { 242 | "version": "3.1.0", 243 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 244 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 245 | "dev": true, 246 | "engines": { 247 | "node": ">=6" 248 | } 249 | }, 250 | "node_modules/chalk": { 251 | "version": "4.1.2", 252 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 253 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 254 | "dev": true, 255 | "dependencies": { 256 | "ansi-styles": "^4.1.0", 257 | "supports-color": "^7.1.0" 258 | }, 259 | "engines": { 260 | "node": ">=10" 261 | }, 262 | "funding": { 263 | "url": "https://github.com/chalk/chalk?sponsor=1" 264 | } 265 | }, 266 | "node_modules/color-convert": { 267 | "version": "2.0.1", 268 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 269 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 270 | "dev": true, 271 | "dependencies": { 272 | "color-name": "~1.1.4" 273 | }, 274 | "engines": { 275 | "node": ">=7.0.0" 276 | } 277 | }, 278 | "node_modules/color-name": { 279 | "version": "1.1.4", 280 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 281 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 282 | "dev": true 283 | }, 284 | "node_modules/concat-map": { 285 | "version": "0.0.1", 286 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 287 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 288 | "dev": true 289 | }, 290 | "node_modules/cross-spawn": { 291 | "version": "7.0.6", 292 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", 293 | "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", 294 | "dev": true, 295 | "license": "MIT", 296 | "dependencies": { 297 | "path-key": "^3.1.0", 298 | "shebang-command": "^2.0.0", 299 | "which": "^2.0.1" 300 | }, 301 | "engines": { 302 | "node": ">= 8" 303 | } 304 | }, 305 | "node_modules/debug": { 306 | "version": "4.3.4", 307 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 308 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 309 | "dev": true, 310 | "dependencies": { 311 | "ms": "2.1.2" 312 | }, 313 | "engines": { 314 | "node": ">=6.0" 315 | }, 316 | "peerDependenciesMeta": { 317 | "supports-color": { 318 | "optional": true 319 | } 320 | } 321 | }, 322 | "node_modules/deep-is": { 323 | "version": "0.1.4", 324 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", 325 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", 326 | "dev": true 327 | }, 328 | "node_modules/doctrine": { 329 | "version": "3.0.0", 330 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 331 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", 332 | "dev": true, 333 | "dependencies": { 334 | "esutils": "^2.0.2" 335 | }, 336 | "engines": { 337 | "node": ">=6.0.0" 338 | } 339 | }, 340 | "node_modules/escape-string-regexp": { 341 | "version": "4.0.0", 342 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 343 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 344 | "dev": true, 345 | "engines": { 346 | "node": ">=10" 347 | }, 348 | "funding": { 349 | "url": "https://github.com/sponsors/sindresorhus" 350 | } 351 | }, 352 | "node_modules/eslint": { 353 | "version": "8.56.0", 354 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", 355 | "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", 356 | "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", 357 | "dev": true, 358 | "dependencies": { 359 | "@eslint-community/eslint-utils": "^4.2.0", 360 | "@eslint-community/regexpp": "^4.6.1", 361 | "@eslint/eslintrc": "^2.1.4", 362 | "@eslint/js": "8.56.0", 363 | "@humanwhocodes/config-array": "^0.11.13", 364 | "@humanwhocodes/module-importer": "^1.0.1", 365 | "@nodelib/fs.walk": "^1.2.8", 366 | "@ungap/structured-clone": "^1.2.0", 367 | "ajv": "^6.12.4", 368 | "chalk": "^4.0.0", 369 | "cross-spawn": "^7.0.2", 370 | "debug": "^4.3.2", 371 | "doctrine": "^3.0.0", 372 | "escape-string-regexp": "^4.0.0", 373 | "eslint-scope": "^7.2.2", 374 | "eslint-visitor-keys": "^3.4.3", 375 | "espree": "^9.6.1", 376 | "esquery": "^1.4.2", 377 | "esutils": "^2.0.2", 378 | "fast-deep-equal": "^3.1.3", 379 | "file-entry-cache": "^6.0.1", 380 | "find-up": "^5.0.0", 381 | "glob-parent": "^6.0.2", 382 | "globals": "^13.19.0", 383 | "graphemer": "^1.4.0", 384 | "ignore": "^5.2.0", 385 | "imurmurhash": "^0.1.4", 386 | "is-glob": "^4.0.0", 387 | "is-path-inside": "^3.0.3", 388 | "js-yaml": "^4.1.0", 389 | "json-stable-stringify-without-jsonify": "^1.0.1", 390 | "levn": "^0.4.1", 391 | "lodash.merge": "^4.6.2", 392 | "minimatch": "^3.1.2", 393 | "natural-compare": "^1.4.0", 394 | "optionator": "^0.9.3", 395 | "strip-ansi": "^6.0.1", 396 | "text-table": "^0.2.0" 397 | }, 398 | "bin": { 399 | "eslint": "bin/eslint.js" 400 | }, 401 | "engines": { 402 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 403 | }, 404 | "funding": { 405 | "url": "https://opencollective.com/eslint" 406 | } 407 | }, 408 | "node_modules/eslint-scope": { 409 | "version": "7.2.2", 410 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", 411 | "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", 412 | "dev": true, 413 | "dependencies": { 414 | "esrecurse": "^4.3.0", 415 | "estraverse": "^5.2.0" 416 | }, 417 | "engines": { 418 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 419 | }, 420 | "funding": { 421 | "url": "https://opencollective.com/eslint" 422 | } 423 | }, 424 | "node_modules/eslint-visitor-keys": { 425 | "version": "3.4.3", 426 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", 427 | "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", 428 | "dev": true, 429 | "engines": { 430 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 431 | }, 432 | "funding": { 433 | "url": "https://opencollective.com/eslint" 434 | } 435 | }, 436 | "node_modules/espree": { 437 | "version": "9.6.1", 438 | "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", 439 | "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", 440 | "dev": true, 441 | "dependencies": { 442 | "acorn": "^8.9.0", 443 | "acorn-jsx": "^5.3.2", 444 | "eslint-visitor-keys": "^3.4.1" 445 | }, 446 | "engines": { 447 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 448 | }, 449 | "funding": { 450 | "url": "https://opencollective.com/eslint" 451 | } 452 | }, 453 | "node_modules/esquery": { 454 | "version": "1.5.0", 455 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", 456 | "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", 457 | "dev": true, 458 | "dependencies": { 459 | "estraverse": "^5.1.0" 460 | }, 461 | "engines": { 462 | "node": ">=0.10" 463 | } 464 | }, 465 | "node_modules/esrecurse": { 466 | "version": "4.3.0", 467 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 468 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 469 | "dev": true, 470 | "dependencies": { 471 | "estraverse": "^5.2.0" 472 | }, 473 | "engines": { 474 | "node": ">=4.0" 475 | } 476 | }, 477 | "node_modules/estraverse": { 478 | "version": "5.3.0", 479 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 480 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 481 | "dev": true, 482 | "engines": { 483 | "node": ">=4.0" 484 | } 485 | }, 486 | "node_modules/esutils": { 487 | "version": "2.0.3", 488 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 489 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 490 | "dev": true, 491 | "engines": { 492 | "node": ">=0.10.0" 493 | } 494 | }, 495 | "node_modules/fast-deep-equal": { 496 | "version": "3.1.3", 497 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 498 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 499 | "dev": true 500 | }, 501 | "node_modules/fast-json-stable-stringify": { 502 | "version": "2.1.0", 503 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 504 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 505 | "dev": true 506 | }, 507 | "node_modules/fast-levenshtein": { 508 | "version": "2.0.6", 509 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 510 | "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", 511 | "dev": true 512 | }, 513 | "node_modules/fastq": { 514 | "version": "1.17.1", 515 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", 516 | "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", 517 | "dev": true, 518 | "dependencies": { 519 | "reusify": "^1.0.4" 520 | } 521 | }, 522 | "node_modules/file-entry-cache": { 523 | "version": "6.0.1", 524 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", 525 | "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", 526 | "dev": true, 527 | "dependencies": { 528 | "flat-cache": "^3.0.4" 529 | }, 530 | "engines": { 531 | "node": "^10.12.0 || >=12.0.0" 532 | } 533 | }, 534 | "node_modules/find-up": { 535 | "version": "5.0.0", 536 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 537 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 538 | "dev": true, 539 | "dependencies": { 540 | "locate-path": "^6.0.0", 541 | "path-exists": "^4.0.0" 542 | }, 543 | "engines": { 544 | "node": ">=10" 545 | }, 546 | "funding": { 547 | "url": "https://github.com/sponsors/sindresorhus" 548 | } 549 | }, 550 | "node_modules/flat-cache": { 551 | "version": "3.2.0", 552 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", 553 | "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", 554 | "dev": true, 555 | "dependencies": { 556 | "flatted": "^3.2.9", 557 | "keyv": "^4.5.3", 558 | "rimraf": "^3.0.2" 559 | }, 560 | "engines": { 561 | "node": "^10.12.0 || >=12.0.0" 562 | } 563 | }, 564 | "node_modules/flatted": { 565 | "version": "3.2.9", 566 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", 567 | "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", 568 | "dev": true 569 | }, 570 | "node_modules/fs.realpath": { 571 | "version": "1.0.0", 572 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 573 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 574 | "dev": true 575 | }, 576 | "node_modules/glob": { 577 | "version": "7.2.3", 578 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 579 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 580 | "deprecated": "Glob versions prior to v9 are no longer supported", 581 | "dev": true, 582 | "dependencies": { 583 | "fs.realpath": "^1.0.0", 584 | "inflight": "^1.0.4", 585 | "inherits": "2", 586 | "minimatch": "^3.1.1", 587 | "once": "^1.3.0", 588 | "path-is-absolute": "^1.0.0" 589 | }, 590 | "engines": { 591 | "node": "*" 592 | }, 593 | "funding": { 594 | "url": "https://github.com/sponsors/isaacs" 595 | } 596 | }, 597 | "node_modules/glob-parent": { 598 | "version": "6.0.2", 599 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", 600 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", 601 | "dev": true, 602 | "dependencies": { 603 | "is-glob": "^4.0.3" 604 | }, 605 | "engines": { 606 | "node": ">=10.13.0" 607 | } 608 | }, 609 | "node_modules/globals": { 610 | "version": "13.24.0", 611 | "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", 612 | "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", 613 | "dev": true, 614 | "dependencies": { 615 | "type-fest": "^0.20.2" 616 | }, 617 | "engines": { 618 | "node": ">=8" 619 | }, 620 | "funding": { 621 | "url": "https://github.com/sponsors/sindresorhus" 622 | } 623 | }, 624 | "node_modules/graphemer": { 625 | "version": "1.4.0", 626 | "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", 627 | "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", 628 | "dev": true 629 | }, 630 | "node_modules/has-flag": { 631 | "version": "4.0.0", 632 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 633 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 634 | "dev": true, 635 | "engines": { 636 | "node": ">=8" 637 | } 638 | }, 639 | "node_modules/ignore": { 640 | "version": "5.3.1", 641 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", 642 | "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", 643 | "dev": true, 644 | "engines": { 645 | "node": ">= 4" 646 | } 647 | }, 648 | "node_modules/import-fresh": { 649 | "version": "3.3.0", 650 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", 651 | "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", 652 | "dev": true, 653 | "dependencies": { 654 | "parent-module": "^1.0.0", 655 | "resolve-from": "^4.0.0" 656 | }, 657 | "engines": { 658 | "node": ">=6" 659 | }, 660 | "funding": { 661 | "url": "https://github.com/sponsors/sindresorhus" 662 | } 663 | }, 664 | "node_modules/imurmurhash": { 665 | "version": "0.1.4", 666 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 667 | "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", 668 | "dev": true, 669 | "engines": { 670 | "node": ">=0.8.19" 671 | } 672 | }, 673 | "node_modules/inflight": { 674 | "version": "1.0.6", 675 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 676 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 677 | "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", 678 | "dev": true, 679 | "dependencies": { 680 | "once": "^1.3.0", 681 | "wrappy": "1" 682 | } 683 | }, 684 | "node_modules/inherits": { 685 | "version": "2.0.4", 686 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 687 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 688 | "dev": true 689 | }, 690 | "node_modules/is-extglob": { 691 | "version": "2.1.1", 692 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 693 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 694 | "dev": true, 695 | "engines": { 696 | "node": ">=0.10.0" 697 | } 698 | }, 699 | "node_modules/is-glob": { 700 | "version": "4.0.3", 701 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 702 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 703 | "dev": true, 704 | "dependencies": { 705 | "is-extglob": "^2.1.1" 706 | }, 707 | "engines": { 708 | "node": ">=0.10.0" 709 | } 710 | }, 711 | "node_modules/is-path-inside": { 712 | "version": "3.0.3", 713 | "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", 714 | "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", 715 | "dev": true, 716 | "engines": { 717 | "node": ">=8" 718 | } 719 | }, 720 | "node_modules/isexe": { 721 | "version": "2.0.0", 722 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 723 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 724 | "dev": true 725 | }, 726 | "node_modules/js-yaml": { 727 | "version": "4.1.0", 728 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 729 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 730 | "dev": true, 731 | "dependencies": { 732 | "argparse": "^2.0.1" 733 | }, 734 | "bin": { 735 | "js-yaml": "bin/js-yaml.js" 736 | } 737 | }, 738 | "node_modules/json-buffer": { 739 | "version": "3.0.1", 740 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", 741 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", 742 | "dev": true 743 | }, 744 | "node_modules/json-schema-traverse": { 745 | "version": "0.4.1", 746 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 747 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 748 | "dev": true 749 | }, 750 | "node_modules/json-stable-stringify-without-jsonify": { 751 | "version": "1.0.1", 752 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 753 | "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", 754 | "dev": true 755 | }, 756 | "node_modules/keyv": { 757 | "version": "4.5.4", 758 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", 759 | "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", 760 | "dev": true, 761 | "dependencies": { 762 | "json-buffer": "3.0.1" 763 | } 764 | }, 765 | "node_modules/levn": { 766 | "version": "0.4.1", 767 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 768 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 769 | "dev": true, 770 | "dependencies": { 771 | "prelude-ls": "^1.2.1", 772 | "type-check": "~0.4.0" 773 | }, 774 | "engines": { 775 | "node": ">= 0.8.0" 776 | } 777 | }, 778 | "node_modules/locate-path": { 779 | "version": "6.0.0", 780 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 781 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 782 | "dev": true, 783 | "dependencies": { 784 | "p-locate": "^5.0.0" 785 | }, 786 | "engines": { 787 | "node": ">=10" 788 | }, 789 | "funding": { 790 | "url": "https://github.com/sponsors/sindresorhus" 791 | } 792 | }, 793 | "node_modules/lodash.merge": { 794 | "version": "4.6.2", 795 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", 796 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", 797 | "dev": true 798 | }, 799 | "node_modules/minimatch": { 800 | "version": "3.1.2", 801 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 802 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 803 | "dev": true, 804 | "dependencies": { 805 | "brace-expansion": "^1.1.7" 806 | }, 807 | "engines": { 808 | "node": "*" 809 | } 810 | }, 811 | "node_modules/ms": { 812 | "version": "2.1.2", 813 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 814 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 815 | "dev": true 816 | }, 817 | "node_modules/natural-compare": { 818 | "version": "1.4.0", 819 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 820 | "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", 821 | "dev": true 822 | }, 823 | "node_modules/once": { 824 | "version": "1.4.0", 825 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 826 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 827 | "dev": true, 828 | "dependencies": { 829 | "wrappy": "1" 830 | } 831 | }, 832 | "node_modules/optionator": { 833 | "version": "0.9.3", 834 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", 835 | "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", 836 | "dev": true, 837 | "dependencies": { 838 | "@aashutoshrathi/word-wrap": "^1.2.3", 839 | "deep-is": "^0.1.3", 840 | "fast-levenshtein": "^2.0.6", 841 | "levn": "^0.4.1", 842 | "prelude-ls": "^1.2.1", 843 | "type-check": "^0.4.0" 844 | }, 845 | "engines": { 846 | "node": ">= 0.8.0" 847 | } 848 | }, 849 | "node_modules/p-limit": { 850 | "version": "3.1.0", 851 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 852 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 853 | "dev": true, 854 | "dependencies": { 855 | "yocto-queue": "^0.1.0" 856 | }, 857 | "engines": { 858 | "node": ">=10" 859 | }, 860 | "funding": { 861 | "url": "https://github.com/sponsors/sindresorhus" 862 | } 863 | }, 864 | "node_modules/p-locate": { 865 | "version": "5.0.0", 866 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 867 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 868 | "dev": true, 869 | "dependencies": { 870 | "p-limit": "^3.0.2" 871 | }, 872 | "engines": { 873 | "node": ">=10" 874 | }, 875 | "funding": { 876 | "url": "https://github.com/sponsors/sindresorhus" 877 | } 878 | }, 879 | "node_modules/parent-module": { 880 | "version": "1.0.1", 881 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 882 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 883 | "dev": true, 884 | "dependencies": { 885 | "callsites": "^3.0.0" 886 | }, 887 | "engines": { 888 | "node": ">=6" 889 | } 890 | }, 891 | "node_modules/path-exists": { 892 | "version": "4.0.0", 893 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 894 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 895 | "dev": true, 896 | "engines": { 897 | "node": ">=8" 898 | } 899 | }, 900 | "node_modules/path-is-absolute": { 901 | "version": "1.0.1", 902 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 903 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 904 | "dev": true, 905 | "engines": { 906 | "node": ">=0.10.0" 907 | } 908 | }, 909 | "node_modules/path-key": { 910 | "version": "3.1.1", 911 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 912 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 913 | "dev": true, 914 | "engines": { 915 | "node": ">=8" 916 | } 917 | }, 918 | "node_modules/prelude-ls": { 919 | "version": "1.2.1", 920 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 921 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 922 | "dev": true, 923 | "engines": { 924 | "node": ">= 0.8.0" 925 | } 926 | }, 927 | "node_modules/prettier": { 928 | "version": "2.8.3", 929 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz", 930 | "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==", 931 | "dev": true, 932 | "bin": { 933 | "prettier": "bin-prettier.js" 934 | }, 935 | "engines": { 936 | "node": ">=10.13.0" 937 | }, 938 | "funding": { 939 | "url": "https://github.com/prettier/prettier?sponsor=1" 940 | } 941 | }, 942 | "node_modules/punycode": { 943 | "version": "2.3.1", 944 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 945 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 946 | "dev": true, 947 | "engines": { 948 | "node": ">=6" 949 | } 950 | }, 951 | "node_modules/queue-microtask": { 952 | "version": "1.2.3", 953 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 954 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 955 | "dev": true, 956 | "funding": [ 957 | { 958 | "type": "github", 959 | "url": "https://github.com/sponsors/feross" 960 | }, 961 | { 962 | "type": "patreon", 963 | "url": "https://www.patreon.com/feross" 964 | }, 965 | { 966 | "type": "consulting", 967 | "url": "https://feross.org/support" 968 | } 969 | ] 970 | }, 971 | "node_modules/resolve-from": { 972 | "version": "4.0.0", 973 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 974 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 975 | "dev": true, 976 | "engines": { 977 | "node": ">=4" 978 | } 979 | }, 980 | "node_modules/reusify": { 981 | "version": "1.0.4", 982 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 983 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", 984 | "dev": true, 985 | "engines": { 986 | "iojs": ">=1.0.0", 987 | "node": ">=0.10.0" 988 | } 989 | }, 990 | "node_modules/rimraf": { 991 | "version": "3.0.2", 992 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", 993 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", 994 | "deprecated": "Rimraf versions prior to v4 are no longer supported", 995 | "dev": true, 996 | "dependencies": { 997 | "glob": "^7.1.3" 998 | }, 999 | "bin": { 1000 | "rimraf": "bin.js" 1001 | }, 1002 | "funding": { 1003 | "url": "https://github.com/sponsors/isaacs" 1004 | } 1005 | }, 1006 | "node_modules/run-parallel": { 1007 | "version": "1.2.0", 1008 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 1009 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 1010 | "dev": true, 1011 | "funding": [ 1012 | { 1013 | "type": "github", 1014 | "url": "https://github.com/sponsors/feross" 1015 | }, 1016 | { 1017 | "type": "patreon", 1018 | "url": "https://www.patreon.com/feross" 1019 | }, 1020 | { 1021 | "type": "consulting", 1022 | "url": "https://feross.org/support" 1023 | } 1024 | ], 1025 | "dependencies": { 1026 | "queue-microtask": "^1.2.2" 1027 | } 1028 | }, 1029 | "node_modules/shebang-command": { 1030 | "version": "2.0.0", 1031 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 1032 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 1033 | "dev": true, 1034 | "dependencies": { 1035 | "shebang-regex": "^3.0.0" 1036 | }, 1037 | "engines": { 1038 | "node": ">=8" 1039 | } 1040 | }, 1041 | "node_modules/shebang-regex": { 1042 | "version": "3.0.0", 1043 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 1044 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 1045 | "dev": true, 1046 | "engines": { 1047 | "node": ">=8" 1048 | } 1049 | }, 1050 | "node_modules/strip-ansi": { 1051 | "version": "6.0.1", 1052 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 1053 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 1054 | "dev": true, 1055 | "dependencies": { 1056 | "ansi-regex": "^5.0.1" 1057 | }, 1058 | "engines": { 1059 | "node": ">=8" 1060 | } 1061 | }, 1062 | "node_modules/strip-json-comments": { 1063 | "version": "3.1.1", 1064 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 1065 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 1066 | "dev": true, 1067 | "engines": { 1068 | "node": ">=8" 1069 | }, 1070 | "funding": { 1071 | "url": "https://github.com/sponsors/sindresorhus" 1072 | } 1073 | }, 1074 | "node_modules/supports-color": { 1075 | "version": "7.2.0", 1076 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1077 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1078 | "dev": true, 1079 | "dependencies": { 1080 | "has-flag": "^4.0.0" 1081 | }, 1082 | "engines": { 1083 | "node": ">=8" 1084 | } 1085 | }, 1086 | "node_modules/text-table": { 1087 | "version": "0.2.0", 1088 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 1089 | "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", 1090 | "dev": true 1091 | }, 1092 | "node_modules/type-check": { 1093 | "version": "0.4.0", 1094 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 1095 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 1096 | "dev": true, 1097 | "dependencies": { 1098 | "prelude-ls": "^1.2.1" 1099 | }, 1100 | "engines": { 1101 | "node": ">= 0.8.0" 1102 | } 1103 | }, 1104 | "node_modules/type-fest": { 1105 | "version": "0.20.2", 1106 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", 1107 | "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", 1108 | "dev": true, 1109 | "engines": { 1110 | "node": ">=10" 1111 | }, 1112 | "funding": { 1113 | "url": "https://github.com/sponsors/sindresorhus" 1114 | } 1115 | }, 1116 | "node_modules/typescript": { 1117 | "version": "5.8.2", 1118 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", 1119 | "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", 1120 | "dev": true, 1121 | "license": "Apache-2.0", 1122 | "bin": { 1123 | "tsc": "bin/tsc", 1124 | "tsserver": "bin/tsserver" 1125 | }, 1126 | "engines": { 1127 | "node": ">=14.17" 1128 | } 1129 | }, 1130 | "node_modules/uri-js": { 1131 | "version": "4.4.1", 1132 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 1133 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 1134 | "dev": true, 1135 | "dependencies": { 1136 | "punycode": "^2.1.0" 1137 | } 1138 | }, 1139 | "node_modules/which": { 1140 | "version": "2.0.2", 1141 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 1142 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 1143 | "dev": true, 1144 | "dependencies": { 1145 | "isexe": "^2.0.0" 1146 | }, 1147 | "bin": { 1148 | "node-which": "bin/node-which" 1149 | }, 1150 | "engines": { 1151 | "node": ">= 8" 1152 | } 1153 | }, 1154 | "node_modules/wrappy": { 1155 | "version": "1.0.2", 1156 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1157 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 1158 | "dev": true 1159 | }, 1160 | "node_modules/yocto-queue": { 1161 | "version": "0.1.0", 1162 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 1163 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 1164 | "dev": true, 1165 | "engines": { 1166 | "node": ">=10" 1167 | }, 1168 | "funding": { 1169 | "url": "https://github.com/sponsors/sindresorhus" 1170 | } 1171 | } 1172 | } 1173 | } 1174 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "inter", 3 | "version": "2.2.4", 4 | "type": "module", 5 | "description": "The javascript framework to build highly interactive front-end web applications.", 6 | "author": "Denis Power", 7 | "license": "MIT", 8 | "jsdelivr": "inter.min.js", 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/interjs/inter.git" 12 | }, 13 | "homepage": "https://interjs.github.io", 14 | "bugs": { 15 | "url": "https://github.com/interjs/inter/issues" 16 | }, 17 | "main": "inter.js", 18 | "keywords": [ 19 | "interjs", 20 | "inter" 21 | ], 22 | "devDependencies": { 23 | "eslint": "^8.56.0", 24 | "prettier": "^2.8.3", 25 | "typescript": "^5.8.2" 26 | }, 27 | "scripts": { 28 | "lint": "eslint ./", 29 | "prettify": "prettier --write ./", 30 | "build": "node builder" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /prettierrc.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /types/ajax.d.ts: -------------------------------------------------------------------------------- 1 | interface backendInterface { 2 | new (): backendInstance; 3 | } 4 | 5 | interface backendInstance { 6 | request(options: ajaxOptions): ajaxReactorInterface; 7 | } 8 | 9 | /*** 10 | * These are the most commonly used HTTP request methods, the others 11 | * ones are not supported in Ajax request. 12 | * 13 | */ 14 | 15 | type httpRequestMethods = 16 | | "GET" 17 | | "POST" 18 | | "PUT" 19 | | "HEAD" 20 | | "DELETE" 21 | | "OPTIONS" 22 | | "PATCH"; 23 | 24 | interface ajaxOptions { 25 | type: httpRequestMethods; 26 | path: string; 27 | headers?: object; 28 | timeout?: number; 29 | events?: { 30 | onprogress?(args: { readonly progress: number; abort(): void }): void; 31 | onabort?(): void; 32 | ontimeout?(): void; 33 | }; 34 | security?: { 35 | username: string; 36 | password: string; 37 | }; 38 | body?: any; 39 | } 40 | 41 | type ajaxResponseCallBack = (response: ajaxResponse) => void; 42 | interface ajaxReactorInterface { 43 | okay(callBack: ajaxResponseCallBack): void; 44 | error(callBack: ajaxResponseCallBack): void; 45 | response( 46 | okayCallBack: ajaxResponseCallBack, 47 | errorCallBack: ajaxResponseCallBack 48 | ): void; 49 | } 50 | 51 | interface ajaxResponse { 52 | readonly data: any; 53 | readonly status: number; 54 | readonly statusText: string; 55 | readonly headers: object; 56 | isObj(): boolean; 57 | } 58 | 59 | export declare var Backend: backendInterface; 60 | -------------------------------------------------------------------------------- /types/ref.d.ts: -------------------------------------------------------------------------------- 1 | type refValueType = string | number | null | void; 2 | type refMethods = { 3 | setRefs?: { 4 | [ref in keyof T]?: refValueType; 5 | }; 6 | observe( 7 | ref: string, 8 | value: refValueType, 9 | previousValue: refValueType 10 | ): boolean; 11 | }; 12 | 13 | interface refOptionsInterface { 14 | in: string; 15 | data: T; 16 | } 17 | 18 | export declare function Ref( 19 | options: refOptionsInterface 20 | ): refMethods & T; 21 | -------------------------------------------------------------------------------- /types/renderif.d.ts: -------------------------------------------------------------------------------- 1 | type refValueType = boolean; 2 | type renderIfMethods = { 3 | setConds: { 4 | [prop in keyof T]?: refValueType; 5 | }; 6 | observe(ref: keyof T, value: refValueType): boolean; 7 | }; 8 | 9 | interface renderIfOptionsInterface { 10 | in: string; 11 | data: { 12 | [prop: string]: boolean; 13 | } & T; 14 | } 15 | 16 | export declare function renderIf( 17 | options: renderIfOptionsInterface 18 | ): renderIfMethods & T; 19 | -------------------------------------------------------------------------------- /types/renderlist.d.ts: -------------------------------------------------------------------------------- 1 | import { templateReturn } from "./template"; 2 | 3 | interface renderListOptionsInterface { 4 | in: string; 5 | each: T; 6 | optimize?: boolean; 7 | do: doOptionsType; 8 | } 9 | 10 | type universalReactorPropsType = { 11 | obserseve(callBack: (reactor: T) => void): boolean; 12 | setEach: eachTypes; 13 | }; 14 | 15 | interface ArrayReactor extends universalReactorPropsType { 16 | addItems(items: any[], index?: number): boolean; 17 | } 18 | 19 | interface ObjectReactor extends universalReactorPropsType { 20 | setProps?: T; 21 | } 22 | 23 | interface objectProps { 24 | setProps?: T; 25 | defineProps?: object; 26 | deleteProps?: Array; 27 | } 28 | 29 | type eachTypes = any[] | Object | Set | Map | number; 30 | type PropValueType = T[keyof T]; 31 | type doOptionsType = T extends any[] 32 | ? ( 33 | this: returnReactorType, 34 | item: Item, 35 | index: number, 36 | reactor: T 37 | ) => templateReturn 38 | : T extends object 39 | ? ( 40 | this: returnReactorType, 41 | prop: string, 42 | value: PropValueType, 43 | reactor: returnReactorType 44 | ) => templateReturn 45 | : templateReturn; 46 | type Item = T[any] extends object ? T[any] & objectProps : T[any]; 47 | type returnReactorType = T extends any[] 48 | ? Item[] & ArrayReactor 49 | : T extends object 50 | ? T & ObjectReactor 51 | : null; 52 | 53 | export declare function renderList( 54 | renderListOption: renderListOptionsInterface 55 | ): returnReactorType; 56 | -------------------------------------------------------------------------------- /types/template.d.ts: -------------------------------------------------------------------------------- 1 | type HTMLTags = keyof HTMLElementTagNameMap; 2 | type textTypes = string | number | null | void; 3 | interface templateOptionsInterface { 4 | tag: HTMLTags | ((this: void) => HTMLTags); 5 | text?: textTypes | ((this: void) => textTypes); 6 | renderIf?: boolean; 7 | events?: { 8 | [event in keyof GlobalEventHandlers]?: ( 9 | this: Document, 10 | event: Event 11 | ) => void; 12 | }; 13 | attrs?: object; 14 | styles?: { 15 | [style in keyof CSSStyleDeclaration]?: CSSStyleDeclaration[style]; 16 | }; 17 | children?: templateOptionsInterface[]; 18 | } 19 | 20 | export interface templateReturn { 21 | element: templateOptionsInterface; 22 | } 23 | 24 | export declare function template( 25 | options: templateOptionsInterface 26 | ): templateReturn; 27 | -------------------------------------------------------------------------------- /types/toattrs.d.ts: -------------------------------------------------------------------------------- 1 | type attrType = string | number | null; 2 | type attrs = T[keyof T]; 3 | interface toAttrsMethods { 4 | setAttrs?: T[keyof T]; 5 | observe?(attr: string, value: attrType): boolean; 6 | } 7 | 8 | interface toAttrsOptionsInterface { 9 | in: string; 10 | data: T; 11 | } 12 | 13 | export declare function toAttrs( 14 | options: toAttrsOptionsInterface 15 | ): { 16 | [prop in keyof T]: toAttrsMethods & T[prop]; 17 | }; 18 | --------------------------------------------------------------------------------