aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--__tests__/index.js19
-rw-r--r--dist/index.js103
-rw-r--r--src/index.js4
3 files changed, 77 insertions, 49 deletions
diff --git a/__tests__/index.js b/__tests__/index.js
index d74c4f0..2df7717 100644
--- a/__tests__/index.js
+++ b/__tests__/index.js
@@ -217,7 +217,7 @@ test('value in quote', t => {
});
test('value in single quote', t => {
- const toParse = `key='value'`;
+ const toParse = 'key=\'value\'';
const r = parse(toParse);
t.is(r.prop.key, 'value');
t.is(r.eaten, toParse);
@@ -275,14 +275,14 @@ test('class with spaces', t => {
});
test('class with spaces2', t => {
- const toParse = `{.class='Hello ! }`;
+ const toParse = '{.class=\'Hello ! }';
const r = parse(toParse);
t.is(r.prop.class, undefined);
t.is(r.eaten, '');
});
test('class with spaces3', t => {
- const toParse = `{ .'Hello !'}`;
+ const toParse = '{ .\'Hello !\'}';
const r = parse(toParse);
t.deepEqual(r.prop.class, ['\'Hello']);
t.is('!\'' in r.prop, true);
@@ -426,7 +426,12 @@ test('quoted key', t => {
t.is(r.prop['"key"'], 'value');
t.is(r.eaten, toParse);
});
-
+test('dashed key', t => {
+ const toParse = '{eg-key=value}';
+ const r = parse(toParse);
+ t.is(r.prop['eg-key'], 'value');
+ t.is(r.eaten, toParse);
+});
test('quoted class', t => {
const toParse = '{."key"}';
const r = parse(toParse);
@@ -484,7 +489,7 @@ test('cariage-return in quoted value (brace version)', t => {
});
test('brace in quoted value', t => {
- const toParse = `onclic="function() { return \\"Yeah !\\"; }"`;
+ const toParse = 'onclic="function() { return \\"Yeah !\\"; }"';
const r = parse(toParse);
t.is(r.prop.onclic, 'function() { return "Yeah !"; }');
t.is(r.eaten, toParse);
@@ -547,14 +552,14 @@ test('defaultValue name', t => {
});
test('braces in attr', t => {
- const toParse = `{ data-json='{"a": 1, "b": 2}' }`;
+ const toParse = '{ data-json=\'{"a": 1, "b": 2}\' }';
const r = parse(toParse);
t.is(r.prop['data-json'], '{"a": 1, "b": 2}');
t.is(r.eaten, toParse);
});
test('nested braces in attr', t => {
- const toParse = `{ data-json='{"a": 1, "b": { "c": 4 }}' }`;
+ const toParse = '{ data-json=\'{"a": 1, "b": { "c": 4 }}\' }';
const r = parse(toParse);
t.is(r.prop['data-json'], '{"a": 1, "b": { "c": 4 }}');
t.is(r.eaten, toParse);
diff --git a/dist/index.js b/dist/index.js
index f081bed..8ae7b4f 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -1,27 +1,29 @@
-'use strict';
-
-// A valid output which means nothing has been parsed.
+'use strict'; // A valid output which means nothing has been parsed.
// Used as error return / invalid output
+function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
+
+function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
+
var nothingHappend = {
prop: {},
eaten: ''
};
-
var defaultConfig = {
defaultValue: function defaultValue() {
return undefined;
} // Its a function
-};
-// Main function
+}; // Main function
+
function parse(value, indexNext, userConfig) {
var letsEat = '';
var stopOnBrace = false;
var errorDetected = false;
- var config = Object.assign({}, defaultConfig, userConfig);
- // Make defaultValue a function if it isn't
+ var config = _objectSpread({}, defaultConfig, userConfig); // Make defaultValue a function if it isn't
+
+
if (typeof config.defaultValue !== 'function') {
var defaultValue = config.defaultValue;
@@ -31,17 +33,17 @@ function parse(value, indexNext, userConfig) {
}
var prop = {};
-
/* They are at least one label and at best two */
+
/* ekqsdf <- one label
* qsdfqsfd=qsdfqsdf <- two */
+
var labelFirst = '';
- var labelSecond = void 0;
+ var labelSecond;
if (indexNext === undefined) {
indexNext = 0;
}
-
/* 3 types :
* .azcv <- class
* #poi <- id
@@ -49,23 +51,26 @@ function parse(value, indexNext, userConfig) {
* jkj <- this is also a key but with a user defined value (default is undefined)
* jkj= <- this is also a key but with a empty value
*/
- var type = void 0;
- var forbidenCharacters = '\n\r{}';
- // A function that detect if it's time to end the parsing
+
+ var type;
+ var forbidenCharacters = '\n\r{}'; // A function that detect if it's time to end the parsing
+
var shouldStop = function shouldStop() {
if (indexNext >= value.length || forbidenCharacters.indexOf(value[indexNext]) > -1) {
if (stopOnBrace && value[indexNext] !== '}') {
errorDetected = true;
}
+
return true;
}
+
return value[indexNext] === '}' && stopOnBrace;
};
- var eaten = '';
- // Couple of functions that parse same kinds of characters
+ var eaten = ''; // Couple of functions that parse same kinds of characters
// Used to parse spaces or identifiers
+
var eat = function eat(chars) {
eaten = '';
@@ -77,6 +82,7 @@ function parse(value, indexNext, userConfig) {
return shouldStop();
};
+
var eatUntil = function eatUntil(chars) {
eaten = '';
@@ -84,10 +90,10 @@ function parse(value, indexNext, userConfig) {
letsEat += value.charAt(indexNext);
eaten += value.charAt(indexNext);
indexNext++;
- }
-
- // Ugly but keep the main loop readable
+ } // Ugly but keep the main loop readable
// Set the label it should set
+
+
if (labelFirst) {
labelSecond = eaten;
} else {
@@ -95,13 +101,13 @@ function parse(value, indexNext, userConfig) {
}
return shouldStop();
- };
-
- // In quote, every character is valid except the unescaped quotes and CR or LF
+ }; // In quote, every character is valid except the unescaped quotes and CR or LF
// Same function for single and double quote
+
+
var eatInQuote = function eatInQuote(quote) {
- eaten = '';
- // First check so value[indexNext-1] will always be valid
+ eaten = ''; // First check so value[indexNext-1] will always be valid
+
if (value[indexNext] === quote) {
return;
}
@@ -110,15 +116,16 @@ function parse(value, indexNext, userConfig) {
letsEat += value.charAt(indexNext);
eaten += value.charAt(indexNext);
indexNext++;
- }
- // If we encounter an EOL, there is an error
+ } // If we encounter an EOL, there is an error
// We are waiting for a quote
+
+
if (value[indexNext] === '\n' || value[indexNext] === '\r' || indexNext >= value.length) {
errorDetected = true;
return true;
- }
+ } // Ugly but keep the main loop readable
+
- // Ugly but keep the main loop readable
if (labelFirst) {
labelSecond = eaten.replace(/\\"/g, '"');
} else {
@@ -126,18 +133,17 @@ function parse(value, indexNext, userConfig) {
}
return shouldStop();
- };
+ }; // It's really common to eat only one character so let's make it a function
+
- // It's really common to eat only one character so let's make it a function
var eatOne = function eatOne(c, skipStopCheck) {
// Miam !
letsEat += c;
indexNext++;
-
return skipStopCheck ? false : shouldStop();
- };
+ }; // Common parsing of quotes
+
- // Common parsing of quotes
var eatQuote = function eatQuote(q) {
eatOne(q, true);
eatInQuote(q, true);
@@ -145,6 +151,7 @@ function parse(value, indexNext, userConfig) {
if (value.charAt(indexNext) !== q) {
return nothingHappend;
}
+
if (eatOne(q)) {
return -1;
}
@@ -156,6 +163,7 @@ function parse(value, indexNext, userConfig) {
// ID
prop.id = prop.id || labelFirst;
break;
+
case 'class':
if (!prop.class) {
prop.class = [];
@@ -166,10 +174,12 @@ function parse(value, indexNext, userConfig) {
}
break;
+
case 'key':
if (!labelFirst) {
return nothingHappend;
}
+
if (!(labelFirst in prop)) {
if (labelSecond === undefined) {
// Here, we have an attribute without value
@@ -179,17 +189,20 @@ function parse(value, indexNext, userConfig) {
prop[labelFirst] = labelFirst === 'class' ? [labelSecond] : labelSecond;
}
}
+
break;
+
default:
}
+
type = undefined;
labelFirst = '';
labelSecond = undefined;
};
-
/** *********************** Start parsing ************************ */
-
// Let's check for leading spaces first
+
+
eat(' \t\v');
if (value[indexNext] === '{') {
@@ -206,6 +219,7 @@ function parse(value, indexNext, userConfig) {
if (value.charAt(indexNext) === '.') {
// Classes
type = 'class';
+
if (eatOne('.')) {
errorDetected = true;
break;
@@ -213,6 +227,7 @@ function parse(value, indexNext, userConfig) {
} else if (value.charAt(indexNext) === '#') {
// ID
type = 'id';
+
if (eatOne('#')) {
errorDetected = true;
break;
@@ -220,12 +235,13 @@ function parse(value, indexNext, userConfig) {
} else {
// Key
type = 'key';
- }
+ } // Extract name
+
- // Extract name
if (eatUntil('=\t\b\v  ') || !labelFirst) {
break;
}
+
if (value.charAt(indexNext) === '=' && type === 'key') {
// Set labelSecond
if (eatOne('=')) {
@@ -234,6 +250,7 @@ function parse(value, indexNext, userConfig) {
if (value.charAt(indexNext) === '"') {
var ret = eatQuote('"');
+
if (ret === -1) {
break;
} else if (ret === nothingHappend) {
@@ -241,6 +258,7 @@ function parse(value, indexNext, userConfig) {
}
} else if (value.charAt(indexNext) === '\'') {
var _ret = eatQuote('\'');
+
if (_ret === -1) {
break;
} else if (_ret === nothingHappend) {
@@ -249,12 +267,14 @@ function parse(value, indexNext, userConfig) {
} else if (eatUntil(' \t\n\r\v=}')) {
break;
}
- }
+ } // Add the parsed attribute to the output prop with the ad hoc type
+
- // Add the parsed attribute to the output prop with the ad hoc type
addAttribute();
}
+
addAttribute();
+
if (stopOnBrace) {
if (indexNext < value.length && value[indexNext] === '}') {
stopOnBrace = false;
@@ -264,7 +284,10 @@ function parse(value, indexNext, userConfig) {
}
}
- return errorDetected ? nothingHappend : { prop: prop, eaten: letsEat };
+ return errorDetected ? nothingHappend : {
+ prop: prop,
+ eaten: letsEat
+ };
}
module.exports = parse; \ No newline at end of file
diff --git a/src/index.js b/src/index.js
index 8af6fff..fc7a02a 100644
--- a/src/index.js
+++ b/src/index.js
@@ -232,8 +232,8 @@ function parse(value, indexNext, userConfig) {
} else if (ret === nothingHappend) {
return nothingHappend;
}
- } else if (value.charAt(indexNext) === `'`) {
- const ret = eatQuote(`'`);
+ } else if (value.charAt(indexNext) === '\'') {
+ const ret = eatQuote('\'');
if (ret === -1) {
break;
} else if (ret === nothingHappend) {