Git Product home page Git Product logo

Comments (3)

TomFrost avatar TomFrost commented on September 17, 2024

@erotavlas My apologies -- I deleted my last response because it was hugely inaccurate. Here's a better one:

Jexl v1 (which is receiving updates only for security issues and major bugs with existing features) only supports webpack (or similar) builds, as well as commonjs require(). The decision was made for Jexl v2 (see this branch) to drop prebuilt frontend versions of this library due to the sheer number of frameworks and formats to be supported, and the overwhelming popularity of build steps in the frontend development workflow.

So, my suggestion: If you foresee yourself using something like webpack or browserify, You're all set now and in the future. If not, I recommend a build step with Gulp, Grunt, or any of the other numerous options to compile any dependencies that don't explicitly expose a AMD compatibility, and wraps them with a function that provides it.

Sorry this isn't the best answer for your use case!

from jexl.

erotavlas avatar erotavlas commented on September 17, 2024

thanks for the quick reply.
I haven't yet worked with build tools like Grunt or Gulp yet. Just a little exposure to webpack, I was considering using that in my Dojo project. So I'm not sure I understand this part " compile any dependencies that don't explicitly expose a AMD compatibility, and wraps them with a function that provides it"

I did get it working as a module. what I did was rename all instances of 'require' inside the distribution (jexl.min.js) to 'jexlrequire', then incorporated this into my own module and returned the jexl object from that. seems to work ok so far.

What I was trying to do at first was incorporate the original source code into my project as is, so that later on I can build it along with the rest of my project. But do you think the way i did it is good enough?

