Current section

Files

Jump to
sprocket priv static client.js
Raw

priv/static/client.js

// modules are defined as an array
// [ module function, map of requires ]
//
// map of requires is short require name -> numeric require
//
// anything defined in a previous bundle is accessed via the
// orig method which is the require for previous bundles
(function (modules, entry, mainEntry, parcelRequireName, globalName) {
/* eslint-disable no-undef */
var globalObject =
typeof globalThis !== 'undefined'
? globalThis
: typeof self !== 'undefined'
? self
: typeof window !== 'undefined'
? window
: typeof global !== 'undefined'
? global
: {};
/* eslint-enable no-undef */
// Save the require from previous bundle to this closure if any
var previousRequire =
typeof globalObject[parcelRequireName] === 'function' &&
globalObject[parcelRequireName];
var cache = previousRequire.cache || {};
// Do not use `require` to prevent Webpack from trying to bundle this call
var nodeRequire =
typeof module !== 'undefined' &&
typeof module.require === 'function' &&
module.require.bind(module);
function newRequire(name, jumped) {
if (!cache[name]) {
if (!modules[name]) {
// if we cannot find the module within our internal map or
// cache jump to the current global require ie. the last bundle
// that was added to the page.
var currentRequire =
typeof globalObject[parcelRequireName] === 'function' &&
globalObject[parcelRequireName];
if (!jumped && currentRequire) {
return currentRequire(name, true);
}
// If there are other bundles on this page the require from the
// previous one is saved to 'previousRequire'. Repeat this as
// many times as there are bundles until the module is found or
// we exhaust the require chain.
if (previousRequire) {
return previousRequire(name, true);
}
// Try the node require function if it exists.
if (nodeRequire && typeof name === 'string') {
return nodeRequire(name);
}
var err = new Error("Cannot find module '" + name + "'");
err.code = 'MODULE_NOT_FOUND';
throw err;
}
localRequire.resolve = resolve;
localRequire.cache = {};
var module = (cache[name] = new newRequire.Module(name));
modules[name][0].call(
module.exports,
localRequire,
module,
module.exports,
this
);
}
return cache[name].exports;
function localRequire(x) {
var res = localRequire.resolve(x);
return res === false ? {} : newRequire(res);
}
function resolve(x) {
var id = modules[name][1][x];
return id != null ? id : x;
}
}
function Module(moduleName) {
this.id = moduleName;
this.bundle = newRequire;
this.exports = {};
}
newRequire.isParcelRequire = true;
newRequire.Module = Module;
newRequire.modules = modules;
newRequire.cache = cache;
newRequire.parent = previousRequire;
newRequire.register = function (id, exports) {
modules[id] = [
function (require, module) {
module.exports = exports;
},
{},
];
};
Object.defineProperty(newRequire, 'root', {
get: function () {
return globalObject[parcelRequireName];
},
});
globalObject[parcelRequireName] = newRequire;
for (var i = 0; i < entry.length; i++) {
newRequire(entry[i]);
}
if (mainEntry) {
// Expose entry point to Node, AMD or browser globals
// Based on https://github.com/ForbesLindesay/umd/blob/master/template.js
var mainExports = newRequire(mainEntry);
// CommonJS
if (typeof exports === 'object' && typeof module !== 'undefined') {
module.exports = mainExports;
// RequireJS
} else if (typeof define === 'function' && define.amd) {
define(function () {
return mainExports;
});
// <script>
} else if (globalName) {
this[globalName] = mainExports;
}
}
})({"2WBxL":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
var _morphdom = require("morphdom");
var _morphdomDefault = parcelHelpers.interopDefault(_morphdom);
var _topbar = require("topbar");
var _topbarDefault = parcelHelpers.interopDefault(_topbar);
var _render = require("./render");
var _patch = require("./patch");
var _events = require("./events");
var _constants = require("./constants");
var _doubleclick = require("./hooks/doubleclick");
const hooks = {
DoubleClick: (0, _doubleclick.doubleclick)
};
window.addEventListener("DOMContentLoaded", ()=>{
let ws_protocol = location.protocol === "https:" ? "wss:" : "ws:";
const socket = new WebSocket(ws_protocol + "//" + location.host + "/live");
let dom;
const spktPreflightId = document.querySelector("meta[name=spkt-preflight-id]")?.getAttribute("content");
const spktCsrfToken = document.querySelector("meta[name=spkt-csrf-token]")?.getAttribute("content");
(0, _topbarDefault.default).config({
barColors: {
0: "#29d"
},
barThickness: 2
});
(0, _topbarDefault.default).show(500);
socket.addEventListener("open", function(event) {
socket.send(JSON.stringify([
"join",
{
id: spktPreflightId,
csrf: spktCsrfToken
}
]));
});
socket.addEventListener("message", function(event) {
let parsed = JSON.parse(event.data);
if (Array.isArray(parsed)) {
switch(parsed[0]){
case "ok":
(0, _topbarDefault.default).hide();
// handle hook lifecycle mounted events
Object.keys(hooks).forEach((hook)=>{
if (hooks[hook].mounted) document.querySelectorAll(`[${(0, _constants.constant).HookAttrPrefix}=${hook}]`).forEach((el)=>{
const pushEvent = (name, payload)=>{
const hookId = el.getAttribute(`${(0, _constants.constant).HookAttrPrefix}-id`);
socket.send(JSON.stringify([
"hook:event",
{
id: hookId,
name,
payload
}
]));
};
hooks[hook].mounted({
el,
pushEvent
});
});
});
dom = parsed[1];
break;
case "update":
dom = (0, _patch.applyPatch)(dom, parsed[1], parsed[2]);
break;
case "error":
const { code , msg } = parsed[1];
console.error(`Error ${code}: ${msg}`);
switch(code){
case "preflight_not_found":
setTimeout(()=>window.location.reload(), 1000);
break;
}
break;
}
(0, _morphdomDefault.default)(document.documentElement, (0, _render.renderDom)(dom), {
onBeforeElUpdated: function(fromEl, toEl) {
if (toEl.hasAttribute((0, _constants.constant).IgnoreUpdate)) return false;
return true;
},
getNodeKey: function(node) {
if (node.nodeType == Node.ELEMENT_NODE) {
const el = node;
if (el.hasAttribute((0, _constants.constant).KeyAttr)) return el.getAttribute((0, _constants.constant).KeyAttr);
}
}
});
}
});
socket.addEventListener("close", function(event) {
(0, _topbarDefault.default).show();
});
// wire up event handlers
(0, _events.initEventHandlers)(socket);
});
},{"morphdom":"ggNB9","topbar":"bqE3G","./render":"7GXQv","./patch":"ejlSn","./events":"69ru5","./constants":"dL7OZ","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3","./hooks/doubleclick":"6mK8N"}],"ggNB9":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
var DOCUMENT_FRAGMENT_NODE = 11;
function morphAttrs(fromNode, toNode) {
var toNodeAttrs = toNode.attributes;
var attr;
var attrName;
var attrNamespaceURI;
var attrValue;
var fromValue;
// document-fragments dont have attributes so lets not do anything
if (toNode.nodeType === DOCUMENT_FRAGMENT_NODE || fromNode.nodeType === DOCUMENT_FRAGMENT_NODE) return;
// update attributes on original DOM element
for(var i = toNodeAttrs.length - 1; i >= 0; i--){
attr = toNodeAttrs[i];
attrName = attr.name;
attrNamespaceURI = attr.namespaceURI;
attrValue = attr.value;
if (attrNamespaceURI) {
attrName = attr.localName || attrName;
fromValue = fromNode.getAttributeNS(attrNamespaceURI, attrName);
if (fromValue !== attrValue) {
if (attr.prefix === "xmlns") attrName = attr.name; // It's not allowed to set an attribute with the XMLNS namespace without specifying the `xmlns` prefix
fromNode.setAttributeNS(attrNamespaceURI, attrName, attrValue);
}
} else {
fromValue = fromNode.getAttribute(attrName);
if (fromValue !== attrValue) fromNode.setAttribute(attrName, attrValue);
}
}
// Remove any extra attributes found on the original DOM element that
// weren't found on the target element.
var fromNodeAttrs = fromNode.attributes;
for(var d = fromNodeAttrs.length - 1; d >= 0; d--){
attr = fromNodeAttrs[d];
attrName = attr.name;
attrNamespaceURI = attr.namespaceURI;
if (attrNamespaceURI) {
attrName = attr.localName || attrName;
if (!toNode.hasAttributeNS(attrNamespaceURI, attrName)) fromNode.removeAttributeNS(attrNamespaceURI, attrName);
} else if (!toNode.hasAttribute(attrName)) fromNode.removeAttribute(attrName);
}
}
var range; // Create a range object for efficently rendering strings to elements.
var NS_XHTML = "http://www.w3.org/1999/xhtml";
var doc = typeof document === "undefined" ? undefined : document;
var HAS_TEMPLATE_SUPPORT = !!doc && "content" in doc.createElement("template");
var HAS_RANGE_SUPPORT = !!doc && doc.createRange && "createContextualFragment" in doc.createRange();
function createFragmentFromTemplate(str) {
var template = doc.createElement("template");
template.innerHTML = str;
return template.content.childNodes[0];
}
function createFragmentFromRange(str) {
if (!range) {
range = doc.createRange();
range.selectNode(doc.body);
}
var fragment = range.createContextualFragment(str);
return fragment.childNodes[0];
}
function createFragmentFromWrap(str) {
var fragment = doc.createElement("body");
fragment.innerHTML = str;
return fragment.childNodes[0];
}
/**
* This is about the same
* var html = new DOMParser().parseFromString(str, 'text/html');
* return html.body.firstChild;
*
* @method toElement
* @param {String} str
*/ function toElement(str) {
str = str.trim();
if (HAS_TEMPLATE_SUPPORT) // avoid restrictions on content for things like `<tr><th>Hi</th></tr>` which
// createContextualFragment doesn't support
// <template> support not available in IE
return createFragmentFromTemplate(str);
else if (HAS_RANGE_SUPPORT) return createFragmentFromRange(str);
return createFragmentFromWrap(str);
}
/**
* Returns true if two node's names are the same.
*
* NOTE: We don't bother checking `namespaceURI` because you will never find two HTML elements with the same
* nodeName and different namespace URIs.
*
* @param {Element} a
* @param {Element} b The target element
* @return {boolean}
*/ function compareNodeNames(fromEl, toEl) {
var fromNodeName = fromEl.nodeName;
var toNodeName = toEl.nodeName;
var fromCodeStart, toCodeStart;
if (fromNodeName === toNodeName) return true;
fromCodeStart = fromNodeName.charCodeAt(0);
toCodeStart = toNodeName.charCodeAt(0);
// If the target element is a virtual DOM node or SVG node then we may
// need to normalize the tag name before comparing. Normal HTML elements that are
// in the "http://www.w3.org/1999/xhtml"
// are converted to upper case
if (fromCodeStart <= 90 && toCodeStart >= 97) return fromNodeName === toNodeName.toUpperCase();
else if (toCodeStart <= 90 && fromCodeStart >= 97) return toNodeName === fromNodeName.toUpperCase();
else return false;
}
/**
* Create an element, optionally with a known namespace URI.
*
* @param {string} name the element name, e.g. 'div' or 'svg'
* @param {string} [namespaceURI] the element's namespace URI, i.e. the value of
* its `xmlns` attribute or its inferred namespace.
*
* @return {Element}
*/ function createElementNS(name, namespaceURI) {
return !namespaceURI || namespaceURI === NS_XHTML ? doc.createElement(name) : doc.createElementNS(namespaceURI, name);
}
/**
* Copies the children of one DOM element to another DOM element
*/ function moveChildren(fromEl, toEl) {
var curChild = fromEl.firstChild;
while(curChild){
var nextChild = curChild.nextSibling;
toEl.appendChild(curChild);
curChild = nextChild;
}
return toEl;
}
function syncBooleanAttrProp(fromEl, toEl, name) {
if (fromEl[name] !== toEl[name]) {
fromEl[name] = toEl[name];
if (fromEl[name]) fromEl.setAttribute(name, "");
else fromEl.removeAttribute(name);
}
}
var specialElHandlers = {
OPTION: function(fromEl, toEl) {
var parentNode = fromEl.parentNode;
if (parentNode) {
var parentName = parentNode.nodeName.toUpperCase();
if (parentName === "OPTGROUP") {
parentNode = parentNode.parentNode;
parentName = parentNode && parentNode.nodeName.toUpperCase();
}
if (parentName === "SELECT" && !parentNode.hasAttribute("multiple")) {
if (fromEl.hasAttribute("selected") && !toEl.selected) {
// Workaround for MS Edge bug where the 'selected' attribute can only be
// removed if set to a non-empty value:
// https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12087679/
fromEl.setAttribute("selected", "selected");
fromEl.removeAttribute("selected");
}
// We have to reset select element's selectedIndex to -1, otherwise setting
// fromEl.selected using the syncBooleanAttrProp below has no effect.
// The correct selectedIndex will be set in the SELECT special handler below.
parentNode.selectedIndex = -1;
}
}
syncBooleanAttrProp(fromEl, toEl, "selected");
},
/**
* The "value" attribute is special for the <input> element since it sets
* the initial value. Changing the "value" attribute without changing the
* "value" property will have no effect since it is only used to the set the
* initial value. Similar for the "checked" attribute, and "disabled".
*/ INPUT: function(fromEl, toEl) {
syncBooleanAttrProp(fromEl, toEl, "checked");
syncBooleanAttrProp(fromEl, toEl, "disabled");
if (fromEl.value !== toEl.value) fromEl.value = toEl.value;
if (!toEl.hasAttribute("value")) fromEl.removeAttribute("value");
},
TEXTAREA: function(fromEl, toEl) {
var newValue = toEl.value;
if (fromEl.value !== newValue) fromEl.value = newValue;
var firstChild = fromEl.firstChild;
if (firstChild) {
// Needed for IE. Apparently IE sets the placeholder as the
// node value and vise versa. This ignores an empty update.
var oldValue = firstChild.nodeValue;
if (oldValue == newValue || !newValue && oldValue == fromEl.placeholder) return;
firstChild.nodeValue = newValue;
}
},
SELECT: function(fromEl, toEl) {
if (!toEl.hasAttribute("multiple")) {
var selectedIndex = -1;
var i = 0;
// We have to loop through children of fromEl, not toEl since nodes can be moved
// from toEl to fromEl directly when morphing.
// At the time this special handler is invoked, all children have already been morphed
// and appended to / removed from fromEl, so using fromEl here is safe and correct.
var curChild = fromEl.firstChild;
var optgroup;
var nodeName;
while(curChild){
nodeName = curChild.nodeName && curChild.nodeName.toUpperCase();
if (nodeName === "OPTGROUP") {
optgroup = curChild;
curChild = optgroup.firstChild;
} else {
if (nodeName === "OPTION") {
if (curChild.hasAttribute("selected")) {
selectedIndex = i;
break;
}
i++;
}
curChild = curChild.nextSibling;
if (!curChild && optgroup) {
curChild = optgroup.nextSibling;
optgroup = null;
}
}
}
fromEl.selectedIndex = selectedIndex;
}
}
};
var ELEMENT_NODE = 1;
var DOCUMENT_FRAGMENT_NODE$1 = 11;
var TEXT_NODE = 3;
var COMMENT_NODE = 8;
function noop() {}
function defaultGetNodeKey(node) {
if (node) return node.getAttribute && node.getAttribute("id") || node.id;
}
function morphdomFactory(morphAttrs) {
return function morphdom(fromNode, toNode, options) {
if (!options) options = {};
if (typeof toNode === "string") {
if (fromNode.nodeName === "#document" || fromNode.nodeName === "HTML" || fromNode.nodeName === "BODY") {
var toNodeHtml = toNode;
toNode = doc.createElement("html");
toNode.innerHTML = toNodeHtml;
} else toNode = toElement(toNode);
} else if (toNode.nodeType === DOCUMENT_FRAGMENT_NODE$1) toNode = toNode.firstElementChild;
var getNodeKey = options.getNodeKey || defaultGetNodeKey;
var onBeforeNodeAdded = options.onBeforeNodeAdded || noop;
var onNodeAdded = options.onNodeAdded || noop;
var onBeforeElUpdated = options.onBeforeElUpdated || noop;
var onElUpdated = options.onElUpdated || noop;
var onBeforeNodeDiscarded = options.onBeforeNodeDiscarded || noop;
var onNodeDiscarded = options.onNodeDiscarded || noop;
var onBeforeElChildrenUpdated = options.onBeforeElChildrenUpdated || noop;
var skipFromChildren = options.skipFromChildren || noop;
var addChild = options.addChild || function(parent, child) {
return parent.appendChild(child);
};
var childrenOnly = options.childrenOnly === true;
// This object is used as a lookup to quickly find all keyed elements in the original DOM tree.
var fromNodesLookup = Object.create(null);
var keyedRemovalList = [];
function addKeyedRemoval(key) {
keyedRemovalList.push(key);
}
function walkDiscardedChildNodes(node, skipKeyedNodes) {
if (node.nodeType === ELEMENT_NODE) {
var curChild = node.firstChild;
while(curChild){
var key = undefined;
if (skipKeyedNodes && (key = getNodeKey(curChild))) // If we are skipping keyed nodes then we add the key
// to a list so that it can be handled at the very end.
addKeyedRemoval(key);
else {
// Only report the node as discarded if it is not keyed. We do this because
// at the end we loop through all keyed elements that were unmatched
// and then discard them in one final pass.
onNodeDiscarded(curChild);
if (curChild.firstChild) walkDiscardedChildNodes(curChild, skipKeyedNodes);
}
curChild = curChild.nextSibling;
}
}
}
/**
* Removes a DOM node out of the original DOM
*
* @param {Node} node The node to remove
* @param {Node} parentNode The nodes parent
* @param {Boolean} skipKeyedNodes If true then elements with keys will be skipped and not discarded.
* @return {undefined}
*/ function removeNode(node, parentNode, skipKeyedNodes) {
if (onBeforeNodeDiscarded(node) === false) return;
if (parentNode) parentNode.removeChild(node);
onNodeDiscarded(node);
walkDiscardedChildNodes(node, skipKeyedNodes);
}
// // TreeWalker implementation is no faster, but keeping this around in case this changes in the future
// function indexTree(root) {
// var treeWalker = document.createTreeWalker(
// root,
// NodeFilter.SHOW_ELEMENT);
//
// var el;
// while((el = treeWalker.nextNode())) {
// var key = getNodeKey(el);
// if (key) {
// fromNodesLookup[key] = el;
// }
// }
// }
// // NodeIterator implementation is no faster, but keeping this around in case this changes in the future
//
// function indexTree(node) {
// var nodeIterator = document.createNodeIterator(node, NodeFilter.SHOW_ELEMENT);
// var el;
// while((el = nodeIterator.nextNode())) {
// var key = getNodeKey(el);
// if (key) {
// fromNodesLookup[key] = el;
// }
// }
// }
function indexTree(node) {
if (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE$1) {
var curChild = node.firstChild;
while(curChild){
var key = getNodeKey(curChild);
if (key) fromNodesLookup[key] = curChild;
// Walk recursively
indexTree(curChild);
curChild = curChild.nextSibling;
}
}
}
indexTree(fromNode);
function handleNodeAdded(el) {
onNodeAdded(el);
var curChild = el.firstChild;
while(curChild){
var nextSibling = curChild.nextSibling;
var key = getNodeKey(curChild);
if (key) {
var unmatchedFromEl = fromNodesLookup[key];
// if we find a duplicate #id node in cache, replace `el` with cache value
// and morph it to the child node.
if (unmatchedFromEl && compareNodeNames(curChild, unmatchedFromEl)) {
curChild.parentNode.replaceChild(unmatchedFromEl, curChild);
morphEl(unmatchedFromEl, curChild);
} else handleNodeAdded(curChild);
} else // recursively call for curChild and it's children to see if we find something in
// fromNodesLookup
handleNodeAdded(curChild);
curChild = nextSibling;
}
}
function cleanupFromEl(fromEl, curFromNodeChild, curFromNodeKey) {
// We have processed all of the "to nodes". If curFromNodeChild is
// non-null then we still have some from nodes left over that need
// to be removed
while(curFromNodeChild){
var fromNextSibling = curFromNodeChild.nextSibling;
if (curFromNodeKey = getNodeKey(curFromNodeChild)) // Since the node is keyed it might be matched up later so we defer
// the actual removal to later
addKeyedRemoval(curFromNodeKey);
else // NOTE: we skip nested keyed nodes from being removed since there is
// still a chance they will be matched up later
removeNode(curFromNodeChild, fromEl, true);
curFromNodeChild = fromNextSibling;
}
}
function morphEl(fromEl, toEl, childrenOnly) {
var toElKey = getNodeKey(toEl);
if (toElKey) // If an element with an ID is being morphed then it will be in the final
// DOM so clear it out of the saved elements collection
delete fromNodesLookup[toElKey];
if (!childrenOnly) {
// optional
if (onBeforeElUpdated(fromEl, toEl) === false) return;
// update attributes on original DOM element first
morphAttrs(fromEl, toEl);
// optional
onElUpdated(fromEl);
if (onBeforeElChildrenUpdated(fromEl, toEl) === false) return;
}
if (fromEl.nodeName !== "TEXTAREA") morphChildren(fromEl, toEl);
else specialElHandlers.TEXTAREA(fromEl, toEl);
}
function morphChildren(fromEl, toEl) {
var skipFrom = skipFromChildren(fromEl);
var curToNodeChild = toEl.firstChild;
var curFromNodeChild = fromEl.firstChild;
var curToNodeKey;
var curFromNodeKey;
var fromNextSibling;
var toNextSibling;
var matchingFromEl;
// walk the children
outer: while(curToNodeChild){
toNextSibling = curToNodeChild.nextSibling;
curToNodeKey = getNodeKey(curToNodeChild);
// walk the fromNode children all the way through
while(!skipFrom && curFromNodeChild){
fromNextSibling = curFromNodeChild.nextSibling;
if (curToNodeChild.isSameNode && curToNodeChild.isSameNode(curFromNodeChild)) {
curToNodeChild = toNextSibling;
curFromNodeChild = fromNextSibling;
continue outer;
}
curFromNodeKey = getNodeKey(curFromNodeChild);
var curFromNodeType = curFromNodeChild.nodeType;
// this means if the curFromNodeChild doesnt have a match with the curToNodeChild
var isCompatible = undefined;
if (curFromNodeType === curToNodeChild.nodeType) {
if (curFromNodeType === ELEMENT_NODE) {
// Both nodes being compared are Element nodes
if (curToNodeKey) // The target node has a key so we want to match it up with the correct element
// in the original DOM tree
{
if (curToNodeKey !== curFromNodeKey) {
// The current element in the original DOM tree does not have a matching key so
// let's check our lookup to see if there is a matching element in the original
// DOM tree
if (matchingFromEl = fromNodesLookup[curToNodeKey]) {
if (fromNextSibling === matchingFromEl) // Special case for single element removals. To avoid removing the original
// DOM node out of the tree (since that can break CSS transitions, etc.),
// we will instead discard the current node and wait until the next
// iteration to properly match up the keyed target element with its matching
// element in the original tree
isCompatible = false;
else {
// We found a matching keyed element somewhere in the original DOM tree.
// Let's move the original DOM node into the current position and morph
// it.
// NOTE: We use insertBefore instead of replaceChild because we want to go through
// the `removeNode()` function for the node that is being discarded so that
// all lifecycle hooks are correctly invoked
fromEl.insertBefore(matchingFromEl, curFromNodeChild);
// fromNextSibling = curFromNodeChild.nextSibling;
if (curFromNodeKey) // Since the node is keyed it might be matched up later so we defer
// the actual removal to later
addKeyedRemoval(curFromNodeKey);
else // NOTE: we skip nested keyed nodes from being removed since there is
// still a chance they will be matched up later
removeNode(curFromNodeChild, fromEl, true);
curFromNodeChild = matchingFromEl;
}
} else // The nodes are not compatible since the "to" node has a key and there
// is no matching keyed node in the source tree
isCompatible = false;
}
} else if (curFromNodeKey) // The original has a key
isCompatible = false;
isCompatible = isCompatible !== false && compareNodeNames(curFromNodeChild, curToNodeChild);
if (isCompatible) // We found compatible DOM elements so transform
// the current "from" node to match the current
// target DOM node.
// MORPH
morphEl(curFromNodeChild, curToNodeChild);
} else if (curFromNodeType === TEXT_NODE || curFromNodeType == COMMENT_NODE) {
// Both nodes being compared are Text or Comment nodes
isCompatible = true;
// Simply update nodeValue on the original node to
// change the text value
if (curFromNodeChild.nodeValue !== curToNodeChild.nodeValue) curFromNodeChild.nodeValue = curToNodeChild.nodeValue;
}
}
if (isCompatible) {
// Advance both the "to" child and the "from" child since we found a match
// Nothing else to do as we already recursively called morphChildren above
curToNodeChild = toNextSibling;
curFromNodeChild = fromNextSibling;
continue outer;
}
// No compatible match so remove the old node from the DOM and continue trying to find a
// match in the original DOM. However, we only do this if the from node is not keyed
// since it is possible that a keyed node might match up with a node somewhere else in the
// target tree and we don't want to discard it just yet since it still might find a
// home in the final DOM tree. After everything is done we will remove any keyed nodes
// that didn't find a home
if (curFromNodeKey) // Since the node is keyed it might be matched up later so we defer
// the actual removal to later
addKeyedRemoval(curFromNodeKey);
else // NOTE: we skip nested keyed nodes from being removed since there is
// still a chance they will be matched up later
removeNode(curFromNodeChild, fromEl, true);
curFromNodeChild = fromNextSibling;
} // END: while(curFromNodeChild) {}
// If we got this far then we did not find a candidate match for
// our "to node" and we exhausted all of the children "from"
// nodes. Therefore, we will just append the current "to" node
// to the end
if (curToNodeKey && (matchingFromEl = fromNodesLookup[curToNodeKey]) && compareNodeNames(matchingFromEl, curToNodeChild)) {
// MORPH
if (!skipFrom) addChild(fromEl, matchingFromEl);
morphEl(matchingFromEl, curToNodeChild);
} else {
var onBeforeNodeAddedResult = onBeforeNodeAdded(curToNodeChild);
if (onBeforeNodeAddedResult !== false) {
if (onBeforeNodeAddedResult) curToNodeChild = onBeforeNodeAddedResult;
if (curToNodeChild.actualize) curToNodeChild = curToNodeChild.actualize(fromEl.ownerDocument || doc);
addChild(fromEl, curToNodeChild);
handleNodeAdded(curToNodeChild);
}
}
curToNodeChild = toNextSibling;
curFromNodeChild = fromNextSibling;
}
cleanupFromEl(fromEl, curFromNodeChild, curFromNodeKey);
var specialElHandler = specialElHandlers[fromEl.nodeName];
if (specialElHandler) specialElHandler(fromEl, toEl);
} // END: morphChildren(...)
var morphedNode = fromNode;
var morphedNodeType = morphedNode.nodeType;
var toNodeType = toNode.nodeType;
if (!childrenOnly) {
// Handle the case where we are given two DOM nodes that are not
// compatible (e.g. <div> --> <span> or <div> --> TEXT)
if (morphedNodeType === ELEMENT_NODE) {
if (toNodeType === ELEMENT_NODE) {
if (!compareNodeNames(fromNode, toNode)) {
onNodeDiscarded(fromNode);
morphedNode = moveChildren(fromNode, createElementNS(toNode.nodeName, toNode.namespaceURI));
}
} else // Going from an element node to a text node
morphedNode = toNode;
} else if (morphedNodeType === TEXT_NODE || morphedNodeType === COMMENT_NODE) {
if (toNodeType === morphedNodeType) {
if (morphedNode.nodeValue !== toNode.nodeValue) morphedNode.nodeValue = toNode.nodeValue;
return morphedNode;
} else // Text node to something else
morphedNode = toNode;
}
}
if (morphedNode === toNode) // The "to node" was not compatible with the "from node" so we had to
// toss out the "from node" and use the "to node"
onNodeDiscarded(fromNode);
else {
if (toNode.isSameNode && toNode.isSameNode(morphedNode)) return;
morphEl(morphedNode, toNode, childrenOnly);
// We now need to loop over any keyed nodes that might need to be
// removed. We only do the removal if we know that the keyed node
// never found a match. When a keyed node is matched up we remove
// it out of fromNodesLookup and we use fromNodesLookup to determine
// if a keyed node has been matched up or not
if (keyedRemovalList) for(var i = 0, len = keyedRemovalList.length; i < len; i++){
var elToRemove = fromNodesLookup[keyedRemovalList[i]];
if (elToRemove) removeNode(elToRemove, elToRemove.parentNode, false);
}
}
if (!childrenOnly && morphedNode !== fromNode && fromNode.parentNode) {
if (morphedNode.actualize) morphedNode = morphedNode.actualize(fromNode.ownerDocument || doc);
// If we had to swap out the from node with a new node because the old
// node was not compatible with the target node then we need to
// replace the old DOM node in the original DOM tree. This is only
// possible if the original DOM node was part of a DOM tree which
// we know is the case if it has a parent node.
fromNode.parentNode.replaceChild(morphedNode, fromNode);
}
return morphedNode;
};
}
var morphdom = morphdomFactory(morphAttrs);
exports.default = morphdom;
},{"@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"gkKU3":[function(require,module,exports) {
exports.interopDefault = function(a) {
return a && a.__esModule ? a : {
default: a
};
};
exports.defineInteropFlag = function(a) {
Object.defineProperty(a, "__esModule", {
value: true
});
};
exports.exportAll = function(source, dest) {
Object.keys(source).forEach(function(key) {
if (key === "default" || key === "__esModule" || dest.hasOwnProperty(key)) return;
Object.defineProperty(dest, key, {
enumerable: true,
get: function() {
return source[key];
}
});
});
return dest;
};
exports.export = function(dest, destName, get) {
Object.defineProperty(dest, destName, {
enumerable: true,
get: get
});
};
},{}],"bqE3G":[function(require,module,exports) {
/**
* @license MIT
* topbar 2.0.0, 2023-02-04
* http://buunguyen.github.io/topbar
* Copyright (c) 2021 Buu Nguyen
*/ (function(window1, document1) {
"use strict";
function repaint() {
canvas.width = window1.innerWidth, canvas.height = 5 * options.barThickness;
var ctx = canvas.getContext("2d");
ctx.shadowBlur = options.shadowBlur, ctx.shadowColor = options.shadowColor;
var stop, lineGradient = ctx.createLinearGradient(0, 0, canvas.width, 0);
for(stop in options.barColors)lineGradient.addColorStop(stop, options.barColors[stop]);
ctx.lineWidth = options.barThickness, ctx.beginPath(), ctx.moveTo(0, options.barThickness / 2), ctx.lineTo(Math.ceil(currentProgress * canvas.width), options.barThickness / 2), ctx.strokeStyle = lineGradient, ctx.stroke();
}
var canvas, currentProgress, showing, progressTimerId = null, fadeTimerId = null, delayTimerId = null, options = {
autoRun: !0,
barThickness: 3,
barColors: {
0: "rgba(26, 188, 156, .9)",
".25": "rgba(52, 152, 219, .9)",
".50": "rgba(241, 196, 15, .9)",
".75": "rgba(230, 126, 34, .9)",
"1.0": "rgba(211, 84, 0, .9)"
},
shadowBlur: 10,
shadowColor: "rgba(0, 0, 0, .6)",
className: null
}, topbar = {
config: function(opts) {
for(var key in opts)options.hasOwnProperty(key) && (options[key] = opts[key]);
},
show: function(handler) {
var type, elem;
showing || (handler ? delayTimerId = delayTimerId || setTimeout(()=>topbar.show(), handler) : (showing = !0, null !== fadeTimerId && window1.cancelAnimationFrame(fadeTimerId), canvas || ((elem = (canvas = document1.createElement("canvas")).style).position = "fixed", elem.top = elem.left = elem.right = elem.margin = elem.padding = 0, elem.zIndex = 100001, elem.display = "none", options.className && canvas.classList.add(options.className), document1.body.appendChild(canvas), type = "resize", handler = repaint, (elem = window1).addEventListener ? elem.addEventListener(type, handler, !1) : elem.attachEvent ? elem.attachEvent("on" + type, handler) : elem["on" + type] = handler), canvas.style.opacity = 1, canvas.style.display = "block", topbar.progress(0), options.autoRun && function loop() {
progressTimerId = window1.requestAnimationFrame(loop), topbar.progress("+" + .05 * Math.pow(1 - Math.sqrt(currentProgress), 2));
}()));
},
progress: function(to) {
return void 0 === to || ("string" == typeof to && (to = (0 <= to.indexOf("+") || 0 <= to.indexOf("-") ? currentProgress : 0) + parseFloat(to)), currentProgress = 1 < to ? 1 : to, repaint()), currentProgress;
},
hide: function() {
clearTimeout(delayTimerId), delayTimerId = null, showing && (showing = !1, null != progressTimerId && (window1.cancelAnimationFrame(progressTimerId), progressTimerId = null), function loop() {
return 1 <= topbar.progress("+.1") && (canvas.style.opacity -= .05, canvas.style.opacity <= .05) ? (canvas.style.display = "none", void (fadeTimerId = null)) : void (fadeTimerId = window1.requestAnimationFrame(loop));
}());
}
};
"object" == typeof module.exports ? module.exports = topbar : "function" == typeof define && define.amd ? define(function() {
return topbar;
}) : this.topbar = topbar;
}).call(this, window, document);
},{}],"7GXQv":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
// very naive and basic rendering algorithm
// TODO: rewrite to a more readable approach
parcelHelpers.export(exports, "renderDom", ()=>renderDom);
var _utils = require("./utils");
function renderDom(dom) {
if (typeof dom === "string") return dom;
switch(dom.type){
case "component":
return renderComponent(dom);
default:
return renderElement(dom);
}
}
function renderComponent(component) {
let result = "";
for(let i = 0; i < Object.keys(component).length - 1; i++)result += renderDom(component[i]);
return result;
}
function renderElement(element) {
const openingTag = Object.keys(element.attrs).reduce((result, key)=>{
return result + ` ${key}="${element.attrs[key]}"`;
}, `<${element.type}`) + ">";
const children = Object.keys(element).filter((key)=>(0, _utils.isInteger)(key)).reduce((rendered, key)=>rendered + renderDom(element[key]), "");
const closingTag = "</" + element.type + ">";
return openingTag + children + closingTag;
}
},{"./utils":"aAKdp","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"aAKdp":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "isInteger", ()=>isInteger);
const isInteger = (str)=>!Number.isNaN(parseInt(str, 10));
},{"@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"ejlSn":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "applyPatch", ()=>applyPatch);
var _utils = require("./utils");
var OpCode;
(function(OpCode) {
OpCode[OpCode["NoOp"] = 0] = "NoOp";
OpCode[OpCode["Update"] = 1] = "Update";
OpCode[OpCode["Replace"] = 2] = "Replace";
OpCode[OpCode["Insert"] = 3] = "Insert";
OpCode[OpCode["Remove"] = 4] = "Remove";
OpCode[OpCode["Change"] = 5] = "Change";
OpCode[OpCode["Move"] = 6] = "Move";
})(OpCode || (OpCode = {}));
function getOperation(patch, debug) {
if (debug) switch(patch[0]){
case "NoOp":
return [
OpCode.NoOp
];
case "Update":
return [
OpCode.Update,
patch[1],
patch[2]
];
case "Replace":
return [
OpCode.Replace,
patch[1]
];
case "Insert":
return [
OpCode.Insert,
patch[1]
];
case "Remove":
return [
OpCode.Remove
];
case "Change":
return [
OpCode.Change,
patch[1]
];
case "Move":
return [
OpCode.Move,
patch[1],
patch[2]
];
default:
throw new Error("Unknown op code: " + patch[0]);
}
// in regular production mode op codes are compressed and sent as integer strings to save bytes
switch(patch[0]){
case "0":
return [
OpCode.NoOp
];
case "1":
return [
OpCode.Update,
patch[1],
patch[2]
];
case "2":
return [
OpCode.Replace,
patch[1]
];
case "3":
return [
OpCode.Insert,
patch[1]
];
case "4":
return [
OpCode.Remove
];
case "5":
return [
OpCode.Change,
patch[1]
];
case "6":
return [
OpCode.Move,
patch[1],
patch[2]
];
default:
throw new Error("Unknown op code: " + patch[0]);
}
}
function applyPatch(original, patch, opts, parent, currentKey) {
const operation = getOperation(patch, !!opts.debug);
switch(operation[0]){
case OpCode.NoOp:
return original;
case OpCode.Update:
const newAttrs = operation[1];
const childrenPatchMap = operation[2];
let updated = Object.assign({}, original);
if (newAttrs) updated = {
...updated,
attrs: newAttrs
};
if (childrenPatchMap) updated = Object.keys(childrenPatchMap).filter((key)=>(0, _utils.isInteger)(key)).reduce((updated, key)=>{
const childOperation = getOperation(patch, !!opts.debug);
let newEl = applyPatch(updated[key], childrenPatchMap[key], opts, original, key);
if (newEl) {
if (childOperation[0] === OpCode.Move) {
const fromKey = childOperation[1];
delete updated[fromKey];
}
return {
...updated,
[key]: newEl
};
} else delete updated[key];
return updated;
}, updated);
return updated;
case OpCode.Replace:
return operation[1];
case OpCode.Insert:
return operation[1];
case OpCode.Remove:
return null;
case OpCode.Change:
return operation[1];
case OpCode.Move:
if (parent) {
const fromKey = operation[1];
const movedAndPatched = applyPatch(parent[fromKey], operation[2], opts, parent, currentKey);
return movedAndPatched;
} else throw new Error("Cannot move element without parent");
}
}
},{"./utils":"aAKdp","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"69ru5":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "initEventHandlers", ()=>initEventHandlers);
var _constants = require("./constants");
// map for browser events to listen for and the corresponding sprocket event types
// they potentially handle
const browserEventKinds = {
click: [
"click"
],
dblclick: [
"dblclick"
],
change: [
"change"
],
input: [
"input"
]
};
function initEventHandlers(socket) {
Object.keys(browserEventKinds).forEach((kind)=>{
window.addEventListener(kind, (e)=>{
let target = e.target;
const handler = bubbleToNearestHandler(target, kind, target.value);
if (handler) socket.send(JSON.stringify([
"event",
handler
]));
});
});
}
function bubbleToNearestHandler(el, kind, value) {
if (el) {
const spktEvents = browserEventKinds[kind];
let spktKind = spktEvents.find((spktEvent)=>{
return el.hasAttribute(`${(0, _constants.constant).EventAttrPrefix}-${spktEvent}`);
});
if (spktKind) {
let id = el.attributes[`${(0, _constants.constant).EventAttrPrefix}-${spktKind}`].value;
return {
kind: spktKind,
id,
value
};
} else return bubbleToNearestHandler(el.parentElement, kind, value);
}
}
},{"./constants":"dL7OZ","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"dL7OZ":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "constant", ()=>constant);
var constant;
(function(constant) {
constant["KeyAttr"] = "spkt-key";
constant["EventAttrPrefix"] = "spkt-event";
constant["IgnoreUpdate"] = "spkt-ignore-update";
constant["HookAttrPrefix"] = "spkt-hook";
})(constant || (constant = {}));
},{"@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"6mK8N":[function(require,module,exports) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "doubleclick", ()=>doubleclick);
const doubleclick = {
mounted ({ el , pushEvent }) {
console.log("doubleclick mounted", el);
el.addEventListener("dblclick", ()=>{
pushEvent("doubleclick", {});
});
}
};
},{"@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}]},["2WBxL"], "2WBxL", "parcelRequire94c2")
//# sourceMappingURL=client.js.map