From 65f536284bfd36b17a9e4384955314a3a35d7858 Mon Sep 17 00:00:00 2001 From: UpperCod Date: Mon, 18 Oct 2021 21:11:44 -0300 Subject: [PATCH] fix getSizes capture --- package.json | 2 +- src/use-responsive-state/src/string-escape.js | 36 +++++++++++++ .../use-responsive-state.js | 51 ++++++++++++------- 3 files changed, 71 insertions(+), 18 deletions(-) create mode 100644 src/use-responsive-state/src/string-escape.js diff --git a/package.json b/package.json index 0354345..886290b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@atomico/hooks", "description": "Series of utilities in hooks format to extend the operation of Atomico", - "version": "3.19.0", + "version": "3.19.1", "type": "module", "workspaces": [ "src/**/*" diff --git a/src/use-responsive-state/src/string-escape.js b/src/use-responsive-state/src/string-escape.js new file mode 100644 index 0000000..b7df9cb --- /dev/null +++ b/src/use-responsive-state/src/string-escape.js @@ -0,0 +1,36 @@ +export class StringEscape extends String { + constructor(string, hash) { + super(string); + this.hash = hash; + } + explode(part) { + return this.split(part).map((part) => { + while (true) { + let nextPart = part.replace(/(-([\d\.]+)-)/, (param1, param2, id) => + id in this.hash ? this.hash[id] : param1 + ); + if (nextPart == part) break; + part = nextPart; + } + return part; + }); + } +} + +export function escape(string, escape) { + const hash = string instanceof StringEscape ? string.hash : {}; + + let count = Object.keys(hash).length; + + while (true) { + const nextString = string.replace(escape, (part) => { + let nextId = id + count++; + hash[nextId] = part; + return `-${nextId}-`; + }); + if (nextString == string) break; + string = nextString; + } + + return new StringEscape(string, hash); +} diff --git a/src/use-responsive-state/use-responsive-state.js b/src/use-responsive-state/use-responsive-state.js index 7269a06..470e7e4 100644 --- a/src/use-responsive-state/use-responsive-state.js +++ b/src/use-responsive-state/use-responsive-state.js @@ -1,6 +1,13 @@ import { useEffect, useState } from "atomico"; +import { escape } from "./src/string-escape"; -export const matchSize = /,\s*([^,]+)\s+(?:(\d+)(?:x(\d+)){0,1}(px|em|rem))/; +export const escapes = [ + /(\([^()]+\))/, + /(\{[^{}]+\})/, + /(\[[^[]]+\])/, + /('[^']+'])/, + /("[^"]+"])/, +]; /** * @type {Object} @@ -59,26 +66,36 @@ export const getQuery = ({ width, height, type }) => { */ export function getSizes(sizes) { if (cacheSize[sizes]) return cacheSize[sizes]; - const values = []; - let test; - while ((test = sizes.match(matchSize))) { - const [replace, value, width, height, type] = test; - sizes = sizes.replace(replace, ""); + let value = escapes.reduce((sizes, regExp) => escape(sizes, regExp), sizes); - values.push({ - value, - width: Number(width), - height: Number(height || ""), - type, - }); - } - return [ - sizes.replace(/\s*,(.*)/, "").trim(), - values + const [defaultValue, query] = value.explode(",").reduce( + ([defaultValue, query], part) => { + const test = part + .trim() + .match(/(.+)\s+([\d\.]+)(?:x([\d\.]+)){0,1}(px|rem|em)$/); + if (test) { + const [, value, width, height, type] = test; + return [ + defaultValue, + [ + ...query, + { value, width: Number(width), height: Number(height || ""), type }, + ], + ]; + } else { + return [part, query]; + } + }, + ["", []] + ); + + return (cacheSize[sizes] = [ + defaultValue, + query .sort((a, b) => (a.height > b.height ? -1 : 1)) .sort((a, b) => (a.width > b.width ? -1 : a.width == b.height ? 0 : 1)), - ]; + ]); } /**