diff --git a/cypress/e2e/parsing.cy.js b/cypress/e2e/parsing.cy.js index a837a5a..d8f453b 100644 --- a/cypress/e2e/parsing.cy.js +++ b/cypress/e2e/parsing.cy.js @@ -17,80 +17,92 @@ describe("Serializer", () => { context("Boolean", () => { let serializer = SerializerFactory.getSerializer(Boolean) - it("parses true", () => expect(serializer.deserialize("true")).to.be.true) - it("parses True", () => expect(serializer.deserialize("True")).to.be.true) - it("parses false", () => expect(serializer.deserialize("false")).to.be.false) - it("parses False", () => expect(serializer.deserialize("False")).to.be.false) + it("Parses true", () => expect(serializer.deserialize("true")).to.be.true) + it("Parses True", () => expect(serializer.deserialize("True")).to.be.true) + it("Parses false", () => expect(serializer.deserialize("false")).to.be.false) + it("Parses False", () => expect(serializer.deserialize("False")).to.be.false) }) context("Integer", () => { let serializer = SerializerFactory.getSerializer(IntegerEntity) - it("parses 0", () => expect(serializer.deserialize("0")) + it("Parses 0", () => expect(serializer.deserialize("0")) .to.be.instanceOf(IntegerEntity) .and.property("value").to.be.equal(0) ) - it("parses +0", () => expect(serializer.deserialize("+0")) + it("Parses +0", () => expect(serializer.deserialize("+0")) .to.be.instanceOf(IntegerEntity) .and.property("value").to.be.equal(0) ) - it("parses -0", () => expect(serializer.deserialize("-0")) + it("Parses -0", () => expect(serializer.deserialize("-0")) .to.be.instanceOf(IntegerEntity) .and.property("value").to.be.equal(0) ) - it("parses 99", () => expect(serializer.deserialize("99")) + it("Parses 99", () => expect(serializer.deserialize("99")) .to.be.instanceOf(IntegerEntity) .and.property("value").to.be.equal(99) ) - it("parses -8685", () => expect(serializer.deserialize("-8685")) + it("Parses -8685", () => expect(serializer.deserialize("-8685")) .to.be.instanceOf(IntegerEntity) .and.property("value").to.be.equal(-8685) ) - it("parses +555", () => expect(serializer.deserialize("+555")) + it("Parses +555", () => expect(serializer.deserialize("+555")) .to.be.instanceOf(IntegerEntity) .and.property("value").to.be.equal(555) ) - it("parses 1000000000", () => expect(serializer.deserialize("1000000000")) + it("Parses 1000000000", () => expect(serializer.deserialize("1000000000")) .to.be.instanceOf(IntegerEntity) .and.property("value").to.be.equal(1000000000) ) - it("throws when not an integer", () => expect(() => serializer.deserialize("1.2").value).to.throw()) + it("Throws when not an integer", () => expect(() => serializer.deserialize("1.2").value).to.throw()) }) context("Number", () => { let serializer = SerializerFactory.getSerializer(Number) - it("parses 0", () => expect(serializer.deserialize("0")).to.be.approximately(0, 0.00001)) - it("parses +0", () => expect(serializer.deserialize("+0")).to.be.approximately(0, 0.00001)) - it("parses -0", () => expect(serializer.deserialize("-0")).to.be.approximately(0, 0.00001)) - it("parses 5", () => expect(serializer.deserialize("5")).to.be.approximately(5, 0.00001)) - it("parses 0.05", () => expect(serializer.deserialize("0.05")).to.be.approximately(0.05, 0.00001)) - it("parses -999.666", () => expect(serializer.deserialize("-999.666")).to.be.approximately(-999.666, 0.001)) - it("parses +45.4545", () => expect(serializer.deserialize("+45.4545")).to.be.approximately(45.4545, 0.001)) - it("parses +1000000000", () => expect(serializer.deserialize("+1000000000")).to.be.approximately(1E9, 0.1)) - it("throws when not numeric", () => expect(() => serializer.deserialize("alpha")).to.throw()) + it("Parses 0", () => expect(serializer.deserialize("0")).to.be.approximately(0, 0.00001)) + it("Parses +0", () => expect(serializer.deserialize("+0")).to.be.approximately(0, 0.00001)) + it("Parses -0", () => expect(serializer.deserialize("-0")).to.be.approximately(0, 0.00001)) + it("Parses 5", () => expect(serializer.deserialize("5")).to.be.approximately(5, 0.00001)) + it("Parses 0.05", () => expect(serializer.deserialize("0.05")).to.be.approximately(0.05, 0.00001)) + it("Parses -999.666", () => expect(serializer.deserialize("-999.666")).to.be.approximately(-999.666, 0.001)) + it("Parses +45.4545", () => expect(serializer.deserialize("+45.4545")).to.be.approximately(45.4545, 0.001)) + it("Parses +1000000000", () => expect(serializer.deserialize("+1000000000")).to.be.approximately(1E9, 0.1)) + it("Throws when not numeric", () => expect(() => serializer.deserialize("alpha")).to.throw()) + }) + + context("String", () => { + let serializer = SerializerFactory.getSerializer(String) + + it('Parses ""', () => expect(serializer.deserialize('""')).to.be.equal("")) + it('Parses "hello"', () => expect(serializer.deserialize('"hello"')).to.be.equal("hello")) + it('Parses "hello world 123 - éèàò@ç ^ ^^^"', () => + expect(serializer.deserialize('"hello world 123 - éèàò@ç ^ ^^^"')) + .to.be.equal("hello world 123 - éèàò@ç ^ ^^^") + ) + it(String.raw`Parses "\""`, () => expect(serializer.deserialize(String.raw`"\""`)).to.be.equal('"')) }) context("KeyBindingEntity", () => { let serializer = SerializerFactory.getSerializer(KeyBindingEntity) - it("parses A", () => + it("Parses A", () => expect(serializer.deserialize("A")) .to.be.instanceOf(KeyBindingEntity) .and.to.deep.contain({ Key: { value: "A" } }) ) - it("parses (bCtrl=True,Key=A)", () => + it("Parses (bCtrl=True,Key=A)", () => expect(serializer.deserialize("(bCtrl=True,Key=A)")) .to.be.instanceOf(KeyBindingEntity) .and.to.deep.contain({ Key: { value: "A" }, bCtrl: true }) ) - it("parses (bCtrl=false,bShift=false,bCmd=false,bAlt=false,Key=X)", () => + it("Parses (bCtrl=false,bShift=false,bCmd=false,bAlt=false,Key=X)", () => expect(serializer.deserialize("(bCtrl=false,bShift=false,bCmd=true,bAlt=false,Key=X)")) .to.be.instanceOf(KeyBindingEntity) .and.to.deep.contain({ Key: { value: "X" }, bAlt: false, bCtrl: false, bCmd: true }) ) - it("parses spaces correctly", () => + it("Parses spaces correctly", () => expect(serializer.deserialize("( bCtrl= false \n, Key \n\n\n =Y ,bAlt=true )")) .to.be.instanceOf(KeyBindingEntity) .and.to.deep.contain({ Key: { value: "Y" }, bAlt: true, bCtrl: false }) @@ -100,30 +112,30 @@ describe("Serializer", () => { context("Guid", () => { let serializer = SerializerFactory.getSerializer(GuidEntity) - it("parses 0556a3ecabf648d0a5c07b2478e9dd32", () => + it("Parses 0556a3ecabf648d0a5c07b2478e9dd32", () => expect(serializer.deserialize("0556a3ecabf648d0a5c07b2478e9dd32")) .to.be.instanceOf(GuidEntity) .and.property("value").to.be.equal("0556a3ecabf648d0a5c07b2478e9dd32") ) - it("parses 64023BC344E0453DBB583FAC411489BC", () => + it("Parses 64023BC344E0453DBB583FAC411489BC", () => expect(serializer.deserialize("64023BC344E0453DBB583FAC411489BC")) .to.be.instanceOf(GuidEntity) .and.property("value").to.be.equal("64023BC344E0453DBB583FAC411489BC") ) - it("parses 6edC4a425ca948da8bC78bA52DED6C6C", () => + it("Parses 6edC4a425ca948da8bC78bA52DED6C6C", () => expect(serializer.deserialize("6edC4a425ca948da8bC78bA52DED6C6C")) .to.be.instanceOf(GuidEntity) .and.property("value").to.be.equal("6edC4a425ca948da8bC78bA52DED6C6C") ) - it("throws when finding space", () => + it("Throws when finding space", () => expect(() => serializer.deserialize("172087193 9B04362973544B3564FDB2C")) .to.throw() ) - it("throws when shorter by 1", () => + it("Throws when shorter by 1", () => expect(() => serializer.deserialize("E25F14F8F3E9441AB07153E7DA2BA2B")) .to.throw() ) - it("throws when longer by 1", () => + it("Throws when longer by 1", () => expect(() => serializer.deserialize("A78988B0097E48418C8CB87EC5A67ABF7")) .to.throw() ) @@ -132,21 +144,21 @@ describe("Serializer", () => { context("Vector", () => { let serializer = SerializerFactory.getSerializer(VectorEntity) - it("parses simple vector", () => expect(serializer.deserialize("(X=1,Y=2,Z=3.5)")) + it("Parses simple vector", () => expect(serializer.deserialize("(X=1,Y=2,Z=3.5)")) .to.be.deep.equal({ X: 1, Y: 2, Z: 3.5, }) ) - it("parses trailing comma", () => expect(serializer.deserialize("(X=10,Y=+20.88,Z=-30.54,)")) + it("Parses trailing comma", () => expect(serializer.deserialize("(X=10,Y=+20.88,Z=-30.54,)")) .to.be.deep.equal({ X: 10, Y: 20.88, Z: -30.54, }) ) - it("parses weird spaces", () => expect(serializer.deserialize(`( + it("Parses weird spaces", () => expect(serializer.deserialize(`( Z = -3.66 , X @@ -162,13 +174,13 @@ describe("Serializer", () => { Z: -3.66, }) ) - it("throws when unexpected types", () => expect(() => serializer.deserialize("(X=1,Y=\"2\",Z=3)")) + it("Throws when unexpected types", () => expect(() => serializer.deserialize("(X=1,Y=\"2\",Z=3)")) .to.throw() ) - it("throws when missing a key", () => expect(() => serializer.deserialize("(X=1,Z=3)")) + it("Throws when missing a key", () => expect(() => serializer.deserialize("(X=1,Z=3)")) .to.throw() ) - it("throws when finding unexpected keys", () => expect(() => serializer.deserialize("(X=1,Y=2,Unexpected=6,Z=3.5)")) + it("Throws when finding unexpected keys", () => expect(() => serializer.deserialize("(X=1,Y=2,Unexpected=6,Z=3.5)")) .to.throw() ) }) @@ -176,19 +188,19 @@ describe("Serializer", () => { context("Vector2D", () => { let serializer = SerializerFactory.getSerializer(Vector2DEntity) - it("parses simple vector", () => expect(serializer.deserialize("(X=78,Y=56.3)")) + it("Parses simple vector", () => expect(serializer.deserialize("(X=78,Y=56.3)")) .to.be.deep.equal({ X: 78, Y: 56.3, }) ) - it("parses trailing comma", () => expect(serializer.deserialize("(X=+4.5,Y=-8.88,)")) + it("Parses trailing comma", () => expect(serializer.deserialize("(X=+4.5,Y=-8.88,)")) .to.be.deep.equal({ X: 4.5, Y: -8.88, }) ) - it("parses weird spaces", () => expect(serializer.deserialize(`( + it("Parses weird spaces", () => expect(serializer.deserialize(`( Y = +93.004 , X @@ -199,13 +211,13 @@ describe("Serializer", () => { Y: 93.004, }) ) - it("throws on unexpected type", () => expect(() => serializer.deserialize("(X=1,Y=\"2\")")) + it("Throws on unexpected type", () => expect(() => serializer.deserialize("(X=1,Y=\"2\")")) .to.throw() ) - it("throws when missing a key", () => expect(() => serializer.deserialize("(X=1)")) + it("Throws when missing a key", () => expect(() => serializer.deserialize("(X=1)")) .to.throw() ) - it("throws when finding unexpected keys", () => expect(() => serializer.deserialize("(X=777, Y=555, Unexpected=6, HH=2)")) + it("Throws when finding unexpected keys", () => expect(() => serializer.deserialize("(X=777, Y=555, Unexpected=6, HH=2)")) .to.throw() ) }) @@ -220,28 +232,28 @@ describe("Serializer", () => { expect(result.toNumber()).to.be.equal(-1) expect(result.toHSVA()).to.be.deep.equal([0, 0, 1, 1]) }) - it("parses red color", () => { + it("Parses red color", () => { const result = serializer.deserialize("(R=1,G=0,B=0)") expect(result.toRGBA()).to.be.deep.equal([255, 0, 0, 255]) expect(result.toRGBAString()).to.be.equal("FF0000FF") expect(result.toNumber()).to.be.equal(-16776961) expect(result.toHSVA()).to.be.deep.equal([0, 1, 1, 1]) }) - it("parses simple color", () => { + it("Parses simple color", () => { const result = serializer.deserialize("(R=0.000000,G=0.660000,B=1.000000,A=1.000000)") expect(result.toRGBA()).to.be.deep.equal([0, 168, 255, 255]) expect(result.toRGBAString()).to.be.equal("00A8FFFF") expect(result.toNumber()).to.be.equal(11075583) expect(result.toHSVA()).to.be.deep.equal([0.55666666666666666666, 1, 1, 1]) }) - it("parses wrong order keys", () => { + it("Parses wrong order keys", () => { const result = serializer.deserialize("(B=0.04394509003266556,G=0.026789300067696642,A=0.83663232408635,R=0.6884158028074934,)") expect(result.toRGBA()).to.be.deep.equal([176, 7, 11, 213]) expect(result.toRGBAString()).to.be.equal("B0070BD5") expect(result.toNumber()).to.be.equal(-1341715499) expect(result.toHSVA().map(v => Utility.roundDecimals(v, 3))).to.be.deep.equal([0.996, 0.961, 0.688, 0.837]) }) - it("parses weird spaces", () => { + it("Parses weird spaces", () => { const result = serializer.deserialize(`( A = 0.327 , R=0.530 , G = 0.685 @@ -252,10 +264,10 @@ describe("Serializer", () => { expect(result.toNumber()).to.be.equal(-2018515373) expect(result.toHSVA().map(v => Utility.roundDecimals(v, 3))).to.be.deep.equal([0.597, 0.411, 0.9, 0.327]) }) - it("throws when missing an expected key", () => expect(() => serializer.deserialize("(R=0.000000,G=0.660000,A=1.000000)")) + it("Throws when missing an expected key", () => expect(() => serializer.deserialize("(R=0.000000,G=0.660000,A=1.000000)")) .to.throw() ) - it("throws when unexpected types", () => expect(() => serializer.deserialize("(R=0.000000,G=\"hello\",A=1.000000)")) + it("Throws when unexpected types", () => expect(() => serializer.deserialize("(R=0.000000,G=\"hello\",A=1.000000)")) .to.throw() ) }) diff --git a/cypress/e2e/utility.cy.js b/cypress/e2e/utility.cy.js index e181bc8..b81b6b4 100644 --- a/cypress/e2e/utility.cy.js +++ b/cypress/e2e/utility.cy.js @@ -144,5 +144,50 @@ describe("Utility class", () => { expect(Utility.range(0, -3)).to.be.deep.equal([0, -1, -2]) expect(Utility.range(7, -7, -4)).to.be.deep.equal([7, 3, -1, -5]) }) + it("String escaping methods test", () => { + expect(Utility.escapeString("")).to.be.equal("") + expect(Utility.unescapeString("")).to.be.equal("") + + expect(Utility.escapeString(String.raw`\"`)).to.be.equal(String.raw`\\\"`) + expect(Utility.unescapeString(String.raw`\"`)).to.be.equal('"') + + expect(Utility.escapeString(String.raw`Hello \"World\"`)).to.be.equal(String.raw`Hello \\\"World\\\"`) + expect(Utility.unescapeString(String.raw`Hello \"World\"`)).to.be.equal('Hello "World"') + + expect(Utility.escapeString(String.raw`Those "\\" are two backslash`)) + .to.be.equal(String.raw`Those \"\\\\\" are two backslash`) + expect(Utility.unescapeString(String.raw`Those "\\" are two backslash`)) + .to.be.equal(String.raw`Those "\" are two backslash`) + + expect(Utility.escapeString(String.raw`Alpha\Beta`)).to.be.equal(String.raw`Alpha\\Beta`) + expect(Utility.unescapeString(String.raw`Alpha\Beta`)).to.be.equal(String.raw`Alpha\Beta`) + + expect(Utility.escapeString(String.raw`Alpha\\Beta`)).to.be.equal(String.raw`Alpha\\\\Beta`) + expect(Utility.unescapeString(String.raw`Alpha\\Beta`)).to.be.equal(String.raw`Alpha\Beta`) + + expect(Utility.escapeString(String.raw`Alpha\\\Beta`)).to.be.equal(String.raw`Alpha\\\\\\Beta`) + expect(Utility.unescapeString(String.raw`Alpha\\\Beta`)).to.be.equal(String.raw`Alpha\\Beta`) + + expect(Utility.escapeString(String.raw`Alpha\\\\Beta`)).to.be.equal(String.raw`Alpha\\\\\\\\Beta`) + expect(Utility.unescapeString(String.raw`Alpha\\\\Beta`)).to.be.equal(String.raw`Alpha\\Beta`) + + expect(Utility.escapeString(String.raw`Alpha\\\\\Beta`)).to.be.equal(String.raw`Alpha\\\\\\\\\\Beta`) + expect(Utility.unescapeString(String.raw`Alpha\\\\\Beta`)).to.be.equal(String.raw`Alpha\\\Beta`) + + expect(Utility.escapeString(String.raw`Alpha\\\\\\Beta`)).to.be.equal(String.raw`Alpha\\\\\\\\\\\\Beta`) + expect(Utility.unescapeString(String.raw`Alpha\\\\\\Beta`)).to.be.equal(String.raw`Alpha\\\Beta`) + + expect(Utility.escapeString(String.raw`Alpha \"Beta\"`)).to.be.equal(String.raw`Alpha \\\"Beta\\\"`) + expect(Utility.unescapeString(String.raw`Alpha \"Beta\"`)).to.be.equal(String.raw`Alpha "Beta"`) + + expect(Utility.escapeString(String.raw`Alpha \\"Beta\\"`)).to.be.equal(String.raw`Alpha \\\\\"Beta\\\\\"`) + expect(Utility.unescapeString(String.raw`Alpha \\"Beta\\"`)).to.be.equal(String.raw`Alpha \"Beta\"`) + + expect(Utility.escapeString('Alpha\nBravo\\Charlie\n"Delta"')) + .to.equal(String.raw`Alpha\nBravo\\Charlie\n\"Delta\"`) + expect(Utility.unescapeString(String.raw`Alpha\nBravo\\Charlie\n\"Delta\"`)).to.equal( + `Alpha\nBravo\\Charlie\n"Delta"` + ) + }) }) }) diff --git a/dist/ueblueprint.js b/dist/ueblueprint.js index 8d035ac..8e11675 100755 --- a/dist/ueblueprint.js +++ b/dist/ueblueprint.js @@ -42,6 +42,7 @@ class Configuration { static colorDragEventName = "ueb-color-drag" static colorPickEventName = "ueb-color-pick" static colorWindowEventName = "ueb-color-window" + static colorWindowName = "Color Picker" static defaultCommentHeight = 96 static defaultCommentWidth = 400 static deleteNodesKeyboardKey = "Delete" @@ -183,7 +184,9 @@ class Configuration { end: "ueb-tracking-mouse-end", } static windowApplyEventName = "ueb-window-apply" + static windowApplyButtonText = "OK" static windowCancelEventName = "ueb-window-cancel" + static windowCancelButtonText = "Cancel" static windowCloseEventName = "ueb-window-close" static ModifierKeys = [ "Ctrl", @@ -711,17 +714,21 @@ class Utility { } /** @param {String} value */ - static escapeString(value, input = false) { + static escapeString(value) { return value + .replaceAll('\\', '\\\\') // Escape \ .replaceAll('"', '\\"') // Escape " .replaceAll("\n", "\\n") // Replace newline with \n + .replaceAll("\t", "\\t") // Replace tab with \t } /** @param {String} value */ - static unescapeString(value, input = false) { + static unescapeString(value) { return value - .replaceAll('\\"', '"') - .replaceAll("\\n", "\n") + .replaceAll("\\t", "\t") // Replace tab with \t + .replaceAll("\\n", "\n") // Replace newline with \n + .replaceAll('\\"', '"') // Escape " + .replaceAll('\\\\', '\\') // Escape \ } /** @param {String} value */ @@ -3097,6 +3104,20 @@ let P = Parsimmon; class Grammar { + static Regex = { + ByteInteger: /0*(?:25[0-5]|2[0-4]\d|1?\d?\d|)(?!\d)/, // A integer between 0 and 255 + HexDigit: /[0-9a-fA-F]/, + InlineOptWhitespace: /[^\S\n]*/, + InlineWhitespace: /[^\S\n]+/, + InsideString: /(?:[^"\\]|\\.)*/, + Integer: /[\-\+]?\d+/, + MultilineWhitespace: /\s*\n\s*/, + Number: /[-\+]?\d+(?:\.\d+)?/, + RealUnit: /^\+?(?:0(?:\.\d+)?|1(?:\.0+)?)(?![\.\d])/, // A number between 0 and 1 included + Symbol: /[a-zA-Z_]\w*/, + Word: /[a-zA-Z_]+/, + } + /* --- Factory --- */ /** @param {Grammar} r */ @@ -3149,6 +3170,8 @@ class Grammar { return r.Integer case InvariantTextEntity: return r.InvariantText + case KeyBindingEntity: + return r.KeyBinding case LinearColorEntity: return r.LinearColor case LocalizedTextEntity: @@ -3275,56 +3298,37 @@ class Grammar { /* --- General --- */ /** @param {Grammar} r */ - InlineWhitespace = r => P.regex(/[^\S\n]+/).desc("single line whitespace") + Null = r => P.regex(new RegExp(String.raw`\(${Grammar.Regex.InlineOptWhitespace.source}\)`)).map(() => null).desc("null: ()") /** @param {Grammar} r */ - InlineOptWhitespace = r => P.regex(/[^\S\n]*/).desc("single line optional whitespace") - - /** @param {Grammar} r */ - MultilineWhitespace = r => P.regex(/[^\S\n]*\n\s*/).desc("whitespace with at least a newline") - - /** @param {Grammar} r */ - Null = r => P.seq(P.string("("), r.InlineOptWhitespace, P.string(")")).map(() => null).desc("null: ()") - - /** @param {Grammar} r */ - Boolean = r => P.alt( - P.string("True"), - P.string("true"), - P.string("False"), - P.string("false"), - ).map(v => v.toLocaleLowerCase() === "true" ? true : false) + Boolean = r => P.regex(/true|false/i).map(v => v.toLocaleLowerCase() === "true" ? true : false) .desc("either True or False") /** @param {Grammar} r */ - HexDigit = r => P.regex(/[0-9a-fA-f]/).desc("hexadecimal digit") + Number = r => P.regex(Grammar.Regex.Number).map(Number).desc("a number") /** @param {Grammar} r */ - Number = r => P.regex(/[-\+]?[0-9]+(?:\.[0-9]+)?/).map(Number).desc("a number") + BigInt = r => P.regex(Grammar.Regex.Integer).map(v => BigInt(v)).desc("a big integer") /** @param {Grammar} r */ - BigInt = r => P.regex(/[\-\+]?[0-9]+/).map(v => BigInt(v)).desc("a big integer") - - /** @param {Grammar} r */ - RealNumber = r => P.regex(/[-\+]?[0-9]+\.[0-9]+/).map(Number).desc("a number written as real") - - /** @param {Grammar} r */ - RealUnit = r => P.regex(/\+?[0-9]+(?:\.[0-9]+)?/).map(Number).assert(v => v >= 0 && v <= 1).desc("a number between 0 and 1") + RealUnit = r => P.regex(Grammar.Regex.RealUnit).map(Number).desc("a number between 0 and 1") /** @param {Grammar} r */ NaturalNumber = r => P.regex(/0|[1-9]\d*/).map(Number).desc("a natural number") /** @param {Grammar} r */ - ColorNumber = r => r.NaturalNumber.assert(n => 0 <= n && n < 256, "the color must be between 0 and 256 excluded") + ColorNumber = r => P.regexp(Grammar.Regex.ByteInteger).desc("a number between 0 and 255") /** @param {Grammar} r */ - Word = r => P.regex(/[a-zA-Z_]+/).desc("a word") + Word = r => P.regexp(Grammar.Regex.Word).desc("a word") /** @param {Grammar} r */ - String = r => P.regex(/(?:[^"\\]|\\.)*/).wrap(P.string('"'), P.string('"')).map(Utility.unescapeString) + String = r => P.regexp(new RegExp(`"(${Grammar.Regex.InsideString.source})"`), 1).map(Utility.unescapeString) .desc('string (with possibility to escape the quote using \")') /** @param {Grammar} r */ - AttributeName = r => r.Word.sepBy1(P.string(".")).tieWith(".").desc("dot-separated words") + AttributeName = r => P.regexp(new RegExp(String.raw`(?:(?:^|(? r.BigInt.map(v => new Integer64Entity(v)).desc("an integer64") /** @param {Grammar} r */ - Integer = r => P.regex(/[\-\+]?[0-9]+/).map(v => new IntegerEntity(v)).desc("an integer") + Integer = r => P.regex(Grammar.Regex.Integer).map(v => new IntegerEntity(v)).desc("an integer") /** @param {Grammar} r */ - Byte = r => P.regex(/\+?[0-9]+/) - .map(v => parseInt(v)) - .assert(v => v >= 0 && v < 1 << 8) - .map(v => new ByteEntity(v)) - .desc("a Byte") + Byte = r => P.regex(Grammar.Regex.ByteInteger).map(v => new ByteEntity(parseInt(v))).desc("a Byte") /** @param {Grammar} r */ - Guid = r => r.HexDigit.times(32).tie().map(v => new GuidEntity({ value: v })).desc("32 digit hexadecimal value") + Guid = r => P.regexp(new RegExp(`${Grammar.Regex.HexDigit.source}{32}`)) + .map(v => new GuidEntity({ value: v })) + .desc("32 digit hexadecimal value") /** @param {Grammar} r */ Identifier = r => P.regex(/\w+/).map(v => new IdentifierEntity(v)) /** @param {Grammar} r */ - PathSymbol = r => P.regex(/[0-9\w]+/).map(v => new PathSymbolEntity({ value: v })) + PathSymbol = r => P.regex(/\w+/).map(v => new PathSymbolEntity({ value: v })) /** @param {Grammar} r */ - PathSymbolOptSpaces = r => P.regex(/[0-9\w]+(?: [0-9\w]+)+|[0-9\w]+/).map(v => new PathSymbolEntity({ value: v })) + PathSymbolOptSpaces = r => P.regex(/(?:(?:^|(? new PathSymbolEntity({ value: v })) /** @param {Grammar} r */ - Symbol = r => P.regex(/[a-zA-Z_]\w*/).map(v => new SymbolEntity({ value: v })) + Symbol = r => P.regex(Grammar.Regex.Symbol).map(v => new SymbolEntity({ value: v })) /** @param {Grammar} r */ - Enum = r => P.regex(/[a-zA-Z_]\w*/).map(v => new EnumEntity({ value: v })) + Enum = r => P.regex(Grammar.Regex.Symbol).map(v => new EnumEntity({ value: v })) /** @param {Grammar} r */ ObjectReference = r => P.alt( @@ -3515,8 +3517,7 @@ class Grammar { /** @param {Grammar} r */ CustomProperties = r => - P.string("CustomProperties") - .then(P.whitespace) + P.regex(/CustomProperties\s+/) .then(r.Pin) .map(pin => entity => { /** @type {Array} */ @@ -3527,14 +3528,14 @@ class Grammar { /** @param {Grammar} r */ Object = r => P.seqMap( - P.seq(P.string("Begin"), P.whitespace, P.string("Object"), P.whitespace), + P.regexp(/Begin\s+Object\s+/), P .alt( r.CustomProperties, Grammar.createAttributeGrammar(r, ObjectEntity) ) .sepBy1(P.whitespace), - P.seq(r.MultilineWhitespace, P.string("End"), P.whitespace, P.string("Object")), + P.regexp(/\s+End\s+Object/), (_0, attributes, _2) => { let values = {}; attributes.forEach(attributeSetter => attributeSetter(values)); @@ -7394,13 +7395,6 @@ class Blueprint extends IElement { reflect: true, converter: Utility.booleanConverter, }, - resting: { - type: Boolean, - attribute: "data-resting", - reflect: true, - converter: Utility.booleanConverter, - noAccessor: true, - }, focused: { type: Boolean, attribute: "data-focused", @@ -7462,12 +7456,6 @@ class Blueprint extends IElement { mousePosition = [0, 0] waitingExpandUpdate = false - get resting() { - return !this.selecting && !this.scrolling - } - set resting(value) { - } - constructor() { super(); this.selecting = false; @@ -8806,15 +8794,19 @@ class ColorPickerWindowTemplate extends WindowTemplate {
` } renderWindowName() { - return y`Color Picker` + return y`${Configuration.colorWindowName}` } } diff --git a/dist/ueblueprint.min.js b/dist/ueblueprint.min.js index da282ce..0bf7ad1 100644 --- a/dist/ueblueprint.min.js +++ b/dist/ueblueprint.min.js @@ -14,13 +14,13 @@ const e=window,t=e.ShadowRoot&&(void 0===e.ShadyCSS||e.ShadyCSS.nativeShadow)&&" * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause */ -var b;g.finalized=!0,g.elementProperties=new Map,g.elementStyles=[],g.shadowRootOptions={mode:"open"},null==h||h({ReactiveElement:g}),(null!==(o=l.reactiveElementVersions)&&void 0!==o?o:l.reactiveElementVersions=[]).push("1.4.2");const v=window,f=v.trustedTypes,y=f?f.createPolicy("lit-html",{createHTML:e=>e}):void 0,w=`lit$${(Math.random()+"").slice(9)}$`,E="?"+w,C=`<${E}>`,S=document,P=(e="")=>S.createComment(e),x=e=>null===e||"object"!=typeof e&&"function"!=typeof e,k=Array.isArray,L=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,N=/-->/g,T=/>/g,A=RegExp(">|[ \t\n\f\r](?:([^\\s\"'>=/]+)([ \t\n\f\r]*=[ \t\n\f\r]*(?:[^ \t\n\f\r\"'`<>=]|(\"|')|))|$)","g"),M=/'/g,D=/"/g,B=/^(?:script|style|textarea|title)$/i,H=(e=>(t,...i)=>({_$litType$:e,strings:t,values:i}))(1),$=Symbol.for("lit-noChange"),O=Symbol.for("lit-nothing"),V=new WeakMap,z=S.createTreeWalker(S,129,null,!1),I=(e,t)=>{const i=e.length-1,n=[];let s,r=2===t?"":"");if(!Array.isArray(e)||!e.hasOwnProperty("raw"))throw Error("invalid template strings array");return[void 0!==y?y.createHTML(o):o,n]};class R{constructor({strings:e,_$litType$:t},i){let n;this.parts=[];let s=0,r=0;const a=e.length-1,o=this.parts,[l,u]=I(e,t);if(this.el=R.createElement(l,i),z.currentNode=this.el.content,2===t){const e=this.el.content,t=e.firstChild;t.remove(),e.append(...t.childNodes)}for(;null!==(n=z.nextNode())&&o.length0){n.textContent=f?f.emptyScript:"";for(let i=0;i