diff --git a/builder/parameter_hunter.js b/builder/parameter_hunter.js index a3f574951..da08eee92 100644 --- a/builder/parameter_hunter.js +++ b/builder/parameter_hunter.js @@ -20,6 +20,93 @@ style_modifier_hunter = new smh(), pattern_assembler = new pa(); + function paramToJson(paramString) { + var paramStringWellFormed = ''; + var paramStringTmp; + var colonPos; + var delimitPos; + var quotePos; + + do { + //if param key is wrapped in single quotes, replace with double quotes. + paramString = paramString.replace(/(^\s*[\{|\,]\s*)'([^']+)'(\s*\:)/, '$1"$2"$3'); + //if params key is not wrapped in any quotes, wrap in double quotes. + paramString = paramString.replace(/(^\s*[\{|\,]\s*)([^\s"'\:]+)(\s*\:)/, '$1"$2"$3'); + //move param key to paramStringWellFormed var. + colonPos = paramString.indexOf(':'); + //except to prevent infinite loops. + if (colonPos === -1) { + colonPos = paramString.length - 1; + } + else { + colonPos += 1; + } + paramStringWellFormed += paramString.substring(0, colonPos); + paramString = paramString.substring(colonPos, paramString.length).trim(); + + //if param value is wrapped in single quotes, replace with double quotes. + if (paramString[0] === '\'') { + quotePos = paramString.search(/[^\\]'/); + //except for unclosed quotes to prevent infinite loops. + if (quotePos === -1) { + quotePos = paramString.length - 1; + } + else { + quotePos += 2; + } + //prepare param value for move to paramStringWellFormed var. + paramStringTmp = paramString.substring(0, quotePos); + //unescape any escaped single quotes. + paramStringTmp = paramStringTmp.replace(/\\'/g, '\''); + //escape any double quotes. + paramStringTmp = paramStringTmp.replace(/"/g, '\\"'); + //replace the delimiting single quotes with double quotes. + paramStringTmp = paramStringTmp.replace(/^'/, '"'); + paramStringTmp = paramStringTmp.replace(/'$/, '"'); + //move param key to paramStringWellFormed var. + paramStringWellFormed += paramStringTmp; + paramString = paramString.substring(quotePos, paramString.length).trim(); + } + //if param value is wrapped in double quotes, just move to paramStringWellFormed var. + else if (paramString[0] === '"') { + quotePos = paramString.search(/[^\\]"/); + //except for unclosed quotes to prevent infinite loops. + if (quotePos === -1) { + quotePos = paramString.length - 1; + } + else { + quotePos += 2; + } + //move param key to paramStringWellFormed var. + paramStringWellFormed += paramString.substring(0, quotePos); + paramString = paramString.substring(quotePos, paramString.length).trim(); + } + //if param value is not wrapped in quotes, move everthing up to the delimiting comma to paramStringWellFormed var. + else { + delimitPos = paramString.indexOf(','); + //except to prevent infinite loops. + if (delimitPos === -1) { + delimitPos = paramString.length - 1; + } + else { + delimitPos += 1; + } + paramStringWellFormed += paramString.substring(0, delimitPos); + paramString = paramString.substring(delimitPos, paramString.length).trim(); + } + + //break at the end. + if (paramString.length === 1) { + paramStringWellFormed += paramString.trim(); + paramString = ''; + break; + } + + } while(paramString); + + return paramStringWellFormed; + } + function findparameters(pattern, patternlab){ if(pattern.parameteredPartials && pattern.parameteredPartials.length > 0){ @@ -39,12 +126,7 @@ var leftParen = pMatch.indexOf('('); var rightParen = pMatch.indexOf(')'); var paramString = '{' + pMatch.substring(leftParen + 1, rightParen) + '}'; - //if param keys are wrapped in single quotes, replace with double quotes. - var paramStringWellFormed = paramString.replace(/(')([^']+)(')(\s*\:)/g, '"$2"$4'); - //if params keys are not wrapped in any quotes, wrap in double quotes. - var paramStringWellFormed = paramStringWellFormed.replace(/([\{|,]\s*)([^\s"'\:]+)(\s*\:)/g, '$1"$2"$3'); - //if param values are wrapped in single quotes, replace with double quotes. - var paramStringWellFormed = paramStringWellFormed.replace(/(\:\s*)(')([^']+)(')/g, '$1"$3"'); + var paramStringWellFormed = paramToJson(paramString); var paramData = {}; var globalData = {}; diff --git a/test/parameter_hunter_tests.js b/test/parameter_hunter_tests.js index 069986553..3672a4a79 100644 --- a/test/parameter_hunter_tests.js +++ b/test/parameter_hunter_tests.js @@ -158,32 +158,32 @@ test.done(); }, - 'parameter hunter parses parameters with single-quoted keys and single-quoted values' : function(test){ + 'parameter hunter parses parameters with single-quoted keys and single-quoted values wrapping internal escaped single-quotes' : function(test){ var currentPattern = currentPatternClosure(); var patternlab = patternlabClosure(); var parameter_hunter = new ph(); - currentPattern.template = "{{> molecules-single-comment('description': 'true') }}"; + currentPattern.template = "{{> molecules-single-comment('description': 'true not,\\'true\\'') }}"; currentPattern.extendedTemplate = currentPattern.template; currentPattern.parameteredPartials[0] = currentPattern.template; parameter_hunter.find_parameters(currentPattern, patternlab); - test.equals(currentPattern.extendedTemplate, '

true

'); + test.equals(currentPattern.extendedTemplate, '

true not,'true'

'); test.done(); }, - 'parameter hunter parses parameters with single-quoted keys and double-quoted values' : function(test){ + 'parameter hunter parses parameters with single-quoted keys and double-quoted values wrapping internal single-quotes' : function(test){ var currentPattern = currentPatternClosure(); var patternlab = patternlabClosure(); var parameter_hunter = new ph(); - currentPattern.template = "{{> molecules-single-comment('description': \"true\") }}"; + currentPattern.template = "{{> molecules-single-comment('description': \"true not:'true'\") }}"; currentPattern.extendedTemplate = currentPattern.template; currentPattern.parameteredPartials[0] = currentPattern.template; parameter_hunter.find_parameters(currentPattern, patternlab); - test.equals(currentPattern.extendedTemplate, '

true

'); + test.equals(currentPattern.extendedTemplate, '

true not:'true'

'); test.done(); }, @@ -203,32 +203,32 @@ test.done(); }, - 'parameter hunter parses parameters with double-quoted keys and single-quoted values' : function(test){ + 'parameter hunter parses parameters with double-quoted keys and single-quoted values wrapping internal double-quotes' : function(test){ var currentPattern = currentPatternClosure(); var patternlab = patternlabClosure(); var parameter_hunter = new ph(); - currentPattern.template = "{{> molecules-single-comment(\"description\": 'true') }}"; + currentPattern.template = "{{> molecules-single-comment(\"description\": 'true not{\"true\"') }}"; currentPattern.extendedTemplate = currentPattern.template; currentPattern.parameteredPartials[0] = currentPattern.template; parameter_hunter.find_parameters(currentPattern, patternlab); - test.equals(currentPattern.extendedTemplate, '

true

'); + test.equals(currentPattern.extendedTemplate, '

true not{"true"

'); test.done(); }, - 'parameter hunter parses parameters with double-quoted keys and double-quoted values' : function(test){ + 'parameter hunter parses parameters with double-quoted keys and double-quoted values wrapping internal escaped double-quotes' : function(test){ var currentPattern = currentPatternClosure(); var patternlab = patternlabClosure(); var parameter_hunter = new ph(); - currentPattern.template = "{{> molecules-single-comment(\"description\": \"true\") }}"; + currentPattern.template = "{{> molecules-single-comment(\"description\": \"true not}\\\"true\\\"\") }}"; currentPattern.extendedTemplate = currentPattern.template; currentPattern.parameteredPartials[0] = currentPattern.template; parameter_hunter.find_parameters(currentPattern, patternlab); - test.equals(currentPattern.extendedTemplate, '

true

'); + test.equals(currentPattern.extendedTemplate, '

true not}"true"

'); test.done(); }