More or less cosmetic
This commit is contained in:
parent
92fa548109
commit
666a3daac3
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue