From bd90f08065958369f1b0faa35a6c870a7dd214c8 Mon Sep 17 00:00:00 2001 From: Christopher Pickering Date: Fri, 28 Oct 2022 14:00:14 +0200 Subject: [PATCH 1/7] fix(attributes): fixed poor django attribute parsing Allow multiple attribute styles inside a quoted value. Split the attribute name into a group to help resolve #427 closes #438 --- src/djlint/formatter/attributes.py | 7 +++- src/djlint/formatter/indent.py | 1 + src/djlint/settings.py | 57 +++++++++++++++++++++--------- 3 files changed, 48 insertions(+), 17 deletions(-) diff --git a/src/djlint/formatter/attributes.py b/src/djlint/formatter/attributes.py index 596ed28..4152670 100644 --- a/src/djlint/formatter/attributes.py +++ b/src/djlint/formatter/attributes.py @@ -258,7 +258,12 @@ def format_attributes(config: Config, html: str, match: re.match) -> str: # format attributes as groups attributes = (spacing).join( - re.findall(config.attribute_pattern, match.group(3).strip(), re.VERBOSE) + [ + x.group() + for x in re.finditer( + config.attribute_pattern, match.group(3).strip(), re.VERBOSE + ) + ] ) close = match.group(4) diff --git a/src/djlint/formatter/indent.py b/src/djlint/formatter/indent.py index 80e16c2..db2ae88 100644 --- a/src/djlint/formatter/indent.py +++ b/src/djlint/formatter/indent.py @@ -197,6 +197,7 @@ def indent_html(rawcode: str, config: Config) -> str: # if a normal tag, we can try to expand attributes elif is_block_raw is False: # get leading space, and attributes + func = partial(format_attributes, config, item) tmp = re.sub( diff --git a/src/djlint/settings.py b/src/djlint/settings.py index cf43b63..17660be 100644 --- a/src/djlint/settings.py +++ b/src/djlint/settings.py @@ -510,29 +510,54 @@ class Config: self.template_if_for_pattern = ( r"(?:{%-?\s?(?:if|for)[^}]*?%}(?:.*?{%\s?end(?:if|for)[^}]*?-?%})+?)" ) + self.attribute_pattern: str = ( - r""" - (?:[^\s]+?[ ]*?=[ ]*?(?:\"[^\"]*?""" - + self.template_if_for_pattern - + r"""[^\"]*?\"|\'[^\']*?""" - + self.template_if_for_pattern - + r"""[^\']*?\')) - | (?:[^\s]+?[ ]*?=[ ]*?(?:\"[^\"]*?{{.*?}}[^\"]*?\"|\'[^\']*?{{.*?}}[^\']*?\')) - | """ - + self.template_if_for_pattern + rf""" + (?: + (?: + (?:\w|-|\.)+ | required | checked + ) # attribute name + (?: [ ]*?=[ ]*? # followed by "=" + (?: + \"[^\"]*? # double quoted attribute + (?: + {self.template_if_for_pattern} # if or for loop + | {{{{.*?}}}} # template stuff + | {{%[^}}]*?%}} + | [^\"] # anything else + )*? + \" # closing quote + | '[^']*? # single quoted attribute + (?: + {self.template_if_for_pattern} # if or for loop + | {{{{.*?}}}} # template stuff + | {{%[^}}]*?%}} + | [^'] # anything else + )*? + \' # closing quote + | (?:\w|-)+ # or a non-quoted value + + ) + )? # attribute value + ) + | {self.template_if_for_pattern} + """ + r""" - | (?:[^\s]+?[ ]*?=[ ]*?(?:\"(?:[^\"]*?{%[^}]*?%}[^\"]*?)+?\")) - | (?:[^\s]+?[ ]*?=[ ]*?(?:\'(?:[^\']*?{%[^}]*?%}[^\']*?)+?\')) - | (?:[^\s]+?[ ]*?=[ ]*?(?:\".*?\"|\'.*?\')) - | required - | checked - | (?:\w|-|\.)+ - | (?:\w|-|\.)+[ ]*?=[ ]*?(?:\w|-)+ | {{.*?}} | {%.*?%} """ ) + # + r"""[^\"]*?\"|\'[^\']*?""" + # + self.template_if_for_pattern + # + r"""[^\']*?\')) + # | (?:[^\s]+?[ ]*?=[ ]*?(?:\"[^\"]*?{{.*?}}[^\"]*?\"|\'[^\']*?{{.*?}}[^\']*?\')) + # | """ + # + self.template_if_for_pattern + # + r""" + # | (?:[^\s]+?[ ]*?=[ ]*?(?:\"(?:[^\"]*?{%[^}]*?%}[^\"]*?)+?\")) + ## | (?:[^\s]+?[ ]*?=[ ]*?(?:\'(?:[^\']*?{%[^}]*?%}[^\']*?)+?\')) + # | (?:[^\s]+?[ ]*?=[ ]*?(?:\".*?\"|\'.*?\')) self.attribute_style_pattern: str = r"^(.*?)(style=)([\"|'])(([^\"']+?;)+?)\3" self.start_template_tags: str = ( From 19136329d7a7a40d1bd4a45314024884189f92b2 Mon Sep 17 00:00:00 2001 From: Christopher Pickering Date: Fri, 28 Oct 2022 14:08:37 +0200 Subject: [PATCH 2/7] removed extra comments --- src/djlint/settings.py | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/djlint/settings.py b/src/djlint/settings.py index 17660be..24b3864 100644 --- a/src/djlint/settings.py +++ b/src/djlint/settings.py @@ -498,15 +498,6 @@ class Config: + f"Error: Invalid pyproject.toml max_attribute_length value {djlint_settings['max_attribute_length']}" ) - # pattern used to find attributes in a tag - # order is important. - # 1. attributes="{% if %}with if or for statement{% endif %}" - # 2. attributes="{{ stuff in here }}" - # 3. {% if %}with if or for statement{% endif %} - # 4. attributes="normal html" - # 5. require | checked | otherword | other-word - # 6. {{ stuff }} - self.template_if_for_pattern = ( r"(?:{%-?\s?(?:if|for)[^}]*?%}(?:.*?{%\s?end(?:if|for)[^}]*?-?%})+?)" ) @@ -548,16 +539,6 @@ class Config: """ ) - # + r"""[^\"]*?\"|\'[^\']*?""" - # + self.template_if_for_pattern - # + r"""[^\']*?\')) - # | (?:[^\s]+?[ ]*?=[ ]*?(?:\"[^\"]*?{{.*?}}[^\"]*?\"|\'[^\']*?{{.*?}}[^\']*?\')) - # | """ - # + self.template_if_for_pattern - # + r""" - # | (?:[^\s]+?[ ]*?=[ ]*?(?:\"(?:[^\"]*?{%[^}]*?%}[^\"]*?)+?\")) - ## | (?:[^\s]+?[ ]*?=[ ]*?(?:\'(?:[^\']*?{%[^}]*?%}[^\']*?)+?\')) - # | (?:[^\s]+?[ ]*?=[ ]*?(?:\".*?\"|\'.*?\')) self.attribute_style_pattern: str = r"^(.*?)(style=)([\"|'])(([^\"']+?;)+?)\3" self.start_template_tags: str = ( From e2e17e6fdf939df5819371f9219d4c78acfa81a5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 31 Oct 2022 07:53:00 +0000 Subject: [PATCH 3/7] chore(deps) Update all non-major dependencies --- .pre-commit-config.yaml | 2 +- docs/package-lock.json | 34 +++++++++++++++++----------------- docs/package.json | 4 ++-- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7a819c5..4290156 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,7 +22,7 @@ repos: - --remove-duplicate-keys - --remove-unused-variables - repo: https://github.com/asottile/pyupgrade - rev: v3.1.0 + rev: v3.2.0 hooks: - id: pyupgrade args: [--py36-plus] diff --git a/docs/package-lock.json b/docs/package-lock.json index e5a478e..0e37c3e 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -1,12 +1,12 @@ { "name": "djlint_docs", - "version": "1.0.39", + "version": "1.0.40", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "djlint_docs", - "version": "1.0.39", + "version": "1.0.40", "license": "AGPL-3.0-or-later", "dependencies": { "@creativebulma/bulma-divider": "^1.1.0", @@ -29,7 +29,7 @@ "@fullhuman/postcss-purgecss": "5.0.0", "@toycode/markdown-it-class": "1.2.4", "algoliasearch": "4.14.2", - "autoprefixer": "10.4.12", + "autoprefixer": "10.4.13", "bulma": "0.9.4", "bulma-pricingtable": "0.2.0", "cssnano": "5.1.13", @@ -1591,9 +1591,9 @@ } }, "node_modules/autoprefixer": { - "version": "10.4.12", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.12.tgz", - "integrity": "sha512-WrCGV9/b97Pa+jtwf5UGaRjgQIg7OK3D06GnoYoZNcG1Xb8Gt3EfuKjlhh9i/VtT16g6PYjZ69jdJ2g8FxSC4Q==", + "version": "10.4.13", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz", + "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", "dev": true, "funding": [ { @@ -1607,7 +1607,7 @@ ], "dependencies": { "browserslist": "^4.21.4", - "caniuse-lite": "^1.0.30001407", + "caniuse-lite": "^1.0.30001426", "fraction.js": "^4.2.0", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", @@ -2037,9 +2037,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001412", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001412.tgz", - "integrity": "sha512-+TeEIee1gS5bYOiuf+PS/kp2mrXic37Hl66VY6EAfxasIk5fELTktK2oOezYed12H8w7jt3s512PpulQidPjwA==", + "version": "1.0.30001427", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001427.tgz", + "integrity": "sha512-lfXQ73oB9c8DP5Suxaszm+Ta2sr/4tf8+381GkIm1MLj/YdLf+rEDyDSRCzeltuyTVGm+/s18gdZ0q+Wmp8VsQ==", "dev": true, "funding": [ { @@ -12949,13 +12949,13 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" }, "autoprefixer": { - "version": "10.4.12", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.12.tgz", - "integrity": "sha512-WrCGV9/b97Pa+jtwf5UGaRjgQIg7OK3D06GnoYoZNcG1Xb8Gt3EfuKjlhh9i/VtT16g6PYjZ69jdJ2g8FxSC4Q==", + "version": "10.4.13", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz", + "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", "dev": true, "requires": { "browserslist": "^4.21.4", - "caniuse-lite": "^1.0.30001407", + "caniuse-lite": "^1.0.30001426", "fraction.js": "^4.2.0", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", @@ -13281,9 +13281,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001412", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001412.tgz", - "integrity": "sha512-+TeEIee1gS5bYOiuf+PS/kp2mrXic37Hl66VY6EAfxasIk5fELTktK2oOezYed12H8w7jt3s512PpulQidPjwA==", + "version": "1.0.30001427", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001427.tgz", + "integrity": "sha512-lfXQ73oB9c8DP5Suxaszm+Ta2sr/4tf8+381GkIm1MLj/YdLf+rEDyDSRCzeltuyTVGm+/s18gdZ0q+Wmp8VsQ==", "dev": true }, "chalk": { diff --git a/docs/package.json b/docs/package.json index 67a81e5..233ecc5 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "djlint_docs", - "version": "1.0.39", + "version": "1.0.40", "description": "", "main": "index.js", "scripts": { @@ -33,7 +33,7 @@ "@fullhuman/postcss-purgecss": "5.0.0", "@toycode/markdown-it-class": "1.2.4", "algoliasearch": "4.14.2", - "autoprefixer": "10.4.12", + "autoprefixer": "10.4.13", "bulma": "0.9.4", "bulma-pricingtable": "0.2.0", "cssnano": "5.1.13", From 9c52bea5c68cb9cb15058f232f44eff72e646ffe Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 31 Oct 2022 07:56:15 +0000 Subject: [PATCH 4/7] chore(deps) Update dependency pytest-xdist to v3 --- poetry.lock | 31 +++++++------------------------ pyproject.toml | 2 +- 2 files changed, 8 insertions(+), 25 deletions(-) diff --git a/poetry.lock b/poetry.lock index 5cee735..290438f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -27,7 +27,7 @@ python-versions = ">=3.5" dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"] docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"] -tests_no_zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] +tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] [[package]] name = "black" @@ -214,9 +214,9 @@ python-versions = ">=3.6.1,<4.0" [package.extras] colors = ["colorama (>=0.4.3,<0.5.0)"] -pipfile_deprecated_finder = ["pipreqs", "requirementslib"] +pipfile-deprecated-finder = ["pipreqs", "requirementslib"] plugins = ["setuptools"] -requirements_deprecated_finder = ["pip-api", "pipreqs"] +requirements-deprecated-finder = ["pip-api", "pipreqs"] [[package]] name = "jsbeautifier" @@ -424,21 +424,9 @@ pytest = ">=4.6" [package.extras] testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] -[[package]] -name = "pytest-forked" -version = "1.4.0" -description = "run tests in isolated forked subprocesses" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -py = "*" -pytest = ">=3.10" - [[package]] name = "pytest-xdist" -version = "2.5.0" +version = "3.0.2" description = "pytest xdist plugin for distributed testing and loop-on-failing modes" category = "dev" optional = false @@ -447,7 +435,6 @@ python-versions = ">=3.6" [package.dependencies] execnet = ">=1.1" pytest = ">=6.2.0" -pytest-forked = "*" [package.extras] psutil = ["psutil (>=3.0)"] @@ -599,7 +586,7 @@ testing = ["func-timeout", "jaraco.itertools", "pytest (>=6)", "pytest-black (>= [metadata] lock-version = "1.1" python-versions = "^3.7.2,<4.0" -content-hash = "8acf641390bd2011581bb8d839bba7f73694ed180b6563c64846df1a05dd2520" +content-hash = "1a3f8a5df6660569c1461b96778b240862569b520f5eba9324c33a8e9696ace9" [metadata.files] astroid = [ @@ -866,13 +853,9 @@ pytest-cov = [ {file = "pytest-cov-4.0.0.tar.gz", hash = "sha256:996b79efde6433cdbd0088872dbc5fb3ed7fe1578b68cdbba634f14bb8dd0470"}, {file = "pytest_cov-4.0.0-py3-none-any.whl", hash = "sha256:2feb1b751d66a8bd934e5edfa2e961d11309dc37b73b0eabe73b5945fee20f6b"}, ] -pytest-forked = [ - {file = "pytest-forked-1.4.0.tar.gz", hash = "sha256:8b67587c8f98cbbadfdd804539ed5455b6ed03802203485dd2f53c1422d7440e"}, - {file = "pytest_forked-1.4.0-py3-none-any.whl", hash = "sha256:bbbb6717efc886b9d64537b41fb1497cfaf3c9601276be8da2cccfea5a3c8ad8"}, -] pytest-xdist = [ - {file = "pytest-xdist-2.5.0.tar.gz", hash = "sha256:4580deca3ff04ddb2ac53eba39d76cb5dd5edeac050cb6fbc768b0dd712b4edf"}, - {file = "pytest_xdist-2.5.0-py3-none-any.whl", hash = "sha256:6fe5c74fec98906deb8f2d2b616b5c782022744978e7bd4695d39c8f42d0ce65"}, + {file = "pytest-xdist-3.0.2.tar.gz", hash = "sha256:688da9b814370e891ba5de650c9327d1a9d861721a524eb917e620eec3e90291"}, + {file = "pytest_xdist-3.0.2-py3-none-any.whl", hash = "sha256:9feb9a18e1790696ea23e1434fa73b325ed4998b0e9fcb221f16fd1945e6df1b"}, ] pyyaml = [ {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, diff --git a/pyproject.toml b/pyproject.toml index 8be3a8b..4e82e5e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,7 +46,7 @@ isort = "^5.9.3" coverage = "^6.4.2" pytest = "^7.1.2" pytest-cov = "^4.0.0" -pytest-xdist = "^2.5.0" +pytest-xdist = "^3.0.0" pylint = "^2.14.5" mypy = "^0.982" types-PyYAML = "^6.0.11" From 907a1bfb9cb533cf2315fca12a29bca2af8452a5 Mon Sep 17 00:00:00 2001 From: Christopher Pickering Date: Thu, 3 Nov 2022 11:15:35 +0100 Subject: [PATCH 5/7] fix(attributes): prevented attribute indentation for url type attributes Also fixed attribute quoting issues closes #320, closes #86, closes #195 --- src/djlint/formatter/attributes.py | 240 +++++------------- src/djlint/settings.py | 23 +- .../html-one.html | 11 +- tests/test_html/test_attributes.py | 23 +- 4 files changed, 107 insertions(+), 190 deletions(-) diff --git a/src/djlint/formatter/attributes.py b/src/djlint/formatter/attributes.py index 4152670..1a4f527 100644 --- a/src/djlint/formatter/attributes.py +++ b/src/djlint/formatter/attributes.py @@ -8,19 +8,13 @@ from ..helpers import inside_ignored_block from ..settings import Config -def format_template_tags(config: Config, attributes: str) -> str: +def format_template_tags(config: Config, attributes: str, spacing: int) -> str: """Format template tags in attributes.""" # find break tags, add breaks + indent # find unindent lines and move back # put short stuff back on one line - leading_space = "" - if re.search(r"^[ ]+", attributes.splitlines()[0], re.MULTILINE): - leading_space = re.search( - r"^[ ]+", attributes.splitlines()[0], re.MULTILINE - ).group() - - def add_indentation(config: Config, attributes: str) -> str: + def add_indentation(config: Config, attributes: str, spacing: int) -> str: """Indent template tags. |
str: | ^----^ base indent | """ - attr_name = ( - list( - re.finditer( - re.compile(r"^<\w+\b\s*", re.M), attributes.splitlines()[0].strip() - ) - ) - )[-1] - - start_test_list = list( - re.finditer( - re.compile( - r"^.*?(?=" + config.template_indent + r")", re.I | re.X | re.M - ), - attributes.splitlines()[0].strip(), - ) - ) + list( - re.finditer( - re.compile(r"^<\w+\b\s*[^\"']+?[\"']", re.M), - attributes.splitlines()[0].strip(), - ) - ) - - start_test = start_test_list[-1] if start_test_list else None - - base_indent = len(attr_name.group()) - indent = 0 indented = "" - indent_adder = 0 - - # if the "start test" open is actually closed, then ignore the indent. - if not re.findall( - re.compile(r"[\"']$", re.M), attributes.splitlines()[0].strip() - ): - indent_adder = len(start_test.group()) - base_indent if start_test else 0 + indent_adder = spacing or 0 for line_number, line in enumerate(attributes.splitlines()): + # when checking for template tag, use "match" to force start of line check. if re.match( re.compile(config.template_unindent, re.I | re.X), line.strip() ): - indent = indent - 1 tmp = (indent * config.indent) + (indent_adder * " ") + line.strip() - # if we are leaving an indented group, then remove the indent_adder elif re.match( re.compile(config.tag_unindent_line, re.I | re.X), line.strip() ): + # if we are leaving an indented group, then remove the indent_adder tmp = ( max(indent - 1, 0) * config.indent + indent_adder * " " + line.strip() ) - # for open tags, search, but then check that they are not closed. elif re.search( re.compile(config.template_indent, re.I | re.X), line.strip() ) and not re.search( re.compile(config.template_unindent, re.I | re.X), line.strip() ): + # for open tags, search, but then check that they are not closed. tmp = (indent * config.indent) + (indent_adder * " ") + line.strip() indent = indent + 1 @@ -102,97 +64,28 @@ def format_template_tags(config: Config, attributes: str) -> str: if line_number == 0: # don't touch first line - indented += f"{leading_space}{line.strip()}" + indented += line.strip() else: - # if changing indent level and not the first item on the line, then - # check if base indent is changed. - # match must start at first of string - start_test = list( - re.finditer(re.compile(r"^(\w+?=[\"'])", re.M), line.strip()) - ) + list( - re.finditer( - re.compile( - r"^(.+?)" + config.template_indent, re.I | re.X | re.M - ), - line.strip(), - ) - ) - - if start_test: - indent_adder = len(start_test[-1].group(1)) - ( - base_indent if line_number == 0 else 0 - ) - - base_indent_space = base_indent * " " - if tmp.strip() != "": - indented += f"\n{leading_space}{base_indent_space}{tmp}" - - end_text = re.findall(re.compile(r"[\"']$", re.M), line.strip()) - - if end_text: - indent_adder = 0 + indented += f"\n{tmp}" return indented - def add_break( - config: Config, attributes: str, pattern: str, match: re.Match - ) -> str: + def add_break(pattern: str, match: re.Match) -> str: """Make a decision if a break should be added.""" - # check if we are inside an attribute. - inside_attribute = any( - x.start() <= match.start() and match.end() <= x.end() - for x in re.finditer( - re.compile( - r"[a-zA-Z-_]+[ ]*?=[ ]*?([\"'])([^\1]*?" - + config.template_if_for_pattern - + r"[^\1]*?)\1", - re.I | re.M | re.X | re.DOTALL, - ), - attributes, - ) - ) - - if inside_attribute: - attr_name = list( - re.finditer( - re.compile(r"^.+?\w+[ ]*?=[ ]*?[\"|']", re.M), - attributes[: match.start()], - ) - )[-1] - else: - # if we don't know where we are, then return what we started with. - if not re.findall( - re.compile(r"^<\w+[^=\"']\s*", re.M), attributes[: match.start()] - ): - return match.group() - - attr_name = list( - re.finditer( - re.compile(r"^<\w+[^=\"']\s*", re.M), attributes[: match.start()] - ) - )[-1] - if pattern == "before": - # but don't add break if we are the first thing in an attribute. - if attr_name.end() == match.start(): - return match.group() - return f"\n{match.group()}" - # but don't add a break if the next char closes the attr. - if re.match(r"\s*?[\"|'|>]", match.group(2)): - return match.group(1) + match.group(2) - return f"{match.group(1)}\n{match.group(2).strip()}" break_char = config.break_before - func = partial(add_break, config, attributes, "before") + func = partial(add_break, "before") + attributes = re.sub( re.compile( break_char - + r"\K((?:{%|{{\#)[ ]*?(?:" + + r".\K((?:{%|{{\#)[ ]*?(?:" + config.break_template_tags + ")[^}]+?[%|}]})", flags=re.IGNORECASE | re.MULTILINE | re.VERBOSE, @@ -201,7 +94,7 @@ def format_template_tags(config: Config, attributes: str) -> str: attributes, ) - func = partial(add_break, config, attributes, "after") + func = partial(add_break, "after") # break after attributes = re.sub( re.compile( @@ -213,34 +106,11 @@ def format_template_tags(config: Config, attributes: str) -> str: func, attributes, ) - - attributes = add_indentation(config, attributes) + attributes = add_indentation(config, attributes, spacing) return attributes -def format_style(match: re.match) -> str: - """Format inline styles.""" - tag = match.group(2) - - quote = match.group(3) - - # if the style attrib is following the tag name - leading_stuff = ( - match.group(1) - if not bool(re.match(r"^\s+$", match.group(1), re.MULTILINE)) - else len(match.group(1)) * " " - ) - - spacing = "\n" + len(match.group(1)) * " " + len(tag) * " " + len(quote) * " " - - styles = (spacing).join( - [x.strip() + ";" for x in match.group(4).split(";") if x.strip()] - ) - - return f"{leading_stuff}{tag}{quote}{styles}{quote}" - - def format_attributes(config: Config, html: str, match: re.match) -> str: """Spread long attributes over multiple lines.""" # check that we are not inside an ignored block @@ -254,38 +124,68 @@ def format_attributes(config: Config, html: str, match: re.match) -> str: tag = match.group(2) + " " - spacing = "\n" + leading_space + len(tag) * " " + spacing = leading_space + len(tag) * " " + + attributes = [] # format attributes as groups - attributes = (spacing).join( - [ - x.group() - for x in re.finditer( - config.attribute_pattern, match.group(3).strip(), re.VERBOSE + for attr_grp in re.finditer( + config.attribute_pattern, match.group(3).strip(), re.VERBOSE + ): + + attrib_name = attr_grp.group(1) + is_quoted = attr_grp.group(2) and attr_grp.group(2)[0] in ["'", '"'] + quote = attr_grp.group(2)[0] if is_quoted else '"' + attrib_value = attr_grp.group(2).strip("\"'") if attr_grp.group(2) else None + standalone = attr_grp.group(3) + + quote_length = 1 + + if attrib_name and attrib_value: + # for the equals sign + quote_length += 1 + + # format style attribute + if attrib_name and attrib_name.lower() == "style": + if config.format_attribute_template_tags: + join_space = "\n" + spacing + else: + join_space = ( + "\n" + spacing + int(quote_length + len(attrib_name or "")) * " " + ) + attrib_value = (";" + join_space).join( + [value.strip() for value in attrib_value.split(";") if value.strip()] ) - ] - ) + + # format template stuff + if config.format_attribute_template_tags: + if attrib_value and attrib_name not in config.ignored_attributes: + attrib_value = format_template_tags( + config, + attrib_value, + int(len(spacing) + len(attrib_name or "") + quote_length), + ) + + if standalone: + standalone = format_template_tags( + config, standalone, int(len(spacing) + len(attrib_name or "")) + ) + + if attrib_name and attrib_value or is_quoted: + attrib_value = attrib_value or "" + attributes.append(f"{attrib_name}={quote}{attrib_value}{quote}") + else: + attributes.append( + (attrib_name or "") + (attrib_value or "") + (standalone or "") + ) + + attribute_string = ("\n" + spacing).join([x for x in attributes if x]) close = match.group(4) - attributes = f"{leading_space}{tag}{attributes}{close}" - - # format template tags - if config.format_attribute_template_tags: - attributes = format_template_tags(config, attributes) - - # format styles - func = partial(format_style) - attributes = re.sub( - re.compile( - config.attribute_style_pattern, - re.VERBOSE | re.IGNORECASE | re.M, - ), - func, - attributes, - ) + attribute_string = f"{leading_space}{tag}{attribute_string}{close}" # clean trailing spaces added by breaks - attributes = "\n".join([x.rstrip() for x in attributes.splitlines()]) + attribute_string = "\n".join([x.rstrip() for x in attribute_string.splitlines()]) - return f"{attributes}" + return f"{attribute_string}" diff --git a/src/djlint/settings.py b/src/djlint/settings.py index 24b3864..00afb4a 100644 --- a/src/djlint/settings.py +++ b/src/djlint/settings.py @@ -505,11 +505,11 @@ class Config: self.attribute_pattern: str = ( rf""" (?: - (?: + ( (?:\w|-|\.)+ | required | checked ) # attribute name (?: [ ]*?=[ ]*? # followed by "=" - (?: + ( \"[^\"]*? # double quoted attribute (?: {self.template_if_for_pattern} # if or for loop @@ -526,21 +526,32 @@ class Config: | [^'] # anything else )*? \' # closing quote - | (?:\w|-)+ # or a non-quoted value + | (?:\w|-)+ # or a non-quoted string value + | {{{{.*?}}}} # a non-quoted template var + | {{%[^}}]*?%}} # a non-quoted template tag + | {self.template_if_for_pattern} # a non-quoted if statement ) )? # attribute value ) - | {self.template_if_for_pattern} + | ({self.template_if_for_pattern} """ + r""" | {{.*?}} - | {%.*?%} + | {%.*?%}) """ ) self.attribute_style_pattern: str = r"^(.*?)(style=)([\"|'])(([^\"']+?;)+?)\3" - + self.ignored_attributes = [ + "href", + "action", + "data-url", + "src", + "url", + "srcset", + "data-src", + ] self.start_template_tags: str = ( r""" if diff --git a/tests/test_config/test_format_attribute_template_tags/html-one.html b/tests/test_config/test_format_attribute_template_tags/html-one.html index dcdc8f4..7393693 100644 --- a/tests/test_config/test_format_attribute_template_tags/html-one.html +++ b/tests/test_config/test_format_attribute_template_tags/html-one.html @@ -4,11 +4,7 @@ {% else %} that is long stuff asdf and more even {% endif %}"/> -report image - + object-id="{{ report.report_id }}" + href="{% if %}{% endif %}"> + diff --git a/tests/test_html/test_attributes.py b/tests/test_html/test_attributes.py index 16a47ce..0dcc8c0 100644 --- a/tests/test_html/test_attributes.py +++ b/tests/test_html/test_attributes.py @@ -46,7 +46,9 @@ def test_long_attributes(runner: CliRunner, tmp_file: TextIO) -> None: class="class one class two" disabled="true" value="something pretty long goes here" - style="width:100px;cursor: text;border:1px solid pink" + style="width:100px; + cursor: text; + border:1px solid pink" required="true"/> """ ) @@ -62,7 +64,7 @@ def test_long_attributes(runner: CliRunner, tmp_file: TextIO) -> None: style="margin-left: 90px; display: contents; font-weight: bold; - font-size: 1.5rem;"> + font-size: 1.5rem"> """, ) @@ -76,7 +78,7 @@ def test_long_attributes(runner: CliRunner, tmp_file: TextIO) -> None:
@@ -85,13 +87,18 @@ def test_long_attributes(runner: CliRunner, tmp_file: TextIO) -> None: ) assert output.exit_code == 0 - # attributes with space around = are not brocken + # attributes with space around = are not broken + # https://github.com/Riverside-Healthcare/djLint/issues/317 + # https://github.com/Riverside-Healthcare/djLint/issues/330 output = reformat( tmp_file, runner, b"""Test\n""", ) - assert output.exit_code == 0 + assert ( + output.text + == """Test\n""" + ) def test_ignored_attributes(runner: CliRunner, tmp_file: TextIO) -> None: @@ -156,7 +163,7 @@ def test_boolean_attributes(runner: CliRunner, tmp_file: TextIO) -> None: """, ) assert output.exit_code == 1 - print(output.text) + assert ( output.text == """ """ ) From 0d170aab6c2250095cc27151c19035a1c49a278d Mon Sep 17 00:00:00 2001 From: Christopher Pickering Date: Thu, 3 Nov 2022 11:40:09 +0100 Subject: [PATCH 6/7] fix(image tag): added image tag to template break tag list. srcset formatting closes #444 --- src/djlint/formatter/attributes.py | 18 ++++++++++++------ src/djlint/settings.py | 1 + tests/test_html/test_attributes.py | 24 ++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/djlint/formatter/attributes.py b/src/djlint/formatter/attributes.py index 1a4f527..ff390bc 100644 --- a/src/djlint/formatter/attributes.py +++ b/src/djlint/formatter/attributes.py @@ -145,18 +145,24 @@ def format_attributes(config: Config, html: str, match: re.match) -> str: # for the equals sign quote_length += 1 + if config.format_attribute_template_tags: + join_space = "\n" + spacing + else: + join_space = ( + "\n" + spacing + int(quote_length + len(attrib_name or "")) * " " + ) + # format style attribute if attrib_name and attrib_name.lower() == "style": - if config.format_attribute_template_tags: - join_space = "\n" + spacing - else: - join_space = ( - "\n" + spacing + int(quote_length + len(attrib_name or "")) * " " - ) attrib_value = (";" + join_space).join( [value.strip() for value in attrib_value.split(";") if value.strip()] ) + elif attrib_name and attrib_name.lower() in ["srcset", "data-srcset", "sizes"]: + attrib_value = ("," + join_space).join( + [value.strip() for value in attrib_value.split(",") if value.strip()] + ) + # format template stuff if config.format_attribute_template_tags: if attrib_value and attrib_name not in config.ignored_attributes: diff --git a/src/djlint/settings.py b/src/djlint/settings.py index 00afb4a..aadad02 100644 --- a/src/djlint/settings.py +++ b/src/djlint/settings.py @@ -614,6 +614,7 @@ class Config: | endraw | call | endcall + | image """ + self.custom_blocks + r""" diff --git a/tests/test_html/test_attributes.py b/tests/test_html/test_attributes.py index 0dcc8c0..8836e05 100644 --- a/tests/test_html/test_attributes.py +++ b/tests/test_html/test_attributes.py @@ -29,6 +29,30 @@ from click.testing import CliRunner from tests.conftest import reformat +def test_srcset(runner: CliRunner, tmp_file: TextIO) -> None: + output = reformat( + tmp_file, + runner, + b"""Block image""", + ) + assert output.exit_code == 0 + + def test_long_attributes(runner: CliRunner, tmp_file: TextIO) -> None: output = reformat( tmp_file, From ffc3939d4f672c133367cbd1766f9a09563b214b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Nov 2022 11:20:47 +0000 Subject: [PATCH 7/7] chore(deps) Update dependency cssnano to v5.1.14 --- docs/package-lock.json | 186 ++++++++++++++++++++--------------------- docs/package.json | 4 +- 2 files changed, 95 insertions(+), 95 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 0e37c3e..87b0276 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -1,12 +1,12 @@ { "name": "djlint_docs", - "version": "1.0.40", + "version": "1.0.41", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "djlint_docs", - "version": "1.0.40", + "version": "1.0.41", "license": "AGPL-3.0-or-later", "dependencies": { "@creativebulma/bulma-divider": "^1.1.0", @@ -32,7 +32,7 @@ "autoprefixer": "10.4.13", "bulma": "0.9.4", "bulma-pricingtable": "0.2.0", - "cssnano": "5.1.13", + "cssnano": "5.1.14", "cz-conventional-changelog": "3.3.0", "eleventy-plugin-edit-on-github": "1.1.0", "eleventy-plugin-metagen": "1.7.11", @@ -2990,9 +2990,9 @@ } }, "node_modules/css-declaration-sorter": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.0.tgz", - "integrity": "sha512-OGT677UGHJTAVMRhPO+HJ4oKln3wkBTwtDFH0ojbqm+MJm6xuDMHp2nkhh/ThaBqq20IbraBQSWKfSLNHQO9Og==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz", + "integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==", "dev": true, "engines": { "node": "^10 || ^12 || >=14" @@ -3077,12 +3077,12 @@ } }, "node_modules/cssnano": { - "version": "5.1.13", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.13.tgz", - "integrity": "sha512-S2SL2ekdEz6w6a2epXn4CmMKU4K3KpcyXLKfAYc9UQQqJRkD/2eLUG0vJ3Db/9OvO5GuAdgXw3pFbR6abqghDQ==", + "version": "5.1.14", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.14.tgz", + "integrity": "sha512-Oou7ihiTocbKqi0J1bB+TRJIQX5RMR3JghA8hcWSw9mjBLQ5Y3RWqEDoYG3sRNlAbCIXpqMoZGbq5KDR3vdzgw==", "dev": true, "dependencies": { - "cssnano-preset-default": "^5.2.12", + "cssnano-preset-default": "^5.2.13", "lilconfig": "^2.0.3", "yaml": "^1.10.2" }, @@ -3098,25 +3098,25 @@ } }, "node_modules/cssnano-preset-default": { - "version": "5.2.12", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.12.tgz", - "integrity": "sha512-OyCBTZi+PXgylz9HAA5kHyoYhfGcYdwFmyaJzWnzxuGRtnMw/kR6ilW9XzlzlRAtB6PLT/r+prYgkef7hngFew==", + "version": "5.2.13", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.13.tgz", + "integrity": "sha512-PX7sQ4Pb+UtOWuz8A1d+Rbi+WimBIxJTRyBdgGp1J75VU0r/HFQeLnMYgHiCAp6AR4rqrc7Y4R+1Rjk3KJz6DQ==", "dev": true, "dependencies": { - "css-declaration-sorter": "^6.3.0", + "css-declaration-sorter": "^6.3.1", "cssnano-utils": "^3.1.0", "postcss-calc": "^8.2.3", "postcss-colormin": "^5.3.0", - "postcss-convert-values": "^5.1.2", + "postcss-convert-values": "^5.1.3", "postcss-discard-comments": "^5.1.2", "postcss-discard-duplicates": "^5.1.0", "postcss-discard-empty": "^5.1.1", "postcss-discard-overridden": "^5.1.0", - "postcss-merge-longhand": "^5.1.6", - "postcss-merge-rules": "^5.1.2", + "postcss-merge-longhand": "^5.1.7", + "postcss-merge-rules": "^5.1.3", "postcss-minify-font-values": "^5.1.0", "postcss-minify-gradients": "^5.1.1", - "postcss-minify-params": "^5.1.3", + "postcss-minify-params": "^5.1.4", "postcss-minify-selectors": "^5.2.1", "postcss-normalize-charset": "^5.1.0", "postcss-normalize-display-values": "^5.1.0", @@ -3124,11 +3124,11 @@ "postcss-normalize-repeat-style": "^5.1.1", "postcss-normalize-string": "^5.1.0", "postcss-normalize-timing-functions": "^5.1.0", - "postcss-normalize-unicode": "^5.1.0", + "postcss-normalize-unicode": "^5.1.1", "postcss-normalize-url": "^5.1.0", "postcss-normalize-whitespace": "^5.1.1", "postcss-ordered-values": "^5.1.3", - "postcss-reduce-initial": "^5.1.0", + "postcss-reduce-initial": "^5.1.1", "postcss-reduce-transforms": "^5.1.0", "postcss-svgo": "^5.1.0", "postcss-unique-selectors": "^5.1.1" @@ -8449,12 +8449,12 @@ } }, "node_modules/postcss-convert-values": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.2.tgz", - "integrity": "sha512-c6Hzc4GAv95B7suy4udszX9Zy4ETyMCgFPUDtWjdFTKH1SE9eFY/jEpHSwTH1QPuwxHpWslhckUQWbNRM4ho5g==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", + "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", "dev": true, "dependencies": { - "browserslist": "^4.20.3", + "browserslist": "^4.21.4", "postcss-value-parser": "^4.2.0" }, "engines": { @@ -8594,13 +8594,13 @@ } }, "node_modules/postcss-merge-longhand": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.6.tgz", - "integrity": "sha512-6C/UGF/3T5OE2CEbOuX7iNO63dnvqhGZeUnKkDeifebY0XqkkvrctYSZurpNE902LDf2yKwwPFgotnfSoPhQiw==", + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", + "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0", - "stylehacks": "^5.1.0" + "stylehacks": "^5.1.1" }, "engines": { "node": "^10 || ^12 || >=14.0" @@ -8610,12 +8610,12 @@ } }, "node_modules/postcss-merge-rules": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.2.tgz", - "integrity": "sha512-zKMUlnw+zYCWoPN6yhPjtcEdlJaMUZ0WyVcxTAmw3lkkN/NDMRkOkiuctQEoWAOvH7twaxUUdvBWl0d4+hifRQ==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.3.tgz", + "integrity": "sha512-LbLd7uFC00vpOuMvyZop8+vvhnfRGpp2S+IMQKeuOZZapPRY4SMq5ErjQeHbHsjCUgJkRNrlU+LmxsKIqPKQlA==", "dev": true, "dependencies": { - "browserslist": "^4.16.6", + "browserslist": "^4.21.4", "caniuse-api": "^3.0.0", "cssnano-utils": "^3.1.0", "postcss-selector-parser": "^6.0.5" @@ -8660,12 +8660,12 @@ } }, "node_modules/postcss-minify-params": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.3.tgz", - "integrity": "sha512-bkzpWcjykkqIujNL+EVEPOlLYi/eZ050oImVtHU7b4lFS82jPnsCb44gvC6pxaNt38Els3jWYDHTjHKf0koTgg==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", + "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", "dev": true, "dependencies": { - "browserslist": "^4.16.6", + "browserslist": "^4.21.4", "cssnano-utils": "^3.1.0", "postcss-value-parser": "^4.2.0" }, @@ -8798,12 +8798,12 @@ } }, "node_modules/postcss-normalize-unicode": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.0.tgz", - "integrity": "sha512-J6M3MizAAZ2dOdSjy2caayJLQT8E8K9XjLce8AUQMwOrCvjCHv24aLC/Lps1R1ylOfol5VIDMaM/Lo9NGlk1SQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", + "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", "dev": true, "dependencies": { - "browserslist": "^4.16.6", + "browserslist": "^4.21.4", "postcss-value-parser": "^4.2.0" }, "engines": { @@ -8861,12 +8861,12 @@ } }, "node_modules/postcss-reduce-initial": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.0.tgz", - "integrity": "sha512-5OgTUviz0aeH6MtBjHfbr57tml13PuedK/Ecg8szzd4XRMbYxH4572JFG067z+FqBIf6Zp/d+0581glkvvWMFw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.1.tgz", + "integrity": "sha512-//jeDqWcHPuXGZLoolFrUXBDyuEGbr9S2rMo19bkTIjBQ4PqkaO+oI8wua5BOUxpfi97i3PCoInsiFIEBfkm9w==", "dev": true, "dependencies": { - "browserslist": "^4.16.6", + "browserslist": "^4.21.4", "caniuse-api": "^3.0.0" }, "engines": { @@ -10530,12 +10530,12 @@ } }, "node_modules/stylehacks": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.0.tgz", - "integrity": "sha512-SzLmvHQTrIWfSgljkQCw2++C9+Ne91d/6Sp92I8c5uHTcy/PgeHamwITIbBW9wnFTY/3ZfSXR9HIL6Ikqmcu6Q==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", + "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", "dev": true, "dependencies": { - "browserslist": "^4.16.6", + "browserslist": "^4.21.4", "postcss-selector-parser": "^6.0.4" }, "engines": { @@ -14041,9 +14041,9 @@ } }, "css-declaration-sorter": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.0.tgz", - "integrity": "sha512-OGT677UGHJTAVMRhPO+HJ4oKln3wkBTwtDFH0ojbqm+MJm6xuDMHp2nkhh/ThaBqq20IbraBQSWKfSLNHQO9Og==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz", + "integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==", "dev": true, "requires": {} }, @@ -14104,36 +14104,36 @@ "dev": true }, "cssnano": { - "version": "5.1.13", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.13.tgz", - "integrity": "sha512-S2SL2ekdEz6w6a2epXn4CmMKU4K3KpcyXLKfAYc9UQQqJRkD/2eLUG0vJ3Db/9OvO5GuAdgXw3pFbR6abqghDQ==", + "version": "5.1.14", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.14.tgz", + "integrity": "sha512-Oou7ihiTocbKqi0J1bB+TRJIQX5RMR3JghA8hcWSw9mjBLQ5Y3RWqEDoYG3sRNlAbCIXpqMoZGbq5KDR3vdzgw==", "dev": true, "requires": { - "cssnano-preset-default": "^5.2.12", + "cssnano-preset-default": "^5.2.13", "lilconfig": "^2.0.3", "yaml": "^1.10.2" } }, "cssnano-preset-default": { - "version": "5.2.12", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.12.tgz", - "integrity": "sha512-OyCBTZi+PXgylz9HAA5kHyoYhfGcYdwFmyaJzWnzxuGRtnMw/kR6ilW9XzlzlRAtB6PLT/r+prYgkef7hngFew==", + "version": "5.2.13", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.13.tgz", + "integrity": "sha512-PX7sQ4Pb+UtOWuz8A1d+Rbi+WimBIxJTRyBdgGp1J75VU0r/HFQeLnMYgHiCAp6AR4rqrc7Y4R+1Rjk3KJz6DQ==", "dev": true, "requires": { - "css-declaration-sorter": "^6.3.0", + "css-declaration-sorter": "^6.3.1", "cssnano-utils": "^3.1.0", "postcss-calc": "^8.2.3", "postcss-colormin": "^5.3.0", - "postcss-convert-values": "^5.1.2", + "postcss-convert-values": "^5.1.3", "postcss-discard-comments": "^5.1.2", "postcss-discard-duplicates": "^5.1.0", "postcss-discard-empty": "^5.1.1", "postcss-discard-overridden": "^5.1.0", - "postcss-merge-longhand": "^5.1.6", - "postcss-merge-rules": "^5.1.2", + "postcss-merge-longhand": "^5.1.7", + "postcss-merge-rules": "^5.1.3", "postcss-minify-font-values": "^5.1.0", "postcss-minify-gradients": "^5.1.1", - "postcss-minify-params": "^5.1.3", + "postcss-minify-params": "^5.1.4", "postcss-minify-selectors": "^5.2.1", "postcss-normalize-charset": "^5.1.0", "postcss-normalize-display-values": "^5.1.0", @@ -14141,11 +14141,11 @@ "postcss-normalize-repeat-style": "^5.1.1", "postcss-normalize-string": "^5.1.0", "postcss-normalize-timing-functions": "^5.1.0", - "postcss-normalize-unicode": "^5.1.0", + "postcss-normalize-unicode": "^5.1.1", "postcss-normalize-url": "^5.1.0", "postcss-normalize-whitespace": "^5.1.1", "postcss-ordered-values": "^5.1.3", - "postcss-reduce-initial": "^5.1.0", + "postcss-reduce-initial": "^5.1.1", "postcss-reduce-transforms": "^5.1.0", "postcss-svgo": "^5.1.0", "postcss-unique-selectors": "^5.1.1" @@ -18047,12 +18047,12 @@ } }, "postcss-convert-values": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.2.tgz", - "integrity": "sha512-c6Hzc4GAv95B7suy4udszX9Zy4ETyMCgFPUDtWjdFTKH1SE9eFY/jEpHSwTH1QPuwxHpWslhckUQWbNRM4ho5g==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", + "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", "dev": true, "requires": { - "browserslist": "^4.20.3", + "browserslist": "^4.21.4", "postcss-value-parser": "^4.2.0" } }, @@ -18133,22 +18133,22 @@ } }, "postcss-merge-longhand": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.6.tgz", - "integrity": "sha512-6C/UGF/3T5OE2CEbOuX7iNO63dnvqhGZeUnKkDeifebY0XqkkvrctYSZurpNE902LDf2yKwwPFgotnfSoPhQiw==", + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", + "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", "dev": true, "requires": { "postcss-value-parser": "^4.2.0", - "stylehacks": "^5.1.0" + "stylehacks": "^5.1.1" } }, "postcss-merge-rules": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.2.tgz", - "integrity": "sha512-zKMUlnw+zYCWoPN6yhPjtcEdlJaMUZ0WyVcxTAmw3lkkN/NDMRkOkiuctQEoWAOvH7twaxUUdvBWl0d4+hifRQ==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.3.tgz", + "integrity": "sha512-LbLd7uFC00vpOuMvyZop8+vvhnfRGpp2S+IMQKeuOZZapPRY4SMq5ErjQeHbHsjCUgJkRNrlU+LmxsKIqPKQlA==", "dev": true, "requires": { - "browserslist": "^4.16.6", + "browserslist": "^4.21.4", "caniuse-api": "^3.0.0", "cssnano-utils": "^3.1.0", "postcss-selector-parser": "^6.0.5" @@ -18175,12 +18175,12 @@ } }, "postcss-minify-params": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.3.tgz", - "integrity": "sha512-bkzpWcjykkqIujNL+EVEPOlLYi/eZ050oImVtHU7b4lFS82jPnsCb44gvC6pxaNt38Els3jWYDHTjHKf0koTgg==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", + "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", "dev": true, "requires": { - "browserslist": "^4.16.6", + "browserslist": "^4.21.4", "cssnano-utils": "^3.1.0", "postcss-value-parser": "^4.2.0" } @@ -18256,12 +18256,12 @@ } }, "postcss-normalize-unicode": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.0.tgz", - "integrity": "sha512-J6M3MizAAZ2dOdSjy2caayJLQT8E8K9XjLce8AUQMwOrCvjCHv24aLC/Lps1R1ylOfol5VIDMaM/Lo9NGlk1SQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", + "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", "dev": true, "requires": { - "browserslist": "^4.16.6", + "browserslist": "^4.21.4", "postcss-value-parser": "^4.2.0" } }, @@ -18295,12 +18295,12 @@ } }, "postcss-reduce-initial": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.0.tgz", - "integrity": "sha512-5OgTUviz0aeH6MtBjHfbr57tml13PuedK/Ecg8szzd4XRMbYxH4572JFG067z+FqBIf6Zp/d+0581glkvvWMFw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.1.tgz", + "integrity": "sha512-//jeDqWcHPuXGZLoolFrUXBDyuEGbr9S2rMo19bkTIjBQ4PqkaO+oI8wua5BOUxpfi97i3PCoInsiFIEBfkm9w==", "dev": true, "requires": { - "browserslist": "^4.16.6", + "browserslist": "^4.21.4", "caniuse-api": "^3.0.0" } }, @@ -19596,12 +19596,12 @@ "dev": true }, "stylehacks": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.0.tgz", - "integrity": "sha512-SzLmvHQTrIWfSgljkQCw2++C9+Ne91d/6Sp92I8c5uHTcy/PgeHamwITIbBW9wnFTY/3ZfSXR9HIL6Ikqmcu6Q==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", + "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", "dev": true, "requires": { - "browserslist": "^4.16.6", + "browserslist": "^4.21.4", "postcss-selector-parser": "^6.0.4" } }, diff --git a/docs/package.json b/docs/package.json index 233ecc5..06d6be3 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "djlint_docs", - "version": "1.0.40", + "version": "1.0.41", "description": "", "main": "index.js", "scripts": { @@ -36,7 +36,7 @@ "autoprefixer": "10.4.13", "bulma": "0.9.4", "bulma-pricingtable": "0.2.0", - "cssnano": "5.1.13", + "cssnano": "5.1.14", "cz-conventional-changelog": "3.3.0", "eleventy-plugin-edit-on-github": "1.1.0", "eleventy-plugin-metagen": "1.7.11",