More or less cosmetic

This commit is contained in:
Tony Garnock-Jones 2021-12-11 16:54:21 +01:00
parent 92fa548109
commit 666a3daac3
1 changed files with 89 additions and 88 deletions

View File

@ -76,12 +76,12 @@ export function spawnWindowEventFactory(ds: Ref) {
const facet = Turn.activeFacet;
facet.preventInertCheck();
let handler = function (event: Event) {
let handler = (event: Event) => {
facet.turn(() => {
send message P.WindowEvent(eventType, embed(create ({ data: event })));
});
return dealWithPreventDefault(eventType, event);
}
};
function updateEventListeners(install: boolean) {
if (install) {
@ -116,108 +116,109 @@ function spawnUIFragmentFactory(ds: Ref) {
spawn named 'UIFragmentFactory' {
at ds {
during P.UIFragment($fragmentId0, _, _, _) => spawn named ['UIFragment', fragmentId0] {
if (!isFragmentId(fragmentId0)) return;
const fragmentId = fragmentId0;
during P.UIFragment($fragmentId0, _, _, _) =>
spawn named ['UIFragment', fragmentId0] {
if (!isFragmentId(fragmentId0)) return;
const fragmentId = fragmentId0;
field version: number = 0;
assert P.UIFragmentVersion(fragmentId, version.value) when (version.value > 0);
field version: number = 0;
assert P.UIFragmentVersion(fragmentId, version.value) when (version.value > 0);
let selector: string;
let html: Array<ChildNode>;
let orderBy: NodeOrderKey;
let anchorNodes: Array<Element> = [];
let eventRegistrations =
new FlexMap<RegistrationKey, HandlerClosure>(JSON.stringify);
let selector: string;
let html: Array<ChildNode>;
let orderBy: NodeOrderKey;
let anchorNodes: Array<Element> = [];
let eventRegistrations =
new FlexMap<RegistrationKey, HandlerClosure>(JSON.stringify);
on stop removeNodes();
on stop removeNodes();
during Observe({
"pattern": :pattern P.UIEvent(fragmentId,
\Q.lit($selector: string),
\Q.lit($eventType: string),
\_)
}) => {
updateEventListeners([ selector, eventType ], true);
on stop updateEventListeners([ selector, eventType ], false);
}
on asserted P.UIFragment(fragmentId, $newSelector: string, $newHtml, $newOrderBy) => {
if (!isNodeOrderKey(newOrderBy)) return;
removeNodes();
selector = newSelector;
html = (newHtml as Embedded<Ref>).embeddedValue.target.data as ChildNode[];
orderBy = newOrderBy;
anchorNodes = (selector !== null) ? selectorMatch(document.body, selector) : [];
if (anchorNodes.length === 0) {
console.warn('UIFragment found no parent nodes matching selector', selector, fragmentId);
during Observe({
"pattern": :pattern P.UIEvent(fragmentId,
\Q.lit($selector: string),
\Q.lit($eventType: string),
\_)
}) => {
updateEventListeners([ selector, eventType ], true);
on stop updateEventListeners([ selector, eventType ], false);
}
anchorNodes.forEach(anchorNode => {
let insertionPoint = findInsertionPoint(anchorNode, orderBy, fragmentId);
html.forEach(newNode => {
setSortKey(newNode, orderBy, fragmentId);
anchorNode.insertBefore(newNode, insertionPoint);
configureNode(newNode);
});
});
on asserted P.UIFragment(fragmentId, $newSelector: string, $newHtml, $newOrderBy) => {
if (!isNodeOrderKey(newOrderBy)) return;
// (re)install event listeners
eventRegistrations.forEach((_handler, key) => updateEventListeners(key, true));
removeNodes();
version.value++;
}
selector = newSelector;
html = (newHtml as Embedded<Ref>).embeddedValue.target.data as ChildNode[];
orderBy = newOrderBy;
anchorNodes = (selector !== null) ? selectorMatch(document.body, selector) : [];
function removeNodes() {
anchorNodes.forEach(anchorNode => {
let insertionPoint = findInsertionPoint(anchorNode, orderBy, fragmentId);
while (true) {
let n = insertionPoint ? insertionPoint.previousSibling : anchorNode.lastChild;
if (!(n && hasSortKey(n, orderBy, fragmentId))) break;
n.parentNode?.removeChild(n); // auto-updates previousSibling/lastChild
if (anchorNodes.length === 0) {
console.warn('UIFragment found no parent nodes matching selector', selector, fragmentId);
}
});
}
function updateEventListeners(key: RegistrationKey, install: boolean) {
const [selector, eventType] = key;
let handlerClosure: HandlerClosure;
if (!eventRegistrations.has(key)) {
const facet = Turn.activeFacet;
function handler(event: Event) {
facet.turn(() => {
send message P.UIEvent(fragmentId, selector, eventType, embed(create ({ data: event })));
anchorNodes.forEach(anchorNode => {
let insertionPoint = findInsertionPoint(anchorNode, orderBy, fragmentId);
html.forEach(newNode => {
setSortKey(newNode, orderBy, fragmentId);
anchorNode.insertBefore(newNode, insertionPoint);
configureNode(newNode);
});
return dealWithPreventDefault(eventType, event);
}
eventRegistrations.set(key, handler);
handlerClosure = handler;
} else {
handlerClosure = eventRegistrations.get(key)!;
});
// (re)install event listeners
eventRegistrations.forEach((_handler, key) => updateEventListeners(key, true));
version.value++;
}
anchorNodes.forEach(anchorNode => {
let insertionPoint = findInsertionPoint(anchorNode, orderBy, fragmentId);
while (true) {
let uiNode = insertionPoint ? insertionPoint.previousSibling : anchorNode.lastChild;
if (!(uiNode && hasSortKey(uiNode, orderBy, fragmentId))) break;
if (isQueryableNode(uiNode)) {
selectorMatch(uiNode, selector).forEach(
eventUpdater(cleanEventType(eventType), handlerClosure, install));
function removeNodes() {
anchorNodes.forEach(anchorNode => {
let insertionPoint = findInsertionPoint(anchorNode, orderBy, fragmentId);
while (true) {
let n = insertionPoint ? insertionPoint.previousSibling : anchorNode.lastChild;
if (!(n && hasSortKey(n, orderBy, fragmentId))) break;
n.parentNode?.removeChild(n); // auto-updates previousSibling/lastChild
}
insertionPoint = uiNode;
}
});
});
}
if (!install) {
eventRegistrations.delete(key);
function updateEventListeners(key: RegistrationKey, install: boolean) {
const [selector, eventType] = key;
let handlerClosure: HandlerClosure;
if (!eventRegistrations.has(key)) {
const facet = Turn.activeFacet;
function handler(event: Event) {
facet.turn(() => {
send message P.UIEvent(fragmentId, selector, eventType, embed(create ({ data: event })));
});
return dealWithPreventDefault(eventType, event);
}
eventRegistrations.set(key, handler);
handlerClosure = handler;
} else {
handlerClosure = eventRegistrations.get(key)!;
}
anchorNodes.forEach(anchorNode => {
let insertionPoint = findInsertionPoint(anchorNode, orderBy, fragmentId);
while (true) {
let uiNode = insertionPoint ? insertionPoint.previousSibling : anchorNode.lastChild;
if (!(uiNode && hasSortKey(uiNode, orderBy, fragmentId))) break;
if (isQueryableNode(uiNode)) {
selectorMatch(uiNode, selector).forEach(
eventUpdater(cleanEventType(eventType), handlerClosure, install));
}
insertionPoint = uiNode;
}
});
if (!install) {
eventRegistrations.delete(key);
}
}
}
}
}
}
}
@ -309,7 +310,7 @@ function configureNode(n: ChildNode) {
// Runs post-insertion configuration of nodes.
// TODO: review this design.
selectorMatch(n, '.-syndicate-focus').forEach(
function (n: Element | HTMLTextAreaElement | HTMLInputElement) {
(n: Element | HTMLTextAreaElement | HTMLInputElement) => {
if ('focus' in n && 'setSelectionRange' in n) {
n.focus();
n.setSelectionRange(n.value.length, n.value.length);
@ -573,7 +574,7 @@ function selectorMatch(n: Element | Node, selector: string): Array<Element> {
}
function eventUpdater(eventType: string, handlerClosure: (event: Event) => void, install: boolean) {
return function (n: EventTarget) {
return (n: EventTarget) => {
// addEventListener and removeEventListener are idempotent.
if (install) {
n.addEventListener(eventType, handlerClosure);