Skip to content
Snippets Groups Projects
Verified Commit 7550446c authored by Volker Schukai's avatar Volker Schukai :alien:
Browse files

fix: no hash if keyValue is empty

parent 131c594e
No related branches found
No related tags found
No related merge requests found
......@@ -12,7 +12,7 @@
* SPDX-License-Identifier: AGPL-3.0
*/
export { parseBracketedKeyValueHash, createBracketedKeyValueHash };
export {parseBracketedKeyValueHash, createBracketedKeyValueHash};
/**
* Parses a string containing bracketed key-value pairs and returns an object representing the parsed result.
......@@ -51,155 +51,155 @@ export { parseBracketedKeyValueHash, createBracketedKeyValueHash };
* @return {Object} - An object representing the parsed result, with keys representing the selectors and values representing the key-value pairs associated with each selector.
* - Returns an empty object if there was an error during parsing. */
function parseBracketedKeyValueHash(hashString) {
const selectors = {};
//const selectorStack = [];
//const keyValueStack = [];
const trimmedHashString = hashString.trim();
const cleanedHashString =
trimmedHashString.charAt(0) === "#"
? trimmedHashString.slice(1)
: trimmedHashString;
//const selectors = (keyValueStack.length > 0) ? result[selectorStack[selectorStack.length - 1]] : result;
let currentSelector = "";
function addToResult(key, value) {
if (currentSelector && key) {
if (!selectors[currentSelector]) {
selectors[currentSelector] = {};
}
selectors[currentSelector][key] = value;
}
}
let currentKey = "";
let currentValue = "";
let inKey = true;
let inValue = false;
let inQuotedValue = false;
let inSelector = true;
let escaped = false;
let quotedValueStartChar = "";
for (let i = 0; i < cleanedHashString.length; i++) {
const c = cleanedHashString[i];
const nextChar = cleanedHashString?.[i + 1];
if (c === "\\" && !escaped) {
escaped = true;
continue;
}
if (escaped) {
if (inSelector) {
currentSelector += c;
} else if (inKey) {
currentKey += c;
} else if (inValue) {
currentValue += c;
}
escaped = false;
continue;
}
if (inQuotedValue && quotedValueStartChar !== c) {
if (inSelector) {
currentSelector += c;
} else if (inKey) {
currentKey += c;
} else if (inValue) {
currentValue += c;
}
continue;
}
if (c === ";" && inSelector) {
inSelector = true;
currentSelector = "";
continue;
}
if (inSelector === true && c !== "(") {
currentSelector += c;
continue;
}
if (c === "(" && inSelector) {
inSelector = false;
inKey = true;
currentKey = "";
continue;
}
if (inKey === true && c !== "=") {
currentKey += c;
continue;
}
if (c === "=" && inKey) {
inKey = false;
inValue = true;
if (nextChar === '"' || nextChar === "'") {
inQuotedValue = true;
quotedValueStartChar = nextChar;
i++;
continue;
}
currentValue = "";
continue;
}
if (inValue === true) {
if (inQuotedValue) {
if (c === quotedValueStartChar) {
inQuotedValue = false;
continue;
}
currentValue += c;
continue;
}
if (c === ",") {
inValue = false;
inKey = true;
const decodedCurrentValue = decodeURIComponent(currentValue);
addToResult(currentKey, decodedCurrentValue);
currentKey = "";
currentValue = "";
continue;
}
if (c === ")") {
inValue = false;
//inKey = true;
inSelector = true;
const decodedCurrentValue = decodeURIComponent(currentValue);
addToResult(currentKey, decodedCurrentValue);
currentKey = "";
currentValue = "";
currentSelector = "";
continue;
}
currentValue += c;
continue;
}
}
if (inSelector) {
return selectors;
}
return {};
const selectors = {};
//const selectorStack = [];
//const keyValueStack = [];
const trimmedHashString = hashString.trim();
const cleanedHashString =
trimmedHashString.charAt(0) === "#"
? trimmedHashString.slice(1)
: trimmedHashString;
//const selectors = (keyValueStack.length > 0) ? result[selectorStack[selectorStack.length - 1]] : result;
let currentSelector = "";
function addToResult(key, value) {
if (currentSelector && key) {
if (!selectors[currentSelector]) {
selectors[currentSelector] = {};
}
selectors[currentSelector][key] = value;
}
}
let currentKey = "";
let currentValue = "";
let inKey = true;
let inValue = false;
let inQuotedValue = false;
let inSelector = true;
let escaped = false;
let quotedValueStartChar = "";
for (let i = 0; i < cleanedHashString.length; i++) {
const c = cleanedHashString[i];
const nextChar = cleanedHashString?.[i + 1];
if (c === "\\" && !escaped) {
escaped = true;
continue;
}
if (escaped) {
if (inSelector) {
currentSelector += c;
} else if (inKey) {
currentKey += c;
} else if (inValue) {
currentValue += c;
}
escaped = false;
continue;
}
if (inQuotedValue && quotedValueStartChar !== c) {
if (inSelector) {
currentSelector += c;
} else if (inKey) {
currentKey += c;
} else if (inValue) {
currentValue += c;
}
continue;
}
if (c === ";" && inSelector) {
inSelector = true;
currentSelector = "";
continue;
}
if (inSelector === true && c !== "(") {
currentSelector += c;
continue;
}
if (c === "(" && inSelector) {
inSelector = false;
inKey = true;
currentKey = "";
continue;
}
if (inKey === true && c !== "=") {
currentKey += c;
continue;
}
if (c === "=" && inKey) {
inKey = false;
inValue = true;
if (nextChar === '"' || nextChar === "'") {
inQuotedValue = true;
quotedValueStartChar = nextChar;
i++;
continue;
}
currentValue = "";
continue;
}
if (inValue === true) {
if (inQuotedValue) {
if (c === quotedValueStartChar) {
inQuotedValue = false;
continue;
}
currentValue += c;
continue;
}
if (c === ",") {
inValue = false;
inKey = true;
const decodedCurrentValue = decodeURIComponent(currentValue);
addToResult(currentKey, decodedCurrentValue);
currentKey = "";
currentValue = "";
continue;
}
if (c === ")") {
inValue = false;
//inKey = true;
inSelector = true;
const decodedCurrentValue = decodeURIComponent(currentValue);
addToResult(currentKey, decodedCurrentValue);
currentKey = "";
currentValue = "";
currentSelector = "";
continue;
}
currentValue += c;
continue;
}
}
if (inSelector) {
return selectors;
}
return {};
}
/**
......@@ -211,37 +211,41 @@ function parseBracketedKeyValueHash(hashString) {
* @since 3.37.0
*/
function createBracketedKeyValueHash(object, addHashPrefix = true) {
if (!object) {
return addHashPrefix ? "#" : "";
}
let hashString = "";
function encodeKeyValue(key, value) {
return encodeURIComponent(key) + "=" + encodeURIComponent(value);
}
for (const selector in object) {
if (object.hasOwnProperty(selector)) {
const keyValuePairs = object[selector];
let selectorString = selector;
let keyValueString = "";
for (const key in keyValuePairs) {
if (keyValuePairs.hasOwnProperty(key)) {
const value = keyValuePairs[key];
keyValueString += keyValueString.length === 0 ? "" : ",";
keyValueString += encodeKeyValue(key, value);
}
}
if (keyValueString.length > 0) {
selectorString += "(" + keyValueString + ")";
hashString += hashString.length === 0 ? "" : ";";
hashString += selectorString;
}
}
}
return addHashPrefix ? "#" + hashString : hashString;
if (!object) {
return addHashPrefix ? "#" : "";
}
let hashString = "";
function encodeKeyValue(key, value) {
return encodeURIComponent(key) + "=" + encodeURIComponent(value);
}
for (const selector in object) {
if (object.hasOwnProperty(selector)) {
const keyValuePairs = object[selector];
let selectorString = selector;
let keyValueString = "";
for (const key in keyValuePairs) {
if (keyValuePairs.hasOwnProperty(key)) {
const value = keyValuePairs[key];
keyValueString += keyValueString.length === 0 ? "" : ",";
keyValueString += encodeKeyValue(key, value);
}
}
if (keyValueString.length > 0) {
selectorString += "(" + keyValueString + ")";
hashString += hashString.length === 0 ? "" : ";";
hashString += selectorString;
}
}
}
if (hashString.length === 0) {
hashString = "#" + hashString;
}
return addHashPrefix ? hashString : hashString;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment