diff --git a/modules/backend/behaviors/relationcontroller/assets/js/october.relation.js b/modules/backend/behaviors/relationcontroller/assets/js/october.relation.js index e7fb3164e..126e39284 100644 --- a/modules/backend/behaviors/relationcontroller/assets/js/october.relation.js +++ b/modules/backend/behaviors/relationcontroller/assets/js/october.relation.js @@ -70,7 +70,7 @@ /* * This function transfers the supplied variables as hidden form inputs, - * to any popup that is spawned within the supplied container. The spawned + * to any popup that is spawned within the supplied container. The spawned * popup must contain a form element. */ this.bindToPopups = function(container, vars) { @@ -87,7 +87,7 @@ if (typeof value == 'object') return value try { - return $.oc.JSON("{" + value + "}") + return ocJSON("{" + value + "}") } catch (e) { throw new Error('Error parsing the '+name+' attribute value. '+e) @@ -97,4 +97,4 @@ } $.oc.relationBehavior = new RelationBehavior; -}(window.jQuery); \ No newline at end of file +}(window.jQuery); diff --git a/modules/backend/widgets/form/assets/js/october.form.js b/modules/backend/widgets/form/assets/js/october.form.js index bb0496527..2a95c5aae 100644 --- a/modules/backend/widgets/form/assets/js/october.form.js +++ b/modules/backend/widgets/form/assets/js/october.form.js @@ -264,7 +264,7 @@ if (typeof value == 'object') return value try { - return $.oc.JSON("{" + value + "}") + return ocJSON("{" + value + "}") } catch (e) { throw new Error('Error parsing the '+name+' attribute value. '+e) diff --git a/modules/system/assets/js/framework-min.js b/modules/system/assets/js/framework-min.js index 019f4050f..e519b55f9 100644 --- a/modules/system/assets/js/framework-min.js +++ b/modules/system/assets/js/framework-min.js @@ -1,4 +1,5 @@ -"use strict";!function(){function a(e,r,n){for(var t="",o=r;o="0"&&str[pos]<="9")){var body="";for(var i=pos;i="0"&&str[i]<="9")){body+=str[i];}else{return{originLength:body.length,body:body};}} +throw new Error("Broken JSON number body near "+body);} +if(str[pos]==="{"||str[pos]==="["){var stack=[str[pos]];var body=str[pos];for(var i=pos+1;i=0)?pos-5:0,50));} +function canBeKeyHead(ch){if(ch[0]==="\\")return false;if((ch[0]>='a'&&ch[0]<='z')||(ch[0]>='A'&&ch[0]<='Z')||ch[0]==='_')return true;if(ch[0]>='0'&&ch[0]<='9')return true;if(ch[0]==='$')return true;if(ch.charCodeAt(0)>255)return true;return false;} +function isBlankChar(ch){return ch===" "||ch==="\n"||ch==="\t";} +function parse(str){str=str.trim();if(!str.length)throw new Error("Broken JSON object.");var result="";while(str&&str[0]===","){str=str.substr(1);} +if(str[0]==="\""||str[0]==="'"){if(str[str.length-1]!==str[0]){throw new Error("Invalid string JSON object.");} +var body="\"";for(var i=1;i="0"&&str[pos]<="9")){var body="";for(var i=pos;i="0"&&str[i]<="9")){body+=str[i];}else{return{originLength:body.length,body:body};}} -throw new Error("Broken JSON number body near "+body);} -if(str[pos]==="{"||str[pos]==="["){var stack=[str[pos]];var body=str[pos];for(var i=pos+1;i=0)?pos-5:0,50));} -function canBeKeyHead(ch){if(ch[0]==="\\")return false;if((ch[0]>='a'&&ch[0]<='z')||(ch[0]>='A'&&ch[0]<='Z')||ch[0]==='_')return true;if(ch[0]>='0'&&ch[0]<='9')return true;if(ch[0]==='$')return true;if(ch.charCodeAt(0)>255)return true;return false;} -function isBlankChar(ch){return ch===" "||ch==="\n"||ch==="\t";} -function parse(str){str=str.trim();if(!str.length)throw new Error("Broken JSON object.");var result="";while(str&&str[0]===","){str=str.substr(1);} -if(str[0]==="\""||str[0]==="'"){if(str[str.length-1]!==str[0]){throw new Error("Invalid string JSON object.");} -var body="\"";for(var i=1;i="0"&&str[pos]<="9")){var body="";for(var i=pos;i="0"&&str[i]<="9")){body+=str[i];}else{return{originLength:body.length,body:body};}} +throw new Error("Broken JSON number body near "+body);} +if(str[pos]==="{"||str[pos]==="["){var stack=[str[pos]];var body=str[pos];for(var i=pos+1;i=0)?pos-5:0,50));} +function canBeKeyHead(ch){if(ch[0]==="\\")return false;if((ch[0]>='a'&&ch[0]<='z')||(ch[0]>='A'&&ch[0]<='Z')||ch[0]==='_')return true;if(ch[0]>='0'&&ch[0]<='9')return true;if(ch[0]==='$')return true;if(ch.charCodeAt(0)>255)return true;return false;} +function isBlankChar(ch){return ch===" "||ch==="\n"||ch==="\t";} +function parse(str){str=str.trim();if(!str.length)throw new Error("Broken JSON object.");var result="";while(str&&str[0]===","){str=str.substr(1);} +if(str[0]==="\""||str[0]==="'"){if(str[str.length-1]!==str[0]){throw new Error("Invalid string JSON object.");} +var body="\"";for(var i=1;i= "0" && str[pos] <= "9")) { + var body = ""; + for (var i = pos; i < str.length; i++) { + if (str[i] === "-" || str[i] === "+" || str[i] === "." || (str[i] >= "0" && str[i] <= "9")) { + body += str[i]; + } else { + return { + originLength: body.length, + body: body + }; + } + } + throw new Error("Broken JSON number body near " + body); + } + + // parse object + if (str[pos] === "{" || str[pos] === "[") { + var stack = [str[pos]]; + var body = str[pos]; + for (var i = pos + 1; i < str.length; i++) { + body += str[i]; + if (str[i] === "\\") { + if (i + 1 < str.length) body += str[i + 1]; + i++; + } else if (str[i] === "\"") { + if (stack[stack.length - 1] === "\"") { + stack.pop(); + } else if (stack[stack.length - 1] !== "'") { + stack.push(str[i]); + } + } else if (str[i] === "'") { + if (stack[stack.length - 1] === "'") { + stack.pop(); + } else if (stack[stack.length - 1] !== "\"") { + stack.push(str[i]); + } + } else if (stack[stack.length - 1] !== "\"" && stack[stack.length - 1] !== "'") { + if (str[i] === "{") { + stack.push("{"); + } else if (str[i] === "}") { + if (stack[stack.length - 1] === "{") { + stack.pop(); + } else { + throw new Error("Broken JSON " + (str[pos] === "{" ? "object" : "array") + " body near " + body); + } + } else if (str[i] === "[") { + stack.push("["); + } else if (str[i] === "]") { + if (stack[stack.length - 1] === "[") { + stack.pop(); + } else { + throw new Error("Broken JSON " + (str[pos] === "{" ? "object" : "array") + " body near " + body); + } + } + } + if (!stack.length) { + return { + originLength: i - pos, + body: body + }; + } + } + throw new Error("Broken JSON " + (str[pos] === "{" ? "object" : "array") + " body near " + body); + } + throw new Error("Broken JSON body near " + str.substr((pos - 5 >= 0) ? pos - 5 : 0, 50)); + } + + function canBeKeyHead(ch) { + if (ch[0] === "\\") return false; + if ((ch[0] >= 'a' && ch[0] <= 'z') || (ch[0] >= 'A' && ch[0] <= 'Z') || ch[0] === '_') return true; + if (ch[0] >= '0' && ch[0] <= '9') return true; + if (ch[0] === '$') return true; + if (ch.charCodeAt(0) > 255) return true; + return false; + } + + function isBlankChar(ch) { + return ch === " " || ch === "\n" || ch === "\t"; + } + + function parse(str) { + str = str.trim(); + if (!str.length) throw new Error("Broken JSON object."); + var result = ""; + + /* + * the mistake ',' + */ + while (str && str[0] === ",") { + str = str.substr(1); + } + + /* + * string + */ + if (str[0] === "\"" || str[0] === "'") { + if (str[str.length - 1] !== str[0]) { + throw new Error("Invalid string JSON object."); + } + + var body = "\""; + for (var i = 1; i < str.length; i++) { + if (str[i] === "\\") { + if (str[i + 1] === "'") { + body += str[i + 1] + } else { + body += str[i]; + body += str[i + 1]; + } + i++; + } else if (str[i] === str[0]) { + body += "\""; + return body + } else if (str[i] === "\"") { + body += "\\\"" + } else body += str[i]; + } + throw new Error("Invalid string JSON object."); + } + + /* + * boolean + */ + if (str === "true" || str === "false") { + return str; + } + + /* + * null + */ + if (str === "null") { + return "null"; + } + + /* + * number + */ + var num = parseFloat(str); + if (!isNaN(num)) { + return num.toString(); + } + + /* + * object + */ + if (str[0] === "{") { + var type = "needKey"; + var result = "{"; + + for (var i = 1; i < str.length; i++) { + if (isBlankChar(str[i])) { + continue; + } else if (type === "needKey" && (str[i] === "\"" || str[i] === "'")) { + var key = parseKey(str, i + 1, str[i]); + result += "\"" + key + "\""; + i += key.length; + i += 1; + type = "afterKey"; + } else if (type === "needKey" && canBeKeyHead(str[i])) { + var key = parseKey(str, i); + result += "\""; + result += key; + result += "\""; + i += key.length - 1; + type = "afterKey"; + } else if (type === "afterKey" && str[i] === ":") { + result += ":"; + type = ":"; + } else if (type === ":") { + var body = getBody(str, i); + + i = i + body.originLength - 1; + result += parse(body.body); + + type = "afterBody"; + } else if (type === "afterBody" || type === "needKey") { + var last = i; + while (str[last] === "," || isBlankChar(str[last])) { + last++; + } + if (str[last] === "}" && last === str.length - 1) { + while (result[result.length - 1] === ",") { + result = result.substr(0, result.length - 1); + } + result += "}"; + return result; + } else if (last !== i && result !== "{") { + result += ","; + type = "needKey"; + i = last - 1; + } + } + } + throw new Error("Broken JSON object near " + result); + } + + /* + * array + */ + if (str[0] === "[") { + var result = "["; + var type = "needBody"; + for (var i = 1; i < str.length; i++) { + if (" " === str[i] || "\n" === str[i] || "\t" === str[i]) { + continue; + } else if (type === "needBody") { + if (str[i] === ",") { + result += "null,"; + continue; + } + if (str[i] === "]" && i === str.length - 1) { + if (result[result.length - 1] === ",") result = result.substr(0, result.length - 1); + result += "]"; + return result; + } + + var body = getBody(str, i); + + i = i + body.originLength - 1; + result += parse(body.body); + + type = "afterBody"; + } else if (type === "afterBody") { + if (str[i] === ",") { + result += ","; + type = "needBody"; + + // deal with mistake "," + while (str[i + 1] === "," || isBlankChar(str[i + 1])) { + if (str[i + 1] === ",") result += "null,"; + i++; + } + } else if (str[i] === "]" && i === str.length - 1) { + result += "]"; + return result; + } + } + } + throw new Error("Broken JSON array near " + result); + } + } + + // Global function + window.ocJSON = function(json) { + var jsonString = parse(json); + return JSON.parse(jsonString); + }; + +}(window); diff --git a/modules/system/assets/js/october.parser.js b/modules/system/assets/js/framework.parser.js similarity index 94% rename from modules/system/assets/js/october.parser.js rename to modules/system/assets/js/framework.parser.js index 62e4e23e6..6a9aad055 100644 --- a/modules/system/assets/js/october.parser.js +++ b/modules/system/assets/js/framework.parser.js @@ -1,16 +1,13 @@ -/* - * October CMS JSON Parser - */ -"use strict"; +/* ======================================================================== + * OctoberCMS: front-end JavaScript parser + * http://octobercms.com + * + * (Note: This lib is included manually in the framework.js file) + * ======================================================================== + * Copyright 2016-2020 Alexey Bobkov, Samuel Georges + * ======================================================================== */ -(function() { - /** - * parse key - * @param str - * @param pos - * @param quote - * @returns {string} - */ ++function(window) { "use strict"; function parseKey(str, pos, quote) { var key = ""; for (var i = pos; i < str.length; i++) { @@ -30,12 +27,6 @@ throw new Error("Broken JSON syntax near " + key); } - /* - * get body - * @param str - * @param pos - * @returns {*} - */ function getBody(str, pos) { // parse string body if (str[pos] === "\"" || str[pos] === "'") { @@ -155,11 +146,6 @@ throw new Error("Broken JSON body near " + str.substr((pos - 5 >= 0) ? pos - 5 : 0, 50)); } - /* - * This is a char can be key head - * @param ch - * @returns {boolean} - */ function canBeKeyHead(ch) { if (ch[0] === "\\") return false; if ((ch[0] >= 'a' && ch[0] <= 'z') || (ch[0] >= 'A' && ch[0] <= 'Z') || ch[0] === '_') return true; @@ -173,10 +159,6 @@ return ch === " " || ch === "\n" || ch === "\t"; } - /* - * parse JSON - * @param str - */ function parse(str) { str = str.trim(); if (!str.length) throw new Error("Broken JSON object."); @@ -339,17 +321,10 @@ } } - /* - * parse October JSON string into JSON object - * @param json - * @returns {*} - */ - if ($.oc === undefined) - $.oc = {} - - $.oc.JSON = function(json) { + // Global function + window.ocJSON = function(json) { var jsonString = parse(json); return JSON.parse(jsonString); }; -})(); +}(window); diff --git a/modules/system/assets/ui/js/autocomplete.js b/modules/system/assets/ui/js/autocomplete.js index 3bf55ca29..1203ff46c 100644 --- a/modules/system/assets/ui/js/autocomplete.js +++ b/modules/system/assets/ui/js/autocomplete.js @@ -1,6 +1,6 @@ /* * The autcomplete plugin, a forked version of Bootstrap's original typeahead plugin. - * + * * Data attributes: * - data-control="autocomplete" - enables the autocomplete plugin * @@ -378,7 +378,7 @@ if (typeof value == 'object') return value try { - return $.oc.JSON("{" + value + "}") + return ocJSON("{" + value + "}") } catch (e) { throw new Error('Error parsing the '+name+' attribute value. '+e) diff --git a/modules/system/assets/ui/js/chart.line.js b/modules/system/assets/ui/js/chart.line.js index d54fd030b..ee41bedfa 100644 --- a/modules/system/assets/ui/js/chart.line.js +++ b/modules/system/assets/ui/js/chart.line.js @@ -39,7 +39,7 @@ tickLength: 5 }, selection: { mode: "x" }, - grid: { + grid: { markingsColor: "rgba(0,0,0, 0.02)", backgroundColor: { colors: ["#fff", "#fff"] }, borderColor: "#7bafcc", @@ -80,7 +80,7 @@ var parsedOptions = {} try { - parsedOptions = $.oc.JSON("{" + value + "}"); + parsedOptions = ocJSON("{" + value + "}"); } catch (e) { throw new Error('Error parsing the data-chart-options attribute value. '+e); } @@ -102,15 +102,15 @@ if (this.options.zoomable) { this.$el.on("plotselected", function (event, ranges) { - var newCoords = { - xaxis: { min: ranges.xaxis.from, max: ranges.xaxis.to } + var newCoords = { + xaxis: { min: ranges.xaxis.from, max: ranges.xaxis.to } } - + $.plot(self.$el, self.fullDataSet, $.extend(true, {}, self.chartOptions, newCoords)) self.resetZoomLink.show() }); } - + /* * Markings Helper */ @@ -121,14 +121,14 @@ function weekendAreas(axes) { var markings = [], d = new Date(axes.xaxis.min); - + // Go to the first Saturday d.setUTCDate(d.getUTCDate() - ((d.getUTCDay() + 1) % 7)) d.setUTCSeconds(0) d.setUTCMinutes(0) d.setUTCHours(0) var i = d.getTime() - + do { // When we don't set yaxis, the rectangle automatically // extends to infinity upwards and downwards @@ -178,7 +178,7 @@ } /* - * Adds a data set to the chart. + * Adds a data set to the chart. * See https://github.com/flot/flot/blob/master/API.md#data-format for the list * of supported data set options. */ diff --git a/modules/system/assets/ui/js/popup.js b/modules/system/assets/ui/js/popup.js index 0da4bc87d..bf3b05e40 100644 --- a/modules/system/assets/ui/js/popup.js +++ b/modules/system/assets/ui/js/popup.js @@ -395,7 +395,7 @@ if (typeof value == 'object') return value try { - return $.oc.JSON("{" + value + "}") + return ocJSON("{" + value + "}") } catch (e) { throw new Error('Error parsing the '+name+' attribute value. '+e) diff --git a/modules/system/assets/ui/storm-min.js b/modules/system/assets/ui/storm-min.js index cb672e04b..54e1ec81a 100644 --- a/modules/system/assets/ui/storm-min.js +++ b/modules/system/assets/ui/storm-min.js @@ -2797,7 +2797,7 @@ $.fn.autocomplete.noConflict=function(){$.fn.autocomplete=old return this} function paramToObj(name,value){if(value===undefined)value='' if(typeof value=='object')return value -try{return $.oc.JSON("{"+value+"}")} +try{return ocJSON("{"+value+"}")} catch(e){throw new Error('Error parsing the '+name+' attribute value. '+e)}} $(document).on('focus.autocomplete.data-api','[data-control="autocomplete"]',function(e){var $this=$(this) if($this.data('autocomplete'))return @@ -3856,7 +3856,7 @@ $.fn.popup.noConflict=function(){$.fn.popup=old return this} function paramToObj(name,value){if(value===undefined)value='' if(typeof value=='object')return value -try{return $.oc.JSON("{"+value+"}")} +try{return ocJSON("{"+value+"}")} catch(e){throw new Error('Error parsing the '+name+' attribute value. '+e)}} $(document).on('click.oc.popup','[data-control="popup"]',function(event){event.preventDefault() $(this).popup()});$(document).on('ajaxPromise','[data-popup-load-indicator]',function(event,context){if($(this).data('request')!=context.handler)return @@ -3899,7 +3899,7 @@ $.oc.chartUtils=new ChartUtils();}(window.jQuery);+function($){"use strict";var this.chartOptions={xaxis:{mode:"time",tickLength:5},selection:{mode:"x"},grid:{markingsColor:"rgba(0,0,0, 0.02)",backgroundColor:{colors:["#fff","#fff"]},borderColor:"#7bafcc",borderWidth:0,color:"#ddd",hoverable:true,clickable:true,labelMargin:10},series:{lines:{show:true,fill:true},points:{show:true}},tooltip:true,tooltipOpts:{defaultTheme:false,content:"%x: %y",dateFormat:"%y-%0m-%0d",shifts:{x:10,y:20}},legend:{show:true,noColumns:2}} this.defaultDataSetOptions={shadowSize:0} var parsedOptions={} -try{parsedOptions=$.oc.JSON("{"+value+"}");}catch(e){throw new Error('Error parsing the data-chart-options attribute value. '+e);} +try{parsedOptions=ocJSON("{"+value+"}");}catch(e){throw new Error('Error parsing the data-chart-options attribute value. '+e);} this.chartOptions=$.extend({},this.chartOptions,parsedOptions) this.options=options this.$el=$(element)