1 /*-------------------- Thymol - the flavour of Thymeleaf --------------------*
3 Thymol version 2.0.0 Copyright (C) 2012-2015 James J. Benson
4 jjbenson .AT. users.sf.net (http://www.thymoljs.org/)
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
10 http://www.apache.org/licenses/LICENSE-2.0
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" basis,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
18 *---------------------------------------------------------------------------*/
21 thymol.thVersion = "2.0.0";
22 thymol.thReleaseDate = "2015-03-31";
23 thymol.thURL = "http://www.thymoljs.org";
24 thymol.thAltURL = "http://www.thymeleaf.org";
25 thymol.thUsingNullPrefix = false;
26 thymol.thThymeleafPrefixList = [];
27 thymol.thThymeleafElementsList = [];
29 var textFuncSynonym = "~~~~", varRefExpr = /([$#]{.*?})/, literalTokenExpr = /^[a-zA-Z0-9\[\]\.\-_]*$/, startParserLevelCommentExpr = /^\s*\/\*\s*$/, endParserLevelCommentExpr = /^\s*\*\/\s*$/, startParserLevelCommentExpr2 = /^\/\*[^\/].*/, endParserLevelCommentExpr2 = /.*[^\/]\*\/$/, prototypeOnlyCommentEscpExpr = /\/\*\/(.*)\/\*\//, varExpr3 = /[\$\*#@]{1}\{(.*)\}$/, nonURLExpr = /[\$\*#]{1}\{(?:!?[^}]*)\}/, numericExpr = /^[+\-]?[0-9]*?[.]?[0-9]*?$/, varParExpr = /([^(]*)\s*[(]([^)]*?)[)]/, domSelectExpr = /([\/]{1,2})?([A-Za-z0-9_\-]*(?:[\(][\)])?)?([^\[]\S[A-Za-z0-9_\-]*(?:[\(][\)])?[\/]*(?:[\.\/#]?[^\[]\S[A-Za-z0-9_\-]*(?:[\(][\)])?[\/]*)*)?([\[][^\]]*?[\]])?/, litSubstExpr = /\.*?([\|][^\|]*?[\|])\.*?/;
31 function isClientSide() {
32 if (typeof thymol.isServerSide !== "undefined" && !!thymol.isServerSide()) {
33 thymol.isClientSide = function() {
38 thymol.isClientSide = function() {
43 function execute(doc) {
44 if (typeof thymol.protocol === "undefined") {
47 if (typeof thymol.root === "undefined") {
50 if (typeof thymol.path === "undefined") {
53 thymol.thDocument = doc;
54 var theWindow = thymol.thWindow;
55 if (typeof thymol.thWindow === "undefined") {
56 if (typeof doc.defaultView !== "undefined") {
57 theWindow = doc.defaultView;
58 } else if (typeof doc.parentWindow !== "undefined") {
59 theWindow = doc.parentWindow;
62 thymol.thWindow = theWindow;
63 var theTop = thymol.thTop;
64 if (typeof thymol.thTop === "undefined") {
65 if (typeof top !== "undefined") {
69 thymol.thTop = theTop;
71 var base = new ThNode(thymol.thDocument, false, null, null, null, thymol.thDocument.nodeName, "::", false, thymol.thDocument);
72 Thymol.prototype.process(base);
74 return thymol.thDocument;
76 function jqSetup(jq) {
78 getComments: function() {
79 return this.filter(function() {
80 return this.nodeType === 8;
83 getThDecorated: function(thInst) {
84 var i, iAttrName, iLength, j, jLength, instances = [], result = null, expanded = false;
85 if (thInst.escpName !== null) {
86 instances = this.filter(thInst.escpName);
88 if (thInst.escpSynonym !== null) {
89 instances = instances.add(this.filter(thInst.escpSynonym));
91 for (i = 0, iLength = instances.length; i < iLength; i++) {
93 for (j = 0, jLength = instances[i].attributes.length; j < jLength; j++) {
94 if (instances[i].attributes[j]) {
95 iAttrName = instances[i].attributes[j].name;
96 if (iAttrName && (thInst.name == iAttrName || thInst.synonym == iAttrName)) {
97 expanded = thymol.ThUtils.processElement(thInst.process, instances[i], instances[i].attributes[j], thInst);
99 if (result === null) {
102 result.push(instances[i]);
113 function ready(func) {
114 if (typeof thymolDeferredFunctions === "undefined" || thymolDeferredFunctions === null) {
115 thymolDeferredFunctions = [];
117 thymolDeferredFunctions.push(func);
119 function setupEnv() {
120 thymol.prefix = Thymol.prototype.getThParam("thPrefix", false, false, thymol.thDefaultPrefix);
121 thymol.dataPrefix = Thymol.prototype.getThParam("thDataPrefix", false, false, thymol.thDefaultDataPrefix);
122 thymol.messagePath = Thymol.prototype.getThParam("thMessagePath", false, true, thymol.thDefaultMessagePath);
123 thymol.resourcePath = Thymol.prototype.getThParam("thResourcePath", false, true, thymol.thDefaultResourcePath);
124 thymol.messagesBaseName = Thymol.prototype.getThParam("thMessagesBaseName", false, false, thymol.thDefaultMessagesBaseName);
125 thymol.relativeRootPath = Thymol.prototype.getThParam("thRelativeRootPath", false, true, thymol.thDefaultRelativeRootPath);
126 thymol.extendedMapping = Thymol.prototype.getThParam("thExtendedMapping", true, false, thymol.thDefaultExtendedMapping);
127 thymol.localMessages = Thymol.prototype.getThParam("thLocalMessages", true, false, thymol.thDefaultLocalMessages);
128 thymol.disableMessages = Thymol.prototype.getThParam("thDisableMessages", true, false, thymol.thDefaultDisableMessages);
129 thymol.templateSuffix = Thymol.prototype.getThParam("thTemplateSuffix", false, false, thymol.thDefaultTemplateSuffix);
130 thymol.scriptPath = "";
131 if (typeof thymol.thScriptPath !== "undefined") {
132 thymol.scriptPath = Thymol.prototype.getThParam("thScriptPath", false, true, thymol.thScriptPath);
134 thymol.absolutePath = "";
135 if (typeof thymol.thAbsolutePath !== "undefined") {
136 thymol.absolutePath = Thymol.prototype.getThParam("thAbsolutePath", false, true, thymol.thAbsolutePath);
138 thymol.useAbsolutePath = false;
139 if (typeof thymol.thUseAbsolutePath !== "undefined") {
140 thymol.useAbsolutePath = Thymol.prototype.getThParam("thUseAbsolutePath", true, false, thymol.thUseAbsolutePath);
142 thymol.useFullURLPath = true;
143 if (typeof thymol.thUseFullURLPath !== "undefined") {
144 thymol.useFullURLPath = Thymol.prototype.getThParam("thUseFullURLPath", true, false, thymol.thUseFullURLPath);
146 thymol.indexFile = Thymol.prototype.getThParam("thIndexFile", false, false, null);
147 thymol.debug = Thymol.prototype.getThParam("thDebug", true, false, false);
148 thymol.allowNullText = Thymol.prototype.getThParam("thAllowNullText", true, false, true);
149 thymol.location = thymol.thLocation;
150 if ("" !== thymol.relativeRootPath) {
151 thymol.root = thymol.location + thymol.relativeRootPath;
152 thymol.messagePath = thymol.root + thymol.messagePath;
154 if (typeof thymol.thMessagePath !== "undefined") {
155 thymol.messagePath = Thymol.prototype.getThParam("thMessagePath", false, true, thymol.thMessagePath);
157 if (typeof thymol.thRoot !== "undefined") {
158 thymol.root = Thymol.prototype.getThParam("thRoot", false, true, thymol.thRoot);
161 thymol.root = Thymol.prototype.getThParam("thRoot", false, true, thymol.root);
162 if (typeof thymol.thPath !== "undefined") {
163 thymol.path = Thymol.prototype.getThParam("thPath", false, true, thymol.thPath);
165 thymol.path = Thymol.prototype.getThParam("thPath", false, true, thymol.path);
166 thymol.protocol = thymol.thDocument.location.protocol;
167 if ("" == thymol.protocol) {
168 thymol.protocol = thymol.thDefaultProtocol;
170 thymol.protocol += "//";
171 if ("" == thymol.thDocument.location.host) {
172 thymol.protocol += "/";
175 thymol.protocol = Thymol.prototype.getThParam("thProtocol", false, false, thymol.protocol);
176 thymol.resourcePath = Thymol.prototype.getThParam("thResourcePath", false, true, thymol.resourcePath);
178 function updatePrefix(pref) {
179 thymol.prefix = pref;
180 thymol.thThymeleafPrefixList = [];
181 thymol.thThymeleafElementsList = [];
184 this.messages = null;
185 this.mappings = null;
188 this.locale = new thymol.ThObject();
190 var accessor = undefined, i, iLimit, j, jLimit;
191 if (typeof thVars !== "undefined") {
192 accessor = new thymol.ThVarsAccessor(thVars, "thVars");
194 this.applicationContext = thymol.makeContext("application", accessor);
195 this.sessionContext = thymol.makeContext("session", undefined);
196 this.sessionContext.persist = function() {
197 var save = this.serialise();
198 thymol.thTop.name = save;
200 this.requestContext = thymol.makeContext("request", undefined);
201 this.booleanAndNullTokens = new Array();
202 this.booleanAndNullTokens["null"] = this.applicationContext.createVariable("null", null);
203 this.booleanAndNullTokens["true"] = this.applicationContext.createVariable("true", true);
204 this.booleanAndNullTokens["false"] = this.applicationContext.createVariable("false", false);
205 this.allowNullText = null;
208 this.thExpressionObjects;
209 this.thDeferredFunctions;
210 this.thPreExecutionFunctions;
211 this.thPostExecutionFunctions;
212 if (typeof this.thExpressionObjects === "undefined" || this.thExpressionObjects === null) {
213 this.thExpressionObjects = {};
215 this.thExpressionObjects["#object"] = {};
216 this.thExpressionObjects["#locale"] = {};
217 this.thExpressionObjects["#ctx"] = [];
218 this.thExpressionObjects["#ctx"]["variables"] = {};
219 thymol.configureModule(thymol.objects.thHttpServletRequestObject);
220 thymol.configureModule(thymol.objects.thHttpSessionObject);
221 if (typeof thymol.thObjectsConfigureModules !== "undefined") {
222 thymol.thObjectsConfigureModules();
224 var scripts = thymol.thDocument.getElementsByTagName("script");
225 for (var i = 0, iLimit = scripts.length; i < iLimit; i++) {
226 var parameters = scripts[i].getAttribute("data-thymol-load");
228 var splits = parameters.split(",");
229 for (var j = 0, jLimit = splits.length; j < jLimit; j++) {
230 thymol.ThUtils.loadScript(splits[j]);
235 if (typeof thymol.thPreExecutionFunctions === "undefined" || thymol.thPreExecutionFunctions === null) {
236 thymol.thPreExecutionFunctions = [];
238 if (typeof thymol.thPostExecutionFunctions === "undefined" || thymol.thPostExecutionFunctions === null) {
239 thymol.thPostExecutionFunctions = [];
246 if (!(typeof thVars === "undefined")) {
247 for (i = 0, iLimit = thVars.length; i < iLimit; i++) {
248 this.applicationContext.createVariable(thVars[i][0], thVars[i][1]);
253 var htmlTagAttrs = $("html")[0].attributes, tp = null, tu, nsspec;
254 $([ thymol.thURL, thymol.thAltURL ]).each(function() {
256 $(htmlTagAttrs).each(function() {
257 if (this.value == tu) {
258 nsspec = this.localName.split(":");
259 if (nsspec.length > 0) {
260 tp = nsspec[nsspec.length - 1];
266 thymol.updatePrefix(tp);
271 var defaultScriptUrl = "";
272 if (!!thymol.thRequest) {
273 thymol.thWindow.location.search = thymol.thRequest;
275 (function(app, req) {
276 var e, f, a = /\+/g, r = /([^&=]+)=?([^&]*)/g, d = function(s) {
277 return decodeURIComponent(s.replace(a, " "));
278 }, q = thymol.thWindow.location.search.substring(1), surl, scriptUrl = defaultScriptUrl;
279 $("script").each(function() {
281 if (surl.indexOf(thymol.thScriptName) >= 0) {
286 while (e = r.exec(scriptUrl)) {
290 thymol.prefix = e[2];
294 thymol.dataPrefix = e[2];
297 case "thMessagePath":
298 thymol.messagePath = e[2];
301 case "thResourcePath":
302 thymol.resourcePath = e[2];
305 case "thMessagesBaseName":
306 thymol.messagesBaseName = e[2];
309 case "thRelativeRootPath":
310 thymol.relativeRootPath = e[2];
313 case "thExtendedMapping":
314 thymol.extendedMapping = e[2];
317 case "thTemplateSuffix":
318 thymol.templateSuffix = e[2];
321 case "thLocalMessages":
322 thymol.localMessages = e[2];
325 case "thDisableMessages":
326 thymol.disableMessages = e[2];
330 thymol.indexFile = e[2];
334 thymol.protocol = e[2];
349 case "thAllowNullText":
350 thymol.allowNullText = e[2];
354 thymol.locale.value = e[2];
357 case "thDefaultPrecision":
358 thymol.thDefaultPrecision = e[2];
361 case "thDefaultPrecedence":
362 thymol.thDefaultPrecedence = e[2];
366 app.createVariable(e[1], e[2]);
369 while (e = r.exec(q)) {
370 req.createVariable(d(e[1]), e[2], true);
372 })(this.applicationContext, this.requestContext);
373 thymol.thInclude = new thymol.ThAttr("include", null, 100, null, thymol.prefix);
374 thymol.thReplace = new thymol.ThAttr("replace", null, 100, null, thymol.prefix);
375 thymol.thSubstituteby = new thymol.ThAttr("substituteby", null, 100, null, thymol.prefix);
376 thymol.thFragment = new thymol.ThAttr("fragment", null, 2e4, null, thymol.prefix);
377 thymol.thRemove = null;
378 thymol.thBlock = new thymol.ThElement("block", function(element) {
379 var i, limit = element.childNodes.length;
380 for (i = 0; i < limit; i++) {
381 if (element.childNodes[i].nodeType === 1) {
382 element.childNodes[i].isBlockChild = true;
386 this.applicationContext.resolveJSONReferences();
387 thymol.setupAttrList();
388 preExecute(this.applicationContext);
389 this.thExpressionObjects["#vars"] = this.applicationContext;
390 this.thExpressionObjects["#root"] = this.applicationContext;
391 this.sessionContext.init();
392 this.sessionContext.resolveJSONReferences();
393 this.requestContext.resolveJSONReferences();
394 this.thExpressionObjects["#ctx"]["variables"] = this.applicationContext;
395 this.thExpressionObjects["#ctx"]["requestParameters"] = this.requestContext;
396 this.thExpressionObjects["#ctx"]["servletContext"] = this.applicationContext;
397 this.thExpressionObjects["#ctx"]["httpServletRequest"] = this.thExpressionObjects["#httpServletRequest"];
398 this.thExpressionObjects["#ctx"]["httpSession"] = this.thExpressionObjects["#httpSession"];
399 this.protocol = Thymol.prototype.override("thProtocol", this.protocol);
400 this.debug = Thymol.prototype.override("thDebug", this.debug);
401 this.root = Thymol.prototype.override("thRoot", this.root);
402 if ("" !== this.relativeRootPath) {
403 var rootURI = thymol.thDocument.location.href;
404 var quePos = rootURI.indexOf("?");
406 rootURI = rootURI.substring(0, quePos);
408 var sepPos = rootURI.lastIndexOf("/");
410 rootURI = rootURI.substring(0, sepPos + 1);
412 var newThRoot = rootURI + this.thLocation + this.relativeRootPath;
413 this.thRoot = Thymol.prototype.getThParam("thRoot", false, true, newThRoot);
415 this.path = Thymol.prototype.override("thPath", this.path);
416 this.allowNullText = Thymol.prototype.override("thAllowNullText", this.allowNullText);
417 this.locale.value = Thymol.prototype.override("thLocale", this.locale.value);
418 if (!(typeof thMappings === "undefined")) {
420 for (j = 0, jLimit = thMappings.length; j < jLimit; j++) {
421 this.mappings.push([ thMappings[j][0], thMappings[j][1] ]);
423 this.mappings.sort(function(a, b) {
424 return a[0].length > b[0].length ? -1 : 1;
429 if (!(typeof thMessages === "undefined")) {
430 this.messages[""] = [];
431 for (j = 0, jLimit = thMessages.length; j < jLimit; j++) {
432 this.messages[""][thMessages[j][0]] = thMessages[j][1];
434 for (var k in thMessages) {
435 if (thMessages.hasOwnProperty(k)) {
436 if (!k.match(numericExpr)) {
437 this.messages[k] = [];
438 for (j = 0, jLimit = thMessages[k].length; j < jLimit; j++) {
439 this.messages[k][thMessages[k][j][0]] = thMessages[k][j][1];
445 if (!(typeof thDisable === "undefined")) {
446 for (j = 0, jLimit = thDisable.length; j < jLimit; j++) {
447 Thymol.prototype.doDisable(thDisable[j]);
450 thymol.thRemove = Thymol.prototype.getThAttrByName("remove");
452 function getLocations(thiz) {
453 thiz.templateName = "";
454 thiz.templatePath = "";
455 if (!!thymol.thDocument.location.href) {
456 var templateName = templatePath = thymol.thDocument.location.href;
457 thiz.templateName = templateName.substring(0, templateName.indexOf(".") == -1 ? templateName.length : templateName.lastIndexOf("."));
458 thiz.templatePath = templatePath.substring(0, templatePath.indexOf("/") == -1 ? 0 : templatePath.lastIndexOf("/") + 1);
462 return thymol.thExpressionObjects["#ctx"];
464 function configureModule(module) {
465 if (typeof thymol.thExpressionObjects === "undefined" || thymol.thExpressionObjects === null) {
466 thymol.thExpressionObjects = {};
468 thymol.thExpressionObjects[module.thExpressionObjectName] = module;
470 function configureAttributeProcessor(prefix, suffix, func, prec, dataAttr) {
471 var p = prefix + ":";
473 if (thymol.thThymeleafPrefixList.indexOf(p) < 0) {
474 thymol.thThymeleafPrefixList.push(p);
477 thymol.thUsingNullPrefix = true;
479 p = new thymol.ThAttr(suffix, func, prec, thymol.thThymeleafPrefixList, prefix, dataAttr);
481 function configureElementProcessor(prefix, suffix, func) {
482 var p = new thymol.ThElement(suffix, func, prefix);
484 function configurePreExecution(func) {
485 if (typeof thymol.thPreExecutionFunctions === "undefined" || thymol.thPreExecutionFunctions === null) {
486 thymol.thPreExecutionFunctions = [];
488 thymol.thPreExecutionFunctions.push(func);
490 function configurePostExecution(func) {
491 if (typeof thymol.thPostExecutionFunctions === "undefined" || thymol.thPostExecutionFunctions === null) {
492 thymol.thPostExecutionFunctions = [];
494 thymol.thPostExecutionFunctions.push(func);
496 function executeDeferred() {
497 if (typeof thymolDeferredFunctions !== "undefined" && thymolDeferredFunctions !== null) {
498 while (thymolDeferredFunctions.length > 0) {
499 var func = thymolDeferredFunctions.pop();
504 function preExecute(context) {
505 while (thymol.thPreExecutionFunctions.length > 0) {
506 var func = thymol.thPreExecutionFunctions.pop();
508 context.resolveJSONReferences();
511 function postExecute() {
512 while (thymol.thPostExecutionFunctions.length > 0) {
513 var func = thymol.thPostExecutionFunctions.pop();
517 function preProcess(expr, element) {
518 var result = expr, fp, lp;
520 fp = result.indexOf("__");
523 if (result.length > 4) {
524 lp = result.lastIndexOf("__");
527 throw new thymol.ThError("Mismatched pre-processing indicators", element);
529 var head = result.substring(0, fp);
530 var centre = result.substring(fp + 2, lp);
531 centre = this.getParsedExpr(centre, element);
532 var tail = result.substring(lp + 2);
533 result = head + centre + tail;
534 fp = result.indexOf("__");
537 result = result.replace(/\\_\\_/g, "__");
540 function substituteParam(argValue, mode, element) {
541 var result = argValue, varName = argValue, subs = null, msg, expo;
544 msg = thymol.getMessage(varName);
548 } else if (mode === 6) {
551 var token = thymol.booleanAndNullTokens[result];
552 if (!(typeof token === "undefined")) {
553 if (token === null) {
559 if (varName.charAt(0) === "#") {
560 if ("#object" === varName) {
561 if (element.thObjectVar) {
562 subs = element.thObjectVar;
565 expo = thymol.thExpressionObjects[varName];
566 if (typeof expo !== "undefined" && expo !== null) {
571 if ((typeof subs === "undefined" || subs == null) && element.thObjectVar) {
572 subs = element.thObjectVar[varName];
574 if ((typeof subs === "undefined" || subs == null) && element.thLocalVars) {
575 subs = element.thLocalVars[varName];
577 if (typeof subs === "undefined" || subs == null) {
578 subs = thymol.ThUtils.getParameter(varName);
580 if (typeof subs === "undefined" || subs == null) {
581 if ("param" === varName) {
582 subs = thymol.requestContext;
584 if ("session" === varName) {
585 subs = thymol.sessionContext;
587 if ("application" === varName) {
588 subs = thymol.applicationContext;
591 if (mode === 2 && (typeof subs === "undefined" || subs == null)) {
597 if (subs instanceof thymol.ThParam) {
603 function getStandardURL(initial) {
604 var result = initial.trim(), mapped, head;
605 mapped = thymol.getMapped(result, thymol.extendedMapping);
609 if ("/" === result && !!thymol.indexFile) {
610 result += thymol.indexFile;
612 if (!/.*:\/\/.*/.test(result)) {
613 if (/^~?\/.*$/.test(result)) {
614 if (/^~.*$/.test(result)) {
615 result = result.substring(1);
617 if (!/^\/\/.*$/.test(result)) {
618 if (thymol.useFullURLPath) {
619 head = thymol.root + thymol.resourcePath;
621 if (head.charAt(head.length - 1) !== "/") {
624 if (result.charAt(0) === "/") {
625 result = head + result.substring(1);
627 result = head + result;
631 result = thymol.resourcePath + result;
638 function getExpression(argValue, element) {
639 var result = argValue, subst = false, initial, shortCut, args, negate, token, lsp;
640 if (typeof argValue === "string") {
641 initial = argValue.trim();
644 shortCut = thymol.ThUtils.getParameter(result);
646 args = result.match(varExpr3);
648 if (args[1] && args[1].length > 0) {
649 shortCut = thymol.ThUtils.getParameter(args[1]);
654 if (shortCut instanceof thymol.ThParam) {
655 result = shortCut.value;
659 if (typeof result === "string" && result.match(numericExpr)) {
660 result = parseInt(result);
663 initial = thymol.ThUtils.unParenthesise(result);
665 if (initial.charAt(0) == "!") {
667 initial = initial.substring(1, initial.length);
668 initial = thymol.ThUtils.unParenthesise(initial);
670 if (literalTokenExpr.test(initial)) {
671 token = thymol.booleanAndNullTokens[initial];
672 if (!(typeof token === "undefined")) {
673 result = token.value;
679 lsp = initial.match(litSubstExpr);
680 if (lsp && lsp.length > 0) {
681 if (thymol.ThUtils.charOcurrences(lsp[1], "'") < 2) {
682 initial = Thymol.prototype.doLiteralSubstExpr(initial, lsp[1]);
687 initial = thymol.ThUtils.unParenthesise(initial);
688 initial = thymol.preProcess(initial, element);
689 result = thymol.getParsedExpr(initial, element, true);
692 if (result == initial && typeof result == typeof initial) {
694 } else if (typeof result === "string") {
696 result = result.replace(/[\\][\\]/g, "\\");
698 result = result.replace(/'/g, "'").replace(/'/gi, "'");
701 if (typeof result === "boolean") {
703 } else if (typeof result === "number") {
704 result = result == 0;
705 } else if (typeof result === "string") {
706 result = !thymol.ThUtils.testLiteralFalse(result);
714 function getMapped(uri, extended) {
715 var mapped = null, i, iLimit, key;
716 if (uri && typeof uri === "string") {
717 if (thymol.mappings) {
718 for (i = 0, iLimit = thymol.mappings.length; i < iLimit; i++) {
719 key = thymol.mappings[i][0];
721 mapped = thymol.mappings[i][1];
723 } else if (extended) {
724 if (uri.indexOf(key) == 0) {
725 mapped = uri.substring(key.length);
726 mapped = thymol.mappings[i][1] + mapped;
735 function substitute(initial, element, lenient) {
736 var argValue = initial, result, args, token, re, subs, saved;
737 if (typeof argValue === "string") {
738 argValue = argValue.trim();
742 while (args != null) {
743 args = argValue.match(/.*([$\*#@]{(!?[^}]*)}).*/);
744 if (args != null && args.length > 0) {
745 if (args.length == 3) {
747 token = token.replace(/[$]/g, "[$]").replace(/[*]/g, "[*]").replace(/[\']/g, "[']").replace(/[+]/g, "[+]").replace(/[\(]/g, "[(]").replace(/[\)]/g, "[)]");
748 re = new RegExp(token);
749 subs = this.getExpression(args[2], element);
750 if (subs != args[2]) {
751 result = result.replace(re, subs, "g");
752 if (result == "null") {
757 if (thymol.debug && !lenient) {
758 thymol.thWindow.alert('thymol variable substitution failed: "' + initial + '"');
762 argValue = argValue.replace(re, subs, "g");
763 if (saved == argValue) {
771 function getWith(element, content) {
772 var argValue = content.trim(), argCount = 0;
775 var argsExpr = thymol.ThParser.parse(argValue, true, false);
776 var identifier = argsExpr.tokens.shift();
777 if (identifier.type_ === 3) {
778 var result = argsExpr.evaluate(element);
779 var varName = identifier.index_;
782 if (!element.thLocalVars) {
783 element.thLocalVars = {};
785 element.thLocalVars[varName] = result;
787 argValue = argValue.substring(argsExpr.position);
791 } while (argValue.length > 0);
795 function getParsedExpr(initial, element, preprocessed) {
796 var expr, result = initial;
797 expr = thymol.ThParser.parse(result, false, preprocessed);
798 expr = expr.simplify();
799 result = expr.evaluate(element);
800 if (typeof result === "number") {
801 result = thymol.ThUtils.getToPrecision(result, expr.precision);
805 function getBooleanValue(param) {
806 var flag = false, val, args;
808 if (typeof param === "boolean") {
810 } else if (typeof param === "number") {
814 if (Object.prototype.toString.call(val) === "[object Array]") {
815 if (val.length === 1) {
821 if (typeof val === "boolean") {
823 } else if (typeof val === "number") {
825 } else if (typeof val === "string") {
826 args = val.match(nonURLExpr);
829 flag = this.testParam(val);
831 flag = !thymol.ThUtils.testLiteralFalse(val);
833 } else if (val instanceof thymol.ThParam) {
834 flag = val.getBooleanValue();
836 flag = typeof val !== "undefined" && val !== null;
842 function isFragmentChild(element) {
843 var result = false, parent = element.parentElement;
845 if (parent.getAttribute(thymol.thFragment.name) || parent.getAttribute(thymol.thFragment.synonym)) {
849 parent = parent.parentElement;
853 function setLocale(locValue) {
854 thymol.locale.value = locValue;
857 function getLocale() {
858 return thymol.locale.value;
860 function getLanguage() {
861 if (!thymol.locale.value) {
862 if (typeof navigator !== "undefined" && !!navigator) {
863 var userLang = navigator.language || navigator.userLanguage || navigator.browserLanguage || navigator.systemLanguage;
865 thymol.locale.value = userLang.replace(/\-/g, "_");
870 function setLocaleValue() {
871 if (!thymol.locale.value) {
872 thymol.locale.value = thymol.thDefaultLocale;
875 var locale = thymol.locale.value.replace(/\-/g, "_");
876 var level = thymol.locale.value;
878 var part, parts = [];
881 sepPos = locale.lastIndexOf("_");
883 part = locale.substring(sepPos + 1);
885 locale = locale.substring(0, sepPos);
886 level = level.substring(0, sepPos);
888 } while (sepPos >= 0);
889 thymol.locale.language = level;
892 for (var i = 0, iLimit = parts.length; i < iLimit; i++) {
894 thymol.locale.country = parts[i];
895 } else if (i === 1) {
896 thymol.locale.variant = parts[i];
900 thymol.locale.levels = levels;
901 thymol.thExpressionObjects["#ctx"]["locale"] = thymol.locale;
902 thymol.thExpressionObjects["#locale"] = thymol.locale;
904 function getMessage(varName, parameters, returnStringAlways) {
905 if (thymol.disableMessages) {
910 if (!!thymol.locale.levels) {
912 var ident, section, jLower = thymol.localMessages ? 0 : 1;
913 for (var j = jLower; j < 2; j++) {
914 for (var i = 0, iLimit = thymol.locale.levels.length; i < iLimit + 1; i++) {
917 locale = thymol.locale.levels[i];
921 ident = ident + locale;
922 section = thymol.messages[ident];
925 section = getLocalMessages(locale);
927 section = getDefaultMessages(locale);
931 thymol.messages[ident] = section;
932 msgKey = section[varName];
945 for (var i = 0, iLimit = thymol.locale.levels.length; i <= iLimit; i++) {
947 locale = thymol.locale.levels[i];
951 if (!!thymol.messages[locale]) {
952 msgKey = thymol.messages[locale][varName];
960 if (typeof parameters === "undefined") {
963 return thymol.ThUtils.renderMessage(msgKey, parameters);
965 } else if (returnStringAlways !== undefined && returnStringAlways) {
966 return "??" + varName + "_" + thymol.locale.value + "??";
970 function getProperties(propFile) {
973 $.get(propFile, function(textContent, status) {
976 if ("success" == status) {
978 } else if (thymol.debug) {
979 thymol.thWindow.alert("read failed: " + propFile);
983 thymol.thWindow.alert("properties file read failed: " + propFile + " error: " + err);
987 if (props !== null) {
988 var splits = props.split("\n");
989 if (splits.length > 0) {
990 for (var i = 0, iLimit = splits.length; i < iLimit; i++) {
991 var line = splits[i].trim();
992 if (line.charAt(0) !== "#") {
993 var p = line.split("=");
995 messages[p[0].trim()] = thymol.ThUtils.unicodeUnescape(p[1].trim());
1003 function getLocalMessages(locale) {
1005 if (!!thymol.thDocument.location.href) {
1006 var propsFile = thymol.templateName;
1007 if (!!locale && locale !== "") {
1008 propsFile += "_" + locale;
1010 propsFile += ".properties";
1011 messages = getProperties(propsFile);
1015 function getDefaultMessages(locale) {
1016 var messages = null;
1018 if (thymol.useAbsolutePath) {
1019 propsPath += thymol.protocol + thymol.root + thymol.path;
1021 propsPath += thymol.messagePath;
1022 if (propsPath !== "") {
1025 var propsFile = propsPath + thymol.messagesBaseName;
1026 if (!!locale && locale !== "") {
1027 propsFile += "_" + locale;
1029 propsFile += ".properties";
1030 messages = getProperties(propsFile);
1033 Thymol.prototype = {
1034 process: function(rootNode) {
1038 this.getChildren(n);
1039 if (n.firstChild && n.firstChild.thDoc && !n.visited) {
1043 if (n.element != n.thDoc) {
1044 this.doReplace(n.isNode, n.element, n.thDoc);
1046 n.thDoc = n.element;
1049 if (n.nextSibling && n.nextSibling.thDoc) {
1052 if (n == rootNode) {
1059 this.processChildren(rootNode);
1062 if (err instanceof thymol.ThError) {
1063 if (!err.suppress) {
1064 thymol.thWindow.alert(err);
1067 thymol.thWindow.alert(err);
1072 getChildren: function(rootNode) {
1073 var count = 0, last = null, changed = false, child, froot, fstar, fchildren, i, iLimit, j, jLimit, element, matches, theAttr;
1074 if (!rootNode.visited) {
1075 this.processComments(rootNode);
1076 var rnd = this.getContentRoot(rootNode);
1078 fstar = $(froot).add(froot.find("*"));
1079 fchildren = fstar.filter(thymol.thInclude.escpName).add(fstar.filter(thymol.thInclude.escpSynonym)).add(fstar.filter(thymol.thReplace.escpName)).add(fstar.filter(thymol.thReplace.escpSynonym)).add(fstar.filter(thymol.thSubstituteby.escpName)).add(fstar.filter(thymol.thSubstituteby.escpSynonym));
1080 for (i = 0, iLimit = fchildren.length; i < iLimit; i++) {
1081 element = fchildren[i], matches = [];
1082 for (j = 0, jLimit = element.attributes.length; j < jLimit; j++) {
1083 theAttr = element.attributes[j];
1084 if (thymol.thInclude.name == theAttr.name || thymol.thInclude.synonym == theAttr.name || thymol.thReplace.name == theAttr.name || thymol.thReplace.synonym == theAttr.name || thymol.thSubstituteby.name == theAttr.name || thymol.thSubstituteby.synonym == theAttr.name) {
1085 matches.push(theAttr);
1088 for (j = 0, jLimit = matches.length; j < jLimit; j++) {
1089 child = this.processImport(element, rootNode, matches[j]);
1090 if (child != null) {
1093 rootNode.firstChild = child;
1095 last.nextSibling = child;
1105 processChildren: function(rootNode) {
1106 var i, iLimit, j, jLimit, k, kLimit;
1107 var elements = rootNode.thDoc.getElementsByTagName("*");
1108 for (k = 0, kLimit = elements.length; k < kLimit; k++) {
1109 var element = elements[k];
1110 for (j = 0, jLimit = thymol.thThymeleafElementsList.length; j < jLimit; j++) {
1111 if (element.localName == thymol.thThymeleafElementsList[j].name || element.localName == thymol.thThymeleafElementsList[j].synonym) {
1112 var updated = thymol.thThymeleafElementsList[j].process(element);
1114 elements = rootNode.thDoc.getElementsByTagName("*");
1116 kLimit = elements.length;
1121 var allAttributes = element.attributes;
1122 if (allAttributes && allAttributes.length > 0) {
1123 var attributes = [], aii = 0;
1124 if (!thymol.thUsingNullPrefix) {
1125 for (i = 0, iLimit = allAttributes.length; i < iLimit; i++) {
1126 var ai = allAttributes[i];
1128 for (j = 0, jLimit = thymol.thThymeleafPrefixList.length; j < jLimit; j++) {
1129 var attrName = ai.name.toString();
1130 if (attrName.length > thymol.thThymeleafPrefixList[j].length) {
1131 attrName = attrName.substring(0, thymol.thThymeleafPrefixList[j].length);
1132 if (attrName === thymol.thThymeleafPrefixList[j]) {
1134 attributes[aii++] = ai;
1141 attributes = allAttributes;
1143 if (attributes.length > 0) {
1144 attributes.sort(function(a, b) {
1145 return b.order - a.order;
1147 var matchedAttributes = [];
1148 for (i = 0, iLimit = attributes.length; i < iLimit; i++) {
1149 var splits = attributes[i].name.toString().split(":");
1150 if (splits && splits.length > 0) {
1151 var prefix = "", name;
1152 if (splits.length > 1) {
1157 var hpos = name.lastIndexOf("-");
1159 prefix = name.substring(0, hpos + 1);
1162 var attrList = thymol.thThymeleafPrefixList[prefix];
1163 if (splits.length > 1) {
1167 for (j = 0, jLimit = attrList.length; j < jLimit; j++) {
1168 var matched = false;
1169 if (name === attrList[j].suffix || name === attrList[j].synonym) {
1171 } else if (attrList[j].regex !== null) {
1172 var fqn = prefix + name;
1173 matched = attrList[j].regex.test(fqn);
1176 var matchedAttribute = {};
1177 matchedAttribute.attr = attrList[j];
1178 matchedAttribute.elementAttr = attributes[i];
1179 matchedAttributes.push(matchedAttribute);
1186 if (matchedAttributes.length > 0) {
1187 matchedAttributes.sort(function(a, b) {
1188 return a.attr.precedence - b.attr.precedence;
1190 var updated = false;
1191 for (i = 0, iLimit = matchedAttributes.length; i < iLimit; i++) {
1192 var exp = thymol.ThUtils.processElement(matchedAttributes[i].attr.process, element, matchedAttributes[i].elementAttr, matchedAttributes[i].attr, 1);
1193 updated = exp || updated;
1196 elements = rootNode.thDoc.getElementsByTagName("*");
1198 kLimit = elements.length;
1204 elements = rootNode.thDoc.getElementsByTagName("*");
1206 for (k = 0, kLimit = elements.length; k < kLimit; k++) {
1207 var element = elements[kc];
1208 var elName = element.nodeName.toLowerCase();
1209 if (elName == thymol.thBlock.name || elName == thymol.thBlock.synonym) {
1210 thymol.ThUtils.removeTag(element);
1211 elements = rootNode.thDoc.getElementsByTagName("*");
1217 override: function(paramName, paramValue) {
1218 var param = paramValue, thv;
1219 thv = thymol.thWindow[paramName];
1220 if (typeof thv === "undefined") {
1221 thv = thymol.applicationContext.javascriptify(paramName);
1224 if (thv instanceof thymol.ThParam) {
1230 thv = thymol.applicationContext[paramName];
1232 if (thv instanceof thymol.ThParam) {
1238 thv = thymol.requestContext[paramName];
1240 if (thv instanceof thymol.ThParam) {
1248 doDisable: function(attrName) {
1249 var tha = this.getThAttrByName(attrName);
1254 thymol.thWindow.alert('cannot disable unknown attribute "' + attrName + '"');
1258 getThAttrByName: function(name) {
1259 var attrList = thymol.thThymeleafPrefixList[thymol.prefix];
1260 attrList.push(thymol.thInclude);
1261 attrList.push(thymol.thReplace);
1262 attrList.push(thymol.thSubstituteby);
1263 attrList.push(thymol.thFragment);
1264 var i, iLimit = attrList.length;
1265 for (i = 0; i < iLimit; i++) {
1266 if (name === attrList[i].suffix) {
1272 getContents: function(rootNode) {
1273 var rnd = this.getContentRoot(rootNode);
1275 var fstar = froot.find("*");
1278 getContentRoot: function(rn) {
1280 if (rnd.nodeName !== "#document") {
1281 rnd = rnd.childNodes;
1285 processComments: function(rootNode) {
1286 var comments = null, fstar, changed, i, iLimit, startComment, parent, startValue, pointer, nextPointer;
1288 fstar = this.getContents(rootNode);
1289 comments = fstar.contents().getComments();
1291 for (i = 0, iLimit = comments.length; i < iLimit; i++) {
1292 startComment = comments[i];
1293 parent = startComment.parentNode;
1294 startValue = startComment.nodeValue.trim();
1295 if (startParserLevelCommentExpr.test(startValue)) {
1296 pointer = startComment;
1297 while (pointer != null) {
1298 if (endParserLevelCommentExpr.test(pointer.nodeValue)) {
1299 changed = parent.removeChild(pointer) != null;
1302 nextPointer = pointer.nextSibling;
1303 changed = parent.removeChild(pointer) != null;
1304 pointer = nextPointer;
1306 } else if (startParserLevelCommentExpr2.test(startValue) && endParserLevelCommentExpr2.test(startValue)) {
1307 parent.removeChild(startComment);
1312 this.processPrototypeOnlyComments(rootNode);
1314 processPrototypeOnlyComments: function(rootNode) {
1315 var comments = null, fstar, changed, indexOfLast, i, iLimit, j, jLimit, k, kLimit, startComment, parent, deletions, res, fullText, innerNodes, done, next, commentText, res2, blockElement, blockDoc, blockDocBody, blockBase, newNode, newDoc;
1317 fstar = this.getContents(rootNode);
1318 comments = fstar.contents().getComments();
1320 indexOfLast = comments.length - 1;
1321 for (i = 0, iLimit = comments.length; i < iLimit; i++) {
1322 startComment = comments[i];
1323 parent = startComment.parentNode;
1324 if (parent != null) {
1325 startValue = startComment.nodeValue.trim();
1327 deletions.push(startComment);
1328 startValue = startValue.replace(/\n/g, "");
1329 res = startValue.match(prototypeOnlyCommentEscpExpr);
1331 fullText = startValue;
1332 if (parent.localName == "table" || parent.localName == "tbody") {
1333 if (startValue.indexOf(thymol.thBlock.name) >= 0 || startValue.indexOf(thymol.thBlock.synonym) >= 0) {
1334 if (startValue.indexOf(thymol.thBlock.endName) < 0 || startValue.indexOf(thymol.thBlock.endSynonym) < 0) {
1335 fullText = fullText.replace(res[0], res[1]);
1338 next = startComment;
1340 next = next.nextSibling;
1342 deletions.push(next);
1343 if (i < indexOfLast) {
1344 if (next == comments[i + 1]) {
1345 commentText = next.nodeValue;
1346 if (commentText.indexOf(thymol.thBlock.endName) >= 0 || commentText.indexOf(thymol.thBlock.endSynonym) >= 0) {
1347 res2 = commentText.match(prototypeOnlyCommentEscpExpr);
1349 commentText = commentText.replace(res2[0], res2[1]);
1350 fullText = fullText + commentText;
1355 innerNodes.push(next);
1362 blockElement = null;
1363 blockDoc = new thymol.thDomParser().parseFromString(fullText, "text/html");
1364 blockDocBody = $(blockDoc).find("body")[0];
1365 for (j = 0, jLimit = blockDocBody.childNodes.length; j < jLimit; j++) {
1366 if (blockDocBody.childNodes[j].localName == thymol.thBlock.name || blockDocBody.childNodes[j].localName == thymol.thBlock.synonym) {
1367 blockElement = blockDocBody.childNodes[j];
1368 for (k = 0, kLimit = innerNodes.length; k < kLimit; k++) {
1369 newNode = blockDoc.importNode(innerNodes[k], true);
1370 blockElement.appendChild(newNode);
1374 if (blockElement != null) {
1375 blockBase = new ThNode(blockDoc, false, null, null, null, blockDoc.nodeName, "::", false, blockDoc);
1376 this.processChildren(blockBase);
1377 changed = this.insertUncommented(blockBase.thDoc, deletions, parent);
1379 parent.removeChild(startComment);
1383 parent.removeChild(startComment);
1388 startValue = startValue.substring(3, startValue.length - 3);
1389 newDoc = new thymol.thDomParser().parseFromString(startValue, "text/html");
1390 changed = this.insertUncommented(newDoc, deletions, parent);
1397 insertUncommented: function(doc, deletions, parent) {
1398 var docBody = $(doc).find("body")[0], i, iLimit, newNode;
1399 for (i = 0, iLimit = docBody.childNodes.length; i < iLimit; i++) {
1400 if (parent.ownerDocument === doc) {
1401 newNode = docBody.childNodes[i].cloneNode(true);
1403 newNode = parent.ownerDocument.importNode(docBody.childNodes[i], true);
1404 newNode.parentNode = parent;
1406 parent.insertBefore(newNode, deletions[0]);
1408 for (i = 0, iLimit = deletions.length; i < iLimit; i++) {
1409 parent.removeChild(deletions[i]);
1413 getList: function(element, content) {
1414 var argValue = content.trim(), argsCount = 0, argsList = [], assigs, i, iLimit, val;
1416 assigs = argValue.split(",");
1417 for (i = 0, iLimit = assigs.length; i < iLimit; i++) {
1418 val = thymol.getExpression(assigs[i], element);
1421 if (!element.thLocalVars) {
1422 element.thLocalVars = {};
1424 element.thLocalVars["..."] = argsList;
1425 argsCount = argsList.length;
1429 testParam: function(param) {
1430 var initial = param, result = false, theParam = null, negate = false;
1431 if (typeof initial === "boolean") {
1436 if (typeof initial === "object" && initial instanceof thymol.ThParam) {
1439 initial = initial.valueOf();
1440 if (initial.charAt(0) == "!") {
1442 initial = initial.substring(1);
1445 theParam = thymol.applicationContext[initial];
1446 if (theParam != null) {
1447 result = theParam.getBooleanValue();
1453 return result ? true : false;
1455 processImport: function(element, rootNode, attr) {
1456 var importNode = null, filePart, fragmentPart, names, parts, fragmentArgsList, isNode, fragment, fileName, content, importError;
1458 if (attr.value.indexOf("::") < 0) {
1459 filePart = attr.value;
1460 fragmentPart = "::";
1462 names = attr.value.split("::");
1463 filePart = names[0].trim();
1464 fragmentPart = names[1].trim();
1466 if ("this" === filePart) {
1469 filePart = this.getFilePath(filePart, element);
1471 if (filePart != null) {
1472 parts = filePart.match(varParExpr);
1473 fragmentArgsList = null;
1475 if (parts.length > 1) {
1476 filePart = parts[1].trim();
1478 if (parts.length > 2) {
1479 fragmentArgsList = parts[2].trim();
1482 if (filePart != "" || !isFragmentChild(element)) {
1483 isNode = thymol.thReplace.name == attr.localName || thymol.thReplace.synonym == attr.localName || thymol.thSubstituteby.name == attr.localName || thymol.thSubstituteby.synonym == attr.localName;
1484 if (thymol.thCache[filePart] != null && thymol.thCache[filePart][fragmentPart] != null) {
1485 isNode = isNode || fragmentPart == "::";
1486 importNode = new ThNode(thymol.thCache[filePart][fragmentPart], false, rootNode, null, null, filePart, fragmentPart, isNode, element);
1490 if (filePart != "") {
1491 fileName = filePart + thymol.templateSuffix;
1492 $.get(fileName, function(textContent, status) {
1494 if ("success" == status) {
1495 content = new thymol.thDomParser().parseFromString(textContent, "text/html");
1496 fragment = Thymol.prototype.getImportNode(element, filePart, fragmentPart, fragmentArgsList, content);
1497 } else if (thymol.debug) {
1498 thymol.thWindow.alert("thymol.processImport file read failed: " + filePart + " fragment: " + fragmentPart);
1505 fragment = this.getImportNode(element, filePart, fragmentPart, fragmentArgsList, thymol.thDocument);
1507 if (fragment == null) {
1508 if (importError !== null) {
1512 thymol.thWindow.alert("thymol.processImport fragment import failed: " + filePart + " fragment: " + fragmentPart);
1515 importNode = new ThNode(fragment, false, rootNode, null, null, filePart, fragmentPart, isNode, element);
1520 element.removeAttribute(attr.name);
1523 getImportNode: function(element, filePart, fragmentArg, fragmentArgsList, content) {
1524 var result = null, fragmentName = fragmentArg.trim(), fragmentPart = fragmentName, parts, argsCount, matched, fragment, htmlContent, fragArray, i, iLimit, j, jLimit, k, clean, bare, vlParts, vlArgs, argsList, varName, newElement;
1525 fragmentName = fragmentName.replace(/text\(\)/g, textFuncSynonym);
1526 parts = fragmentName.match(varParExpr);
1527 if (parts == null && fragmentArgsList != null) {
1529 parts[1] = fragmentName;
1530 parts[2] = fragmentArgsList;
1534 if (parts.length > 1) {
1535 fragmentName = parts[1].trim();
1536 if (parts.length > 2) {
1537 if (parts[2].indexOf("=") > 0) {
1538 argsCount = thymol.getWith(element, parts[2]);
1540 argsCount = this.getList(element, parts[2]);
1545 if (thymol.thCache[filePart] == null) {
1546 thymol.thCache[filePart] = new Object();
1550 if (fragmentName == "::") {
1551 htmlContent = $("html", content)[0];
1552 result = htmlContent;
1555 fragArray = $(thymol.thFragment.escpName, content);
1556 for (i = 0, iLimit = fragArray.length; i < iLimit; i++) {
1557 fragment = fragArray[i];
1558 for (j = 0, jLimit = fragment.attributes.length; j < jLimit; j++) {
1559 clean = fragment.attributes[j];
1560 clean = clean.value.replace(/\s/g, "");
1562 vlParts = clean.match(varParExpr);
1564 if (vlParts.length > 1) {
1565 bare = vlParts[1].trim();
1568 if (fragmentName == bare && argsCount > 0) {
1569 if (vlParts.length > 2) {
1570 vlArgs = vlParts[2].trim().split(",");
1572 if (vlArgs.length == argsCount) {
1573 argsList = element.thLocalVars["..."];
1574 if (argsList != null) {
1575 for (k = 0; k < argsCount; k++) {
1576 varName = vlArgs[k].trim();
1577 element.thLocalVars[varName] = argsList[k];
1579 element.thLocalVars["..."] = null;
1583 } else if (vlArgs.length > argsCount) {
1589 if (fragmentName == clean || fragmentPart == clean || fragmentName == bare) {
1601 fragment = this.getDOMSelection(fragmentName, content);
1606 if (!element.isBlockChild) {
1607 throw new thymol.ThError('getImportNode cannot match fragment: "' + fragmentName + '"', element);
1611 thymol.thCache[filePart][fragmentPart] = result;
1613 newElement = result.cloneNode(true);
1614 if (newElement.nodeType == 1) {
1615 newElement.removeAttribute(thymol.thFragment.name);
1616 newElement.removeAttribute(thymol.thFragment.synonym);
1618 result = newElement;
1619 result.thLocalVars = element.thLocalVars;
1623 getDOMSelection: function(initial, content) {
1624 var spec = initial, result = null, scope = "", query = new Array(), parts = "", innr = thymol.ThUtils.unBracket(spec), i, iLimit, j, jLimit, k, kLimit, m, mLimit, token, indx, saved, indxed, start, selection, descend, subQuery, exprFrags, classSpecs, qTerms, subSelect, partial, html, newNode;
1625 if (spec != innr && innr.charAt(innr.length - 1) == "]") {
1628 while (spec != "") {
1629 parts = spec.match(domSelectExpr);
1630 if (parts != null && parts.length > 1) {
1631 for (i = 1, iLimit = parts.length; i < iLimit; i++) {
1632 if (parts[i] != null) {
1635 innr = thymol.ThUtils.unBracket(token);
1636 if (token != innr) {
1637 if (innr.match(numericExpr)) {
1642 spec = spec.replace(token, "");
1643 if (saved == spec) {
1647 token = query[query.length - 1];
1648 indxed = new String(token);
1650 query[query.length - 1] = indxed;
1652 query.push(token.trim());
1662 if (query.length > 0 && query[0] != "" && query[0].charAt(0) == "/") {
1667 selection.push(content);
1669 for (i = start, iLimit = query.length; i < iLimit; i++) {
1670 subQuery = query[i];
1671 innr = thymol.ThUtils.unBracket(subQuery);
1672 if (subQuery != innr) {
1673 innr = innr.replace(/[']/g, '"');
1675 exprFrags = innr.split(/\s{1}\s*((?:and)|(?:or))\s{1}\s*/);
1676 for (j = 0, jLimit = exprFrags.length; j < jLimit; j++) {
1677 if (exprFrags[j] != "and" && exprFrags[j] != "or") {
1678 classSpecs = exprFrags[j].match(/[@]?\s*(?:class)\s*(\W?[=])\s*[\"]((?:\w*[\-_]*)*)[\"]/);
1679 if (classSpecs && classSpecs.length > 0) {
1680 if (classSpecs[1] == "=") {
1681 subQuery = subQuery + "[class~='" + classSpecs[2] + "']";
1683 if (classSpecs[1] == "^=") {
1684 subQuery = subQuery + "[class^='" + classSpecs[2] + "'],[class*=' " + classSpecs[2] + "']";
1687 subQuery = subQuery + "[" + exprFrags[j] + "]";
1689 } else if (exprFrags[j] == "or") {
1690 subQuery = subQuery + ",";
1694 qTerms = subQuery.split("/");
1695 for (j = 0, jLimit = qTerms.length; j < jLimit; j++) {
1696 if (qTerms[j] != "") {
1697 qTerms[j] = qTerms[j].replace(/[@]/g, "");
1698 if (subQuery.indx != null) {
1699 qTerms[j] = qTerms[j] + ":eq(" + subQuery.indx + ")";
1702 for (k = 0, kLimit = selection.length; k < kLimit; k++) {
1704 if (qTerms[j] == textFuncSynonym) {
1705 partial = $(selection[k]).contents().filter(function() {
1706 return this.nodeType === 3;
1708 } else if (descend) {
1709 partial = $(selection[k]).children(qTerms[j]);
1710 } else if (j == 0) {
1712 html = $("html", selection[k]);
1713 if (html.length > 0) {
1714 selection[k] = html;
1716 partial = $(selection[k]).children("body").children(qTerms[j]);
1719 if (i == 0 || scope == "//") {
1720 partial = $(selection[k]).find(qTerms[j]);
1723 partial = $(selection[k]).filter(qTerms[j]);
1727 partial = $(selection[k]).children(qTerms[j]);
1729 if (partial != null) {
1730 for (m = 0, mLimit = partial.length; m < mLimit; m++) {
1731 subSelect.push(partial[m]);
1735 selection = subSelect;
1738 descend = qTerms[qTerms.length - 1] == "";
1741 if (result != null && !(result.length === undefined)) {
1742 if (result.length > 1) {
1743 newNode = thymol.thDocument.createDocumentFragment();
1744 for (i = 0, iLimit = result.length; i < iLimit; i++) {
1745 var newChild = thymol.thDocument.importNode(result[i], true);
1746 newNode.appendChild(newChild);
1755 getFilePath: function(part, element) {
1756 var result = thymol.substitute(part, element), mapped = null, slashpos;
1758 if (thymol.mappings) {
1759 mapped = thymol.getMapped(result, false);
1765 var dotFirst = result.charAt(0) === ".";
1766 if (result && (thymol.useAbsolutePath || !dotFirst)) {
1767 slashpos = result.indexOf("/");
1768 if (thymol.useAbsolutePath || slashpos >= 0) {
1769 if (slashpos == 0 && !thymol.useAbsolutePath) {
1770 result = result.substring(1);
1773 if (thymol.useAbsolutePath) {
1774 proto = thymol.protocol;
1776 if (thymol.useAbsolutePath && !!thymol.absolutePath) {
1777 result = proto + thymol.absolutePath + result;
1780 result = thymol.templatePath + result;
1782 result = proto + thymol.root + thymol.path + result;
1790 doLiteralSubstExpr: function(param, primary) {
1791 var result = param.trim(), term, subst, lsp;
1792 if (thymol.ThUtils.isLiteralSubst(result)) {
1793 result = this.decodeLiteralSubst(result);
1796 while (term != null) {
1797 if (thymol.ThUtils.isLiteralSubst(term)) {
1798 subst = this.decodeLiteralSubst(term);
1799 result = result.replace(term, subst);
1800 lsp = result.match(litSubstExpr);
1801 if (lsp && lsp.length > 0) {
1813 decodeLiteralSubst: function(param) {
1814 var result = param, parts, rep, i, iLimit;
1815 result = result.trim();
1816 result = result.substring(1, result.length - 1);
1817 result = result.replace(/[\']/g, "'");
1818 parts = result.split(varRefExpr);
1819 if (parts && parts.length > 0) {
1821 for (i = 0, iLimit = parts.length; i < iLimit; i++) {
1822 if (parts[i] != "") {
1823 if (!parts[i].match(varRefExpr)) {
1824 parts[i] = "'" + parts[i] + "'";
1829 rep = rep + "+" + parts[i];
1837 doReplace: function(isNode, element, content) {
1839 var parent = element.parentNode;
1840 if (content.nodeName.toLowerCase() == "html") {
1841 this.doInsertion(element, content, function(e, n) {
1842 if (n.nodeType == 1) {
1843 n.removeAttribute(thymol.thFragment.name);
1844 n.removeAttribute(thymol.thFragment.synonym);
1846 e.parentNode.insertBefore(n, e);
1848 parent.removeChild(element);
1850 var node = this.doClone(content, parent.ownerDocument);
1851 if (node.nodeType == 1) {
1852 node.removeAttribute(thymol.thFragment.name);
1853 node.removeAttribute(thymol.thFragment.synonym);
1855 parent.replaceChild(node, element);
1856 node.parentNode = parent;
1860 while (element.firstChild != null) {
1861 element.removeChild(element.firstChild);
1862 if (element.firstChild == null) {
1866 this.doInsertion(element, content, function(e, n) {
1867 if (n.nodeType == 1) {
1868 n.removeAttribute(thymol.thFragment.name);
1869 n.removeAttribute(thymol.thFragment.synonym);
1874 element.innerHTML = content.innerHTML;
1878 doClone: function(old, targetDoc) {
1879 var node, cNodes, i, iNode, aNode;
1880 if (!!old.parentNode && old.parentNode.ownerDocument === targetDoc) {
1881 node = old.cloneNode(false);
1883 node = targetDoc.importNode(old, false);
1885 if (node !== null) {
1886 if (node.nodeType == 1) {
1887 if (old.thLocalVars !== null) {
1888 node.thLocalVars = old.thLocalVars;
1891 if (old.childNodes !== null) {
1892 cNodes = old.childNodes.length;
1894 for (i = 0; i < cNodes; i++) {
1895 iNode = old.childNodes[i];
1896 if (iNode !== null) {
1897 aNode = this.doClone(iNode, targetDoc);
1898 if (aNode !== null) {
1899 node.appendChild(aNode);
1908 doInsertion: function(element, content, func) {
1909 var topLevel = true, parent = element.parentElement, i, iLimit, iNode, elementName, j, jLimit, jNode, cJNode, cINode;
1910 if (parent != null) {
1911 topLevel = element.parentElement.nodeName.toLowerCase() == "html";
1913 for (i = 0, iLimit = content.childNodes.length; i < iLimit; i++) {
1914 iNode = content.childNodes[i];
1917 elementName = iNode.nodeName.toLowerCase();
1918 if (elementName != "head") {
1919 if (elementName == "body") {
1920 for (j = 0, jLimit = iNode.childNodes.length; j < jLimit; j++) {
1921 jNode = iNode.childNodes[j];
1923 cJNode = this.doClone(jNode, parent.ownerDocument);
1924 func(element, cJNode);
1928 cINode = this.doClone(iNode, parent.ownerDocument);
1929 func(element, cINode);
1933 cINode = this.doClone(iNode, parent.ownerDocument);
1934 func(element, cINode);
1939 getThParam: function(paramName, isBoolean, isPath, defaultValue) {
1940 var localValue = defaultValue, globalValue = thymol.thWindow[paramName], theParam = thymol.ThUtils.getParameter(paramName);
1941 if (typeof globalValue === "undefined") {
1942 globalValue = thymol.applicationContext.javascriptify(paramName);
1945 if (theParam instanceof ThParam) {
1946 if (theParam.globalValue !== globalValue) {
1947 theParam.globalValue = globalValue;
1948 theParam.value = globalValue;
1949 localValue = globalValue;
1953 localValue = theParam.getBooleanValue();
1956 if (!(typeof globalValue === "undefined")) {
1957 if (globalValue != null) {
1959 localValue = globalValue == true;
1961 localValue = globalValue;
1966 if (!isBoolean && isPath && localValue.length > 0 && localValue.charAt(localValue.length - 1) != "/") {
1967 localValue = localValue + "/";
1969 thymol.applicationContext.createVariable(paramName, localValue);
1973 function addDialect(spec) {
1974 var i, iLimit, prec = thymol.thDefaultPrecedence;
1975 if (spec !== null && typeof spec !== "undefined") {
1976 if (spec.attributeProcessors !== null && typeof spec.attributeProcessors !== "undefined") {
1977 for (i = 0, iLimit = spec.attributeProcessors.length; i < iLimit; i++) {
1978 if (spec.attributeProcessors[i].precedence !== null && typeof spec.attributeProcessors[i].precedence !== "undefined") {
1979 prec = spec.attributeProcessors[i].precedence;
1981 prec = thymol.thDefaultPrecedence;
1983 configureAttributeProcessor(spec.prefix, spec.attributeProcessors[i].name, spec.attributeProcessors[i].processor, prec, null);
1986 if (spec.elementProcessors !== null && typeof spec.elementProcessors !== "undefined") {
1987 for (i = 0, iLimit = spec.elementProcessors.length; i < iLimit; i++) {
1988 configureElementProcessor(spec.prefix, spec.elementProcessors[i].name, spec.elementProcessors[i].processor);
1991 if (spec.objects !== null && typeof spec.objects !== "undefined") {
1992 for (i = 0, iLimit = spec.objects.length; i < iLimit; i++) {
1993 if (spec.objects[i].name !== null && typeof spec.objects[i].name !== "undefined") {
1994 spec.objects[i].object.thExpressionObjectName = spec.objects[i].name;
1995 configureModule(spec.objects[i].object);
1997 configureModule(spec.objects[i]);
2003 function ThNode(thDocParam, visitedParam, parentDocParam, firstChildParam, nextSiblingParam, fileNameParam, fragNameParam, isNodeParam, elementParam) {
2004 this.thDoc = thDocParam;
2005 this.visited = visitedParam;
2006 this.parentDoc = parentDocParam;
2007 this.firstChild = firstChildParam;
2008 this.nextSibling = nextSiblingParam;
2009 this.fileName = fileNameParam;
2010 this.fragName = fragNameParam;
2011 this.isNode = isNodeParam;
2012 this.element = elementParam;
2014 function ThError(message, element, source) {
2015 this.name = "ThError";
2016 this.message = message || "Default Message";
2017 if (element !== null && typeof element !== "undefined" && element.isBlockChild) {
2018 this.suppress = true;
2020 this.element = element || {};
2021 this.suppress = false;
2024 if (!!source.stack) {
2025 this.stack = source.stack;
2029 ThError.prototype = new Error();
2030 ThError.prototype.constructor = ThError;
2031 function ThParam(valueArg) {
2032 this.value = valueArg;
2034 this["class"] = new thymol.ThClass("Thymol.ThParam");
2035 this.getBooleanValue = function() {
2036 return !thymol.ThUtils.testLiteralFalse(this.value);
2038 this.toString = function() {
2041 this.getNumericValue = function() {
2042 return Number(this.value);
2045 function ThAttr(suffix, func, prec, list, pref, dataAttr) {
2046 var prefix = "", dataPrefix = null, escpPrefix = "";
2047 if (typeof pref !== "undefined" && pref !== null) {
2048 prefix = pref + ":";
2049 if (thymol.thThymeleafPrefixList.indexOf(prefix) < 0) {
2050 thymol.thThymeleafPrefixList.push(prefix);
2052 escpPrefix = pref + "\\:";
2053 if (typeof dataAttr === "undefined" || dataAttr === null) {
2054 dataPrefix = thymol.dataPrefix + "-" + pref + "-";
2055 if (thymol.thThymeleafPrefixList.indexOf(dataPrefix) < 0) {
2056 thymol.thThymeleafPrefixList.push(dataPrefix);
2059 dataPrefix = dataAttr;
2062 this.suffix = suffix;
2063 this.name = prefix + suffix;
2065 if (suffix.indexOf("*") >= 0 || suffix.indexOf("?") >= 0 || suffix.indexOf("+") >= 0 || suffix.indexOf("\\") >= 0 || suffix.indexOf("|") >= 0 || suffix.indexOf("[") >= 0 || suffix.indexOf("]") >= 0 || suffix.indexOf("{") >= 0 || suffix.indexOf("}") >= 0) {
2066 if ("*" === suffix) {
2069 suffix = prefix + suffix;
2070 this.regex = new RegExp(suffix);
2072 this.escpName = "[" + escpPrefix + suffix + "]";
2073 if (dataPrefix !== null) {
2074 this.synonym = dataPrefix + suffix;
2075 this.escpSynonym = "[" + this.synonym + "]";
2077 this.synonym = null;
2078 this.escpSynonym = null;
2080 if (typeof prec !== "undefined" && prec !== null) {
2081 this.precedence = prec;
2083 this.precedence = thymol.thDefaultPrecedence;
2086 var attrList = list[pref];
2089 list[pref] = attrList;
2090 if (dataPrefix !== null) {
2091 list[dataPrefix] = attrList;
2094 attrList.push(this);
2096 this.process = function() {
2097 thymol.thWindow.alert('unsupported processing function for attribute "' + this.name + '"');
2099 if (!(typeof func === "undefined")) {
2100 this.process = func;
2102 this.disable = function() {
2104 this.escpName = null;
2105 this.escpSynonym = null;
2106 this.process = function() {};
2109 function ThElement(suffix, func, pref) {
2110 var tha = new thymol.ThAttr(suffix, null, 0, null, pref);
2111 this.name = tha.name;
2112 this.synonym = tha.synonym;
2113 this.endName = "/" + tha.name;
2114 this.endSynonym = "/" + tha.synonym;
2115 this.process = function() {
2116 thymol.thWindow.alert('unsupported processing function for element "' + this.name + '"');
2118 if (!(typeof func === "undefined")) {
2119 this.process = func;
2121 this.disable = function() {
2123 this.synonym = null;
2124 this.endName = null;
2125 this.endSynonym = null;
2126 this.process = null;
2128 thymol.thThymeleafElementsList.push(this);
2133 this.isContent = function(k) {
2134 return this.hasOwnProperty(k) && typeof this[k] !== "function" && k !== "that" && k !== "setSize";
2136 this.add = function(k) {
2137 var contained = typeof this[k] !== "undefined";
2139 if (contained !== (typeof this[k] !== "undefined")) {
2143 this.addAll = function(other) {
2144 var k = null, value;
2146 if (other.hasOwnProperty(k)) {
2148 if (typeof value !== "function") {
2154 this.clear = function() {
2155 for (var k in this) {
2156 if (this.hasOwnProperty(k)) {
2162 this.contains = function(k) {
2163 return typeof this[k] !== "undefined";
2165 this.containsAll = function(keys) {
2166 var keySet = keys, k = null;
2167 if (typeof keys === "Array" || Object.prototype.toString.call(keys) === "[object Array]") {
2168 keySet = ThSet.prototype.fromArray(keys);
2171 if (keySet.hasOwnProperty(k)) {
2172 if (typeof this[k] === "undefined") {
2179 this.isEmpty = function() {
2180 return this.setSize === 0;
2182 this.size = function() {
2183 return this.setSize;
2185 this.remove = function(k) {
2186 var contained = typeof this[k] !== "undefined";
2188 if (contained !== (typeof this[k] !== "undefined")) {
2192 this.toArray = function() {
2193 return getArray(this);
2195 this.toString = function() {
2196 var array = getArray();
2197 return array.toString();
2199 function getArray(obj) {
2200 var array = [], k = null, value;
2202 if (obj.hasOwnProperty(k) && k !== "that" && k !== "setSize") {
2204 if (typeof value !== "function") {
2212 ThSet.prototype.fromArray = function(array) {
2213 var set = new thymol.ThSet(), i, iLimit;
2214 for (i = 0, iLimit = array.length; i < iLimit; i++) {
2221 this.containsKey = function(k) {
2222 return this.contains(k);
2224 this.containsValue = function(target) {
2225 var k = null, value;
2226 for (k in this.that) {
2227 if (this.that.hasOwnProperty(k) && k !== "that") {
2228 value = this.that[k];
2229 if (value === target) {
2236 this.entrySet = function() {
2239 this.get = function(k) {
2240 return this.that[k];
2242 this.keySet = function() {
2245 this.put = function(k, v) {
2246 var contained = typeof this[k] !== "undefined";
2248 if (contained !== (typeof this[k] !== "undefined")) {
2252 this.putAll = function(t) {
2257 this.values = function() {
2261 ThMap.prototype = new ThSet();
2262 ThMap.prototype.constructor = ThMap;
2263 function ThObject(dolly) {
2264 for (prop in dolly) {
2265 if (dolly.hasOwnProperty(prop)) {
2268 this[prop] = dolly[prop];
2273 this["class"] = new thymol.ThClass("Thymol.ThObject");
2274 this.toNonThObject = function() {
2276 for (prop in this) {
2277 if (this.hasOwnProperty(prop)) {
2280 if (prop !== "toNonThObject") {
2281 if (prop !== "class" || prop === "class" && this[prop] !== null && this[prop].name !== "Thymol.ThObject") {
2282 plain[prop] = this[prop];
2292 function ThVarsAccessor(storeArg, storeNameArg) {
2293 this.store = storeArg;
2294 this.arrayName = storeNameArg;
2295 this.length = function() {
2296 return this.store.length;
2298 this.get = function(name) {
2299 return this.store[name];
2301 this.set = function(name, value) {
2302 this.store[name] = value;
2305 function ThClass(nValue) {
2313 ThElement: ThElement,
2317 ThVarsAccessor: ThVarsAccessor,
2319 thDomParser: thymol.thDomParser,
2320 thDocument: thymol.thDocument,
2321 thWindow: thymol.thWindow,
2322 thTop: thymol.thTop,
2323 thRequest: thymol.thRequest,
2324 thVersion: thymol.thVersion,
2325 thReleaseDate: thymol.thReleaseDate,
2326 thURL: thymol.thURL,
2327 thAltURL: thymol.thAltURL,
2328 thInclude: thymol.thInclude,
2329 thReplace: thymol.thReplace,
2330 thSubstituteby: thymol.thSubstituteby,
2331 thFragment: thymol.thFragment,
2332 thRemove: thymol.thRemove,
2333 thBlock: thymol.thBlock,
2334 thScriptName: thymol.thScriptName,
2335 thDefaultPrefix: thymol.thDefaultPrefix,
2336 thDefaultDataPrefix: thymol.thDefaultDataPrefix,
2337 thDefaultPrecision: thymol.thDefaultPrecision,
2338 thDefaultProtocol: thymol.thDefaultProtocol,
2339 thDefaultLocale: thymol.thDefaultLocale,
2340 thDefaultPrecedence: thymol.thDefaultPrecedence,
2341 thDefaultMessagePath: thymol.thDefaultMessagePath,
2342 thDefaultResourcePath: thymol.thDefaultResourcePath,
2343 thDefaultMessagesBaseName: thymol.thDefaultMessagesBaseName,
2344 thDefaultRelativeRootPath: thymol.thDefaultRelativeRootPath,
2345 thDefaultExtendedMapping: thymol.thDefaultExtendedMapping,
2346 thDefaultLocalMessages: thymol.thDefaultLocalMessages,
2347 thDefaultDisableMessages: thymol.thDefaultDisableMessages,
2348 thDefaultTemplateSuffix: thymol.thDefaultTemplateSuffix,
2349 thThymeleafPrefixList: thymol.thThymeleafPrefixList,
2350 thThymeleafElementsList: thymol.thThymeleafElementsList,
2351 thLocation: thymol.thLocation,
2352 messagePath: thymol.messagePath,
2353 resourcePath: thymol.resourcePath,
2354 relativeRootPath: thymol.relativeRootPath,
2355 messagesBaseName: thymol.messagesBaseName,
2356 extendedMapping: thymol.extendedMapping,
2357 scriptPath: thymol.scriptPath,
2358 absolutePath: thymol.absolutePath,
2359 useAbsolutePath: thymol.useAbsolutePath,
2360 useFullURLPath: thymol.useFullURLPath,
2361 localMessages: thymol.localMessages,
2362 indexFile: thymol.indexFile,
2363 disableMessages: thymol.disableMessages,
2364 templateSuffix: thymol.templateSuffix,
2365 prefix: thymol.prefix,
2366 dataPrefix: thymol.dataPrefix,
2367 templateName: thymol.templateName,
2368 templatePath: thymol.templatePath,
2369 objects: thymol.objects,
2371 isClientSide: isClientSide,
2373 updatePrefix: updatePrefix,
2376 addDialect: addDialect,
2377 isFragmentChild: isFragmentChild,
2378 preProcess: preProcess,
2379 substitute: substitute,
2380 substituteParam: substituteParam,
2381 configureModule: configureModule,
2382 configureAttributeProcessor: configureAttributeProcessor,
2383 configureElementProcessor: configureElementProcessor,
2384 configurePreExecution: configurePreExecution,
2385 configurePostExecution: configurePostExecution,
2386 getStandardURL: getStandardURL,
2387 getMessage: getMessage,
2388 getExpression: getExpression,
2390 getParsedExpr: getParsedExpr,
2391 getLocale: getLocale,
2392 getMapped: getMapped,
2393 getBooleanValue: getBooleanValue,
2394 setLocale: setLocale
2398 thymol.makeContext = function(contextNameParam, varAccessorParam) {
2399 var jsonDeclSpec = "(?:\\W*([\\'][A-Za-z]+(?:\\w|[$])*[\\'])\\s*[:])?\\s*([#][A-Za-z]+(?:\\w|[$])*)(?:\\W|[^$])*", jsonDeclExpr = new RegExp(jsonDeclSpec), context = new Array();
2400 context.contextName = contextNameParam;
2401 context.varAccessor = varAccessorParam;
2402 context.varStore = [];
2403 context.varNamePrefix = "";
2404 if (typeof varAccessorParam === "undefined") {
2405 context.varAccessor = new thymol.ThVarsAccessor(context.varStore, "varStore");
2407 context.varNamePrefix = context.varAccessor.arrayName + "[";
2408 context.getJSONView = function(param, rootVal) {
2409 var pType = typeof param, view = "", objType;
2410 if (pType === "string") {
2411 view = view + "'" + param + "'";
2412 } else if (pType === "number" || pType === "boolean") {
2413 view = view + param;
2414 } else if (pType === "object") {
2415 if (param instanceof Object) {
2416 objType = Object.prototype.toString.call(param);
2417 if ("[object Array]" === objType) {
2418 view = this.getJSONViewArray(param, false);
2419 } else if ("[object Object]" === objType) {
2420 view = this.getJSONViewObject(param, false);
2427 context.init = function() {
2428 var persisted = thymol.thTop.name, paramRow, paramName, params, i, iLimit, paramValue;
2429 if (persisted && persisted !== "") {
2430 params = this.javascriptify(persisted);
2431 if (params && params.length > 0) {
2432 for (i = 0, iLimit = params.length; i < iLimit; i++) {
2433 paramRow = params[i];
2435 paramName = paramRow[0];
2437 paramValue = paramRow[1];
2438 this.createVariable(paramName, paramValue);
2445 context.getJSONViewObject = function(param, rootVal) {
2446 var isRoot = true, key = null, view = "{", value, identifier, definition, suffix, instanceNamePrefix, isTaken, i, iLimit, instanceValue;
2447 if (typeof rootVal === "boolean") {
2450 for (key in param) {
2453 if (typeof value !== "function") {
2457 identifier = this.getJSONView(key, false);
2458 definition = this.getJSONView(value, false);
2459 view = view + identifier + ":";
2460 if (!isRoot && typeof value === "object") {
2462 instanceNamePrefix = key + "$";
2463 instanceName = null;
2466 instanceName = instanceNamePrefix + suffix++;
2467 instanceValue = context[instanceName];
2468 if (instanceValue === null || typeof instanceValue === "undefined") {
2470 for (i = 0, iLimit = varStore.length; i < iLimit; i++) {
2471 if (instanceName === varStore[i][0]) {
2477 this.addAttribute(instanceName, definition);
2481 if (instanceName !== null) {
2482 view = view + "#" + instanceName;
2485 view = view + definition;
2493 context.getJSONViewArray = function(param, rootVal) {
2495 for (i = 0; i < param.length; i++) {
2496 view = view + this.getJSONView(param[i], false);
2497 if (i < param.length - 1) {
2504 context.getAttribute = function(name) {
2505 return context[name];
2507 context.addAttribute = function(name, value) {
2511 varStore.push(entry);
2513 context.serialise = function() {
2515 var serialised = "[", key = null, value, cn, view, name, i, iLimit;
2516 for (key in context) {
2518 value = context[key];
2519 if (value != null && typeof value === "object") {
2520 cn = Object.prototype.toString.call(value);
2521 if ("[object Array]" !== cn && !(value instanceof thymol.ThClass) && !(value instanceof thymol.ThVarsAccessor)) {
2522 if (serialised !== "[") {
2523 serialised = serialised + ",";
2525 view = this.getJSONView(value, true);
2526 serialised = serialised + "[";
2527 serialised = serialised + '"' + key + '"';
2528 serialised = serialised + ",";
2529 serialised = serialised + '"' + view + '"';
2530 serialised = serialised + "]";
2535 for (i = 0, iLimit = varStore.length; i < iLimit; i++) {
2536 name = varStore[i][0];
2537 view = varStore[i][1];
2538 serialised = serialised + ",[";
2539 serialised = serialised + '"' + name + '"';
2540 serialised = serialised + ",";
2541 serialised = serialised + '"' + view + '"';
2542 serialised = serialised + "]";
2544 serialised = serialised + "]";
2547 context.javascriptify = function(fn) {
2549 return new Function("return " + fn)();
2554 context.createVariable = function(name, valParam, isReq) {
2555 var value = valParam, param, tt, literalBoolean, strValue, initial, existing, newArray;
2557 if (!(value instanceof thymol.ThParam)) {
2558 tt = typeof valParam;
2559 if (tt !== "function" && tt !== "object") {
2560 if (tt === "string") {
2562 value = isReq ? decodeURIComponent(value) : decodeURI(value);
2565 if (tt === "boolean" || tt === "number") {
2566 param = new thymol.ThParam(value);
2567 } else if (value || value === "") {
2568 literalBoolean = thymol.ThUtils.testLiteralFalse(value);
2569 if (literalBoolean) {
2572 strValue = new String(value);
2573 initial = strValue.trim();
2574 if (initial.charAt(0) === "#") {
2575 initial = initial.substring(1);
2577 param = this.createJSONVariable(initial);
2579 if (err instanceof ReferenceError) {}
2580 if (err instanceof EvalError) {}
2581 if (param == null || isReq) {
2582 param = new thymol.ThParam(value);
2586 param = new thymol.ThParam(strValue.toString());
2593 existing = context[name];
2594 if (typeof existing !== "undefined" && existing !== null) {
2595 if (Object.prototype.toString.call(existing) === "[object Array]") {
2596 existing.push(param);
2599 thymol.thWindow.alert('request parameters should be of type string array "' + name + '"');
2603 newArray = new Array();
2604 newArray["class"] = {};
2605 newArray["class"]["name"] = "[Thymol.ThParam]";
2606 newArray.push(param);
2607 context[name] = newArray;
2610 context[name] = param;
2614 context.createJSONVariable = function(initial) {
2615 var current = initial.trim(), parts = " ", substIndex, token, re, vName, obj, result;
2616 substIndex = this.varAccessor.length() + 1;
2618 parts = current.match(jsonDeclExpr);
2619 if (parts && parts.length > 2) {
2621 token = token.replace(/[\']/g, "[']").replace(/[$]/g, "[$]");
2622 re = new RegExp(token);
2623 vName = this.varNamePrefix + substIndex + "]";
2625 obj.name = parts[2].substring(1);
2626 this.varAccessor.set(substIndex, obj);
2627 substIndex = substIndex + 1;
2628 current = current.replace(re, "'" + vName + "'", "g");
2631 current = current.replace(/[\']/g, '"');
2632 result = $.parseJSON(current);
2633 if ("[object Array]" !== Object.prototype.toString.call(result)) {
2634 result = new thymol.ThObject(result);
2638 context.resolveJSONReferences = function() {
2639 var key = null, param, prop = null, val, ref, subst, isReq = "request" === this.contextName;
2640 for (key in context) {
2642 param = context[key];
2643 if (param != null && typeof param === "object") {
2644 if (!(param instanceof thymol.ThVarsAccessor) && !(param instanceof thymol.ThClass)) {
2645 if (!(param instanceof thymol.ThParam)) {
2646 if (isReq && Object.prototype.toString.call(param) === "[object Array]") {
2647 for (var i = 0, iLimit = param.length; i < iLimit; i++) {
2649 if (!!pi && typeof pi.value === "string" && pi.value.charAt(0) == "#") {
2650 var pv = thymol.ThUtils.getParameter(pi.value.substring(1));
2655 for (prop in param) {
2658 if (typeof val === "string") {
2659 if (val.indexOf(this.varNamePrefix) == 0) {
2661 if (prop.match(/\d*/)) {
2662 ref = val.substring(this.varNamePrefix.length, val.length - 1);
2663 ref = this.varAccessor.get(ref);
2664 subst = context[ref.name];
2666 subst = context[prop];
2668 param[prop] = subst;
2674 } else if (typeof param.value === "string" && param.value.charAt(0) == "#") {
2675 subst = context[param.value.substring(1)];
2676 context[key] = subst;
2686 thymol.ThUtils = function() {
2687 function mergeVars(thiz, other) {
2688 var current = thiz, prop = null;
2692 for (prop in other) {
2693 if (other.hasOwnProperty(prop)) {
2695 if (!current[prop]) {
2696 current[prop] = other[prop];
2703 function processElement(func, element, arg, obj) {
2704 var result = null, parent = element.parentElement;
2705 if (!thymol.isFragmentChild(element)) {
2706 if (!element.thObjectVar) {
2707 parent = element.parentElement;
2709 if (parent.thObjectVar) {
2710 element.thObjectVar = parent.thObjectVar;
2713 parent = parent.parentElement;
2716 parent = element.parentElement;
2718 if (parent.thLocalVars) {
2719 element.thLocalVars = mergeVars(element.thLocalVars, parent.thLocalVars);
2722 parent = parent.parentElement;
2724 result = func(element, arg, obj);
2728 function unQuote(param) {
2729 var par = param, pared;
2731 if (typeof par === "string") {
2733 if (par.charAt(0) == '"') {
2734 if (par.charAt(par.length - 1) == '"') {
2735 pared = par.substring(1, par.length - 1);
2736 if (pairParity(pared, '"', '"') == 0) {
2740 } else if (par.charAt(0) == "'") {
2741 if (par.charAt(par.length - 1) == "'") {
2742 pared = par.substring(1, par.length - 1);
2743 if (pairParity(pared, "'", "'") == 0) {
2752 function unParenthesise(param) {
2753 var par = param, pared;
2755 if (typeof par === "string") {
2757 if (par.charAt(0) == "(") {
2758 if (par.charAt(par.length - 1) == ")") {
2759 pared = par.substring(1, par.length - 1).trim();
2760 if (pairParity(pared, "(", ")") == 0) {
2769 function pairParity(str, left, right) {
2770 var i, ch, strLength = str.length, parity = 0;
2771 for (i = 0; i < strLength; i++) {
2775 } else if (ch == right) {
2784 function unBracket(param) {
2785 var par = param, pared;
2786 if (typeof par === "string") {
2790 if (par.charAt(0) == "[") {
2791 if (par.charAt(par.length - 1) == "]") {
2792 pared = par.substring(1, par.length - 1);
2793 if (pairParity(pared, "[", "]") == 0) {
2801 function getToPrecision(n, p) {
2802 if (typeof p === "undefined") {
2805 var up = thymol.thDefaultPrecision, ndp = 0, s, sl, dp, v;
2811 dp = s.indexOf(".");
2816 v = n.toPrecision(ndp + 1);
2817 v = truncateDecimals(v);
2826 } else if (ndp < up) {
2837 function truncateDecimals(valp) {
2838 var val = valp, iLimit = valp.length - 1, i;
2839 for (i = iLimit; i >= 0; i--) {
2840 if (val.charAt(i) === "0") {
2841 val = val.substr(0, i);
2848 function getDecimalDigits(val) {
2849 var digits = 0, s, dp;
2851 dp = s.indexOf(".") + 1;
2853 digits = s.length - dp;
2857 function testLiteralFalse(initial) {
2858 var result = false, val;
2859 if (typeof initial === "string") {
2860 val = initial.toLowerCase();
2861 result = val == "false" || val == "off" || val == "no";
2862 } else if (typeof initial === "boolean") {
2867 function renderMessage(msg, values) {
2868 var result = msg, i, iLimit;
2869 if (Object.prototype.toString.call(values) == "[object Array]") {
2870 for (i = 0, iLimit = values.length; i < iLimit; i++) {
2871 result = renderMessageArg(result, i, values[i]);
2874 result = renderMessageArg(msg, 0, values);
2878 function renderMessageArg(msg, index, value) {
2879 var result = msg, splits, i, iLimit, iUpper;
2880 splits = msg.split("{" + index + "}");
2881 if (splits.length > 0) {
2883 for (i = 0, iLimit = splits.length, iUpper = iLimit - 1; i < iLimit; i++) {
2884 result += splits[i];
2892 function getParameter(name) {
2894 result = thymol.requestContext[name];
2895 tor = typeof result;
2896 if (tor === "undefined") {
2897 result = thymol.sessionContext[name];
2898 if (typeof result === "undefined") {
2899 result = thymol.applicationContext[name];
2901 } else if (tor === "object") {
2902 if (Object.prototype.toString.call(result) === "[object Array]") {
2903 if (result.length === 1) {
2910 function charOcurrences(str, chr) {
2911 var count = 0, i = 0, iLimit = str.length;
2912 for (;i < iLimit; i++) {
2913 if (str.charAt(i) === chr) {
2919 function isLiteral(val) {
2921 if (typeof val === "string") {
2922 first = val.charAt(0);
2923 last = val.charAt(val.length - 1);
2924 if (first == "'" && last == "'") {
2927 if (first == '"' && last == '"') {
2933 function isLiteralSubst(param) {
2934 var result = false, par = param;
2935 if (typeof par === "string") {
2939 if (par.charAt(0) == "|") {
2940 if (par.charAt(par.length - 1) == "|") {
2947 function loadScript(file) {
2948 var script = thymol.Thymol.prototype.getFilePath(file);
2950 var jqxhr = $.ajax({
2956 }).done(function() {
2958 }).fail(function() {
2962 function unescape(text) {
2963 var result = text, i, iLimit, iUpper, c, cc;
2964 if (text !== null && typeof text !== "undefined") {
2966 iLimit = text.length;
2967 iUpper = iLimit - 3;
2968 for (i = 0; i < iLimit; i++) {
2972 cc = text.charAt(i + 1).toLowerCase();
2973 if ((cc === "g" || cc === "l") && text.charAt(i + 2).toLowerCase() === "t" && text.charAt(i + 3) === ";") {
2980 } else if (i < iUpper - 1 && cc === "a" && text.charAt(i + 2).toLowerCase() === "m" && text.charAt(i + 3).toLowerCase() === "p" && text.charAt(i + 4) === ";") {
2982 } else if (i < iUpper - 2) {
2983 if (cc === "q" && text.charAt(i + 2).toLowerCase() === "u" && text.charAt(i + 3).toLowerCase() === "o" && text.charAt(i + 4).toLowerCase() === "t" && text.charAt(i + 5) === ";") {
2986 } else if (cc === "a" && text.charAt(i + 2).toLowerCase() === "p" && text.charAt(i + 3).toLowerCase() === "o" && text.charAt(i + 4).toLowerCase() === "s" && text.charAt(i + 5) === ";") {
2998 function unicodeUnescape(initial) {
2999 var result = initial.replace(/\\u([\da-f]{4})/gi, function(match, grp) {
3000 return String.fromCharCode(parseInt(grp, 16));
3002 result = unescape(result);
3005 function removeTag(element) {
3006 var parent = element.parentNode, i, iLimit, savedObject = element.thObjectVar, savedLocals = element.thLocalVars;
3008 for (i = 0, iLimit = element.childNodes.length; i < iLimit; i++) {
3009 var newNode = element.childNodes[i].cloneNode(true);
3010 if (newNode.nodeType === 1) {
3011 if (!!savedObject) {
3012 newNode.thObjectVar = savedObject;
3014 if (!!savedLocals) {
3015 newNode.thLocalVars = savedLocals;
3018 parent.insertBefore(newNode, element);
3020 parent.removeChild(element);
3023 function getRequestEncoded(initial) {
3024 var result = initial;
3025 result = encodeURIComponent(result);
3026 result = result.replace(/%20/g, "+");
3027 result = result.replace(/%26/g, "&");
3028 result = result.replace(/%3A/g, ":");
3029 result = result.replace(/!/g, "%21");
3030 result = result.replace(/'/g, "%27");
3031 result = result.replace(/\(/g, "%28");
3032 result = result.replace(/\)/g, "%29");
3033 result = result.replace(/\*/g, "%2A");
3034 result = result.replace(/~/g, "%7E");
3038 getParameter: getParameter,
3039 processElement: processElement,
3041 unParenthesise: unParenthesise,
3042 unBracket: unBracket,
3043 getToPrecision: getToPrecision,
3044 getDecimalDigits: getDecimalDigits,
3045 testLiteralFalse: testLiteralFalse,
3046 renderMessage: renderMessage,
3047 charOcurrences: charOcurrences,
3048 isLiteral: isLiteral,
3049 isLiteralSubst: isLiteralSubst,
3050 loadScript: loadScript,
3052 unicodeUnescape: unicodeUnescape,
3053 removeTag: removeTag,
3054 getRequestEncoded: getRequestEncoded
3058 thymol.ThParser = function(scope) {
3059 function object(o) {
3064 function NullReturn(varName) {
3065 this.varName = varName;
3074 function Token(type_p, index_p, prio_p, number_p, mode_p, meta_p) {
3075 this.type_ = type_p;
3076 this.index_ = index_p || 0;
3077 this.prio_ = prio_p || 0;
3078 this.number_ = number_p !== undefined && number_p !== null ? number_p : 0;
3079 this.mode_ = mode_p !== undefined && mode_p !== null ? mode_p : 0;
3080 this.meta_ = meta_p;
3081 this.toString = function() {
3082 switch (this.type_) {
3084 return this.number_;
3097 return "Invalid Token";
3101 function Expression(tokens, ops1, ops2, functions, precision, position) {
3102 this.tokens = tokens;
3105 this.functions = functions;
3106 this.precision = precision;
3107 this.position = position;
3109 Expression.prototype = {
3110 simplify: function(valuesParam) {
3111 var values = valuesParam || {};
3113 var newexpression = [];
3117 var L = this.tokens.length;
3120 for (i = 0; i < L; i++) {
3121 item = this.tokens[i];
3122 var type_ = item.type_;
3123 if (type_ === TNUMBER) {
3125 } else if (type_ === TVAR && !(item.index_ in new Object()) && item.index_ in values) {
3126 item = new Token(TNUMBER, 0, 0, values[item.index_]);
3128 } else if (type_ === TOP2 && nstack.length > 1) {
3129 f = this.ops2[item.index_];
3133 item = new Token(TNUMBER, 0, 0, f(n1.number_, n2.number_));
3136 } else if (type_ === TOP1 && nstack.length > 0) {
3137 if ("{" == item.index_) {
3138 if (item.mode_ == 2) {
3143 f = this.ops1[item.index_];
3144 item = new Token(TNUMBER, 0, 0, f(n1.number_));
3148 while (nstack.length > 0) {
3149 newexpression.push(nstack.shift());
3151 newexpression.push(item);
3154 while (nstack.length > 0) {
3155 newexpression.push(nstack.shift());
3157 var res = new Expression(newexpression, object(this.ops1), object(this.ops2), object(this.functions), this.precision);
3160 evaluate: function(element) {
3166 var L = this.tokens.length;
3170 for (i = 0; i < L; i++) {
3171 item = this.tokens[i];
3172 if (i === 0 && thymol.disableMessages && item.mode_ === 4) {
3173 var nullReturn = new thymol.ThClass();
3174 nullReturn.abort = true;
3177 var type_ = item.type_;
3178 if (type_ === TNUMBER) {
3179 nstack.push(item.number_);
3183 } else if (type_ === TOP2) {
3185 if (typeof n2 === "undefined" || n2 instanceof NullReturn) {
3189 if (typeof n1 === "undefined" || n1 instanceof NullReturn) {
3192 f = this.ops2[item.index_];
3193 var pathMatch = false;
3195 if (item.mode_ === 6) {
3197 res = n1 + "[" + n2 + "]";
3198 } else if (f === append) {
3200 if (!!item.meta_.paths) {
3201 var values = item.meta_.paths[n1];
3213 if (!item.meta_.params) {
3214 item.meta_.params = [];
3216 var values = item.meta_.params[n1];
3219 item.meta_.params[n1] = values;
3229 if (f === dot && "class" === n2 && !!n1 && !n1["class"]) {
3230 var tn2 = typeof n2;
3231 if (tn2 === "object" && n2 instanceof thymol.ThParam) {
3234 res = new thymol.ThClass("JavaScript:" + tn2);
3238 if (typeof res === "function") {
3240 next = this.tokens[i + 1];
3241 if (next.type_ === TNUMBER && Object.prototype.toString.call(next.number_) == "[object Array]" && next.number_.length == 0) {
3251 if (Object.prototype.toString.call(res) == "[object Array]") {
3252 res.arrayResult = true;
3257 if (!element.isBlockChild) {
3258 var aValue = n1 == null ? "null" : n1;
3259 var bValue = n2 == null ? "null" : n2;
3260 var message = "while evaluating expression: " + this.tokens[i - 2].index_ + ": " + aValue + ", " + this.tokens[i - 1].index_ + ": " + bValue;
3261 throw new thymol.ThError(message, element, err);
3267 } else if (type_ === TVAR) {
3268 var next = null, pushed = nstack.length;
3269 if (item.index_ != null) {
3271 next = this.tokens[i + 1];
3272 if (next.type_ === TOP2 && next.index_ === ".") {
3273 nstack.push(item.index_);
3276 if (pushed === nstack.length) {
3277 var val = thymol.substituteParam(item.index_, item.mode_, element);
3278 if (Object.prototype.toString.call(val) == "[object Array]") {
3279 val.arrayResult = true;
3281 this.updatePrecision(val);
3283 val = new NullReturn(item.index_);
3287 } else if (pushed === nstack.length && item.index_ in this.functions) {
3288 nstack.push(this.functions[item.index_]);
3290 if (!element.isBlockChild) {
3291 throw new thymol.ThError("Exception undefined variable: " + item.index_, element);
3294 } else if (type_ === TOP1) {
3296 if (typeof n1 === "undefined" || n1 instanceof NullReturn) {
3297 if (item.mode_ === 2) {
3304 if ("{" === item.index_) {
3305 var prev = this.tokens[i - 1];
3306 if (prev.mode_ == 7) {
3307 if (thymol.conversionService) {
3308 n1 = thymol.conversionService(n1);
3312 if (typeof n1 === "string") {
3313 if (item.mode_ === 2) {
3314 res = thymol.getStandardURL(n1);
3316 var subst = thymol.substituteParam(n1, item.mode_, element);
3317 if (subst != null) {
3318 this.updatePrecision(subst);
3324 f = this.ops1[item.index_];
3328 if (!element.isBlockChild) {
3329 var aValue = n1 == null ? "null" : n1;
3330 var message = "while evaluating expression: " + this.tokens[i - 2].index_ + ": " + aValue;
3331 throw new thymol.ThError(message, element, err);
3335 if (Object.prototype.toString.call(res) == "[object Array]") {
3336 res.arrayResult = true;
3339 } else if (type_ === TFUNCALL || type_ === MSGSUBST || type_ === ARGLIST) {
3342 if (type_ === MSGSUBST) {
3343 if (f instanceof NullReturn) {
3344 res = "??" + f.varName + "_" + thymol.locale.value + "??";
3346 res = thymol.ThUtils.renderMessage(f, n1);
3349 } else if (type_ === ARGLIST) {
3350 var pathMatch = false;
3352 if (typeof n2 === "undefined") {
3358 if (!!item.meta_.paths) {
3359 var values = item.meta_.paths[f];
3364 for (var j in item.meta_.paths) {
3365 if (item.meta_.paths.hasOwnProperty(j)) {
3366 var values = item.meta_.paths[j];
3367 var isReq = n2.indexOf("?") >= 0;
3368 if (!!values && values.length > 0) {
3369 var pathVar = "{" + j + "}";
3370 var repReg = new RegExp(pathVar, "g");
3373 for (var k = 0, kLimit = values.length; k < kLimit; k++) {
3374 if (rep.length > 0) {
3378 rep = rep + thymol.ThUtils.getRequestEncoded(values[k]);
3380 rep = rep + encodeURIComponent(values[k]);
3383 n2 = n2.replace(repReg, rep);
3392 if (typeof f === "undefined" || f instanceof NullReturn) {
3397 f = thymol.ThUtils.getRequestEncoded(f);
3400 if (f != "?" && n1 != "") {
3404 n1 = thymol.ThUtils.getRequestEncoded(n1);
3407 if (typeof n2 === "undefined" || n2 instanceof NullReturn) {
3415 var separator = res.indexOf("?") >= 0 ? "&" : "?";
3416 for (var j in item.meta_.params) {
3417 if (item.meta_.params.hasOwnProperty(j)) {
3418 var values = item.meta_.params[j];
3419 if (!!values && values.length > 0) {
3420 for (var k = 0, kLimit = values.length; k < kLimit; k++) {
3421 res = res + separator + thymol.ThUtils.getRequestEncoded(j) + "=" + thymol.ThUtils.getRequestEncoded(values[k]);
3429 if (!!item.meta_.urlFragment) {
3430 res = res + item.meta_.urlFragment;
3434 } else if (f.apply && f.call) {
3435 if (!!n1 && !!n1.isDirect) {
3438 if (n1 instanceof NullReturn) {
3441 if (n1 != null && (n1.arrayResult || Object.prototype.toString.call(n1) !== "[object Array]")) {
3442 res = f.call(element, n1);
3444 res = f.apply(element, n1);
3447 if (res instanceof String) {
3448 if (res.precision) {
3449 if (typeof this.precision === "undefined" || res.precision > this.precision) {
3450 this.precision = res.precision;
3453 res = res.toString();
3454 } else if (Object.prototype.toString.call(res) == "[object Array]") {
3455 res.arrayResult = true;
3459 if (!element.isBlockChild) {
3460 throw new thymol.ThError(f + " is not a function", element);
3464 if (!element.isBlockChild) {
3465 throw new thymol.ThError("invalid expression item type: " + type_, element);
3469 if (nstack.length > 1) {
3470 if (!element.isBlockChild) {
3471 throw new thymol.ThError("invalid Expression (parity)", element);
3477 updatePrecision: function(val) {
3478 if (typeof val === "number") {
3479 var p = thymol.ThUtils.getDecimalDigits(val);
3480 if (typeof this.precision === "undefined" || p > this.precision) {
3486 function add(a, b) {
3489 function assign(a) {
3492 function sub(a, b) {
3495 function mul(a, b) {
3498 function div(a, b) {
3501 function mod(a, b) {
3504 function concat(a, b) {
3511 var v = thymol.getBooleanValue(a);
3514 function random(a) {
3515 return Math.random() * (a || 1);
3518 var aa = Math.floor(a);
3525 function append(a, b) {
3527 if (a.arrayResult === true || Object.prototype.toString.call(a) != "[object Array]") {
3532 if (b.arrayResult === true || Object.prototype.toString.call(b) != "[object Array]") {
3543 function equal(a, b) {
3546 function notEqual(a, b) {
3561 function and(a, b) {
3567 function dot(a, b) {
3570 function binary(a, b) {
3571 return a ? b : null;
3573 function elvis(a, b) {
3574 return a != null ? a : b;
3576 function getStr(pos, expression, mode, partial, preprocessed) {
3577 var localMode = mode;
3579 var c = expression.charAt(pos);
3580 var start = pos + 1;
3581 var end = expression.length;
3583 if (localMode === 4 || c === "#") {
3588 var inCurly = false;
3589 var curlyPos = null;
3590 var urlFragPos = -1;
3592 if (localMode !== 4 && c !== "'" && c !== '"') {
3593 for (;i <= end; i++) {
3594 if (c.toUpperCase() === c.toLowerCase()) {
3598 if (meta === null) {
3602 } else if (mode === 2 && c === "#") {
3605 if (i === pos || !inCurly && c === "}" || c !== "_" && c !== "?" && c !== ":" && (c < "0" || c > "9")) {
3606 if (!(partial && c == "-") && !((mode === 2 || mode === 6) && (c === "/" || c === "." || c === "~" || c === "?" || c === "=" || c === ":" || c === "-" || c === "_" || c === "[" || c === "]" || c === "#" || inCurly && c === "{" || inCurly && c === "}")) || mode === 6 && c === "=") {
3611 if (inCurly && c === "}") {
3613 if (meta === null) {
3614 var message = 'bad path variable definition in expression: "' + expression + '" near column ' + pos;
3615 throw new thymol.ThError(message, element);
3617 var curlyVar = expression.substring(curlyPos, i - 1);
3619 meta.paths[curlyVar] = values;
3623 c = expression.charAt(i);
3625 if (urlFragPos >= 0) {
3626 var urlFrag = expression.substring(urlFragPos - 1, i);
3627 s = s.substring(0, s.length - urlFrag.length);
3628 if (meta === null) {
3630 meta.urlFragment = urlFrag;
3635 var preprocessing = false;
3636 if (c === "'" || c === '"') {
3641 if (c === stopChar && i > start && !preprocessing) {
3642 if (localMode !== 4 || quoted) {
3649 var nc = expression.charAt(i);
3650 if (c === "_" && nc === "_" && !preprocessed) {
3651 preprocessing = !preprocessing;
3654 if (nc === "'" && s.charAt(s.length - 1) !== "\\") {
3660 nc = expression.charAt(i);
3665 var exp = thymol.thExpressionObjects[s];
3666 if (typeof exp !== "undefined" && exp !== null) {
3684 var str = new Object();
3687 if (meta !== null) {
3692 function ThParser() {
3694 this.success = false;
3696 this.expression = "";
3698 this.tokennumber = 0;
3700 this.tokenindex = 0;
3767 ThParser.parse = function(expr, partial, preprocessed) {
3768 return new thymol.ThParser().parse(expr, partial, preprocessed);
3770 ThParser.evaluate = function(expr, partial, element) {
3771 return thymol.ThParser.parse(expr, partial, false).evaluate(element);
3773 ThParser.Expression = Expression;
3796 var PRIMARY = 1 << 0;
3797 var OPERATOR = 1 << 1;
3798 var FUNCTION = 1 << 2;
3799 var LPAREN = 1 << 3;
3800 var RPAREN = 1 << 4;
3804 var NULLARY_CALL = 1 << 8;
3805 var LBRACK = 1 << 9;
3806 var RBRACK = 1 << 10;
3807 var LVARBRK = 1 << 11;
3808 var RVARBRK = 1 << 11;
3809 var OPTION = 1 << 12;
3810 var ASSIGN = 1 << 13;
3811 ThParser.prototype = {
3812 parse: function(expr, partial, preprocessed) {
3814 this.success = true;
3816 var tokenstack = [];
3819 var expected = PRIMARY | LPAREN | LVARBRK | FUNCTION | OPERATOR | SIGN | OPTION;
3821 this.expression = expr;
3824 while (this.pos < this.expression.length) {
3825 if (this.isWhite()) {} else if (this.isOperator()) {
3826 if (this.isSign() && expected & SIGN) {
3827 if (this.isNegativeSign()) {
3829 this.tokenindex = "-";
3831 this.addfunc(tokenstack, operstack, TOP1);
3833 expected = PRIMARY | LPAREN | LVARBRK | FUNCTION | SIGN | OPTION;
3834 } else if (this.isAssign() && expected & ASSIGN) {
3836 expected = PRIMARY | LPAREN | LVARBRK | FUNCTION | SIGN | OPTION;
3837 } else if (this.isComment()) {} else {
3838 if (this.tokenindex == "!") {
3839 if ((expected & SIGN) === 0) {
3840 this.error_parsing(this.pos, "unexpected sign");
3843 this.addfunc(tokenstack, operstack, TOP1);
3845 if ((expected & OPERATOR) === 0) {
3846 this.error_parsing(this.pos, "unexpected operator");
3849 this.addfunc(tokenstack, operstack, TOP2);
3851 if (this.expression.charAt(this.pos - 1) === "[") {
3854 expected = PRIMARY | OPERATOR | LPAREN | LVARBRK | FUNCTION | SIGN | OPTION;
3856 } else if (this.isNumber()) {
3857 if ((expected & PRIMARY) === 0) {
3858 this.error_parsing(this.pos, "unexpected number");
3860 var token = new Token(TNUMBER, 0, 0, this.tokennumber);
3861 tokenstack.push(token);
3862 expected = OPERATOR | RPAREN | RBRACK | RVARBRK | COMMA;
3863 } else if (this.isLeftParenth()) {
3864 if ((expected & LPAREN) === 0) {
3865 this.error_parsing(this.pos, 'unexpected "("');
3867 modestack.push(this.mode);
3868 if (expected & CALL) {
3870 this.tokenprio = -2;
3871 this.tokenindex = -1;
3874 if (this.mode === 4) {
3877 } else if (this.mode === 2) {
3880 var url = tokenstack[tokenstack.length - 1];
3884 this.meta = url.meta_;
3888 this.addfunc(tokenstack, operstack, ft);
3891 if (this.mode === 5 || this.mode === 6) {
3894 expected = PRIMARY | OPERATOR | LPAREN | LVARBRK | FUNCTION | SIGN | OPTION | NULLARY_CALL;
3895 } else if (this.isRightParenth()) {
3896 if (expected & NULLARY_CALL) {
3897 var token = new Token(TNUMBER, 0, 0, []);
3898 tokenstack.push(token);
3899 } else if ((expected & RPAREN) === 0) {
3900 this.error_parsing(this.pos, 'unexpected ")"');
3902 if (this.mode === 5 || this.mode === 6) {
3905 this.mode = modestack.pop();
3906 expected = OPERATOR | RPAREN | RBRACK | RVARBRK | COMMA | LPAREN | LVARBRK | CALL | OPTION;
3907 } else if (this.isRightBracket()) {
3908 if ((expected & RBRACK) === 0) {
3909 this.error_parsing(this.pos, 'unexpected "]"');
3911 expected = OPERATOR | RPAREN | RBRACK | RVARBRK | COMMA | LPAREN | LVARBRK | CALL | OPTION;
3912 } else if (this.isLeftVarBrk(modestack)) {
3913 if ((expected & LVARBRK) === 0) {
3914 this.error_parsing(this.pos, 'unexpected "{"');
3917 this.addfunc(tokenstack, operstack, TOP1);
3918 expected = PRIMARY | LPAREN | LVARBRK | FUNCTION | SIGN | OPTION;
3919 } else if (this.isRightVarBrk()) {
3920 if ((expected & RVARBRK) === 0) {
3921 this.error_parsing(this.pos, 'unexpected "}"');
3923 this.mode = modestack.pop();
3924 expected = FUNCTION | OPERATOR | RPAREN | RBRACK | RVARBRK | COMMA | LPAREN | LVARBRK | CALL | OPTION;
3925 } else if (this.isLeftCurly()) {
3926 if (this.mode == 1 || this.mode == 2 || this.mode == 3 || this.mode == 4) {
3927 modestack.push(this.mode);
3930 this.error_parsing(this.pos, 'unexpected "{"');
3932 } else if (this.isRightCurly()) {
3933 if (this.mode == 7) {
3934 this.mode = modestack.pop();
3936 this.error_parsing(this.pos, 'unexpected "}"');
3938 } else if (this.isComma()) {
3939 if ((expected & COMMA) === 0) {
3940 this.error_parsing(this.pos, 'unexpected ","');
3945 if (this.mode === 5 || this.mode === 6) {
3949 this.addfunc(tokenstack, operstack, TOP2);
3951 if (this.mode === 5 || this.mode === 6) {
3955 expected = PRIMARY | LPAREN | LVARBRK | FUNCTION | SIGN | OPTION;
3956 } else if (this.isConst()) {
3957 if ((expected & PRIMARY) === 0) {
3958 this.error_parsing(this.pos, "unexpected constant");
3960 var consttoken = new Token(TNUMBER, 0, 0, this.tokennumber);
3961 tokenstack.push(consttoken);
3962 expected = OPERATOR | RPAREN | RVARBRK | RBRACK | COMMA;
3964 var str = getStr(this.pos, this.expression, this.mode, partial, preprocessed);
3965 if (this.isOpX(str, this.ops2) && (this.mode !== 2 && "/" !== str)) {
3966 if ("and" === str.str || "or" === str.str) {
3969 if ((expected & OPERATOR) === 0) {
3970 this.error_parsing(this.pos, "unexpected binary operator");
3972 this.addfunc(tokenstack, operstack, TOP2);
3974 expected = PRIMARY | LPAREN | LVARBRK | FUNCTION | OPERATOR | SIGN | OPTION;
3975 } else if (this.isOpX(str, this.ops1)) {
3976 if ((expected & OPERATOR) === 0) {
3977 this.error_parsing(this.pos, "unexpected unary operator");
3979 this.addfunc(tokenstack, operstack, TOP1);
3981 expected = PRIMARY | LPAREN | LVARBRK | FUNCTION;
3982 } else if (this.isLiteralValue(str)) {
3983 if ((expected & PRIMARY) === 0) {
3984 this.error_parsing(this.pos, "unexpected literal value");
3986 var token = new Token(TNUMBER, 0, 0, this.tokennumber);
3987 tokenstack.push(token);
3988 expected = FUNCTION | OPERATOR | RPAREN | RBRACK | RVARBRK | COMMA | LPAREN | RVARBRK | LBRACK | CALL | OPTION;
3989 if (this.mode === 6) {
3990 expected = expected | ASSIGN;
3992 } else if (this.isVar(str)) {
3993 if ((expected & PRIMARY) === 0) {
3994 this.error_parsing(this.pos, "unexpected variable");
3996 var vartoken = new Token(TVAR, this.tokenindex, 0, 0, this.mode, str.meta);
3997 tokenstack.push(vartoken);
3998 expected = FUNCTION | OPERATOR | RPAREN | RBRACK | RVARBRK | COMMA | LPAREN | RVARBRK | LBRACK | CALL | OPTION | ASSIGN;
4000 if (this.errormsg === "") {
4001 this.error_parsing(this.pos, "unknown character");
4003 this.error_parsing(this.pos, this.errormsg);
4008 if (this.tmpprio < 0 || this.tmpprio >= 10) {
4009 this.error_parsing(this.pos, 'unmatched "() or []"');
4011 while (operstack.length > 0) {
4012 var tmp = operstack.pop();
4013 tokenstack.push(tmp);
4015 if (noperators + 1 !== tokenstack.length) {
4016 this.error_parsing(this.pos, "parity");
4018 var res = new Expression(tokenstack, object(this.ops1), object(this.ops2), object(this.functions), this.precision, this.pos);
4021 evaluate: function(expr, element) {
4022 return this.parse(expr).evaluate(element);
4024 error_parsing: function(column, msg) {
4025 this.success = false;
4026 this.errormsg = "parse error [column " + column + "]: " + msg;
4027 throw new Error(this.errormsg);
4029 addfunc: function(tokenstack, operstack, type_) {
4030 var operator = new Token(type_, this.tokenindex, this.tokenprio + this.tmpprio, 0, this.mode, this.meta);
4031 while (operstack.length > 0) {
4032 if (operator.prio_ <= operstack[operstack.length - 1].prio_) {
4033 tokenstack.push(operstack.pop());
4038 operstack.push(operator);
4040 isNumber: function() {
4044 while (this.pos < this.expression.length) {
4045 var code = this.expression.charCodeAt(this.pos);
4046 if (code >= 48 && code <= 57 || code === 46) {
4047 str += this.expression.charAt(this.pos);
4048 if (prec >= 0 || code === 46) {
4058 if (prec >= 0 && (typeof this.precision === "undefined" || prec > this.precision)) {
4059 this.precision = prec;
4061 this.tokennumber = parseFloat(str);
4065 isConst: function() {
4067 for (var i in this.consts) {
4070 str = this.expression.substr(this.pos, L);
4072 this.tokennumber = this.consts[i];
4080 isOperator: function() {
4081 var ch = this.expression.charAt(this.pos);
4084 this.tokenindex = "+";
4085 } else if (ch === "-") {
4087 this.tokenindex = "-";
4088 } else if (ch === "|") {
4089 if (this.expression.charAt(this.pos + 1) === "|") {
4092 this.tokenindex = "||";
4096 } else if (ch === "*") {
4097 if (this.expression.charAt(this.pos + 1) === "{") {
4101 this.tokenindex = "*";
4102 } else if (ch === "/" && this.mode != 2 && this.pos > 0) {
4104 this.tokenindex = "/";
4105 } else if (ch === "%") {
4107 this.tokenindex = "%";
4108 } else if (ch === "^") {
4110 this.tokenindex = "^";
4111 } else if (ch === "=" || ch === "!") {
4112 if (this.expression.charAt(this.pos + 1) === "=") {
4114 this.tokenindex = "==";
4115 } else if (ch === "!") {
4116 this.tokenindex = "!=";
4122 } else if (ch === "!") {
4124 this.tokenindex = "!";
4125 } else if (ch === "=") {
4126 this.tokenindex = "=";
4130 } else if (ch === "<") {
4131 if (this.expression.charAt(this.pos + 1) === "=") {
4132 this.tokenindex = "<=";
4135 this.tokenindex = "<";
4138 } else if (ch === ">") {
4139 if (this.expression.charAt(this.pos + 1) === "=") {
4140 this.tokenindex = ">=";
4143 this.tokenindex = ">";
4146 } else if (ch === "." || ch === "[") {
4147 this.tokenprio = 10;
4148 this.tokenindex = ".";
4155 isRightBracket: function() {
4156 var code = this.expression.charCodeAt(this.pos);
4164 isSign: function() {
4165 var code = this.expression.charCodeAt(this.pos - 1);
4166 if (code === 45 || code === 43) {
4171 isAssign: function() {
4172 var code = this.expression.charCodeAt(this.pos - 1);
4174 var cha = this.expression.charAt(this.pos - 2);
4175 if (cha === "!" || cha === ">" || cha === "<" || cha === "=") {
4178 cha = this.expression.charAt(this.pos);
4179 if (cha === ">" || cha === "<" || cha === "=") {
4186 isPositiveSign: function() {
4187 var code = this.expression.charCodeAt(this.pos - 1);
4193 isNegativeSign: function() {
4194 var code = this.expression.charCodeAt(this.pos - 1);
4200 isLeftParenth: function() {
4201 var code = this.expression.charCodeAt(this.pos);
4209 isRightParenth: function() {
4210 var code = this.expression.charCodeAt(this.pos);
4218 isLeftCurly: function() {
4219 var code = this.expression.charCodeAt(this.pos);
4227 isRightCurly: function() {
4228 var code = this.expression.charCodeAt(this.pos);
4236 isComma: function() {
4237 var code = this.expression.charCodeAt(this.pos);
4240 this.tokenprio = -1;
4241 this.tokenindex = ",";
4246 isWhite: function() {
4247 var code = this.expression.charCodeAt(this.pos);
4248 if (code === 32 || code === 9 || code === 10 || code === 13) {
4254 isLeftVarBrk: function(modestack) {
4255 var pp = this.pos, ch = this.expression.charAt(pp);
4256 if (ch === "$" || ch === "@" || ch === "*" || ch === "#") {
4258 var ch2 = this.expression.charAt(pp);
4262 this.tokenprio = -4;
4263 var oldMode = this.mode;
4264 modestack.push(oldMode);
4267 } else if (ch === "@") {
4269 } else if (ch === "*") {
4271 } else if (ch === "#") {
4274 this.tokenindex = "{";
4281 isRightVarBrk: function() {
4282 var code = this.expression.charCodeAt(this.pos);
4290 isOpX: function(str, group) {
4291 if (str.str.length > 0) {
4292 if (str.str in new Object()) {
4295 if (str.str in group) {
4296 this.tokenindex = str.str;
4304 isLiteralValue: function(str) {
4305 if (typeof str.str === "string") {
4306 var first = str.str.charAt(0);
4307 var last = str.str.charAt(str.str.length - 1);
4308 if (first == "'" && last == "'" || first == '"' && last == '"') {
4309 this.tokennumber = str.str.substring(1, str.str.length - 1);
4316 isVar: function(str) {
4317 if (str.str.length > 0) {
4318 this.tokenindex = str.str;
4325 isComment: function() {
4326 var code = this.expression.charCodeAt(this.pos - 1);
4327 if (code === 47 && this.expression.charCodeAt(this.pos) === 42) {
4328 this.pos = this.expression.indexOf("*/", this.pos) + 2;
4329 if (this.pos === 1) {
4330 this.pos = this.expression.length;
4341 var specAttrModList = [ "abbr", "accept", "accept-charset", "accesskey", "action", "align", "alt", "archive", "audio", "autocomplete", "axis", "background", "bgcolor", "border", "cellpadding", "cellspacing", "challenge", "charset", "cite", "class", "classid", "codebase", "codetype", "cols", "colspan", "compact", "content", "contenteditable", "contextmenu", "data", "datetime", "dir", "draggable", "dropzone", "enctype", "for", "form", "formaction", "formenctype", "formmethod", "formtarget", "frame", "frameborder", "headers", "height", "high", "href", "hreflang", "hspace", "http-equiv", "icon", "id", "keytype", "kind", "label", "lang", "list", "longdesc", "low", "manifest", "marginheight", "marginwidth", "max", "maxlength", "media", "method", "min", "name", "optimum", "pattern", "placeholder", "poster", "preload", "radiogroup", "rel", "rev", "rows", "rowspan", "rules", "sandbox", "scheme", "scope", "scrolling", "size", "sizes", "span", "spellcheck", "src", "srclang", "standby", "start", "step", "style", "summary", "tabindex", "target", "title", "type", "usemap", "value", "valuetype", "vspace", "width", "wrap", "xmlbase", "xmllang", "xmlspace" ];
4342 var fixedValBoolAttrList = [ "async", "autofocus", "autoplay", "checked", "controls", "declare", "default", "defer", "disabled", "formnovalidate", "hidden", "ismap", "loop", "multiple", "novalidate", "nowrap", "open", "pubdate", "readonly", "required", "reversed", "scoped", "seamless", "selected" ];
4343 var eventAttrList = [ "onabort", "onafterprint", "onbeforeprint", "onbeforeunload", "onblur", "oncanplay", "oncanplaythrough", "onchange", "onclick", "oncontextmenu", "ondblclick", "ondrag", "ondragend", "ondragenter", "ondragleave", "ondragover", "ondragstart", "ondrop", "ondurationchanged", "onemptied", "onended", "onerror", "onfocus", "onformchange", "onforminput", "onhashchange", "oninput", "oninvalid", "onkeydown", "onkeypress", "onkeyup", "onload", "onloadeddata", "onloadedmetadata", "onloadstart", "onmessage", "onmousedown", "onmousemove", "onmouseout", "onmouseover", "onmouseup", "onmousewheel", "onoffline", "ononline", "onpause", "onplay", "onplaying", "onpopstate", "onprogress", "onratechange", "onreadystatechange", "onredo", "onreset", "onresize", "onscroll", "onseeked", "onseeking", "onselect", "onshow", "onstalled", "onstorage", "onsubmit", "onsuspend", "ontimeupdate", "onundo", "onunload", "onvolumechange", "onwaiting" ];
4344 var literalTokenExpr = /^[a-zA-Z0-9\[\]\.\-_]*$/;
4345 var numericExpr = /^[+\-]?[0-9]*?[.]?[0-9]*?$/;
4346 var nonURLExpr = /[\$\*#]{1}\{(?:!?[^}]*)\}/;
4347 var varExpr = /[\$\*#@]{1}\{(!?[^}]*)\}/;
4348 var textInlineCommentExpr = /\[\[(.*)\]\]/;
4349 var javascriptInlineCommentExpr = /\/\*\[\[(.*)\]\]\*\//;
4350 var javascriptInlineRemainderExpr = /\s*(?:['][^']*['])*(?:["][^"]*["])*(?:[\(][^\(\)]*[\)])*(?:[\{][^\{\}]*[\}])*(?:[\[][^\[\]]*[\]])*((?:[;,\(\)\[\]:\{\}](?=(?:\s*\/\/.*?(?:\n|$)))(?:\s*\/\/.*?(?:\n|$)))|(?:\s*\/\/.*?(?:\n|$))|(?:[;,\(\)\[\]:\{\}](?=(?:\s*(?:\n|$)))(?:\s*(?:\n|$)))|(?:\s*(?:\n|$)))/;
4352 thymol.getThAttribute = function(part, element) {
4353 var result = thymol.ThUtils.unParenthesise(part);
4354 result = thymol.doExpression(result, element);
4355 if (Object.prototype.toString.call(result) === "[object Array]") {
4356 if (result.length === 1) {
4360 if (result instanceof thymol.ThParam) {
4361 result = result.value;
4365 thymol.doExpression = function(part, element) {
4366 var result = thymol.ThUtils.unParenthesise(part), expr, unq, token, mapped;
4368 unq = thymol.ThUtils.unQuote(result);
4369 if (unq != result) {
4370 result = thymol.preProcess(unq, element);
4372 if (literalTokenExpr.test(result)) {
4373 token = thymol.booleanAndNullTokens[result];
4374 if (!(typeof token === "undefined")) {
4377 if (result.match(numericExpr)) {
4378 result = thymol.ThUtils.getToPrecision(result, thymol.ThUtils.getDecimalDigits(result));
4380 expr = thymol.getExpression(result, element);
4381 if (expr !== undefined && expr !== null && !(expr != expr)) {
4387 expr = thymol.getExpression(result, element);
4388 if (expr !== null && !(expr != expr)) {
4397 thymol.processText = function(element, thUrlAttr, thAttr) {
4398 var url = thymol.getThAttribute(thUrlAttr.value, element), updated = false, text, newTextNode, i, iLimit, iUpper;
4400 if (!thymol.allowNullText) {
4402 thymol.thWindow.alert("thymol.processText cannot process: " + thUrlAttr.name + '="' + thUrlAttr.value + '"\n' + element.innerHTML);
4408 if (url instanceof thymol.ThParam || url instanceof thymol.ThObject) {
4412 } else if (url instanceof thymol.ThClass && url.abort) {
4413 element.removeAttribute(thUrlAttr.name);
4418 while (element.firstChild != null) {
4419 element.removeChild(element.firstChild);
4421 if (element.firstChild == null) {
4425 if ("text" == thAttr.suffix) {
4426 if (Object.prototype.toString.call(url) === "[object Array]") {
4428 for (i = 0, iLimit = url.length, iUpper = url.length - 1; i < iLimit; i++) {
4429 text += url[i].toString();
4436 text = url.toString();
4438 text = thymol.ThUtils.unescape(text);
4439 newTextNode = element.ownerDocument.createTextNode(text);
4440 element.appendChild(newTextNode);
4443 if ("utext" == thAttr.suffix) {
4444 element.innerHTML = url;
4446 element.removeAttribute(thUrlAttr.name);
4449 thymol.thWindow.alert("text replace error");
4454 thymol.processSpecAttrMod = function(element, thUrlAttr, thAttrObj) {
4455 var url = thymol.getThAttribute(thUrlAttr.value, element);
4456 if (!url || !(url instanceof thymol.ThClass) || !url.abort) {
4457 element.setAttribute(thAttrObj.suffix, url);
4459 element.removeAttribute(thUrlAttr.name);
4461 thymol.processAttr = function(element, thUrlAttr, thAttrObj) {
4462 var argValue = thUrlAttr.value.trim(), argsExpr, expr, identifier, attrName = null, ep, lp, url, tt;
4465 argsExpr = thymol.ThParser.parse(argValue, true, false);
4466 identifier = argsExpr.tokens.shift();
4467 if (identifier.type_ === 3) {
4468 attrName = identifier.index_;
4470 ep = argValue.indexOf("=");
4472 lp = argsExpr.position - 1;
4473 if (argsExpr.position === argValue.length) {
4474 lp = argValue.position;
4476 expr = argValue.substring(ep + 1, lp).trim();
4477 if (fixedValBoolAttrList.indexOf(attrName) >= 0) {
4478 thymol.doFixedValBoolAttr(expr, element, attrName);
4480 url = thymol.getThAttribute(expr, element);
4482 if (thAttrObj.suffix == "attrappend" || thAttrObj.suffix == "attrprepend") {
4483 if (url !== null && (tt === "number" || tt === "string" && url.length > 0)) {
4484 existing = element.getAttribute(attrName);
4486 if (thAttrObj.suffix == "attrappend") {
4487 url = existing + url;
4488 } else if (thAttrObj.suffix == "attrprepend") {
4489 url = url + existing;
4494 if (url !== null && (tt === "number" || tt === "string" && url.length > 0)) {
4495 element.setAttribute(attrName, url);
4500 argValue = argValue.substring(argsExpr.position);
4504 } while (argValue.length > 0);
4506 element.removeAttribute(thUrlAttr.name);
4508 thymol.processCSSAttr = function(element, thUrlAttr, thAttrObj) {
4509 var parts = thUrlAttr.value.split(","), i, iLimit, expr, attrName, url, tt, existing;
4510 for (i = 0, iLimit = parts.length; i < iLimit; i++) {
4512 attrName = thAttrObj.suffix == "classappend" ? "class" : "style";
4515 url = thymol.getThAttribute(expr, element);
4517 if (url !== null && (tt === "number" || tt === "string" && url.length > 0)) {
4518 existing = element.getAttribute(attrName);
4520 url = existing + " " + url;
4523 if (url !== null && (tt === "number" || tt === "string" && url.length > 0)) {
4524 element.setAttribute(attrName, url);
4529 element.removeAttribute(thUrlAttr.name);
4531 thymol.processFixedValBoolAttr = function(element, thUrlAttr, thAttrObj) {
4532 var val = thymol.doFixedValBoolAttr(thUrlAttr.value, element, thAttrObj.suffix);
4534 element.removeAttribute(thUrlAttr.name);
4537 thymol.thWindow.alert("thymol.processFixedValBoolAttr cannot process: " + thUrlAttr.name + '="' + thUrlAttr.value + '"\n' + element.innerHTML);
4541 thymol.doFixedValBoolAttr = function(valParam, element, attr) {
4542 var val = thymol.getBoolean(valParam, element);
4544 element.setAttribute(attr, attr);
4548 thymol.processPairedAttr = function(element, thUrlAttr, thAttrObj) {
4549 var url = thymol.getThAttribute(thUrlAttr.value, element);
4551 if (thAttrObj.suffix === "alt-title") {
4552 element.setAttribute("alt", url);
4553 element.setAttribute("title", url);
4555 if (thAttrObj.suffix === "lang-xmllang") {
4556 element.setAttribute("lang", url);
4557 element.setAttribute("xml:lang", url);
4559 element.removeAttribute(thUrlAttr.name);
4562 thymol.thWindow.alert("thymol.processPairedAttr cannot process: " + thUrlAttr.name + '="' + thUrlAttr.value + '"\n' + element.innerHTML);
4566 thymol.processConditional = function(element, attr, thAttrObj) {
4567 var removed = false;
4569 removed = thymol.doIfOrUnless(element, attr.value, thAttrObj.suffix === "if");
4571 element.removeAttribute(attr.name);
4574 thymol.doIfOrUnless = function(element, value, isIf) {
4575 var processed = false, flag;
4577 flag = thymol.getBoolean(value, element);
4581 element.parentNode.removeChild(element);
4586 element.parentNode.removeChild(element);
4591 if (!processed && thymol.debug) {
4592 thymol.thWindow.alert("thymol.processConditional cannot process conditional: " + value + "\n" + element.innerHTML);
4596 thymol.processEach = function(element, thUrlAttr, junk) {
4597 var elementsUpdated = false, initial = thUrlAttr.value.trim(), colonPos, varName, varNames, statVarName, expr, root, node, i, iLimit, tho, stat, count, newNode, next;
4598 colonPos = initial.indexOf(":");
4600 varName = initial.substring(0, colonPos);
4602 varName = varName.trim();
4603 varNames = varName.split(",");
4604 varName = varNames[0].trim();
4605 if (varNames.length > 1) {
4606 statVarName = varNames[1].trim();
4608 statVarName = varName + "Stat";
4610 expr = initial.substr(colonPos + 1);
4613 expr = thymol.getExpression(expr, element);
4614 if (expr instanceof thymol.ThSet) {
4615 expr = expr.toArray();
4617 root = element.parentNode;
4618 if (expr && expr instanceof Object && expr.length > 0) {
4620 iLimit = expr.length;
4621 element.removeAttribute(thUrlAttr.name);
4622 for (i = 0; i < iLimit; i++) {
4624 stat = new Object();
4626 stat.size = expr.length;
4635 if (i == expr.length - 1) {
4647 if (!node.thLocalVars) {
4648 node.thLocalVars = {};
4650 node.thLocalVars[varName] = tho;
4651 node.thLocalVars[statVarName] = stat;
4652 if (count < expr.length) {
4653 newNode = element.cloneNode(true);
4654 if (node.nextElementSibling != null) {
4655 next = root.insertBefore(newNode, node.nextElementSibling);
4657 next = root.appendChild(newNode);
4660 elementsUpdated = true;
4664 if (root !== null) {
4665 if (!element.thLocalVars) {
4666 element.thLocalVars = {};
4668 if (!element.thLocalVars[varName]) {
4669 element.thLocalVars[varName] = new Object();
4671 if (!element.thLocalVars[statVarName]) {
4672 element.thLocalVars[statVarName] = new Object();
4674 root.removeChild(element);
4675 elementsUpdated = true;
4681 return elementsUpdated;
4683 thymol.processObject = function(element, thUrlAttr) {
4684 var argValue = thUrlAttr.value.trim(), val;
4686 val = thymol.getExpression(argValue, element);
4688 element.thObjectVar = val;
4691 element.removeAttribute(thUrlAttr.name);
4693 thymol.processInline = function(element, thUrlAttr, thAttrObj) {
4694 var mode = thymol.getThAttribute(thUrlAttr.value, element);
4695 if (mode == "text") {
4696 thymol.doInlineText(element);
4697 } else if (mode == "javascript" || mode == "dart") {
4698 thymol.doInlineJavascript(element);
4701 thymol.thWindow.alert('thymol.processInline cannot process scripting mode: "' + mode + '" - it isn\'t supported by version "' + thymol.thVersion + '"\n');
4704 element.removeAttribute(thUrlAttr.name);
4706 thymol.doInlineText = function(element) {
4707 var changed, value, i, iLimit, expr, term, result;
4708 for (i = 0, iLimit = element.childNodes.length; i < iLimit; i++) {
4711 if (element.childNodes[i].nodeType == 1) {
4712 thymol.doInlineText(element.childNodes[i]);
4713 } else if (element.childNodes[i].nodeType == 3) {
4714 value = element.childNodes[i].nodeValue;
4716 expr = textInlineCommentExpr.exec(value);
4719 if (expr.length > 1) {
4720 term = "[[" + expr[1] + "]]";
4722 if (expr.length > 1) {
4723 result = thymol.getThAttribute(expr[1], element);
4724 result = value.replace(term, result);
4725 element.childNodes[i].nodeValue = result;
4735 thymol.doInlineJavascript = function(element) {
4736 var changed, value, second, i, iLimit, expr, scraps, remainder, termIndx, term, secondIndx, result;
4737 for (i = 0, iLimit = element.childNodes.length; i < iLimit; i++) {
4741 value = element.childNodes[i].nodeValue;
4743 expr = javascriptInlineCommentExpr.exec(value);
4745 termIndx = expr.index;
4747 if (expr.length > 1) {
4748 term = "/*[[" + expr[1] + "]]*/";
4750 termIndx = termIndx + term.length;
4751 remainder = value.substring(termIndx);
4752 scraps = javascriptInlineRemainderExpr.exec(remainder);
4754 if (scraps.length > 1) {
4755 secondIndx = remainder.indexOf(scraps[1]);
4756 second = remainder.substring(secondIndx);
4757 value = value.substring(0, termIndx);
4758 value = value + second;
4761 if (expr.length > 1) {
4762 result = thymol.getExpression(expr[1], element);
4763 if (result instanceof thymol.ThObject) {
4764 result = result.toNonThObject();
4766 if (!thymol.ThUtils.isLiteral(result)) {
4767 result = thymol.getStringView(result);
4769 result = value.replace(term, result);
4770 element.childNodes[i].nodeValue = result;
4780 thymol.getStringView = function(param) {
4781 var view = "", objType;
4782 if (typeof param === "string") {
4783 view = view + "'" + param + "'";
4784 } else if (typeof param === "number" || typeof param === "boolean") {
4785 view = view + param;
4786 } else if (typeof param === "object") {
4787 if (param instanceof Object) {
4788 objType = Object.prototype.toString.call(param);
4789 if ("[object Array]" == objType) {
4790 view = thymol.getStringViewArray(param);
4791 } else if ("[object Object]" == objType) {
4792 view = thymol.getStringViewObject(param);
4798 thymol.getStringViewArray = function(param) {
4799 var view = "[", i, iLimit;
4800 for (i = 0, iLimit = param.length; i < iLimit; i++) {
4801 view = view + thymol.getStringView(param[i]);
4802 if (i < param.length - 1) {
4809 thymol.getStringViewObject = function(param) {
4810 var view = "{", key = null;
4811 for (key in param) {
4816 view = view + thymol.getStringView(key) + ":";
4817 view = view + thymol.getStringView(param[key]);
4823 thymol.processRemove = function(element, thUrlAttr) {
4824 var haveRemoved = false;
4825 var locals = element.thLocalVars, savedLocals = element.thLocalVars, arg, nodes, first;
4829 if (!locals["tag"]) {
4830 locals["tag"] = "tag";
4832 if (!locals["body"]) {
4833 locals["body"] = "body";
4835 if (!locals["none"]) {
4836 locals["none"] = "none";
4838 if (!locals["all"]) {
4839 locals["all"] = "all";
4841 if (!locals["all-but-first"]) {
4842 locals["all-but-first"] = "all-but-first";
4844 element.thLocalVars = locals;
4845 arg = thymol.getThAttribute(thUrlAttr.value, element);
4846 element.thLocalVars = savedLocals;
4847 element.removeAttribute(thUrlAttr.name);
4849 if (element.parentNode != null) {
4850 element.parentNode.removeChild(element);
4853 } else if ("body" == arg) {
4854 element.innerHTML = "";
4856 } else if ("tag" == arg) {
4857 thymol.ThUtils.removeTag(element);
4859 } else if ("all-but-first" == arg) {
4860 nodes = element.childNodes;
4862 $(nodes).each(function() {
4863 if (this.nodeType == 1) {
4865 element.removeChild(this);
4871 } else if ("none" == arg || null == arg) {}
4874 thymol.processSwitch = function(element, attr) {
4875 var val = thymol.ThUtils.unParenthesise(attr.value), updated = false, args, matched = false, thCaseSpecs, caseClause, remove, ccAttr;
4876 val = thymol.getThAttribute(val, element);
4877 if (typeof val === "string") {
4878 args = val.match(nonURLExpr);
4883 val = thymol.ThUtils.unQuote(val);
4884 thCaseSpecs = $(thCase.escpName, element);
4885 thCaseSpecs.each(function() {
4888 $(caseClause.attributes).each(function() {
4890 if (thCase.name == ccAttr.name || thCase.synonym == ccAttr.name) {
4892 matched = thymol.processCase(element, ccAttr, val);
4897 caseClause.removeAttribute(ccAttr.name);
4901 element.removeChild(caseClause);
4907 thymol.processCase = function(element, attr, param) {
4908 var val = thymol.substitute(attr.value, element);
4909 val = thymol.ThUtils.unQuote(val);
4910 if (val == "*" || param && param == val) {
4915 thymol.processWith = function(element, thUrlAttr) {
4916 thymol.getWith(element, thUrlAttr.value);
4917 element.removeAttribute(thUrlAttr.name);
4919 thymol.processAssert = function(element, thUrlAttr) {
4920 var argValue = thUrlAttr.value.trim(), result = true, term = "", terms, i, iLimit, expr, val, flag;
4922 terms = argValue.split(",");
4923 for (i = 0, iLimit = terms.length; i < iLimit; i++) {
4925 expr = thymol.ThUtils.unParenthesise(term);
4927 val = thymol.getExpression(expr, element);
4929 flag = thymol.getBoolean(val, element);
4945 if (argValue != term) {
4946 argValue = " list is: " + argValue;
4951 term = ' false term is: "' + term + '"';
4954 thymol.thWindow.alert("thymol.processAssert assertion failure -" + argValue + term + "\n");
4957 element.removeAttribute(thUrlAttr.name);
4959 thymol.processFragment = function(element, thUrlAttr, thAttrObj) {
4960 element.removeAttribute(thUrlAttr.name);
4962 thymol.getBoolean = function(param, element) {
4963 if (param == null) {
4966 if (typeof param === "boolean") {
4968 } else if (typeof param === "number") {
4971 var initial = thymol.ThUtils.unParenthesise(param), negate = false, val, args, flag;
4972 if (initial.charAt(0) == "!") {
4974 initial = initial.substring(1, initial.length);
4975 initial = thymol.ThUtils.unParenthesise(initial);
4977 val = thymol.getThAttribute(initial, element);
4979 args = initial.match(varExpr);
4981 if (args[1].charAt(0) == "!") {
4986 flag = thymol.getBooleanValue(val);
4992 thymol.appendToAttrList = function(func, prec, attrArray) {
4993 var j, jLimit = attrArray.length, tha = null;
4994 for (j = 0; j < jLimit; j++) {
4995 tha = new thymol.ThAttr(attrArray[j], func, prec, thymol.thThymeleafPrefixList, thymol.prefix);
4999 thymol.setupAttrList = function() {
5000 thCase = new thymol.ThAttr("case", null, 275, thymol.thThymeleafPrefixList, thymol.prefix);
5002 prefix: thymol.prefix,
5003 attributeProcessors: [ {
5005 processor: thymol.processEach,
5009 processor: thymol.processSwitch,
5013 processor: thymol.processConditional,
5017 processor: thymol.processConditional,
5021 processor: thymol.processObject,
5025 processor: thymol.processWith,
5029 processor: thymol.processAttr,
5032 name: "attrprepend",
5033 processor: thymol.processAttr,
5037 processor: thymol.processAttr,
5041 processor: thymol.processPairedAttr,
5044 name: "lang-xmllang",
5045 processor: thymol.processPairedAttr,
5049 processor: thymol.processInline,
5052 name: "classappend",
5053 processor: thymol.processCSSAttr,
5056 name: "styleappend",
5057 processor: thymol.processCSSAttr,
5061 processor: thymol.processText,
5065 processor: thymol.processText,
5069 processor: thymol.processFragment,
5073 processor: thymol.processAssert,
5077 processor: thymol.processRemove,
5081 thymol.appendToAttrList(thymol.processSpecAttrMod, 1e3, specAttrModList);
5082 thymol.appendToAttrList(thymol.processSpecAttrMod, 1e3, eventAttrList);
5083 thymol.appendToAttrList(thymol.processFixedValBoolAttr, 1e3, fixedValBoolAttrList);
5087 thymol.objects.thHttpSessionObject = function() {
5088 var thExpressionObjectName = "#httpSession";
5089 function getAttribute(name) {
5090 var result = thymol.sessionContext[name];
5093 function getParameter(name) {
5094 var result = thymol.sessionContext[name];
5097 function getServletContext() {
5098 var result = thymol.applicationContext;
5101 function getSessionContext() {
5102 var result = thymol.sessionContext;
5105 function getContextPath() {
5109 function getRequestName() {
5113 function getParameterValues(name) {
5114 var result = thymol.sessionContext[name];
5118 thExpressionObjectName: thExpressionObjectName,
5119 getAttribute: getAttribute,
5120 getParameter: getParameter,
5121 getServletContext: getServletContext,
5122 getSessionContext: getSessionContext,
5123 getContextPath: getContextPath,
5124 getRequestName: getRequestName,
5125 getParameterValues: getParameterValues
5129 thymol.objects.thHttpServletRequestObject = function() {
5130 var thExpressionObjectName = "#httpServletRequest";
5131 function getAttribute(name) {
5132 var result = thymol.requestContext[name][0];
5133 if (result instanceof thymol.ThParam) {
5134 result = thymol.ThUtils.unQuote(result.value);
5138 function getParameter(name) {
5139 var result = thymol.requestContext[name];
5142 function getContextPath() {
5146 function getRequestName() {
5150 function getParameterValues(name) {
5151 var result = thymol.requestContext[name];
5154 function getSession(create) {
5155 return thymol.objects.thHttpSessionObject;
5158 thExpressionObjectName: thExpressionObjectName,
5159 getAttribute: getAttribute,
5160 getParameter: getParameter,
5161 getContextPath: getContextPath,
5162 getRequestName: getRequestName,
5163 getParameterValues: getParameterValues,
5164 getSession: getSession
5168 thymol.objects.thAggregatesObject = function() {
5169 var thExpressionObjectName = "#aggregates";
5170 function sum(target) {
5171 return aggregate(target, false, "sum");
5173 function avg(target) {
5174 return aggregate(target, true, "avg");
5176 function aggregate(target, doAvg, label) {
5177 if (target !== null) {
5180 var tt = typeof target;
5181 var ptc = Object.prototype.toString.call(target);
5182 if (tt === "Array" || ptc === "[object Array]") {
5183 count = target.length;
5184 for (var i = 0; i < count; i++) {
5185 if (target[i] !== null) {
5186 result += target[i];
5188 throw new thymol.ThError("#aggregates." + label + " Cannot aggregate on object containing nulls");
5193 for (var k in target) {
5194 var value = target[k];
5195 var process = false;
5196 if (value !== null) {
5197 if (target instanceof thymol.ThSet) {
5198 process = target.isContent(k);
5200 process = target.hasOwnProperty(k) && typeof value !== "function";
5203 throw new thymol.ThError("#aggregates." + label + " Cannot aggregate on object containing nulls");
5213 throw new thymol.ThError("#aggregates." + label + " Cannot get size of object");
5215 result = result / count;
5219 throw new thymol.ThError("#aggregates." + label + " Cannot aggregate on null");
5222 thExpressionObjectName: thExpressionObjectName,
5228 thymol.objects.thArraysObject = function() {
5229 var thExpressionObjectName = "#arrays";
5230 function toArray(target) {
5231 if (target !== null) {
5232 return toTypedArray(null, target);
5234 throw new thymol.ThError("#arrays.toArray Cannot convert null to array");
5236 function toStringArray(target) {
5237 if (target !== null) {
5238 return toTypedArray("string", target);
5240 throw new thymol.ThError("#arrays.toStringArray Cannot convert null to array");
5242 function toNumberArray(target) {
5243 if (target !== null) {
5244 return toTypedArray("number", target);
5246 throw new thymol.ThError("#arrays.toNumberArray Cannot convert null to array");
5248 function toBooleanArray(target) {
5249 if (target !== null) {
5250 return toTypedArray("boolean", target);
5252 throw new thymol.ThError("#arrays.toBooleanArray Cannot convert null to array");
5254 function toTypedArray(componentClass, target) {
5255 if (target instanceof Array) {
5256 if (componentClass === null || componentClass === "undefined") {
5259 var result = new Array();
5261 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
5262 if (target[i] !== null) {
5263 if (componentClass === "string") {
5264 result.push(new String(target[i]).valueOf());
5265 } else if (componentClass === "number") {
5266 result.push(new Number(target[i]).valueOf());
5267 } else if (componentClass === "boolean") {
5268 result.push(new Boolean(target[i]).valueOf());
5270 result.push(target[i]);
5275 throw new IllegalArgumentException('#arrays.toArray Cannot convert object of class "' + targetComponentClass.getName() + '[]" to an array' + " of " + componentClass.getClass().getSimpleName());
5278 } else if (target instanceof Object) {
5279 var result = new Array();
5281 for (var k in target) {
5282 var value = target[k];
5283 var process = false;
5284 if (value !== null) {
5285 if (target instanceof thymol.ThSet) {
5286 process = target.isContent(k);
5288 process = target.hasOwnProperty(k) && typeof value !== "function";
5292 if (componentClass === "string") {
5293 result.push(new String(value).valueOf());
5294 } else if (componentClass === "number") {
5295 result.push(new Number(value).valueOf());
5296 } else if (componentClass === "boolean") {
5297 result.push(new Boolean(value).valueOf());
5304 throw new IllegalArgumentException('#arrays.toArray Cannot convert object of class "' + targetComponentClass.getName() + '[]" to an array' + " of " + componentClass.getClass().getSimpleName());
5308 throw new thymol.ThError('#arrays.toArray Cannot convert object of type "' + typeof target + '" to an array' + (componentClass == null ? "" : " of " + componentClass));
5311 function length(target) {
5312 if (target !== null) {
5313 return target.length;
5315 throw new thymol.ThError("#arrays.length Cannot get array length of null");
5317 function isEmpty(target) {
5318 return target === null || target.length <= 0;
5320 function contains(target, element) {
5321 if (target !== null) {
5322 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
5323 if (target[i] === null) {
5324 if (element === null) {
5327 } else if (element !== null && target[i] === element) {
5333 throw new thymol.ThError("#arrays.contains Cannot execute array contains: target is null");
5335 function containsAll(target, elements) {
5336 if (target !== null) {
5337 if (elements !== null) {
5339 if (elements instanceof Array) {
5340 elementsArray = [].concat(elements);
5342 if (elements instanceof thymol.ThSet) {
5343 elementsArray = elements.toArray();
5346 for (var k in elements) {
5347 if (elements.hasOwnProperty(k) && typeof elements[k] !== "function") {
5348 elementsArray.push(elements[k]);
5353 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
5354 for (var j = 0, jLimit = elementsArray.length; j < jLimit; j++) {
5355 if (target[i] === elementsArray[j]) {
5356 elementsArray.splice(j, 1);
5360 return elementsArray.length === 0;
5362 throw new thymol.ThError("#arrays.containsAll Cannot execute array containsAll: elements is null");
5364 throw new thymol.ThError("#arrays.containsAll Cannot execute array containsAll: target is null");
5367 thExpressionObjectName: thExpressionObjectName,
5369 toStringArray: toStringArray,
5370 toIntegerArray: toNumberArray,
5371 toLongArray: toNumberArray,
5372 toDoubleArray: toNumberArray,
5373 toFloatArray: toNumberArray,
5374 toBooleanArray: toBooleanArray,
5378 containsAll: containsAll
5382 thymol.objects.thBoolsObject = function() {
5383 var thExpressionObjectName = "#bools";
5384 function isTrue(target) {
5387 if (target == null || (tc = typeof target) === "undefined") {
5390 if (tc === "boolean") {
5392 } else if (tc === "number") {
5393 result = target != 0;
5394 } else if (tc === "string") {
5395 if (target.length === 1) {
5396 result = target.charCodeAt(0) != 0;
5397 } else if (thymol.ThUtils.testLiteralFalse(target)) {
5404 function arrayIsTrue(target) {
5405 if (target !== null) {
5407 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
5408 result.push(isTrue(target[i]));
5412 throw new thymol.ThError("#bools.arrayIsTrue Target cannot be null");
5414 function setIsTrue(target) {
5415 if (target !== null) {
5416 var result = new thymol.ThSet();
5417 for (var k in target) {
5418 if (target.isContent(k)) {
5419 result.add(isTrue(target[k]));
5424 throw new thymol.ThError("#bools.setIsTrue Target cannot be null");
5426 function isFalse(target) {
5427 return !isTrue(target);
5429 function arrayIsFalse(target) {
5430 if (target !== null) {
5432 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
5433 result.push(!isTrue(target[i]));
5437 throw new thymol.ThError("#bools.arrayIsFalse Target cannot be null");
5439 function setIsFalse(target) {
5440 if (target !== null) {
5441 var result = new thymol.ThSet();
5442 for (var k in target) {
5443 if (target.isContent(k)) {
5444 result.add(!isTrue(target[k]));
5449 throw new thymol.ThError("#bools.setIsFalse Target cannot be null");
5451 function arrayAnd(target) {
5452 if (target !== null) {
5453 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
5454 if (!isTrue(target[i])) {
5460 throw new thymol.ThError("#bools.arrayAnd Target cannot be null");
5462 function setAnd(target) {
5463 if (target !== null) {
5464 for (var k in target) {
5465 if (target.isContent(k)) {
5466 if (!isTrue(target[k])) {
5473 throw new thymol.ThError("#bools.setAnd Target cannot be null");
5475 function arrayOr(target) {
5476 if (target !== null) {
5477 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
5478 if (isTrue(target[i])) {
5484 throw new thymol.ThError("#bools.arrayOr Target cannot be null");
5486 function setOr(target) {
5487 if (target !== null) {
5488 for (var k in target) {
5489 if (target.isContent(k)) {
5490 if (isTrue(target[k])) {
5497 throw new thymol.ThError("#bools.setOr Target cannot be null");
5500 thExpressionObjectName: thExpressionObjectName,
5502 arrayIsTrue: arrayIsTrue,
5503 listIsTrue: arrayIsTrue,
5504 setIsTrue: setIsTrue,
5506 arrayIsFalse: arrayIsFalse,
5507 listIsFalse: arrayIsFalse,
5508 setIsFalse: setIsFalse,
5518 thymol.objects.thDatesObject = function() {
5519 var thExpressionObjectName = "#dates";
5520 function createProxy() {
5521 if (arguments !== null) {
5522 if (arguments.length > 6) {
5523 return create(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6]);
5524 } else if (arguments.length > 5) {
5525 return create(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], 0);
5526 } else if (arguments.length > 4) {
5527 return create(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], 0, 0);
5529 return create(arguments[0], arguments[1], arguments[2], 0, 0, 0, 0);
5532 function create(year, month, day, hour, minute, second, millisecond) {
5533 var result = new Date();
5534 result.setMilliseconds(millisecond);
5535 result.setSeconds(second);
5536 result.setMinutes(minute);
5537 result.setHours(hour);
5538 result.setDate(day);
5539 result.setMonth(month - 1);
5540 result.setFullYear(year);
5543 function getDay(dateValue) {
5544 var month = dateValue.getMonth() + 1;
5545 var year = dateValue.getFullYear();
5546 var day = dateValue.getDate();
5547 var a = Math.floor((14 - month) / 12);
5548 var y = year + 4800 - a;
5549 var m = month + 12 * a - 3;
5550 var jdn = day + Math.floor((153 * m + 2) / 5) + 365 * y + Math.floor(y / 4);
5551 if (jdn < 2331254) {
5554 jdn = jdn - Math.floor(y / 100) + Math.floor(y / 400) - 32045;
5556 var mjdn = (jdn + 1) % 7;
5559 function createNow() {
5562 function createToday() {
5563 var today = new Date();
5564 today.setHours(0, 0, 0, 0);
5567 function format(dateParam, patternParam, locale) {
5570 if (arguments === null) {
5573 if (arguments.length > 1) {
5574 pattern = patternParam;
5578 return formatDate(date, pattern, locale);
5580 function formatDate(target, patternParam, locale) {
5582 if (arguments.length > 1) {
5583 pattern = patternParam;
5585 var result = dateFormat(target, pattern, false);
5588 function arrayFormat(target, patternParam) {
5590 if (arguments.length > 1) {
5591 pattern = patternParam;
5594 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
5595 result.push(dateFormat(target[i], pattern, false));
5599 function setFormat(target, patternParam) {
5601 if (arguments.length > 1) {
5602 pattern = patternParam;
5604 var result = new thymol.ThSet();
5605 for (var k in target) {
5606 if (target.isContent(k)) {
5607 result.add(dateFormat(target[k], pattern, false));
5612 function day(target) {
5613 return target.getDate();
5615 function arrayDay(target) {
5617 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
5618 result.push(target[i].getDate());
5622 function setDay(target) {
5623 var result = new thymol.ThSet();
5624 for (var k in target) {
5625 if (target.isContent(k)) {
5626 result.add(target[k].getDate());
5631 function month(target) {
5632 return target.getMonth() + 1;
5634 function arrayMonth(target) {
5636 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
5637 result.push(target[i].getMonth() + 1);
5641 function setMonth(target) {
5642 var result = new thymol.ThSet();
5643 for (var k in target) {
5644 if (target.isContent(k)) {
5645 result.add(target[k].getMonth() + 1);
5650 function monthName(target) {
5651 return dateFormat.i18n.monthNames[target.getMonth() + 12];
5653 function arrayMonthName(target) {
5655 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
5656 result.push(dateFormat.i18n.monthNames[target[i].getMonth() + 12]);
5660 function setMonthName(target) {
5661 var result = new thymol.ThSet();
5662 for (var k in target) {
5663 if (target.isContent(k)) {
5664 result.add(dateFormat.i18n.monthNames[target[k].getMonth() + 12]);
5669 function monthNameShort(target) {
5670 return dateFormat.i18n.monthNames[target.getMonth()];
5672 function arrayMonthNameShort(target) {
5674 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
5675 result.push(dateFormat.i18n.monthNames[target[i].getMonth()]);
5679 function setMonthNameShort(target) {
5680 var result = new thymol.ThSet();
5681 for (var k in target) {
5682 if (target.isContent(k)) {
5683 result.add(dateFormat.i18n.monthNames[target[k].getMonth()]);
5688 function year(target) {
5689 return target.getFullYear();
5691 function arrayYear(target) {
5693 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
5694 result.push(target[i].getFullYear());
5698 function setYear(target) {
5699 var result = new thymol.ThSet();
5700 for (var k in target) {
5701 if (target.isContent(k)) {
5702 result.add(target[k].getFullYear());
5707 function dayOfWeek(target) {
5708 return getDay(target) + 1;
5710 function arrayDayOfWeek(target) {
5712 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
5713 result.push(getDay(target[i]) + 1);
5717 function setDayOfWeek(target) {
5718 var result = new thymol.ThSet();
5719 for (var k in target) {
5720 if (target.isContent(k)) {
5721 result.add(getDay(target[k]) + 1);
5726 function dayOfWeekName(target) {
5727 return dateFormat.i18n.dayNames[getDay(target) + 7];
5729 function arrayDayOfWeekName(target) {
5731 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
5732 result.push(dateFormat.i18n.dayNames[getDay(target[i]) + 7]);
5736 function setDayOfWeekName(target) {
5737 var result = new thymol.ThSet();
5738 for (var k in target) {
5739 if (target.isContent(k)) {
5740 result.add(dateFormat.i18n.dayNames[getDay(target[k]) + 7]);
5745 function dayOfWeekNameShort(target) {
5746 return dateFormat.i18n.dayNames[getDay(target)];
5748 function arrayDayOfWeekNameShort(target) {
5750 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
5751 result.push(dateFormat.i18n.dayNames[getDay(target[i])]);
5755 function setDayOfWeekNameShort(target) {
5756 var result = new thymol.ThSet();
5757 for (var k in target) {
5758 if (target.isContent(k)) {
5759 result.add(dateFormat.i18n.dayNames[getDay(target[k])]);
5764 function hour(target) {
5765 return target.getHours();
5767 function arrayHour(target) {
5769 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
5770 result.push(target[i].getHours());
5774 function setHour(target) {
5775 var result = new thymol.ThSet();
5776 for (var k in target) {
5777 if (target.isContent(k)) {
5778 result.add(target[k].getHours());
5783 function minute(target) {
5784 return target.getMinutes();
5786 function arrayMinute(target) {
5788 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
5789 result.push(target[i].getMinutes());
5793 function setMinute(target) {
5794 var result = new thymol.ThSet();
5795 for (var k in target) {
5796 if (target.isContent(k)) {
5797 result.add(target[k].getMinutes());
5802 function second(target) {
5803 return target.getSeconds();
5805 function arraySecond(target) {
5807 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
5808 result.push(target[i].getSeconds());
5812 function setSecond(target) {
5813 var result = new thymol.ThSet();
5814 for (var k in target) {
5815 if (target.isContent(k)) {
5816 result.add(target[k].getSeconds());
5821 function millisecond(target) {
5822 return target.getMilliseconds();
5824 function arrayMillisecond(target) {
5826 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
5827 result.push(target[i].getMilliseconds());
5831 function setMillisecond(target) {
5832 var result = new thymol.ThSet();
5833 for (var k in target) {
5834 if (target.isContent(k)) {
5835 result.add(target[k].getMilliseconds());
5840 var timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g, timezoneClip = /[^-+\dA-Z]/g;
5841 function processTZ(target) {
5842 var toStr = String(target);
5844 result = (result.match(timezone) || [ "" ]).pop();
5845 if ("" !== result) {
5846 result = result.replace(timezoneClip, "");
5847 var tail = toStr.match(/[\(]((?:[GL]M|BS)T[^\)]*?)[\)]/);
5849 if (target.getFullYear() > 1916 || target.getFullYear() === 1916 && target.getMonth() > 4 || target.getFullYear() === 1916 && target.getMonth() === 4 && target.getDate() > 20) {
5850 result = result.replace(/GMT\+\d{1,4}/, "BST");
5852 result = result.replace(/GMT\+\d{1,4}/, "GMT");
5858 var dateFormat = function() {
5859 var token = /d{1,4}|M{1,4}|yy(?:yy)?|([HhmsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g, pad = function(valp, lenp) {
5860 var val = String(valp), len = lenp || 2;
5861 while (val.length < len) val = "0" + val;
5864 return function(datep, maskp, utcp) {
5865 var dF = dateFormat, mask = maskp, date = datep, utc = utcp;
5866 if (arguments.length == 1 && Object.prototype.toString.call(date) == "[object String]" && !/\d/.test(date)) {
5870 date = date ? new Date(date) : new Date();
5871 if (isNaN(date)) throw SyntaxError("invalid date");
5872 mask = String(dF.masks[mask] || mask || dF.masks["default"]);
5873 if (mask.slice(0, 4) == "UTC:") {
5874 mask = mask.slice(4);
5877 var _ = utc ? "getUTC" : "get", d = date[_ + "Date"](), D = getDay(date), M = date[_ + "Month"](), y = date[_ + "FullYear"](), H = date[_ + "Hours"](), m = date[_ + "Minutes"](), s = date[_ + "Seconds"](), L = date[_ + "Milliseconds"](), o = utc ? 0 : date.getTimezoneOffset(), flags = {
5880 ddd: dF.i18n.dayNames[D],
5881 dddd: dF.i18n.dayNames[D + 7],
5884 MMM: dF.i18n.monthNames[M],
5885 MMMM: dF.i18n.monthNames[M + 12],
5886 yy: String(y).slice(2),
5889 hh: pad(H % 12 || 12),
5897 L: pad(L > 99 ? Math.round(L / 10) : L),
5898 t: H < 12 ? "a" : "p",
5899 tt: H < 12 ? "am" : "pm",
5900 T: H < 12 ? "A" : "P",
5901 TT: H < 12 ? "AM" : "PM",
5902 Z: utc ? "UTC" : processTZ(date),
5903 o: (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
5904 S: [ "th", "st", "nd", "rd" ][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
5906 return mask.replace(token, function($0) {
5907 return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
5911 dateFormat.masks = {
5912 "default": "dd MMMM yyyy HH:mm:ss Z",
5913 shortDate: "M/d/yy",
5914 mediumDate: "MMM d, yyyy",
5915 longDate: "d MMMM yyyy",
5916 fullDate: "dddd, MMMM d, yyyy",
5917 shortTime: "h:mm TT",
5918 mediumTime: "h:mm:ss TT",
5919 longTime: "h:mm:ss TT Z",
5920 isoDate: "yyyy-MM-dd",
5921 isoTime: "HH:mm:ss",
5922 isoDateTime: "yyyy-MM-dd'T'HH:mm:ss",
5923 isoUtcDateTime: "UTC:yyyy-MM-dd'T'HH:mm:ss'Z'"
5926 dayNames: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ],
5927 monthNames: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]
5929 Date.prototype.format = function(mask, utc) {
5930 return dateFormat(this, mask, utc);
5933 thExpressionObjectName: thExpressionObjectName,
5934 create: createProxy,
5935 createNow: createNow,
5936 createNowForTimeZone: createNow,
5937 createToday: createToday,
5938 createTodayForTimeZone: createToday,
5940 dateFormat: dateFormat,
5941 arrayFormat: arrayFormat,
5942 listFormat: arrayFormat,
5943 setFormat: setFormat,
5949 arrayMonth: arrayMonth,
5950 listMonth: arrayMonth,
5952 monthName: monthName,
5953 arrayMonthName: arrayMonthName,
5954 listMonthName: arrayMonthName,
5955 setMonthName: setMonthName,
5956 monthNameShort: monthNameShort,
5957 arrayMonthNameShort: arrayMonthNameShort,
5958 listMonthNameShort: arrayMonthNameShort,
5959 setMonthNameShort: setMonthNameShort,
5961 arrayYear: arrayYear,
5962 listYear: arrayYear,
5964 dayOfWeek: dayOfWeek,
5965 arrayDayOfWeek: arrayDayOfWeek,
5966 listDayOfWeek: arrayDayOfWeek,
5967 setDayOfWeek: setDayOfWeek,
5968 dayOfWeekName: dayOfWeekName,
5969 arrayDayOfWeekName: arrayDayOfWeekName,
5970 listDayOfWeekName: arrayDayOfWeekName,
5971 setDayOfWeekName: setDayOfWeekName,
5972 dayOfWeekNameShort: dayOfWeekNameShort,
5973 arrayDayOfWeekNameShort: arrayDayOfWeekNameShort,
5974 listDayOfWeekNameShort: arrayDayOfWeekNameShort,
5975 setDayOfWeekNameShort: setDayOfWeekNameShort,
5977 arrayHour: arrayHour,
5978 listHour: arrayHour,
5981 arrayMinute: arrayMinute,
5982 listMinute: arrayMinute,
5983 setMinute: setMinute,
5985 arraySecond: arraySecond,
5986 listSecond: arraySecond,
5987 setSecond: setSecond,
5988 millisecond: millisecond,
5989 arrayMillisecond: arrayMillisecond,
5990 listMillisecond: arrayMillisecond,
5991 setMillisecond: setMillisecond
5995 thymol.objects.thCalendarsObject = function() {
5996 var thExpressionObjectName = "#calendars";
5998 thExpressionObjectName: thExpressionObjectName,
5999 create: thymol.objects.thDatesObject.create,
6000 createNow: thymol.objects.thDatesObject.createNow,
6001 createNowForTimeZone: thymol.objects.thDatesObject.createNow,
6002 createToday: thymol.objects.thDatesObject.createToday,
6003 createTodayForTimeZone: thymol.objects.thDatesObject.createToday,
6004 format: thymol.objects.thDatesObject.format,
6005 dateFormat: thymol.objects.thDatesObject.dateFormat,
6006 arrayFormat: thymol.objects.thDatesObject.arrayFormat,
6007 listFormat: thymol.objects.thDatesObject.arrayFormat,
6008 setFormat: thymol.objects.thDatesObject.setFormat,
6009 day: thymol.objects.thDatesObject.day,
6010 arrayDay: thymol.objects.thDatesObject.arrayDay,
6011 listDay: thymol.objects.thDatesObject.arrayDay,
6012 setDay: thymol.objects.thDatesObject.setDay,
6013 month: thymol.objects.thDatesObject.month,
6014 arrayMonth: thymol.objects.thDatesObject.arrayMonth,
6015 listMonth: thymol.objects.thDatesObject.arrayMonth,
6016 setMonth: thymol.objects.thDatesObject.setMonth,
6017 monthName: thymol.objects.thDatesObject.monthName,
6018 arrayMonthName: thymol.objects.thDatesObject.arrayMonthName,
6019 listMonthName: thymol.objects.thDatesObject.arrayMonthName,
6020 setMonthName: thymol.objects.thDatesObject.setMonthName,
6021 monthNameShort: thymol.objects.thDatesObject.monthNameShort,
6022 arrayMonthNameShort: thymol.objects.thDatesObject.arrayMonthNameShort,
6023 listMonthNameShort: thymol.objects.thDatesObject.arrayMonthNameShort,
6024 setMonthNameShort: thymol.objects.thDatesObject.setMonthNameShort,
6025 year: thymol.objects.thDatesObject.year,
6026 arrayYear: thymol.objects.thDatesObject.arrayYear,
6027 listYear: thymol.objects.thDatesObject.arrayYear,
6028 setYear: thymol.objects.thDatesObject.setYear,
6029 dayOfWeek: thymol.objects.thDatesObject.dayOfWeek,
6030 arrayDayOfWeek: thymol.objects.thDatesObject.arrayDayOfWeek,
6031 listDayOfWeek: thymol.objects.thDatesObject.arrayDayOfWeek,
6032 setDayOfWeek: thymol.objects.thDatesObject.setDayOfWeek,
6033 dayOfWeekName: thymol.objects.thDatesObject.dayOfWeekName,
6034 arrayDayOfWeekName: thymol.objects.thDatesObject.arrayDayOfWeekName,
6035 listDayOfWeekName: thymol.objects.thDatesObject.arrayDayOfWeekName,
6036 setDayOfWeekName: thymol.objects.thDatesObject.setDayOfWeekName,
6037 dayOfWeekNameShort: thymol.objects.thDatesObject.dayOfWeekNameShort,
6038 arrayDayOfWeekNameShort: thymol.objects.thDatesObject.arrayDayOfWeekNameShort,
6039 listDayOfWeekNameShort: thymol.objects.thDatesObject.arrayDayOfWeekNameShort,
6040 setDayOfWeekNameShort: thymol.objects.thDatesObject.setDayOfWeekNameShort,
6041 hour: thymol.objects.thDatesObject.hour,
6042 arrayHour: thymol.objects.thDatesObject.arrayHour,
6043 listHour: thymol.objects.thDatesObject.arrayHour,
6044 setHour: thymol.objects.thDatesObject.setHour,
6045 minute: thymol.objects.thDatesObject.minute,
6046 arrayMinute: thymol.objects.thDatesObject.arrayMinute,
6047 listMinute: thymol.objects.thDatesObject.arrayMinute,
6048 setMinute: thymol.objects.thDatesObject.setMinute,
6049 second: thymol.objects.thDatesObject.second,
6050 arraySecond: thymol.objects.thDatesObject.arraySecond,
6051 listSecond: thymol.objects.thDatesObject.arraySecond,
6052 setSecond: thymol.objects.thDatesObject.setSecond,
6053 millisecond: thymol.objects.thDatesObject.millisecond,
6054 arrayMillisecond: thymol.objects.thDatesObject.arrayMillisecond,
6055 listMillisecond: thymol.objects.thDatesObject.arrayMillisecond,
6056 setMillisecond: thymol.objects.thDatesObject.setMillisecond
6060 thymol.objects.thIdsObject = function() {
6061 var thExpressionObjectName = "#ids";
6064 var str = id.toString();
6065 var idCount = getLocal(str);
6066 var result = str + idCount;
6068 setLocal(str, idCount);
6071 throw new thymol.ThError("#ids.seq ID Cannot be null");
6075 var str = id.toString();
6076 var idCount = getLocal(str);
6077 return str + idCount;
6079 throw new thymol.ThError("#ids.next ID Cannot be null");
6083 var str = id.toString();
6084 var idCount = getLocal(str);
6085 return str + (idCount - 1);
6087 throw new thymol.ThError("#ids.prev ID Cannot be null");
6089 function setLocal(str, idCount) {
6090 if (!thymol.objects.thIdsObject.thLocalVars) {
6091 thymol.objects.thIdsObject.thLocalVars = [];
6093 if (!thymol.objects.thIdsObject.thLocalVars["thIdCounts"]) {
6094 thymol.objects.thIdsObject.thLocalVars["thIdCounts"] = [];
6096 thymol.objects.thIdsObject.thLocalVars["thIdCounts"][str] = idCount;
6098 function getLocal(str) {
6099 if (!thymol.objects.thIdsObject.thLocalVars) {
6100 thymol.objects.thIdsObject.thLocalVars = [];
6102 if (!thymol.objects.thIdsObject.thLocalVars["thIdCounts"]) {
6103 thymol.objects.thIdsObject.thLocalVars["thIdCounts"] = [];
6105 if (!thymol.objects.thIdsObject.thLocalVars["thIdCounts"][str]) {
6106 thymol.objects.thIdsObject.thLocalVars["thIdCounts"][str] = 1;
6108 return thymol.objects.thIdsObject.thLocalVars["thIdCounts"][str];
6111 thExpressionObjectName: thExpressionObjectName,
6118 thymol.objects.thListsObject = function() {
6119 var thExpressionObjectName = "#lists";
6120 function sort(list, comparator) {
6121 if (list !== null) {
6122 if (arguments.length > 1) {
6123 if (comparator !== null) {
6124 if (typeof comparator === "function") {
6125 return list.sort(comparator);
6127 throw new thymol.ThError("#lists.sort Cannot execute list sort: comparator is not a function");
6129 throw new thymol.ThError("#lists.sort Cannot execute list sort: comparator is null");
6133 throw new thymol.ThError("#lists.sort Cannot execute list sort: list is null");
6136 thExpressionObjectName: thExpressionObjectName,
6137 toList: thymol.objects.thArraysObject.toArray,
6138 size: thymol.objects.thArraysObject.length,
6139 isEmpty: thymol.objects.thArraysObject.isEmpty,
6140 contains: thymol.objects.thArraysObject.contains,
6141 containsAll: thymol.objects.thArraysObject.containsAll,
6146 thymol.objects.thMapsObject = function() {
6147 var thExpressionObjectName = "#maps";
6148 function size(target) {
6149 if (target !== null) {
6150 if (target instanceof thymol.ThMap) {
6151 return target.size();
6153 throw new thymol.ThError('#maps.size Cannot get size of non-map type "' + typeof target + '"');
6155 throw new thymol.ThError("#maps.size Cannot get size of null");
6157 function isEmpty(target) {
6158 if (target !== null) {
6159 if (target instanceof thymol.ThMap) {
6160 return target.isEmpty();
6162 throw new thymol.ThError('#maps.size Cannot get isEmpty of non-map type "' + typeof target + '"');
6164 throw new thymol.ThError("#maps.size Cannot get isEmpty of null");
6166 function containsKey(target, key) {
6167 if (target !== null) {
6168 if (target instanceof thymol.ThMap) {
6169 return target.containsKey(key);
6171 throw new thymol.ThError('#maps.size Cannot get containsKey of non-map type "' + typeof target + '"');
6173 throw new thymol.ThError("#maps.containsKey Cannot execute map containsKey: target is null");
6175 function containsValue(target, value) {
6176 if (target !== null) {
6177 if (target instanceof thymol.ThMap) {
6178 return target.containsValue(value);
6180 throw new thymol.ThError('#maps.size Cannot get containsValue of non-map type "' + typeof target + '"');
6182 throw new thymol.ThError("#maps.containsKey Cannot execute map containsValue: target is null");
6184 function containsAllKeys(target, keys) {
6185 if (target !== null) {
6186 if (target instanceof thymol.ThMap) {
6187 var ptc = Object.prototype.toString.call(keys);
6188 if (keys instanceof thymol.ThSet || keys instanceof Array || ptc === "[object Array]") {
6189 return target.containsAll(keys);
6191 throw new thymol.ThError('#maps.size Cannot get containsAllKeys with non-collection type "' + ptc + '"');
6193 throw new thymol.ThError('#maps.size Cannot get containsAllKeys of non-map type "' + typeof target + '"');
6195 throw new thymol.ThError("#maps.containsKey Cannot execute map containsAllKeys: target is null");
6197 function containsAllValues(target, values) {
6198 if (target !== null) {
6199 if (target instanceof thymol.ThMap) {
6200 var ptc = Object.prototype.toString.call(values);
6201 if (values instanceof thymol.ThSet || values instanceof Array || ptc === "[object Array]") {
6202 var vArray = values;
6203 if (values instanceof thymol.ThSet) {
6204 vArray = values.toArray();
6206 for (var i = 0, iLimit = vArray.length; i < iLimit; i++) {
6208 for (var k in target) {
6209 if (target.hasOwnProperty(k)) {
6210 var value = target[k];
6211 if (value === vArray[i]) {
6223 throw new thymol.ThError('#maps.size Cannot get containsAllValues with non-collection type "' + ptc + '"');
6225 throw new thymol.ThError('#maps.size Cannot get containsAllValues of non-map type "' + typeof target + '"');
6227 throw new thymol.ThError("#maps.containsKey Cannot execute map containsAllValues: target is null");
6230 thExpressionObjectName: thExpressionObjectName,
6233 containsKey: containsKey,
6234 containsValue: containsValue,
6235 containsAllKeys: containsAllKeys,
6236 containsAllValues: containsAllValues
6240 thymol.objects.thMessagesObject = function() {
6241 var thExpressionObjectName = "#messages";
6243 if (arguments !== null) {
6244 if (arguments.length > 0) {
6245 return msgWithParams(arguments[0], Array.prototype.slice.call(arguments, 1));
6247 throw new thymol.ThError("#messages.msg Invoked with no arguments!");
6249 throw new thymol.ThError("#messages.msg Target cannot be null");
6251 function msgWithParams(target, params) {
6252 if (target !== null) {
6253 return thymol.getMessage(target, params, true);
6255 throw new thymol.ThError("#messages.msgWithParams Target cannot be null");
6257 function msgOrNull() {
6258 if (arguments !== null) {
6259 if (arguments.length > 0) {
6260 return msgOrNullWithParams(arguments[0], Array.prototype.slice.call(arguments, 1));
6262 throw new thymol.ThError("#messages.msgOrNull Invoked with no arguments!");
6264 throw new thymol.ThError("#messages.msgOrNull Target cannot be null");
6266 function msgOrNullWithParams(target, params) {
6267 if (target !== null) {
6268 return thymol.getMessage(target, params, false);
6270 throw new thymol.ThError("#messages.msgOrNullWithParams Target cannot be null");
6272 function arrayMsg() {
6273 if (arguments !== null) {
6274 if (arguments.length > 0) {
6275 return arrayMsgWithParams(arguments[0], Array.prototype.slice.call(arguments, 1));
6277 throw new thymol.ThError("#messages.arrayMsg Invoked with no arguments!");
6279 throw new thymol.ThError("#messages.arrayMsg Target cannot be null");
6281 function arrayMsgWithParams(target, params) {
6282 if (target !== null) {
6284 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
6285 result.push(msgWithParams(target[i], params));
6289 throw new thymol.ThError("#messages.arrayMsgWithParams Target cannot be null");
6292 if (arguments !== null) {
6293 if (arguments.length > 0) {
6294 return setMsgWithParams(arguments[0], Array.prototype.slice.call(arguments, 1));
6296 throw new thymol.ThError("#messages.setMsg Invoked with no arguments!");
6298 throw new thymol.ThError("#messages.setMsg Target cannot be null");
6300 function setMsgWithParams(target, params) {
6301 if (target !== null) {
6302 var result = new thymol.ThSet();
6303 for (var k in target) {
6304 if (target.isContent(k)) {
6305 result.add(msgWithParams(target[k], params));
6310 throw new thymol.ThError("#messages.setMsgWithParams Target cannot be null");
6312 function arrayMsgOrNull() {
6313 if (arguments !== null) {
6314 if (arguments.length > 0) {
6315 return arrayMsgOrNullWithParams(arguments[0], Array.prototype.slice.call(arguments, 1));
6317 throw new thymol.ThError("#messages.arrayMsgOrNull Invoked with no arguments!");
6319 throw new thymol.ThError("#messages.arrayMsgOrNull Target cannot be null");
6321 function arrayMsgOrNullWithParams(target, params) {
6322 if (target !== null) {
6324 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
6325 result.push(msgOrNullWithParams(target[i], params));
6329 throw new thymol.ThError("#messages.arrayMsgOrNullWithParams Target cannot be null");
6331 function setMsgOrNull() {
6332 if (arguments !== null) {
6333 if (arguments.length > 0) {
6334 return setMsgOrNullWithParams(arguments[0], Array.prototype.slice.call(arguments, 1));
6336 throw new thymol.ThError("#messages.setMsgOrNull Invoked with no arguments!");
6338 throw new thymol.ThError("#messages.setMsgOrNull Target cannot be null");
6340 function setMsgOrNullWithParams(target, params) {
6341 if (target !== null) {
6342 var result = new thymol.ThSet();
6343 for (var k in target) {
6344 if (target.isContent(k)) {
6345 result.add(msgOrNullWithParams(target[k], params));
6350 throw new thymol.ThError("#messages.setMsgOrNullWithParams Target cannot be null");
6353 thExpressionObjectName: thExpressionObjectName,
6355 msgWithParams: msgWithParams,
6356 msgOrNull: msgOrNull,
6357 msgOrNullWithParams: msgOrNullWithParams,
6361 arrayMsgWithParams: arrayMsgWithParams,
6362 listMsgWithParams: arrayMsgWithParams,
6363 setMsgWithParams: setMsgWithParams,
6364 arrayMsgOrNull: arrayMsgOrNull,
6365 listMsgOrNull: arrayMsgOrNull,
6366 setMsgOrNull: setMsgOrNull,
6367 arrayMsgOrNullWithParams: arrayMsgOrNullWithParams,
6368 listMsgOrNullWithParams: arrayMsgOrNullWithParams,
6369 setMsgOrNullWithParams: setMsgOrNullWithParams
6373 thymol.objects.thNumbersObject = function() {
6374 var thExpressionObjectName = "#numbers";
6375 var DEFAULT_THOU_PT = ",";
6376 var DEFAULT_DECI_PT = ".";
6377 var DEFAULT_NONE_PT = "?";
6378 function formatDecimalProxy() {
6379 if (arguments !== null) {
6380 if (arguments.length > 4) {
6381 return formatDecimal5(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);
6382 } else if (arguments.length > 3) {
6383 return formatDecimal4(arguments[0], arguments[1], arguments[2], arguments[3]);
6385 return formatDecimal3(arguments[0], arguments[1], arguments[2]);
6388 function formatIntegerProxy() {
6389 if (arguments !== null) {
6390 if (arguments.length > 4) {
6391 return formatDecimal5(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);
6392 } else if (arguments.length > 3) {
6393 return formatDecimal5(arguments[0], arguments[1], "NONE", arguments[2], arguments[3]);
6394 } else if (arguments.length > 2) {
6395 if (typeof arguments[2] === "string") {
6396 return formatDecimal5(arguments[0], arguments[1], arguments[2], 0, "POINT");
6398 return formatDecimal5(arguments[0], arguments[1], "NONE", arguments[2], "POINT");
6400 return formatDecimal5(arguments[0], arguments[1], "NONE", 0, "POINT");
6404 function arrayFormatIntegerProxy() {
6405 if (arguments !== null) {
6406 if (arguments.length > 2) {
6407 return arrayFormatDecimal(arguments[0], arguments[1], arguments[2], 0, "POINT");
6409 return arrayFormatDecimal(arguments[0], arguments[1], "NONE", 0, "POINT");
6412 function setFormatIntegerProxy() {
6413 if (arguments !== null) {
6414 if (arguments.length > 2) {
6415 return setFormatDecimal(arguments[0], arguments[1], arguments[2], 0, "POINT");
6417 return setFormatDecimal(arguments[0], arguments[1], "NONE", 0, "POINT");
6420 function arrayFormatDecimalProxy() {
6421 if (arguments !== null) {
6422 if (arguments.length > 4) {
6423 return arrayFormatDecimal(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);
6424 } else if (arguments.length > 3) {
6425 return arrayFormatDecimal(arguments[0], arguments[1], "NONE", arguments[2], arguments[3]);
6427 return arrayFormatDecimal(arguments[0], arguments[1], "NONE", arguments[2], "POINT");
6430 function setFormatDecimalProxy() {
6431 if (arguments !== null) {
6432 if (arguments.length > 4) {
6433 return setFormatDecimal(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);
6434 } else if (arguments.length > 3) {
6435 return setFormatDecimal(arguments[0], arguments[1], "NONE", arguments[2], arguments[3]);
6437 return setFormatDecimal(arguments[0], arguments[1], "NONE", arguments[2], "POINT");
6440 function sequenceProxy() {
6441 if (arguments !== null) {
6442 if (arguments.length > 2) {
6443 return sequence(arguments[0], arguments[1], arguments[2]);
6445 return sequence(arguments[0], arguments[1], 1);
6448 function getIntegerDigits(val) {
6449 var s = val.toString();
6450 var digits = s.length;
6451 var dp = s.indexOf(".");
6457 function formatDecimal3(target, minIntegerDigits, decimalDigits) {
6458 var result = target.toString();
6459 var value = new Number(target);
6460 value = value.toFixed(decimalDigits);
6461 if (minIntegerDigits > 0) {
6463 value = new Number(value);
6464 var a = Math.abs(value);
6465 if (a < Math.pow(10, minIntegerDigits)) {
6467 result = result.substring(1);
6469 var p = getIntegerDigits(a);
6470 var x = minIntegerDigits - p;
6472 for (var i = 0; i < x; i++) {
6473 result = "0" + result;
6477 result = "-" + result;
6481 result = value.toString();
6483 result = new String(result);
6484 result.precision = decimalDigits;
6487 function formatDecimal4(target, minIntegerDigits, decimalDigits, decimalPointType) {
6488 var result = formatDecimal3(target, minIntegerDigits, decimalDigits);
6490 if ("DEFAULT" === decimalPointType) {
6491 decimalPoint = DEFAULT_DECI_PT;
6492 } else if ("NONE" === decimalPointType) {
6493 decimalPoint = DEFAULT_NONE_PT;
6495 decimalPoint = getPointType(decimalPointType);
6497 if ("." !== decimalPoint) {
6498 result = result.replace(".", decimalPoint, "g");
6502 function formatDecimal5(target, minIntegerDigits, thousandsPointType, decimalDigits, decimalPointType) {
6503 var result = target.toString();
6505 if ("DEFAULT" === decimalPointType) {
6506 decimalPoint = DEFAULT_DECI_PT;
6507 } else if ("NONE" === decimalPointType) {
6508 decimalPoint = DEFAULT_NONE_PT;
6510 decimalPoint = getPointType(decimalPointType);
6512 if ("" !== decimalPoint) {
6513 result = formatDecimal4(target, minIntegerDigits, decimalDigits, decimalPointType);
6515 result = formatDecimal3(target, minIntegerDigits, decimalDigits);
6518 if ("DEFAULT" === thousandsPointType) {
6519 thousandsPoint = DEFAULT_THOU_PT;
6521 thousandsPoint = getPointType(thousandsPointType);
6523 if ("" !== thousandsPoint) {
6524 result = addThousandsPointType(result.toString(), decimalPoint, thousandsPoint);
6528 function getPointType(type) {
6530 if ("COMMA" === type) {
6532 } else if ("WHITESPACE" === type) {
6534 } else if ("NONE" === type) {
6539 function arrayFormatDecimal(target, minIntegerDigits, thousandsPointType, decimalDigits, decimalPointType) {
6541 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
6542 result.push(formatDecimal5(target[i], minIntegerDigits, thousandsPointType, decimalDigits, decimalPointType));
6546 function setFormatDecimal(target, minIntegerDigits, thousandsPointType, decimalDigits, decimalPointType) {
6547 var result = new thymol.ThSet();
6548 for (var k in target) {
6549 if (target.hasOwnProperty(k) && typeof target[k] !== "function") {
6550 result.add(formatDecimal5(target[k], minIntegerDigits, thousandsPointType, decimalDigits, decimalPointType));
6555 function addThousandsPointType(nStr, dpt, tpt) {
6556 var x = nStr.split(dpt);
6558 var x2 = x.length > 1 ? dpt + x[1] : "";
6559 var rgx = /(\d+)(\d{3})/;
6560 while (rgx.test(x1)) {
6561 x1 = x1.replace(rgx, "$1" + tpt + "$2");
6565 function sequence(start, stop, step) {
6569 if (start <= stop) {
6573 } while (value <= stop);
6578 } while (value >= stop);
6584 thExpressionObjectName: thExpressionObjectName,
6585 formatDecimal: formatDecimalProxy,
6586 formatInteger: formatIntegerProxy,
6587 arrayFormatInteger: arrayFormatIntegerProxy,
6588 arrayFormatDecimal: arrayFormatDecimalProxy,
6589 listFormatInteger: arrayFormatIntegerProxy,
6590 listFormatDecimal: arrayFormatDecimalProxy,
6591 setFormatInteger: setFormatIntegerProxy,
6592 setFormatDecimal: setFormatDecimalProxy,
6593 sequence: sequenceProxy
6597 thymol.objects.thObjectsObject = function() {
6598 var thExpressionObjectName = "#objects";
6599 function nullSafe(target, defaultValue) {
6600 return target != null ? target : defaultValue;
6602 function arrayNullSafe(target, defaultValue) {
6603 if (target !== null) {
6605 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
6606 result.push(nullSafe(target[i], defaultValue));
6610 throw new thymol.ThError("#objects.arrayNullSafe Target cannot be null");
6612 function setNullSafe(target, defaultValue) {
6613 if (target !== null) {
6614 var result = new thymol.ThSet();
6615 for (var k in target) {
6616 if (target.isContent(k)) {
6617 result.add(nullSafe(target[k], defaultValue));
6622 throw new thymol.ThError("#objects.setNullSafe Target cannot be null");
6625 thExpressionObjectName: thExpressionObjectName,
6627 arrayNullSafe: arrayNullSafe,
6628 listNullSafe: arrayNullSafe,
6629 setNullSafe: setNullSafe
6633 thymol.objects.thSetsObject = function() {
6634 var thExpressionObjectName = "#sets";
6635 function toSet(target) {
6636 if (target !== null) {
6637 var tt = typeof target;
6638 var ptc = Object.prototype.toString.call(target);
6640 if (tt === "thymol.ThSet") {
6643 if (tt === "Array" || ptc === "[object Array]") {
6644 result = thymol.ThSet.prototype.fromArray(target);
6645 } else if (tt === "object") {
6646 result = new thymol.ThSet();
6647 for (var k in target) {
6648 var value = target[k];
6649 var process = false;
6650 if (value !== null) {
6651 if (target instanceof thymol.ThSet) {
6652 process = target.isContent(k);
6654 process = target.hasOwnProperty(k) && typeof value !== "function";
6662 throw new thymol.ThError('#sets.toSet Cannot convert object of type "' + tt + '" to a set');
6666 throw new thymol.ThError("#sets.toSet Cannot convert null to set");
6668 function size(target) {
6669 if (target !== null) {
6670 if (target instanceof thymol.ThSet) {
6671 return target.size();
6673 throw new thymol.ThError('#sets.size Cannot get size of non-set type "' + typeof target + '"');
6675 throw new thymol.ThError("#sets.size Cannot get size of null");
6677 function isEmpty(target) {
6678 if (target !== null) {
6679 if (target instanceof thymol.ThSet) {
6680 return target.isEmpty();
6682 throw new thymol.ThError('#sets.size Cannot get isEmpty of non-set type "' + typeof target + '"');
6684 throw new thymol.ThError("#sets.size Cannot get isEmpty of null");
6686 function contains(target, element) {
6687 if (target !== null) {
6688 for (var k in target) {
6689 if (target.isContent(k)) {
6690 if (target[k] === null) {
6691 if (element === null) {
6694 } else if (element !== null && target[k] === element) {
6701 throw new thymol.ThError("#sets.contains Cannot execute sets contains: target is null");
6703 function containsAll(target, elements) {
6704 if (target !== null) {
6705 if (elements !== null) {
6707 if (elements instanceof Array) {
6708 elementsArray = [].concat(elements);
6710 if (elements instanceof thymol.ThSet) {
6711 elementsArray = elements.toArray();
6714 for (var k in elements) {
6715 if (elements.hasOwnProperty(k) && typeof elements[k] !== "function") {
6716 elementsArray.push(elements[k]);
6721 for (var k in target) {
6722 if (target.isContent(k)) {
6723 for (var j = 0, jLimit = elementsArray.length; j < jLimit; j++) {
6724 if (target[k] === elementsArray[j]) {
6725 elementsArray.splice(j, 1);
6730 return elementsArray.length === 0;
6732 throw new thymol.ThError("#sets.containsAll Cannot execute sets containsAll: elements is null");
6734 throw new thymol.ThError("#sets.containsAll Cannot execute sets containsAll: target is null");
6737 thExpressionObjectName: thExpressionObjectName,
6742 containsAll: containsAll
6746 thymol.objects.thStringsObject = function() {
6747 var thExpressionObjectName = "#strings";
6748 function toString(target) {
6750 if (target !== null && typeof target !== "undefined") {
6751 result = target.toString();
6755 function arrayToString(target) {
6757 if (target !== null && typeof target !== "undefined") {
6759 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
6760 if (target[i] !== null) {
6761 result.push(target[i].toString());
6769 function setToString(target) {
6771 if (target !== null && typeof target !== "undefined") {
6772 result = new thymol.ThSet();
6773 for (var k in target) {
6774 if (target.isContent(k)) {
6775 result.add(toString(target[k]));
6781 function abbreviate(target, maxSize, source) {
6784 if (target !== null && typeof target !== "undefined") {
6785 result = target.toString();
6786 if (result.length > maxSize) {
6787 result = result.substring(0, maxSize - 3) + "...";
6792 throwAbbreviateException("abbreviate", maxSize);
6794 function arrayAbbreviate(target, maxSize) {
6797 if (target !== null && typeof target !== "undefined") {
6799 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
6800 result.push(abbreviate(target[i], maxSize));
6805 throwAbbreviateException("arrayAbbreviate", maxSize);
6807 function setAbbreviate(target, maxSize) {
6810 if (target !== null && typeof target !== "undefined") {
6811 result = new thymol.ThSet();
6812 for (var k in target) {
6813 if (target.isContent(k)) {
6814 result.add(abbreviate(target[k], maxSize));
6820 throwAbbreviateException("setAbbreviate", maxSize);
6822 function throwAbbreviateException(source, maxSize) {
6823 throw new thymol.ThError("#strings." + source + ' Maximum size must be greater than or equal to 3 but was: "' + maxSize + '"');
6825 function equals(o1, o2) {
6828 } else if (o2 !== null) {
6829 return o1.toString() === o2.toString();
6833 function equalsIgnoreCase(o1, o2) {
6836 } else if (o2 !== null) {
6837 return o1.toString().toLowerCase() === o2.toString().toLowerCase();
6841 function contains(target, fragment) {
6842 if (target !== null) {
6843 if (fragment !== null) {
6844 return target.toString().indexOf(fragment) >= 0;
6846 throw new thymol.ThError("#strings.contains Fragment cannot be null");
6848 throw new thymol.ThError("#strings.contains Cannot apply contains on null");
6850 function arrayContains(target, fragment) {
6851 if (target !== null) {
6853 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
6854 result.push(contains(target[i], fragment));
6858 throw new thymol.ThError("#strings.arrayContains Cannot apply arrayContains on null");
6860 function setContains(target, fragment) {
6861 if (target !== null) {
6862 var result = new thymol.ThSet();
6863 for (var k in target) {
6864 if (target.isContent(k)) {
6865 result.add(contains(target[k], fragment));
6870 throw new thymol.ThError("#strings.setContains Cannot apply setContains on null");
6872 function containsIgnoreCase(target, fragment) {
6873 if (target !== null) {
6874 if (fragment !== null) {
6875 return target.toString().toLowerCase().indexOf(fragment.toLowerCase()) >= 0;
6877 throw new thymol.ThError("#strings.containsIgnoreCase Fragment cannot be null");
6879 throw new thymol.ThError("#strings.containsIgnoreCase Cannot apply containsIgnoreCase on null");
6881 function arrayContainsIgnoreCase(target, fragment) {
6882 if (target !== null) {
6884 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
6885 result.push(containsIgnoreCase(target[i], fragment));
6889 throw new thymol.ThError("#strings.arrayContainsIgnoreCase Cannot apply arrayContainsIgnoreCase on null");
6891 function setContainsIgnoreCase(target, fragment) {
6892 if (target !== null) {
6893 var result = new thymol.ThSet();
6894 for (var k in target) {
6895 if (target.isContent(k)) {
6896 result.add(containsIgnoreCase(target[k], fragment));
6901 throw new thymol.ThError("#strings.setContainsIgnoreCase Cannot apply setContainsIgnoreCase on null");
6903 function startsWith(target, prefix) {
6904 if (target !== null) {
6905 if (prefix !== null) {
6906 return target.toString().indexOf(prefix) === 0;
6908 throw new thymol.ThError("#strings.startsWith Prefix cannot be null");
6910 throw new thymol.ThError("#strings.startsWith Cannot apply startsWith on null");
6912 function arrayStartsWith(target, prefix) {
6913 if (target !== null) {
6915 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
6916 result.push(startsWith(target[i], prefix));
6920 throw new thymol.ThError("#strings.arrayStartsWith Target cannot be null");
6922 function setStartsWith(target, prefix) {
6923 if (target !== null) {
6924 var result = new thymol.ThSet();
6925 for (var k in target) {
6926 if (target.isContent(k)) {
6927 result.add(startsWith(target[k], prefix));
6932 throw new thymol.ThError("#strings.setStartsWith Target cannot be null");
6934 function endsWith(target, suffix) {
6935 if (target !== null) {
6936 if (suffix !== null) {
6937 var str = target.toString();
6938 return str.indexOf(suffix) === str.length - suffix.length;
6940 throw new thymol.ThError("#strings.startsWith Suffix cannot be null");
6942 throw new thymol.ThError("#strings.endsWith Cannot apply endsWith on null");
6944 function arrayEndsWith(target, suffix) {
6945 if (target !== null) {
6947 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
6948 result.push(endsWith(target[i], suffix));
6952 throw new thymol.ThError("#strings.arrayEndsWith Target cannot be null");
6954 function setEndsWith(target, suffix) {
6955 if (target !== null) {
6956 var result = new thymol.ThSet();
6957 for (var k in target) {
6958 if (target.isContent(k)) {
6959 result.add(endsWith(target[k], suffix));
6964 throw new thymol.ThError("#strings.setEndsWith Target cannot be null");
6966 function substring(target, start, end) {
6967 if (target !== null) {
6968 return target.toString().substring(start, end);
6970 throw new thymol.ThError("#strings.substring Target cannot be null");
6972 function arraySubstring(target, start, end) {
6973 if (target !== null) {
6975 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
6976 result.push(substring(target[i], start, end));
6980 throw new thymol.ThError("#strings.arraySubstring Target cannot be null");
6982 function setSubstring(target, start, end) {
6983 if (target !== null) {
6984 var result = new thymol.ThSet();
6985 for (var k in target) {
6986 if (target.isContent(k)) {
6987 result.add(substring(target[k], start, end));
6992 throw new thymol.ThError("#strings.setSubstring Target cannot be null");
6994 function substringAfter(target, substr) {
6995 if (target !== null) {
6996 if (substr !== null) {
6997 var str = target.toString();
6998 var indx = str.indexOf(substr);
7002 return str.substring(indx + substr.length);
7004 throw new thymol.ThError("#strings.substringAfter Parameter substring cannot be null");
7006 throw new thymol.ThError("#strings.substringAfter Cannot apply substringAfter on null");
7008 function arraySubstringAfter(target, substr) {
7009 if (target !== null) {
7011 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
7012 result.push(substringAfter(target[i], substr));
7016 throw new thymol.ThError("#strings.arraySubstringAfter Cannot apply arraySubstringAfter on null");
7018 function setSubstringAfter(target, substr) {
7019 if (target !== null) {
7020 var result = new thymol.ThSet();
7021 for (var k in target) {
7022 if (target.isContent(k)) {
7023 result.add(substringAfter(target[k], substr));
7028 throw new thymol.ThError("#strings.setSubstringAfter Cannot apply setSubstringAfter on null");
7030 function substringBefore(target, substr) {
7031 if (target !== null) {
7032 if (substr !== null) {
7033 var str = target.toString();
7034 var indx = str.indexOf(substr);
7038 return str.substring(0, indx);
7040 throw new thymol.ThError("#strings.substringBefore Parameter substring cannot be null");
7042 throw new thymol.ThError("#strings.substringBefore Cannot apply substringBefore on null");
7044 function arraySubstringBefore(target, substr) {
7045 if (target !== null) {
7047 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
7048 result.push(substringBefore(target[i], substr));
7052 throw new thymol.ThError("#strings.arraySubstringBefore Cannot apply arraySubstringBefore on null");
7054 function setSubstringBefore(target, substr) {
7055 if (target !== null) {
7056 var result = new thymol.ThSet();
7057 for (var k in target) {
7058 if (target.isContent(k)) {
7059 result.add(substringBefore(target[k], substr));
7064 throw new thymol.ThError("#strings.setSubstringBefore Cannot apply setSubstringBefore on null");
7066 function prepend(target, prefix) {
7067 if (target !== null) {
7068 if (prefix !== null) {
7069 return prefix.toString() + target.toString();
7071 throw new thymol.ThError("#strings.prepend Prefix cannot be null");
7073 throw new thymol.ThError("#strings.prepend Cannot apply prepend on null");
7075 function arrayPrepend(target, prefix) {
7076 if (target !== null) {
7078 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
7079 result.push(prepend(target[i], prefix));
7083 throw new thymol.ThError("#strings.arrayPrepend Cannot apply arrayPrepend on null");
7085 function setPrepend(target, prefix) {
7086 if (target !== null) {
7087 var result = new thymol.ThSet();
7088 for (var k in target) {
7089 if (target.isContent(k)) {
7090 result.add(prepend(target[k], prefix));
7095 throw new thymol.ThError("#strings.setPrepend Cannot apply setPrepend on null");
7097 function repeat(target, times) {
7099 for (var i = 0; i < times; i++) {
7100 result += target.toString();
7104 function append(target, suffix) {
7105 if (target !== null) {
7106 if (suffix !== null) {
7107 return target.toString() + suffix.toString();
7109 throw new thymol.ThError("#strings.append Suffix cannot be null");
7111 throw new thymol.ThError("#strings.append Cannot apply append on null");
7115 for (var i = 0, iLimit = arguments.length; i < iLimit; i++) {
7116 if (arguments[i] !== null) {
7117 result += arguments[i];
7122 function concatReplaceNulls() {
7124 for (var i = 1, iLimit = arguments.length; i < iLimit; i++) {
7125 if (arguments[i] === null) {
7126 result += arguments[0];
7128 result += arguments[i];
7133 function arrayAppend(target, suffix) {
7134 if (target !== null) {
7136 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
7137 result.push(append(target[i], suffix));
7141 throw new thymol.ThError("#strings.arrayAppend Target cannot be null");
7143 function setAppend(target, suffix) {
7144 if (target !== null) {
7145 var result = new thymol.ThSet();
7146 for (var k in target) {
7147 if (target.isContent(k)) {
7148 result.add(append(target[k], suffix));
7153 throw new thymol.ThError("#strings.setAppend Target cannot be null");
7155 function indexOf(target, fragment) {
7156 if (target !== null) {
7157 if (fragment !== null) {
7158 var str = target.toString();
7159 var indx = str.indexOf(fragment);
7162 throw new thymol.ThError("#strings.indexOf Fragment cannot be null");
7164 throw new thymol.ThError("#strings.indexOf Cannot apply indexOf on null");
7166 function arrayIndexOf(target, fragment) {
7167 if (target !== null) {
7169 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
7170 result.push(indexOf(target[i], fragment));
7174 throw new thymol.ThError("#strings.arrayIndexOf Cannot apply arrayIndexOf on null");
7176 function setIndexOf(target, fragment) {
7177 if (target !== null) {
7178 var result = new thymol.ThSet();
7179 for (var k in target) {
7180 if (target.isContent(k)) {
7181 result.add(indexOf(target[k], fragment));
7186 throw new thymol.ThError("#strings.setIndexOf Cannot apply setIndexOf on null");
7188 function isEmpty(target) {
7189 if (target !== null) {
7190 var str = target.toString();
7192 str = str.replace(/(?:[\\]t)/g, " ").replace(/(?:[\\]n)/g, "\n").replace(/(?:[\\]v)/g, "
\v").replace(/(?:[\\]f)/g, "\f").replace(/(?:[\\]r)/g, "\r");
7194 if (str.length !== 0) {
7201 function arrayIsEmpty(target) {
7202 if (target !== null) {
7204 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
7205 result.push(isEmpty(target[i]));
7209 throw new thymol.ThError("#strings.arrayIsEmpty Target cannot be null");
7211 function setIsEmpty(target) {
7212 if (target !== null) {
7213 var result = new thymol.ThSet();
7214 for (var k in target) {
7215 if (target.isContent(k)) {
7216 result.add(isEmpty(target[k]));
7221 throw new thymol.ThError("#strings.setIsEmpty Target cannot be null");
7223 function arrayJoin(stringArray, separator) {
7224 if (stringArray !== null) {
7225 if (separator !== null) {
7226 var sepStr = separator.toString();
7228 for (var i = 0, iLimit = stringArray.length; i < iLimit; i++) {
7229 if ("" !== result) {
7232 result += stringArray[i];
7236 throw new thymol.ThError("#strings.arrayJoin Separator cannot be null");
7238 throw new thymol.ThError("#strings.arrayJoin Cannot apply join on null");
7240 function setJoin(stringSet, separator) {
7241 if (stringSet !== null) {
7242 if (separator !== null) {
7243 var sepStr = separator.toString();
7245 for (var k in stringSet) {
7246 if (stringSet.isContent(k)) {
7247 if ("" !== result) {
7250 result += stringSet[k];
7255 throw new thymol.ThError("#strings.setJoin Separator cannot be null");
7257 throw new thymol.ThError("#strings.setJoin Cannot apply join on null");
7259 function doRegExpify(target, flags) {
7260 var result = target.toString();
7261 result = result.replace(/[\\]/g, "\\").replace(/[\^]/g, "^").replace(/[\[]/g, "[").replace(/[\]]/g, "]").replace(/[\(]/g, "(").replace(/[\)]/g, ")");
7262 result = "[" + result + "]";
7263 return new RegExp(result, flags);
7265 function doSplit(target, separator) {
7266 var re = doRegExpify(separator);
7267 var splits = target.split(re);
7269 for (var i = 0, iLimit = splits.length; i < iLimit; i++) {
7271 result.push(splits[i]);
7276 function arraySplit(target, separator) {
7277 if (target !== null) {
7278 if (separator !== null) {
7279 return doSplit(target, separator);
7281 throw new thymol.ThError("#strings.arraySplit Separator cannot be null");
7283 throw new thymol.ThError("#strings.arraySplit Cannot apply split on null");
7285 function setSplit(target, separator) {
7286 if (target !== null) {
7287 if (separator !== null) {
7288 var result = new thymol.ThSet();
7289 var splits = doSplit(target, separator);
7290 for (var i = 0, iLimit = splits.length; i < iLimit; i++) {
7291 result.add(splits[i]);
7295 throw new thymol.ThError("#strings.setSplit Separator cannot be null");
7297 throw new thymol.ThError("#strings.setSplit Cannot apply split on null");
7299 function length(target) {
7300 if (target !== null) {
7301 return target.toString().length;
7303 throw new thymol.ThError("#strings.length Cannot apply length on null");
7305 function arrayLength(target) {
7306 if (target !== null) {
7308 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
7309 result.push(length(target[i]));
7313 throw new thymol.ThError("#strings.arrayLength Target cannot be null");
7315 function setLength(target) {
7316 if (target !== null) {
7317 var result = new thymol.ThSet();
7318 for (var k in target) {
7319 if (target.isContent(k)) {
7320 result.add(length(target[k]));
7325 throw new thymol.ThError("#strings.setLength Target cannot be null");
7327 function getReplacer(target) {
7328 var bfr = target.replace(/[$]/g, "[$]").replace(/[*]/g, "[*]").replace(/[\']/g, "[']").replace(/[+]/g, "[+]").replace(/[\(]/g, "[(]").replace(/[\)]/g, "[)]");
7329 return new RegExp(bfr, "g");
7331 function replace(target, before, after) {
7332 if (target !== null) {
7333 if (before !== null) {
7334 var bfr = unescapeXml(before);
7335 if (after !== null) {
7336 var re = getReplacer(bfr);
7337 var aft = unescapeXml(after);
7338 return target.replace(re, aft);
7340 throw new thymol.ThError("#strings.replace After cannot be null");
7342 throw new thymol.ThError("#strings.replace Before cannot be null");
7344 throw new thymol.ThError("#strings.replace Cannot apply replace on null");
7346 function arrayReplace(target, before, after) {
7347 if (target !== null) {
7348 if (before !== null) {
7349 var bfr = unescapeXml(before);
7350 if (after !== null) {
7351 var re = getReplacer(bfr);
7352 var aft = unescapeXml(after);
7354 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
7355 result.push(target[i].toString().replace(re, aft));
7359 throw new thymol.ThError("#strings.arrayReplace After cannot be null");
7361 throw new thymol.ThError("#strings.arrayReplace Before cannot be null");
7363 throw new thymol.ThError("#strings.arrayReplace Cannot apply replace on null");
7365 function setReplace(target, before, after) {
7366 if (target !== null) {
7367 if (before !== null) {
7368 var bfr = unescapeXml(before);
7369 if (after !== null) {
7370 var re = getReplacer(bfr);
7371 var aft = unescapeXml(after);
7372 var result = new thymol.ThSet();
7373 for (var k in target) {
7374 if (target.isContent(k)) {
7375 result.add(target[k].toString().replace(re, aft));
7380 throw new thymol.ThError("#strings.setReplace Array of 'after' values cannot be null");
7382 throw new thymol.ThError("#strings.setReplace Array of 'before' values cannot be null");
7384 throw new thymol.ThError("#strings.setReplace Cannot apply replace on null");
7386 function multipleReplace(target, before, after) {
7387 if (target !== null) {
7388 if (before !== null) {
7389 if (Object.prototype.toString.call(before) == "[object Array]") {
7390 if (after !== null) {
7391 if (Object.prototype.toString.call(after) == "[object Array]") {
7392 if (before.length === after.length) {
7393 var result = target;
7395 for (var i = 0, iLimit = before.length; i < iLimit; i++) {
7396 bfr = unescapeXml(before[i]);
7397 var re = getReplacer(bfr);
7398 aft = unescapeXml(after[i]);
7399 result = result.replace(re, aft);
7403 throw new thymol.ThError("#strings.multipleReplace Arrays of 'before' and 'after' values must have the same length");
7405 throw new thymol.ThError("#strings.multipleReplace After must be an array type");
7407 throw new thymol.ThError("#strings.multipleReplace After cannot be null");
7409 throw new thymol.ThError("#strings.multipleReplace Before must be an array type");
7411 throw new thymol.ThError("#strings.multipleReplace Before cannot be null");
7413 throw new thymol.ThError("#strings.multipleReplace Target cannot be null");
7415 function arrayMultipleReplace(target, before, after) {
7416 if (target !== null) {
7418 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
7419 result.push(multipleReplace(target[i].toString(), before, after));
7423 throw new thymol.ThError("#strings.arrayMultipleReplace Target cannot be null");
7425 function setMultipleReplace(target, before, after) {
7426 if (target !== null) {
7427 var result = new thymol.ThSet();
7428 for (var k in target) {
7429 if (target.isContent(k)) {
7430 result.add(multipleReplace(target[k].toString(), before, after));
7435 throw new thymol.ThError("#strings.setMultipleReplace Target cannot be null");
7437 function toUpperCase(target) {
7439 if (target !== null && typeof target !== "undefined") {
7440 result = target.toString().toUpperCase();
7444 function arrayToUpperCase(target) {
7446 if (target !== null && typeof target !== "undefined") {
7448 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
7449 if (target[i] !== null) {
7450 result.push(target[i].toString().toUpperCase());
7458 function setToUpperCase(target) {
7460 if (target !== null && typeof target !== "undefined") {
7461 result = new thymol.ThSet();
7462 for (var k in target) {
7463 if (target.isContent(k)) {
7464 result.add(target[k].toString().toUpperCase());
7470 function toLowerCase(target) {
7472 if (target !== null && typeof target !== "undefined") {
7473 result = target.toString().toLowerCase();
7477 function arrayToLowerCase(target) {
7479 if (target !== null && typeof target !== "undefined") {
7481 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
7482 if (target[i] !== null) {
7483 result.push(target[i].toString().toLowerCase());
7491 function setToLowerCase(target) {
7493 if (target !== null && typeof target !== "undefined") {
7494 result = new thymol.ThSet();
7495 for (var k in target) {
7496 if (target.isContent(k)) {
7497 result.add(target[k].toString().toLowerCase());
7503 function trim(target) {
7505 if (target !== null && typeof target !== "undefined") {
7506 result = target.toString().trim();
7510 function arrayTrim(target) {
7512 if (target !== null && typeof target !== "undefined") {
7514 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
7515 if (target[i] !== null) {
7516 result.push(target[i].toString().trim());
7524 function setTrim(target) {
7526 if (target !== null && typeof target !== "undefined") {
7527 result = new thymol.ThSet();
7528 for (var k in target) {
7529 if (target.isContent(k)) {
7530 result.add(target[k].toString().trim());
7536 function capitalize(target) {
7538 if (target !== null && typeof target !== "undefined") {
7539 result = target.toString();
7540 if (result.length > 0) {
7541 result = result.charAt(0).toUpperCase() + result.substr(1);
7546 function arrayCapitalize(target) {
7548 if (target !== null && typeof target !== "undefined") {
7550 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
7551 if (target[i] !== null) {
7552 result.push(capitalize(target[i]));
7560 function setCapitalize(target) {
7562 if (target !== null && typeof target !== "undefined") {
7563 result = new thymol.ThSet();
7564 for (var k in target) {
7565 if (target.isContent(k)) {
7566 result.add(capitalize(target[k]));
7572 function unCapitalize(target) {
7574 if (target !== null && typeof target !== "undefined") {
7575 result = target.toString();
7576 if (result.length > 0) {
7577 result = result.charAt(0).toLowerCase() + result.substr(1);
7582 function arrayUnCapitalize(target) {
7584 if (target !== null && typeof target !== "undefined") {
7586 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
7587 if (target[i] !== null) {
7588 result.push(unCapitalize(target[i]));
7596 function setUnCapitalize(target) {
7598 if (target !== null && typeof target !== "undefined") {
7599 result = new thymol.ThSet();
7600 for (var k in target) {
7601 if (target.isContent(k)) {
7602 result.add(unCapitalize(target[k]));
7608 function capitalizeWords(target, delimiters) {
7610 if (typeof delimiters === "undefined") {
7611 splitter = new RegExp("[^ \r\n\f
\v]\\w*", "g");
7613 var spec = "[^ " + delimiters + "]\\w*";
7614 splitter = new RegExp(spec, "g");
7617 if (target !== null && typeof target !== "undefined") {
7618 var str = target.toString();
7619 if (str.length > 0) {
7623 while ((matched = splitter.exec(str)) !== null) {
7624 result += str.substring(indx, matched.index);
7625 result += matched[0].charAt(0).toUpperCase() + matched[0].substr(1);
7626 indx = splitter.lastIndex;
7628 result += str.substring(indx);
7633 function arrayCapitalizeWords(target, delimiters) {
7635 if (target !== null && typeof target !== "undefined") {
7637 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
7638 if (target[i] !== null) {
7639 result.push(capitalizeWords(target[i], delimiters));
7647 function setCapitalizeWords(target, delimiters) {
7649 if (target !== null && typeof target !== "undefined") {
7650 result = new thymol.ThSet();
7651 for (var k in target) {
7652 if (target.isContent(k)) {
7653 result.add(capitalizeWords(target[k], delimiters));
7659 function escapeXml(target, escapeQuotesParam) {
7660 var result = target;
7661 if (target !== null && typeof target !== "undefined") {
7662 var escapeQuotes = escapeQuotesParam !== null && typeof escapeQuotesParam !== "undefined" && escapeQuotesParam;
7664 result = escapeXmlTrue(target);
7667 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
7668 var c = target.charAt(i);
7670 if (!isEntityStart(target, i)) {
7673 } else if (c === "<") {
7675 } else if (c === ">") {
7677 } else if (c === '"') {
7679 } else if (c === "'") {
7688 function escapeXmlTrue(target) {
7690 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
7691 var c = target.charAt(i);
7693 if (!isEntityStart(target, i)) {
7696 } else if (c === "<") {
7698 } else if (c === ">") {
7700 } else if (c === '"') {
7702 } else if (c === "'") {
7709 function unescapeXml(target) {
7711 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
7712 var c = target.charAt(i);
7714 c = isEntity(target, i);
7719 } else if (c === ">") {
7721 } else if (c === "&") {
7723 } else if (c === """) {
7725 } else if (c === "'") {
7736 function isEntity(buffer, position) {
7738 var i = position + 1;
7739 while (i < buffer.length) {
7741 if (!(c >= "A" && c <= "Z" || c >= "a" && c <= "z" || c >= "0" && c <= "9" || c == ";" || c == "#")) {
7752 function isEntityStart(buffer, position) {
7753 var i = position + 1;
7754 while (i < buffer.length) {
7756 if (!(c >= "A" && c <= "Z" || c >= "a" && c <= "z" || c >= "0" && c <= "9" || c == ";" || c == "#")) {
7766 function arrayEscapeXml(target) {
7768 if (target !== null && typeof target !== "undefined") {
7770 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
7771 if (target[i] !== null) {
7772 result.push(escapeXml(target[i], false));
7780 function setEscapeXml(target) {
7782 if (target !== null && typeof target !== "undefined") {
7783 result = new thymol.ThSet();
7784 for (var k in target) {
7785 if (target.isContent(k)) {
7786 result.add(escapeXml(target[k], false));
7792 function escapeJavaScript(target) {
7793 var result = target;
7794 if (target !== null && typeof target !== "undefined") {
7795 result = escapeJavaAny(target, true);
7799 function escapeJavaAny(target, javaScript) {
7801 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
7802 var c = target.charAt(i);
7803 var cc = target.charCodeAt(i);
7804 if (cc >= 32 && cc <= 127) {
7822 if (i > 0 && target.charAt(i - 1) == "<") {
7829 if (javaScript && i > 1) {
7830 if (target.charAt(i - 1) == "]" && target.charAt(i - 2) == "]") {
7865 c = unicodeEscape(cc);
7874 function unicodeEscape(c) {
7878 var output = "\\u" + x.toUpperCase();
7881 function hexEscape(c) {
7885 var output = "\\x" + x.toUpperCase();
7888 function arrayEscapeJavaScript(target) {
7890 if (target !== null && typeof target !== "undefined") {
7892 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
7893 if (target[i] !== null) {
7894 result.push(escapeJavaScript(target[i]));
7902 function setEscapeJavaScript(target) {
7904 if (target !== null && typeof target !== "undefined") {
7905 result = new thymol.ThSet();
7906 for (var k in target) {
7907 if (target.isContent(k)) {
7908 result.add(escapeJavaScript(target[k]));
7914 function unescapeJavaScript(target) {
7915 var result = target;
7916 if (target !== null && typeof target !== "undefined") {
7917 result = unescapeJavaAny(target);
7921 function unescapeJavaAny(target) {
7923 var unicodeSpec = "";
7924 var unicodeLen = -1;
7927 var lastWasEscape = false;
7928 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
7929 var c = target.charAt(i);
7930 if (unicodeLen >= 0) {
7932 if (c >= "0" && c <= "9" || c >= "A" && c <= "F" || c >= "a" && c <= "f") {
7934 if (unicodeLen > 3) {
7935 var cc = parseInt(unicodeSpec, 16);
7936 c = String.fromCharCode(cc);
7940 lastWasEscape = false;
7945 } else if (hexLen >= 0) {
7947 if (c >= "0" && c <= "9" || c >= "A" && c <= "F" || c >= "a" && c <= "f") {
7950 var cc = parseInt(hexSpec, 16);
7951 c = String.fromCharCode(cc);
7955 lastWasEscape = false;
7960 } else if (lastWasEscape) {
7963 } else if (c === "x") {
7991 lastWasEscape = false;
7993 } else if (c == "\\") {
7994 lastWasEscape = true;
7997 lastWasEscape = false;
8000 if (unicodeLen >= 0) {
8001 result += "\\u" + unicodeSpec;
8002 } else if (hexLen >= 0) {
8003 result += "\\x" + hexSpec;
8004 } else if (lastWasEscape) {
8009 function arrayUnescapeJavaScript(target) {
8011 if (target !== null && typeof target !== "undefined") {
8013 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
8014 if (target[i] !== null) {
8015 result.push(unescapeJavaScript(target[i]));
8023 function setUnescapeJavaScript(target) {
8025 if (target !== null && typeof target !== "undefined") {
8026 result = new thymol.ThSet();
8027 for (var k in target) {
8028 if (target.isContent(k)) {
8029 result.add(unescapeJavaScript(target[k]));
8035 function escapeJava(target) {
8036 var result = target;
8037 if (target !== null && typeof target !== "undefined") {
8038 result = escapeJavaAny(target, false);
8042 function arrayEscapeJava(target) {
8044 if (target !== null && typeof target !== "undefined") {
8046 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
8047 if (target[i] !== null) {
8048 result.push(escapeJava(target[i]));
8056 function setEscapeJava(target) {
8058 if (target !== null && typeof target !== "undefined") {
8059 result = new thymol.ThSet();
8060 for (var k in target) {
8061 if (target.isContent(k)) {
8062 result.add(escapeJava(target[k]));
8068 var ALPHA_NUMERIC = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
8069 function randomAlphanumeric(count) {
8071 for (var i = 0; i < count; i++) {
8072 result += ALPHA_NUMERIC.charAt(Math.floor(Math.random() * ALPHA_NUMERIC.length));
8076 function defaultString(target, defaultValue) {
8077 if (defaultValue !== null && typeof defaultValue !== "undefined") {
8078 if (target == null) {
8079 return defaultValue.toString();
8081 var targetString = target.toString();
8082 if (isEmpty(targetString)) {
8083 return defaultValue.toString();
8085 return targetString;
8087 throw new thymol.ThError("#strings.defaultString defaultValue cannot be null");
8089 function doArrayDefaultString(target, defaultValue) {
8090 if (target == null || typeof target === "undefined") {
8094 for (var i = 0, iLimit = target.length; i < iLimit; i++) {
8095 result.push(defaultString(target[i], defaultValue));
8099 function arrayDefaultString(target, defaultValue) {
8100 if (defaultValue !== null && typeof defaultValue !== "undefined") {
8101 return doArrayDefaultString(target, defaultValue);
8103 throw new thymol.ThError("#strings.arrayDefaultString defaultValue cannot be null");
8105 function listDefaultString(target, defaultValue) {
8106 if (defaultValue !== null && typeof defaultValue !== "undefined") {
8107 return doArrayDefaultString(target, defaultValue);
8109 throw new thymol.ThError("#strings.listDefaultString defaultValue cannot be null");
8111 function setDefaultString(target, defaultValue) {
8112 if (defaultValue !== null && typeof defaultValue !== "undefined") {
8113 if (target == null || typeof target === "undefined") {
8116 result = new thymol.ThSet();
8117 for (var k in target) {
8118 if (target.isContent(k)) {
8119 result.add(defaultString(target[k], defaultValue));
8124 throw new thymol.ThError("#strings.setDefaultString defaultValue cannot be null");
8127 thExpressionObjectName: thExpressionObjectName,
8129 arrayToString: arrayToString,
8130 listToString: arrayToString,
8131 setToString: setToString,
8132 abbreviate: abbreviate,
8133 arrayAbbreviate: arrayAbbreviate,
8134 listAbbreviate: arrayAbbreviate,
8135 setAbbreviate: setAbbreviate,
8137 equalsIgnoreCase: equalsIgnoreCase,
8139 arrayContains: arrayContains,
8140 listContains: arrayContains,
8141 setContains: setContains,
8142 containsIgnoreCase: containsIgnoreCase,
8143 arrayContainsIgnoreCase: arrayContainsIgnoreCase,
8144 listContainsIgnoreCase: arrayContainsIgnoreCase,
8145 setContainsIgnoreCase: setContainsIgnoreCase,
8146 startsWith: startsWith,
8147 arrayStartsWith: arrayStartsWith,
8148 listStartsWith: arrayStartsWith,
8149 setStartsWith: setStartsWith,
8151 arrayEndsWith: arrayEndsWith,
8152 listEndsWith: arrayEndsWith,
8153 setEndsWith: setEndsWith,
8154 substring: substring,
8155 arraySubstring: arraySubstring,
8156 listSubstring: arraySubstring,
8157 setSubstring: setSubstring,
8158 substringAfter: substringAfter,
8159 arraySubstringAfter: arraySubstringAfter,
8160 listSubstringAfter: arraySubstringAfter,
8161 setSubstringAfter: setSubstringAfter,
8162 substringBefore: substringBefore,
8163 arraySubstringBefore: arraySubstringBefore,
8164 listSubstringBefore: arraySubstringBefore,
8165 setSubstringBefore: setSubstringBefore,
8167 arrayPrepend: arrayPrepend,
8168 listPrepend: arrayPrepend,
8169 setPrepend: setPrepend,
8173 concatReplaceNulls: concatReplaceNulls,
8174 arrayAppend: arrayAppend,
8175 listAppend: arrayAppend,
8176 setAppend: setAppend,
8178 arrayIndexOf: arrayIndexOf,
8179 listIndexOf: arrayIndexOf,
8180 setIndexOf: setIndexOf,
8182 arrayIsEmpty: arrayIsEmpty,
8183 listIsEmpty: arrayIsEmpty,
8184 setIsEmpty: setIsEmpty,
8185 arrayJoin: arrayJoin,
8186 listJoin: arrayJoin,
8188 arraySplit: arraySplit,
8189 listSplit: arraySplit,
8192 arrayLength: arrayLength,
8193 listLength: arrayLength,
8194 setLength: setLength,
8196 arrayReplace: arrayReplace,
8197 listReplace: arrayReplace,
8198 setReplace: setReplace,
8199 multipleReplace: multipleReplace,
8200 arrayMultipleReplace: arrayMultipleReplace,
8201 listMultipleReplace: arrayMultipleReplace,
8202 setMultipleReplace: setMultipleReplace,
8203 toUpperCase: toUpperCase,
8204 arrayToUpperCase: arrayToUpperCase,
8205 listToUpperCase: arrayToUpperCase,
8206 setToUpperCase: setToUpperCase,
8207 toLowerCase: toLowerCase,
8208 arrayToLowerCase: arrayToLowerCase,
8209 listToLowerCase: arrayToLowerCase,
8210 setToLowerCase: setToLowerCase,
8212 arrayTrim: arrayTrim,
8213 listTrim: arrayTrim,
8215 capitalize: capitalize,
8216 arrayCapitalize: arrayCapitalize,
8217 listCapitalize: arrayCapitalize,
8218 setCapitalize: setCapitalize,
8219 unCapitalize: unCapitalize,
8220 arrayUnCapitalize: arrayUnCapitalize,
8221 listUnCapitalize: arrayUnCapitalize,
8222 setUnCapitalize: setUnCapitalize,
8223 capitalizeWords: capitalizeWords,
8224 arrayCapitalizeWords: arrayCapitalizeWords,
8225 listCapitalizeWords: arrayCapitalizeWords,
8226 setCapitalizeWords: setCapitalizeWords,
8227 escapeXml: escapeXml,
8228 arrayEscapeXml: arrayEscapeXml,
8229 listEscapeXml: arrayEscapeXml,
8230 setEscapeXml: setEscapeXml,
8231 escapeJavaScript: escapeJavaScript,
8232 arrayEscapeJavaScript: arrayEscapeJavaScript,
8233 listEscapeJavaScript: arrayEscapeJavaScript,
8234 setEscapeJavaScript: setEscapeJavaScript,
8235 unescapeJavaScript: unescapeJavaScript,
8236 arrayUnescapeJavaScript: arrayUnescapeJavaScript,
8237 listUnescapeJavaScript: arrayUnescapeJavaScript,
8238 setUnescapeJavaScript: setUnescapeJavaScript,
8239 escapeJava: escapeJava,
8240 arrayEscapeJava: arrayEscapeJava,
8241 listEscapeJava: arrayEscapeJava,
8242 setEscapeJava: setEscapeJava,
8243 unescapeJava: unescapeJavaScript,
8244 arrayUnescapeJava: arrayUnescapeJavaScript,
8245 listUnescapeJava: arrayUnescapeJavaScript,
8246 setUnescapeJava: setUnescapeJavaScript,
8247 randomAlphanumeric: randomAlphanumeric,
8248 defaultString: defaultString,
8249 arrayDefaultString: arrayDefaultString,
8250 listDefaultString: listDefaultString,
8251 setDefaultString: setDefaultString
8255 thymol.thObjectsConfigureModules = function() {
8257 objects: [ thymol.objects.thAggregatesObject, thymol.objects.thArraysObject, thymol.objects.thBoolsObject, thymol.objects.thDatesObject, thymol.objects.thCalendarsObject, thymol.objects.thIdsObject, thymol.objects.thListsObject, thymol.objects.thMapsObject, thymol.objects.thMessagesObject, thymol.objects.thNumbersObject, thymol.objects.thObjectsObject, thymol.objects.thSetsObject, thymol.objects.thStringsObject ]
8261 thymol.isServerSide = function() {
8265 exports.thymol = thymol;