diff --git a/cjs/hyper/render.js b/cjs/hyper/render.js index 376ae28f..51fd110b 100644 --- a/cjs/hyper/render.js +++ b/cjs/hyper/render.js @@ -8,7 +8,7 @@ const { unique } = require('../shared/utils.js'); -const {selfClosing} = require('../shared/re.js'); +const {selfClosing: SC_RE} = require('../shared/re.js'); // a weak collection of contexts that // are already known to hyperHTML @@ -39,14 +39,22 @@ function render(template) { // to the current context, and render it after cleaning the context up function upgrade(template) { template = unique(template); + const adopt = render.adopt; const info = templates.get(template) || createTemplate.call(this, template); - const fragment = importNode(this.ownerDocument, info.fragment); - const updates = Updates.create(fragment, info.paths); + let fragment, updates; + if (adopt) { + updates = Updates.create(this, info.paths, adopt); + } else { + fragment = importNode(this.ownerDocument, info.fragment); + updates = Updates.create(fragment, info.paths, adopt); + } bewitched.set(this, {template, updates}); update.apply(updates, arguments); - this.textContent = ''; - this.appendChild(fragment); + if (!adopt) { + this.textContent = ''; + this.appendChild(fragment); + } } // an update simply loops over all mapped DOM operations @@ -73,7 +81,6 @@ function createTemplate(template) { // some node could be special though, like a custom element // with a self closing tag, which should work through these changes. -const SC_RE = selfClosing; const SC_PLACE = ($0, $1, $2) => { return VOID_ELEMENTS.test($1) ? $0 : ('<' + $1 + $2 + '>' + $1 + '>'); }; diff --git a/cjs/index.js b/cjs/index.js index 0a05cd07..3d4fc04b 100644 --- a/cjs/index.js +++ b/cjs/index.js @@ -13,10 +13,18 @@ const diff = (m => m.__esModule ? m.default : m)(require('./shared/domdiff.js')) // you can do the following // const {bind, wire} = hyperHTML; // and use them right away: bind(node)`hello!`; -const bind = context => render.bind(context); +const adopt = context => function () { + render.adopt = true; + return render.apply(context, arguments); +}; +const bind = context => function () { + render.adopt = false; + return render.apply(context, arguments); +}; const define = Intent.define; hyper.Component = Component; +hyper.adopt = adopt; hyper.bind = bind; hyper.define = define; hyper.diff = diff; @@ -30,6 +38,7 @@ setup(content); // everything is exported directly or through the // hyperHTML callback, when used as top level script exports.Component = Component; +exports.adopt = adopt; exports.bind = bind; exports.define = define; exports.diff = diff; diff --git a/cjs/objects/Path.js b/cjs/objects/Path.js index aef883cf..af79b848 100644 --- a/cjs/objects/Path.js +++ b/cjs/objects/Path.js @@ -53,6 +53,6 @@ Object.defineProperty(exports, '__esModule', {value: true}).default = { for (let i = 0; i < length; i++) { node = node.childNodes[path[i]]; } - return node; + return {node, childNodes: []}; } } diff --git a/cjs/objects/Updates.js b/cjs/objects/Updates.js index 447823c1..e284fd23 100644 --- a/cjs/objects/Updates.js +++ b/cjs/objects/Updates.js @@ -54,27 +54,54 @@ value instanceof Component; // Updates can be related to any kind of content, // attributes, or special text-only cases such - -
-| 1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355 -356 -357 -358 -359 -360 -361 -362 -363 -364 -365 -366 -367 -368 -369 -370 -371 -372 -373 -374 -375 -376 -377 -378 -379 -380 -381 -382 -383 -384 -385 -386 -387 -388 -389 -390 -391 -392 -393 -394 -395 -396 -397 -398 -399 -400 -401 -402 -403 -404 -405 -406 -407 -408 -409 -410 -411 -412 -413 -414 -415 -416 -417 -418 -419 -420 -421 -422 -423 -424 -425 -426 -427 -428 -429 -430 -431 -432 -433 -434 -435 -436 -437 -438 -439 -440 -441 -442 -443 -444 -445 -446 -447 -448 -449 -450 -451 -452 -453 -454 -455 -456 -457 -458 -459 -460 -461 -462 -463 -464 -465 -466 -467 -468 -469 -470 -471 -472 -473 -474 -475 -476 -477 -478 -479 -480 -481 -482 -483 -484 -485 -486 -487 -488 -489 -490 -491 -492 -493 -494 -495 -496 -497 -498 -499 -500 -501 -502 -503 -504 -505 -506 -507 -508 -509 -510 -511 -512 -513 -514 -515 -516 -517 -518 -519 -520 -521 -522 -523 -524 -525 -526 -527 -528 -529 -530 -531 -532 -533 -534 -535 -536 -537 -538 -539 -540 -541 -542 -543 -544 -545 -546 -547 -548 -549 -550 -551 -552 -553 -554 -555 -556 -557 -558 -559 -560 -561 -562 -563 -564 -565 -566 -567 -568 -569 -570 -571 -572 -573 -574 -575 -576 -577 -578 -579 -580 -581 -582 -583 -584 -585 -586 -587 -588 -589 -590 -591 -592 -593 -594 -595 -596 -597 -598 -599 -600 -601 -602 -603 -604 -605 -606 -607 -608 -609 -610 -611 -612 -613 -614 -615 -616 -617 -618 -619 -620 -621 -622 -623 -624 -625 -626 -627 -628 -629 -630 -631 -632 -633 -634 -635 -636 -637 -638 -639 -640 -641 -642 -643 -644 -645 -646 -647 -648 -649 -650 -651 -652 -653 -654 -655 -656 -657 -658 -659 -660 -661 -662 -663 -664 -665 -666 -667 -668 -669 -670 -671 -672 -673 -674 -675 -676 -677 -678 -679 -680 -681 -682 -683 -684 -685 -686 -687 -688 -689 -690 -691 -692 -693 -694 -695 -696 -697 -698 -699 -700 -701 -702 -703 -704 -705 -706 -707 -708 -709 -710 -711 -712 -713 -714 -715 -716 -717 -718 -719 -720 -721 -722 -723 -724 -725 -726 -727 -728 -729 -730 -731 -732 -733 -734 -735 -736 -737 -738 -739 -740 -741 -742 -743 -744 -745 -746 -747 -748 -749 -750 -751 -752 -753 -754 -755 -756 -757 -758 -759 -760 -761 -762 -763 -764 -765 -766 -767 -768 -769 -770 -771 -772 -773 -774 -775 -776 -777 -778 -779 -780 -781 -782 -783 -784 -785 -786 -787 -788 -789 -790 -791 -792 -793 -794 -795 -796 -797 -798 -799 -800 -801 -802 -803 -804 -805 -806 -807 -808 -809 -810 -811 -812 -813 -814 -815 -816 -817 -818 -819 -820 -821 -822 -823 -824 -825 -826 -827 -828 -829 -830 -831 -832 -833 -834 -835 -836 -837 -838 -839 -840 -841 -842 -843 -844 -845 -846 -847 -848 -849 -850 -851 -852 -853 -854 -855 -856 -857 -858 -859 -860 -861 -862 -863 -864 -865 -866 -867 -868 -869 -870 -871 -872 -873 -874 -875 -876 -877 -878 -879 -880 -881 -882 -883 -884 -885 -886 -887 -888 -889 -890 -891 -892 -893 -894 -895 -896 -897 -898 -899 -900 -901 -902 -903 -904 -905 -906 -907 -908 -909 -910 -911 -912 -913 -914 -915 -916 -917 -918 -919 -920 -921 -922 -923 -924 -925 -926 -927 -928 -929 -930 -931 -932 -933 -934 -935 -936 -937 -938 -939 -940 -941 -942 -943 -944 -945 -946 -947 -948 -949 -950 -951 -952 -953 -954 -955 -956 -957 -958 -959 -960 -961 -962 -963 -964 -965 -966 -967 -968 -969 -970 -971 -972 -973 -974 -975 -976 -977 -978 -979 -980 -981 -982 -983 -984 -985 -986 -987 -988 -989 -990 -991 -992 -993 -994 -995 -996 -997 -998 -999 -1000 -1001 -1002 -1003 -1004 -1005 -1006 -1007 -1008 -1009 -1010 -1011 -1012 -1013 -1014 -1015 -1016 -1017 -1018 -1019 -1020 -1021 -1022 -1023 -1024 -1025 -1026 -1027 -1028 -1029 -1030 -1031 -1032 -1033 -1034 -1035 -1036 -1037 -1038 -1039 -1040 -1041 -1042 -1043 -1044 -1045 -1046 -1047 -1048 -1049 -1050 -1051 -1052 -1053 -1054 -1055 -1056 -1057 -1058 -1059 -1060 -1061 -1062 -1063 -1064 -1065 -1066 -1067 -1068 -1069 -1070 -1071 -1072 -1073 -1074 -1075 -1076 -1077 -1078 -1079 -1080 -1081 -1082 -1083 -1084 -1085 -1086 -1087 -1088 -1089 -1090 -1091 -1092 -1093 -1094 -1095 -1096 -1097 -1098 -1099 -1100 -1101 -1102 -1103 -1104 -1105 -1106 -1107 -1108 -1109 -1110 -1111 -1112 -1113 -1114 -1115 -1116 -1117 -1118 -1119 -1120 -1121 -1122 -1123 -1124 -1125 -1126 -1127 -1128 -1129 -1130 -1131 -1132 -1133 -1134 -1135 -1136 -1137 -1138 -1139 -1140 -1141 -1142 -1143 -1144 -1145 -1146 -1147 -1148 -1149 -1150 -1151 -1152 -1153 -1154 -1155 -1156 -1157 -1158 -1159 -1160 -1161 -1162 -1163 -1164 -1165 -1166 -1167 -1168 -1169 -1170 -1171 -1172 -1173 -1174 -1175 -1176 -1177 -1178 -1179 -1180 -1181 -1182 -1183 -1184 -1185 -1186 -1187 -1188 -1189 -1190 -1191 -1192 -1193 -1194 -1195 -1196 -1197 -1198 -1199 -1200 -1201 -1202 -1203 -1204 -1205 -1206 -1207 -1208 -1209 -1210 -1211 -1212 -1213 -1214 -1215 -1216 -1217 -1218 -1219 -1220 -1221 -1222 -1223 -1224 -1225 -1226 -1227 -1228 -1229 -1230 -1231 -1232 -1233 -1234 -1235 -1236 -1237 -1238 -1239 -1240 -1241 -1242 -1243 -1244 -1245 -1246 -1247 -1248 -1249 -1250 -1251 -1252 -1253 -1254 -1255 -1256 -1257 -1258 -1259 -1260 -1261 -1262 -1263 -1264 -1265 -1266 -1267 -1268 -1269 -1270 -1271 -1272 -1273 -1274 -1275 -1276 -1277 -1278 -1279 -1280 -1281 -1282 -1283 -1284 -1285 -1286 -1287 -1288 -1289 -1290 -1291 -1292 -1293 -1294 -1295 -1296 -1297 | 2× - - -2× - - - - -2× -2× -2× -2× - - -2× - - -2× -2× - - -2× -2× - - -2× -2× -2× -2× - - - - - - - -2× -2× -2× - -1× -12× -12× -12× - - - - -2× -1× - -1× - -108× - - -77× - - - - - -2× -5× - -291× - - -136× - - - - - - - - -2× -1× -1× - -8× - - -37× - - - - - -2× -1× -117× - - - -2× -62× - - - - - - - - - - -1× - - - - - - - -1× -2× -2× -2× -6× -6× - -2× -28× - - -6× -6× - -22× -22× - - -2× -8× -8× -8× - -2× - - - -28× -28× - - - -2× - - -24× -24× - - - - - -22× - - - -20× - - - - -22× -22× -22× -24× -22× -22× - - - - - - - - - -2× -6× -6× - -86× - - -58× - - - - -2× -2× -2× - -2× - -2× - - - - - - - -4× -2× - -4× - - - - - -16× -10× -10× -8× - - - - - - -2× -176× - -2× -482× - -2× -224× - -2× -78× - - - - - -2× -2× -2× -2× -2× - -2× - -2× - -2× - - -2× - - -2× - - -2× -2× -2× - - - - - -2× - - - - - -2× -12× - -98× -98× -172× - - - -2× -2× -93× - -2× -87× - - - - - -2× -174× - - - - - - -2× -446× -446× - - - - - - - - -446× -446× -338× - -446× - - - - - - - - - -1× - - - -2× -105× - -108× - - - - -2× - - - - - - - - - - -2× -632× - - - - - -2× -2× - - - - - -1× - -1× -323× -323× - - - -1× -309× - - -2× - - - - - -2× -84× -84× -84× - -86× -86× -86× -1× -1× -1× - -85× -85× - -86× - - - - -2× -2× -2× -2× -2× -2× - -2× -2× -2× -2× -2× - - -1× -16× -16× -16× -16× - - - -2× -12× -12× -12× - - - -2× -4× -4× -4× -2× - -2× -2× -2× -2× - -4× - - - - - - - - - - - - - -2× -153× -153× -153× - - -8× -8× - -58× -58× -58× - -87× -87× - -153× -136× - -153× - - -2× -194× - - -2× - -153× - - -217× -217× -295× - -217× - - - - -2× - - - -2× -8× -2× -2× -2× -2× - -6× - - - - - -2× -8× - -8× -36× - -22× -18× -10× -8× -6× -6× -4× - - - - - -8× - -18× -18× -18× -18× - -18× -18× -18× - - -18× -14× -14× -14× - -18× - - - - -2× -2× -2× - -2× -4× -4× -4× - -4× - - - - - - - - - - - -2× -559× - - -2× - - - - - -295× -295× -295× - -295× -295× -295× -295× -295× -295× -295× -626× -46× -580× -12× -568× -22× -546× -5× -541× -222× -222× -319× -88× -88× -231× -65× -65× -65× -166× -28× -28× -28× - -138× -138× -89× -89× - -49× -49× -49× -49× - - - -295× -252× -154× -154× -154× -116× - -38× -38× -106× - -38× - - -98× -98× -67× - -31× -31× -31× -31× - - - -295× - - - - - - -2× - - - -1× -2× - - -2× -2× - - - -2× -512× - - - - - - - - -2× -82× - - - - - - - - - -2× -213× -213× -213× -217× -217× -217× - -111× -111× - -98× -98× - -8× -8× - - -213× - - - - - - - - - - -2× -351× -351× -351× -504× -504× - -199× -199× -199× - -70× -66× -66× - - - - - -70× - - - - - - -235× -1× -1× - -235× - - - - - - - - - - - - - -2× -199× -199× -199× -199× -199× -199× -137× -137× -87× - - - -87× -87× -87× - - - - -87× - -87× - - -199× -199× -87× - - - - - - - - -199× -199× -2× -2× -2× - -2× -2× - - - - - - - -2× -12× -12× -2× -10× -2× -8× -2× - -6× - - - - -2× -127× - - - - - - - - - - - -2× -111× -111× -111× -280× - - - -104× -30× -10× -10× - - -74× -74× -74× - -104× - - -176× -8× -8× -8× - - -168× -168× -168× -86× -9× -4× - - -77× - - - -18× -18× - -59× -8× - -59× -4× -4× - - -55× -55× - - -82× -28× -54× -4× -50× -10× -40× -4× -36× -4× -32× -22× -10× -2× - -8× - -168× - - -111× - - - - - - - - - -2× -98× -98× - - -98× -8× - - - -90× -38× -38× -16× -2× -2× - -16× -22× -20× - -38× -52× -42× -42× -42× - - - - - - -52× -14× -28× -26× -26× -24× -24× -4× - - - - - - - - -38× -38× -38× -74× -54× -54× -50× -4× -2× -2× - -4× - -46× -46× -40× -40× - - - - - - - - - - - - -2× - -8× -8× -54× -38× -38× -14× -2× -12× -2× -10× -2× -8× -2× -6× -2× -4× -2× - -2× - - -24× - - - -8× - - -2× - - - - - -2× -1× - - - - - - - -2× -24× -24× -24× -18× -18× -15× - - - - - - -2× -103× -18× - - -103× -103× -103× -88× - - - - - - -2× -2× -6× -6× -6× -6× -6× - - - -1× -6× - -1× -6× - - - - - - -2× - - - - -2× - - - - - -1× -412× -412× -199× - -213× - -412× - - - - - - -1× -213× -213× -213× -213× -213× -213× -213× -213× - - - -1× -412× -412× -444× - - - - - - - -1× -152× -152× -152× -152× -152× -152× -152× - - - - -2× -2× -48× - - - -2× - - - - - - - - - - -2× -94× - - - - - - - - -2× -112× - - - - -112× -184× -184× -184× -120× -120× -120× -120× - -184× -184× -120× -8× - -120× - -184× - - - - - - -2× -50× -50× -50× -50× -12× -12× - -50× -50× - - - - - - - - - - - - -2× -120× -120× -120× -120× -236× -236× -134× - - -120× - - - - - - - - -2× -193× - -2× - -2× -2× -2× -2× -2× -2× - - - -2× - - - - -1× -20× - - - - - - - - - - -2× - - -2× - | var hyperHTML = (function (global) {
-'use strict';
-
-var G = document.defaultView;
-
-// Node.CONSTANTS
-// 'cause some engine has no global Node defined
-// (i.e. Node, NativeScript, basicHTML ... )
-var ELEMENT_NODE = 1;
-var TEXT_NODE = 3;
-var COMMENT_NODE = 8;
-var DOCUMENT_FRAGMENT_NODE = 11;
-
-// HTML related constants
-var VOID_ELEMENTS = /^area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr$/i;
-
-// SVG related constants
-var OWNER_SVG_ELEMENT = 'ownerSVGElement';
-var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
-
-// Custom Elements / MutationObserver constants
-var CONNECTED = 'connected';
-var DISCONNECTED = 'dis' + CONNECTED;
-
-// hyperHTML related constants
-var EXPANDO = '_hyper: ';
-var SHOULD_USE_TEXT_CONTENT = /^style|textarea$/i;
-var UID = EXPANDO + (Math.random() * new Date() | 0) + ';';
-var UIDC = '<!--' + UID + '-->';
-
-// you know that kind of basics you need to cover
-// your use case only but you don't want to bloat the library?
-// There's even a package in here:
-// https://www.npmjs.com/package/poorlyfills
-
-// used to dispatch simple events
-var Event = G.Event;
-try {
- new Event('Event');
-} catch (o_O) {
- Event = function Event(type) {
- var e = document.createEvent('Event');
- e.initEvent(type, false, false);
- return e;
- };
-}
-
-// used to store template literals
-var Map = G.Map || function Map() {
- var keys = [],
- values = [];
- return {
- get: function get(obj) {
- return values[keys.indexOf(obj)];
- },
- set: function set(obj, value) {
- values[keys.push(obj) - 1] = value;
- }
- };
-};
-
-// used to store wired content
-var WeakMap = G.WeakMap || function WeakMap() {
- return {
- get: function get(obj) {
- return obj[UID];
- },
- set: function set(obj, value) {
- Object.defineProperty(obj, UID, {
- configurable: true,
- value: value
- });
- }
- };
-};
-
-// used to store hyper.Components
-var WeakSet = G.WeakSet || function WeakSet() {
- var wm = new WeakMap();
- return {
- add: function add(obj) {
- wm.set(obj, true);
- },
- has: function has(obj) {
- return wm.get(obj) === true;
- }
- };
-};
-
-// used to be sure IE9 or older Androids work as expected
-var isArray = Array.isArray || function (toString) {
- return function (arr) {
- return toString.call(arr) === '[object Array]';
- };
-}({}.toString);
-
-var trim = UID.trim || function () {
- return this.replace(/^\s+|\s+$/g, '');
-};
-
-// hyperHTML.Component is a very basic class
-// able to create Custom Elements like components
-// including the ability to listen to connect/disconnect
-// events via onconnect/ondisconnect attributes
-// Components can be created imperatively or declaratively.
-// The main difference is that declared components
-// will not automatically render on setState(...)
-// to simplify state handling on render.
-function Component() {}
-
-// components will lazily define html or svg properties
-// as soon as these are invoked within the .render() method
-// Such render() method is not provided by the base class
-// but it must be available through the Component extend.
-// Declared components could implement a
-// render(props) method too and use props as needed.
-function setup(content) {
- var children = new WeakMap();
- var create = Object.create;
- var createEntry = function createEntry(wm, id, component) {
- wm.set(id, component);
- return component;
- };
- var get = function get(Class, info, id) {
- switch (typeof id) {
- case 'object':
- case 'function':
- var wm = info.w || (info.w = new WeakMap());
- return wm.get(id) || createEntry(wm, id, new Class());
- default:
- var sm = info.p || (info.p = create(null));
- return sm[id] || (sm[id] = new Class());
- }
- };
- var set = function set(context) {
- var info = { w: null, p: null };
- children.set(context, info);
- return info;
- };
- Object.defineProperties(Component, {
- for: {
- configurable: true,
- value: function value(context, id) {
- var info = children.get(context) || set(context);
- return get(this, info, id == null ? 'default' : id);
- }
- }
- });
- Object.defineProperties(Component.prototype, {
- handleEvent: {
- value: function value(e) {
- var ct = e.currentTarget;
- this['getAttribute' in ct && ct.getAttribute('data-call') || 'on' + e.type](e);
- }
- },
- html: lazyGetter('html', content),
- svg: lazyGetter('svg', content),
- state: lazyGetter('state', function () {
- return this.defaultState;
- }),
- defaultState: {
- get: function get() {
- return {};
- }
- },
- setState: {
- value: function value(state, render) {
- var target = this.state;
- var source = typeof state === 'function' ? state.call(this, target) : state;
- for (var key in source) {
- target[key] = source[key];
- }if (render !== false) this.render();
- return this;
- }
- }
- });
-}
-
-// instead of a secret key I could've used a WeakMap
-// However, attaching a property directly will result
-// into better performance with thousands of components
-// hanging around, and less memory pressure caused by the WeakMap
-var lazyGetter = function lazyGetter(type, fn) {
- var secret = '_' + type + '$';
- return {
- get: function get() {
- return this[secret] || (this[type] = fn.call(this, type));
- },
- set: function set(value) {
- Object.defineProperty(this, secret, { configurable: true, value: value });
- }
- };
-};
-
-var intents = {};
-var keys = [];
-var hasOwnProperty = intents.hasOwnProperty;
-
-var length = 0;
-
-var Intent = {
-
- // hyperHTML.define('intent', (object, update) => {...})
- // can be used to define a third parts update mechanism
- // when every other known mechanism failed.
- // hyper.define('user', info => info.name);
- // hyper(node)`<p>${{user}}</p>`;
- define: function define(intent, callback) {
- if (!(intent in intents)) {
- length = keys.push(intent);
- }
- intents[intent] = callback;
- },
-
- // this method is used internally as last resort
- // to retrieve a value out of an object
- invoke: function invoke(object, callback) {
- for (var i = 0; i < length; i++) {
- var key = keys[i];
- if (hasOwnProperty.call(object, key)) {
- return intents[key](object[key], callback);
- }
- }
- }
-};
-
-// these are tiny helpers to simplify most common operations needed here
-var create = function create(node, type) {
- return doc(node).createElement(type);
-};
-var doc = function doc(node) {
- return node.ownerDocument || node;
-};
-var fragment = function fragment(node) {
- return doc(node).createDocumentFragment();
-};
-var text = function text(node, _text) {
- return doc(node).createTextNode(_text);
-};
-
-// TODO: I'd love to code-cover RegExp too here
-// these are fundamental for this library
-
-var spaces = ' \\f\\n\\r\\t';
-var almostEverything = '[^ ' + spaces + '\\/>"\'=]+';
-var attrName = '[ ' + spaces + ']+' + almostEverything;
-var tagName = '<([A-Za-z]+[A-Za-z0-9:_-]*)((?:';
-var attrPartials = '(?:=(?:\'[^\']*?\'|"[^"]*?"|<[^>]*?>|' + almostEverything + '))?)';
-
-var attrSeeker = new RegExp(tagName + attrName + attrPartials + '+)([ ' + spaces + ']*/?>)', 'g');
-
-var selfClosing = new RegExp(tagName + attrName + attrPartials + '*)([ ' + spaces + ']*/>)', 'g');
-
-var testFragment = fragment(document);
-
-// DOM4 node.append(...many)
-var hasAppend = 'append' in testFragment;
-
-// detect old browsers without HTMLTemplateElement content support
-var hasContent = 'content' in create(document, 'template');
-
-// IE 11 has problems with cloning templates: it "forgets" empty childNodes
-testFragment.appendChild(text(testFragment, 'g'));
-testFragment.appendChild(text(testFragment, ''));
-var hasDoomedCloneNode = testFragment.cloneNode(true).childNodes.length === 1;
-
-// old browsers need to fallback to cloneNode
-// Custom Elements V0 and V1 will work polyfilled
-// but native implementations need importNode instead
-// (specially Chromium and its old V0 implementation)
-var hasImportNode = 'importNode' in document;
-
-// appends an array of nodes
-// to a generic node/fragment
-// When available, uses append passing all arguments at once
-// hoping that's somehow faster, even if append has more checks on type
-var append = hasAppend ? function (node, childNodes) {
- node.append.apply(node, childNodes);
-} : function (node, childNodes) {
- var length = childNodes.length;
- for (var i = 0; i < length; i++) {
- node.appendChild(childNodes[i]);
- }
-};
-
-var findAttributes = new RegExp('(' + attrName + '=)([\'"]?)' + UIDC + '\\2', 'gi');
-var comments = function comments($0, $1, $2, $3) {
- return '<' + $1 + $2.replace(findAttributes, replaceAttributes) + $3;
-};
-var replaceAttributes = function replaceAttributes($0, $1, $2) {
- return $1 + ($2 || '"') + UID + ($2 || '"');
-};
-
-// given a node and a generic HTML content,
-// create either an SVG or an HTML fragment
-// where such content will be injected
-var createFragment = function createFragment(node, html) {
- return (OWNER_SVG_ELEMENT in node ? SVGFragment : HTMLFragment)(node, html.replace(attrSeeker, comments));
-};
-
-// IE/Edge shenanigans proof cloneNode
-// it goes through all nodes manually
-// instead of relying the engine to suddenly
-// merge nodes together
-var cloneNode = hasDoomedCloneNode ? function (node) {
- var clone = node.cloneNode();
- var childNodes = node.childNodes ||
- // this is an excess of caution
- // but some node, in IE, might not
- // have childNodes property.
- // The following fallback ensure working code
- // in older IE without compromising performance
- // or any other browser/engine involved.
- /* istanbul ignore next */
- [];
- var length = childNodes.length;
- for (var i = 0; i < length; i++) {
- clone.appendChild(cloneNode(childNodes[i]));
- }
- return clone;
-} :
-// the following ignore is due code-coverage
-// combination of not having document.importNode
-// but having a working node.cloneNode.
-// This shenario is common on older Android/WebKit browsers
-// but basicHTML here tests just two major cases:
-// with document.importNode or with broken cloneNode.
-/* istanbul ignore next */
-function (node) {
- return node.cloneNode(true);
-};
-
-// used to import html into fragments
-var importNode = hasImportNode ? function (doc$$1, node) {
- return doc$$1.importNode(node, true);
-} : function (doc$$1, node) {
- return cloneNode(node);
-};
-
-// just recycling a one-off array to use slice
-// in every needed place
-var slice = [].slice;
-
-// lazy evaluated, returns the unique identity
-// of a template literal, as tempalte literal itself.
-// By default, ES2015 template literals are unique
-// tag`a${1}z` === tag`a${2}z`
-// even if interpolated values are different
-// the template chunks are in a frozen Array
-// that is identical each time you use the same
-// literal to represent same static content
-// around its own interpolations.
-var unique = function unique(template) {
- return _TL(template);
-};
-
-// TL returns a unique version of the template
-// it needs lazy feature detection
-// (cannot trust literals with transpiled code)
-var _TL = function TL(template) {
- if (
- // TypeScript template literals are not standard
- template.propertyIsEnumerable('raw') ||
- // Firefox < 55 has not standard implementation neither
- /Firefox\/(\d+)/.test((G.navigator || {}).userAgent) && parseFloat(RegExp.$1) < 55) {
- // in these cases, address templates once
- var templateObjects = {};
- // but always return the same template
- _TL = function TL(template) {
- var key = '_' + template.join(UID);
- return templateObjects[key] || (templateObjects[key] = template);
- };
- } else {
- // make TL an identity like function
- _TL = function TL(template) {
- return template;
- };
- }
- return _TL(template);
-};
-
-// create document fragments via native template
-// with a fallback for browsers that won't be able
-// to deal with some injected element such <td> or others
-var HTMLFragment = hasContent ? function (node, html) {
- var container = create(node, 'template');
- container.innerHTML = html;
- return container.content;
-} : function (node, html) {
- var container = create(node, 'template');
- var content = fragment(node);
- if (/^[^\S]*?<(col(?:group)?|t(?:head|body|foot|r|d|h))/i.test(html)) {
- var selector = RegExp.$1;
- container.innerHTML = '<table>' + html + '</table>';
- append(content, slice.call(container.querySelectorAll(selector)));
- } else {
- container.innerHTML = html;
- append(content, slice.call(container.childNodes));
- }
- return content;
-};
-
-// creates SVG fragment with a fallback for IE that needs SVG
-// within the HTML content
-var SVGFragment = hasContent ? function (node, html) {
- var content = fragment(node);
- var container = doc(node).createElementNS(SVG_NAMESPACE, 'svg');
- container.innerHTML = html;
- append(content, slice.call(container.childNodes));
- return content;
-} : function (node, html) {
- var content = fragment(node);
- var container = create(node, 'div');
- container.innerHTML = '<svg xmlns="' + SVG_NAMESPACE + '">' + html + '</svg>';
- append(content, slice.call(container.firstChild.childNodes));
- return content;
-};
-
-function Wire(childNodes) {
- this.childNodes = childNodes;
- this.length = childNodes.length;
- this.first = childNodes[0];
- this.last = childNodes[this.length - 1];
-}
-
-// when a wire is inserted, all its nodes will follow
-Wire.prototype.insert = function insert() {
- var df = fragment(this.first);
- append(df, this.childNodes);
- return df;
-};
-
-// when a wire is removed, all its nodes must be removed as well
-Wire.prototype.remove = function remove() {
- var first = this.first;
- var last = this.last;
- if (this.length === 2) {
- last.parentNode.removeChild(last);
- } else {
- var range = doc(first).createRange();
- range.setStartBefore(this.childNodes[1]);
- range.setEndAfter(last);
- range.deleteContents();
- }
- return first;
-};
-
-// every template literal interpolation indicates
-// a precise target in the DOM the template is representing.
-// `<p id=${'attribute'}>some ${'content'}</p>`
-// hyperHTML finds only once per template literal,
-// hence once per entire application life-cycle,
-// all nodes that are related to interpolations.
-// These nodes are stored as indexes used to retrieve,
-// once per upgrade, nodes that will change on each future update.
-// A path example is [2, 0, 1] representing the operation:
-// node.childNodes[2].childNodes[0].childNodes[1]
-// Attributes are addressed via their owner node and their name.
-var createPath = function createPath(node) {
- var path = [];
- var parentNode = void 0;
- switch (node.nodeType) {
- case ELEMENT_NODE:
- case DOCUMENT_FRAGMENT_NODE:
- parentNode = node;
- break;
- case COMMENT_NODE:
- parentNode = node.parentNode;
- prepend(path, parentNode, node);
- break;
- default:
- parentNode = node.ownerElement;
- break;
- }
- for (node = parentNode; parentNode = parentNode.parentNode; node = parentNode) {
- prepend(path, parentNode, node);
- }
- return path;
-};
-
-var prepend = function prepend(path, parent, node) {
- path.unshift(path.indexOf.call(parent.childNodes, node));
-};
-
-var Path = {
- create: function create(type, node, name) {
- return { type: type, name: name, node: node, path: createPath(node) };
- },
- find: function find(node, path) {
- var length = path.length;
- for (var i = 0; i < length; i++) {
- node = node.childNodes[path[i]];
- }
- return node;
- }
-};
-
-// from https://github.com/developit/preact/blob/33fc697ac11762a1cb6e71e9847670d047af7ce5/src/constants.js
-var IS_NON_DIMENSIONAL = /acit|ex(?:s|g|n|p|$)|rph|ows|mnc|ntw|ine[ch]|zoo|^ord/i;
-
-// style is handled as both string and object
-// even if the target is an SVG element (consistency)
-var Style = (function (node, original, isSVG) {
- if (isSVG) {
- var style = original.cloneNode(true);
- style.value = '';
- node.setAttributeNode(style);
- return update(style, isSVG);
- }
- return update(node.style, isSVG);
-});
-
-// the update takes care or changing/replacing
-// only properties that are different or
-// in case of string, the whole node
-var update = function update(style, isSVG) {
- var oldType = void 0,
- oldValue = void 0;
- return function (newValue) {
- switch (typeof newValue) {
- case 'object':
- if (newValue) {
- if (oldType === 'object') {
- if (!isSVG) {
- if (oldValue !== newValue) {
- for (var key in oldValue) {
- if (!(key in newValue)) {
- style[key] = '';
- }
- }
- }
- }
- } else {
- if (isSVG) style.value = '';else style.cssText = '';
- }
- var info = isSVG ? {} : style;
- for (var _key in newValue) {
- var value = newValue[_key];
- info[_key] = typeof value === 'number' && !IS_NON_DIMENSIONAL.test(_key) ? value + 'px' : value;
- }
- oldType = 'object';
- if (isSVG) style.value = toStyle(oldValue = info);else oldValue = newValue;
- break;
- }
- default:
- if (oldValue != newValue) {
- oldType = 'string';
- oldValue = newValue;
- if (isSVG) style.value = newValue || '';else style.cssText = newValue || '';
- }
- break;
- }
- };
-};
-
-var hyphen = /([^A-Z])([A-Z]+)/g;
-var ized = function ized($0, $1, $2) {
- return $1 + '-' + $2.toLowerCase();
-};
-var toStyle = function toStyle(object) {
- var css = [];
- for (var key in object) {
- css.push(key.replace(hyphen, ized), ':', object[key], ';');
- }
- return css.join('');
-};
-
-/* AUTOMATICALLY IMPORTED, DO NOT MODIFY */
-/*! (c) 2017 Andrea Giammarchi (ISC) */
-
-/**
- * This code is a revisited port of the snabbdom vDOM diffing logic,
- * the same that fuels as fork Vue.js or other libraries.
- * @credits https://github.com/snabbdom/snabbdom
- */
-
-var identity = function identity(O) {
- return O;
-};
-
-var domdiff = function domdiff(parentNode, // where changes happen
-currentNodes, // Array of current items/nodes
-futureNodes, // Array of future items/nodes
-getNode, // optional way to retrieve a node from an item
-beforeNode // optional item/node to use as insertBefore delimiter
-) {
- var get = getNode || identity;
- var before = beforeNode == null ? null : get(beforeNode, 0);
- var currentStart = 0,
- futureStart = 0;
- var currentEnd = currentNodes.length - 1;
- var currentStartNode = currentNodes[0];
- var currentEndNode = currentNodes[currentEnd];
- var futureEnd = futureNodes.length - 1;
- var futureStartNode = futureNodes[0];
- var futureEndNode = futureNodes[futureEnd];
- while (currentStart <= currentEnd && futureStart <= futureEnd) {
- if (currentStartNode == null) {
- currentStartNode = currentNodes[++currentStart];
- } else if (currentEndNode == null) {
- currentEndNode = currentNodes[--currentEnd];
- } else if (futureStartNode == null) {
- futureStartNode = futureNodes[++futureStart];
- } else if (futureEndNode == null) {
- futureEndNode = futureNodes[--futureEnd];
- } else if (currentStartNode == futureStartNode) {
- currentStartNode = currentNodes[++currentStart];
- futureStartNode = futureNodes[++futureStart];
- } else if (currentEndNode == futureEndNode) {
- currentEndNode = currentNodes[--currentEnd];
- futureEndNode = futureNodes[--futureEnd];
- } else if (currentStartNode == futureEndNode) {
- parentNode.insertBefore(get(currentStartNode, 1), get(currentEndNode, -0).nextSibling);
- currentStartNode = currentNodes[++currentStart];
- futureEndNode = futureNodes[--futureEnd];
- } else if (currentEndNode == futureStartNode) {
- parentNode.insertBefore(get(currentEndNode, 1), get(currentStartNode, 0));
- currentEndNode = currentNodes[--currentEnd];
- futureStartNode = futureNodes[++futureStart];
- } else {
- var index = currentNodes.indexOf(futureStartNode);
- if (index < 0) {
- parentNode.insertBefore(get(futureStartNode, 1), get(currentStartNode, 0));
- futureStartNode = futureNodes[++futureStart];
- } else {
- var el = currentNodes[index];
- currentNodes[index] = null;
- parentNode.insertBefore(get(el, 1), get(currentStartNode, 0));
- futureStartNode = futureNodes[++futureStart];
- }
- }
- }
- if (currentStart <= currentEnd || futureStart <= futureEnd) {
- if (currentStart > currentEnd) {
- var pin = futureNodes[futureEnd + 1];
- var place = pin == null ? before : get(pin, 0);
- if (futureStart === futureEnd) {
- parentNode.insertBefore(get(futureNodes[futureStart], 1), place);
- } else {
- var fragment = parentNode.ownerDocument.createDocumentFragment();
- while (futureStart <= futureEnd) {
- fragment.appendChild(get(futureNodes[futureStart++], 1));
- }
- parentNode.insertBefore(fragment, place);
- }
- } else {
- if (currentNodes[currentStart] == null) currentStart++;
- if (currentStart === currentEnd) {
- parentNode.removeChild(get(currentNodes[currentStart], -1));
- } else {
- var range = parentNode.ownerDocument.createRange();
- range.setStartBefore(get(currentNodes[currentStart], -1));
- range.setEndAfter(get(currentNodes[currentEnd], -1));
- range.deleteContents();
- }
- }
- }
- return futureNodes;
-};
-
-// hyper.Component have a connected/disconnected
-// mechanism provided by MutationObserver
-// This weak set is used to recognize components
-// as DOM node that needs to trigger connected/disconnected events
-var components = new WeakSet();
-
-// a basic dictionary used to filter already cached attributes
-// while looking for special hyperHTML values.
-function Cache() {}
-Cache.prototype = Object.create(null);
-
-// returns an intent to explicitly inject content as html
-var asHTML = function asHTML(html) {
- return { html: html };
-};
-
-// returns nodes from wires and components
-var asNode = function asNode(item, i) {
- return 'ELEMENT_NODE' in item ? item : item.constructor === Wire ?
- // in the Wire case, the content can be
- // removed, post-pended, inserted, or pre-pended and
- // all these cases are handled by domdiff already
- /* istanbul ignore next */
- 1 / i < 0 ? i ? item.remove() : item.last : i ? item.insert() : item.first : asNode(item.render(), i);
-};
-
-// returns true if domdiff can handle the value
-var canDiff = function canDiff(value) {
- return 'ELEMENT_NODE' in value || value instanceof Wire || value instanceof Component;
-};
-
-// updates are created once per context upgrade
-// within the main render function (../hyper/render.js)
-// These are an Array of callbacks to invoke passing
-// each interpolation value.
-// Updates can be related to any kind of content,
-// attributes, or special text-only cases such <style>
-// elements or <textarea>
-var create$1 = function create$$1(root, paths) {
- var updates = [];
- var length = paths.length;
- for (var i = 0; i < length; i++) {
- var info = paths[i];
- var node = Path.find(root, info.path);
- switch (info.type) {
- case 'any':
- updates.push(setAnyContent(node, []));
- break;
- case 'attr':
- updates.push(setAttribute(node, info.name, info.node));
- break;
- case 'text':
- updates.push(setTextContent(node));
- break;
- }
- }
- return updates;
-};
-
-// finding all paths is a one-off operation performed
-// when a new template literal is used.
-// The goal is to map all target nodes that will be
-// used to update content/attributes every time
-// the same template literal is used to create content.
-// The result is a list of paths related to the template
-// with all the necessary info to create updates as
-// list of callbacks that target directly affected nodes.
-var find = function find(node, paths, parts) {
- var childNodes = node.childNodes;
- var length = childNodes.length;
- for (var i = 0; i < length; i++) {
- var child = childNodes[i];
- switch (child.nodeType) {
- case ELEMENT_NODE:
- findAttributes$1(child, paths, parts);
- find(child, paths, parts);
- break;
- case COMMENT_NODE:
- if (child.textContent === UID) {
- parts.shift();
- paths.push(
- // basicHTML or other non standard engines
- // might end up having comments in nodes
- // where they shouldn't, hence this check.
- SHOULD_USE_TEXT_CONTENT.test(node.nodeName) ? Path.create('text', node) : Path.create('any', child));
- }
- break;
- case TEXT_NODE:
- // the following ignore is actually covered by browsers
- // only basicHTML ends up on previous COMMENT_NODE case
- // instead of TEXT_NODE because it knows nothing about
- // special style or textarea behavior
- /* istanbul ignore if */
- Iif (SHOULD_USE_TEXT_CONTENT.test(node.nodeName) && trim.call(child.textContent) === UIDC) {
- parts.shift();
- paths.push(Path.create('text', node));
- }
- break;
- }
- }
-};
-
-// attributes are searched via unique hyperHTML id value.
-// Despite HTML being case insensitive, hyperHTML is able
-// to recognize attributes by name in a caseSensitive way.
-// This plays well with Custom Elements definitions
-// and also with XML-like environments, without trusting
-// the resulting DOM but the template literal as the source of truth.
-// IE/Edge has a funny bug with attributes and these might be duplicated.
-// This is why there is a cache in charge of being sure no duplicated
-// attributes are ever considered in future updates.
-var findAttributes$1 = function findAttributes(node, paths, parts) {
- var cache = new Cache();
- var attributes = node.attributes;
- var array = slice.call(attributes);
- var remove = [];
- var length = array.length;
- for (var i = 0; i < length; i++) {
- var attribute = array[i];
- if (attribute.value === UID) {
- var name = attribute.name;
- // the following ignore is covered by IE
- // and the IE9 double viewBox test
- /* istanbul ignore else */
- Eif (!(name in cache)) {
- var realName = parts.shift().replace(/^(?:|[\S\s]*?\s)(\S+?)=['"]?$/, '$1');
- cache[name] = attributes[realName] ||
- // the following ignore is covered by browsers
- // while basicHTML is already case-sensitive
- /* istanbul ignore next */
- attributes[realName.toLowerCase()];
- paths.push(Path.create('attr', cache[name], realName));
- }
- remove.push(attribute);
- }
- }
- var len = remove.length;
- for (var _i = 0; _i < len; _i++) {
- node.removeAttributeNode(remove[_i]);
- }
-
- // This is a very specific Firefox/Safari issue
- // but since it should be a not so common pattern,
- // it's probably worth patching regardless.
- // Basically, scripts created through strings are death.
- // You need to create fresh new scripts instead.
- // TODO: is there any other node that needs such nonsense ?
- var nodeName = node.nodeName;
- if (/^script$/i.test(nodeName)) {
- var script = create(node, nodeName);
- for (var _i2 = 0; _i2 < attributes.length; _i2++) {
- script.setAttributeNode(attributes[_i2].cloneNode(true));
- }
- script.textContent = node.textContent;
- node.parentNode.replaceChild(script, node);
- }
-};
-
-// when a Promise is used as interpolation value
-// its result must be parsed once resolved.
-// This callback is in charge of understanding what to do
-// with a returned value once the promise is resolved.
-var invokeAtDistance = function invokeAtDistance(value, callback) {
- callback(value.placeholder);
- if ('text' in value) {
- Promise.resolve(value.text).then(String).then(callback);
- } else if ('any' in value) {
- Promise.resolve(value.any).then(callback);
- } else if ('html' in value) {
- Promise.resolve(value.html).then(asHTML).then(callback);
- } else {
- Promise.resolve(Intent.invoke(value, callback)).then(callback);
- }
-};
-
-// quick and dirty way to check for Promise/ish values
-var isPromise_ish = function isPromise_ish(value) {
- return value != null && 'then' in value;
-};
-
-// in a hyper(node)`<div>${content}</div>` case
-// everything could happen:
-// * it's a JS primitive, stored as text
-// * it's null or undefined, the node should be cleaned
-// * it's a component, update the content by rendering it
-// * it's a promise, update the content once resolved
-// * it's an explicit intent, perform the desired operation
-// * it's an Array, resolve all values if Promises and/or
-// update the node with the resulting list of content
-var setAnyContent = function setAnyContent(node, childNodes) {
- var fastPath = false;
- var oldValue = void 0;
- var anyContent = function anyContent(value) {
- switch (typeof value) {
- case 'string':
- case 'number':
- case 'boolean':
- if (fastPath) {
- if (oldValue !== value) {
- oldValue = value;
- childNodes[0].textContent = value;
- }
- } else {
- fastPath = true;
- oldValue = value;
- childNodes = domdiff(node.parentNode, childNodes, [text(node, value)], asNode, node);
- }
- break;
- case 'object':
- case 'undefined':
- if (value == null) {
- fastPath = false;
- childNodes = domdiff(node.parentNode, childNodes, [], asNode, node);
- break;
- }
- default:
- fastPath = false;
- oldValue = value;
- if (isArray(value)) {
- if (value.length === 0) {
- if (childNodes.length) {
- childNodes = domdiff(node.parentNode, childNodes, [], asNode, node);
- }
- } else {
- switch (typeof value[0]) {
- case 'string':
- case 'number':
- case 'boolean':
- anyContent({ html: value });
- break;
- case 'object':
- if (isArray(value[0])) {
- value = value.concat.apply([], value);
- }
- if (isPromise_ish(value[0])) {
- Promise.all(value).then(anyContent);
- break;
- }
- default:
- childNodes = domdiff(node.parentNode, childNodes, value, asNode, node);
- break;
- }
- }
- } else if (canDiff(value)) {
- childNodes = domdiff(node.parentNode, childNodes, value.nodeType === DOCUMENT_FRAGMENT_NODE ? slice.call(value.childNodes) : [value], asNode, node);
- } else if (isPromise_ish(value)) {
- value.then(anyContent);
- } else if ('placeholder' in value) {
- invokeAtDistance(value, anyContent);
- } else if ('text' in value) {
- anyContent(String(value.text));
- } else if ('any' in value) {
- anyContent(value.any);
- } else if ('html' in value) {
- childNodes = domdiff(node.parentNode, childNodes, slice.call(createFragment(node, [].concat(value.html).join('')).childNodes), asNode, node);
- } else if ('length' in value) {
- anyContent(slice.call(value));
- } else {
- anyContent(Intent.invoke(value, anyContent));
- }
- break;
- }
- };
- return anyContent;
-};
-
-// there are four kind of attributes, and related behavior:
-// * events, with a name starting with `on`, to add/remove event listeners
-// * special, with a name present in their inherited prototype, accessed directly
-// * regular, accessed through get/setAttribute standard DOM methods
-// * style, the only regular attribute that also accepts an object as value
-// so that you can style=${{width: 120}}. In this case, the behavior has been
-// fully inspired by Preact library and its simplicity.
-var setAttribute = function setAttribute(node, name, original) {
- var isSVG = OWNER_SVG_ELEMENT in node;
- var oldValue = void 0;
- // if the attribute is the style one
- // handle it differently from others
- if (name === 'style') {
- return Style(node, original, isSVG);
- }
- // the name is an event one,
- // add/remove event listeners accordingly
- else if (/^on/.test(name)) {
- var type = name.slice(2);
- if (type === CONNECTED || type === DISCONNECTED) {
- if (notObserving) {
- notObserving = false;
- observe();
- }
- components.add(node);
- } else if (name.toLowerCase() in node) {
- type = type.toLowerCase();
- }
- return function (newValue) {
- if (oldValue !== newValue) {
- if (oldValue) node.removeEventListener(type, oldValue, false);
- oldValue = newValue;
- if (newValue) node.addEventListener(type, newValue, false);
- }
- };
- }
- // the attribute is special ('value' in input)
- // and it's not SVG *or* the name is exactly data,
- // in this case assign the value directly
- else if (name === 'data' || !isSVG && name in node) {
- return function (newValue) {
- if (oldValue !== newValue) {
- oldValue = newValue;
- if (node[name] !== newValue) {
- node[name] = newValue;
- if (newValue == null) {
- node.removeAttribute(name);
- }
- }
- }
- };
- }
- // in every other case, use the attribute node as it is
- // update only the value, set it as node only when/if needed
- else {
- var owner = false;
- var attribute = original.cloneNode(true);
- return function (newValue) {
- if (oldValue !== newValue) {
- oldValue = newValue;
- if (attribute.value !== newValue) {
- if (newValue == null) {
- if (owner) {
- owner = false;
- node.removeAttributeNode(attribute);
- }
- attribute.value = newValue;
- } else {
- attribute.value = newValue;
- if (!owner) {
- owner = true;
- node.setAttributeNode(attribute);
- }
- }
- }
- }
- };
- }
-};
-
-// style or textareas don't accept HTML as content
-// it's pointless to transform or analyze anything
-// different from text there but it's worth checking
-// for possible defined intents.
-var setTextContent = function setTextContent(node) {
- // avoid hyper comments inside textarea/style when value is undefined
- var oldValue = '';
- var textContent = function textContent(value) {
- if (oldValue !== value) {
- oldValue = value;
- if (typeof value === 'object' && value) {
- if (isPromise_ish(value)) {
- value.then(textContent);
- } else if ('placeholder' in value) {
- invokeAtDistance(value, textContent);
- } else if ('text' in value) {
- textContent(String(value.text));
- } else if ('any' in value) {
- textContent(value.any);
- } else if ('html' in value) {
- textContent([].concat(value.html).join(''));
- } else if ('length' in value) {
- textContent(slice.call(value).join(''));
- } else {
- textContent(Intent.invoke(value, textContent));
- }
- } else {
- node.textContent = value == null ? '' : value;
- }
- }
- };
- return textContent;
-};
-
-var Updates = { create: create$1, find: find };
-
-// hyper.Components might need connected/disconnected notifications
-// used by components and their onconnect/ondisconnect callbacks.
-// When one of these callbacks is encountered,
-// the document starts being observed.
-var notObserving = true;
-function observe() {
-
- // when hyper.Component related DOM nodes
- // are appended or removed from the live tree
- // these might listen to connected/disconnected events
- // This utility is in charge of finding all components
- // involved in the DOM update/change and dispatch
- // related information to them
- var dispatchAll = function dispatchAll(nodes, type) {
- var event = new Event(type);
- var length = nodes.length;
- for (var i = 0; i < length; i++) {
- var node = nodes[i];
- if (node.nodeType === ELEMENT_NODE) {
- dispatchTarget(node, event);
- }
- }
- };
-
- // the way it's done is via the components weak set
- // and recursively looking for nested components too
- var dispatchTarget = function dispatchTarget(node, event) {
- if (components.has(node)) {
- node.dispatchEvent(event);
- }
-
- var children = node.children;
- var length = children.length;
- for (var i = 0; i < length; i++) {
- dispatchTarget(children[i], event);
- }
- };
-
- // The MutationObserver is the best way to implement that
- // but there is a fallback to deprecated DOMNodeInserted/Removed
- // so that even older browsers/engines can help components life-cycle
- try {
- new MutationObserver(function (records) {
- var length = records.length;
- for (var i = 0; i < length; i++) {
- var record = records[i];
- dispatchAll(record.removedNodes, DISCONNECTED);
- dispatchAll(record.addedNodes, CONNECTED);
- }
- }).observe(document, { subtree: true, childList: true });
- } catch (o_O) {
- document.addEventListener('DOMNodeRemoved', function (event) {
- dispatchAll([event.target], DISCONNECTED);
- }, false);
- document.addEventListener('DOMNodeInserted', function (event) {
- dispatchAll([event.target], CONNECTED);
- }, false);
- }
-}
-
-// a weak collection of contexts that
-// are already known to hyperHTML
-var bewitched = new WeakMap();
-
-// the collection of all template literals
-// since these are unique and immutable
-// for the whole application life-cycle
-var templates = new Map();
-
-// better known as hyper.bind(node), the render is
-// the main tag function in charge of fully upgrading
-// or simply updating, contexts used as hyperHTML targets.
-// The `this` context is either a regular DOM node or a fragment.
-function render(template) {
- var wicked = bewitched.get(this);
- if (wicked && wicked.template === unique(template)) {
- update$1.apply(wicked.updates, arguments);
- } else {
- upgrade.apply(this, arguments);
- }
- return this;
-}
-
-// an upgrade is in charge of collecting template info,
-// parse it once, if unknown, to map all interpolations
-// as single DOM callbacks, relate such template
-// to the current context, and render it after cleaning the context up
-function upgrade(template) {
- template = unique(template);
- var info = templates.get(template) || createTemplate.call(this, template);
- var fragment = importNode(this.ownerDocument, info.fragment);
- var updates = Updates.create(fragment, info.paths);
- bewitched.set(this, { template: template, updates: updates });
- update$1.apply(updates, arguments);
- this.textContent = '';
- this.appendChild(fragment);
-}
-
-// an update simply loops over all mapped DOM operations
-function update$1() {
- var length = arguments.length;
- for (var i = 1; i < length; i++) {
- this[i - 1](arguments[i]);
- }
-}
-
-// a template can be used to create a document fragment
-// aware of all interpolations and with a list
-// of paths used to find once those nodes that need updates,
-// no matter if these are attributes, text nodes, or regular one
-function createTemplate(template) {
- var paths = [];
- var html = template.join(UIDC).replace(SC_RE, SC_PLACE);
- var fragment = createFragment(this, html);
- Updates.find(fragment, paths, template.slice());
- var info = { fragment: fragment, paths: paths };
- templates.set(template, info);
- return info;
-}
-
-// some node could be special though, like a custom element
-// with a self closing tag, which should work through these changes.
-var SC_RE = selfClosing;
-var SC_PLACE = function SC_PLACE($0, $1, $2) {
- return VOID_ELEMENTS.test($1) ? $0 : '<' + $1 + $2 + '></' + $1 + '>';
-};
-
-// all wires used per each context
-var wires = new WeakMap();
-
-// A wire is a callback used as tag function
-// to lazily relate a generic object to a template literal.
-// hyper.wire(user)`<div id=user>${user.name}</div>`; => the div#user
-// This provides the ability to have a unique DOM structure
-// related to a unique JS object through a reusable template literal.
-// A wire can specify a type, as svg or html, and also an id
-// via html:id or :id convention. Such :id allows same JS objects
-// to be associated to different DOM structures accordingly with
-// the used template literal without losing previously rendered parts.
-var wire = function wire(obj, type) {
- return obj == null ? content(type || 'html') : weakly(obj, type || 'html');
-};
-
-// A wire content is a virtual reference to one or more nodes.
-// It's represented by either a DOM node, or an Array.
-// In both cases, the wire content role is to simply update
-// all nodes through the list of related callbacks.
-// In few words, a wire content is like an invisible parent node
-// in charge of updating its content like a bound element would do.
-var content = function content(type) {
- var wire = void 0,
- container = void 0,
- content = void 0,
- template = void 0,
- updates = void 0;
- return function (statics) {
- statics = unique(statics);
- var setup = template !== statics;
- if (setup) {
- template = statics;
- content = fragment(document);
- container = type === 'svg' ? document.createElementNS(SVG_NAMESPACE, 'svg') : content;
- updates = render.bind(container);
- }
- updates.apply(null, arguments);
- if (setup) {
- if (type === 'svg') {
- append(content, slice.call(container.childNodes));
- }
- wire = wireContent(content);
- }
- return wire;
- };
-};
-
-// wires are weakly created through objects.
-// Each object can have multiple wires associated
-// and this is thanks to the type + :id feature.
-var weakly = function weakly(obj, type) {
- var i = type.indexOf(':');
- var wire = wires.get(obj);
- var id = type;
- if (-1 < i) {
- id = type.slice(i + 1);
- type = type.slice(0, i) || 'html';
- }
- if (!wire) wires.set(obj, wire = {});
- return wire[id] || (wire[id] = content(type));
-};
-
-// a document fragment loses its nodes as soon
-// as it's appended into another node.
-// This would easily lose wired content
-// so that on a second render call, the parent
-// node wouldn't know which node was there
-// associated to the interpolation.
-// To prevent hyperHTML to forget about wired nodes,
-// these are either returned as Array or, if there's ony one entry,
-// as single referenced node that won't disappear from the fragment.
-// The initial fragment, at this point, would be used as unique reference.
-var wireContent = function wireContent(node) {
- var childNodes = node.childNodes;
- var length = childNodes.length;
- var wireNodes = [];
- for (var i = 0; i < length; i++) {
- var child = childNodes[i];
- if (child.nodeType === ELEMENT_NODE || trim.call(child.textContent).length !== 0) {
- wireNodes.push(child);
- }
- }
- return wireNodes.length === 1 ? wireNodes[0] : new Wire(wireNodes);
-};
-
-/*! (c) Andrea Giammarchi (ISC) */
-
-// all functions are self bound to the right context
-// you can do the following
-// const {bind, wire} = hyperHTML;
-// and use them right away: bind(node)`hello!`;
-var bind = function bind(context) {
- return render.bind(context);
-};
-var define = Intent.define;
-
-hyper.Component = Component;
-hyper.bind = bind;
-hyper.define = define;
-hyper.diff = domdiff;
-hyper.hyper = hyper;
-hyper.wire = wire;
-
-// the wire content is the lazy defined
-// html or svg property of each hyper.Component
-setup(content);
-
-// by default, hyperHTML is a smart function
-// that "magically" understands what's the best
-// thing to do with passed arguments
-function hyper(HTML) {
- return arguments.length < 2 ? HTML == null ? content('html') : typeof HTML === 'string' ? hyper.wire(null, HTML) : 'raw' in HTML ? content('html')(HTML) : 'nodeType' in HTML ? hyper.bind(HTML) : weakly(HTML, 'html') : ('raw' in HTML ? content('html') : hyper.wire).apply(null, arguments);
-}
-
-
-
-
-
-
-
-
-
-return hyper;
-
-}(window));
-module.exports = hyperHTML;
- |