define([

], function () {

    jexlrequire = function e(t, r, n) { function a(i, s) { if (!r[i]) { if (!t[i]) { var p = "function" == typeof jexlrequire && jexlrequire; if (!s && p) return p(i, !0); if (o) return o(i, !0); var u = new Error("Cannot find module '" + i + "'"); throw u.code = "MODULE_NOT_FOUND", u } var c = r[i] = { exports: {} }; t[i][0].call(c.exports, function (e) { var r = t[i][1][e]; return a(r ? r : e) }, c, c.exports, e, t, r, n) } return r[i].exports } for (var o = "function" == typeof jexlrequire && jexlrequire, i = 0; i < n.length; i++) a(n[i]); return a }({ 1: [function (e, t) { function r(e) { this._grammar = e } var n = /^-?(?:(?:[0-9]*\.[0-9]+)|[0-9]+)$/, a = /^[a-zA-Z_\$][a-zA-Z0-9_\$]*$/, o = /\\\\/, i = ["'(?:(?:\\\\')?[^'])*'", '"(?:(?:\\\\")?[^"])*"', "\\s+", "\\btrue\\b", "\\bfalse\\b"], s = ["\\b[a-zA-Z_\\$][a-zA-Z0-9_\\$]*\\b", "(?:(?:[0-9]*\\.[0-9]+)|[0-9]+)"], p = ["binaryOp", "unaryOp", "openParen", "openBracket", "question", "colon"]; r.prototype.getElements = function (e) { var t = this._getSplitRegex(); return e.split(t).filter(function (e) { return e }) }, r.prototype.getTokens = function (e) { for (var t = [], r = !1, n = 0; n < e.length; n++) this._isWhitespace(e[n]) ? t.length && (t[t.length - 1].raw += e[n]) : "-" === e[n] && this._isNegative(t) ? r = !0 : (r && (e[n] = "-" + e[n], r = !1), t.push(this._createToken(e[n]))); return r && t.push(this._createToken("-")), t }, r.prototype.tokenize = function (e) { var t = this.getElements(e); return this.getTokens(t) }, r.prototype._createToken = function (e) { var t = { type: "literal", value: e, raw: e }; if ('"' == e[0] || "'" == e[0]) t.value = this._unquote(e); else if (e.match(n)) t.value = parseFloat(e); else if ("true" === e || "false" === e) t.value = "true" === e; else if (this._grammar[e]) t.type = this._grammar[e].type; else { if (!e.match(a)) throw new Error("Invalid expression token: " + e); t.type = "identifier" } return t }, r.prototype._escapeRegExp = function (e) { return e = e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), e.match(a) && (e = "\\b" + e + "\\b"), e }, r.prototype._getSplitRegex = function () { if (!this._splitRegex) { var e = Object.keys(this._grammar); e = e.sort(function (e, t) { return t.length - e.length }).map(function (e) { return this._escapeRegExp(e) }, this), this._splitRegex = new RegExp("(" + [i.join("|"), e.join("|"), s.join("|")].join("|") + ")") } return this._splitRegex }, r.prototype._isNegative = function (e) { return e.length ? p.some(function (t) { return t === e[e.length - 1].type }) : !0 }, r.prototype._isWhitespace = function (e) { for (var t = 0; t < e.length; t++) if (" " != e[t]) return !1; return !0 }, r.prototype._unquote = function (e) { var t = e[0], r = new RegExp("\\\\" + t, "g"); return e.substr(1, e.length - 2).replace(r, t).replace(o, "\\") }, t.exports = r }, {}], 2: [function (e, t) { var r = e("./handlers"), n = function (e, t, r, n) { this._grammar = e, this._transforms = t || {}, this._context = r || {}, this._relContext = n || this._context }; n.prototype.eval = function (e) { var t = this; return Promise.resolve().then(function () { return r[e.type].call(t, e) }) }, n.prototype.evalArray = function (e) { return Promise.all(e.map(function (e) { return this.eval(e) }, this)) }, n.prototype.evalMap = function (e) { var t = Object.keys(e), r = {}, n = t.map(function (t) { return this.eval(e[t]) }, this); return Promise.all(n).then(function (e) { return e.forEach(function (e, n) { r[t[n]] = e }), r }) }, n.prototype._filterRelative = function (e, t) { var r = []; return Array.isArray(e) || (e = [e]), e.forEach(function (e) { var a = new n(this._grammar, this._transforms, this._context, e); r.push(a.eval(t)) }, this), Promise.all(r).then(function (t) { var r = []; return t.forEach(function (t, n) { t && r.push(e[n]) }), r }) }, n.prototype._filterStatic = function (e, t) { return this.eval(t).then(function (t) { return "boolean" == typeof t ? t ? e : void 0 : e[t] }) }, t.exports = n }, { "./handlers": 3 }], 3: [function (e, t, r) { r.ArrayLiteral = function (e) { return this.evalArray(e.value) }, r.BinaryExpression = function (e) { var t = this; return Promise.all([this.eval(e.left), this.eval(e.right)]).then(function (r) { return t._grammar[e.operator].eval(r[0], r[1]) }) }, r.ConditionalExpression = function (e) { var t = this; return this.eval(e.test).then(function (r) { return r ? e.consequent ? t.eval(e.consequent) : r : t.eval(e.alternate) }) }, r.FilterExpression = function (e) { var t = this; return this.eval(e.subject).then(function (r) { return e.relative ? t._filterRelative(r, e.expr) : t._filterStatic(r, e.expr) }) }, r.Identifier = function (e) { return e.from ? this.eval(e.from).then(function (t) { return void 0 === t ? void 0 : (Array.isArray(t) && (t = t[0]), t ? t[e.value] : void 0) }) : e.relative ? this._relContext[e.value] : this._context[e.value] }, r.Literal = function (e) { return e.value }, r.ObjectLiteral = function (e) { return this.evalMap(e.value) }, r.Transform = function (e) { var t = this._transforms[e.name]; if (!t) throw new Error("Transform '" + e.name + "' is not defined."); return Promise.all([this.eval(e.subject), this.evalArray(e.args || [])]).then(function (e) { return t.apply(null, [e[0]].concat(e[1])) }) }, r.UnaryExpression = function (e) { var t = this; return this.eval(e.right).then(function (r) { return t._grammar[e.operator].eval(r) }) } }, {}], 4: [function (e, t, r) { r.elements = { ".": { type: "dot" }, "[": { type: "openBracket" }, "]": { type: "closeBracket" }, "|": { type: "pipe" }, "{": { type: "openCurl" }, "}": { type: "closeCurl" }, ":": { type: "colon" }, ",": { type: "comma" }, "(": { type: "openParen" }, ")": { type: "closeParen" }, "?": { type: "question" }, "+": { type: "binaryOp", precedence: 30, eval: function (e, t) { return e + t } }, "-": { type: "binaryOp", precedence: 30, eval: function (e, t) { return e - t } }, "*": { type: "binaryOp", precedence: 40, eval: function (e, t) { return e * t } }, "/": { type: "binaryOp", precedence: 40, eval: function (e, t) { return e / t } }, "//": { type: "binaryOp", precedence: 40, eval: function (e, t) { return Math.floor(e / t) } }, "%": { type: "binaryOp", precedence: 50, eval: function (e, t) { return e % t } }, "^": { type: "binaryOp", precedence: 50, eval: function (e, t) { return Math.pow(e, t) } }, "==": { type: "binaryOp", precedence: 20, eval: function (e, t) { return e == t } }, "!=": { type: "binaryOp", precedence: 20, eval: function (e, t) { return e != t } }, ">": { type: "binaryOp", precedence: 20, eval: function (e, t) { return e > t } }, ">=": { type: "binaryOp", precedence: 20, eval: function (e, t) { return e >= t } }, "<": { type: "binaryOp", precedence: 20, eval: function (e, t) { return t > e } }, "<=": { type: "binaryOp", precedence: 20, eval: function (e, t) { return t >= e } }, "&&": { type: "binaryOp", precedence: 10, eval: function (e, t) { return e && t } }, "||": { type: "binaryOp", precedence: 10, eval: function (e, t) { return e || t } }, "in": { type: "binaryOp", precedence: 20, eval: function (e, t) { return "string" == typeof t ? -1 !== t.indexOf(e) : Array.isArray(t) ? t.some(function (t) { return t == e }) : !1 } }, "!": { type: "unaryOp", precedence: 1 / 0, eval: function (e) { return !e } } } }, {}], 5: [function (e, t) { function r(e, t, r) { this._grammar = e, this._state = "expectOperand", this._tree = null, this._exprStr = t || "", this._relative = !1, this._stopMap = r || {} } var n = e("./handlers"), a = e("./states").states; r.prototype.addToken = function (e) { if ("complete" == this._state) throw new Error("Cannot add a new token to a completed Parser"); var t = a[this._state], r = this._exprStr; if (this._exprStr += e.raw, t.subHandler) { this._subParser || this._startSubExpression(r); var o = this._subParser.addToken(e); if (o) { if (this._endSubExpression(), this._parentStop) return o; this._state = o } } else { if (!t.tokenTypes[e.type]) { if (this._stopMap[e.type]) return this._stopMap[e.type]; throw new Error("Token " + e.raw + " (" + e.type + ") unexpected in expression: " + this._exprStr) } var i = t.tokenTypes[e.type], s = n[e.type]; i.handler && (s = i.handler), s && s.call(this, e), i.toState && (this._state = i.toState) } return !1 }, r.prototype.addTokens = function (e) { e.forEach(this.addToken, this) }, r.prototype.complete = function () { if (this._cursor && !a[this._state].completable) throw new Error("Unexpected end of expression: " + this._exprStr); return this._subParser && this._endSubExpression(), this._state = "complete", this._cursor ? this._tree : null }, r.prototype.isRelative = function () { return this._relative }, r.prototype._endSubExpression = function () { a[this._state].subHandler.call(this, this._subParser.complete()), this._subParser = null }, r.prototype._placeAtCursor = function (e) { this._cursor ? (this._cursor.right = e, this._setParent(e, this._cursor)) : this._tree = e, this._cursor = e }, r.prototype._placeBeforeCursor = function (e) { this._cursor = this._cursor._parent, this._placeAtCursor(e) }, r.prototype._setParent = function (e, t) { Object.defineProperty(e, "_parent", { value: t, writable: !0 }) }, r.prototype._startSubExpression = function (e) { var t = a[this._state].endStates; t || (this._parentStop = !0, t = this._stopMap), this._subParser = new r(this._grammar, e, t) }, t.exports = r }, { "./handlers": 6, "./states": 7 }], 6: [function (e, t, r) { r.argVal = function (e) { this._cursor.args.push(e) }, r.arrayStart = function () { this._placeAtCursor({ type: "ArrayLiteral", value: [] }) }, r.arrayVal = function (e) { e && this._cursor.value.push(e) }, r.binaryOp = function (e) { for (var t = this._grammar[e.value].precedence || 0, r = this._cursor._parent; r && r.operator && this._grammar[r.operator].precedence >= t;) this._cursor = r, r = r._parent; var n = { type: "BinaryExpression", operator: e.value, left: this._cursor }; this._setParent(this._cursor, n), this._cursor = r, this._placeAtCursor(n) }, r.dot = function () { this._nextIdentEncapsulate = this._cursor && ("BinaryExpression" != this._cursor.type || "BinaryExpression" == this._cursor.type && this._cursor.right) && "UnaryExpression" != this._cursor.type, this._nextIdentRelative = !this._cursor || this._cursor && !this._nextIdentEncapsulate, this._nextIdentRelative && (this._relative = !0) }, r.filter = function (e) { this._placeBeforeCursor({ type: "FilterExpression", expr: e, relative: this._subParser.isRelative(), subject: this._cursor }) }, r.identifier = function (e) { var t = { type: "Identifier", value: e.value }; this._nextIdentEncapsulate ? (t.from = this._cursor, this._placeBeforeCursor(t), this._nextIdentEncapsulate = !1) : (this._nextIdentRelative && (t.relative = !0), this._placeAtCursor(t)) }, r.literal = function (e) { this._placeAtCursor({ type: "Literal", value: e.value }) }, r.objKey = function (e) { this._curObjKey = e.value }, r.objStart = function () { this._placeAtCursor({ type: "ObjectLiteral", value: {} }) }, r.objVal = function (e) { this._cursor.value[this._curObjKey] = e }, r.subExpression = function (e) { this._placeAtCursor(e) }, r.ternaryEnd = function (e) { this._cursor.alternate = e }, r.ternaryMid = function (e) { this._cursor.consequent = e }, r.ternaryStart = function () { this._tree = { type: "ConditionalExpression", test: this._tree }, this._cursor = this._tree }, r.transform = function (e) { this._placeBeforeCursor({ type: "Transform", name: e.value, args: [], subject: this._cursor }) }, r.unaryOp = function (e) { this._placeAtCursor({ type: "UnaryExpression", operator: e.value }) } }, {}], 7: [function (e, t, r) { var n = e("./handlers"); r.states = { expectOperand: { tokenTypes: { literal: { toState: "expectBinOp" }, identifier: { toState: "identifier" }, unaryOp: {}, openParen: { toState: "subExpression" }, openCurl: { toState: "expectObjKey", handler: n.objStart }, dot: { toState: "traverse" }, openBracket: { toState: "arrayVal", handler: n.arrayStart } } }, expectBinOp: { tokenTypes: { binaryOp: { toState: "expectOperand" }, pipe: { toState: "expectTransform" }, dot: { toState: "traverse" }, question: { toState: "ternaryMid", handler: n.ternaryStart } }, completable: !0 }, expectTransform: { tokenTypes: { identifier: { toState: "postTransform", handler: n.transform } } }, expectObjKey: { tokenTypes: { identifier: { toState: "expectKeyValSep", handler: n.objKey }, closeCurl: { toState: "expectBinOp" } } }, expectKeyValSep: { tokenTypes: { colon: { toState: "objVal" } } }, postTransform: { tokenTypes: { openParen: { toState: "argVal" }, binaryOp: { toState: "expectOperand" }, dot: { toState: "traverse" }, openBracket: { toState: "filter" }, pipe: { toState: "expectTransform" } }, completable: !0 }, postTransformArgs: { tokenTypes: { binaryOp: { toState: "expectOperand" }, dot: { toState: "traverse" }, openBracket: { toState: "filter" }, pipe: { toState: "expectTransform" } }, completable: !0 }, identifier: { tokenTypes: { binaryOp: { toState: "expectOperand" }, dot: { toState: "traverse" }, openBracket: { toState: "filter" }, pipe: { toState: "expectTransform" }, question: { toState: "ternaryMid", handler: n.ternaryStart } }, completable: !0 }, traverse: { tokenTypes: { identifier: { toState: "identifier" } } }, filter: { subHandler: n.filter, endStates: { closeBracket: "identifier" } }, subExpression: { subHandler: n.subExpression, endStates: { closeParen: "expectBinOp" } }, argVal: { subHandler: n.argVal, endStates: { comma: "argVal", closeParen: "postTransformArgs" } }, objVal: { subHandler: n.objVal, endStates: { comma: "expectObjKey", closeCurl: "expectBinOp" } }, arrayVal: { subHandler: n.arrayVal, endStates: { comma: "arrayVal", closeBracket: "expectBinOp" } }, ternaryMid: { subHandler: n.ternaryMid, endStates: { colon: "ternaryEnd" } }, ternaryEnd: { subHandler: n.ternaryEnd, completable: !0 } } }, { "./handlers": 6 }], Jexl: [function (e, t) { function r() { this._customGrammar = null, this._lexer = null, this._transforms = {} } var n = e("./evaluator/Evaluator"), a = e("./Lexer"), o = e("./parser/Parser"), i = e("./grammar").elements; r.prototype.addBinaryOp = function (e, t, r) { this._addGrammarElement(e, { type: "binaryOp", precedence: t, eval: r }) }, r.prototype.addUnaryOp = function (e, t) { this._addGrammarElement(e, { type: "unaryOp", weight: 1 / 0, eval: t }) }, r.prototype.addTransform = function (e, t) { this._transforms[e] = t }, r.prototype.addTransforms = function (e) { for (var t in e) e.hasOwnProperty(t) && (this._transforms[t] = e[t]) }, r.prototype.getTransform = function (e) { return this._transforms[e] }, r.prototype.eval = function (e, t, r) { "function" == typeof t ? (r = t, t = {}) : t || (t = {}); var n = this._eval(e, t); if (r) { var a = !1; return n.then(function (e) { a = !0, setTimeout(r.bind(null, null, e), 0) })["catch"](function (e) { a || setTimeout(r.bind(null, e), 0) }) } return n }, r.prototype.removeOp = function (e) { var t = this._getCustomGrammar(); !t[e] || "binaryOp" != t[e].type && "unaryOp" != t[e].type || (delete t[e], this._lexer = null) }, r.prototype._addGrammarElement = function (e, t) { var r = this._getCustomGrammar(); r[e] = t, this._lexer = null }, r.prototype._eval = function (e, t) { var r = this, a = this._getGrammar(), i = new o(a), s = new n(a, this._transforms, t); return Promise.resolve().then(function () { return i.addTokens(r._getLexer().tokenize(e)), s.eval(i.complete()) }) }, r.prototype._getCustomGrammar = function () { if (!this._customGrammar) { this._customGrammar = {}; for (var e in i) i.hasOwnProperty(e) && (this._customGrammar[e] = i[e]) } return this._customGrammar }, r.prototype._getGrammar = function () { return this._customGrammar || i }, r.prototype._getLexer = function () { return this._lexer || (this._lexer = new a(this._getGrammar())), this._lexer }, t.exports = new r, t.exports.Jexl = r }, { "./Lexer": 1, "./evaluator/Evaluator": 2, "./grammar": 4, "./parser/Parser": 5 }] }, {}, []);

    var jexl = jexlrequire('Jexl');

    return jexl;
});

from jexl.

TomFrost avatar TomFrost commented on September 17, 2024

Nice solution! That's exactly what I meant by wrapping it in a function-- I wasn't thinking to rename the require calls (but if that conflicts with dojo then that was good thinking), but getting the jexl instance and just returning that within a define was my thought. I'm glad you got it!

In v2, if you don't end up with something like webpack, it should be fairly trivial to run browserify to get a frontend-compatible copy of jexl. Actually, I think renaming the require call to something else (or omitting it entirely) is a feature of browserify, so it might even make sense to look into doing it that way now before v2 is released, as it would take away your need to manually edit the code when new versions come out.

All the best!

from jexl.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.