livereload-morph 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/livereload-morph.cjs +56 -11
- package/dist/livereload-morph.esm.js +56 -11
- package/dist/livereload-morph.js +56 -11
- package/dist/livereload-morph.min.js +1 -1
- package/package.json +1 -1
|
@@ -1084,6 +1084,17 @@ class Morpher {
|
|
|
1084
1084
|
this.Timer = Timer2;
|
|
1085
1085
|
this.document = window2.document;
|
|
1086
1086
|
this.importCacheWaitPeriod = importCacheWaitPeriod;
|
|
1087
|
+
this.preserveStateCallback = (attributeName, node) => {
|
|
1088
|
+
if (node.tagName === "INPUT" || node.tagName === "TEXTAREA" || node.tagName === "SELECT") {
|
|
1089
|
+
if (attributeName === "value" || attributeName === "checked") {
|
|
1090
|
+
return false;
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
if (node.tagName === "DETAILS" && attributeName === "open") {
|
|
1094
|
+
return false;
|
|
1095
|
+
}
|
|
1096
|
+
return true;
|
|
1097
|
+
};
|
|
1087
1098
|
}
|
|
1088
1099
|
reload(path, options = {}) {
|
|
1089
1100
|
const isCSSFile = path.match(/\.css(?:\.map)?$/i);
|
|
@@ -1125,6 +1136,16 @@ class Morpher {
|
|
|
1125
1136
|
}
|
|
1126
1137
|
},
|
|
1127
1138
|
callbacks: {
|
|
1139
|
+
beforeNodeMorphed: (oldNode, newNode) => {
|
|
1140
|
+
if (oldNode.tagName === "IFRAME" && newNode.tagName === "IFRAME") {
|
|
1141
|
+
const newSrcdoc = newNode.getAttribute("srcdoc");
|
|
1142
|
+
if (newSrcdoc !== null) {
|
|
1143
|
+
this.morphIframeSrcdoc(oldNode, newSrcdoc, options);
|
|
1144
|
+
return false;
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
return true;
|
|
1148
|
+
},
|
|
1128
1149
|
afterNodeMorphed: (oldNode) => {
|
|
1129
1150
|
if (options.morphShadowDOM === false)
|
|
1130
1151
|
return;
|
|
@@ -1155,17 +1176,7 @@ class Morpher {
|
|
|
1155
1176
|
}
|
|
1156
1177
|
}
|
|
1157
1178
|
},
|
|
1158
|
-
beforeAttributeUpdated:
|
|
1159
|
-
if (node.tagName === "INPUT" || node.tagName === "TEXTAREA" || node.tagName === "SELECT") {
|
|
1160
|
-
if (attributeName === "value" || attributeName === "checked") {
|
|
1161
|
-
return false;
|
|
1162
|
-
}
|
|
1163
|
-
}
|
|
1164
|
-
if (node.tagName === "DETAILS" && attributeName === "open") {
|
|
1165
|
-
return false;
|
|
1166
|
-
}
|
|
1167
|
-
return true;
|
|
1168
|
-
}
|
|
1179
|
+
beforeAttributeUpdated: this.preserveStateCallback
|
|
1169
1180
|
}
|
|
1170
1181
|
});
|
|
1171
1182
|
this.console.log("HTML morphed successfully");
|
|
@@ -1177,6 +1188,40 @@ class Morpher {
|
|
|
1177
1188
|
}
|
|
1178
1189
|
}
|
|
1179
1190
|
}
|
|
1191
|
+
morphIframeSrcdoc(iframe, newSrcdoc, options = {}) {
|
|
1192
|
+
try {
|
|
1193
|
+
const iframeDoc = iframe.contentDocument;
|
|
1194
|
+
if (!iframeDoc || !iframeDoc.body) {
|
|
1195
|
+
this.console.log("Cannot access iframe contentDocument, falling back to srcdoc replacement");
|
|
1196
|
+
iframe.setAttribute("srcdoc", newSrcdoc);
|
|
1197
|
+
return;
|
|
1198
|
+
}
|
|
1199
|
+
const parser = new DOMParser;
|
|
1200
|
+
const newDoc = parser.parseFromString(newSrcdoc, "text/html");
|
|
1201
|
+
const morphOptions = {
|
|
1202
|
+
morphStyle: "innerHTML",
|
|
1203
|
+
callbacks: {
|
|
1204
|
+
beforeAttributeUpdated: this.preserveStateCallback
|
|
1205
|
+
}
|
|
1206
|
+
};
|
|
1207
|
+
if (newDoc.head) {
|
|
1208
|
+
if (iframeDoc.head) {
|
|
1209
|
+
Idiomorph.morph(iframeDoc.head, newDoc.head.innerHTML, morphOptions);
|
|
1210
|
+
} else {
|
|
1211
|
+
const head = iframeDoc.createElement("head");
|
|
1212
|
+
head.innerHTML = newDoc.head.innerHTML;
|
|
1213
|
+
iframeDoc.documentElement.insertBefore(head, iframeDoc.body);
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
if (newDoc.body) {
|
|
1217
|
+
Idiomorph.morph(iframeDoc.body, newDoc.body.innerHTML, morphOptions);
|
|
1218
|
+
}
|
|
1219
|
+
this.console.log("iframe srcdoc morphed successfully");
|
|
1220
|
+
} catch (error) {
|
|
1221
|
+
this.console.error(`iframe srcdoc morph failed, so we fall back. msg: ${error.message}`);
|
|
1222
|
+
iframe.setAttribute("srcdoc", newSrcdoc);
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1180
1225
|
async reloadStylesheet(path, options = {}) {
|
|
1181
1226
|
try {
|
|
1182
1227
|
const links = Array.from(this.document.getElementsByTagName("link")).filter((link) => link.rel && link.rel.match(/^stylesheet$/i) && !link.__LiveReload_pendingRemoval);
|
|
@@ -1049,6 +1049,17 @@ class Morpher {
|
|
|
1049
1049
|
this.Timer = Timer2;
|
|
1050
1050
|
this.document = window2.document;
|
|
1051
1051
|
this.importCacheWaitPeriod = importCacheWaitPeriod;
|
|
1052
|
+
this.preserveStateCallback = (attributeName, node) => {
|
|
1053
|
+
if (node.tagName === "INPUT" || node.tagName === "TEXTAREA" || node.tagName === "SELECT") {
|
|
1054
|
+
if (attributeName === "value" || attributeName === "checked") {
|
|
1055
|
+
return false;
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
if (node.tagName === "DETAILS" && attributeName === "open") {
|
|
1059
|
+
return false;
|
|
1060
|
+
}
|
|
1061
|
+
return true;
|
|
1062
|
+
};
|
|
1052
1063
|
}
|
|
1053
1064
|
reload(path, options = {}) {
|
|
1054
1065
|
const isCSSFile = path.match(/\.css(?:\.map)?$/i);
|
|
@@ -1090,6 +1101,16 @@ class Morpher {
|
|
|
1090
1101
|
}
|
|
1091
1102
|
},
|
|
1092
1103
|
callbacks: {
|
|
1104
|
+
beforeNodeMorphed: (oldNode, newNode) => {
|
|
1105
|
+
if (oldNode.tagName === "IFRAME" && newNode.tagName === "IFRAME") {
|
|
1106
|
+
const newSrcdoc = newNode.getAttribute("srcdoc");
|
|
1107
|
+
if (newSrcdoc !== null) {
|
|
1108
|
+
this.morphIframeSrcdoc(oldNode, newSrcdoc, options);
|
|
1109
|
+
return false;
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
return true;
|
|
1113
|
+
},
|
|
1093
1114
|
afterNodeMorphed: (oldNode) => {
|
|
1094
1115
|
if (options.morphShadowDOM === false)
|
|
1095
1116
|
return;
|
|
@@ -1120,17 +1141,7 @@ class Morpher {
|
|
|
1120
1141
|
}
|
|
1121
1142
|
}
|
|
1122
1143
|
},
|
|
1123
|
-
beforeAttributeUpdated:
|
|
1124
|
-
if (node.tagName === "INPUT" || node.tagName === "TEXTAREA" || node.tagName === "SELECT") {
|
|
1125
|
-
if (attributeName === "value" || attributeName === "checked") {
|
|
1126
|
-
return false;
|
|
1127
|
-
}
|
|
1128
|
-
}
|
|
1129
|
-
if (node.tagName === "DETAILS" && attributeName === "open") {
|
|
1130
|
-
return false;
|
|
1131
|
-
}
|
|
1132
|
-
return true;
|
|
1133
|
-
}
|
|
1144
|
+
beforeAttributeUpdated: this.preserveStateCallback
|
|
1134
1145
|
}
|
|
1135
1146
|
});
|
|
1136
1147
|
this.console.log("HTML morphed successfully");
|
|
@@ -1142,6 +1153,40 @@ class Morpher {
|
|
|
1142
1153
|
}
|
|
1143
1154
|
}
|
|
1144
1155
|
}
|
|
1156
|
+
morphIframeSrcdoc(iframe, newSrcdoc, options = {}) {
|
|
1157
|
+
try {
|
|
1158
|
+
const iframeDoc = iframe.contentDocument;
|
|
1159
|
+
if (!iframeDoc || !iframeDoc.body) {
|
|
1160
|
+
this.console.log("Cannot access iframe contentDocument, falling back to srcdoc replacement");
|
|
1161
|
+
iframe.setAttribute("srcdoc", newSrcdoc);
|
|
1162
|
+
return;
|
|
1163
|
+
}
|
|
1164
|
+
const parser = new DOMParser;
|
|
1165
|
+
const newDoc = parser.parseFromString(newSrcdoc, "text/html");
|
|
1166
|
+
const morphOptions = {
|
|
1167
|
+
morphStyle: "innerHTML",
|
|
1168
|
+
callbacks: {
|
|
1169
|
+
beforeAttributeUpdated: this.preserveStateCallback
|
|
1170
|
+
}
|
|
1171
|
+
};
|
|
1172
|
+
if (newDoc.head) {
|
|
1173
|
+
if (iframeDoc.head) {
|
|
1174
|
+
Idiomorph.morph(iframeDoc.head, newDoc.head.innerHTML, morphOptions);
|
|
1175
|
+
} else {
|
|
1176
|
+
const head = iframeDoc.createElement("head");
|
|
1177
|
+
head.innerHTML = newDoc.head.innerHTML;
|
|
1178
|
+
iframeDoc.documentElement.insertBefore(head, iframeDoc.body);
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
if (newDoc.body) {
|
|
1182
|
+
Idiomorph.morph(iframeDoc.body, newDoc.body.innerHTML, morphOptions);
|
|
1183
|
+
}
|
|
1184
|
+
this.console.log("iframe srcdoc morphed successfully");
|
|
1185
|
+
} catch (error) {
|
|
1186
|
+
this.console.error(`iframe srcdoc morph failed, so we fall back. msg: ${error.message}`);
|
|
1187
|
+
iframe.setAttribute("srcdoc", newSrcdoc);
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1145
1190
|
async reloadStylesheet(path, options = {}) {
|
|
1146
1191
|
try {
|
|
1147
1192
|
const links = Array.from(this.document.getElementsByTagName("link")).filter((link) => link.rel && link.rel.match(/^stylesheet$/i) && !link.__LiveReload_pendingRemoval);
|
package/dist/livereload-morph.js
CHANGED
|
@@ -1084,6 +1084,17 @@
|
|
|
1084
1084
|
this.Timer = Timer2;
|
|
1085
1085
|
this.document = window2.document;
|
|
1086
1086
|
this.importCacheWaitPeriod = importCacheWaitPeriod;
|
|
1087
|
+
this.preserveStateCallback = (attributeName, node) => {
|
|
1088
|
+
if (node.tagName === "INPUT" || node.tagName === "TEXTAREA" || node.tagName === "SELECT") {
|
|
1089
|
+
if (attributeName === "value" || attributeName === "checked") {
|
|
1090
|
+
return false;
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
if (node.tagName === "DETAILS" && attributeName === "open") {
|
|
1094
|
+
return false;
|
|
1095
|
+
}
|
|
1096
|
+
return true;
|
|
1097
|
+
};
|
|
1087
1098
|
}
|
|
1088
1099
|
reload(path, options = {}) {
|
|
1089
1100
|
const isCSSFile = path.match(/\.css(?:\.map)?$/i);
|
|
@@ -1125,6 +1136,16 @@
|
|
|
1125
1136
|
}
|
|
1126
1137
|
},
|
|
1127
1138
|
callbacks: {
|
|
1139
|
+
beforeNodeMorphed: (oldNode, newNode) => {
|
|
1140
|
+
if (oldNode.tagName === "IFRAME" && newNode.tagName === "IFRAME") {
|
|
1141
|
+
const newSrcdoc = newNode.getAttribute("srcdoc");
|
|
1142
|
+
if (newSrcdoc !== null) {
|
|
1143
|
+
this.morphIframeSrcdoc(oldNode, newSrcdoc, options);
|
|
1144
|
+
return false;
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
return true;
|
|
1148
|
+
},
|
|
1128
1149
|
afterNodeMorphed: (oldNode) => {
|
|
1129
1150
|
if (options.morphShadowDOM === false)
|
|
1130
1151
|
return;
|
|
@@ -1155,17 +1176,7 @@
|
|
|
1155
1176
|
}
|
|
1156
1177
|
}
|
|
1157
1178
|
},
|
|
1158
|
-
beforeAttributeUpdated:
|
|
1159
|
-
if (node.tagName === "INPUT" || node.tagName === "TEXTAREA" || node.tagName === "SELECT") {
|
|
1160
|
-
if (attributeName === "value" || attributeName === "checked") {
|
|
1161
|
-
return false;
|
|
1162
|
-
}
|
|
1163
|
-
}
|
|
1164
|
-
if (node.tagName === "DETAILS" && attributeName === "open") {
|
|
1165
|
-
return false;
|
|
1166
|
-
}
|
|
1167
|
-
return true;
|
|
1168
|
-
}
|
|
1179
|
+
beforeAttributeUpdated: this.preserveStateCallback
|
|
1169
1180
|
}
|
|
1170
1181
|
});
|
|
1171
1182
|
this.console.log("HTML morphed successfully");
|
|
@@ -1177,6 +1188,40 @@
|
|
|
1177
1188
|
}
|
|
1178
1189
|
}
|
|
1179
1190
|
}
|
|
1191
|
+
morphIframeSrcdoc(iframe, newSrcdoc, options = {}) {
|
|
1192
|
+
try {
|
|
1193
|
+
const iframeDoc = iframe.contentDocument;
|
|
1194
|
+
if (!iframeDoc || !iframeDoc.body) {
|
|
1195
|
+
this.console.log("Cannot access iframe contentDocument, falling back to srcdoc replacement");
|
|
1196
|
+
iframe.setAttribute("srcdoc", newSrcdoc);
|
|
1197
|
+
return;
|
|
1198
|
+
}
|
|
1199
|
+
const parser = new DOMParser;
|
|
1200
|
+
const newDoc = parser.parseFromString(newSrcdoc, "text/html");
|
|
1201
|
+
const morphOptions = {
|
|
1202
|
+
morphStyle: "innerHTML",
|
|
1203
|
+
callbacks: {
|
|
1204
|
+
beforeAttributeUpdated: this.preserveStateCallback
|
|
1205
|
+
}
|
|
1206
|
+
};
|
|
1207
|
+
if (newDoc.head) {
|
|
1208
|
+
if (iframeDoc.head) {
|
|
1209
|
+
Idiomorph.morph(iframeDoc.head, newDoc.head.innerHTML, morphOptions);
|
|
1210
|
+
} else {
|
|
1211
|
+
const head = iframeDoc.createElement("head");
|
|
1212
|
+
head.innerHTML = newDoc.head.innerHTML;
|
|
1213
|
+
iframeDoc.documentElement.insertBefore(head, iframeDoc.body);
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
if (newDoc.body) {
|
|
1217
|
+
Idiomorph.morph(iframeDoc.body, newDoc.body.innerHTML, morphOptions);
|
|
1218
|
+
}
|
|
1219
|
+
this.console.log("iframe srcdoc morphed successfully");
|
|
1220
|
+
} catch (error) {
|
|
1221
|
+
this.console.error(`iframe srcdoc morph failed, so we fall back. msg: ${error.message}`);
|
|
1222
|
+
iframe.setAttribute("srcdoc", newSrcdoc);
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1180
1225
|
async reloadStylesheet(path, options = {}) {
|
|
1181
1226
|
try {
|
|
1182
1227
|
const links = Array.from(this.document.getElementsByTagName("link")).filter((link) => link.rel && link.rel.match(/^stylesheet$/i) && !link.__LiveReload_pendingRemoval);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var{defineProperty:h,getOwnPropertyNames:l,getOwnPropertyDescriptor:o}=Object,n=Object.prototype.hasOwnProperty;var m=new WeakMap,t=(_)=>{var $=m.get(_),Z;if($)return $;if($=h({},"__esModule",{value:!0}),_&&typeof _==="object"||typeof _==="function")l(_).map((K)=>!n.call($,K)&&h($,K,{get:()=>_[K],enumerable:!(Z=o(_,K))||Z.enumerable}));return m.set(_,$),$};var e=(_,$)=>{for(var Z in $)h(_,Z,{get:$[Z],enumerable:!0,configurable:!0,set:(K)=>$[Z]=()=>K})};var J_={};e(J_,{default:()=>G_});var c="http://livereload.com/protocols/official-6",s="http://livereload.com/protocols/official-7";class I{constructor(_,$){this.message=`LiveReload protocol error (${_}) after receiving data: "${$}".`}}class E{constructor(_){this.handlers=_,this.reset()}reset(){this.protocol=null}process(_){try{let $;if(!this.protocol){if(_.match(new RegExp("^!!ver:([\\d.]+)$")))this.protocol=6;else if($=this._parseMessage(_,["hello"]))if(!$.protocols.length)throw new I("no protocols specified in handshake message");else if(Array.from($.protocols).includes("http://livereload.com/protocols/official-7"))this.protocol=7;else if(Array.from($.protocols).includes("http://livereload.com/protocols/official-6"))this.protocol=6;else throw new I("no supported protocols found");return this.handlers.connected(this.protocol)}if(this.protocol===6){if($=JSON.parse(_),!$.length)throw new I("protocol 6 messages must be arrays");let[Z,K]=Array.from($);if(Z!=="refresh")throw new I("unknown protocol 6 command");return this.handlers.message({command:"reload",path:K.path,liveCSS:K.apply_css_live!=null?K.apply_css_live:!0})}return $=this._parseMessage(_,["reload","alert"]),this.handlers.message($)}catch($){if($ instanceof I)return this.handlers.error($);throw $}}_parseMessage(_,$){let Z;try{Z=JSON.parse(_)}catch(K){throw new I("unparsable JSON",_)}if(!Z.command)throw new I('missing "command" key',_);if(!$.includes(Z.command))throw new I(`invalid command '${Z.command}', only valid commands are: ${$.join(", ")})`,_);return Z}}var __="1.0.0";class x{constructor(_,$,Z,K){this.options=_,this.WebSocket=$,this.Timer=Z,this.handlers=K;let X=this.options.path?`${this.options.path}`:"livereload",Y=this.options.port?`:${this.options.port}`:"";this._uri=`ws${this.options.https?"s":""}://${this.options.host}${Y}/${X}`,this._nextDelay=this.options.mindelay,this._connectionDesired=!1,this.protocol=0,this.protocolParser=new E({connected:(V)=>{return this.protocol=V,this._handshakeTimeout.stop(),this._nextDelay=this.options.mindelay,this._disconnectionReason="broken",this.handlers.connected(this.protocol)},error:(V)=>{return this.handlers.error(V),this._closeOnError()},message:(V)=>{return this.handlers.message(V)}}),this._handshakeTimeout=new this.Timer(()=>{if(!this._isSocketConnected())return;return this._disconnectionReason="handshake-timeout",this.socket.close()}),this._reconnectTimer=new this.Timer(()=>{if(!this._connectionDesired)return;return this.connect()}),this.connect()}_isSocketConnected(){return this.socket&&this.socket.readyState===this.WebSocket.OPEN}connect(){if(this._connectionDesired=!0,this._isSocketConnected())return;this._reconnectTimer.stop(),this._disconnectionReason="cannot-connect",this.protocolParser.reset(),this.handlers.connecting(),this.socket=new this.WebSocket(this._uri),this.socket.onopen=(_)=>this._onopen(_),this.socket.onclose=(_)=>this._onclose(_),this.socket.onmessage=(_)=>this._onmessage(_),this.socket.onerror=(_)=>this._onerror(_)}disconnect(){if(this._connectionDesired=!1,this._reconnectTimer.stop(),!this._isSocketConnected())return;return this._disconnectionReason="manual",this.socket.close()}_scheduleReconnection(){if(!this._connectionDesired)return;if(!this._reconnectTimer.running)this._reconnectTimer.start(this._nextDelay),this._nextDelay=Math.min(this.options.maxdelay,this._nextDelay*2)}sendCommand(_){if(!this.protocol)return;return this._sendCommand(_)}_sendCommand(_){return this.socket.send(JSON.stringify(_))}_closeOnError(){return this._handshakeTimeout.stop(),this._disconnectionReason="error",this.socket.close()}_onopen(_){this.handlers.socketConnected(),this._disconnectionReason="handshake-failed";let $={command:"hello",protocols:[c,s]};return $.ver=__,this._sendCommand($),this._handshakeTimeout.start(this.options.handshake_timeout)}_onclose(_){return this.protocol=0,this.handlers.disconnected(this._disconnectionReason,this._nextDelay),this._scheduleReconnection()}_onerror(_){}_onmessage(_){return this.protocolParser.process(_.data)}}class b{constructor(_){this.func=_,this.running=!1,this.id=null,this._handler=()=>{return this.running=!1,this.id=null,this.func()}}start(_){if(this.running)clearTimeout(this.id);this.id=setTimeout(this._handler,_),this.running=!0}stop(){if(this.running)clearTimeout(this.id),this.running=!1,this.id=null}}b.start=(_,$)=>setTimeout($,_);class S{constructor(){this.https=!1,this.host=null;let _=35729;Object.defineProperty(this,"port",{get(){return _},set($){_=$?isNaN($)?$:+$:""}}),this.mindelay=1000,this.maxdelay=60000,this.handshake_timeout=5000,this.morphHTML=!0,this.morphShadowDOM=!0,this.verbose=!1,this.importCacheWaitPeriod=200}set(_,$){if(typeof $>"u")return;if(!isNaN(+$))$=+$;if($==="true")$=!0;else if($==="false")$=!1;this[_]=$}}S.extract=function(_){let $=_.defaultView||window;if($&&$.LiveMorphOptions){let K=new S;for(let[X,Y]of Object.entries($.LiveMorphOptions))K.set(X,Y);return K}let Z=Array.from(_.getElementsByTagName("script"));for(let K of Z){let X=K.getAttribute("data-livereload-morph-host");if(X){let Y=new S;Y.host=X;let V=K.getAttribute("data-livereload-morph-port");if(V)Y.port=parseInt(V,10);let B=K.getAttribute("data-livereload-morph-verbose");if(B!==null)Y.verbose=B==="true";return Y}}for(let K of Z){let X=K.src||"";if(X.includes("livereload-morph")){let Y=X.indexOf("?");if(Y!==-1){let V=X.slice(Y+1),B=new URLSearchParams(V),f=B.get("host");if(f){let k=new S;k.host=f;for(let[N,g]of B.entries())k.set(N,g);return k}}}}return null};var a=function(){let _=()=>{},$={morphStyle:"outerHTML",callbacks:{beforeNodeAdded:_,afterNodeAdded:_,beforeNodeMorphed:_,afterNodeMorphed:_,beforeNodeRemoved:_,afterNodeRemoved:_,beforeAttributeUpdated:_},head:{style:"merge",shouldPreserve:(j)=>j.getAttribute("im-preserve")==="true",shouldReAppend:(j)=>j.getAttribute("im-re-append")==="true",shouldRemove:_,afterHeadMorphed:_},restoreFocus:!0};function Z(j,A,W={}){j=N(j);let T=g(A),U=k(j,T,W),O=X(U,()=>{return B(U,j,T,(Q)=>{if(Q.morphStyle==="innerHTML")return Y(Q,j,T),Array.from(j.childNodes);else return K(Q,j,T)})});return U.pantry.remove(),O}function K(j,A,W){let T=g(A);return Y(j,T,W,A,A.nextSibling),Array.from(T.childNodes)}function X(j,A){if(!j.config.restoreFocus)return A();let W=document.activeElement;if(!(W instanceof HTMLInputElement||W instanceof HTMLTextAreaElement))return A();let{id:T,selectionStart:U,selectionEnd:O}=W,Q=A();if(T&&T!==document.activeElement?.getAttribute("id"))W=j.target.querySelector(`[id="${T}"]`),W?.focus();if(W&&!W.selectionEnd&&O)W.setSelectionRange(U,O);return Q}let Y=function(){function j(G,J,D,z=null,R=null){if(J instanceof HTMLTemplateElement&&D instanceof HTMLTemplateElement)J=J.content,D=D.content;z||=J.firstChild;for(let F of D.childNodes){if(z&&z!=R){let H=W(G,F,z,R);if(H){if(H!==z)U(G,z,H);V(H,F,G),z=H.nextSibling;continue}}if(F instanceof Element){let H=F.getAttribute("id");if(G.persistentIds.has(H)){let y=O(J,H,z,G);V(y,F,G),z=y.nextSibling;continue}}let L=A(J,F,z,G);if(L)z=L.nextSibling}while(z&&z!=R){let F=z;z=z.nextSibling,T(G,F)}}function A(G,J,D,z){if(z.callbacks.beforeNodeAdded(J)===!1)return null;if(z.idMap.has(J)){let R=document.createElement(J.tagName);return G.insertBefore(R,D),V(R,J,z),z.callbacks.afterNodeAdded(R),R}else{let R=document.importNode(J,!0);return G.insertBefore(R,D),z.callbacks.afterNodeAdded(R),R}}let W=function(){function G(z,R,F,L){let H=null,y=R.nextSibling,p=0,M=F;while(M&&M!=L){if(D(M,R)){if(J(z,M,R))return M;if(H===null){if(!z.idMap.has(M))H=M}}if(H===null&&y&&D(M,y)){if(p++,y=y.nextSibling,p>=2)H=void 0}if(z.activeElementAndParents.includes(M))break;M=M.nextSibling}return H||null}function J(z,R,F){let L=z.idMap.get(R),H=z.idMap.get(F);if(!H||!L)return!1;for(let y of L)if(H.has(y))return!0;return!1}function D(z,R){let F=z,L=R;return F.nodeType===L.nodeType&&F.tagName===L.tagName&&(!F.getAttribute?.("id")||F.getAttribute?.("id")===L.getAttribute?.("id"))}return G}();function T(G,J){if(G.idMap.has(J))q(G.pantry,J,null);else{if(G.callbacks.beforeNodeRemoved(J)===!1)return;J.parentNode?.removeChild(J),G.callbacks.afterNodeRemoved(J)}}function U(G,J,D){let z=J;while(z&&z!==D){let R=z;z=z.nextSibling,T(G,R)}return z}function O(G,J,D,z){let R=z.target.getAttribute?.("id")===J&&z.target||z.target.querySelector(`[id="${J}"]`)||z.pantry.querySelector(`[id="${J}"]`);return Q(R,z),q(G,R,D),R}function Q(G,J){let D=G.getAttribute("id");while(G=G.parentNode){let z=J.idMap.get(G);if(z){if(z.delete(D),!z.size)J.idMap.delete(G)}}}function q(G,J,D){if(G.moveBefore)try{G.moveBefore(J,D)}catch(z){G.insertBefore(J,D)}else G.insertBefore(J,D)}return j}(),V=function(){function j(Q,q,G){if(G.ignoreActive&&Q===document.activeElement)return null;if(G.callbacks.beforeNodeMorphed(Q,q)===!1)return Q;if(Q instanceof HTMLHeadElement&&G.head.ignore);else if(Q instanceof HTMLHeadElement&&G.head.style!=="morph")f(Q,q,G);else if(A(Q,q,G),!O(Q,G))Y(G,Q,q);return G.callbacks.afterNodeMorphed(Q,q),Q}function A(Q,q,G){let J=q.nodeType;if(J===1){let D=Q,z=q,R=D.attributes,F=z.attributes;for(let L of F){if(U(L.name,D,"update",G))continue;if(D.getAttribute(L.name)!==L.value)D.setAttribute(L.name,L.value)}for(let L=R.length-1;0<=L;L--){let H=R[L];if(!H)continue;if(!z.hasAttribute(H.name)){if(U(H.name,D,"remove",G))continue;D.removeAttribute(H.name)}}if(!O(D,G))W(D,z,G)}if(J===8||J===3){if(Q.nodeValue!==q.nodeValue)Q.nodeValue=q.nodeValue}}function W(Q,q,G){if(Q instanceof HTMLInputElement&&q instanceof HTMLInputElement&&q.type!=="file"){let J=q.value,D=Q.value;if(T(Q,q,"checked",G),T(Q,q,"disabled",G),!q.hasAttribute("value")){if(!U("value",Q,"remove",G))Q.value="",Q.removeAttribute("value")}else if(D!==J){if(!U("value",Q,"update",G))Q.setAttribute("value",J),Q.value=J}}else if(Q instanceof HTMLOptionElement&&q instanceof HTMLOptionElement)T(Q,q,"selected",G);else if(Q instanceof HTMLTextAreaElement&&q instanceof HTMLTextAreaElement){let J=q.value,D=Q.value;if(U("value",Q,"update",G))return;if(J!==D)Q.value=J;if(Q.firstChild&&Q.firstChild.nodeValue!==J)Q.firstChild.nodeValue=J}}function T(Q,q,G,J){let D=q[G],z=Q[G];if(D!==z){let R=U(G,Q,"update",J);if(!R)Q[G]=q[G];if(D){if(!R)Q.setAttribute(G,"")}else if(!U(G,Q,"remove",J))Q.removeAttribute(G)}}function U(Q,q,G,J){if(Q==="value"&&J.ignoreActiveValue&&q===document.activeElement)return!0;return J.callbacks.beforeAttributeUpdated(Q,q,G)===!1}function O(Q,q){return!!q.ignoreActiveValue&&Q===document.activeElement&&Q!==document.body}return j}();function B(j,A,W,T){if(j.head.block){let U=A.querySelector("head"),O=W.querySelector("head");if(U&&O){let Q=f(U,O,j);return Promise.all(Q).then(()=>{let q=Object.assign(j,{head:{block:!1,ignore:!0}});return T(q)})}}return T(j)}function f(j,A,W){let T=[],U=[],O=[],Q=[],q=new Map;for(let J of A.children)q.set(J.outerHTML,J);for(let J of j.children){let D=q.has(J.outerHTML),z=W.head.shouldReAppend(J),R=W.head.shouldPreserve(J);if(D||R)if(z)U.push(J);else q.delete(J.outerHTML),O.push(J);else if(W.head.style==="append"){if(z)U.push(J),Q.push(J)}else if(W.head.shouldRemove(J)!==!1)U.push(J)}Q.push(...q.values());let G=[];for(let J of Q){let D=document.createRange().createContextualFragment(J.outerHTML).firstChild;if(W.callbacks.beforeNodeAdded(D)!==!1){if("href"in D&&D.href||"src"in D&&D.src){let z,R=new Promise(function(F){z=F});D.addEventListener("load",function(){z()}),G.push(R)}j.appendChild(D),W.callbacks.afterNodeAdded(D),T.push(D)}}for(let J of U)if(W.callbacks.beforeNodeRemoved(J)!==!1)j.removeChild(J),W.callbacks.afterNodeRemoved(J);return W.head.afterHeadMorphed(j,{added:T,kept:O,removed:U}),G}let k=function(){function j(G,J,D){let{persistentIds:z,idMap:R}=Q(G,J),F=A(D),L=F.morphStyle||"outerHTML";if(!["innerHTML","outerHTML"].includes(L))throw`Do not understand how to morph style ${L}`;return{target:G,newContent:J,config:F,morphStyle:L,ignoreActive:F.ignoreActive,ignoreActiveValue:F.ignoreActiveValue,restoreFocus:F.restoreFocus,idMap:R,persistentIds:z,pantry:W(),activeElementAndParents:T(G),callbacks:F.callbacks,head:F.head}}function A(G){let J=Object.assign({},$);return Object.assign(J,G),J.callbacks=Object.assign({},$.callbacks,G.callbacks),J.head=Object.assign({},$.head,G.head),J}function W(){let G=document.createElement("div");return G.hidden=!0,document.body.insertAdjacentElement("afterend",G),G}function T(G){let J=[],D=document.activeElement;if(D?.tagName!=="BODY"&&G.contains(D))while(D){if(J.push(D),D===G)break;D=D.parentElement}return J}function U(G){let J=Array.from(G.querySelectorAll("[id]"));if(G.getAttribute?.("id"))J.push(G);return J}function O(G,J,D,z){for(let R of z){let F=R.getAttribute("id");if(J.has(F)){let L=R;while(L){let H=G.get(L);if(H==null)H=new Set,G.set(L,H);if(H.add(F),L===D)break;L=L.parentElement}}}}function Q(G,J){let D=U(G),z=U(J),R=q(D,z),F=new Map;O(F,R,G,D);let L=J.__idiomorphRoot||J;return O(F,R,L,z),{persistentIds:R,idMap:F}}function q(G,J){let D=new Set,z=new Map;for(let{id:F,tagName:L}of G)if(z.has(F))D.add(F);else z.set(F,L);let R=new Set;for(let{id:F,tagName:L}of J)if(R.has(F))D.add(F);else if(z.get(F)===L)R.add(F);for(let F of D)R.delete(F);return R}return j}(),{normalizeElement:N,normalizeParent:g}=function(){let j=new WeakSet;function A(O){if(O instanceof Document)return O.documentElement;else return O}function W(O){if(O==null)return document.createElement("div");else if(typeof O==="string")return W(U(O));else if(j.has(O))return O;else if(O instanceof Node)if(O.parentNode)return new T(O);else{let Q=document.createElement("div");return Q.append(O),Q}else{let Q=document.createElement("div");for(let q of[...O])Q.append(q);return Q}}class T{constructor(O){this.originalNode=O,this.realParentNode=O.parentNode,this.previousSibling=O.previousSibling,this.nextSibling=O.nextSibling}get childNodes(){let O=[],Q=this.previousSibling?this.previousSibling.nextSibling:this.realParentNode.firstChild;while(Q&&Q!=this.nextSibling)O.push(Q),Q=Q.nextSibling;return O}querySelectorAll(O){return this.childNodes.reduce((Q,q)=>{if(q instanceof Element){if(q.matches(O))Q.push(q);let G=q.querySelectorAll(O);for(let J=0;J<G.length;J++)Q.push(G[J])}return Q},[])}insertBefore(O,Q){return this.realParentNode.insertBefore(O,Q)}moveBefore(O,Q){return this.realParentNode.moveBefore(O,Q)}get __idiomorphRoot(){return this.originalNode}}function U(O){let Q=new DOMParser,q=O.replace(/<svg(\s[^>]*>|>)([\s\S]*?)<\/svg>/gim,"");if(q.match(/<\/html>/)||q.match(/<\/head>/)||q.match(/<\/body>/)){let G=Q.parseFromString(O,"text/html");if(q.match(/<\/html>/))return j.add(G),G;else{let J=G.firstChild;if(J)j.add(J);return J}}else{let J=Q.parseFromString("<body><template>"+O+"</template></body>","text/html").body.querySelector("template").content;return j.add(J),J}}return{normalizeElement:A,normalizeParent:W}}();return{morph:Z,defaults:$}}();function i(_){let $="",Z="",K=_.indexOf("#");if(K>=0)$=_.slice(K),_=_.slice(0,K);let X=_.indexOf("??");if(X>=0){if(X+1!==_.lastIndexOf("?"))K=_.lastIndexOf("?")}else K=_.indexOf("?");if(K>=0)Z=_.slice(K),_=_.slice(0,K);return{url:_,params:Z,hash:$}}function C(_){if(!_)return"";let $;if({url:_}=i(_),_.indexOf("file://")===0)$=_.replace(new RegExp("^file://(localhost)?"),"");else $=_.replace(new RegExp("^([^:]+:)?//([^:/]+)(:\\d*)?/"),"/");return decodeURIComponent($)}function $_(_,$){if(_=_.replace(/^\/+/,"").toLowerCase(),$=$.replace(/^\/+/,"").toLowerCase(),_===$)return 1e4;let Z=_.split(/\/|\\/).reverse(),K=$.split(/\/|\\/).reverse(),X=Math.min(Z.length,K.length),Y=0;while(Y<X&&Z[Y]===K[Y])++Y;return Y}function r(_,$,Z=(K)=>K){let K={score:0};for(let X of $){let Y=$_(_,Z(X));if(Y>K.score)K={object:X,score:Y}}if(K.score===0)return null;return K}function v(_){let{url:$,params:Z,hash:K}=i(_),X=`livereload=${Date.now()}`;if(!Z)return`${$}?${X}${K}`;if(Z.includes("livereload=")){let Y=Z.replace(/([?&])livereload=\d+/,`$1${X}`);return`${$}${Y}${K}`}return`${$}${Z}&${X}${K}`}function d(_,$=15000){return new Promise((Z)=>{let K=!1,X=()=>{if(K)return;K=!0,Z()};_.onload=()=>{X()};let Y=50,V=()=>{if(K)return;if(_.sheet){X();return}setTimeout(V,Y)};setTimeout(V,Y),setTimeout(X,$)})}class w{constructor(_,$,Z,K=200){this.window=_,this.console=$,this.Timer=Z,this.document=_.document,this.importCacheWaitPeriod=K}reload(_,$={}){let Z=_.match(/\.css(?:\.map)?$/i),K=_.match(/\.(jpe?g|png|gif|svg|webp|ico)$/i),X=_.match(/\.m?js$/i);if(Z&&$.liveCSS)return this.reloadStylesheet(_,$);if(K&&$.liveImg)return this.reloadImages(_);if(X)return this.reloadPage();if($.morphHTML)return this.morphHTML(_,$);this.reloadPage()}async morphHTML(_,$={}){try{let Z=await fetch(this.window.location.href,{cache:"no-cache",headers:{"X-Live-Morph":"true"}});if(!Z.ok)throw Error(`Fetch failed: ${Z.status} ${Z.statusText}`);let K=await Z.text();K=K.replace(/<!DOCTYPE[^>]*>/i,"").trim(),a.morph(this.document.documentElement,K,{head:{style:"merge",shouldPreserve:(X)=>{if(X.tagName==="SCRIPT"&&X.src)return X.src.toLowerCase().includes("livereload-morph");return!1}},callbacks:{afterNodeMorphed:(X)=>{if($.morphShadowDOM===!1)return;if(X.children){for(let Y of X.children)if(Y.tagName==="TEMPLATE"&&(Y.hasAttribute("shadowrootmode")||Y.hasAttribute("shadowroot"))){let V={mode:Y.getAttribute("shadowrootmode")||Y.getAttribute("shadowroot")||"open"};if(Y.hasAttribute("shadowrootdelegatesfocus"))V.delegatesFocus=!0;if(Y.hasAttribute("shadowrootclonable"))V.clonable=!0;if(Y.hasAttribute("shadowrootserializable"))V.serializable=!0;let B=X.shadowRoot;if(!B)B=X.attachShadow(V);B.innerHTML="",B.appendChild(Y.content.cloneNode(!0)),Y.remove();break}}},beforeAttributeUpdated:(X,Y)=>{if(Y.tagName==="INPUT"||Y.tagName==="TEXTAREA"||Y.tagName==="SELECT"){if(X==="value"||X==="checked")return!1}if(Y.tagName==="DETAILS"&&X==="open")return!1;return!0}}}),this.console.log("HTML morphed successfully")}catch(Z){if(this.console.error(`Morph failed: ${Z.message}`),$.fallbackToReload!==!1)this.console.log("Falling back to full page reload"),this.reloadPage()}}async reloadStylesheet(_,$={}){try{let Z=Array.from(this.document.getElementsByTagName("link")).filter((Y)=>Y.rel&&Y.rel.match(/^stylesheet$/i)&&!Y.__LiveReload_pendingRemoval),K=[];for(let Y of Array.from(this.document.getElementsByTagName("style")))if(Y.sheet)this.collectImportedStylesheets(Y,Y.sheet,K);for(let Y of Z)if(Y.sheet)this.collectImportedStylesheets(Y,Y.sheet,K);if(this.window.StyleFix&&this.document.querySelectorAll)for(let Y of Array.from(this.document.querySelectorAll("style[data-href]")))Z.push(Y);this.console.log(`CSS reload: found ${Z.length} LINKed stylesheets, ${K.length} @imported stylesheets`);let X=r(_,Z.concat(K),(Y)=>C(Y.href||this.linkHref(Y)));if(!X){if($.reloadMissingCSS!==!1){this.console.log(`CSS reload: no match found for '${_}', reloading all stylesheets`);for(let Y of Z)await this.reattachStylesheetLink(Y)}else this.console.log(`CSS reload: no match found for '${_}', skipping (reloadMissingCSS=false)`);return}if(X.object.rule)this.console.log(`CSS reload: reloading @imported stylesheet: ${X.object.href}`),await this.reattachImportedRule(X.object);else this.console.log(`CSS reload: reloading stylesheet: ${this.linkHref(X.object)}`),await this.reattachStylesheetLink(X.object)}catch(Z){this.console.error(`Stylesheet reload failed: ${Z.message}`),this.console.error("Stack:",Z.stack)}}async reattachStylesheetLink(_){if(_.__LiveReload_pendingRemoval)return;_.__LiveReload_pendingRemoval=!0;let $;if(_.tagName==="STYLE")$=this.document.createElement("link"),$.rel="stylesheet",$.media=_.media,$.disabled=_.disabled;else $=_.cloneNode(!1);$.href=v(this.linkHref(_));let Z=_.parentNode;if(Z.lastChild===_)Z.appendChild($);else Z.insertBefore($,_.nextSibling);await d($);let K=/AppleWebKit/.test(this.window.navigator.userAgent)?5:200;if(await new Promise((X)=>this.Timer.start(K,X)),_.parentNode)_.parentNode.removeChild(_);if(this.window.StyleFix)this.window.StyleFix.link($)}reloadPage(){this.window.location.reload()}reloadImages(_){for(let K of Array.from(this.document.images))if(this.pathsMatch(_,C(K.src)))K.src=v(K.src);let $=["background","border"],Z=["backgroundImage","borderImage","webkitBorderImage","MozBorderImage"];for(let K of $)for(let X of Array.from(this.document.querySelectorAll(`[style*=${K}]`)))this.reloadStyleImages(X.style,Z,_);for(let K of Array.from(this.document.styleSheets))this.reloadStylesheetImages(K,_);this.console.log(`Image reload: ${_}`)}reloadStylesheetImages(_,$){let Z;try{Z=(_||{}).cssRules}catch(X){return}if(!Z)return;let K=["backgroundImage","borderImage","webkitBorderImage","MozBorderImage"];for(let X of Array.from(Z))switch(X.type){case CSSRule.IMPORT_RULE:this.reloadStylesheetImages(X.styleSheet,$);break;case CSSRule.STYLE_RULE:this.reloadStyleImages(X.style,K,$);break;case CSSRule.MEDIA_RULE:this.reloadStylesheetImages(X,$);break}}reloadStyleImages(_,$,Z){for(let K of $){let X=_[K];if(typeof X==="string"){let Y=X.replace(/\burl\s*\(([^)]*)\)/g,(V,B)=>{let f=B.replace(/^['"]|['"]$/g,"");if(this.pathsMatch(Z,C(f)))return`url(${v(f)})`;return V});if(Y!==X)_[K]=Y}}}pathsMatch(_,$){let Z=_.replace(/^\//,"").split("/").reverse(),K=$.replace(/^\//,"").split("/").reverse(),X=Math.min(Z.length,K.length);for(let Y=0;Y<X;Y++)if(Z[Y]!==K[Y])return!1;return X>0}linkHref(_){return _.href||_.getAttribute&&_.getAttribute("data-href")}collectImportedStylesheets(_,$,Z){let K;try{K=($||{}).cssRules}catch(X){return}if(K&&K.length)for(let X=0;X<K.length;X++){let Y=K[X];switch(Y.type){case CSSRule.CHARSET_RULE:continue;case CSSRule.IMPORT_RULE:Z.push({link:_,rule:Y,index:X,href:Y.href}),this.collectImportedStylesheets(_,Y.styleSheet,Z);break;default:break}}}async reattachImportedRule({rule:_,index:$,link:Z}){let K=_.parentStyleSheet,X=v(_.href),Y="";try{Y=_.media.length?[].join.call(_.media,", "):""}catch(B){if(B.name!=="SecurityError")this.console.error(`Unexpected error accessing @import media: ${B.name}: ${B.message}`)}let V=`@import url("${X}") ${Y};`;if(_.__LiveReload_newHref=X,this.importCacheWaitPeriod>0){let B=this.document.createElement("link");if(B.rel="stylesheet",B.href=X,B.__LiveReload_pendingRemoval=!0,Z.parentNode)Z.parentNode.insertBefore(B,Z);if(await new Promise((f)=>this.Timer.start(this.importCacheWaitPeriod,f)),B.parentNode)B.parentNode.removeChild(B);if(_.__LiveReload_newHref!==X)return}if(K.insertRule(V,$),K.deleteRule($+1),this.importCacheWaitPeriod>0){let B=K.cssRules[$];if(B.__LiveReload_newHref=X,await new Promise((f)=>this.Timer.start(this.importCacheWaitPeriod,f)),B.__LiveReload_newHref!==X)return;K.insertRule(V,$),K.deleteRule($+1)}}}class u{constructor(_){if(this.window=_,this.listeners={},!(this.WebSocket=this.window.WebSocket||this.window.MozWebSocket)){console.error("[LiveMorph] Disabled because the browser does not support WebSockets");return}if(this.options=S.extract(this.window.document),!this.options){console.error("[LiveMorph] Disabled - no configuration found"),console.error('[LiveMorph] Set window.LiveMorphOptions = { host: "localhost", port: 35729 }');return}console.log("[LiveMorph] Options loaded:",JSON.stringify({host:this.options.host,port:this.options.port,morphHTML:this.options.morphHTML,verbose:this.options.verbose})),this.console=this._setupConsole(),this.morpher=new w(this.window,this.console,b,this.options.importCacheWaitPeriod),this.connector=new x(this.options,this.WebSocket,b,{connecting:()=>{},socketConnected:()=>{},connected:($)=>{if(typeof this.listeners.connect==="function")this.listeners.connect();let{host:Z}=this.options,K=this.options.port?`:${this.options.port}`:"";return this.log(`Connected to ${Z}${K} (protocol v${$})`),this.sendInfo()},error:($)=>{if($ instanceof I)return console.log(`[LiveMorph] ${$.message}`);else return console.log(`[LiveMorph] Internal error: ${$.message}`)},disconnected:($,Z)=>{if(typeof this.listeners.disconnect==="function")this.listeners.disconnect();let{host:K}=this.options,X=this.options.port?`:${this.options.port}`:"",Y=(Z/1000).toFixed(0);switch($){case"cannot-connect":return this.log(`Cannot connect to ${K}${X}, will retry in ${Y} sec`);case"broken":return this.log(`Disconnected from ${K}${X}, reconnecting in ${Y} sec`);case"handshake-timeout":return this.log(`Cannot connect to ${K}${X} (handshake timeout), will retry in ${Y} sec`);case"handshake-failed":return this.log(`Cannot connect to ${K}${X} (handshake failed), will retry in ${Y} sec`);case"manual":case"error":default:return this.log(`Disconnected from ${K}${X} (${$}), reconnecting in ${Y} sec`)}},message:($)=>{switch($.command){case"reload":return this.performReload($);case"alert":return this.performAlert($)}}}),this.initialized=!0}_setupConsole(){if(!(this.window.console&&this.window.console.log&&this.window.console.error))return{log(){},error(){}};if(this.options.verbose)return this.window.console;return{log(){},error:this.window.console.error.bind(this.window.console)}}on(_,$){this.listeners[_]=$}log(_){return this.console.log(`[LiveMorph] ${_}`)}performReload(_){this.log(`Received reload request for: ${_.path}`);let $={liveCSS:_.liveCSS!=null?_.liveCSS:!0,liveImg:_.liveImg!=null?_.liveImg:!0,reloadMissingCSS:_.reloadMissingCSS!=null?_.reloadMissingCSS:!0,morphHTML:this.options.morphHTML,morphShadowDOM:this.options.morphShadowDOM};return this.log(`Reload options: ${JSON.stringify($)}`),this.morpher.reload(_.path,$)}performAlert(_){return alert(_.message)}sendInfo(){if(!this.initialized)return;if(!(this.connector.protocol>=7))return;this.connector.sendCommand({command:"info",plugins:{},url:this.window.location.href})}shutDown(){if(!this.initialized)return;if(this.connector.disconnect(),this.log("Disconnected"),typeof this.listeners.shutdown==="function")this.listeners.shutdown()}}var P=new u(window);window.LiveMorph=P;if(typeof document<"u")document.addEventListener("LiveMorphShutDown",()=>{P.shutDown()}),P.on("connect",()=>{let _=new CustomEvent("LiveMorphConnect");document.dispatchEvent(_)}),P.on("disconnect",()=>{let _=new CustomEvent("LiveMorphDisconnect");document.dispatchEvent(_)});var G_=P;})();
|
|
1
|
+
(()=>{var{defineProperty:h,getOwnPropertyNames:l,getOwnPropertyDescriptor:o}=Object,n=Object.prototype.hasOwnProperty;var c=new WeakMap,t=(_)=>{var $=c.get(_),Z;if($)return $;if($=h({},"__esModule",{value:!0}),_&&typeof _==="object"||typeof _==="function")l(_).map((J)=>!n.call($,J)&&h($,J,{get:()=>_[J],enumerable:!(Z=o(_,J))||Z.enumerable}));return c.set(_,$),$};var e=(_,$)=>{for(var Z in $)h(_,Z,{get:$[Z],enumerable:!0,configurable:!0,set:(J)=>$[Z]=()=>J})};var J_={};e(J_,{default:()=>G_});var s="http://livereload.com/protocols/official-6",a="http://livereload.com/protocols/official-7";class I{constructor(_,$){this.message=`LiveReload protocol error (${_}) after receiving data: "${$}".`}}class x{constructor(_){this.handlers=_,this.reset()}reset(){this.protocol=null}process(_){try{let $;if(!this.protocol){if(_.match(new RegExp("^!!ver:([\\d.]+)$")))this.protocol=6;else if($=this._parseMessage(_,["hello"]))if(!$.protocols.length)throw new I("no protocols specified in handshake message");else if(Array.from($.protocols).includes("http://livereload.com/protocols/official-7"))this.protocol=7;else if(Array.from($.protocols).includes("http://livereload.com/protocols/official-6"))this.protocol=6;else throw new I("no supported protocols found");return this.handlers.connected(this.protocol)}if(this.protocol===6){if($=JSON.parse(_),!$.length)throw new I("protocol 6 messages must be arrays");let[Z,J]=Array.from($);if(Z!=="refresh")throw new I("unknown protocol 6 command");return this.handlers.message({command:"reload",path:J.path,liveCSS:J.apply_css_live!=null?J.apply_css_live:!0})}return $=this._parseMessage(_,["reload","alert"]),this.handlers.message($)}catch($){if($ instanceof I)return this.handlers.error($);throw $}}_parseMessage(_,$){let Z;try{Z=JSON.parse(_)}catch(J){throw new I("unparsable JSON",_)}if(!Z.command)throw new I('missing "command" key',_);if(!$.includes(Z.command))throw new I(`invalid command '${Z.command}', only valid commands are: ${$.join(", ")})`,_);return Z}}var __="1.0.0";class w{constructor(_,$,Z,J){this.options=_,this.WebSocket=$,this.Timer=Z,this.handlers=J;let X=this.options.path?`${this.options.path}`:"livereload",Q=this.options.port?`:${this.options.port}`:"";this._uri=`ws${this.options.https?"s":""}://${this.options.host}${Q}/${X}`,this._nextDelay=this.options.mindelay,this._connectionDesired=!1,this.protocol=0,this.protocolParser=new x({connected:(B)=>{return this.protocol=B,this._handshakeTimeout.stop(),this._nextDelay=this.options.mindelay,this._disconnectionReason="broken",this.handlers.connected(this.protocol)},error:(B)=>{return this.handlers.error(B),this._closeOnError()},message:(B)=>{return this.handlers.message(B)}}),this._handshakeTimeout=new this.Timer(()=>{if(!this._isSocketConnected())return;return this._disconnectionReason="handshake-timeout",this.socket.close()}),this._reconnectTimer=new this.Timer(()=>{if(!this._connectionDesired)return;return this.connect()}),this.connect()}_isSocketConnected(){return this.socket&&this.socket.readyState===this.WebSocket.OPEN}connect(){if(this._connectionDesired=!0,this._isSocketConnected())return;this._reconnectTimer.stop(),this._disconnectionReason="cannot-connect",this.protocolParser.reset(),this.handlers.connecting(),this.socket=new this.WebSocket(this._uri),this.socket.onopen=(_)=>this._onopen(_),this.socket.onclose=(_)=>this._onclose(_),this.socket.onmessage=(_)=>this._onmessage(_),this.socket.onerror=(_)=>this._onerror(_)}disconnect(){if(this._connectionDesired=!1,this._reconnectTimer.stop(),!this._isSocketConnected())return;return this._disconnectionReason="manual",this.socket.close()}_scheduleReconnection(){if(!this._connectionDesired)return;if(!this._reconnectTimer.running)this._reconnectTimer.start(this._nextDelay),this._nextDelay=Math.min(this.options.maxdelay,this._nextDelay*2)}sendCommand(_){if(!this.protocol)return;return this._sendCommand(_)}_sendCommand(_){return this.socket.send(JSON.stringify(_))}_closeOnError(){return this._handshakeTimeout.stop(),this._disconnectionReason="error",this.socket.close()}_onopen(_){this.handlers.socketConnected(),this._disconnectionReason="handshake-failed";let $={command:"hello",protocols:[s,a]};return $.ver=__,this._sendCommand($),this._handshakeTimeout.start(this.options.handshake_timeout)}_onclose(_){return this.protocol=0,this.handlers.disconnected(this._disconnectionReason,this._nextDelay),this._scheduleReconnection()}_onerror(_){}_onmessage(_){return this.protocolParser.process(_.data)}}class b{constructor(_){this.func=_,this.running=!1,this.id=null,this._handler=()=>{return this.running=!1,this.id=null,this.func()}}start(_){if(this.running)clearTimeout(this.id);this.id=setTimeout(this._handler,_),this.running=!0}stop(){if(this.running)clearTimeout(this.id),this.running=!1,this.id=null}}b.start=(_,$)=>setTimeout($,_);class S{constructor(){this.https=!1,this.host=null;let _=35729;Object.defineProperty(this,"port",{get(){return _},set($){_=$?isNaN($)?$:+$:""}}),this.mindelay=1000,this.maxdelay=60000,this.handshake_timeout=5000,this.morphHTML=!0,this.morphShadowDOM=!0,this.verbose=!1,this.importCacheWaitPeriod=200}set(_,$){if(typeof $>"u")return;if(!isNaN(+$))$=+$;if($==="true")$=!0;else if($==="false")$=!1;this[_]=$}}S.extract=function(_){let $=_.defaultView||window;if($&&$.LiveMorphOptions){let J=new S;for(let[X,Q]of Object.entries($.LiveMorphOptions))J.set(X,Q);return J}let Z=Array.from(_.getElementsByTagName("script"));for(let J of Z){let X=J.getAttribute("data-livereload-morph-host");if(X){let Q=new S;Q.host=X;let B=J.getAttribute("data-livereload-morph-port");if(B)Q.port=parseInt(B,10);let U=J.getAttribute("data-livereload-morph-verbose");if(U!==null)Q.verbose=U==="true";return Q}}for(let J of Z){let X=J.src||"";if(X.includes("livereload-morph")){let Q=X.indexOf("?");if(Q!==-1){let B=X.slice(Q+1),U=new URLSearchParams(B),M=U.get("host");if(M){let k=new S;k.host=M;for(let[E,g]of U.entries())k.set(E,g);return k}}}}return null};var C=function(){let _=()=>{},$={morphStyle:"outerHTML",callbacks:{beforeNodeAdded:_,afterNodeAdded:_,beforeNodeMorphed:_,afterNodeMorphed:_,beforeNodeRemoved:_,afterNodeRemoved:_,beforeAttributeUpdated:_},head:{style:"merge",shouldPreserve:(W)=>W.getAttribute("im-preserve")==="true",shouldReAppend:(W)=>W.getAttribute("im-re-append")==="true",shouldRemove:_,afterHeadMorphed:_},restoreFocus:!0};function Z(W,A,T={}){W=E(W);let D=g(A),V=k(W,D,T),O=X(V,()=>{return U(V,W,D,(Y)=>{if(Y.morphStyle==="innerHTML")return Q(Y,W,D),Array.from(W.childNodes);else return J(Y,W,D)})});return V.pantry.remove(),O}function J(W,A,T){let D=g(A);return Q(W,D,T,A,A.nextSibling),Array.from(D.childNodes)}function X(W,A){if(!W.config.restoreFocus)return A();let T=document.activeElement;if(!(T instanceof HTMLInputElement||T instanceof HTMLTextAreaElement))return A();let{id:D,selectionStart:V,selectionEnd:O}=T,Y=A();if(D&&D!==document.activeElement?.getAttribute("id"))T=W.target.querySelector(`[id="${D}"]`),T?.focus();if(T&&!T.selectionEnd&&O)T.setSelectionRange(V,O);return Y}let Q=function(){function W(K,G,q,z=null,F=null){if(G instanceof HTMLTemplateElement&&q instanceof HTMLTemplateElement)G=G.content,q=q.content;z||=G.firstChild;for(let L of q.childNodes){if(z&&z!=F){let H=T(K,L,z,F);if(H){if(H!==z)V(K,z,H);B(H,L,K),z=H.nextSibling;continue}}if(L instanceof Element){let H=L.getAttribute("id");if(K.persistentIds.has(H)){let f=O(G,H,z,K);B(f,L,K),z=f.nextSibling;continue}}let j=A(G,L,z,K);if(j)z=j.nextSibling}while(z&&z!=F){let L=z;z=z.nextSibling,D(K,L)}}function A(K,G,q,z){if(z.callbacks.beforeNodeAdded(G)===!1)return null;if(z.idMap.has(G)){let F=document.createElement(G.tagName);return K.insertBefore(F,q),B(F,G,z),z.callbacks.afterNodeAdded(F),F}else{let F=document.importNode(G,!0);return K.insertBefore(F,q),z.callbacks.afterNodeAdded(F),F}}let T=function(){function K(z,F,L,j){let H=null,f=F.nextSibling,m=0,y=L;while(y&&y!=j){if(q(y,F)){if(G(z,y,F))return y;if(H===null){if(!z.idMap.has(y))H=y}}if(H===null&&f&&q(y,f)){if(m++,f=f.nextSibling,m>=2)H=void 0}if(z.activeElementAndParents.includes(y))break;y=y.nextSibling}return H||null}function G(z,F,L){let j=z.idMap.get(F),H=z.idMap.get(L);if(!H||!j)return!1;for(let f of j)if(H.has(f))return!0;return!1}function q(z,F){let L=z,j=F;return L.nodeType===j.nodeType&&L.tagName===j.tagName&&(!L.getAttribute?.("id")||L.getAttribute?.("id")===j.getAttribute?.("id"))}return K}();function D(K,G){if(K.idMap.has(G))R(K.pantry,G,null);else{if(K.callbacks.beforeNodeRemoved(G)===!1)return;G.parentNode?.removeChild(G),K.callbacks.afterNodeRemoved(G)}}function V(K,G,q){let z=G;while(z&&z!==q){let F=z;z=z.nextSibling,D(K,F)}return z}function O(K,G,q,z){let F=z.target.getAttribute?.("id")===G&&z.target||z.target.querySelector(`[id="${G}"]`)||z.pantry.querySelector(`[id="${G}"]`);return Y(F,z),R(K,F,q),F}function Y(K,G){let q=K.getAttribute("id");while(K=K.parentNode){let z=G.idMap.get(K);if(z){if(z.delete(q),!z.size)G.idMap.delete(K)}}}function R(K,G,q){if(K.moveBefore)try{K.moveBefore(G,q)}catch(z){K.insertBefore(G,q)}else K.insertBefore(G,q)}return W}(),B=function(){function W(Y,R,K){if(K.ignoreActive&&Y===document.activeElement)return null;if(K.callbacks.beforeNodeMorphed(Y,R)===!1)return Y;if(Y instanceof HTMLHeadElement&&K.head.ignore);else if(Y instanceof HTMLHeadElement&&K.head.style!=="morph")M(Y,R,K);else if(A(Y,R,K),!O(Y,K))Q(K,Y,R);return K.callbacks.afterNodeMorphed(Y,R),Y}function A(Y,R,K){let G=R.nodeType;if(G===1){let q=Y,z=R,F=q.attributes,L=z.attributes;for(let j of L){if(V(j.name,q,"update",K))continue;if(q.getAttribute(j.name)!==j.value)q.setAttribute(j.name,j.value)}for(let j=F.length-1;0<=j;j--){let H=F[j];if(!H)continue;if(!z.hasAttribute(H.name)){if(V(H.name,q,"remove",K))continue;q.removeAttribute(H.name)}}if(!O(q,K))T(q,z,K)}if(G===8||G===3){if(Y.nodeValue!==R.nodeValue)Y.nodeValue=R.nodeValue}}function T(Y,R,K){if(Y instanceof HTMLInputElement&&R instanceof HTMLInputElement&&R.type!=="file"){let G=R.value,q=Y.value;if(D(Y,R,"checked",K),D(Y,R,"disabled",K),!R.hasAttribute("value")){if(!V("value",Y,"remove",K))Y.value="",Y.removeAttribute("value")}else if(q!==G){if(!V("value",Y,"update",K))Y.setAttribute("value",G),Y.value=G}}else if(Y instanceof HTMLOptionElement&&R instanceof HTMLOptionElement)D(Y,R,"selected",K);else if(Y instanceof HTMLTextAreaElement&&R instanceof HTMLTextAreaElement){let G=R.value,q=Y.value;if(V("value",Y,"update",K))return;if(G!==q)Y.value=G;if(Y.firstChild&&Y.firstChild.nodeValue!==G)Y.firstChild.nodeValue=G}}function D(Y,R,K,G){let q=R[K],z=Y[K];if(q!==z){let F=V(K,Y,"update",G);if(!F)Y[K]=R[K];if(q){if(!F)Y.setAttribute(K,"")}else if(!V(K,Y,"remove",G))Y.removeAttribute(K)}}function V(Y,R,K,G){if(Y==="value"&&G.ignoreActiveValue&&R===document.activeElement)return!0;return G.callbacks.beforeAttributeUpdated(Y,R,K)===!1}function O(Y,R){return!!R.ignoreActiveValue&&Y===document.activeElement&&Y!==document.body}return W}();function U(W,A,T,D){if(W.head.block){let V=A.querySelector("head"),O=T.querySelector("head");if(V&&O){let Y=M(V,O,W);return Promise.all(Y).then(()=>{let R=Object.assign(W,{head:{block:!1,ignore:!0}});return D(R)})}}return D(W)}function M(W,A,T){let D=[],V=[],O=[],Y=[],R=new Map;for(let G of A.children)R.set(G.outerHTML,G);for(let G of W.children){let q=R.has(G.outerHTML),z=T.head.shouldReAppend(G),F=T.head.shouldPreserve(G);if(q||F)if(z)V.push(G);else R.delete(G.outerHTML),O.push(G);else if(T.head.style==="append"){if(z)V.push(G),Y.push(G)}else if(T.head.shouldRemove(G)!==!1)V.push(G)}Y.push(...R.values());let K=[];for(let G of Y){let q=document.createRange().createContextualFragment(G.outerHTML).firstChild;if(T.callbacks.beforeNodeAdded(q)!==!1){if("href"in q&&q.href||"src"in q&&q.src){let z,F=new Promise(function(L){z=L});q.addEventListener("load",function(){z()}),K.push(F)}W.appendChild(q),T.callbacks.afterNodeAdded(q),D.push(q)}}for(let G of V)if(T.callbacks.beforeNodeRemoved(G)!==!1)W.removeChild(G),T.callbacks.afterNodeRemoved(G);return T.head.afterHeadMorphed(W,{added:D,kept:O,removed:V}),K}let k=function(){function W(K,G,q){let{persistentIds:z,idMap:F}=Y(K,G),L=A(q),j=L.morphStyle||"outerHTML";if(!["innerHTML","outerHTML"].includes(j))throw`Do not understand how to morph style ${j}`;return{target:K,newContent:G,config:L,morphStyle:j,ignoreActive:L.ignoreActive,ignoreActiveValue:L.ignoreActiveValue,restoreFocus:L.restoreFocus,idMap:F,persistentIds:z,pantry:T(),activeElementAndParents:D(K),callbacks:L.callbacks,head:L.head}}function A(K){let G=Object.assign({},$);return Object.assign(G,K),G.callbacks=Object.assign({},$.callbacks,K.callbacks),G.head=Object.assign({},$.head,K.head),G}function T(){let K=document.createElement("div");return K.hidden=!0,document.body.insertAdjacentElement("afterend",K),K}function D(K){let G=[],q=document.activeElement;if(q?.tagName!=="BODY"&&K.contains(q))while(q){if(G.push(q),q===K)break;q=q.parentElement}return G}function V(K){let G=Array.from(K.querySelectorAll("[id]"));if(K.getAttribute?.("id"))G.push(K);return G}function O(K,G,q,z){for(let F of z){let L=F.getAttribute("id");if(G.has(L)){let j=F;while(j){let H=K.get(j);if(H==null)H=new Set,K.set(j,H);if(H.add(L),j===q)break;j=j.parentElement}}}}function Y(K,G){let q=V(K),z=V(G),F=R(q,z),L=new Map;O(L,F,K,q);let j=G.__idiomorphRoot||G;return O(L,F,j,z),{persistentIds:F,idMap:L}}function R(K,G){let q=new Set,z=new Map;for(let{id:L,tagName:j}of K)if(z.has(L))q.add(L);else z.set(L,j);let F=new Set;for(let{id:L,tagName:j}of G)if(F.has(L))q.add(L);else if(z.get(L)===j)F.add(L);for(let L of q)F.delete(L);return F}return W}(),{normalizeElement:E,normalizeParent:g}=function(){let W=new WeakSet;function A(O){if(O instanceof Document)return O.documentElement;else return O}function T(O){if(O==null)return document.createElement("div");else if(typeof O==="string")return T(V(O));else if(W.has(O))return O;else if(O instanceof Node)if(O.parentNode)return new D(O);else{let Y=document.createElement("div");return Y.append(O),Y}else{let Y=document.createElement("div");for(let R of[...O])Y.append(R);return Y}}class D{constructor(O){this.originalNode=O,this.realParentNode=O.parentNode,this.previousSibling=O.previousSibling,this.nextSibling=O.nextSibling}get childNodes(){let O=[],Y=this.previousSibling?this.previousSibling.nextSibling:this.realParentNode.firstChild;while(Y&&Y!=this.nextSibling)O.push(Y),Y=Y.nextSibling;return O}querySelectorAll(O){return this.childNodes.reduce((Y,R)=>{if(R instanceof Element){if(R.matches(O))Y.push(R);let K=R.querySelectorAll(O);for(let G=0;G<K.length;G++)Y.push(K[G])}return Y},[])}insertBefore(O,Y){return this.realParentNode.insertBefore(O,Y)}moveBefore(O,Y){return this.realParentNode.moveBefore(O,Y)}get __idiomorphRoot(){return this.originalNode}}function V(O){let Y=new DOMParser,R=O.replace(/<svg(\s[^>]*>|>)([\s\S]*?)<\/svg>/gim,"");if(R.match(/<\/html>/)||R.match(/<\/head>/)||R.match(/<\/body>/)){let K=Y.parseFromString(O,"text/html");if(R.match(/<\/html>/))return W.add(K),K;else{let G=K.firstChild;if(G)W.add(G);return G}}else{let G=Y.parseFromString("<body><template>"+O+"</template></body>","text/html").body.querySelector("template").content;return W.add(G),G}}return{normalizeElement:A,normalizeParent:T}}();return{morph:Z,defaults:$}}();function i(_){let $="",Z="",J=_.indexOf("#");if(J>=0)$=_.slice(J),_=_.slice(0,J);let X=_.indexOf("??");if(X>=0){if(X+1!==_.lastIndexOf("?"))J=_.lastIndexOf("?")}else J=_.indexOf("?");if(J>=0)Z=_.slice(J),_=_.slice(0,J);return{url:_,params:Z,hash:$}}function N(_){if(!_)return"";let $;if({url:_}=i(_),_.indexOf("file://")===0)$=_.replace(new RegExp("^file://(localhost)?"),"");else $=_.replace(new RegExp("^([^:]+:)?//([^:/]+)(:\\d*)?/"),"/");return decodeURIComponent($)}function $_(_,$){if(_=_.replace(/^\/+/,"").toLowerCase(),$=$.replace(/^\/+/,"").toLowerCase(),_===$)return 1e4;let Z=_.split(/\/|\\/).reverse(),J=$.split(/\/|\\/).reverse(),X=Math.min(Z.length,J.length),Q=0;while(Q<X&&Z[Q]===J[Q])++Q;return Q}function r(_,$,Z=(J)=>J){let J={score:0};for(let X of $){let Q=$_(_,Z(X));if(Q>J.score)J={object:X,score:Q}}if(J.score===0)return null;return J}function v(_){let{url:$,params:Z,hash:J}=i(_),X=`livereload=${Date.now()}`;if(!Z)return`${$}?${X}${J}`;if(Z.includes("livereload=")){let Q=Z.replace(/([?&])livereload=\d+/,`$1${X}`);return`${$}${Q}${J}`}return`${$}${Z}&${X}${J}`}function d(_,$=15000){return new Promise((Z)=>{let J=!1,X=()=>{if(J)return;J=!0,Z()};_.onload=()=>{X()};let Q=50,B=()=>{if(J)return;if(_.sheet){X();return}setTimeout(B,Q)};setTimeout(B,Q),setTimeout(X,$)})}class u{constructor(_,$,Z,J=200){this.window=_,this.console=$,this.Timer=Z,this.document=_.document,this.importCacheWaitPeriod=J,this.preserveStateCallback=(X,Q)=>{if(Q.tagName==="INPUT"||Q.tagName==="TEXTAREA"||Q.tagName==="SELECT"){if(X==="value"||X==="checked")return!1}if(Q.tagName==="DETAILS"&&X==="open")return!1;return!0}}reload(_,$={}){let Z=_.match(/\.css(?:\.map)?$/i),J=_.match(/\.(jpe?g|png|gif|svg|webp|ico)$/i),X=_.match(/\.m?js$/i);if(Z&&$.liveCSS)return this.reloadStylesheet(_,$);if(J&&$.liveImg)return this.reloadImages(_);if(X)return this.reloadPage();if($.morphHTML)return this.morphHTML(_,$);this.reloadPage()}async morphHTML(_,$={}){try{let Z=await fetch(this.window.location.href,{cache:"no-cache",headers:{"X-Live-Morph":"true"}});if(!Z.ok)throw Error(`Fetch failed: ${Z.status} ${Z.statusText}`);let J=await Z.text();J=J.replace(/<!DOCTYPE[^>]*>/i,"").trim(),C.morph(this.document.documentElement,J,{head:{style:"merge",shouldPreserve:(X)=>{if(X.tagName==="SCRIPT"&&X.src)return X.src.toLowerCase().includes("livereload-morph");return!1}},callbacks:{beforeNodeMorphed:(X,Q)=>{if(X.tagName==="IFRAME"&&Q.tagName==="IFRAME"){let B=Q.getAttribute("srcdoc");if(B!==null)return this.morphIframeSrcdoc(X,B,$),!1}return!0},afterNodeMorphed:(X)=>{if($.morphShadowDOM===!1)return;if(X.children){for(let Q of X.children)if(Q.tagName==="TEMPLATE"&&(Q.hasAttribute("shadowrootmode")||Q.hasAttribute("shadowroot"))){let B={mode:Q.getAttribute("shadowrootmode")||Q.getAttribute("shadowroot")||"open"};if(Q.hasAttribute("shadowrootdelegatesfocus"))B.delegatesFocus=!0;if(Q.hasAttribute("shadowrootclonable"))B.clonable=!0;if(Q.hasAttribute("shadowrootserializable"))B.serializable=!0;let U=X.shadowRoot;if(!U)U=X.attachShadow(B);U.innerHTML="",U.appendChild(Q.content.cloneNode(!0)),Q.remove();break}}},beforeAttributeUpdated:this.preserveStateCallback}}),this.console.log("HTML morphed successfully")}catch(Z){if(this.console.error(`Morph failed: ${Z.message}`),$.fallbackToReload!==!1)this.console.log("Falling back to full page reload"),this.reloadPage()}}morphIframeSrcdoc(_,$,Z={}){try{let J=_.contentDocument;if(!J||!J.body){this.console.log("Cannot access iframe contentDocument, falling back to srcdoc replacement"),_.setAttribute("srcdoc",$);return}let Q=new DOMParser().parseFromString($,"text/html"),B={morphStyle:"innerHTML",callbacks:{beforeAttributeUpdated:this.preserveStateCallback}};if(Q.head)if(J.head)C.morph(J.head,Q.head.innerHTML,B);else{let U=J.createElement("head");U.innerHTML=Q.head.innerHTML,J.documentElement.insertBefore(U,J.body)}if(Q.body)C.morph(J.body,Q.body.innerHTML,B);this.console.log("iframe srcdoc morphed successfully")}catch(J){this.console.error(`iframe srcdoc morph failed, so we fall back. msg: ${J.message}`),_.setAttribute("srcdoc",$)}}async reloadStylesheet(_,$={}){try{let Z=Array.from(this.document.getElementsByTagName("link")).filter((Q)=>Q.rel&&Q.rel.match(/^stylesheet$/i)&&!Q.__LiveReload_pendingRemoval),J=[];for(let Q of Array.from(this.document.getElementsByTagName("style")))if(Q.sheet)this.collectImportedStylesheets(Q,Q.sheet,J);for(let Q of Z)if(Q.sheet)this.collectImportedStylesheets(Q,Q.sheet,J);if(this.window.StyleFix&&this.document.querySelectorAll)for(let Q of Array.from(this.document.querySelectorAll("style[data-href]")))Z.push(Q);this.console.log(`CSS reload: found ${Z.length} LINKed stylesheets, ${J.length} @imported stylesheets`);let X=r(_,Z.concat(J),(Q)=>N(Q.href||this.linkHref(Q)));if(!X){if($.reloadMissingCSS!==!1){this.console.log(`CSS reload: no match found for '${_}', reloading all stylesheets`);for(let Q of Z)await this.reattachStylesheetLink(Q)}else this.console.log(`CSS reload: no match found for '${_}', skipping (reloadMissingCSS=false)`);return}if(X.object.rule)this.console.log(`CSS reload: reloading @imported stylesheet: ${X.object.href}`),await this.reattachImportedRule(X.object);else this.console.log(`CSS reload: reloading stylesheet: ${this.linkHref(X.object)}`),await this.reattachStylesheetLink(X.object)}catch(Z){this.console.error(`Stylesheet reload failed: ${Z.message}`),this.console.error("Stack:",Z.stack)}}async reattachStylesheetLink(_){if(_.__LiveReload_pendingRemoval)return;_.__LiveReload_pendingRemoval=!0;let $;if(_.tagName==="STYLE")$=this.document.createElement("link"),$.rel="stylesheet",$.media=_.media,$.disabled=_.disabled;else $=_.cloneNode(!1);$.href=v(this.linkHref(_));let Z=_.parentNode;if(Z.lastChild===_)Z.appendChild($);else Z.insertBefore($,_.nextSibling);await d($);let J=/AppleWebKit/.test(this.window.navigator.userAgent)?5:200;if(await new Promise((X)=>this.Timer.start(J,X)),_.parentNode)_.parentNode.removeChild(_);if(this.window.StyleFix)this.window.StyleFix.link($)}reloadPage(){this.window.location.reload()}reloadImages(_){for(let J of Array.from(this.document.images))if(this.pathsMatch(_,N(J.src)))J.src=v(J.src);let $=["background","border"],Z=["backgroundImage","borderImage","webkitBorderImage","MozBorderImage"];for(let J of $)for(let X of Array.from(this.document.querySelectorAll(`[style*=${J}]`)))this.reloadStyleImages(X.style,Z,_);for(let J of Array.from(this.document.styleSheets))this.reloadStylesheetImages(J,_);this.console.log(`Image reload: ${_}`)}reloadStylesheetImages(_,$){let Z;try{Z=(_||{}).cssRules}catch(X){return}if(!Z)return;let J=["backgroundImage","borderImage","webkitBorderImage","MozBorderImage"];for(let X of Array.from(Z))switch(X.type){case CSSRule.IMPORT_RULE:this.reloadStylesheetImages(X.styleSheet,$);break;case CSSRule.STYLE_RULE:this.reloadStyleImages(X.style,J,$);break;case CSSRule.MEDIA_RULE:this.reloadStylesheetImages(X,$);break}}reloadStyleImages(_,$,Z){for(let J of $){let X=_[J];if(typeof X==="string"){let Q=X.replace(/\burl\s*\(([^)]*)\)/g,(B,U)=>{let M=U.replace(/^['"]|['"]$/g,"");if(this.pathsMatch(Z,N(M)))return`url(${v(M)})`;return B});if(Q!==X)_[J]=Q}}}pathsMatch(_,$){let Z=_.replace(/^\//,"").split("/").reverse(),J=$.replace(/^\//,"").split("/").reverse(),X=Math.min(Z.length,J.length);for(let Q=0;Q<X;Q++)if(Z[Q]!==J[Q])return!1;return X>0}linkHref(_){return _.href||_.getAttribute&&_.getAttribute("data-href")}collectImportedStylesheets(_,$,Z){let J;try{J=($||{}).cssRules}catch(X){return}if(J&&J.length)for(let X=0;X<J.length;X++){let Q=J[X];switch(Q.type){case CSSRule.CHARSET_RULE:continue;case CSSRule.IMPORT_RULE:Z.push({link:_,rule:Q,index:X,href:Q.href}),this.collectImportedStylesheets(_,Q.styleSheet,Z);break;default:break}}}async reattachImportedRule({rule:_,index:$,link:Z}){let J=_.parentStyleSheet,X=v(_.href),Q="";try{Q=_.media.length?[].join.call(_.media,", "):""}catch(U){if(U.name!=="SecurityError")this.console.error(`Unexpected error accessing @import media: ${U.name}: ${U.message}`)}let B=`@import url("${X}") ${Q};`;if(_.__LiveReload_newHref=X,this.importCacheWaitPeriod>0){let U=this.document.createElement("link");if(U.rel="stylesheet",U.href=X,U.__LiveReload_pendingRemoval=!0,Z.parentNode)Z.parentNode.insertBefore(U,Z);if(await new Promise((M)=>this.Timer.start(this.importCacheWaitPeriod,M)),U.parentNode)U.parentNode.removeChild(U);if(_.__LiveReload_newHref!==X)return}if(J.insertRule(B,$),J.deleteRule($+1),this.importCacheWaitPeriod>0){let U=J.cssRules[$];if(U.__LiveReload_newHref=X,await new Promise((M)=>this.Timer.start(this.importCacheWaitPeriod,M)),U.__LiveReload_newHref!==X)return;J.insertRule(B,$),J.deleteRule($+1)}}}class p{constructor(_){if(this.window=_,this.listeners={},!(this.WebSocket=this.window.WebSocket||this.window.MozWebSocket)){console.error("[LiveMorph] Disabled because the browser does not support WebSockets");return}if(this.options=S.extract(this.window.document),!this.options){console.error("[LiveMorph] Disabled - no configuration found"),console.error('[LiveMorph] Set window.LiveMorphOptions = { host: "localhost", port: 35729 }');return}console.log("[LiveMorph] Options loaded:",JSON.stringify({host:this.options.host,port:this.options.port,morphHTML:this.options.morphHTML,verbose:this.options.verbose})),this.console=this._setupConsole(),this.morpher=new u(this.window,this.console,b,this.options.importCacheWaitPeriod),this.connector=new w(this.options,this.WebSocket,b,{connecting:()=>{},socketConnected:()=>{},connected:($)=>{if(typeof this.listeners.connect==="function")this.listeners.connect();let{host:Z}=this.options,J=this.options.port?`:${this.options.port}`:"";return this.log(`Connected to ${Z}${J} (protocol v${$})`),this.sendInfo()},error:($)=>{if($ instanceof I)return console.log(`[LiveMorph] ${$.message}`);else return console.log(`[LiveMorph] Internal error: ${$.message}`)},disconnected:($,Z)=>{if(typeof this.listeners.disconnect==="function")this.listeners.disconnect();let{host:J}=this.options,X=this.options.port?`:${this.options.port}`:"",Q=(Z/1000).toFixed(0);switch($){case"cannot-connect":return this.log(`Cannot connect to ${J}${X}, will retry in ${Q} sec`);case"broken":return this.log(`Disconnected from ${J}${X}, reconnecting in ${Q} sec`);case"handshake-timeout":return this.log(`Cannot connect to ${J}${X} (handshake timeout), will retry in ${Q} sec`);case"handshake-failed":return this.log(`Cannot connect to ${J}${X} (handshake failed), will retry in ${Q} sec`);case"manual":case"error":default:return this.log(`Disconnected from ${J}${X} (${$}), reconnecting in ${Q} sec`)}},message:($)=>{switch($.command){case"reload":return this.performReload($);case"alert":return this.performAlert($)}}}),this.initialized=!0}_setupConsole(){if(!(this.window.console&&this.window.console.log&&this.window.console.error))return{log(){},error(){}};if(this.options.verbose)return this.window.console;return{log(){},error:this.window.console.error.bind(this.window.console)}}on(_,$){this.listeners[_]=$}log(_){return this.console.log(`[LiveMorph] ${_}`)}performReload(_){this.log(`Received reload request for: ${_.path}`);let $={liveCSS:_.liveCSS!=null?_.liveCSS:!0,liveImg:_.liveImg!=null?_.liveImg:!0,reloadMissingCSS:_.reloadMissingCSS!=null?_.reloadMissingCSS:!0,morphHTML:this.options.morphHTML,morphShadowDOM:this.options.morphShadowDOM};return this.log(`Reload options: ${JSON.stringify($)}`),this.morpher.reload(_.path,$)}performAlert(_){return alert(_.message)}sendInfo(){if(!this.initialized)return;if(!(this.connector.protocol>=7))return;this.connector.sendCommand({command:"info",plugins:{},url:this.window.location.href})}shutDown(){if(!this.initialized)return;if(this.connector.disconnect(),this.log("Disconnected"),typeof this.listeners.shutdown==="function")this.listeners.shutdown()}}var P=new p(window);window.LiveMorph=P;if(typeof document<"u")document.addEventListener("LiveMorphShutDown",()=>{P.shutDown()}),P.on("connect",()=>{let _=new CustomEvent("LiveMorphConnect");document.dispatchEvent(_)}),P.on("disconnect",()=>{let _=new CustomEvent("LiveMorphDisconnect");document.dispatchEvent(_)});var G_=P;})();
|