snabbdom.cjs.js 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', { value: true });
  3. function createElement(tagName, options) {
  4. return document.createElement(tagName, options);
  5. }
  6. function createElementNS(namespaceURI, qualifiedName, options) {
  7. return document.createElementNS(namespaceURI, qualifiedName, options);
  8. }
  9. function createDocumentFragment() {
  10. return parseFragment(document.createDocumentFragment());
  11. }
  12. function createTextNode(text) {
  13. return document.createTextNode(text);
  14. }
  15. function createComment(text) {
  16. return document.createComment(text);
  17. }
  18. function insertBefore(parentNode, newNode, referenceNode) {
  19. if (isDocumentFragment$1(parentNode)) {
  20. let node = parentNode;
  21. while (node && isDocumentFragment$1(node)) {
  22. const fragment = parseFragment(node);
  23. node = fragment.parent;
  24. }
  25. parentNode = node !== null && node !== void 0 ? node : parentNode;
  26. }
  27. if (isDocumentFragment$1(newNode)) {
  28. newNode = parseFragment(newNode, parentNode);
  29. }
  30. if (referenceNode && isDocumentFragment$1(referenceNode)) {
  31. referenceNode = parseFragment(referenceNode).firstChildNode;
  32. }
  33. parentNode.insertBefore(newNode, referenceNode);
  34. }
  35. function removeChild(node, child) {
  36. node.removeChild(child);
  37. }
  38. function appendChild(node, child) {
  39. if (isDocumentFragment$1(child)) {
  40. child = parseFragment(child, node);
  41. }
  42. node.appendChild(child);
  43. }
  44. function parentNode(node) {
  45. if (isDocumentFragment$1(node)) {
  46. while (node && isDocumentFragment$1(node)) {
  47. const fragment = parseFragment(node);
  48. node = fragment.parent;
  49. }
  50. return node !== null && node !== void 0 ? node : null;
  51. }
  52. return node.parentNode;
  53. }
  54. function nextSibling(node) {
  55. var _a;
  56. if (isDocumentFragment$1(node)) {
  57. const fragment = parseFragment(node);
  58. const parent = parentNode(fragment);
  59. if (parent && fragment.lastChildNode) {
  60. const children = Array.from(parent.childNodes);
  61. const index = children.indexOf(fragment.lastChildNode);
  62. return (_a = children[index + 1]) !== null && _a !== void 0 ? _a : null;
  63. }
  64. return null;
  65. }
  66. return node.nextSibling;
  67. }
  68. function tagName(elm) {
  69. return elm.tagName;
  70. }
  71. function setTextContent(node, text) {
  72. node.textContent = text;
  73. }
  74. function getTextContent(node) {
  75. return node.textContent;
  76. }
  77. function isElement$1(node) {
  78. return node.nodeType === 1;
  79. }
  80. function isText(node) {
  81. return node.nodeType === 3;
  82. }
  83. function isComment(node) {
  84. return node.nodeType === 8;
  85. }
  86. function isDocumentFragment$1(node) {
  87. return node.nodeType === 11;
  88. }
  89. function parseFragment(fragmentNode, parentNode) {
  90. var _a, _b, _c;
  91. const fragment = fragmentNode;
  92. (_a = fragment.parent) !== null && _a !== void 0 ? _a : (fragment.parent = parentNode !== null && parentNode !== void 0 ? parentNode : null);
  93. (_b = fragment.firstChildNode) !== null && _b !== void 0 ? _b : (fragment.firstChildNode = fragmentNode.firstChild);
  94. (_c = fragment.lastChildNode) !== null && _c !== void 0 ? _c : (fragment.lastChildNode = fragmentNode.lastChild);
  95. return fragment;
  96. }
  97. const htmlDomApi = {
  98. createElement,
  99. createElementNS,
  100. createTextNode,
  101. createDocumentFragment,
  102. createComment,
  103. insertBefore,
  104. removeChild,
  105. appendChild,
  106. parentNode,
  107. nextSibling,
  108. tagName,
  109. setTextContent,
  110. getTextContent,
  111. isElement: isElement$1,
  112. isText,
  113. isComment,
  114. isDocumentFragment: isDocumentFragment$1,
  115. };
  116. function vnode(sel, data, children, text, elm) {
  117. const key = data === undefined ? undefined : data.key;
  118. return { sel, data, children, text, elm, key };
  119. }
  120. const array = Array.isArray;
  121. function primitive(s) {
  122. return (typeof s === "string" ||
  123. typeof s === "number" ||
  124. s instanceof String ||
  125. s instanceof Number);
  126. }
  127. function isUndef(s) {
  128. return s === undefined;
  129. }
  130. function isDef(s) {
  131. return s !== undefined;
  132. }
  133. const emptyNode = vnode("", {}, [], undefined, undefined);
  134. function sameVnode(vnode1, vnode2) {
  135. var _a, _b;
  136. const isSameKey = vnode1.key === vnode2.key;
  137. const isSameIs = ((_a = vnode1.data) === null || _a === void 0 ? void 0 : _a.is) === ((_b = vnode2.data) === null || _b === void 0 ? void 0 : _b.is);
  138. const isSameSel = vnode1.sel === vnode2.sel;
  139. const isSameTextOrFragment = !vnode1.sel && vnode1.sel === vnode2.sel
  140. ? typeof vnode1.text === typeof vnode2.text
  141. : true;
  142. return isSameSel && isSameKey && isSameIs && isSameTextOrFragment;
  143. }
  144. /**
  145. * @todo Remove this function when the document fragment is considered stable.
  146. */
  147. function documentFragmentIsNotSupported() {
  148. throw new Error("The document fragment is not supported on this platform.");
  149. }
  150. function isElement(api, vnode) {
  151. return api.isElement(vnode);
  152. }
  153. function isDocumentFragment(api, vnode) {
  154. return api.isDocumentFragment(vnode);
  155. }
  156. function createKeyToOldIdx(children, beginIdx, endIdx) {
  157. var _a;
  158. const map = {};
  159. for (let i = beginIdx; i <= endIdx; ++i) {
  160. const key = (_a = children[i]) === null || _a === void 0 ? void 0 : _a.key;
  161. if (key !== undefined) {
  162. map[key] = i;
  163. }
  164. }
  165. return map;
  166. }
  167. const hooks = [
  168. "create",
  169. "update",
  170. "remove",
  171. "destroy",
  172. "pre",
  173. "post",
  174. ];
  175. function init$1(modules, domApi, options) {
  176. const cbs = {
  177. create: [],
  178. update: [],
  179. remove: [],
  180. destroy: [],
  181. pre: [],
  182. post: [],
  183. };
  184. const api = domApi !== undefined ? domApi : htmlDomApi;
  185. for (const hook of hooks) {
  186. for (const module of modules) {
  187. const currentHook = module[hook];
  188. if (currentHook !== undefined) {
  189. cbs[hook].push(currentHook);
  190. }
  191. }
  192. }
  193. function emptyNodeAt(elm) {
  194. const id = elm.id ? "#" + elm.id : "";
  195. // elm.className doesn't return a string when elm is an SVG element inside a shadowRoot.
  196. // https://stackoverflow.com/questions/29454340/detecting-classname-of-svganimatedstring
  197. const classes = elm.getAttribute("class");
  198. const c = classes ? "." + classes.split(" ").join(".") : "";
  199. return vnode(api.tagName(elm).toLowerCase() + id + c, {}, [], undefined, elm);
  200. }
  201. function emptyDocumentFragmentAt(frag) {
  202. return vnode(undefined, {}, [], undefined, frag);
  203. }
  204. function createRmCb(childElm, listeners) {
  205. return function rmCb() {
  206. if (--listeners === 0) {
  207. const parent = api.parentNode(childElm);
  208. api.removeChild(parent, childElm);
  209. }
  210. };
  211. }
  212. function createElm(vnode, insertedVnodeQueue) {
  213. var _a, _b, _c, _d;
  214. let i;
  215. let data = vnode.data;
  216. if (data !== undefined) {
  217. const init = (_a = data.hook) === null || _a === void 0 ? void 0 : _a.init;
  218. if (isDef(init)) {
  219. init(vnode);
  220. data = vnode.data;
  221. }
  222. }
  223. const children = vnode.children;
  224. const sel = vnode.sel;
  225. if (sel === "!") {
  226. if (isUndef(vnode.text)) {
  227. vnode.text = "";
  228. }
  229. vnode.elm = api.createComment(vnode.text);
  230. }
  231. else if (sel !== undefined) {
  232. // Parse selector
  233. const hashIdx = sel.indexOf("#");
  234. const dotIdx = sel.indexOf(".", hashIdx);
  235. const hash = hashIdx > 0 ? hashIdx : sel.length;
  236. const dot = dotIdx > 0 ? dotIdx : sel.length;
  237. const tag = hashIdx !== -1 || dotIdx !== -1
  238. ? sel.slice(0, Math.min(hash, dot))
  239. : sel;
  240. const elm = (vnode.elm =
  241. isDef(data) && isDef((i = data.ns))
  242. ? api.createElementNS(i, tag, data)
  243. : api.createElement(tag, data));
  244. if (hash < dot)
  245. elm.setAttribute("id", sel.slice(hash + 1, dot));
  246. if (dotIdx > 0)
  247. elm.setAttribute("class", sel.slice(dot + 1).replace(/\./g, " "));
  248. for (i = 0; i < cbs.create.length; ++i)
  249. cbs.create[i](emptyNode, vnode);
  250. if (array(children)) {
  251. for (i = 0; i < children.length; ++i) {
  252. const ch = children[i];
  253. if (ch != null) {
  254. api.appendChild(elm, createElm(ch, insertedVnodeQueue));
  255. }
  256. }
  257. }
  258. else if (primitive(vnode.text)) {
  259. api.appendChild(elm, api.createTextNode(vnode.text));
  260. }
  261. const hook = vnode.data.hook;
  262. if (isDef(hook)) {
  263. (_b = hook.create) === null || _b === void 0 ? void 0 : _b.call(hook, emptyNode, vnode);
  264. if (hook.insert) {
  265. insertedVnodeQueue.push(vnode);
  266. }
  267. }
  268. }
  269. else if (((_c = options === null || options === void 0 ? void 0 : options.experimental) === null || _c === void 0 ? void 0 : _c.fragments) && vnode.children) {
  270. vnode.elm = ((_d = api.createDocumentFragment) !== null && _d !== void 0 ? _d : documentFragmentIsNotSupported)();
  271. for (i = 0; i < cbs.create.length; ++i)
  272. cbs.create[i](emptyNode, vnode);
  273. for (i = 0; i < vnode.children.length; ++i) {
  274. const ch = vnode.children[i];
  275. if (ch != null) {
  276. api.appendChild(vnode.elm, createElm(ch, insertedVnodeQueue));
  277. }
  278. }
  279. }
  280. else {
  281. vnode.elm = api.createTextNode(vnode.text);
  282. }
  283. return vnode.elm;
  284. }
  285. function addVnodes(parentElm, before, vnodes, startIdx, endIdx, insertedVnodeQueue) {
  286. for (; startIdx <= endIdx; ++startIdx) {
  287. const ch = vnodes[startIdx];
  288. if (ch != null) {
  289. api.insertBefore(parentElm, createElm(ch, insertedVnodeQueue), before);
  290. }
  291. }
  292. }
  293. function invokeDestroyHook(vnode) {
  294. var _a, _b;
  295. const data = vnode.data;
  296. if (data !== undefined) {
  297. (_b = (_a = data === null || data === void 0 ? void 0 : data.hook) === null || _a === void 0 ? void 0 : _a.destroy) === null || _b === void 0 ? void 0 : _b.call(_a, vnode);
  298. for (let i = 0; i < cbs.destroy.length; ++i)
  299. cbs.destroy[i](vnode);
  300. if (vnode.children !== undefined) {
  301. for (let j = 0; j < vnode.children.length; ++j) {
  302. const child = vnode.children[j];
  303. if (child != null && typeof child !== "string") {
  304. invokeDestroyHook(child);
  305. }
  306. }
  307. }
  308. }
  309. }
  310. function removeVnodes(parentElm, vnodes, startIdx, endIdx) {
  311. var _a, _b;
  312. for (; startIdx <= endIdx; ++startIdx) {
  313. let listeners;
  314. let rm;
  315. const ch = vnodes[startIdx];
  316. if (ch != null) {
  317. if (isDef(ch.sel)) {
  318. invokeDestroyHook(ch);
  319. listeners = cbs.remove.length + 1;
  320. rm = createRmCb(ch.elm, listeners);
  321. for (let i = 0; i < cbs.remove.length; ++i)
  322. cbs.remove[i](ch, rm);
  323. const removeHook = (_b = (_a = ch === null || ch === void 0 ? void 0 : ch.data) === null || _a === void 0 ? void 0 : _a.hook) === null || _b === void 0 ? void 0 : _b.remove;
  324. if (isDef(removeHook)) {
  325. removeHook(ch, rm);
  326. }
  327. else {
  328. rm();
  329. }
  330. }
  331. else if (ch.children) {
  332. // Fragment node
  333. invokeDestroyHook(ch);
  334. removeVnodes(parentElm, ch.children, 0, ch.children.length - 1);
  335. }
  336. else {
  337. // Text node
  338. api.removeChild(parentElm, ch.elm);
  339. }
  340. }
  341. }
  342. }
  343. function updateChildren(parentElm, oldCh, newCh, insertedVnodeQueue) {
  344. let oldStartIdx = 0;
  345. let newStartIdx = 0;
  346. let oldEndIdx = oldCh.length - 1;
  347. let oldStartVnode = oldCh[0];
  348. let oldEndVnode = oldCh[oldEndIdx];
  349. let newEndIdx = newCh.length - 1;
  350. let newStartVnode = newCh[0];
  351. let newEndVnode = newCh[newEndIdx];
  352. let oldKeyToIdx;
  353. let idxInOld;
  354. let elmToMove;
  355. let before;
  356. while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
  357. if (oldStartVnode == null) {
  358. oldStartVnode = oldCh[++oldStartIdx]; // Vnode might have been moved left
  359. }
  360. else if (oldEndVnode == null) {
  361. oldEndVnode = oldCh[--oldEndIdx];
  362. }
  363. else if (newStartVnode == null) {
  364. newStartVnode = newCh[++newStartIdx];
  365. }
  366. else if (newEndVnode == null) {
  367. newEndVnode = newCh[--newEndIdx];
  368. }
  369. else if (sameVnode(oldStartVnode, newStartVnode)) {
  370. patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue);
  371. oldStartVnode = oldCh[++oldStartIdx];
  372. newStartVnode = newCh[++newStartIdx];
  373. }
  374. else if (sameVnode(oldEndVnode, newEndVnode)) {
  375. patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue);
  376. oldEndVnode = oldCh[--oldEndIdx];
  377. newEndVnode = newCh[--newEndIdx];
  378. }
  379. else if (sameVnode(oldStartVnode, newEndVnode)) {
  380. // Vnode moved right
  381. patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue);
  382. api.insertBefore(parentElm, oldStartVnode.elm, api.nextSibling(oldEndVnode.elm));
  383. oldStartVnode = oldCh[++oldStartIdx];
  384. newEndVnode = newCh[--newEndIdx];
  385. }
  386. else if (sameVnode(oldEndVnode, newStartVnode)) {
  387. // Vnode moved left
  388. patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue);
  389. api.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm);
  390. oldEndVnode = oldCh[--oldEndIdx];
  391. newStartVnode = newCh[++newStartIdx];
  392. }
  393. else {
  394. if (oldKeyToIdx === undefined) {
  395. oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx);
  396. }
  397. idxInOld = oldKeyToIdx[newStartVnode.key];
  398. if (isUndef(idxInOld)) {
  399. // New element
  400. api.insertBefore(parentElm, createElm(newStartVnode, insertedVnodeQueue), oldStartVnode.elm);
  401. }
  402. else {
  403. elmToMove = oldCh[idxInOld];
  404. if (elmToMove.sel !== newStartVnode.sel) {
  405. api.insertBefore(parentElm, createElm(newStartVnode, insertedVnodeQueue), oldStartVnode.elm);
  406. }
  407. else {
  408. patchVnode(elmToMove, newStartVnode, insertedVnodeQueue);
  409. oldCh[idxInOld] = undefined;
  410. api.insertBefore(parentElm, elmToMove.elm, oldStartVnode.elm);
  411. }
  412. }
  413. newStartVnode = newCh[++newStartIdx];
  414. }
  415. }
  416. if (newStartIdx <= newEndIdx) {
  417. before = newCh[newEndIdx + 1] == null ? null : newCh[newEndIdx + 1].elm;
  418. addVnodes(parentElm, before, newCh, newStartIdx, newEndIdx, insertedVnodeQueue);
  419. }
  420. if (oldStartIdx <= oldEndIdx) {
  421. removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx);
  422. }
  423. }
  424. function patchVnode(oldVnode, vnode, insertedVnodeQueue) {
  425. var _a, _b, _c, _d, _e, _f, _g, _h;
  426. const hook = (_a = vnode.data) === null || _a === void 0 ? void 0 : _a.hook;
  427. (_b = hook === null || hook === void 0 ? void 0 : hook.prepatch) === null || _b === void 0 ? void 0 : _b.call(hook, oldVnode, vnode);
  428. const elm = (vnode.elm = oldVnode.elm);
  429. if (oldVnode === vnode)
  430. return;
  431. if (vnode.data !== undefined ||
  432. (isDef(vnode.text) && vnode.text !== oldVnode.text)) {
  433. (_c = vnode.data) !== null && _c !== void 0 ? _c : (vnode.data = {});
  434. (_d = oldVnode.data) !== null && _d !== void 0 ? _d : (oldVnode.data = {});
  435. for (let i = 0; i < cbs.update.length; ++i)
  436. cbs.update[i](oldVnode, vnode);
  437. (_g = (_f = (_e = vnode.data) === null || _e === void 0 ? void 0 : _e.hook) === null || _f === void 0 ? void 0 : _f.update) === null || _g === void 0 ? void 0 : _g.call(_f, oldVnode, vnode);
  438. }
  439. const oldCh = oldVnode.children;
  440. const ch = vnode.children;
  441. if (isUndef(vnode.text)) {
  442. if (isDef(oldCh) && isDef(ch)) {
  443. if (oldCh !== ch)
  444. updateChildren(elm, oldCh, ch, insertedVnodeQueue);
  445. }
  446. else if (isDef(ch)) {
  447. if (isDef(oldVnode.text))
  448. api.setTextContent(elm, "");
  449. addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue);
  450. }
  451. else if (isDef(oldCh)) {
  452. removeVnodes(elm, oldCh, 0, oldCh.length - 1);
  453. }
  454. else if (isDef(oldVnode.text)) {
  455. api.setTextContent(elm, "");
  456. }
  457. }
  458. else if (oldVnode.text !== vnode.text) {
  459. if (isDef(oldCh)) {
  460. removeVnodes(elm, oldCh, 0, oldCh.length - 1);
  461. }
  462. api.setTextContent(elm, vnode.text);
  463. }
  464. (_h = hook === null || hook === void 0 ? void 0 : hook.postpatch) === null || _h === void 0 ? void 0 : _h.call(hook, oldVnode, vnode);
  465. }
  466. return function patch(oldVnode, vnode) {
  467. let i, elm, parent;
  468. const insertedVnodeQueue = [];
  469. for (i = 0; i < cbs.pre.length; ++i)
  470. cbs.pre[i]();
  471. if (isElement(api, oldVnode)) {
  472. oldVnode = emptyNodeAt(oldVnode);
  473. }
  474. else if (isDocumentFragment(api, oldVnode)) {
  475. oldVnode = emptyDocumentFragmentAt(oldVnode);
  476. }
  477. if (sameVnode(oldVnode, vnode)) {
  478. patchVnode(oldVnode, vnode, insertedVnodeQueue);
  479. }
  480. else {
  481. elm = oldVnode.elm;
  482. parent = api.parentNode(elm);
  483. createElm(vnode, insertedVnodeQueue);
  484. if (parent !== null) {
  485. api.insertBefore(parent, vnode.elm, api.nextSibling(elm));
  486. removeVnodes(parent, [oldVnode], 0, 0);
  487. }
  488. }
  489. for (i = 0; i < insertedVnodeQueue.length; ++i) {
  490. insertedVnodeQueue[i].data.hook.insert(insertedVnodeQueue[i]);
  491. }
  492. for (i = 0; i < cbs.post.length; ++i)
  493. cbs.post[i]();
  494. return vnode;
  495. };
  496. }
  497. function addNS(data, children, sel) {
  498. data.ns = "http://www.w3.org/2000/svg";
  499. if (sel !== "foreignObject" && children !== undefined) {
  500. for (let i = 0; i < children.length; ++i) {
  501. const child = children[i];
  502. if (typeof child === "string")
  503. continue;
  504. const childData = child.data;
  505. if (childData !== undefined) {
  506. addNS(childData, child.children, child.sel);
  507. }
  508. }
  509. }
  510. }
  511. function h(sel, b, c) {
  512. let data = {};
  513. let children;
  514. let text;
  515. let i;
  516. if (c !== undefined) {
  517. if (b !== null) {
  518. data = b;
  519. }
  520. if (array(c)) {
  521. children = c;
  522. }
  523. else if (primitive(c)) {
  524. text = c.toString();
  525. }
  526. else if (c && c.sel) {
  527. children = [c];
  528. }
  529. }
  530. else if (b !== undefined && b !== null) {
  531. if (array(b)) {
  532. children = b;
  533. }
  534. else if (primitive(b)) {
  535. text = b.toString();
  536. }
  537. else if (b && b.sel) {
  538. children = [b];
  539. }
  540. else {
  541. data = b;
  542. }
  543. }
  544. if (children !== undefined) {
  545. for (i = 0; i < children.length; ++i) {
  546. if (primitive(children[i]))
  547. children[i] = vnode(undefined, undefined, undefined, children[i], undefined);
  548. }
  549. }
  550. if (sel[0] === "s" &&
  551. sel[1] === "v" &&
  552. sel[2] === "g" &&
  553. (sel.length === 3 || sel[3] === "." || sel[3] === "#")) {
  554. addNS(data, children, sel);
  555. }
  556. return vnode(sel, data, children, text, undefined);
  557. }
  558. /**
  559. * @experimental
  560. */
  561. function fragment(children) {
  562. let c;
  563. let text;
  564. if (array(children)) {
  565. c = children;
  566. }
  567. else if (primitive(c)) {
  568. text = children;
  569. }
  570. else if (c && c.sel) {
  571. c = [children];
  572. }
  573. if (c !== undefined) {
  574. for (let i = 0; i < c.length; ++i) {
  575. if (primitive(c[i]))
  576. c[i] = vnode(undefined, undefined, undefined, c[i], undefined);
  577. }
  578. }
  579. return vnode(undefined, {}, c, text, undefined);
  580. }
  581. function copyToThunk(vnode, thunk) {
  582. var _a;
  583. const ns = (_a = thunk.data) === null || _a === void 0 ? void 0 : _a.ns;
  584. vnode.data.fn = thunk.data.fn;
  585. vnode.data.args = thunk.data.args;
  586. thunk.data = vnode.data;
  587. thunk.children = vnode.children;
  588. thunk.text = vnode.text;
  589. thunk.elm = vnode.elm;
  590. if (ns)
  591. addNS(thunk.data, thunk.children, thunk.sel);
  592. }
  593. function init(thunk) {
  594. const cur = thunk.data;
  595. const vnode = cur.fn(...cur.args);
  596. copyToThunk(vnode, thunk);
  597. }
  598. function prepatch(oldVnode, thunk) {
  599. let i;
  600. const old = oldVnode.data;
  601. const cur = thunk.data;
  602. const oldArgs = old.args;
  603. const args = cur.args;
  604. if (old.fn !== cur.fn || oldArgs.length !== args.length) {
  605. copyToThunk(cur.fn(...args), thunk);
  606. return;
  607. }
  608. for (i = 0; i < args.length; ++i) {
  609. if (oldArgs[i] !== args[i]) {
  610. copyToThunk(cur.fn(...args), thunk);
  611. return;
  612. }
  613. }
  614. copyToThunk(oldVnode, thunk);
  615. }
  616. const thunk = function thunk(sel, key, fn, args) {
  617. if (args === undefined) {
  618. args = fn;
  619. fn = key;
  620. key = undefined;
  621. }
  622. return h(sel, {
  623. key: key,
  624. hook: { init, prepatch },
  625. fn: fn,
  626. args: args,
  627. });
  628. };
  629. function pre(vnode, newVnode) {
  630. const attachData = vnode.data.attachData;
  631. // Copy created placeholder and real element from old vnode
  632. newVnode.data.attachData.placeholder = attachData.placeholder;
  633. newVnode.data.attachData.real = attachData.real;
  634. // Mount real element in vnode so the patch process operates on it
  635. vnode.elm = vnode.data.attachData.real;
  636. }
  637. function post(_, vnode) {
  638. // Mount dummy placeholder in vnode so potential reorders use it
  639. vnode.elm = vnode.data.attachData.placeholder;
  640. }
  641. function destroy(vnode) {
  642. // Remove placeholder
  643. if (vnode.elm !== undefined) {
  644. vnode.elm.parentNode.removeChild(vnode.elm);
  645. }
  646. // Remove real element from where it was inserted
  647. vnode.elm = vnode.data.attachData.real;
  648. }
  649. function create(_, vnode) {
  650. const real = vnode.elm;
  651. const attachData = vnode.data.attachData;
  652. const placeholder = document.createElement("span");
  653. // Replace actual element with dummy placeholder
  654. // Snabbdom will then insert placeholder instead
  655. vnode.elm = placeholder;
  656. attachData.target.appendChild(real);
  657. attachData.real = real;
  658. attachData.placeholder = placeholder;
  659. }
  660. function attachTo(target, vnode) {
  661. if (vnode.data === undefined)
  662. vnode.data = {};
  663. if (vnode.data.hook === undefined)
  664. vnode.data.hook = {};
  665. const data = vnode.data;
  666. const hook = vnode.data.hook;
  667. data.attachData = { target: target, placeholder: undefined, real: undefined };
  668. hook.create = create;
  669. hook.prepatch = pre;
  670. hook.postpatch = post;
  671. hook.destroy = destroy;
  672. return vnode;
  673. }
  674. function toVNode(node, domApi) {
  675. const api = domApi !== undefined ? domApi : htmlDomApi;
  676. let text;
  677. if (api.isElement(node)) {
  678. const id = node.id ? "#" + node.id : "";
  679. const cn = node.getAttribute("class");
  680. const c = cn ? "." + cn.split(" ").join(".") : "";
  681. const sel = api.tagName(node).toLowerCase() + id + c;
  682. const attrs = {};
  683. const dataset = {};
  684. const data = {};
  685. const children = [];
  686. let name;
  687. let i, n;
  688. const elmAttrs = node.attributes;
  689. const elmChildren = node.childNodes;
  690. for (i = 0, n = elmAttrs.length; i < n; i++) {
  691. name = elmAttrs[i].nodeName;
  692. if (name[0] === "d" &&
  693. name[1] === "a" &&
  694. name[2] === "t" &&
  695. name[3] === "a" &&
  696. name[4] === "-") {
  697. dataset[name.slice(5)] = elmAttrs[i].nodeValue || "";
  698. }
  699. else if (name !== "id" && name !== "class") {
  700. attrs[name] = elmAttrs[i].nodeValue;
  701. }
  702. }
  703. for (i = 0, n = elmChildren.length; i < n; i++) {
  704. children.push(toVNode(elmChildren[i], domApi));
  705. }
  706. if (Object.keys(attrs).length > 0)
  707. data.attrs = attrs;
  708. if (Object.keys(dataset).length > 0)
  709. data.dataset = dataset;
  710. if (sel[0] === "s" &&
  711. sel[1] === "v" &&
  712. sel[2] === "g" &&
  713. (sel.length === 3 || sel[3] === "." || sel[3] === "#")) {
  714. addNS(data, children, sel);
  715. }
  716. return vnode(sel, data, children, undefined, node);
  717. }
  718. else if (api.isText(node)) {
  719. text = api.getTextContent(node);
  720. return vnode(undefined, undefined, undefined, text, node);
  721. }
  722. else if (api.isComment(node)) {
  723. text = api.getTextContent(node);
  724. return vnode("!", {}, [], text, node);
  725. }
  726. else {
  727. return vnode("", {}, [], undefined, node);
  728. }
  729. }
  730. const xlinkNS = "http://www.w3.org/1999/xlink";
  731. const xmlNS = "http://www.w3.org/XML/1998/namespace";
  732. const colonChar = 58;
  733. const xChar = 120;
  734. function updateAttrs(oldVnode, vnode) {
  735. let key;
  736. const elm = vnode.elm;
  737. let oldAttrs = oldVnode.data.attrs;
  738. let attrs = vnode.data.attrs;
  739. if (!oldAttrs && !attrs)
  740. return;
  741. if (oldAttrs === attrs)
  742. return;
  743. oldAttrs = oldAttrs || {};
  744. attrs = attrs || {};
  745. // update modified attributes, add new attributes
  746. for (key in attrs) {
  747. const cur = attrs[key];
  748. const old = oldAttrs[key];
  749. if (old !== cur) {
  750. if (cur === true) {
  751. elm.setAttribute(key, "");
  752. }
  753. else if (cur === false) {
  754. elm.removeAttribute(key);
  755. }
  756. else {
  757. if (key.charCodeAt(0) !== xChar) {
  758. elm.setAttribute(key, cur);
  759. }
  760. else if (key.charCodeAt(3) === colonChar) {
  761. // Assume xml namespace
  762. elm.setAttributeNS(xmlNS, key, cur);
  763. }
  764. else if (key.charCodeAt(5) === colonChar) {
  765. // Assume xlink namespace
  766. elm.setAttributeNS(xlinkNS, key, cur);
  767. }
  768. else {
  769. elm.setAttribute(key, cur);
  770. }
  771. }
  772. }
  773. }
  774. // remove removed attributes
  775. // use `in` operator since the previous `for` iteration uses it (.i.e. add even attributes with undefined value)
  776. // the other option is to remove all attributes with value == undefined
  777. for (key in oldAttrs) {
  778. if (!(key in attrs)) {
  779. elm.removeAttribute(key);
  780. }
  781. }
  782. }
  783. const attributesModule = {
  784. create: updateAttrs,
  785. update: updateAttrs,
  786. };
  787. function updateClass(oldVnode, vnode) {
  788. let cur;
  789. let name;
  790. const elm = vnode.elm;
  791. let oldClass = oldVnode.data.class;
  792. let klass = vnode.data.class;
  793. if (!oldClass && !klass)
  794. return;
  795. if (oldClass === klass)
  796. return;
  797. oldClass = oldClass || {};
  798. klass = klass || {};
  799. for (name in oldClass) {
  800. if (oldClass[name] && !Object.prototype.hasOwnProperty.call(klass, name)) {
  801. // was `true` and now not provided
  802. elm.classList.remove(name);
  803. }
  804. }
  805. for (name in klass) {
  806. cur = klass[name];
  807. if (cur !== oldClass[name]) {
  808. elm.classList[cur ? "add" : "remove"](name);
  809. }
  810. }
  811. }
  812. const classModule = { create: updateClass, update: updateClass };
  813. const CAPS_REGEX = /[A-Z]/g;
  814. function updateDataset(oldVnode, vnode) {
  815. const elm = vnode.elm;
  816. let oldDataset = oldVnode.data.dataset;
  817. let dataset = vnode.data.dataset;
  818. let key;
  819. if (!oldDataset && !dataset)
  820. return;
  821. if (oldDataset === dataset)
  822. return;
  823. oldDataset = oldDataset || {};
  824. dataset = dataset || {};
  825. const d = elm.dataset;
  826. for (key in oldDataset) {
  827. if (!dataset[key]) {
  828. if (d) {
  829. if (key in d) {
  830. delete d[key];
  831. }
  832. }
  833. else {
  834. elm.removeAttribute("data-" + key.replace(CAPS_REGEX, "-$&").toLowerCase());
  835. }
  836. }
  837. }
  838. for (key in dataset) {
  839. if (oldDataset[key] !== dataset[key]) {
  840. if (d) {
  841. d[key] = dataset[key];
  842. }
  843. else {
  844. elm.setAttribute("data-" + key.replace(CAPS_REGEX, "-$&").toLowerCase(), dataset[key]);
  845. }
  846. }
  847. }
  848. }
  849. const datasetModule = {
  850. create: updateDataset,
  851. update: updateDataset,
  852. };
  853. function invokeHandler(handler, vnode, event) {
  854. if (typeof handler === "function") {
  855. // call function handler
  856. handler.call(vnode, event, vnode);
  857. }
  858. else if (typeof handler === "object") {
  859. // call multiple handlers
  860. for (let i = 0; i < handler.length; i++) {
  861. invokeHandler(handler[i], vnode, event);
  862. }
  863. }
  864. }
  865. function handleEvent(event, vnode) {
  866. const name = event.type;
  867. const on = vnode.data.on;
  868. // call event handler(s) if exists
  869. if (on && on[name]) {
  870. invokeHandler(on[name], vnode, event);
  871. }
  872. }
  873. function createListener() {
  874. return function handler(event) {
  875. handleEvent(event, handler.vnode);
  876. };
  877. }
  878. function updateEventListeners(oldVnode, vnode) {
  879. const oldOn = oldVnode.data.on;
  880. const oldListener = oldVnode.listener;
  881. const oldElm = oldVnode.elm;
  882. const on = vnode && vnode.data.on;
  883. const elm = (vnode && vnode.elm);
  884. let name;
  885. // optimization for reused immutable handlers
  886. if (oldOn === on) {
  887. return;
  888. }
  889. // remove existing listeners which no longer used
  890. if (oldOn && oldListener) {
  891. // if element changed or deleted we remove all existing listeners unconditionally
  892. if (!on) {
  893. for (name in oldOn) {
  894. // remove listener if element was changed or existing listeners removed
  895. oldElm.removeEventListener(name, oldListener, false);
  896. }
  897. }
  898. else {
  899. for (name in oldOn) {
  900. // remove listener if existing listener removed
  901. if (!on[name]) {
  902. oldElm.removeEventListener(name, oldListener, false);
  903. }
  904. }
  905. }
  906. }
  907. // add new listeners which has not already attached
  908. if (on) {
  909. // reuse existing listener or create new
  910. const listener = (vnode.listener =
  911. oldVnode.listener || createListener());
  912. // update vnode for listener
  913. listener.vnode = vnode;
  914. // if element changed or added we add all needed listeners unconditionally
  915. if (!oldOn) {
  916. for (name in on) {
  917. // add listener if element was changed or new listeners added
  918. elm.addEventListener(name, listener, false);
  919. }
  920. }
  921. else {
  922. for (name in on) {
  923. // add listener if new listener added
  924. if (!oldOn[name]) {
  925. elm.addEventListener(name, listener, false);
  926. }
  927. }
  928. }
  929. }
  930. }
  931. const eventListenersModule = {
  932. create: updateEventListeners,
  933. update: updateEventListeners,
  934. destroy: updateEventListeners,
  935. };
  936. function updateProps(oldVnode, vnode) {
  937. let key;
  938. let cur;
  939. let old;
  940. const elm = vnode.elm;
  941. let oldProps = oldVnode.data.props;
  942. let props = vnode.data.props;
  943. if (!oldProps && !props)
  944. return;
  945. if (oldProps === props)
  946. return;
  947. oldProps = oldProps || {};
  948. props = props || {};
  949. for (key in props) {
  950. cur = props[key];
  951. old = oldProps[key];
  952. if (old !== cur && (key !== "value" || elm[key] !== cur)) {
  953. elm[key] = cur;
  954. }
  955. }
  956. }
  957. const propsModule = { create: updateProps, update: updateProps };
  958. // Bindig `requestAnimationFrame` like this fixes a bug in IE/Edge. See #360 and #409.
  959. const raf = (typeof window !== "undefined" &&
  960. window.requestAnimationFrame.bind(window)) ||
  961. setTimeout;
  962. const nextFrame = function (fn) {
  963. raf(function () {
  964. raf(fn);
  965. });
  966. };
  967. let reflowForced = false;
  968. function setNextFrame(obj, prop, val) {
  969. nextFrame(function () {
  970. obj[prop] = val;
  971. });
  972. }
  973. function updateStyle(oldVnode, vnode) {
  974. let cur;
  975. let name;
  976. const elm = vnode.elm;
  977. let oldStyle = oldVnode.data.style;
  978. let style = vnode.data.style;
  979. if (!oldStyle && !style)
  980. return;
  981. if (oldStyle === style)
  982. return;
  983. oldStyle = oldStyle || {};
  984. style = style || {};
  985. const oldHasDel = "delayed" in oldStyle;
  986. for (name in oldStyle) {
  987. if (!style[name]) {
  988. if (name[0] === "-" && name[1] === "-") {
  989. elm.style.removeProperty(name);
  990. }
  991. else {
  992. elm.style[name] = "";
  993. }
  994. }
  995. }
  996. for (name in style) {
  997. cur = style[name];
  998. if (name === "delayed" && style.delayed) {
  999. for (const name2 in style.delayed) {
  1000. cur = style.delayed[name2];
  1001. if (!oldHasDel || cur !== oldStyle.delayed[name2]) {
  1002. setNextFrame(elm.style, name2, cur);
  1003. }
  1004. }
  1005. }
  1006. else if (name !== "remove" && cur !== oldStyle[name]) {
  1007. if (name[0] === "-" && name[1] === "-") {
  1008. elm.style.setProperty(name, cur);
  1009. }
  1010. else {
  1011. elm.style[name] = cur;
  1012. }
  1013. }
  1014. }
  1015. }
  1016. function applyDestroyStyle(vnode) {
  1017. let style;
  1018. let name;
  1019. const elm = vnode.elm;
  1020. const s = vnode.data.style;
  1021. if (!s || !(style = s.destroy))
  1022. return;
  1023. for (name in style) {
  1024. elm.style[name] = style[name];
  1025. }
  1026. }
  1027. function applyRemoveStyle(vnode, rm) {
  1028. const s = vnode.data.style;
  1029. if (!s || !s.remove) {
  1030. rm();
  1031. return;
  1032. }
  1033. if (!reflowForced) {
  1034. // eslint-disable-next-line @typescript-eslint/no-unused-expressions
  1035. vnode.elm.offsetLeft;
  1036. reflowForced = true;
  1037. }
  1038. let name;
  1039. const elm = vnode.elm;
  1040. let i = 0;
  1041. const style = s.remove;
  1042. let amount = 0;
  1043. const applied = [];
  1044. for (name in style) {
  1045. applied.push(name);
  1046. elm.style[name] = style[name];
  1047. }
  1048. const compStyle = getComputedStyle(elm);
  1049. const props = compStyle["transition-property"].split(", ");
  1050. for (; i < props.length; ++i) {
  1051. if (applied.indexOf(props[i]) !== -1)
  1052. amount++;
  1053. }
  1054. elm.addEventListener("transitionend", function (ev) {
  1055. if (ev.target === elm)
  1056. --amount;
  1057. if (amount === 0)
  1058. rm();
  1059. });
  1060. }
  1061. function forceReflow() {
  1062. reflowForced = false;
  1063. }
  1064. const styleModule = {
  1065. pre: forceReflow,
  1066. create: updateStyle,
  1067. update: updateStyle,
  1068. destroy: applyDestroyStyle,
  1069. remove: applyRemoveStyle,
  1070. };
  1071. /* eslint-disable @typescript-eslint/no-namespace, import/export */
  1072. function Fragment(data, ...children) {
  1073. const flatChildren = flattenAndFilter(children, []);
  1074. if (flatChildren.length === 1 &&
  1075. !flatChildren[0].sel &&
  1076. flatChildren[0].text) {
  1077. // only child is a simple text node, pass as text for a simpler vtree
  1078. return vnode(undefined, undefined, undefined, flatChildren[0].text, undefined);
  1079. }
  1080. else {
  1081. return vnode(undefined, data !== null && data !== void 0 ? data : {}, flatChildren, undefined, undefined);
  1082. }
  1083. }
  1084. function flattenAndFilter(children, flattened) {
  1085. for (const child of children) {
  1086. // filter out falsey children, except 0 since zero can be a valid value e.g inside a chart
  1087. if (child !== undefined &&
  1088. child !== null &&
  1089. child !== false &&
  1090. child !== "") {
  1091. if (Array.isArray(child)) {
  1092. flattenAndFilter(child, flattened);
  1093. }
  1094. else if (typeof child === "string" ||
  1095. typeof child === "number" ||
  1096. typeof child === "boolean") {
  1097. flattened.push(vnode(undefined, undefined, undefined, String(child), undefined));
  1098. }
  1099. else {
  1100. flattened.push(child);
  1101. }
  1102. }
  1103. }
  1104. return flattened;
  1105. }
  1106. /**
  1107. * jsx/tsx compatible factory function
  1108. * see: https://www.typescriptlang.org/docs/handbook/jsx.html#factory-functions
  1109. */
  1110. function jsx(tag, data, ...children) {
  1111. const flatChildren = flattenAndFilter(children, []);
  1112. if (typeof tag === "function") {
  1113. // tag is a function component
  1114. return tag(data, flatChildren);
  1115. }
  1116. else {
  1117. if (flatChildren.length === 1 &&
  1118. !flatChildren[0].sel &&
  1119. flatChildren[0].text) {
  1120. // only child is a simple text node, pass as text for a simpler vtree
  1121. return h(tag, data, flatChildren[0].text);
  1122. }
  1123. else {
  1124. return h(tag, data, flatChildren);
  1125. }
  1126. }
  1127. }
  1128. (function (jsx) {
  1129. })(jsx || (jsx = {}));
  1130. exports.Fragment = Fragment;
  1131. exports.array = array;
  1132. exports.attachTo = attachTo;
  1133. exports.attributesModule = attributesModule;
  1134. exports.classModule = classModule;
  1135. exports.datasetModule = datasetModule;
  1136. exports.eventListenersModule = eventListenersModule;
  1137. exports.fragment = fragment;
  1138. exports.h = h;
  1139. exports.htmlDomApi = htmlDomApi;
  1140. exports.init = init$1;
  1141. exports.jsx = jsx;
  1142. exports.primitive = primitive;
  1143. exports.propsModule = propsModule;
  1144. exports.styleModule = styleModule;
  1145. exports.thunk = thunk;
  1146. exports.toVNode = toVNode;
  1147. exports.vnode = vnode;