fable 3.1.16 → 3.1.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fable.js +33 -17
- package/dist/fable.js.map +1 -1
- package/dist/fable.min.js +2 -2
- package/dist/fable.min.js.map +1 -1
- package/package.json +1 -1
- package/source/services/Fable-Service-DataFormat.js +19 -1
- package/source/services/Fable-Service-MetaTemplate/MetaTemplate-StringParser.js +28 -17
- package/source/services/Fable-Service-MetaTemplate.js +3 -2
- package/test/DataFormat-StringManipulation_tests.js +19 -0
package/dist/fable.js
CHANGED
|
@@ -3054,7 +3054,7 @@ try{if(!global.localStorage)return false;}catch(_){return false;}var val=global.
|
|
|
3054
3054
|
// presumably different callback function.
|
|
3055
3055
|
// This makes sure that own properties are retained, so that
|
|
3056
3056
|
// decorations and such are not lost along the way.
|
|
3057
|
-
module.exports=wrappy;function wrappy(fn,cb){if(fn&&cb)return wrappy(fn)(cb);if(typeof fn!=='function')throw new TypeError('need wrapper function');Object.keys(fn).forEach(function(k){wrapper[k]=fn[k];});return wrapper;function wrapper(){var args=new Array(arguments.length);for(var i=0;i<args.length;i++){args[i]=arguments[i];}var ret=fn.apply(this,args);var cb=args[args.length-1];if(typeof ret==='function'&&ret!==cb){Object.keys(cb).forEach(function(k){ret[k]=cb[k];});}return ret;}}},{}],148:[function(require,module,exports){module.exports=extend;var hasOwnProperty=Object.prototype.hasOwnProperty;function extend(){var target={};for(var i=0;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;}},{}],149:[function(require,module,exports){module.exports={"name":"fable","version":"3.1.
|
|
3057
|
+
module.exports=wrappy;function wrappy(fn,cb){if(fn&&cb)return wrappy(fn)(cb);if(typeof fn!=='function')throw new TypeError('need wrapper function');Object.keys(fn).forEach(function(k){wrapper[k]=fn[k];});return wrapper;function wrapper(){var args=new Array(arguments.length);for(var i=0;i<args.length;i++){args[i]=arguments[i];}var ret=fn.apply(this,args);var cb=args[args.length-1];if(typeof ret==='function'&&ret!==cb){Object.keys(cb).forEach(function(k){ret[k]=cb[k];});}return ret;}}},{}],148:[function(require,module,exports){module.exports=extend;var hasOwnProperty=Object.prototype.hasOwnProperty;function extend(){var target={};for(var i=0;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;}},{}],149:[function(require,module,exports){module.exports={"name":"fable","version":"3.1.18","description":"A service dependency injection, configuration and logging library.","main":"source/Fable.js","scripts":{"start":"node source/Fable.js","coverage":"./node_modules/.bin/nyc --reporter=lcov --reporter=text-lcov ./node_modules/mocha/bin/_mocha -- -u tdd -R spec","test":"./node_modules/.bin/mocha -u tdd -R spec","build":"npx quack build","docker-dev-build":"docker build ./ -f Dockerfile_LUXURYCode -t fable-image:local","docker-dev-run":"docker run -it -d --name fable-dev -p 30001:8080 -p 38086:8086 -v \"$PWD/.config:/home/coder/.config\" -v \"$PWD:/home/coder/fable\" -u \"$(id -u):$(id -g)\" -e \"DOCKER_USER=$USER\" fable-image:local","docker-dev-shell":"docker exec -it fable-dev /bin/bash","tests":"./node_modules/mocha/bin/_mocha -u tdd --exit -R spec --grep"},"mocha":{"diff":true,"extension":["js"],"package":"./package.json","reporter":"spec","slow":"75","timeout":"5000","ui":"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]},"browser":{"./source/service/Fable-Service-EnvironmentData.js":"./source/service/Fable-Service-EnvironmentData-Web.js","./source/service/Fable-Service-FilePersistence.js":"./source/service/Fable-Service-FilePersistence-Web.js"},"repository":{"type":"git","url":"https://github.com/stevenvelozo/fable.git"},"keywords":["entity","behavior"],"author":"Steven Velozo <steven@velozo.com> (http://velozo.com/)","license":"MIT","bugs":{"url":"https://github.com/stevenvelozo/fable/issues"},"homepage":"https://github.com/stevenvelozo/fable","devDependencies":{"quackage":"^1.0.42"},"dependencies":{"async.eachlimit":"^0.5.2","async.waterfall":"^0.5.2","big.js":"^6.2.2","cachetrax":"^1.0.4","cookie":"^0.6.0","data-arithmatic":"^1.0.7","dayjs":"^1.11.13","fable-log":"^3.0.16","fable-serviceproviderbase":"^3.0.15","fable-settings":"^3.0.12","fable-uuid":"^3.0.11","manyfest":"^1.0.41","simple-get":"^4.0.1"}};},{}],150:[function(require,module,exports){/**
|
|
3058
3058
|
* Fable Application Services Support Library
|
|
3059
3059
|
* @author <steven@velozo.com>
|
|
3060
3060
|
*/// Pre-init services
|
|
@@ -3172,7 +3172,7 @@ this._Regex_formatterInsertCommas=/.{1,3}/g;// Match Function:
|
|
|
3172
3172
|
// Thoughts about below: /^([+-]?)(0*)(\d+)(\.(\d+))?$/;
|
|
3173
3173
|
this._Regex_formatterAddCommasToNumber=/^([-+]?)(0?)(\d+)(.?)(\d+)$/g;this._Regex_formatterDollarsRemoveCommas=/,/gi;this._Regex_formatterCleanNonAlphaChar=/[^a-zA-Z]/gi;this._Regex_formatterCapitalizeEachWord=/([a-zA-Z]+)/g;this._Regex_matcherHTMLEntities=/&(#?[a-zA-Z0-9]+);/g;// TODO: Potentially pull these in from a configuration.
|
|
3174
3174
|
// TODO: Use locale data for this if it's defaults all the way down.
|
|
3175
|
-
this._Value_MoneySign_Currency='$';this._Value_NaN_Currency='--';this._Value_GroupSeparator_Number=',';this._Value_Prefix_StringHash='HSH';this._Value_Clean_formatterCleanNonAlpha='';this._UseEngineStringStartsWith=typeof String.prototype.startsWith==='function';this._UseEngineStringEndsWith=typeof String.prototype.endsWith==='function';}/*************************************************************************
|
|
3175
|
+
this._Value_MoneySign_Currency='$';this._Value_NaN_Currency='--';this._Value_GroupSeparator_Number=',';this._Value_Prefix_StringHash='HSH';this._Value_Clean_formatterCleanNonAlpha='';this._UseEngineStringStartsWith=typeof String.prototype.startsWith==='function';this._UseEngineStringEndsWith=typeof String.prototype.endsWith==='function';this._SanitizeObjectKeyRegex=/[^a-zA-Z0-9_]/gi;this._SanitizeObjectKeyReplacement='_';this._SanitizeObjectKeyInvalid='INVALID';}/*************************************************************************
|
|
3176
3176
|
* String Manipulation and Comparison Functions
|
|
3177
3177
|
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*//**
|
|
3178
3178
|
* Reverse a string
|
|
@@ -3285,7 +3285,12 @@ if(pString.startsWith(pWrapCharacter)&&pString.endsWith(pWrapCharacter)){return
|
|
|
3285
3285
|
*
|
|
3286
3286
|
* @param {*} pString
|
|
3287
3287
|
* @returns
|
|
3288
|
-
*/cleanNonAlphaCharacters(pString){if(typeof pString=='string'&&pString!=''){return pString.replace(this._Regex_formatterCleanNonAlphaChar,this._Value_Clean_formatterCleanNonAlpha);}return'';}
|
|
3288
|
+
*/cleanNonAlphaCharacters(pString){if(typeof pString=='string'&&pString!=''){return pString.replace(this._Regex_formatterCleanNonAlphaChar,this._Value_Clean_formatterCleanNonAlpha);}return'';}/**
|
|
3289
|
+
* Clean a string of any characters to create a consistent object key.
|
|
3290
|
+
*
|
|
3291
|
+
* @param {string} pString The string to clean.
|
|
3292
|
+
* @return {string} the cleaned string, or a placeholder if the input is invalid
|
|
3293
|
+
*/sanitizeObjectKey(pString){if(typeof pString!=='string'||pString.length<1){return this._SanitizeObjectKeyInvalid;}return pString.replace(this._SanitizeObjectKeyRegex,this._SanitizeObjectKeyReplacement);}/*************************************************************************
|
|
3289
3294
|
* Number Formatting Functions
|
|
3290
3295
|
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*//**
|
|
3291
3296
|
* Insert commas every 3 characters from the right. Used by formatterAddCommasToNumber().
|
|
@@ -4238,8 +4243,9 @@ let tmpHistogramValueSet=Object.keys(tmpHistogram);let tmpModeValueSet=[];for(le
|
|
|
4238
4243
|
* @param {function} fCallback - The callback function to call when a pattern is matched
|
|
4239
4244
|
* @param {array} pDataContext - The history of data objects already passed in
|
|
4240
4245
|
* @param {any} [pScope] - A sticky scope that can be used to carry state and simplify template
|
|
4246
|
+
* @param {any} [pState] - A catchall state object for plumbing data through template processing.
|
|
4241
4247
|
* @return {string} The result from the parser
|
|
4242
|
-
*/parseString(pString,pData,fCallback,pDataContext,pScope){if(this.LogNoisiness>4){this.fable.log.trace(`Metatemplate parsing template string [${pString}] where the callback is a ${typeof fCallback}`,{TemplateData:pData});}return this.StringParser.parseString(pString,this.ParseTree,pData,fCallback,pDataContext,pScope);}}module.exports=FableServiceMetaTemplate;},{"./Fable-Service-MetaTemplate/MetaTemplate-StringParser.js":172,"./Fable-Service-MetaTemplate/MetaTemplate-WordTree.js":173,"fable-serviceproviderbase":59}],172:[function(require,module,exports){/**
|
|
4248
|
+
*/parseString(pString,pData,fCallback,pDataContext,pScope,pState){if(this.LogNoisiness>4){this.fable.log.trace(`Metatemplate parsing template string [${pString}] where the callback is a ${typeof fCallback}`,{TemplateData:pData});}return this.StringParser.parseString(pString,this.ParseTree,pData,fCallback,pDataContext,pScope,pState);}}module.exports=FableServiceMetaTemplate;},{"./Fable-Service-MetaTemplate/MetaTemplate-StringParser.js":172,"./Fable-Service-MetaTemplate/MetaTemplate-WordTree.js":173,"fable-serviceproviderbase":59}],172:[function(require,module,exports){/**
|
|
4243
4249
|
* String Parser
|
|
4244
4250
|
* @author Steven Velozo <steven@velozo.com>
|
|
4245
4251
|
* @description Parse a string, properly processing each matched token in the word tree.
|
|
@@ -4271,29 +4277,37 @@ pParserState.Pattern=false;pParserState.PatternStartNode=false;pParserState.Star
|
|
|
4271
4277
|
* @param {string} pCharacter - The character to append
|
|
4272
4278
|
* @param {Object} pParserState - The state object for the current parsing task
|
|
4273
4279
|
* @param {any} pData - The data available to the template
|
|
4274
|
-
* @param {any} pDataContext - The history of data objects/context already passed in
|
|
4280
|
+
* @param {Array<any>} pDataContext - The history of data objects/context already passed in
|
|
4275
4281
|
* @param {any} [pScope] - A sticky scope that can be used to carry state and simplify template
|
|
4282
|
+
* @param {any} [pState] - A catchall state object for plumbing data through template processing.
|
|
4276
4283
|
* @private
|
|
4277
|
-
*/parseCharacter(pCharacter,pParserState,pData,pDataContext,pScope){// If we are already in a pattern match traversal
|
|
4284
|
+
*/parseCharacter(pCharacter,pParserState,pData,pDataContext,pScope,pState){// If we are already in a pattern match traversal
|
|
4278
4285
|
if(pParserState.PatternMatch){// If the pattern is still matching the start and we haven't passed the buffer
|
|
4279
4286
|
if(!pParserState.StartPatternMatchComplete&&pCharacter in pParserState.Pattern){pParserState.Pattern=pParserState.Pattern[pCharacter];this.appendOutputBuffer(pCharacter,pParserState);}else if(pParserState.EndPatternMatchBegan){if(pCharacter in pParserState.Pattern.PatternEnd){// This leaf has a PatternEnd tree, so we will wait until that end is met.
|
|
4280
4287
|
pParserState.Pattern=pParserState.Pattern.PatternEnd[pCharacter];// Flush the output buffer.
|
|
4281
4288
|
this.appendOutputBuffer(pCharacter,pParserState);// If this last character is the end of the pattern, parse it.
|
|
4282
4289
|
// Run the function
|
|
4283
|
-
let tmpFunctionContext='ParserContext'in pParserState.Pattern?pParserState.Pattern.ParserContext:false;if(tmpFunctionContext){pParserState.OutputBuffer=pParserState.Pattern.Parse.call(tmpFunctionContext,pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length,pParserState.OutputBuffer.length-(pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)),pData,pDataContext,pScope);}else{pParserState.OutputBuffer=pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length,pParserState.OutputBuffer.length-(pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)),pData,pDataContext,pScope);}return this.resetOutputBuffer(pParserState);}else if(pCharacter in pParserState.PatternStartNode.PatternEnd){// We broke out of the end -- see if this is a new start of the end.
|
|
4290
|
+
let tmpFunctionContext='ParserContext'in pParserState.Pattern?pParserState.Pattern.ParserContext:false;if(tmpFunctionContext){pParserState.OutputBuffer=pParserState.Pattern.Parse.call(tmpFunctionContext,pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length,pParserState.OutputBuffer.length-(pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)),pData,pDataContext,pScope,pState);}else{pParserState.OutputBuffer=pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length,pParserState.OutputBuffer.length-(pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)),pData,pDataContext,pScope,pState);}return this.resetOutputBuffer(pParserState);}else if(pCharacter in pParserState.PatternStartNode.PatternEnd){// We broke out of the end -- see if this is a new start of the end.
|
|
4284
4291
|
pParserState.Pattern=pParserState.PatternStartNode.PatternEnd[pCharacter];this.appendOutputBuffer(pCharacter,pParserState);}else{pParserState.EndPatternMatchBegan=false;this.appendOutputBuffer(pCharacter,pParserState);}}else if('PatternEnd'in pParserState.Pattern){if(!pParserState.StartPatternMatchComplete){pParserState.StartPatternMatchComplete=true;pParserState.PatternStartNode=pParserState.Pattern;}this.appendOutputBuffer(pCharacter,pParserState);if(pCharacter in pParserState.Pattern.PatternEnd){// This is the first character of the end pattern.
|
|
4285
4292
|
pParserState.EndPatternMatchBegan=true;// This leaf has a PatternEnd tree, so we will wait until that end is met.
|
|
4286
4293
|
pParserState.Pattern=pParserState.Pattern.PatternEnd[pCharacter];// If this last character is the end of the pattern, parse it.
|
|
4287
4294
|
if('Parse'in pParserState.Pattern){// Run the t*mplate function
|
|
4288
|
-
let tmpFunctionContext='ParserContext'in pParserState.Pattern?pParserState.Pattern.ParserContext:false;if(tmpFunctionContext){pParserState.OutputBuffer=pParserState.Pattern.Parse.call(tmpFunctionContext,pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length,pParserState.OutputBuffer.length-(pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)),pData,pDataContext,pScope);}else{pParserState.OutputBuffer=pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length,pParserState.OutputBuffer.length-(pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)),pData,pDataContext,pScope);}return this.resetOutputBuffer(pParserState);}}}else{// We are in a pattern start but didn't match one; reset and start trying again from this character.
|
|
4295
|
+
let tmpFunctionContext='ParserContext'in pParserState.Pattern?pParserState.Pattern.ParserContext:false;if(tmpFunctionContext){pParserState.OutputBuffer=pParserState.Pattern.Parse.call(tmpFunctionContext,pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length,pParserState.OutputBuffer.length-(pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)),pData,pDataContext,pScope,pState);}else{pParserState.OutputBuffer=pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length,pParserState.OutputBuffer.length-(pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)),pData,pDataContext,pScope,pState);}return this.resetOutputBuffer(pParserState);}}}else{// We are in a pattern start but didn't match one; reset and start trying again from this character.
|
|
4289
4296
|
this.resetOutputBuffer(pParserState);}}// If we aren't in a pattern match or pattern, and this isn't the start of a new pattern (RAW mode)....
|
|
4290
4297
|
if(!pParserState.PatternMatch){// This may be the start of a new pattern....
|
|
4291
4298
|
if(pCharacter in pParserState.ParseTree){// ... assign the root node as the matched node.
|
|
4292
|
-
this.resetOutputBuffer(pParserState);this.appendOutputBuffer(pCharacter,pParserState);pParserState.Pattern=pParserState.ParseTree[pCharacter];pParserState.PatternMatch=true;return true;}else{this.appendOutputBuffer(pCharacter,pParserState);}}return false;}
|
|
4299
|
+
this.resetOutputBuffer(pParserState);this.appendOutputBuffer(pCharacter,pParserState);pParserState.Pattern=pParserState.ParseTree[pCharacter];pParserState.PatternMatch=true;return true;}else{this.appendOutputBuffer(pCharacter,pParserState);}}return false;}/**
|
|
4300
|
+
* @param {Object} pParserState - The state object for the current parsing task
|
|
4301
|
+
* @param {Object} pData - The data to pass to the function as a second parameter
|
|
4302
|
+
* @param {function} fCallback - The callback function to call when the parse is complete
|
|
4303
|
+
* @param {array} pDataContext - The history of data objects/context already passed in
|
|
4304
|
+
* @param {any} [pScope] - A sticky scope that can be used to carry state and simplify template
|
|
4305
|
+
* @param {any} [pState] - A catchall state object for plumbing data through template processing.
|
|
4306
|
+
*/executePatternAsync(pParserState,pData,fCallback,pDataContext,pScope,pState){// ... this is the end of a pattern, cut off the end tag and parse it.
|
|
4293
4307
|
// Trim the start and end tags off the output buffer now
|
|
4294
4308
|
if(pParserState.Pattern.isAsync){// Run the function
|
|
4295
|
-
let tmpFunctionContext='ParserContext'in pParserState.Pattern?pParserState.Pattern.ParserContext:false;if(tmpFunctionContext){return pParserState.Pattern.ParseAsync.call(tmpFunctionContext,pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length,pParserState.OutputBuffer.length-(pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)),pData,(pError,pAsyncOutput)=>{if(pError){this.fable.log.info(`Precedent ERROR: Async template error happened parsing ${pParserState.Pattern.PatternStart} ... ${pParserState.Pattern.PatternEnd}: ${pError}`);}pParserState.OutputBuffer=pAsyncOutput;this.resetOutputBuffer(pParserState);return fCallback();},pDataContext,pScope);}else{return pParserState.Pattern.ParseAsync(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length,pParserState.OutputBuffer.length-(pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)),pData,(pError,pAsyncOutput)=>{if(pError){this.fable.log.info(`Precedent ERROR: Async template error happened parsing ${pParserState.Pattern.PatternStart} ... ${pParserState.Pattern.PatternEnd}: ${pError}`);}pParserState.OutputBuffer=pAsyncOutput;this.resetOutputBuffer(pParserState);return fCallback();},pDataContext,pScope);}}else{// Run the t*mplate function
|
|
4296
|
-
let tmpFunctionContext='ParserContext'in pParserState.Pattern?pParserState.Pattern.ParserContext:false;if(tmpFunctionContext){pParserState.OutputBuffer=pParserState.Pattern.Parse.call(tmpFunctionContext,pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length,pParserState.OutputBuffer.length-(pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)),pData,pDataContext,pScope);}else{pParserState.OutputBuffer=pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length,pParserState.OutputBuffer.length-(pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)),pData,pDataContext,pScope);}this.resetOutputBuffer(pParserState);return fCallback();}}/**
|
|
4309
|
+
let tmpFunctionContext='ParserContext'in pParserState.Pattern?pParserState.Pattern.ParserContext:false;if(tmpFunctionContext){return pParserState.Pattern.ParseAsync.call(tmpFunctionContext,pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length,pParserState.OutputBuffer.length-(pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)),pData,(pError,pAsyncOutput)=>{if(pError){this.fable.log.info(`Precedent ERROR: Async template error happened parsing ${pParserState.Pattern.PatternStart} ... ${pParserState.Pattern.PatternEnd}: ${pError}`);}pParserState.OutputBuffer=pAsyncOutput;this.resetOutputBuffer(pParserState);return fCallback();},pDataContext,pScope,pState);}else{return pParserState.Pattern.ParseAsync(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length,pParserState.OutputBuffer.length-(pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)),pData,(pError,pAsyncOutput)=>{if(pError){this.fable.log.info(`Precedent ERROR: Async template error happened parsing ${pParserState.Pattern.PatternStart} ... ${pParserState.Pattern.PatternEnd}: ${pError}`);}pParserState.OutputBuffer=pAsyncOutput;this.resetOutputBuffer(pParserState);return fCallback();},pDataContext,pScope,pState);}}else{// Run the t*mplate function
|
|
4310
|
+
let tmpFunctionContext='ParserContext'in pParserState.Pattern?pParserState.Pattern.ParserContext:false;if(tmpFunctionContext){pParserState.OutputBuffer=pParserState.Pattern.Parse.call(tmpFunctionContext,pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length,pParserState.OutputBuffer.length-(pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)),pData,pDataContext,pScope,pState);}else{pParserState.OutputBuffer=pParserState.Pattern.Parse(pParserState.OutputBuffer.substr(pParserState.Pattern.PatternStartString.length,pParserState.OutputBuffer.length-(pParserState.Pattern.PatternStartString.length+pParserState.Pattern.PatternEndString.length)),pData,pDataContext,pScope,pState);}this.resetOutputBuffer(pParserState);return fCallback();}}/**
|
|
4297
4311
|
* Parse a character in the buffer.
|
|
4298
4312
|
* @method parseCharacterAsync
|
|
4299
4313
|
* @param {string} pCharacter - The character to append
|
|
@@ -4302,17 +4316,18 @@ let tmpFunctionContext='ParserContext'in pParserState.Pattern?pParserState.Patte
|
|
|
4302
4316
|
* @param {function} fCallback - The callback function to call when the parse is complete
|
|
4303
4317
|
* @param {array} pDataContext - The history of data objects/context already passed in
|
|
4304
4318
|
* @param {any} [pScope] - A sticky scope that can be used to carry state and simplify template
|
|
4319
|
+
* @param {any} [pState] - A catchall state object for plumbing data through template processing.
|
|
4305
4320
|
* @private
|
|
4306
|
-
*/parseCharacterAsync(pCharacter,pParserState,pData,fCallback,pDataContext,pScope){// If we are already in a pattern match traversal
|
|
4321
|
+
*/parseCharacterAsync(pCharacter,pParserState,pData,fCallback,pDataContext,pScope,pState){// If we are already in a pattern match traversal
|
|
4307
4322
|
if(pParserState.PatternMatch){// If the pattern is still matching the start and we haven't passed the buffer
|
|
4308
4323
|
if(!pParserState.StartPatternMatchComplete&&pCharacter in pParserState.Pattern){pParserState.Pattern=pParserState.Pattern[pCharacter];this.appendOutputBuffer(pCharacter,pParserState);}else if(pParserState.EndPatternMatchBegan){if(pCharacter in pParserState.Pattern.PatternEnd){// This leaf has a PatternEnd tree, so we will wait until that end is met.
|
|
4309
4324
|
pParserState.Pattern=pParserState.Pattern.PatternEnd[pCharacter];// Flush the output buffer.
|
|
4310
4325
|
this.appendOutputBuffer(pCharacter,pParserState);// If this last character is the end of the pattern, parse it.
|
|
4311
|
-
if('Parse'in pParserState.Pattern){return this.executePatternAsync(pParserState,pData,fCallback,pDataContext,pScope);}}else if(pCharacter in pParserState.PatternStartNode.PatternEnd){// We broke out of the end -- see if this is a new start of the end.
|
|
4326
|
+
if('Parse'in pParserState.Pattern){return this.executePatternAsync(pParserState,pData,fCallback,pDataContext,pScope,pState);}}else if(pCharacter in pParserState.PatternStartNode.PatternEnd){// We broke out of the end -- see if this is a new start of the end.
|
|
4312
4327
|
pParserState.Pattern=pParserState.PatternStartNode.PatternEnd[pCharacter];this.appendOutputBuffer(pCharacter,pParserState);}else{pParserState.EndPatternMatchBegan=false;this.appendOutputBuffer(pCharacter,pParserState);}}else if('PatternEnd'in pParserState.Pattern){if(!pParserState.StartPatternMatchComplete){pParserState.StartPatternMatchComplete=true;pParserState.PatternStartNode=pParserState.Pattern;}this.appendOutputBuffer(pCharacter,pParserState);if(pCharacter in pParserState.Pattern.PatternEnd){// This is the first character of the end pattern.
|
|
4313
4328
|
pParserState.EndPatternMatchBegan=true;// This leaf has a PatternEnd tree, so we will wait until that end is met.
|
|
4314
4329
|
pParserState.Pattern=pParserState.Pattern.PatternEnd[pCharacter];// If this last character is the end of the pattern, parse it.
|
|
4315
|
-
if('Parse'in pParserState.Pattern){return this.executePatternAsync(pParserState,pData,fCallback,pDataContext,pScope);}}}else{// We are in a pattern start but didn't match one; reset and start trying again from this character.
|
|
4330
|
+
if('Parse'in pParserState.Pattern){return this.executePatternAsync(pParserState,pData,fCallback,pDataContext,pScope,pState);}}}else{// We are in a pattern start but didn't match one; reset and start trying again from this character.
|
|
4316
4331
|
this.resetOutputBuffer(pParserState);}}// If we aren't in a pattern match or pattern, and this isn't the start of a new pattern (RAW mode)....
|
|
4317
4332
|
else{// This may be the start of a new pattern....
|
|
4318
4333
|
if(pCharacter in pParserState.ParseTree){// ... assign the root node as the matched node.
|
|
@@ -4327,10 +4342,11 @@ return fCallback();}/**
|
|
|
4327
4342
|
* @param {function} fCallback - The callback function to call when the parse is complete
|
|
4328
4343
|
* @param {array} pDataContext - The history of data objects/context already passed in
|
|
4329
4344
|
* @param {any} [pScope] - A sticky scope that can be used to carry state and simplify template
|
|
4330
|
-
|
|
4345
|
+
* @param {any} [pState] - A catchall state object for plumbing data through template processing.
|
|
4346
|
+
*/parseString(pString,pParseTree,pData,fCallback,pDataContext,pScope,pState){// TODO: There is danger here if a template function attempts to functionally recurse and doesn't pass this in.
|
|
4331
4347
|
let tmpPreviousDataContext=Array.isArray(pDataContext)?pDataContext:[];let tmpDataContext=Array.from(tmpPreviousDataContext);tmpDataContext.push(pData);if(typeof fCallback!=='function'){let tmpParserState=this.newParserState(pParseTree);for(var i=0;i<pString.length;i++){// TODO: This is not fast.
|
|
4332
|
-
this.parseCharacter(pString[i],tmpParserState,pData,tmpDataContext,pScope);}this.flushOutputBuffer(tmpParserState);return tmpParserState.Output;}else{// This is the async mode
|
|
4333
|
-
let tmpParserState=this.newParserState(pParseTree);tmpParserState.Asynchronous=true;let tmpAnticipate=this.fable.instantiateServiceProviderWithoutRegistration('Anticipate');for(let i=0;i<pString.length;i++){tmpAnticipate.anticipate(fCallback=>{this.parseCharacterAsync(pString[i],tmpParserState,pData,fCallback,tmpDataContext,pScope);});}tmpAnticipate.wait(pError=>{// Flush the remaining data
|
|
4348
|
+
this.parseCharacter(pString[i],tmpParserState,pData,tmpDataContext,pScope,pState);}this.flushOutputBuffer(tmpParserState);return tmpParserState.Output;}else{// This is the async mode
|
|
4349
|
+
let tmpParserState=this.newParserState(pParseTree);tmpParserState.Asynchronous=true;let tmpAnticipate=this.fable.instantiateServiceProviderWithoutRegistration('Anticipate');for(let i=0;i<pString.length;i++){tmpAnticipate.anticipate(fCallback=>{this.parseCharacterAsync(pString[i],tmpParserState,pData,fCallback,tmpDataContext,pScope,pState);});}tmpAnticipate.wait(pError=>{// Flush the remaining data
|
|
4334
4350
|
this.flushOutputBuffer(tmpParserState);return fCallback(pError,tmpParserState.Output);});}}}module.exports=StringParser;},{}],173:[function(require,module,exports){/**
|
|
4335
4351
|
* Word Tree
|
|
4336
4352
|
* @author Steven Velozo <steven@velozo.com>
|