Classes naming refactoring

This commit is contained in:
barsdeveloper
2022-02-27 12:44:48 +01:00
parent 96f0d593e7
commit e8946745d6
35 changed files with 790 additions and 786 deletions

288
dist/ueblueprint.js vendored
View File

@@ -124,6 +124,28 @@ class Configuration {
}
}
/**
* This solves the sole purpose of providing compression capability for html inside template literals strings. Check rollup.config.js function minifyHTML()
*/
const html = String.raw;
document.createElement("div");
const tagReplacement = {
'&': '&',
'<': '&lt;',
'>': '&gt;',
"'": '&#39;',
'"': '&quot;'
};
function sanitizeText(value) {
if (value.constructor === String) {
return value.replace(/[&<>'"]/g, tag => tagReplacement[tag])
}
return value
}
class OrderedIndexArray {
/**
@@ -429,23 +451,23 @@ class FastSelectionModel {
/**
* @typedef {import("../Blueprint").default} Blueprint
* @typedef {import("../entity/Entity").default} Entity
* @typedef {import("../entity/IEntity").IEntity} IEntity
* @typedef {import("../input/Context").default} Context
* @typedef {import("../template/Template").default} Template
*/
class GraphElement extends HTMLElement {
class IElement extends HTMLElement {
/**
*
* @param {Entity} entity The entity containing blueprint related data for this graph element
* @param {IEntity} entity The entity containing blueprint related data for this graph element
* @param {Template} template The template to render this node
*/
constructor(entity, template) {
super();
/** @type {Blueprint} */
this.blueprint = null;
/** @type {Entity} */
/** @type {IEntity} */
this.entity = entity;
/** @type {Template} */
this.template = template;
@@ -472,31 +494,14 @@ class GraphElement extends HTMLElement {
}
}
document.createElement("div");
const tagReplacement = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
"'": '&#39;',
'"': '&quot;'
};
function sanitizeText(value) {
if (value.constructor === String) {
return value.replace(/[&<>'"]/g, tag => tagReplacement[tag])
}
return value
}
/**
* @typedef {import("../graph/GraphElement").default} GraphElement
* @typedef {import("../element/IElement").default} IElement
*/
class Template {
/**
* Computes the html content of the target element.
* @param {GraphElement} entity Element of the graph
* @param {IElement} entity Element of the graph
* @returns The result html
*/
render(entity) {
@@ -505,7 +510,7 @@ class Template {
/**
* Applies the style to the element.
* @param {GraphElement} element Element of the graph
* @param {IElement} element Element of the graph
*/
apply(element) {
// TODO replace with the safer element.setHTML(...) when it will be available
@@ -514,13 +519,13 @@ class Template {
}
/**
* @typedef {import("../graph/GraphSelector").default} GraphSelector
* @typedef {import("../element/SelectorElement").default} SelectorElement
*/
class SelectorTemplate extends Template {
/**
* Applies the style to the element.
* @param {GraphSelector} selector Selector element
* @param {SelectorElement} selector Selector element
*/
apply(selector) {
super.apply(selector);
@@ -530,7 +535,7 @@ class SelectorTemplate extends Template {
/**
* Applies the style relative to selection beginning.
* @param {GraphSelector} selector Selector element
* @param {SelectorElement} selector Selector element
*/
applyStartSelecting(selector, initialPosition) {
// Set initial position
@@ -544,7 +549,7 @@ class SelectorTemplate extends Template {
/**
* Applies the style relative to selection.
* @param {GraphSelector} selector Selector element
* @param {SelectorElement} selector Selector element
*/
applyDoSelecting(selector, finalPosition) {
selector.style.setProperty("--ueb-to-x", sanitizeText(finalPosition[0]));
@@ -553,14 +558,14 @@ class SelectorTemplate extends Template {
/**
* Applies the style relative to selection finishing.
* @param {GraphSelector} selector Selector element
* @param {SelectorElement} selector Selector element
*/
applyFinishSelecting(selector) {
selector.blueprint.dataset.selecting = "false";
}
}
class GraphSelector extends GraphElement {
class SelectorElement extends IElement {
static tagName = "ueb-selector"
@@ -595,12 +600,7 @@ class GraphSelector extends GraphElement {
}
}
customElements.define(GraphSelector.tagName, GraphSelector);
/**
* This solves the sole purpose of providing compression capability for html inside template literals strings. Check rollup.config.js function minifyHTML()
*/
const html = String.raw;
customElements.define(SelectorElement.tagName, SelectorElement);
/** @typedef {import("../Blueprint").default} Blueprint */
class BlueprintTemplate extends Template {
@@ -675,7 +675,7 @@ class BlueprintTemplate extends Template {
blueprint.viewportElement = blueprint.querySelector('.ueb-viewport-body');
blueprint.gridElement = blueprint.viewportElement.querySelector(".ueb-grid");
blueprint.nodesContainerElement = blueprint.querySelector("[data-nodes]");
blueprint.selectorElement = new GraphSelector();
blueprint.selectorElement = new SelectorElement();
blueprint.nodesContainerElement.append(blueprint.selectorElement, ...blueprint.getNodes());
this.applyEndDragScrolling(blueprint);
}
@@ -898,7 +898,7 @@ class Utility {
}
}
class Entity {
class IEntity {
constructor(options = {}) {
/**
@@ -951,7 +951,7 @@ class Entity {
}
}
class ObjectReferenceEntity extends Entity {
class ObjectReferenceEntity extends IEntity {
static attributes = {
type: String,
@@ -963,7 +963,7 @@ class ObjectReferenceEntity extends Entity {
}
}
class FunctionReferenceEntity extends Entity {
class FunctionReferenceEntity extends IEntity {
static attributes = {
MemberParent: ObjectReferenceEntity,
@@ -975,7 +975,7 @@ class FunctionReferenceEntity extends Entity {
}
}
class GuidEntity extends Entity {
class GuidEntity extends IEntity {
static attributes = {
value: String
@@ -1002,7 +1002,7 @@ class GuidEntity extends Entity {
}
}
class IntegerEntity extends Entity {
class IntegerEntity extends IEntity {
static attributes = {
value: Number
@@ -1031,7 +1031,7 @@ class IntegerEntity extends Entity {
}
}
class LocalizedTextEntity extends Entity {
class LocalizedTextEntity extends IEntity {
static lookbehind = "NSLOCTEXT"
static attributes = {
@@ -1045,7 +1045,7 @@ class LocalizedTextEntity extends Entity {
}
}
class PathSymbolEntity extends Entity {
class PathSymbolEntity extends IEntity {
static attributes = {
value: String
@@ -1060,7 +1060,7 @@ class PathSymbolEntity extends Entity {
}
}
class PinReferenceEntity extends Entity {
class PinReferenceEntity extends IEntity {
static attributes = {
objectName: PathSymbolEntity,
@@ -1072,7 +1072,7 @@ class PinReferenceEntity extends Entity {
}
}
class PinEntity$1 extends Entity {
class PinEntity$1 extends IEntity {
static lookbehind = "Pin"
static attributes = {
@@ -1126,7 +1126,7 @@ class PinEntity$1 extends Entity {
}
}
class VariableReferenceEntity extends Entity {
class VariableReferenceEntity extends IEntity {
static attributes = {
MemberName: String,
@@ -1139,7 +1139,7 @@ class VariableReferenceEntity extends Entity {
}
}
class ObjectEntity extends Entity {
class ObjectEntity extends IEntity {
static attributes = {
Class: ObjectReferenceEntity,
@@ -1394,7 +1394,7 @@ class Serializer {
if (value instanceof Array) {
return `(${value.map(v => serialize(v) + ",")})`
}
if (value instanceof Entity) {
if (value instanceof IEntity) {
return serialize(value)
}
}
@@ -1518,8 +1518,8 @@ class Copy extends Context {
}
/**
* @typedef {import("../graph/GraphLink").default} GraphLink
* @typedef {import("../graph/GraphLinkMessage").default} GraphLinkMessage
* @typedef {import("../element/LinkElement").default} LinkElement
* @typedef {import("../element/LinkMessageElement").default} LinkMessageElement
*/
class LinkTemplate extends Template {
@@ -1533,7 +1533,7 @@ class LinkTemplate extends Template {
/**
* Computes the html content of the target element.
* @param {GraphLink} link connecting two graph nodes
* @param {LinkElement} link connecting two graph nodes
* @returns The result html
*/
render(link) {
@@ -1546,7 +1546,7 @@ class LinkTemplate extends Template {
/**
* Applies the style to the element.
* @param {GraphLink} link Element of the graph
* @param {LinkElement} link Element of the graph
*/
apply(link) {
super.apply(link);
@@ -1559,7 +1559,7 @@ class LinkTemplate extends Template {
/**
* Applies the style relative to the source pin location.
* @param {GraphLink} link Link element
* @param {LinkElement} link Link element
*/
applySourceLocation(link) {
link.style.setProperty("--ueb-from-input", link.originatesFromInput ? "0" : "1");
@@ -1569,7 +1569,7 @@ class LinkTemplate extends Template {
/**
* Applies the style relative to the destination pin location.
* @param {GraphLink} link Link element
* @param {LinkElement} link Link element
*/
applyFullLocation(link) {
const dx = Math.max(Math.abs(link.sourceLocation[0] - link.destinationLocation[0]), 1);
@@ -1611,8 +1611,8 @@ class LinkTemplate extends Template {
/**
*
* @param {GraphLink} link element
* @param {GraphLinkMessage} linkMessage
* @param {LinkElement} link element
* @param {LinkMessageElement} linkMessage
*/
applyLinkMessage(link, linkMessage) {
link.querySelectorAll(linkMessage.constructor.tagName).forEach(element => element.remove());
@@ -1622,15 +1622,15 @@ class LinkTemplate extends Template {
}
/**
* @typedef {import("./GraphPin").default} GraphPin
* @typedef {import("./GraphLinkMessage").default} GraphLinkMessage
* @typedef {import("./PinElement").default} PinElement
* @typedef {import("./LinkMessageElement").default} LinkMessageElement
*/
class GraphLink extends GraphElement {
class LinkElement extends IElement {
static tagName = "ueb-link"
/** @type {GraphPin} */
/** @type {PinElement} */
#source
/** @type {GraphPin} */
/** @type {PinElement} */
#destination
#nodeDeleteHandler
#nodeDragSourceHandler
@@ -1638,14 +1638,14 @@ class GraphLink extends GraphElement {
sourceLocation = [0, 0]
/** @type {SVGPathElement} */
pathElement
/** @type {GraphLinkMessage} */
/** @type {LinkMessageElement} */
linkMessageElement
originatesFromInput = false
destinationLocation = [0, 0]
/**
* @param {?GraphPin} source
* @param {?GraphPin} destination
* @param {?PinElement} source
* @param {?PinElement} destination
*/
constructor(source, destination) {
super({}, new LinkTemplate());
@@ -1730,25 +1730,25 @@ class GraphLink extends GraphElement {
/**
*
* @returns {GraphPin}
* @returns {PinElement}
*/
getSourcePin() {
return this.#source
}
/**
* @param {GraphPin} graphPin
* @param {PinElement} pin
*/
setSourcePin(graphPin) {
setSourcePin(pin) {
if (this.#source) {
const nodeElement = this.#source.getGraphNode();
const nodeElement = this.#source.getNodeElement();
nodeElement.removeEventListener(Configuration.nodeDeleteEventName, this.#nodeDeleteHandler);
nodeElement.removeEventListener(Configuration.nodeDragLocalEventName, this.#nodeDragSourceHandler);
}
this.#source = graphPin;
this.#source = pin;
if (this.#source) {
const nodeElement = this.#source.getGraphNode();
this.originatesFromInput = graphPin.isInput();
const nodeElement = this.#source.getNodeElement();
this.originatesFromInput = pin.isInput();
nodeElement.addEventListener(Configuration.nodeDeleteEventName, this.#nodeDeleteHandler);
nodeElement.addEventListener(Configuration.nodeDragLocalEventName, this.#nodeDragSourceHandler);
this.setSourceLocation();
@@ -1757,7 +1757,7 @@ class GraphLink extends GraphElement {
/**
*
* @returns {GraphPin}
* @returns {PinElement}
*/
getDestinationPin() {
return this.#destination
@@ -1765,17 +1765,17 @@ class GraphLink extends GraphElement {
/**
*
* @param {GraphPin} graphPin
* @param {PinElement} pin
*/
setDestinationPin(graphPin) {
setDestinationPin(pin) {
if (this.#destination) {
const nodeElement = this.#destination.getGraphNode();
const nodeElement = this.#destination.getNodeElement();
nodeElement.removeEventListener(Configuration.nodeDeleteEventName, this.#nodeDeleteHandler);
nodeElement.removeEventListener(Configuration.nodeDragLocalEventName, this.#nodeDragDestinatonHandler);
}
this.#destination = graphPin;
this.#destination = pin;
if (this.#destination) {
const nodeElement = this.#destination.getGraphNode();
const nodeElement = this.#destination.getNodeElement();
nodeElement.addEventListener(Configuration.nodeDeleteEventName, this.#nodeDeleteHandler);
nodeElement.addEventListener(Configuration.nodeDragLocalEventName, this.#nodeDragDestinatonHandler);
this.setDestinationLocation();
@@ -1784,23 +1784,23 @@ class GraphLink extends GraphElement {
/**
*
* @param {GraphLinkMessage} linkMessage
* @param {LinkMessageElement} linkMessage
*/
setLinkMessage(linkMessage) {
this.template.applyLinkMessage(this, linkMessage);
}
}
customElements.define(GraphLink.tagName, GraphLink);
customElements.define(LinkElement.tagName, LinkElement);
/**
* @typedef {import("../graph/GraphPin").default} GraphPin
* @typedef {import("../element/PinElement").default} PinElement
*/
class PinTemplate extends Template {
/**
* Computes the html content of the pin.
* @param {GraphPin} pin Pin entity
* @param {PinElement} pin html element
* @returns The result html
*/
render(pin) {
@@ -1819,7 +1819,7 @@ class PinTemplate extends Template {
/**
* Applies the style to the element.
* @param {GraphPin} pin Element of the graph
* @param {PinElement} pin element of the graph
*/
apply(pin) {
super.apply(pin);
@@ -1830,7 +1830,7 @@ class PinTemplate extends Template {
/**
*
* @param {GraphPin} pin
* @param {PinElement} pin
* @returns
*/
getLinkLocation(pin) {
@@ -1842,13 +1842,13 @@ class PinTemplate extends Template {
}
/**
* @typedef {import("../graph/GraphLinkMessage").default} GraphLinkMessage
* @typedef {import("../element/LinkMessageElement").default} LinkMessageElement
*/
class LinkMessageTemplate extends Template {
/**
* Computes the html content of the target element.
* @param {GraphLinkMessage} linkMessage attached to link destination
* @param {LinkMessageElement} linkMessage attached to link destination
* @returns The result html
*/
render(linkMessage) {
@@ -1860,11 +1860,11 @@ class LinkMessageTemplate extends Template {
/**
* Applies the style to the element.
* @param {GraphLinkMessage} linkMessage element
* @param {LinkMessageElement} linkMessage element
*/
apply(linkMessage) {
super.apply(linkMessage);
linkMessage.linkElement = linkMessage.closest(GraphLink.tagName);
linkMessage.linkElement = linkMessage.closest(LinkElement.tagName);
linkMessage.querySelector(".ueb-link-message").innerText = linkMessage.message(
linkMessage.linkElement.getSourcePin(),
linkMessage.linkElement.getDestinationPin()
@@ -1874,39 +1874,39 @@ class LinkMessageTemplate extends Template {
}
/**
* @typedef {import("./GraphPin").default} GraphPin
* @typedef {import("./GraphLink").default} GraphLink
* @typedef {(sourcePin: GraphPin, sourcePin: GraphPin) => String} LinkRetrieval
* @typedef {import("./PinElement").default} PinElement
* @typedef {import("./LinkElement").default} LinkElement
* @typedef {(sourcePin: PinElement, sourcePin: PinElement) => String} LinkRetrieval
*/
class GraphLinkMessage extends GraphElement {
class LinkMessageElement extends IElement {
static tagName = "ueb-link-message"
static CONVERT_TYPE = _ => new GraphLinkMessage(
static convertType = _ => new LinkMessageElement(
"ueb-icon-conver-type",
/** @type {LinkRetrieval} */
(s, d) => `Convert ${s.getType()} to ${d.getType()}.`
)
static DIRECTIONS_INCOMPATIBLE = _ => new GraphLinkMessage(
static directionsIncompatible = _ => new LinkMessageElement(
"ueb-icon-directions-incompatible",
/** @type {LinkRetrieval} */
(s, d) => "Directions are not compatbile."
)
static PLACE_NODE = _ => new GraphLinkMessage(
static placeNode = _ => new LinkMessageElement(
"ueb-icon-place-node",
/** @type {LinkRetrieval} */
(s, d) => "Place a new node."
)
static REPLACE_LiNK = _ => new GraphLinkMessage(
static replaceLink = _ => new LinkMessageElement(
"ueb-icon-replace-link",
/** @type {LinkRetrieval} */
(s, d) => "Replace existing input connections."
)
static SAME_NODE = _ => new GraphLinkMessage(
static sameNode = _ => new LinkMessageElement(
"ueb-icon-same-node",
/** @type {LinkRetrieval} */
(s, d) => "Both are on the same node."
)
static TYPES_INCOMPATIBLE = _ => new GraphLinkMessage(
static typesIncompatible = _ => new LinkMessageElement(
"ueb-icon-types-incompatible",
/** @type {LinkRetrieval} */
(s, d) => `${s.getType()} is not compatible with ${d.getType()}.`
@@ -1916,7 +1916,7 @@ class GraphLinkMessage extends GraphElement {
icon
/** @type {String} */
message
/** @type {GraphLink} */
/** @type {LinkElement} */
linkElement
constructor(icon, message) {
@@ -1927,7 +1927,7 @@ class GraphLinkMessage extends GraphElement {
}
customElements.define(GraphLinkMessage.tagName, GraphLinkMessage);
customElements.define(LinkMessageElement.tagName, LinkMessageElement);
class Pointing extends Context {
@@ -2086,10 +2086,10 @@ class MouseClickDrag extends Pointing {
}
}
/** @typedef {import("../../graph/GraphPin").default} GraphPin */
/** @typedef {import("../../element/PinElement").default} PinElement */
class MouseCreateLink extends MouseClickDrag {
/** @type {NodeListOf<GraphPin>} */
/** @type {NodeListOf<PinElement>} */
#listenedPins
/** @type {(e: MouseEvent) => void} */
@@ -2100,9 +2100,9 @@ class MouseCreateLink extends MouseClickDrag {
constructor(target, blueprint, options) {
super(target, blueprint, options);
/** @type {import("../../graph/GraphPin").default} */
/** @type {import("../../element/PinElement").PinElement} */
this.target;
/** @type {import("../../graph/GraphLink").default} */
/** @type {import("../../element/LinkElement").LinkElement} */
this.link;
/** @type {import("../../entity/PinEntity").default} */
this.enteredPin;
@@ -2121,8 +2121,8 @@ class MouseCreateLink extends MouseClickDrag {
}
startDrag() {
this.link = new GraphLink(this.target, null);
this.link.setLinkMessage(GraphLinkMessage.PLACE_NODE());
this.link = new LinkElement(this.target, null);
this.link.setLinkMessage(LinkMessageElement.placeNode());
this.blueprint.nodesContainerElement.insertBefore(this.link, this.blueprint.selectorElement.nextElementSibling);
this.#listenedPins = this.blueprint.querySelectorAll(this.target.constructor.tagName);
this.#listenedPins.forEach(pin => {
@@ -2156,7 +2156,7 @@ class MouseCreateLink extends MouseClickDrag {
}
}
class GraphPin extends GraphElement {
class PinElement extends IElement {
static tagName = "ueb-pin"
@@ -2219,21 +2219,21 @@ class GraphPin extends GraphElement {
return this.template.getLinkLocation(this)
}
getGraphNode() {
getNodeElement() {
return this.closest("ueb-node")
}
}
customElements.define(GraphPin.tagName, GraphPin);
customElements.define(PinElement.tagName, PinElement);
/**
* @typedef {import("../graph/SelectableDraggable").default} SelectableDraggable
* @typedef {import("../element/ISelectableDraggableElement").default} ISelectableDraggableElement
*/
class SelectableDraggableTemplate extends Template {
/**
* Returns the html elements rendered from this template.
* @param {SelectableDraggable} element Element of the graph
* @param {ISelectableDraggableElement} element Element of the graph
*/
applyLocation(element) {
element.style.setProperty("--ueb-position-x", sanitizeText(element.location[0]));
@@ -2242,7 +2242,7 @@ class SelectableDraggableTemplate extends Template {
/**
* Returns the html elements rendered from this template.
* @param {SelectableDraggable} element Element of the graph
* @param {ISelectableDraggableElement} element Element of the graph
*/
applySelected(element) {
if (element.selected) {
@@ -2254,13 +2254,13 @@ class SelectableDraggableTemplate extends Template {
}
/**
* @typedef {import("../graph/GraphNode").default} GraphNode
* @typedef {import("../element/NodeElement").default} NodeElement
*/
class NodeTemplate extends SelectableDraggableTemplate {
/**
* Computes the html content of the target element.
* @param {GraphNode} node Graph node element
* @param {NodeElement} node Graph node element
* @returns The result html
*/
render(node) {
@@ -2284,7 +2284,7 @@ class NodeTemplate extends SelectableDraggableTemplate {
/**
* Applies the style to the element.
* @param {GraphNode} node Element of the graph
* @param {NodeElement} node Element of the graph
*/
apply(node) {
super.apply(node);
@@ -2298,19 +2298,19 @@ class NodeTemplate extends SelectableDraggableTemplate {
/** @type {HTMLElement} */
let outputContainer = node.querySelector(".ueb-node-outputs");
let pins = node.getPinEntities();
pins.filter(v => v.isInput()).forEach(v => inputContainer.appendChild(new GraphPin(v)));
pins.filter(v => v.isOutput()).forEach(v => outputContainer.appendChild(new GraphPin(v)));
pins.filter(v => v.isInput()).forEach(v => inputContainer.appendChild(new PinElement(v)));
pins.filter(v => v.isOutput()).forEach(v => outputContainer.appendChild(new PinElement(v)));
}
}
/**
* @typedef {import("../../graph/SelectableDraggable").default} SelectableDraggable
* @typedef {import("../../element/ISelectableDraggableElement").ISelectableDraggableElement} ISelectableDraggableElement
*/
class MouseMoveNodes extends MouseClickDrag {
/**
*
* @param {SelectableDraggable} target
* @param {ISelectableDraggableElement} target
* @param {*} blueprint
* @param {*} options
*/
@@ -2318,7 +2318,7 @@ class MouseMoveNodes extends MouseClickDrag {
super(target, blueprint, options);
this.stepSize = parseInt(options?.stepSize ?? this.blueprint.gridSize);
this.mouseLocation = [0, 0];
/** @type {SelectableDraggable} */
/** @type {ISelectableDraggableElement} */
this.target;
}
@@ -2351,14 +2351,16 @@ class MouseMoveNodes extends MouseClickDrag {
}
}
class SelectableDraggable extends GraphElement {
/** @typedef {import("../template/SelectableDraggableTemplate").default} SelectableDraggableTemplate */
class ISelectableDraggableElement extends IElement {
constructor(...args) {
super(...args);
this.dragObject = null;
this.location = [0, 0];
this.selected = false;
/** @type {import("../template/SelectableDraggableTemplate").default} */
/** @type {SelectableDraggableTemplate} */
this.template;
let self = this;
@@ -2429,7 +2431,7 @@ class SelectableDraggable extends GraphElement {
}
}
class GraphNode extends SelectableDraggable {
class NodeElement extends ISelectableDraggableElement {
static tagName = "ueb-node"
@@ -2447,7 +2449,7 @@ class GraphNode extends SelectableDraggable {
static fromSerializedObject(str) {
let entity = SerializerFactory.getSerializer(ObjectEntity).read(str);
return new GraphNode(entity)
return new NodeElement(entity)
}
disconnectedCallback() {
@@ -2484,7 +2486,7 @@ class GraphNode extends SelectableDraggable {
}
}
customElements.define(GraphNode.tagName, GraphNode);
customElements.define(NodeElement.tagName, NodeElement);
let P = Parsimmon;
@@ -2708,7 +2710,7 @@ class Paste extends Context {
let left = 0;
let count = 0;
let nodes = this.serializer.readMultiple(value).map(entity => {
let node = new GraphNode(entity);
let node = new NodeElement(entity);
top += node.location[1];
left += node.location[0];
++count;
@@ -2850,14 +2852,14 @@ class Zoom extends MouseWheel {
}
}
class Blueprint extends GraphElement {
class Blueprint extends IElement {
static tagName = "ueb-blueprint"
/** @type {number} */
gridSize = Configuration.gridSize
/** @type {GraphNode[]}" */
/** @type {NodeElement[]}" */
nodes = []
/** @type {GraphLink[]}" */
/** @type {LinkElement[]}" */
links = []
expandGridSize = Configuration.expandGridSize
/** @type {number[]} */
@@ -2872,7 +2874,7 @@ class Blueprint extends GraphElement {
viewportElement = null
/** @type {HTMLElement} */
overlayElement = null
/** @type {GraphSelector} */
/** @type {SelectorElement} */
selectorElement = null
/** @type {HTMLElement} */
nodesContainerElement = null
@@ -2881,7 +2883,7 @@ class Blueprint extends GraphElement {
/** @type {HTMLElement} */
headerElement = null
focused = false
/** @type {(node: GraphNode) => BoundariesInfo} */
/** @type {(node: NodeElement) => BoundariesInfo} */
nodeBoundariesSupplier = node => {
let rect = node.getBoundingClientRect();
let gridRect = this.nodesContainerElement.getBoundingClientRect();
@@ -2894,7 +2896,7 @@ class Blueprint extends GraphElement {
secondarySup: (rect.bottom - gridRect.bottom) * scaleCorrection
}
}
/** @type {(node: GraphNode, selected: bool) => void}} */
/** @type {(node: NodeElement, selected: bool) => void}} */
nodeSelectToggleFunction = (node, selected) => {
node.setSelected(selected);
}
@@ -3122,7 +3124,7 @@ class Blueprint extends GraphElement {
/**
* Returns the list of nodes in this blueprint. It can filter the list providing just the selected ones.
* @returns {GraphNode[]} Nodes
* @returns {NodeElement[]} Nodes
*/
getNodes(selected = false) {
if (selected) {
@@ -3136,7 +3138,7 @@ class Blueprint extends GraphElement {
/**
* Returns the list of links in this blueprint.
* @returns {GraphLink[]} Nodes
* @returns {LinkElement[]} Nodes
*/
getLinks() {
return this.links
@@ -3158,7 +3160,7 @@ class Blueprint extends GraphElement {
/**
*
* @param {...GraphElement} graphElements
* @param {...IElement} graphElements
*/
addGraphElement(...graphElements) {
if (this.nodesContainerElement) {
@@ -3166,14 +3168,14 @@ class Blueprint extends GraphElement {
if (element.closest(Blueprint.tagName) != this) {
this.nodesContainerElement.appendChild(element);
}
this.nodes = [...this.querySelectorAll(GraphNode.tagName)];
this.links = [...this.querySelectorAll(GraphLink.tagName)];
this.nodes = [...this.querySelectorAll(NodeElement.tagName)];
this.links = [...this.querySelectorAll(LinkElement.tagName)];
});
} else {
graphElements.forEach(element => {
if (element instanceof GraphNode) {
if (element instanceof NodeElement) {
this.nodes.push(element);
} else if (element instanceof GraphLink) {
} else if (element instanceof LinkElement) {
this.links.push(element);
}
});
@@ -3182,7 +3184,7 @@ class Blueprint extends GraphElement {
/**
*
* @param {...GraphElement} graphElements
* @param {...IElement} graphElements
*/
removeGraphElement(...graphElements) {
let removed = false;
@@ -3193,8 +3195,8 @@ class Blueprint extends GraphElement {
}
});
if (removed) {
this.nodes = [...this.querySelectorAll(GraphNode.tagName)];
this.links = [...this.querySelectorAll(GraphLink.tagName)];
this.nodes = [...this.querySelectorAll(NodeElement.tagName)];
this.links = [...this.querySelectorAll(LinkElement.tagName)];
}
}
@@ -3301,4 +3303,4 @@ function initializeSerializerFactory() {
initializeSerializerFactory();
export { Blueprint, Configuration, GraphLink, GraphNode };
export { Blueprint, Configuration, LinkElement, NodeElement };

View File

@@ -14,9 +14,9 @@
<body>
<div>Hello</div>
<script type="module">
import { Blueprint, GraphNode, Configuration } from "./dist/ueblueprint.js"
import { Blueprint, NodeElement, Configuration } from "./dist/ueblueprint.js"
Configuration.deleteNodesKeyboardKey = "Delete"
let node1 = GraphNode.fromSerializedObject(`Begin Object Class=/Script/BlueprintGraph.K2Node_CommutativeAssociativeBinaryOperator Name="K2Node_CommutativeAssociativeBinaryOperator_1"
let node1 = NodeElement.fromSerializedObject(`Begin Object Class=/Script/BlueprintGraph.K2Node_CommutativeAssociativeBinaryOperator Name="K2Node_CommutativeAssociativeBinaryOperator_1"
bIsPureFunc=True
FunctionReference=(MemberParent=Class'"/Script/Engine.KismetStringLibrary"',MemberName="Concat_StrStr")
NodePosX=30

View File

@@ -1,10 +1,10 @@
import BlueprintTemplate from "./template/BlueprintTemplate"
import Configuration from "./Configuration"
import Copy from "./input/common/Copy"
import GraphElement from "./graph/GraphElement"
import GraphLink from "./graph/GraphLink"
import GraphNode from "./graph/GraphNode"
import GraphSelector from "./graph/GraphSelector"
import IElement from "./element/IElement"
import LinkElement from "./element/LinkElement"
import NodeElement from "./element/NodeElement"
import SelectorElement from "./element/SelectorElement"
import KeyboardCanc from "./input/keybaord/KeyboardCanc"
import KeyboardSelectAll from "./input/keybaord/KeyboardSelectAll"
import MouseScrollGraph from "./input/mouse/MouseScrollGraph"
@@ -15,14 +15,14 @@ import Unfocus from "./input/mouse/Unfocus"
import Utility from "./Utility"
import Zoom from "./input/mouse/Zoom"
export default class Blueprint extends GraphElement {
export default class Blueprint extends IElement {
static tagName = "ueb-blueprint"
/** @type {number} */
gridSize = Configuration.gridSize
/** @type {GraphNode[]}" */
/** @type {NodeElement[]}" */
nodes = []
/** @type {GraphLink[]}" */
/** @type {LinkElement[]}" */
links = []
expandGridSize = Configuration.expandGridSize
/** @type {number[]} */
@@ -37,7 +37,7 @@ export default class Blueprint extends GraphElement {
viewportElement = null
/** @type {HTMLElement} */
overlayElement = null
/** @type {GraphSelector} */
/** @type {SelectorElement} */
selectorElement = null
/** @type {HTMLElement} */
nodesContainerElement = null
@@ -46,7 +46,7 @@ export default class Blueprint extends GraphElement {
/** @type {HTMLElement} */
headerElement = null
focused = false
/** @type {(node: GraphNode) => BoundariesInfo} */
/** @type {(node: NodeElement) => BoundariesInfo} */
nodeBoundariesSupplier = node => {
let rect = node.getBoundingClientRect()
let gridRect = this.nodesContainerElement.getBoundingClientRect()
@@ -59,7 +59,7 @@ export default class Blueprint extends GraphElement {
secondarySup: (rect.bottom - gridRect.bottom) * scaleCorrection
}
}
/** @type {(node: GraphNode, selected: bool) => void}} */
/** @type {(node: NodeElement, selected: bool) => void}} */
nodeSelectToggleFunction = (node, selected) => {
node.setSelected(selected)
}
@@ -287,7 +287,7 @@ export default class Blueprint extends GraphElement {
/**
* Returns the list of nodes in this blueprint. It can filter the list providing just the selected ones.
* @returns {GraphNode[]} Nodes
* @returns {NodeElement[]} Nodes
*/
getNodes(selected = false) {
if (selected) {
@@ -301,7 +301,7 @@ export default class Blueprint extends GraphElement {
/**
* Returns the list of links in this blueprint.
* @returns {GraphLink[]} Nodes
* @returns {LinkElement[]} Nodes
*/
getLinks() {
return this.links
@@ -323,7 +323,7 @@ export default class Blueprint extends GraphElement {
/**
*
* @param {...GraphElement} graphElements
* @param {...IElement} graphElements
*/
addGraphElement(...graphElements) {
if (this.nodesContainerElement) {
@@ -331,14 +331,14 @@ export default class Blueprint extends GraphElement {
if (element.closest(Blueprint.tagName) != this) {
this.nodesContainerElement.appendChild(element)
}
this.nodes = [...this.querySelectorAll(GraphNode.tagName)]
this.links = [...this.querySelectorAll(GraphLink.tagName)]
this.nodes = [...this.querySelectorAll(NodeElement.tagName)]
this.links = [...this.querySelectorAll(LinkElement.tagName)]
})
} else {
graphElements.forEach(element => {
if (element instanceof GraphNode) {
if (element instanceof NodeElement) {
this.nodes.push(element)
} else if (element instanceof GraphLink) {
} else if (element instanceof LinkElement) {
this.links.push(element)
}
})
@@ -347,7 +347,7 @@ export default class Blueprint extends GraphElement {
/**
*
* @param {...GraphElement} graphElements
* @param {...IElement} graphElements
*/
removeGraphElement(...graphElements) {
let removed = false
@@ -358,8 +358,8 @@ export default class Blueprint extends GraphElement {
}
})
if (removed) {
this.nodes = [...this.querySelectorAll(GraphNode.tagName)]
this.links = [...this.querySelectorAll(GraphLink.tagName)]
this.nodes = [...this.querySelectorAll(NodeElement.tagName)]
this.links = [...this.querySelectorAll(LinkElement.tagName)]
}
}

88
js/graph/GraphElement.js → js/element/IElement.js Executable file → Normal file
View File

@@ -1,44 +1,44 @@
/**
* @typedef {import("../Blueprint").default} Blueprint
* @typedef {import("../entity/Entity").default} Entity
* @typedef {import("../input/Context").default} Context
* @typedef {import("../template/Template").default} Template
*/
export default class GraphElement extends HTMLElement {
/**
*
* @param {Entity} entity The entity containing blueprint related data for this graph element
* @param {Template} template The template to render this node
*/
constructor(entity, template) {
super()
/** @type {Blueprint} */
this.blueprint = null
/** @type {Entity} */
this.entity = entity
/** @type {Template} */
this.template = template
/** @type {Context[]} */
this.inputObjects = []
}
getTemplate() {
return this.template
}
connectedCallback() {
this.blueprint = this.closest("ueb-blueprint")
this.template.apply(this)
this.inputObjects = this.createInputObjects()
}
disconnectedCallback() {
this.inputObjects.forEach(v => v.unlistenDOMElement())
}
createInputObjects() {
return []
}
}
/**
* @typedef {import("../Blueprint").default} Blueprint
* @typedef {import("../entity/IEntity").IEntity} IEntity
* @typedef {import("../input/Context").default} Context
* @typedef {import("../template/Template").default} Template
*/
export default class IElement extends HTMLElement {
/**
*
* @param {IEntity} entity The entity containing blueprint related data for this graph element
* @param {Template} template The template to render this node
*/
constructor(entity, template) {
super()
/** @type {Blueprint} */
this.blueprint = null
/** @type {IEntity} */
this.entity = entity
/** @type {Template} */
this.template = template
/** @type {Context[]} */
this.inputObjects = []
}
getTemplate() {
return this.template
}
connectedCallback() {
this.blueprint = this.closest("ueb-blueprint")
this.template.apply(this)
this.inputObjects = this.createInputObjects()
}
disconnectedCallback() {
this.inputObjects.forEach(v => v.unlistenDOMElement())
}
createInputObjects() {
return []
}
}

View File

@@ -1,81 +1,83 @@
import Configuration from "../Configuration"
import MouseMoveNodes from "../input/mouse/MouseMoveNodes"
import GraphElement from "./GraphElement"
export default class SelectableDraggable extends GraphElement {
constructor(...args) {
super(...args)
this.dragObject = null
this.location = [0, 0]
this.selected = false
/** @type {import("../template/SelectableDraggableTemplate").default} */
this.template
let self = this
this.dragHandler = (e) => {
self.addLocation(e.detail.value)
}
}
createInputObjects() {
return [
new MouseMoveNodes(this, this.blueprint, {
looseTarget: true
}),
]
}
setLocation(value = [0, 0]) {
const d = [value[0] - this.location[0], value[1] - this.location[1]]
const dragLocalEvent = new CustomEvent(Configuration.nodeDragLocalEventName, {
detail: {
value: d
},
bubbles: false,
cancelable: true
})
this.location = value
this.template.applyLocation(this)
this.dispatchEvent(dragLocalEvent)
}
addLocation(value) {
this.setLocation([this.location[0] + value[0], this.location[1] + value[1]])
}
setSelected(value = true) {
if (this.selected == value) {
return
}
this.selected = value
if (this.selected) {
this.blueprint.addEventListener(Configuration.nodeDragEventName, this.dragHandler)
} else {
this.blueprint.removeEventListener(Configuration.nodeDragEventName, this.dragHandler)
}
this.template.applySelected(this)
}
dispatchDragEvent(value) {
if (!this.selected) {
this.blueprint.unselectAll()
this.setSelected(true)
}
const dragEvent = new CustomEvent(Configuration.nodeDragEventName, {
detail: {
value: value
},
bubbles: true,
cancelable: true
})
this.dispatchEvent(dragEvent)
}
snapToGrid() {
let snappedLocation = this.blueprint.snapToGrid(this.location)
if (this.location[0] != snappedLocation[0] || this.location[1] != snappedLocation[1]) {
this.setLocation(snappedLocation)
}
}
}
import Configuration from "../Configuration"
import MouseMoveNodes from "../input/mouse/MouseMoveNodes"
import IElement from "./IElement"
/** @typedef {import("../template/SelectableDraggableTemplate").default} SelectableDraggableTemplate */
export default class ISelectableDraggableElement extends IElement {
constructor(...args) {
super(...args)
this.dragObject = null
this.location = [0, 0]
this.selected = false
/** @type {SelectableDraggableTemplate} */
this.template
let self = this
this.dragHandler = (e) => {
self.addLocation(e.detail.value)
}
}
createInputObjects() {
return [
new MouseMoveNodes(this, this.blueprint, {
looseTarget: true
}),
]
}
setLocation(value = [0, 0]) {
const d = [value[0] - this.location[0], value[1] - this.location[1]]
const dragLocalEvent = new CustomEvent(Configuration.nodeDragLocalEventName, {
detail: {
value: d
},
bubbles: false,
cancelable: true
})
this.location = value
this.template.applyLocation(this)
this.dispatchEvent(dragLocalEvent)
}
addLocation(value) {
this.setLocation([this.location[0] + value[0], this.location[1] + value[1]])
}
setSelected(value = true) {
if (this.selected == value) {
return
}
this.selected = value
if (this.selected) {
this.blueprint.addEventListener(Configuration.nodeDragEventName, this.dragHandler)
} else {
this.blueprint.removeEventListener(Configuration.nodeDragEventName, this.dragHandler)
}
this.template.applySelected(this)
}
dispatchDragEvent(value) {
if (!this.selected) {
this.blueprint.unselectAll()
this.setSelected(true)
}
const dragEvent = new CustomEvent(Configuration.nodeDragEventName, {
detail: {
value: value
},
bubbles: true,
cancelable: true
})
this.dispatchEvent(dragEvent)
}
snapToGrid() {
let snappedLocation = this.blueprint.snapToGrid(this.location)
if (this.location[0] != snappedLocation[0] || this.location[1] != snappedLocation[1]) {
this.setLocation(snappedLocation)
}
}
}

350
js/graph/GraphLink.js → js/element/LinkElement.js Executable file → Normal file
View File

@@ -1,175 +1,175 @@
import GraphElement from "./GraphElement"
import LinkTemplate from "../template/LinkTemplate"
import Configuration from "../Configuration"
/**
* @typedef {import("./GraphPin").default} GraphPin
* @typedef {import("./GraphLinkMessage").default} GraphLinkMessage
*/
export default class GraphLink extends GraphElement {
static tagName = "ueb-link"
/** @type {GraphPin} */
#source
/** @type {GraphPin} */
#destination
#nodeDeleteHandler
#nodeDragSourceHandler
#nodeDragDestinatonHandler
sourceLocation = [0, 0]
/** @type {SVGPathElement} */
pathElement
/** @type {GraphLinkMessage} */
linkMessageElement
originatesFromInput = false
destinationLocation = [0, 0]
/**
* @param {?GraphPin} source
* @param {?GraphPin} destination
*/
constructor(source, destination) {
super({}, new LinkTemplate())
/** @type {import("../template/LinkTemplate").default} */
this.template
const self = this
this.#nodeDeleteHandler = _ => self.remove()
this.#nodeDragSourceHandler = e => self.addSourceLocation(e.detail.value)
this.#nodeDragDestinatonHandler = e => self.addDestinationLocation(e.detail.value)
if (source) {
this.setSourcePin(source)
}
if (destination) {
this.setDestinationPin(destination)
}
}
/**
*
* @returns {Number[]}
*/
getSourceLocation() {
return this.sourceLocation
}
/**
*
* @param {Number[]} offset
*/
addSourceLocation(offset) {
const location = [
this.sourceLocation[0] + offset[0],
this.sourceLocation[1] + offset[1]
]
this.sourceLocation = location
this.template.applyFullLocation(this)
}
/**
*
* @param {Number[]} location
*/
setSourceLocation(location) {
if (location == null) {
location = this.#source.template.getLinkLocation(this.#source)
}
this.sourceLocation = location
this.template.applySourceLocation(this)
}
/**
*
* @returns {Number[]}
*/
getDestinationLocation() {
return this.destinationLocation
}
/**
*
* @param {Number[]} offset
*/
addDestinationLocation(offset) {
const location = [
this.destinationLocation[0] + offset[0],
this.destinationLocation[1] + offset[1]
]
this.setDestinationLocation(location)
}
/**
*
* @param {Number[]} location
*/
setDestinationLocation(location) {
if (location == null) {
location = this.#destination.template.getLinkLocation(this.#destination)
}
this.destinationLocation = location
this.template.applyFullLocation(this)
}
/**
*
* @returns {GraphPin}
*/
getSourcePin() {
return this.#source
}
/**
* @param {GraphPin} graphPin
*/
setSourcePin(graphPin) {
if (this.#source) {
const nodeElement = this.#source.getGraphNode()
nodeElement.removeEventListener(Configuration.nodeDeleteEventName, this.#nodeDeleteHandler)
nodeElement.removeEventListener(Configuration.nodeDragLocalEventName, this.#nodeDragSourceHandler)
}
this.#source = graphPin
if (this.#source) {
const nodeElement = this.#source.getGraphNode()
this.originatesFromInput = graphPin.isInput()
nodeElement.addEventListener(Configuration.nodeDeleteEventName, this.#nodeDeleteHandler)
nodeElement.addEventListener(Configuration.nodeDragLocalEventName, this.#nodeDragSourceHandler)
this.setSourceLocation()
}
}
/**
*
* @returns {GraphPin}
*/
getDestinationPin() {
return this.#destination
}
/**
*
* @param {GraphPin} graphPin
*/
setDestinationPin(graphPin) {
if (this.#destination) {
const nodeElement = this.#destination.getGraphNode()
nodeElement.removeEventListener(Configuration.nodeDeleteEventName, this.#nodeDeleteHandler)
nodeElement.removeEventListener(Configuration.nodeDragLocalEventName, this.#nodeDragDestinatonHandler)
}
this.#destination = graphPin
if (this.#destination) {
const nodeElement = this.#destination.getGraphNode()
nodeElement.addEventListener(Configuration.nodeDeleteEventName, this.#nodeDeleteHandler)
nodeElement.addEventListener(Configuration.nodeDragLocalEventName, this.#nodeDragDestinatonHandler)
this.setDestinationLocation()
}
}
/**
*
* @param {GraphLinkMessage} linkMessage
*/
setLinkMessage(linkMessage) {
this.template.applyLinkMessage(this, linkMessage)
}
}
customElements.define(GraphLink.tagName, GraphLink)
import IElement from "./IElement"
import LinkTemplate from "../template/LinkTemplate"
import Configuration from "../Configuration"
/**
* @typedef {import("./PinElement").default} PinElement
* @typedef {import("./LinkMessageElement").default} LinkMessageElement
*/
export default class LinkElement extends IElement {
static tagName = "ueb-link"
/** @type {PinElement} */
#source
/** @type {PinElement} */
#destination
#nodeDeleteHandler
#nodeDragSourceHandler
#nodeDragDestinatonHandler
sourceLocation = [0, 0]
/** @type {SVGPathElement} */
pathElement
/** @type {LinkMessageElement} */
linkMessageElement
originatesFromInput = false
destinationLocation = [0, 0]
/**
* @param {?PinElement} source
* @param {?PinElement} destination
*/
constructor(source, destination) {
super({}, new LinkTemplate())
/** @type {import("../template/LinkTemplate").default} */
this.template
const self = this
this.#nodeDeleteHandler = _ => self.remove()
this.#nodeDragSourceHandler = e => self.addSourceLocation(e.detail.value)
this.#nodeDragDestinatonHandler = e => self.addDestinationLocation(e.detail.value)
if (source) {
this.setSourcePin(source)
}
if (destination) {
this.setDestinationPin(destination)
}
}
/**
*
* @returns {Number[]}
*/
getSourceLocation() {
return this.sourceLocation
}
/**
*
* @param {Number[]} offset
*/
addSourceLocation(offset) {
const location = [
this.sourceLocation[0] + offset[0],
this.sourceLocation[1] + offset[1]
]
this.sourceLocation = location
this.template.applyFullLocation(this)
}
/**
*
* @param {Number[]} location
*/
setSourceLocation(location) {
if (location == null) {
location = this.#source.template.getLinkLocation(this.#source)
}
this.sourceLocation = location
this.template.applySourceLocation(this)
}
/**
*
* @returns {Number[]}
*/
getDestinationLocation() {
return this.destinationLocation
}
/**
*
* @param {Number[]} offset
*/
addDestinationLocation(offset) {
const location = [
this.destinationLocation[0] + offset[0],
this.destinationLocation[1] + offset[1]
]
this.setDestinationLocation(location)
}
/**
*
* @param {Number[]} location
*/
setDestinationLocation(location) {
if (location == null) {
location = this.#destination.template.getLinkLocation(this.#destination)
}
this.destinationLocation = location
this.template.applyFullLocation(this)
}
/**
*
* @returns {PinElement}
*/
getSourcePin() {
return this.#source
}
/**
* @param {PinElement} pin
*/
setSourcePin(pin) {
if (this.#source) {
const nodeElement = this.#source.getNodeElement()
nodeElement.removeEventListener(Configuration.nodeDeleteEventName, this.#nodeDeleteHandler)
nodeElement.removeEventListener(Configuration.nodeDragLocalEventName, this.#nodeDragSourceHandler)
}
this.#source = pin
if (this.#source) {
const nodeElement = this.#source.getNodeElement()
this.originatesFromInput = pin.isInput()
nodeElement.addEventListener(Configuration.nodeDeleteEventName, this.#nodeDeleteHandler)
nodeElement.addEventListener(Configuration.nodeDragLocalEventName, this.#nodeDragSourceHandler)
this.setSourceLocation()
}
}
/**
*
* @returns {PinElement}
*/
getDestinationPin() {
return this.#destination
}
/**
*
* @param {PinElement} pin
*/
setDestinationPin(pin) {
if (this.#destination) {
const nodeElement = this.#destination.getNodeElement()
nodeElement.removeEventListener(Configuration.nodeDeleteEventName, this.#nodeDeleteHandler)
nodeElement.removeEventListener(Configuration.nodeDragLocalEventName, this.#nodeDragDestinatonHandler)
}
this.#destination = pin
if (this.#destination) {
const nodeElement = this.#destination.getNodeElement()
nodeElement.addEventListener(Configuration.nodeDeleteEventName, this.#nodeDeleteHandler)
nodeElement.addEventListener(Configuration.nodeDragLocalEventName, this.#nodeDragDestinatonHandler)
this.setDestinationLocation()
}
}
/**
*
* @param {LinkMessageElement} linkMessage
*/
setLinkMessage(linkMessage) {
this.template.applyLinkMessage(this, linkMessage)
}
}
customElements.define(LinkElement.tagName, LinkElement)

View File

@@ -1,40 +1,40 @@
import LinkMessageTemplate from "../template/LinkMessageTemplate";
import GraphElement from "./GraphElement";
import IElement from "./IElement"
import LinkMessageTemplate from "../template/LinkMessageTemplate"
/**
* @typedef {import("./GraphPin").default} GraphPin
* @typedef {import("./GraphLink").default} GraphLink
* @typedef {(sourcePin: GraphPin, sourcePin: GraphPin) => String} LinkRetrieval
* @typedef {import("./PinElement").default} PinElement
* @typedef {import("./LinkElement").default} LinkElement
* @typedef {(sourcePin: PinElement, sourcePin: PinElement) => String} LinkRetrieval
*/
export default class GraphLinkMessage extends GraphElement {
export default class LinkMessageElement extends IElement {
static tagName = "ueb-link-message"
static CONVERT_TYPE = _ => new GraphLinkMessage(
static convertType = _ => new LinkMessageElement(
"ueb-icon-conver-type",
/** @type {LinkRetrieval} */
(s, d) => `Convert ${s.getType()} to ${d.getType()}.`
)
static DIRECTIONS_INCOMPATIBLE = _ => new GraphLinkMessage(
static directionsIncompatible = _ => new LinkMessageElement(
"ueb-icon-directions-incompatible",
/** @type {LinkRetrieval} */
(s, d) => "Directions are not compatbile."
)
static PLACE_NODE = _ => new GraphLinkMessage(
static placeNode = _ => new LinkMessageElement(
"ueb-icon-place-node",
/** @type {LinkRetrieval} */
(s, d) => "Place a new node."
)
static REPLACE_LiNK = _ => new GraphLinkMessage(
static replaceLink = _ => new LinkMessageElement(
"ueb-icon-replace-link",
/** @type {LinkRetrieval} */
(s, d) => "Replace existing input connections."
)
static SAME_NODE = _ => new GraphLinkMessage(
static sameNode = _ => new LinkMessageElement(
"ueb-icon-same-node",
/** @type {LinkRetrieval} */
(s, d) => "Both are on the same node."
)
static TYPES_INCOMPATIBLE = _ => new GraphLinkMessage(
static typesIncompatible = _ => new LinkMessageElement(
"ueb-icon-types-incompatible",
/** @type {LinkRetrieval} */
(s, d) => `${s.getType()} is not compatible with ${d.getType()}.`
@@ -44,7 +44,7 @@ export default class GraphLinkMessage extends GraphElement {
icon
/** @type {String} */
message
/** @type {GraphLink} */
/** @type {LinkElement} */
linkElement
constructor(icon, message) {
@@ -55,4 +55,4 @@ export default class GraphLinkMessage extends GraphElement {
}
customElements.define(GraphLinkMessage.tagName, GraphLinkMessage)
customElements.define(LinkMessageElement.tagName, LinkMessageElement)

126
js/graph/GraphNode.js → js/element/NodeElement.js Executable file → Normal file
View File

@@ -1,63 +1,63 @@
import NodeTemplate from "../template/NodeTemplate"
import ObjectEntity from "../entity/ObjectEntity"
import PinEntity from "../entity/PinEntity"
import SelectableDraggable from "./SelectableDraggable"
import SerializerFactory from "../serialization/SerializerFactory"
import Configuration from "../Configuration"
export default class GraphNode extends SelectableDraggable {
static tagName = "ueb-node"
/**
*
* @param {ObjectEntity} entity
*/
constructor(entity) {
super(entity, new NodeTemplate())
/** @type {ObjectEntity} */
this.entity
this.dragLinkObjects = []
super.setLocation([this.entity.NodePosX, this.entity.NodePosY])
}
static fromSerializedObject(str) {
let entity = SerializerFactory.getSerializer(ObjectEntity).read(str)
return new GraphNode(entity)
}
disconnectedCallback() {
super.disconnectedCallback()
this.dispatchDeleteEvent()
}
/**
*
* @returns {PinEntity[]}
*/
getPinEntities() {
return this.entity.CustomProperties.filter(v => v instanceof PinEntity)
}
connectedCallback() {
const type = this.getAttribute("type")?.trim()
super.connectedCallback()
}
setLocation(value = [0, 0]) {
let nodeType = this.entity.NodePosX.constructor
this.entity.NodePosX = new nodeType(value[0])
this.entity.NodePosY = new nodeType(value[1])
super.setLocation(value)
}
dispatchDeleteEvent(value) {
let deleteEvent = new CustomEvent(Configuration.nodeDeleteEventName, {
bubbles: true,
cancelable: true,
})
this.dispatchEvent(deleteEvent)
}
}
customElements.define(GraphNode.tagName, GraphNode)
import NodeTemplate from "../template/NodeTemplate"
import ObjectEntity from "../entity/ObjectEntity"
import PinEntity from "../entity/PinEntity"
import ISelectableDraggableElement from "./ISelectableDraggableElement"
import SerializerFactory from "../serialization/SerializerFactory"
import Configuration from "../Configuration"
export default class NodeElement extends ISelectableDraggableElement {
static tagName = "ueb-node"
/**
*
* @param {ObjectEntity} entity
*/
constructor(entity) {
super(entity, new NodeTemplate())
/** @type {ObjectEntity} */
this.entity
this.dragLinkObjects = []
super.setLocation([this.entity.NodePosX, this.entity.NodePosY])
}
static fromSerializedObject(str) {
let entity = SerializerFactory.getSerializer(ObjectEntity).read(str)
return new NodeElement(entity)
}
disconnectedCallback() {
super.disconnectedCallback()
this.dispatchDeleteEvent()
}
/**
*
* @returns {PinEntity[]}
*/
getPinEntities() {
return this.entity.CustomProperties.filter(v => v instanceof PinEntity)
}
connectedCallback() {
const type = this.getAttribute("type")?.trim()
super.connectedCallback()
}
setLocation(value = [0, 0]) {
let nodeType = this.entity.NodePosX.constructor
this.entity.NodePosX = new nodeType(value[0])
this.entity.NodePosY = new nodeType(value[1])
super.setLocation(value)
}
dispatchDeleteEvent(value) {
let deleteEvent = new CustomEvent(Configuration.nodeDeleteEventName, {
bubbles: true,
cancelable: true,
})
this.dispatchEvent(deleteEvent)
}
}
customElements.define(NodeElement.tagName, NodeElement)

146
js/graph/GraphPin.js → js/element/PinElement.js Executable file → Normal file
View File

@@ -1,73 +1,73 @@
import GraphElement from "./GraphElement"
import PinTemplate from "../template/PinTemplate"
import MouseCreateLink from "../input/mouse/MouseCreateLink"
export default class GraphPin extends GraphElement {
static tagName = "ueb-pin"
constructor(entity) {
super(entity, new PinTemplate())
/** @type {import("../entity/PinEntity").default} */
this.entity
/** @type {PinTemplate} */
this.template
/** @type {HTMLElement} */
this.clickableElement = null
}
createInputObjects() {
return [
new MouseCreateLink(this.clickableElement, this.blueprint, {
moveEverywhere: true,
looseTarget: true
}),
]
}
/**
*
* @returns {String}
*/
getPinDisplayName() {
return this.entity.PinName
}
getAttributes() {
return PinEntity.attributes
}
isInput() {
return this.entity.isInput()
}
isOutput() {
return this.entity.isOutput()
}
isConnected() {
return this.entity.isConnected()
}
getType() {
return this.entity.getType()
}
getClickableElement() {
return this.clickableElement
}
/**
* Returns The exact location where the link originates from or arrives at.
* @returns {Number[]} The location array
*/
getLinkLocation() {
return this.template.getLinkLocation(this)
}
getGraphNode() {
return this.closest("ueb-node")
}
}
customElements.define(GraphPin.tagName, GraphPin)
import IElement from "./IElement"
import PinTemplate from "../template/PinTemplate"
import MouseCreateLink from "../input/mouse/MouseCreateLink"
export default class PinElement extends IElement {
static tagName = "ueb-pin"
constructor(entity) {
super(entity, new PinTemplate())
/** @type {import("../entity/PinEntity").default} */
this.entity
/** @type {PinTemplate} */
this.template
/** @type {HTMLElement} */
this.clickableElement = null
}
createInputObjects() {
return [
new MouseCreateLink(this.clickableElement, this.blueprint, {
moveEverywhere: true,
looseTarget: true
}),
]
}
/**
*
* @returns {String}
*/
getPinDisplayName() {
return this.entity.PinName
}
getAttributes() {
return PinEntity.attributes
}
isInput() {
return this.entity.isInput()
}
isOutput() {
return this.entity.isOutput()
}
isConnected() {
return this.entity.isConnected()
}
getType() {
return this.entity.getType()
}
getClickableElement() {
return this.clickableElement
}
/**
* Returns The exact location where the link originates from or arrives at.
* @returns {Number[]} The location array
*/
getLinkLocation() {
return this.template.getLinkLocation(this)
}
getNodeElement() {
return this.closest("ueb-node")
}
}
customElements.define(PinElement.tagName, PinElement)

View File

@@ -1,40 +1,40 @@
import FastSelectionModel from "../selection/FastSelectionModel"
import GraphElement from "./GraphElement"
import SelectorTemplate from "../template/SelectorTemplate"
export default class GraphSelector extends GraphElement {
static tagName = "ueb-selector"
constructor() {
super({}, new SelectorTemplate())
this.selectionModel = null
/** @type {SelectorTemplate} */
this.template
}
/**
* Create a selection rectangle starting from the specified position
* @param {number[]} initialPosition - Selection rectangle initial position (relative to the .ueb-grid element)
*/
startSelecting(initialPosition) {
this.template.applyStartSelecting(this, initialPosition)
this.selectionModel = new FastSelectionModel(initialPosition, this.blueprint.getNodes(), this.blueprint.nodeBoundariesSupplier, this.blueprint.nodeSelectToggleFunction)
}
/**
* Move selection rectagle to the specified final position. The initial position was specified by startSelecting()
* @param {number[]} finalPosition - Selection rectangle final position (relative to the .ueb-grid element)
*/
doSelecting(finalPosition) {
this.template.applyDoSelecting(this, finalPosition)
this.selectionModel.selectTo(finalPosition)
}
finishSelecting() {
this.template.applyFinishSelecting(this)
this.selectionModel = null
}
}
customElements.define(GraphSelector.tagName, GraphSelector)
import FastSelectionModel from "../selection/FastSelectionModel"
import IElement from "./IElement"
import SelectorTemplate from "../template/SelectorTemplate"
export default class SelectorElement extends IElement {
static tagName = "ueb-selector"
constructor() {
super({}, new SelectorTemplate())
this.selectionModel = null
/** @type {SelectorTemplate} */
this.template
}
/**
* Create a selection rectangle starting from the specified position
* @param {number[]} initialPosition - Selection rectangle initial position (relative to the .ueb-grid element)
*/
startSelecting(initialPosition) {
this.template.applyStartSelecting(this, initialPosition)
this.selectionModel = new FastSelectionModel(initialPosition, this.blueprint.getNodes(), this.blueprint.nodeBoundariesSupplier, this.blueprint.nodeSelectToggleFunction)
}
/**
* Move selection rectagle to the specified final position. The initial position was specified by startSelecting()
* @param {number[]} finalPosition - Selection rectangle final position (relative to the .ueb-grid element)
*/
doSelecting(finalPosition) {
this.template.applyDoSelecting(this, finalPosition)
this.selectionModel.selectTo(finalPosition)
}
finishSelecting() {
this.template.applyFinishSelecting(this)
this.selectionModel = null
}
}
customElements.define(SelectorElement.tagName, SelectorElement)

View File

@@ -1,7 +1,7 @@
import Entity from "./Entity"
import IEntity from "./IEntity"
import ObjectReferenceEntity from "./ObjectReferenceEntity"
export default class FunctionReferenceEntity extends Entity {
export default class FunctionReferenceEntity extends IEntity {
static attributes = {
MemberParent: ObjectReferenceEntity,

View File

@@ -1,6 +1,6 @@
import Entity from "./Entity"
import IEntity from "./IEntity"
export default class GuidEntity extends Entity {
export default class GuidEntity extends IEntity {
static attributes = {
value: String

110
js/entity/Entity.js → js/entity/IEntity.js Executable file → Normal file
View File

@@ -1,55 +1,55 @@
import TypeInitialization from "./TypeInitialization"
import Utility from "../Utility"
export default class Entity {
constructor(options = {}) {
/**
*
* @param {String[]} prefix
* @param {Object} target
* @param {Object} properties
*/
const defineAllAttributes = (prefix, target, properties) => {
let fullKey = prefix.concat("")
const last = fullKey.length - 1
for (let property in properties) {
fullKey[last] = property
// Not instanceof because all objects are instenceof Object, exact match needed
if (properties[property]?.constructor === Object) {
target[property] = {}
defineAllAttributes(fullKey, target[property], properties[property])
continue
}
/*
* The value can either be:
* - Array: can contain multiple values, its property is assigned multiple times like (X=1, X=4, X="Hello World")
* - TypeInitialization: contains the maximum amount of information about the attribute.
* - A type: the default value will be default constructed object without arguments.
* - A proper value.
*/
const value = Utility.objectGet(options, fullKey)
if (value !== null) {
target[property] = value
continue
}
let defaultValue = properties[property]
if (defaultValue instanceof TypeInitialization) {
if (!defaultValue.showDefault) {
continue
}
defaultValue = defaultValue.value
}
if (defaultValue instanceof Array) {
target[property] = []
continue
}
if (defaultValue instanceof Function) {
defaultValue = TypeInitialization.sanitize(new defaultValue())
}
target[property] = defaultValue
}
}
defineAllAttributes([], this, this.getAttributes())
}
}
import TypeInitialization from "./TypeInitialization"
import Utility from "../Utility"
export default class IEntity {
constructor(options = {}) {
/**
*
* @param {String[]} prefix
* @param {Object} target
* @param {Object} properties
*/
const defineAllAttributes = (prefix, target, properties) => {
let fullKey = prefix.concat("")
const last = fullKey.length - 1
for (let property in properties) {
fullKey[last] = property
// Not instanceof because all objects are instenceof Object, exact match needed
if (properties[property]?.constructor === Object) {
target[property] = {}
defineAllAttributes(fullKey, target[property], properties[property])
continue
}
/*
* The value can either be:
* - Array: can contain multiple values, its property is assigned multiple times like (X=1, X=4, X="Hello World")
* - TypeInitialization: contains the maximum amount of information about the attribute.
* - A type: the default value will be default constructed object without arguments.
* - A proper value.
*/
const value = Utility.objectGet(options, fullKey)
if (value !== null) {
target[property] = value
continue
}
let defaultValue = properties[property]
if (defaultValue instanceof TypeInitialization) {
if (!defaultValue.showDefault) {
continue
}
defaultValue = defaultValue.value
}
if (defaultValue instanceof Array) {
target[property] = []
continue
}
if (defaultValue instanceof Function) {
defaultValue = TypeInitialization.sanitize(new defaultValue())
}
target[property] = defaultValue
}
}
defineAllAttributes([], this, this.getAttributes())
}
}

View File

@@ -1,6 +1,6 @@
import Entity from "./Entity"
import IEntity from "./IEntity"
export default class IntegerEntity extends Entity {
export default class IntegerEntity extends IEntity {
static attributes = {
value: Number

View File

@@ -1,6 +1,6 @@
import Entity from "./Entity"
import IEntity from "./IEntity"
export default class KeyBinding extends Entity {
export default class KeyBinding extends IEntity {
static attributes = {
bCtrlDown: false,

View File

@@ -1,6 +1,6 @@
import Entity from "./Entity"
import IEntity from "./IEntity"
export default class LocalizedTextEntity extends Entity {
export default class LocalizedTextEntity extends IEntity {
static lookbehind = "NSLOCTEXT"
static attributes = {

View File

@@ -1,4 +1,4 @@
import Entity from "./Entity"
import IEntity from "./IEntity"
import FunctionReferenceEntity from "./FunctionReferenceEntity"
import GuidEntity from "./GuidEntity"
import IntegerEntity from "./IntegerEntity"
@@ -7,7 +7,7 @@ import PinEntity from "./PinEntity"
import TypeInitialization from "./TypeInitialization"
import VariableReferenceEntity from "./VariableReferenceEntity"
export default class ObjectEntity extends Entity {
export default class ObjectEntity extends IEntity {
static attributes = {
Class: ObjectReferenceEntity,

View File

@@ -1,6 +1,6 @@
import Entity from "./Entity"
import IEntity from "./IEntity"
export default class ObjectReferenceEntity extends Entity {
export default class ObjectReferenceEntity extends IEntity {
static attributes = {
type: String,

View File

@@ -1,6 +1,6 @@
import Entity from "./Entity"
import IEntity from "./IEntity"
export default class PathSymbolEntity extends Entity {
export default class PathSymbolEntity extends IEntity {
static attributes = {
value: String

View File

@@ -1,11 +1,11 @@
import Entity from "./Entity"
import IEntity from "./IEntity"
import GuidEntity from "./GuidEntity"
import LocalizedTextEntity from "./LocalizedTextEntity"
import ObjectReferenceEntity from "./ObjectReferenceEntity"
import PinReferenceEntity from "./PinReferenceEntity"
import TypeInitialization from "./TypeInitialization"
export default class PinEntity extends Entity {
export default class PinEntity extends IEntity {
static lookbehind = "Pin"
static attributes = {

View File

@@ -1,8 +1,8 @@
import Entity from "./Entity"
import IEntity from "./IEntity"
import GuidEntity from "./GuidEntity"
import PathSymbol from "./PathSymbolEntity"
export default class PinReferenceEntity extends Entity {
export default class PinReferenceEntity extends IEntity {
static attributes = {
objectName: PathSymbol,

View File

@@ -1,7 +1,7 @@
import Entity from "./Entity"
import IEntity from "./IEntity"
import GuidEntity from "./GuidEntity"
export default class VariableReferenceEntity extends Entity {
export default class VariableReferenceEntity extends IEntity {
static attributes = {
MemberName: String,

View File

@@ -1,10 +1,10 @@
import Blueprint from "./Blueprint"
import Configuration from "./Configuration"
import GraphLink from "./graph/GraphLink"
import GraphNode from "./graph/GraphNode"
import LinkElement from "./element/LinkElement"
import NodeElement from "./element/NodeElement"
import initializeSerializerFactory from "./serialization/initializeSerializerFactory"
initializeSerializerFactory()
export { Blueprint as Blueprint, GraphNode as GraphNode, GraphLink as GraphLink, Configuration as Configuration }
export { Blueprint as Blueprint, NodeElement as NodeElement, LinkElement as LinkElement, Configuration as Configuration }

View File

@@ -1,4 +1,4 @@
import GraphNode from "../../graph/GraphNode"
import NodeElement from "../../element/NodeElement"
import ObjectSerializer from "../../serialization/ObjectSerializer"
import Context from "../Context"
@@ -27,7 +27,7 @@ export default class Paste extends Context {
let left = 0
let count = 0
let nodes = this.serializer.readMultiple(value).map(entity => {
let node = new GraphNode(entity)
let node = new NodeElement(entity)
top += node.location[1]
left += node.location[0]
++count

View File

@@ -1,11 +1,11 @@
import GraphLink from "../../graph/GraphLink"
import GraphLinkMessage from "../../graph/GraphLinkMessage"
import LinkElement from "../../element/LinkElement"
import LinkMessageElement from "../../element/LinkMessageElement"
import MouseClickDrag from "./MouseClickDrag"
/** @typedef {import("../../graph/GraphPin").default} GraphPin */
/** @typedef {import("../../element/PinElement").default} PinElement */
export default class MouseCreateLink extends MouseClickDrag {
/** @type {NodeListOf<GraphPin>} */
/** @type {NodeListOf<PinElement>} */
#listenedPins
/** @type {(e: MouseEvent) => void} */
@@ -16,9 +16,9 @@ export default class MouseCreateLink extends MouseClickDrag {
constructor(target, blueprint, options) {
super(target, blueprint, options)
/** @type {import("../../graph/GraphPin").default} */
/** @type {import("../../element/PinElement").PinElement} */
this.target
/** @type {import("../../graph/GraphLink").default} */
/** @type {import("../../element/LinkElement").LinkElement} */
this.link
/** @type {import("../../entity/PinEntity").default} */
this.enteredPin
@@ -37,8 +37,8 @@ export default class MouseCreateLink extends MouseClickDrag {
}
startDrag() {
this.link = new GraphLink(this.target, null)
this.link.setLinkMessage(GraphLinkMessage.PLACE_NODE())
this.link = new LinkElement(this.target, null)
this.link.setLinkMessage(LinkMessageElement.placeNode())
this.blueprint.nodesContainerElement.insertBefore(this.link, this.blueprint.selectorElement.nextElementSibling)
this.#listenedPins = this.blueprint.querySelectorAll(this.target.constructor.tagName)
this.#listenedPins.forEach(pin => {

View File

@@ -2,13 +2,13 @@ import MouseClickDrag from "./MouseClickDrag"
import Utility from "../../Utility"
/**
* @typedef {import("../../graph/SelectableDraggable").default} SelectableDraggable
* @typedef {import("../../element/ISelectableDraggableElement").ISelectableDraggableElement} ISelectableDraggableElement
*/
export default class MouseMoveNodes extends MouseClickDrag {
/**
*
* @param {SelectableDraggable} target
* @param {ISelectableDraggableElement} target
* @param {*} blueprint
* @param {*} options
*/
@@ -16,7 +16,7 @@ export default class MouseMoveNodes extends MouseClickDrag {
super(target, blueprint, options)
this.stepSize = parseInt(options?.stepSize ?? this.blueprint.gridSize)
this.mouseLocation = [0, 0]
/** @type {SelectableDraggable} */
/** @type {ISelectableDraggableElement} */
this.target
}

View File

@@ -1,4 +1,4 @@
import Entity from "../entity/Entity"
import IEntity from "../entity/IEntity"
import Grammar from "./Grammar"
import Parsimmon from "parsimmon"
import SerializerFactory from "./SerializerFactory"
@@ -37,7 +37,7 @@ export default class Serializer {
if (value instanceof Array) {
return `(${value.map(v => serialize(v) + ",")})`
}
if (value instanceof Entity) {
if (value instanceof IEntity) {
return serialize(value)
}
}

View File

@@ -1,7 +1,7 @@
import Configuration from "../Configuration"
import GraphSelector from "../graph/GraphSelector"
import html from "./html"
import sanitizeText from "./sanitizeText"
import SelectorElement from "../element/SelectorElement"
import Template from "./Template"
/** @typedef {import("../Blueprint").default} Blueprint */
@@ -77,7 +77,7 @@ export default class BlueprintTemplate extends Template {
blueprint.viewportElement = blueprint.querySelector('.ueb-viewport-body')
blueprint.gridElement = blueprint.viewportElement.querySelector(".ueb-grid")
blueprint.nodesContainerElement = blueprint.querySelector("[data-nodes]")
blueprint.selectorElement = new GraphSelector()
blueprint.selectorElement = new SelectorElement()
blueprint.nodesContainerElement.append(blueprint.selectorElement, ...blueprint.getNodes())
this.applyEndDragScrolling(blueprint)
}

View File

@@ -1,15 +1,15 @@
import GraphLink from "../graph/GraphLink"
import LinkElement from "../element/LinkElement"
import html from "./html"
import Template from "./Template"
/**
* @typedef {import("../graph/GraphLinkMessage").default} GraphLinkMessage
* @typedef {import("../element/LinkMessageElement").default} LinkMessageElement
*/
export default class LinkMessageTemplate extends Template {
/**
* Computes the html content of the target element.
* @param {GraphLinkMessage} linkMessage attached to link destination
* @param {LinkMessageElement} linkMessage attached to link destination
* @returns The result html
*/
render(linkMessage) {
@@ -21,11 +21,11 @@ export default class LinkMessageTemplate extends Template {
/**
* Applies the style to the element.
* @param {GraphLinkMessage} linkMessage element
* @param {LinkMessageElement} linkMessage element
*/
apply(linkMessage) {
super.apply(linkMessage)
linkMessage.linkElement = linkMessage.closest(GraphLink.tagName)
linkMessage.linkElement = linkMessage.closest(LinkElement.tagName)
linkMessage.querySelector(".ueb-link-message").innerText = linkMessage.message(
linkMessage.linkElement.getSourcePin(),
linkMessage.linkElement.getDestinationPin()

View File

@@ -4,8 +4,8 @@ import Template from "./Template"
import Configuration from "../Configuration"
/**
* @typedef {import("../graph/GraphLink").default} GraphLink
* @typedef {import("../graph/GraphLinkMessage").default} GraphLinkMessage
* @typedef {import("../element/LinkElement").default} LinkElement
* @typedef {import("../element/LinkMessageElement").default} LinkMessageElement
*/
export default class LinkTemplate extends Template {
@@ -19,7 +19,7 @@ export default class LinkTemplate extends Template {
/**
* Computes the html content of the target element.
* @param {GraphLink} link connecting two graph nodes
* @param {LinkElement} link connecting two graph nodes
* @returns The result html
*/
render(link) {
@@ -32,7 +32,7 @@ export default class LinkTemplate extends Template {
/**
* Applies the style to the element.
* @param {GraphLink} link Element of the graph
* @param {LinkElement} link Element of the graph
*/
apply(link) {
super.apply(link)
@@ -45,7 +45,7 @@ export default class LinkTemplate extends Template {
/**
* Applies the style relative to the source pin location.
* @param {GraphLink} link Link element
* @param {LinkElement} link Link element
*/
applySourceLocation(link) {
link.style.setProperty("--ueb-from-input", link.originatesFromInput ? "0" : "1")
@@ -55,7 +55,7 @@ export default class LinkTemplate extends Template {
/**
* Applies the style relative to the destination pin location.
* @param {GraphLink} link Link element
* @param {LinkElement} link Link element
*/
applyFullLocation(link) {
const dx = Math.max(Math.abs(link.sourceLocation[0] - link.destinationLocation[0]), 1)
@@ -97,8 +97,8 @@ export default class LinkTemplate extends Template {
/**
*
* @param {GraphLink} link element
* @param {GraphLinkMessage} linkMessage
* @param {LinkElement} link element
* @param {LinkMessageElement} linkMessage
*/
applyLinkMessage(link, linkMessage) {
link.querySelectorAll(linkMessage.constructor.tagName).forEach(element => element.remove())

View File

@@ -1,17 +1,17 @@
import GraphPin from "../graph/GraphPin"
import PinElement from "../element/PinElement"
import html from "./html"
import PinEntity from "../entity/PinEntity"
import sanitizeText from "./sanitizeText"
import SelectableDraggableTemplate from "./SelectableDraggableTemplate"
/**
* @typedef {import("../graph/GraphNode").default} GraphNode
* @typedef {import("../element/NodeElement").default} NodeElement
*/
export default class NodeTemplate extends SelectableDraggableTemplate {
/**
* Computes the html content of the target element.
* @param {GraphNode} node Graph node element
* @param {NodeElement} node Graph node element
* @returns The result html
*/
render(node) {
@@ -35,7 +35,7 @@ export default class NodeTemplate extends SelectableDraggableTemplate {
/**
* Applies the style to the element.
* @param {GraphNode} node Element of the graph
* @param {NodeElement} node Element of the graph
*/
apply(node) {
super.apply(node)
@@ -49,7 +49,7 @@ export default class NodeTemplate extends SelectableDraggableTemplate {
/** @type {HTMLElement} */
let outputContainer = node.querySelector(".ueb-node-outputs")
let pins = node.getPinEntities()
pins.filter(v => v.isInput()).forEach(v => inputContainer.appendChild(new GraphPin(v)))
pins.filter(v => v.isOutput()).forEach(v => outputContainer.appendChild(new GraphPin(v)))
pins.filter(v => v.isInput()).forEach(v => inputContainer.appendChild(new PinElement(v)))
pins.filter(v => v.isOutput()).forEach(v => outputContainer.appendChild(new PinElement(v)))
}
}

View File

@@ -4,13 +4,13 @@ import sanitizeText from "./sanitizeText"
import Template from "./Template"
/**
* @typedef {import("../graph/GraphPin").default} GraphPin
* @typedef {import("../element/PinElement").default} PinElement
*/
export default class PinTemplate extends Template {
/**
* Computes the html content of the pin.
* @param {GraphPin} pin Pin entity
* @param {PinElement} pin html element
* @returns The result html
*/
render(pin) {
@@ -29,7 +29,7 @@ export default class PinTemplate extends Template {
/**
* Applies the style to the element.
* @param {GraphPin} pin Element of the graph
* @param {PinElement} pin element of the graph
*/
apply(pin) {
super.apply(pin)
@@ -40,7 +40,7 @@ export default class PinTemplate extends Template {
/**
*
* @param {GraphPin} pin
* @param {PinElement} pin
* @returns
*/
getLinkLocation(pin) {

View File

@@ -2,13 +2,13 @@ import sanitizeText from "./sanitizeText"
import Template from "./Template"
/**
* @typedef {import("../graph/SelectableDraggable").default} SelectableDraggable
* @typedef {import("../element/ISelectableDraggableElement").default} ISelectableDraggableElement
*/
export default class SelectableDraggableTemplate extends Template {
/**
* Returns the html elements rendered from this template.
* @param {SelectableDraggable} element Element of the graph
* @param {ISelectableDraggableElement} element Element of the graph
*/
applyLocation(element) {
element.style.setProperty("--ueb-position-x", sanitizeText(element.location[0]))
@@ -17,7 +17,7 @@ export default class SelectableDraggableTemplate extends Template {
/**
* Returns the html elements rendered from this template.
* @param {SelectableDraggable} element Element of the graph
* @param {ISelectableDraggableElement} element Element of the graph
*/
applySelected(element) {
if (element.selected) {

View File

@@ -2,13 +2,13 @@ import sanitizeText from "./sanitizeText"
import Template from "./Template"
/**
* @typedef {import("../graph/GraphSelector").default} GraphSelector
* @typedef {import("../element/SelectorElement").default} SelectorElement
*/
export default class SelectorTemplate extends Template {
/**
* Applies the style to the element.
* @param {GraphSelector} selector Selector element
* @param {SelectorElement} selector Selector element
*/
apply(selector) {
super.apply(selector)
@@ -18,7 +18,7 @@ export default class SelectorTemplate extends Template {
/**
* Applies the style relative to selection beginning.
* @param {GraphSelector} selector Selector element
* @param {SelectorElement} selector Selector element
*/
applyStartSelecting(selector, initialPosition) {
// Set initial position
@@ -32,7 +32,7 @@ export default class SelectorTemplate extends Template {
/**
* Applies the style relative to selection.
* @param {GraphSelector} selector Selector element
* @param {SelectorElement} selector Selector element
*/
applyDoSelecting(selector, finalPosition) {
selector.style.setProperty("--ueb-to-x", sanitizeText(finalPosition[0]))
@@ -41,7 +41,7 @@ export default class SelectorTemplate extends Template {
/**
* Applies the style relative to selection finishing.
* @param {GraphSelector} selector Selector element
* @param {SelectorElement} selector Selector element
*/
applyFinishSelecting(selector) {
selector.blueprint.dataset.selecting = "false"

View File

@@ -1,11 +1,11 @@
/**
* @typedef {import("../graph/GraphElement").default} GraphElement
* @typedef {import("../element/IElement").default} IElement
*/
export default class Template {
/**
* Computes the html content of the target element.
* @param {GraphElement} entity Element of the graph
* @param {IElement} entity Element of the graph
* @returns The result html
*/
render(entity) {
@@ -14,7 +14,7 @@ export default class Template {
/**
* Applies the style to the element.
* @param {GraphElement} element Element of the graph
* @param {IElement} element Element of the graph
*/
apply(element) {
// TODO replace with the safer element.setHTML(...) when it will be available