mirror of
https://github.com/barsdeveloper/ueblueprint.git
synced 2026-02-04 08:17:41 +08:00
String encode/decode
This commit is contained in:
62
dist/ueblueprint.js
vendored
62
dist/ueblueprint.js
vendored
@@ -431,22 +431,41 @@ class Utility {
|
|||||||
/**
|
/**
|
||||||
* @param {String} value
|
* @param {String} value
|
||||||
*/
|
*/
|
||||||
static sanitizeString(value, input = false) {
|
static encodeInputString(value) {
|
||||||
return value
|
return value
|
||||||
.replace(/\n$/, "") // Remove trailing newline
|
.replace(/\n$/, "") // Remove trailing newline
|
||||||
.replaceAll("\u00A0", " ") // Replace special space symbol
|
.replaceAll("\u00A0", " ") // Replace special space symbol
|
||||||
|
.replaceAll("\r\n", String.raw`\r\n`) // Replace newline with \r\n
|
||||||
.replaceAll("\n", String.raw`\r\n`) // Replace newline with \r\n
|
.replaceAll("\n", String.raw`\r\n`) // Replace newline with \r\n
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {String} value
|
* @param {String} value
|
||||||
*/
|
*/
|
||||||
static renderInputString(value) {
|
static decodeInputString(value) {
|
||||||
return value
|
return value
|
||||||
.replaceAll(" ", "\u00A0") // Replace special space symbol
|
.replaceAll(" ", "\u00A0") // Replace special space symbol
|
||||||
.replaceAll(String.raw`\r\n`, "<br />\n") // Replace newline with \r\n
|
.replaceAll(String.raw`\r\n`, "<br />\n") // Replace newline with \r\n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {String} value
|
||||||
|
*/
|
||||||
|
static encodeString(value, input = false) {
|
||||||
|
return value
|
||||||
|
.replaceAll("\u00A0", " ") // Replace special space symbol
|
||||||
|
.replaceAll("\n", String.raw`\n`) // Replace newline with \n
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {String} value
|
||||||
|
*/
|
||||||
|
static decodeString(value, input = false) {
|
||||||
|
return value
|
||||||
|
.replaceAll(" ", "\u00A0") // Replace special space symbol
|
||||||
|
.replaceAll(String.raw`\n`, "\n") // Replace newline with \n
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {String} value
|
* @param {String} value
|
||||||
*/
|
*/
|
||||||
@@ -1263,7 +1282,7 @@ class ISerializer {
|
|||||||
this.attributeKeyPrinter = attributeKeyPrinter ?? (k => k.join("."));
|
this.attributeKeyPrinter = attributeKeyPrinter ?? (k => k.join("."));
|
||||||
}
|
}
|
||||||
|
|
||||||
writeValue(value) {
|
writeValue(value, fullKey = undefined) {
|
||||||
if (value === null) {
|
if (value === null) {
|
||||||
return "()"
|
return "()"
|
||||||
}
|
}
|
||||||
@@ -1271,13 +1290,13 @@ class ISerializer {
|
|||||||
// This is an exact match (and not instanceof) to hit also primitive types (by accessing value.constructor they are converted to objects automatically)
|
// This is an exact match (and not instanceof) to hit also primitive types (by accessing value.constructor they are converted to objects automatically)
|
||||||
switch (value?.constructor) {
|
switch (value?.constructor) {
|
||||||
case Function:
|
case Function:
|
||||||
return this.writeValue(value())
|
return this.writeValue(value(), fullKey)
|
||||||
case Boolean:
|
case Boolean:
|
||||||
return Utility.FirstCapital(value.toString())
|
return Utility.FirstCapital(value.toString())
|
||||||
case Number:
|
case Number:
|
||||||
return value.toString()
|
return value.toString()
|
||||||
case String:
|
case String:
|
||||||
return `"${value}"`
|
return `"${Utility.encodeString(value)}"`
|
||||||
}
|
}
|
||||||
if (value instanceof Array) {
|
if (value instanceof Array) {
|
||||||
return `(${value.map(v => serialize(v) + ",").join("")})`
|
return `(${value.map(v => serialize(v) + ",").join("")})`
|
||||||
@@ -1308,7 +1327,7 @@ class ISerializer {
|
|||||||
+ this.prefix
|
+ this.prefix
|
||||||
+ this.attributeKeyPrinter(fullKey)
|
+ this.attributeKeyPrinter(fullKey)
|
||||||
+ this.attributeValueConjunctionSign
|
+ this.attributeValueConjunctionSign
|
||||||
+ this.writeValue(value);
|
+ this.writeValue(value, fullKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.trailingSeparator && result.length && fullKey.length === 1) {
|
if (this.trailingSeparator && result.length && fullKey.length === 1) {
|
||||||
@@ -1371,7 +1390,7 @@ class ObjectSerializer extends ISerializer {
|
|||||||
* @param {ObjectEntity} object
|
* @param {ObjectEntity} object
|
||||||
*/
|
*/
|
||||||
write(object) {
|
write(object) {
|
||||||
let result = `Begin Object Class=${object.Class.path} Name=${this.writeValue(object.Name)}
|
let result = `Begin Object Class=${object.Class.path} Name=${this.writeValue(object.Name, "Name")}
|
||||||
${this.subWrite([], object)
|
${this.subWrite([], object)
|
||||||
+ object
|
+ object
|
||||||
.CustomProperties.map(pin =>
|
.CustomProperties.map(pin =>
|
||||||
@@ -3007,7 +3026,7 @@ class IInputPinTemplate extends PinTemplate {
|
|||||||
* @param {PinElement} pin
|
* @param {PinElement} pin
|
||||||
*/
|
*/
|
||||||
getInput(pin) {
|
getInput(pin) {
|
||||||
return Utility.sanitizeString(
|
return Utility.encodeInputString(
|
||||||
/** @type {HTMLElement} */(pin.querySelector(".ueb-pin-input-content")).innerText
|
/** @type {HTMLElement} */(pin.querySelector(".ueb-pin-input-content")).innerText
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -3027,7 +3046,7 @@ class IInputPinTemplate extends PinTemplate {
|
|||||||
return html`
|
return html`
|
||||||
<div class="ueb-pin-input">
|
<div class="ueb-pin-input">
|
||||||
<div class="ueb-pin-input-content" role="textbox" contenteditable="true">
|
<div class="ueb-pin-input-content" role="textbox" contenteditable="true">
|
||||||
${Utility.renderInputString(sanitizeText(pin.entity.getDefaultValue()))}
|
${Utility.decodeInputString(sanitizeText(pin.entity.getDefaultValue()))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
@@ -3464,7 +3483,11 @@ class NodeElement extends ISelectableDraggableElement {
|
|||||||
super.setLocation([this.entity.NodePosX.value, this.entity.NodePosY.value]);
|
super.setLocation([this.entity.NodePosX.value, this.entity.NodePosY.value]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {String} str
|
||||||
|
*/
|
||||||
static fromSerializedObject(str) {
|
static fromSerializedObject(str) {
|
||||||
|
str = str.trim();
|
||||||
let entity = SerializerFactory.getSerializer(ObjectEntity).read(str);
|
let entity = SerializerFactory.getSerializer(ObjectEntity).read(str);
|
||||||
return new NodeElement(entity)
|
return new NodeElement(entity)
|
||||||
}
|
}
|
||||||
@@ -4735,6 +4758,23 @@ class CustomSerializer extends GeneralSerializer {
|
|||||||
|
|
||||||
// @ts-check
|
// @ts-check
|
||||||
|
|
||||||
|
class PinSerializer extends GeneralSerializer {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super(v => `${PinEntity.lookbehind} (${v})`, PinEntity, "", ",", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
writeValue(value, fullKey) {
|
||||||
|
if (value?.constructor === String && fullKey == "DefaultValue") {
|
||||||
|
// @ts-expect-error
|
||||||
|
return `"${Utility.encodeInputString(value)}"`
|
||||||
|
}
|
||||||
|
return super.writeValue(value, fullKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-check
|
||||||
|
|
||||||
class ToStringSerializer extends GeneralSerializer {
|
class ToStringSerializer extends GeneralSerializer {
|
||||||
|
|
||||||
constructor(entityType) {
|
constructor(entityType) {
|
||||||
@@ -4757,8 +4797,8 @@ function initializeSerializerFactory() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
SerializerFactory.registerSerializer(
|
SerializerFactory.registerSerializer(
|
||||||
PinEntity,
|
PinEntity,
|
||||||
new GeneralSerializer(v => `${PinEntity.lookbehind} (${v})`, PinEntity, "", ",", true)
|
new PinSerializer()
|
||||||
);
|
);
|
||||||
|
|
||||||
SerializerFactory.registerSerializer(
|
SerializerFactory.registerSerializer(
|
||||||
|
|||||||
@@ -149,22 +149,41 @@ export default class Utility {
|
|||||||
/**
|
/**
|
||||||
* @param {String} value
|
* @param {String} value
|
||||||
*/
|
*/
|
||||||
static sanitizeString(value, input = false) {
|
static encodeInputString(value) {
|
||||||
return value
|
return value
|
||||||
.replace(/\n$/, "") // Remove trailing newline
|
.replace(/\n$/, "") // Remove trailing newline
|
||||||
.replaceAll("\u00A0", " ") // Replace special space symbol
|
.replaceAll("\u00A0", " ") // Replace special space symbol
|
||||||
|
.replaceAll("\r\n", String.raw`\r\n`) // Replace newline with \r\n
|
||||||
.replaceAll("\n", String.raw`\r\n`) // Replace newline with \r\n
|
.replaceAll("\n", String.raw`\r\n`) // Replace newline with \r\n
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {String} value
|
* @param {String} value
|
||||||
*/
|
*/
|
||||||
static renderInputString(value) {
|
static decodeInputString(value) {
|
||||||
return value
|
return value
|
||||||
.replaceAll(" ", "\u00A0") // Replace special space symbol
|
.replaceAll(" ", "\u00A0") // Replace special space symbol
|
||||||
.replaceAll(String.raw`\r\n`, "<br />\n") // Replace newline with \r\n
|
.replaceAll(String.raw`\r\n`, "<br />\n") // Replace newline with \r\n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {String} value
|
||||||
|
*/
|
||||||
|
static encodeString(value, input = false) {
|
||||||
|
return value
|
||||||
|
.replaceAll("\u00A0", " ") // Replace special space symbol
|
||||||
|
.replaceAll("\n", String.raw`\n`) // Replace newline with \n
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {String} value
|
||||||
|
*/
|
||||||
|
static decodeString(value, input = false) {
|
||||||
|
return value
|
||||||
|
.replaceAll(" ", "\u00A0") // Replace special space symbol
|
||||||
|
.replaceAll(String.raw`\n`, "\n") // Replace newline with \n
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {String} value
|
* @param {String} value
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -23,7 +23,11 @@ export default class NodeElement extends ISelectableDraggableElement {
|
|||||||
super.setLocation([this.entity.NodePosX.value, this.entity.NodePosY.value])
|
super.setLocation([this.entity.NodePosX.value, this.entity.NodePosY.value])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {String} str
|
||||||
|
*/
|
||||||
static fromSerializedObject(str) {
|
static fromSerializedObject(str) {
|
||||||
|
str = str.trim()
|
||||||
let entity = SerializerFactory.getSerializer(ObjectEntity).read(str)
|
let entity = SerializerFactory.getSerializer(ObjectEntity).read(str)
|
||||||
return new NodeElement(entity)
|
return new NodeElement(entity)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,10 @@
|
|||||||
|
|
||||||
import Blueprint from "./Blueprint"
|
import Blueprint from "./Blueprint"
|
||||||
import Configuration from "./Configuration"
|
import Configuration from "./Configuration"
|
||||||
|
import initializeSerializerFactory from "./serialization/initializeSerializerFactory"
|
||||||
import LinkElement from "./element/LinkElement"
|
import LinkElement from "./element/LinkElement"
|
||||||
import NodeElement from "./element/NodeElement"
|
import NodeElement from "./element/NodeElement"
|
||||||
|
|
||||||
import initializeSerializerFactory from "./serialization/initializeSerializerFactory"
|
|
||||||
|
|
||||||
initializeSerializerFactory()
|
initializeSerializerFactory()
|
||||||
|
|
||||||
export { Blueprint as Blueprint, NodeElement as NodeElement, LinkElement as LinkElement, Configuration as Configuration }
|
export { Blueprint as Blueprint, NodeElement as NodeElement, LinkElement as LinkElement, Configuration as Configuration }
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export default class ISerializer {
|
|||||||
this.attributeKeyPrinter = attributeKeyPrinter ?? (k => k.join("."))
|
this.attributeKeyPrinter = attributeKeyPrinter ?? (k => k.join("."))
|
||||||
}
|
}
|
||||||
|
|
||||||
writeValue(value) {
|
writeValue(value, fullKey = undefined) {
|
||||||
if (value === null) {
|
if (value === null) {
|
||||||
return "()"
|
return "()"
|
||||||
}
|
}
|
||||||
@@ -28,13 +28,13 @@ export default class ISerializer {
|
|||||||
// This is an exact match (and not instanceof) to hit also primitive types (by accessing value.constructor they are converted to objects automatically)
|
// This is an exact match (and not instanceof) to hit also primitive types (by accessing value.constructor they are converted to objects automatically)
|
||||||
switch (value?.constructor) {
|
switch (value?.constructor) {
|
||||||
case Function:
|
case Function:
|
||||||
return this.writeValue(value())
|
return this.writeValue(value(), fullKey)
|
||||||
case Boolean:
|
case Boolean:
|
||||||
return Utility.FirstCapital(value.toString())
|
return Utility.FirstCapital(value.toString())
|
||||||
case Number:
|
case Number:
|
||||||
return value.toString()
|
return value.toString()
|
||||||
case String:
|
case String:
|
||||||
return `"${value}"`
|
return `"${Utility.encodeString(value)}"`
|
||||||
}
|
}
|
||||||
if (value instanceof Array) {
|
if (value instanceof Array) {
|
||||||
return `(${value.map(v => serialize(v) + ",").join("")})`
|
return `(${value.map(v => serialize(v) + ",").join("")})`
|
||||||
@@ -65,7 +65,7 @@ export default class ISerializer {
|
|||||||
+ this.prefix
|
+ this.prefix
|
||||||
+ this.attributeKeyPrinter(fullKey)
|
+ this.attributeKeyPrinter(fullKey)
|
||||||
+ this.attributeValueConjunctionSign
|
+ this.attributeValueConjunctionSign
|
||||||
+ this.writeValue(value)
|
+ this.writeValue(value, fullKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.trailingSeparator && result.length && fullKey.length === 1) {
|
if (this.trailingSeparator && result.length && fullKey.length === 1) {
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export default class ObjectSerializer extends ISerializer {
|
|||||||
* @param {ObjectEntity} object
|
* @param {ObjectEntity} object
|
||||||
*/
|
*/
|
||||||
write(object) {
|
write(object) {
|
||||||
let result = `Begin Object Class=${object.Class.path} Name=${this.writeValue(object.Name)}
|
let result = `Begin Object Class=${object.Class.path} Name=${this.writeValue(object.Name, "Name")}
|
||||||
${this.subWrite([], object)
|
${this.subWrite([], object)
|
||||||
+ object
|
+ object
|
||||||
.CustomProperties.map(pin =>
|
.CustomProperties.map(pin =>
|
||||||
|
|||||||
20
js/serialization/PinSerializer.js
Executable file
20
js/serialization/PinSerializer.js
Executable file
@@ -0,0 +1,20 @@
|
|||||||
|
// @ts-check
|
||||||
|
|
||||||
|
import PinEntity from "../entity/PinEntity"
|
||||||
|
import Utility from "../Utility"
|
||||||
|
import GeneralSerializer from "./GeneralSerializer"
|
||||||
|
|
||||||
|
export default class PinSerializer extends GeneralSerializer {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super(v => `${PinEntity.lookbehind} (${v})`, PinEntity, "", ",", true)
|
||||||
|
}
|
||||||
|
|
||||||
|
writeValue(value, fullKey) {
|
||||||
|
if (value?.constructor === String && fullKey == "DefaultValue") {
|
||||||
|
// @ts-expect-error
|
||||||
|
return `"${Utility.encodeInputString(value)}"`
|
||||||
|
}
|
||||||
|
return super.writeValue(value, fullKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ import GeneralSerializer from "./GeneralSerializer"
|
|||||||
import GuidEntity from "../entity/GuidEntity"
|
import GuidEntity from "../entity/GuidEntity"
|
||||||
import IdentifierEntity from "../entity/IdentifierEntity"
|
import IdentifierEntity from "../entity/IdentifierEntity"
|
||||||
import IntegerEntity from "../entity/IntegerEntity"
|
import IntegerEntity from "../entity/IntegerEntity"
|
||||||
|
import InvariantTextEntity from "../entity/InvariantTextEntity"
|
||||||
import KeyBindingEntity from "../entity/KeyBindingEntity"
|
import KeyBindingEntity from "../entity/KeyBindingEntity"
|
||||||
import LocalizedTextEntity from "../entity/LocalizedTextEntity"
|
import LocalizedTextEntity from "../entity/LocalizedTextEntity"
|
||||||
import ObjectEntity from "../entity/ObjectEntity"
|
import ObjectEntity from "../entity/ObjectEntity"
|
||||||
@@ -14,9 +15,9 @@ import ObjectSerializer from "./ObjectSerializer"
|
|||||||
import PathSymbolEntity from "../entity/PathSymbolEntity"
|
import PathSymbolEntity from "../entity/PathSymbolEntity"
|
||||||
import PinEntity from "../entity/PinEntity"
|
import PinEntity from "../entity/PinEntity"
|
||||||
import PinReferenceEntity from "../entity/PinReferenceEntity"
|
import PinReferenceEntity from "../entity/PinReferenceEntity"
|
||||||
|
import PinSerializer from "./PinSerializer"
|
||||||
import SerializerFactory from "./SerializerFactory"
|
import SerializerFactory from "./SerializerFactory"
|
||||||
import ToStringSerializer from "./ToStringSerializer"
|
import ToStringSerializer from "./ToStringSerializer"
|
||||||
import InvariantTextEntity from "../entity/InvariantTextEntity"
|
|
||||||
|
|
||||||
export default function initializeSerializerFactory() {
|
export default function initializeSerializerFactory() {
|
||||||
|
|
||||||
@@ -26,8 +27,8 @@ export default function initializeSerializerFactory() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
SerializerFactory.registerSerializer(
|
SerializerFactory.registerSerializer(
|
||||||
PinEntity,
|
PinEntity,
|
||||||
new GeneralSerializer(v => `${PinEntity.lookbehind} (${v})`, PinEntity, "", ",", true)
|
new PinSerializer()
|
||||||
)
|
)
|
||||||
|
|
||||||
SerializerFactory.registerSerializer(
|
SerializerFactory.registerSerializer(
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ export default class IInputPinTemplate extends PinTemplate {
|
|||||||
* @param {PinElement} pin
|
* @param {PinElement} pin
|
||||||
*/
|
*/
|
||||||
getInput(pin) {
|
getInput(pin) {
|
||||||
return Utility.sanitizeString(
|
return Utility.encodeInputString(
|
||||||
/** @type {HTMLElement} */(pin.querySelector(".ueb-pin-input-content")).innerText
|
/** @type {HTMLElement} */(pin.querySelector(".ueb-pin-input-content")).innerText
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -85,7 +85,7 @@ export default class IInputPinTemplate extends PinTemplate {
|
|||||||
return html`
|
return html`
|
||||||
<div class="ueb-pin-input">
|
<div class="ueb-pin-input">
|
||||||
<div class="ueb-pin-input-content" role="textbox" contenteditable="true">
|
<div class="ueb-pin-input-content" role="textbox" contenteditable="true">
|
||||||
${Utility.renderInputString(sanitizeText(pin.entity.getDefaultValue()))}
|
${Utility.decodeInputString(sanitizeText(pin.entity.getDefaultValue()))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
|
|||||||
Reference in New Issue
Block a user