Various fixes

This commit is contained in:
barsdeveloper
2022-03-19 14:46:53 +01:00
parent 391a537a78
commit 42615b93f8
25 changed files with 267 additions and 131 deletions

191
dist/ueblueprint.js vendored
View File

@@ -518,6 +518,13 @@ class IElement extends HTMLElement {
createInputObjects() {
return []
}
/**
* @param {IElement} element
*/
isSameGraph(element) {
return this.blueprint && this.blueprint == element?.blueprint
}
}
/**
@@ -812,6 +819,26 @@ class Utility {
return location
}
/**
* Gets a value from an object, gives defaultValue in case of failure
* @param {Object} target Object holding the data
* @param {String[]} keys The chained keys to access from object in order to get the value
* @param {any} defaultValue Value to return in case from doesn't have it
* @returns {any} The value in from corresponding to the keys or defaultValue otherwise
*/
static objectGet(target, keys, defaultValue = undefined) {
if (!(keys instanceof Array)) {
console.error("Expected keys to be an array.");
}
if (keys.length == 0 || !(keys[0] in target) || target[keys[0]] === undefined) {
return defaultValue
}
if (keys.length == 1) {
return target[keys[0]]
}
return Utility.objectGet(target[keys[0]], keys.slice(1), defaultValue)
}
/**
* Sets a value in an object
* @param {Object} target Object holding the data
@@ -820,7 +847,7 @@ class Utility {
* @param {Boolean} create Whether to create or not the key in case it doesn't exist
* @returns {Boolean} Returns true on succes, false otherwise
*/
static objectSet(target, keys, value, create = false) {
static objectSet(target, keys, value, create = false, defaultDictType = Object) {
if (!(keys instanceof Array)) {
console.error("Expected keys to be an array.");
}
@@ -831,33 +858,13 @@ class Utility {
}
} else if (keys.length > 0) {
if (create && !(target[keys[0]] instanceof Object)) {
target[keys[0]] = {};
target[keys[0]] = new defaultDictType();
}
return Utility.objectSet(target[keys[0]], keys.slice(1), value, create)
return Utility.objectSet(target[keys[0]], keys.slice(1), value, create, defaultDictType)
}
return false
}
/**
* Gets a value from an object, gives defaultValue in case of failure
* @param {Object} source Object holding the data
* @param {String[]} keys The chained keys to access from object in order to get the value
* @param {any} defaultValue Value to return in case from doesn't have it
* @returns {any} The value in from corresponding to the keys or defaultValue otherwise
*/
static objectGet(source, keys, defaultValue = null) {
if (!(keys instanceof Array)) {
console.error("Expected keys to be an array.");
}
if (keys.length == 0 || !(keys[0] in source) || source[keys[0]] === undefined) {
return defaultValue
}
if (keys.length == 1) {
return source[keys[0]]
}
return Utility.objectGet(source[keys[0]], keys.slice(1), defaultValue)
}
static equals(a, b) {
a = TypeInitialization.sanitize(a);
b = TypeInitialization.sanitize(b);
@@ -865,7 +872,6 @@ class Utility {
}
/**
*
* @param {String} value
*/
static FirstCapital(value) {
@@ -910,7 +916,7 @@ class IEntity {
const defineAllAttributes = (prefix, target, properties) => {
let fullKey = prefix.concat("");
const last = fullKey.length - 1;
for (let property in properties) {
for (let property of Object.getOwnPropertyNames(properties)) {
fullKey[last] = property;
// Not instanceof because all objects are instenceof Object, exact match needed
if (properties[property]?.constructor === Object) {
@@ -920,7 +926,7 @@ class IEntity {
}
/*
* The value can either be:
* - Array: can contain multiple values, its property is assigned multiple times like (X=1, X=4, X="Hello World")
* - 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.
@@ -933,6 +939,7 @@ class IEntity {
let defaultValue = properties[property];
if (defaultValue instanceof TypeInitialization) {
if (!defaultValue.showDefault) {
target[property] = undefined; // to preserve the order
continue
}
defaultValue = defaultValue.value;
@@ -955,7 +962,7 @@ class ObjectReferenceEntity extends IEntity {
static attributes = {
type: String,
path: String
path: String,
}
}
@@ -963,17 +970,14 @@ class FunctionReferenceEntity extends IEntity {
static attributes = {
MemberParent: ObjectReferenceEntity,
MemberName: ""
MemberName: "",
}
/** @type {ObjectReferenceEntity} */ MemberParent
/** @type {String} */ MemberName
}
class GuidEntity extends IEntity {
static attributes = {
value: String
value: String,
}
static generateGuid(random = true) {
@@ -988,6 +992,10 @@ class GuidEntity extends IEntity {
return new GuidEntity({ value: guid })
}
valueOf() {
return this.value
}
toString() {
return this.value
}
@@ -996,13 +1004,13 @@ class GuidEntity extends IEntity {
class IntegerEntity extends IEntity {
static attributes = {
value: Number
value: Number,
}
constructor(options = {}) {
if (options.constructor === Number || options.constructor === String) {
if (options.constructor == Number || options.constructor == String) {
options = {
value: options
value: options,
};
}
super(options);
@@ -1024,14 +1032,14 @@ class LocalizedTextEntity extends IEntity {
static attributes = {
namespace: String,
key: String,
value: String
value: String,
}
}
class PathSymbolEntity extends IEntity {
static attributes = {
value: String
value: String,
}
toString() {
@@ -1043,7 +1051,7 @@ class PinReferenceEntity extends IEntity {
static attributes = {
objectName: PathSymbolEntity,
pinGuid: GuidEntity
pinGuid: GuidEntity,
}
}
@@ -1113,13 +1121,13 @@ class PinEntity extends IEntity {
linkTo(targetObjectName, targetPinEntity) {
/** @type {PinReferenceEntity[]} */
this.LinkedTo;
const linkExists = this.LinkedTo.find(
const linkFound = this.LinkedTo.find(
/** @type {PinReferenceEntity} */
pinReferenceEntity => {
return pinReferenceEntity.objectName == targetObjectName
&& pinReferenceEntity.pinGuid == targetPinEntity.PinId
&& pinReferenceEntity.pinGuid.valueOf() == targetPinEntity.PinId.valueOf()
});
if (!linkExists) {
if (!linkFound) {
this.LinkedTo.push(new PinReferenceEntity({
objectName: targetObjectName,
pinGuid: targetPinEntity.PinId
@@ -1159,7 +1167,7 @@ class VariableReferenceEntity extends IEntity {
static attributes = {
MemberName: String,
MemberGuid: GuidEntity,
bSelfContext: false
bSelfContext: false,
}
}
@@ -1178,11 +1186,11 @@ class ObjectEntity extends IEntity {
NodeGuid: GuidEntity,
ErrorType: new TypeInitialization(IntegerEntity, false),
ErrorMsg: new TypeInitialization(String, false, ""),
CustomProperties: [PinEntity]
CustomProperties: [PinEntity],
}
/**
* @returns {String} The name of the node
* @returns {String}
*/
getName() {
return this.Name
@@ -1427,14 +1435,14 @@ class ISerializer {
let result = "";
let fullKey = key.concat("");
const last = fullKey.length - 1;
for (const property in object) {
for (const property of Object.getOwnPropertyNames(object)) {
fullKey[last] = property;
const value = object[property];
if (object[property]?.constructor === Object) {
// Recursive call when finding an object
result += (result.length ? this.separator : "")
+ this.subWrite(fullKey, value);
} else if (this.showProperty(fullKey, value)) {
} else if (value !== undefined && this.showProperty(fullKey, value)) {
result += (result.length ? this.separator : "")
+ this.prefix
+ this.attributeKeyPrinter(fullKey)
@@ -1507,7 +1515,7 @@ ${this.subWrite([], object)
+ object
.CustomProperties.map(pin => this.separator + this.prefix + "CustomProperties " + SerializerFactory.getSerializer(PinEntity).write(pin))
.join("")}
End Object`;
End Object\n`;
return result
}
}
@@ -1804,7 +1812,7 @@ class LinkTemplate extends ITemplate {
c2 = Math.min(c2, LinkTemplate.c2DecreasingValue(width));
const d = Configuration.linkRightSVGPath(start, c1, c2);
// TODO move to CSS when Firefox will support property d and css will have enough functions
link.pathElement.setAttribute("d", d);
link.pathElement?.setAttribute("d", d);
}
/**
@@ -2088,6 +2096,7 @@ class IMouseClickDrag extends IPointing {
}
// Attach the listeners
movementListenedElement.addEventListener("mousemove", self.#mouseStartedMovingHandler);
document.addEventListener("mouseup", self.#mouseUpHandler);
self.clickedPosition = self.locationFromEvent(e);
self.clicked(self.clickedPosition);
}
@@ -2108,7 +2117,6 @@ class IMouseClickDrag extends IPointing {
// Delegate from now on to self.#mouseMoveHandler
movementListenedElement.removeEventListener("mousemove", self.#mouseStartedMovingHandler);
movementListenedElement.addEventListener("mousemove", self.#mouseMoveHandler);
document.addEventListener("mouseup", self.#mouseUpHandler);
// Handler calls e.preventDefault() when it receives the event, this means dispatchEvent returns false
const dragEvent = self.getEvent(Configuration.trackingMouseEventName.begin);
self.#trackingMouse = this.target.dispatchEvent(dragEvent) == false;
@@ -2140,7 +2148,9 @@ class IMouseClickDrag extends IPointing {
movementListenedElement.removeEventListener("mousemove", self.#mouseStartedMovingHandler);
movementListenedElement.removeEventListener("mousemove", self.#mouseMoveHandler);
document.removeEventListener("mouseup", self.#mouseUpHandler);
self.endDrag();
if (self.started) {
self.endDrag();
}
if (self.#trackingMouse) {
const dragEvent = self.getEvent(Configuration.trackingMouseEventName.end);
this.target.dispatchEvent(dragEvent);
@@ -2265,6 +2275,38 @@ class MouseTracking extends IPointing {
}
}
/**
* @template Key
* @template Value
*/
class MultiKeyWeakMap {
map = new WeakMap()
constructor() {
return new Proxy(this.map, this)
}
/**
* @param {WeakMap} target
* @param {Key} p
* @param {*} receiver
* @returns {Value}
*/
get(target, p, receiver) {
return Utility.objectGet(target, p)
}
/**
* @param {WeakMap} target
* @param {Key} p
* @param {Value} value
*/
set(target, p, value) {
return Utility.objectSet(target, p, value, true, WeakMap)
}
}
/**
* @typedef {import("../../element/ISelectableDraggableElement").default} ISelectableDraggableElement
*/
@@ -2628,15 +2670,14 @@ class PinTemplate extends ITemplate {
"ueb-pin-" + sanitizeText(pin.getType())
);
pin.clickableElement = pin;
window.customElements.whenDefined(NodeElement.tagName).then(pin.nodeElement = pin.closest(NodeElement.tagName));
window.customElements.whenDefined("ueb-node").then(pin.nodeElement = pin.closest("ueb-node"));
pin.getLinks().forEach(pinReference => {
const targetPin = pin.blueprint.getPin(pinReference.pinGuid);
const targetPin = pin.blueprint.getPin(pinReference);
if (targetPin) {
const [sourcePin, destinationPin] = pin.isOutput() ? [pin, targetPin] : [targetPin, pin];
pin.blueprint.addGraphElement(new LinkElement(sourcePin, destinationPin));
}
});
}
/**
@@ -2706,6 +2747,11 @@ class PinElement extends IElement {
return this.entity.PinId
}
/** @type {GuidEntity} */
GetPinIdValue() {
return this.GetPinId().value
}
/**
* @returns {String}
*/
@@ -2752,14 +2798,17 @@ class PinElement extends IElement {
return this.template.getLinkLocation(this)
}
/**
* @returns {NodeElement}
*/
getNodeElement() {
return this.closest("ueb-node")
}
getLinks() {
return this.entity.LinkedTo.map(pinReference =>
return this.entity.LinkedTo?.map(pinReference =>
pinReference
)
) ?? []
}
/**
@@ -3103,8 +3152,21 @@ class Zoom extends IMouseWheel {
class Blueprint extends IElement {
static tagName = "ueb-blueprint"
/** @type {WeakMap<GuidEntity, PinElement>} */
#pinGuidMap = new WeakMap()
/** @type {MultiKeyWeakMap<String, PinElement>} */
#pinGuidMap = new Proxy(new MultiKeyWeakMap(), {
get(target, p, receiver) {
if (p instanceof PinReferenceEntity) {
p = [p.objectName, p.pinGuid];
}
return Reflect.get(target, p)
},
set(target, p, value) {
if (p instanceof PinReferenceEntity) {
p = [p.objectName, p.pinGuid];
}
return Reflect.set(target, p, value)
}
})
/** @type {number} */
gridSize = Configuration.gridSize
/** @type {NodeElement[]}" */
@@ -3386,10 +3448,10 @@ class Blueprint extends IElement {
}
/**
* @param {GuidEntity} guid
* @param {PinReferenceEntity} pinReference
*/
getPin(guid) {
return this.#pinGuidMap[guid]
getPin(pinReference) {
return this.#pinGuidMap[pinReference]
}
/**
@@ -3431,7 +3493,12 @@ class Blueprint extends IElement {
if (element instanceof NodeElement) {
this.nodes.push(element);
element.getPinElements().forEach(
pinElement => this.#pinGuidMap[pinElement.GetPinId()] = pinElement
pinElement => this.#pinGuidMap[
new PinReferenceEntity({
objectName: pinElement.getNodeElement().getNodeName(),
pinGuid: pinElement.GetPinId(),
})
] = pinElement
);
} else if (element instanceof LinkElement) {
this.links.push(element);
@@ -3556,7 +3623,7 @@ function initializeSerializerFactory() {
);
SerializerFactory.registerSerializer(
LocalizedTextEntity,
new GeneralSerializer(v => `${LocalizedTextEntity.lookbehind}(${v})`, LocalizedTextEntity, "", ",", false, "", _ => "")
new GeneralSerializer(v => `${LocalizedTextEntity.lookbehind}(${v})`, LocalizedTextEntity, "", ", ", false, "", _ => "")
);
SerializerFactory.registerSerializer(
PinReferenceEntity,

View File

@@ -7,6 +7,7 @@ import KeyboardSelectAll from "./input/keybaord/KeyboardSelectAll"
import LinkElement from "./element/LinkElement"
import MouseScrollGraph from "./input/mouse/MouseScrollGraph"
import MouseTracking from "./input/mouse/MouseTracking"
import MultiKeyWeakMap from "./MultiKeyMap"
import NodeElement from "./element/NodeElement"
import Paste from "./input/common/Paste"
import Select from "./input/mouse/Select"
@@ -14,6 +15,7 @@ import SelectorElement from "./element/SelectorElement"
import Unfocus from "./input/mouse/Unfocus"
import Utility from "./Utility"
import Zoom from "./input/mouse/Zoom"
import PinReferenceEntity from "./entity/PinReferenceEntity"
/**
* @typedef {import("./entity/GuidEntity").default} GuidEntity
@@ -22,8 +24,21 @@ import Zoom from "./input/mouse/Zoom"
export default class Blueprint extends IElement {
static tagName = "ueb-blueprint"
/** @type {WeakMap<GuidEntity, PinElement>} */
#pinGuidMap = new WeakMap()
/** @type {MultiKeyWeakMap<String, PinElement>} */
#pinGuidMap = new Proxy(new MultiKeyWeakMap(), {
get(target, p, receiver) {
if (p instanceof PinReferenceEntity) {
p = [p.objectName, p.pinGuid]
}
return Reflect.get(target, p)
},
set(target, p, value) {
if (p instanceof PinReferenceEntity) {
p = [p.objectName, p.pinGuid]
}
return Reflect.set(target, p, value)
}
})
/** @type {number} */
gridSize = Configuration.gridSize
/** @type {NodeElement[]}" */
@@ -305,10 +320,10 @@ export default class Blueprint extends IElement {
}
/**
* @param {GuidEntity} guid
* @param {PinReferenceEntity} pinReference
*/
getPin(guid) {
return this.#pinGuidMap[guid]
getPin(pinReference) {
return this.#pinGuidMap[pinReference]
}
/**
@@ -350,7 +365,12 @@ export default class Blueprint extends IElement {
if (element instanceof NodeElement) {
this.nodes.push(element)
element.getPinElements().forEach(
pinElement => this.#pinGuidMap[pinElement.GetPinId()] = pinElement
pinElement => this.#pinGuidMap[
new PinReferenceEntity({
objectName: pinElement.getNodeElement().getNodeName(),
pinGuid: pinElement.GetPinId(),
})
] = pinElement
)
} else if (element instanceof LinkElement) {
this.links.push(element)

33
js/MultiKeyMap.js Normal file
View File

@@ -0,0 +1,33 @@
import Utility from "./Utility"
/**
* @template Key
* @template Value
*/
export default class MultiKeyWeakMap {
map = new WeakMap()
constructor() {
return new Proxy(this.map, this)
}
/**
* @param {WeakMap} target
* @param {Key} p
* @param {*} receiver
* @returns {Value}
*/
get(target, p, receiver) {
return Utility.objectGet(target, p)
}
/**
* @param {WeakMap} target
* @param {Key} p
* @param {Value} value
*/
set(target, p, value) {
return Utility.objectSet(target, p, value, true, WeakMap)
}
}

View File

@@ -30,6 +30,26 @@ export default class Utility {
return location
}
/**
* Gets a value from an object, gives defaultValue in case of failure
* @param {Object} target Object holding the data
* @param {String[]} keys The chained keys to access from object in order to get the value
* @param {any} defaultValue Value to return in case from doesn't have it
* @returns {any} The value in from corresponding to the keys or defaultValue otherwise
*/
static objectGet(target, keys, defaultValue = undefined) {
if (!(keys instanceof Array)) {
console.error("Expected keys to be an array.")
}
if (keys.length == 0 || !(keys[0] in target) || target[keys[0]] === undefined) {
return defaultValue
}
if (keys.length == 1) {
return target[keys[0]]
}
return Utility.objectGet(target[keys[0]], keys.slice(1), defaultValue)
}
/**
* Sets a value in an object
* @param {Object} target Object holding the data
@@ -38,7 +58,7 @@ export default class Utility {
* @param {Boolean} create Whether to create or not the key in case it doesn't exist
* @returns {Boolean} Returns true on succes, false otherwise
*/
static objectSet(target, keys, value, create = false) {
static objectSet(target, keys, value, create = false, defaultDictType = Object) {
if (!(keys instanceof Array)) {
console.error("Expected keys to be an array.")
}
@@ -49,33 +69,13 @@ export default class Utility {
}
} else if (keys.length > 0) {
if (create && !(target[keys[0]] instanceof Object)) {
target[keys[0]] = {}
target[keys[0]] = new defaultDictType()
}
return Utility.objectSet(target[keys[0]], keys.slice(1), value, create)
return Utility.objectSet(target[keys[0]], keys.slice(1), value, create, defaultDictType)
}
return false
}
/**
* Gets a value from an object, gives defaultValue in case of failure
* @param {Object} source Object holding the data
* @param {String[]} keys The chained keys to access from object in order to get the value
* @param {any} defaultValue Value to return in case from doesn't have it
* @returns {any} The value in from corresponding to the keys or defaultValue otherwise
*/
static objectGet(source, keys, defaultValue = null) {
if (!(keys instanceof Array)) {
console.error("Expected keys to be an array.")
}
if (keys.length == 0 || !(keys[0] in source) || source[keys[0]] === undefined) {
return defaultValue
}
if (keys.length == 1) {
return source[keys[0]]
}
return Utility.objectGet(source[keys[0]], keys.slice(1), defaultValue)
}
static equals(a, b) {
a = TypeInitialization.sanitize(a)
b = TypeInitialization.sanitize(b)
@@ -83,7 +83,6 @@ export default class Utility {
}
/**
*
* @param {String} value
*/
static FirstCapital(value) {

View File

@@ -42,4 +42,11 @@ export default class IElement extends HTMLElement {
createInputObjects() {
return []
}
/**
* @param {IElement} element
*/
isSameGraph(element) {
return this.blueprint && this.blueprint == element?.blueprint
}
}

View File

@@ -2,8 +2,8 @@ import Configuration from "../Configuration"
import ISelectableDraggableElement from "./ISelectableDraggableElement"
import NodeTemplate from "../template/NodeTemplate"
import ObjectEntity from "../entity/ObjectEntity"
import PinEntity from "../entity/PinEntity"
import SerializerFactory from "../serialization/SerializerFactory"
import PinEntity from "../entity/PinEntity"
export default class NodeElement extends ISelectableDraggableElement {

View File

@@ -46,6 +46,11 @@ export default class PinElement extends IElement {
return this.entity.PinId
}
/** @type {GuidEntity} */
GetPinIdValue() {
return this.GetPinId().value
}
/**
* @returns {String}
*/
@@ -92,14 +97,17 @@ export default class PinElement extends IElement {
return this.template.getLinkLocation(this)
}
/**
* @returns {NodeElement}
*/
getNodeElement() {
return this.closest("ueb-node")
}
getLinks() {
return this.entity.LinkedTo.map(pinReference =>
return this.entity.LinkedTo?.map(pinReference =>
pinReference
)
) ?? []
}
/**

View File

@@ -5,9 +5,6 @@ export default class FunctionReferenceEntity extends IEntity {
static attributes = {
MemberParent: ObjectReferenceEntity,
MemberName: ""
MemberName: "",
}
/** @type {ObjectReferenceEntity} */ MemberParent
/** @type {String} */ MemberName
}

View File

@@ -4,7 +4,7 @@ import IEntity from "./IEntity"
export default class GuidEntity extends IEntity {
static attributes = {
value: String
value: String,
}
static generateGuid(random = true) {
@@ -19,6 +19,10 @@ export default class GuidEntity extends IEntity {
return new GuidEntity({ value: guid })
}
valueOf() {
return this.value
}
toString() {
return this.value
}

View File

@@ -12,7 +12,7 @@ export default class IEntity {
const defineAllAttributes = (prefix, target, properties) => {
let fullKey = prefix.concat("")
const last = fullKey.length - 1
for (let property in properties) {
for (let property of Object.getOwnPropertyNames(properties)) {
fullKey[last] = property
// Not instanceof because all objects are instenceof Object, exact match needed
if (properties[property]?.constructor === Object) {
@@ -22,7 +22,7 @@ export default class IEntity {
}
/*
* The value can either be:
* - Array: can contain multiple values, its property is assigned multiple times like (X=1, X=4, X="Hello World")
* - 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.
@@ -35,6 +35,7 @@ export default class IEntity {
let defaultValue = properties[property]
if (defaultValue instanceof TypeInitialization) {
if (!defaultValue.showDefault) {
target[property] = undefined // to preserve the order
continue
}
defaultValue = defaultValue.value

View File

@@ -3,13 +3,13 @@ import IEntity from "./IEntity"
export default class IntegerEntity extends IEntity {
static attributes = {
value: Number
value: Number,
}
constructor(options = {}) {
if (options.constructor === Number || options.constructor === String) {
if (options.constructor == Number || options.constructor == String) {
options = {
value: options
value: options,
}
}
super(options)

View File

@@ -6,6 +6,6 @@ export default class LocalizedTextEntity extends IEntity {
static attributes = {
namespace: String,
key: String,
value: String
value: String,
}
}

View File

@@ -22,11 +22,11 @@ export default class ObjectEntity extends IEntity {
NodeGuid: GuidEntity,
ErrorType: new TypeInitialization(IntegerEntity, false),
ErrorMsg: new TypeInitialization(String, false, ""),
CustomProperties: [PinEntity]
CustomProperties: [PinEntity],
}
/**
* @returns {String} The name of the node
* @returns {String}
*/
getName() {
return this.Name

View File

@@ -4,6 +4,6 @@ export default class ObjectReferenceEntity extends IEntity {
static attributes = {
type: String,
path: String
path: String,
}
}

View File

@@ -3,7 +3,7 @@ import IEntity from "./IEntity"
export default class PathSymbolEntity extends IEntity {
static attributes = {
value: String
value: String,
}
toString() {

View File

@@ -71,13 +71,13 @@ export default class PinEntity extends IEntity {
linkTo(targetObjectName, targetPinEntity) {
/** @type {PinReferenceEntity[]} */
this.LinkedTo
const linkExists = this.LinkedTo.find(
const linkFound = this.LinkedTo.find(
/** @type {PinReferenceEntity} */
pinReferenceEntity => {
return pinReferenceEntity.objectName == targetObjectName
&& pinReferenceEntity.pinGuid == targetPinEntity.PinId
&& pinReferenceEntity.pinGuid.valueOf() == targetPinEntity.PinId.valueOf()
})
if (!linkExists) {
if (!linkFound) {
this.LinkedTo.push(new PinReferenceEntity({
objectName: targetObjectName,
pinGuid: targetPinEntity.PinId

View File

@@ -6,6 +6,6 @@ export default class PinReferenceEntity extends IEntity {
static attributes = {
objectName: PathSymbolEntity,
pinGuid: GuidEntity
pinGuid: GuidEntity,
}
}

View File

@@ -6,6 +6,6 @@ export default class VariableReferenceEntity extends IEntity {
static attributes = {
MemberName: String,
MemberGuid: GuidEntity,
bSelfContext: false
bSelfContext: false,
}
}

View File

@@ -46,6 +46,7 @@ export default class IMouseClickDrag extends IPointing {
}
// Attach the listeners
movementListenedElement.addEventListener("mousemove", self.#mouseStartedMovingHandler)
document.addEventListener("mouseup", self.#mouseUpHandler)
self.clickedPosition = self.locationFromEvent(e)
self.clicked(self.clickedPosition)
}
@@ -66,7 +67,6 @@ export default class IMouseClickDrag extends IPointing {
// Delegate from now on to self.#mouseMoveHandler
movementListenedElement.removeEventListener("mousemove", self.#mouseStartedMovingHandler)
movementListenedElement.addEventListener("mousemove", self.#mouseMoveHandler)
document.addEventListener("mouseup", self.#mouseUpHandler)
// Handler calls e.preventDefault() when it receives the event, this means dispatchEvent returns false
const dragEvent = self.getEvent(Configuration.trackingMouseEventName.begin)
self.#trackingMouse = this.target.dispatchEvent(dragEvent) == false
@@ -98,7 +98,9 @@ export default class IMouseClickDrag extends IPointing {
movementListenedElement.removeEventListener("mousemove", self.#mouseStartedMovingHandler)
movementListenedElement.removeEventListener("mousemove", self.#mouseMoveHandler)
document.removeEventListener("mouseup", self.#mouseUpHandler)
self.endDrag()
if (self.started) {
self.endDrag()
}
if (self.#trackingMouse) {
const dragEvent = self.getEvent(Configuration.trackingMouseEventName.end)
this.target.dispatchEvent(dragEvent)

View File

@@ -51,14 +51,14 @@ export default class ISerializer {
let result = ""
let fullKey = key.concat("")
const last = fullKey.length - 1
for (const property in object) {
for (const property of Object.getOwnPropertyNames(object)) {
fullKey[last] = property
const value = object[property]
if (object[property]?.constructor === Object) {
// Recursive call when finding an object
result += (result.length ? this.separator : "")
+ this.subWrite(fullKey, value)
} else if (this.showProperty(fullKey, value)) {
} else if (value !== undefined && this.showProperty(fullKey, value)) {
result += (result.length ? this.separator : "")
+ this.prefix
+ this.attributeKeyPrinter(fullKey)

View File

@@ -51,7 +51,7 @@ ${this.subWrite([], object)
+ object
.CustomProperties.map(pin => this.separator + this.prefix + "CustomProperties " + SerializerFactory.getSerializer(PinEntity).write(pin))
.join("")}
End Object`
End Object\n`
return result
}
}

View File

@@ -28,7 +28,7 @@ export default function initializeSerializerFactory() {
)
SerializerFactory.registerSerializer(
LocalizedTextEntity,
new GeneralSerializer(v => `${LocalizedTextEntity.lookbehind}(${v})`, LocalizedTextEntity, "", ",", false, "", _ => "")
new GeneralSerializer(v => `${LocalizedTextEntity.lookbehind}(${v})`, LocalizedTextEntity, "", ", ", false, "", _ => "")
)
SerializerFactory.registerSerializer(
PinReferenceEntity,

View File

@@ -154,7 +154,7 @@ export default class LinkTemplate extends ITemplate {
c2 = Math.min(c2, LinkTemplate.c2DecreasingValue(width))
const d = Configuration.linkRightSVGPath(start, c1, c2)
// TODO move to CSS when Firefox will support property d and css will have enough functions
link.pathElement.setAttribute("d", d)
link.pathElement?.setAttribute("d", d)
}
/**

View File

@@ -1,7 +1,6 @@
import html from "./html"
import ITemplate from "./ITemplate"
import LinkElement from "../element/LinkElement"
import NodeElement from "../element/NodeElement"
import sanitizeText from "./sanitizeText"
import Utility from "../Utility"
@@ -41,15 +40,14 @@ export default class PinTemplate extends ITemplate {
"ueb-pin-" + sanitizeText(pin.getType())
)
pin.clickableElement = pin
window.customElements.whenDefined(NodeElement.tagName).then(pin.nodeElement = pin.closest(NodeElement.tagName))
window.customElements.whenDefined("ueb-node").then(pin.nodeElement = pin.closest("ueb-node"))
pin.getLinks().forEach(pinReference => {
const targetPin = pin.blueprint.getPin(pinReference.pinGuid)
const targetPin = pin.blueprint.getPin(pinReference)
if (targetPin) {
const [sourcePin, destinationPin] = pin.isOutput() ? [pin, targetPin] : [targetPin, pin]
pin.blueprint.addGraphElement(new LinkElement(sourcePin, destinationPin))
}
})
}
/**

View File

@@ -1,8 +1,8 @@
import { nodeResolve } from '@rollup/plugin-node-resolve'
import minifyHTML from 'rollup-plugin-minify-html-template-literals'
import commonjs from '@rollup/plugin-commonjs'
import { terser } from 'rollup-plugin-terser'
import copy from 'rollup-plugin-copy'
import { nodeResolve } from "@rollup/plugin-node-resolve"
import minifyHTML from "rollup-plugin-minify-html-template-literals"
import commonjs from "@rollup/plugin-commonjs"
import { terser } from "rollup-plugin-terser"
import copy from "rollup-plugin-copy"
export default {
input: 'js/export.js',