mirror of
https://github.com/Hopiu/djLint.git
synced 2026-03-16 21:40:24 +00:00
Merge branch 'dev' of github.com:Riverside-Healthcare/djLint into dev
This commit is contained in:
commit
ddb3da04b5
42 changed files with 8245 additions and 6491 deletions
21
.github/workflows/linkcheck.yaml
vendored
Normal file
21
.github/workflows/linkcheck.yaml
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
name: Linkcheck
|
||||
on: [push]
|
||||
jobs:
|
||||
linkcheck:
|
||||
name: Linkcheck
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.x
|
||||
|
||||
- name: npm install, build
|
||||
run: |
|
||||
cd docs
|
||||
npm install
|
||||
npm run build
|
||||
|
||||
- uses: untitaker/hyperlink@0.1.26
|
||||
with:
|
||||
args: docs/_site/
|
||||
23
.github/workflows/release.yml
vendored
23
.github/workflows/release.yml
vendored
|
|
@ -26,6 +26,27 @@ jobs:
|
|||
- name: Setup Poetry
|
||||
uses: snok/install-poetry@v1
|
||||
|
||||
- name: Update wheels in docs demo
|
||||
run: |
|
||||
# remove old wheels
|
||||
rm -f docs/src/static/py/*
|
||||
# build new wheels
|
||||
poetry run pip wheel . -w docs/src/static/py
|
||||
# rename wheels
|
||||
cd docs/src/static/py
|
||||
mv djlint* djlint-99-py3-none-any.whl
|
||||
mv click* click-99-py3-none-any.whl
|
||||
mv colorama* colorama-99-py3-none-any.whl
|
||||
mv cssbeautifier* cssbeautifier-99-py3-none-any.whl
|
||||
mv EditorConfig* EditorConfig-99-py3-none-any.whl
|
||||
mv html_tag_names* html_tag_names-99-py3-none-any.whl
|
||||
mv html_void_elements* html_void_elements-99-py3-none-any.whl
|
||||
mv importlib_metadata* importlib_metadata-99-py3-none-any.whl
|
||||
mv jsbeautifier* jsbeautifier-99-py3-none-any.whl
|
||||
mv pathspec* pathspec-99-py3-none-any.whl
|
||||
mv PyYAML* PyYAML-99-py3-none-any.whl
|
||||
mv zipp* zipp-99-py3-none-any.whl
|
||||
|
||||
- name: Semantic Release
|
||||
uses: cycjimmy/semantic-release-action@v3
|
||||
|
||||
|
|
@ -42,6 +63,6 @@ jobs:
|
|||
|
||||
- name: Build and publish package
|
||||
if: steps.semantic.outputs.new_release_published == 'true'
|
||||
uses: JRubics/poetry-publish@v1.13
|
||||
uses: JRubics/poetry-publish@v1.15
|
||||
with:
|
||||
pypi_token: ${{ secrets.PYPI_API_TOKEN }}
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@ exclude: >
|
|||
)
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.3.0
|
||||
rev: v4.4.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: end-of-file-fixer
|
||||
- id: check-yaml
|
||||
- repo: https://github.com/myint/autoflake
|
||||
rev: v1.7.7
|
||||
rev: v2.0.0
|
||||
hooks:
|
||||
- id: autoflake
|
||||
exclude: &fixtures tests/functional/|tests/input|tests/extensions/data|tests/regrtest_data/|tests/data/
|
||||
|
|
@ -22,7 +22,7 @@ repos:
|
|||
- --remove-duplicate-keys
|
||||
- --remove-unused-variables
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v3.2.0
|
||||
rev: v3.3.1
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: [--py36-plus]
|
||||
|
|
@ -33,11 +33,11 @@ repos:
|
|||
exclude: docs*
|
||||
additional_dependencies: [toml]
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 22.10.0
|
||||
rev: 22.12.0
|
||||
hooks:
|
||||
- id: black
|
||||
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
|
||||
rev: v2.4.0
|
||||
rev: v2.5.0
|
||||
hooks:
|
||||
- id: pretty-format-ini
|
||||
args: [--autofix]
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
"prepareCmd" : "poetry version ${nextRelease.version}"
|
||||
}],
|
||||
["@semantic-release/git", {
|
||||
"assets": ["package.json", "pyproject.toml"]
|
||||
"assets": ["package.json", "pyproject.toml", "docs"]
|
||||
}],
|
||||
"@semantic-release/github"
|
||||
]
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ const outdent = require('outdent');
|
|||
const schema = require('@quasibit/eleventy-plugin-schema');
|
||||
const editOnGithub = require('eleventy-plugin-edit-on-github');
|
||||
const i18n_func = require('eleventy-plugin-i18n/i18n.js');
|
||||
const rollupper = require('./src/_utils/rollupper');
|
||||
const { nodeResolve } = require('@rollup/plugin-node-resolve');
|
||||
|
||||
const slugifyCustom = (s) =>
|
||||
slugify(s, { lower: true, remove: /[*+~.()'"!:@]/g });
|
||||
|
|
@ -93,6 +95,15 @@ module.exports = function (eleventyConfig) {
|
|||
eleventyConfig.addPlugin(metagen);
|
||||
eleventyConfig.addPlugin(criticalCss);
|
||||
eleventyConfig.addPlugin(schema);
|
||||
eleventyConfig.addPlugin(rollupper, {
|
||||
rollup: {
|
||||
output: {
|
||||
format: 'umd',
|
||||
dir: '_site/static/js',
|
||||
},
|
||||
plugins: [nodeResolve()],
|
||||
},
|
||||
});
|
||||
eleventyConfig.addPlugin(editOnGithub, {
|
||||
// required
|
||||
github_edit_repo: 'https://github.com/Riverside-Healthcare/djLint',
|
||||
|
|
@ -190,6 +201,16 @@ module.exports = function (eleventyConfig) {
|
|||
'src/static/img/favicon.ico': 'favicon.ico',
|
||||
});
|
||||
|
||||
// copy wheels
|
||||
eleventyConfig.addPassthroughCopy({
|
||||
'src/static/py': 'static/py',
|
||||
});
|
||||
|
||||
// copy python
|
||||
eleventyConfig.addPassthroughCopy({
|
||||
'src/static/js/worker.js': 'static/js/worker.js',
|
||||
});
|
||||
|
||||
eleventyConfig.addFilter('jsonify', (text) => {
|
||||
return JSON.stringify(text).replace(/(?:\\n\s*){2,}/g, '\\n');
|
||||
});
|
||||
|
|
@ -203,6 +224,15 @@ module.exports = function (eleventyConfig) {
|
|||
}
|
||||
});
|
||||
|
||||
eleventyConfig.addFilter('year', (value) => {
|
||||
try {
|
||||
const options = { year: 'numeric' };
|
||||
return value.toLocaleDateString('en-us', options);
|
||||
} catch (e) {
|
||||
return value;
|
||||
}
|
||||
});
|
||||
|
||||
eleventyConfig.addFilter('algExcerpt', (text) => {
|
||||
return text
|
||||
.replace(/<code class="language-.*?">.*?<\/code>/gs, '')
|
||||
|
|
@ -244,6 +274,8 @@ module.exports = function (eleventyConfig) {
|
|||
'infinity',
|
||||
'download',
|
||||
'code-commit',
|
||||
'spinner',
|
||||
'circle-question',
|
||||
],
|
||||
},
|
||||
'_site/static/font/fontawesome/webfonts',
|
||||
|
|
|
|||
11185
docs/package-lock.json
generated
11185
docs/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "djlint_docs",
|
||||
"version": "1.0.42",
|
||||
"version": "1.0.51",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
|
@ -13,23 +13,28 @@
|
|||
"license": "AGPL-3.0-or-later",
|
||||
"browserslist": "> 2%, not dead",
|
||||
"dependencies": {
|
||||
"@codemirror/lang-html": "^6.2.0",
|
||||
"@codemirror/state": "^6.1.4",
|
||||
"@creativebulma/bulma-divider": "^1.1.0",
|
||||
"@fontsource/crimson-pro": "^4.5.8",
|
||||
"@fontsource/rasa": "^4.5.8",
|
||||
"@quasibit/eleventy-plugin-schema": "^1.9.1",
|
||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||
"@sindresorhus/slugify": "^2.1.0",
|
||||
"animate-sass": "^0.8.2",
|
||||
"animate.css": "github:animate-css/animate.css",
|
||||
"codemirror": "^6.0.1",
|
||||
"eleventy-critical-css": "^1.1.0",
|
||||
"eleventy-plugin-i18n": "^0.1.3",
|
||||
"md5": "^2.3.0"
|
||||
"md5": "^2.3.0",
|
||||
"rollup": "^3.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@11ty/eleventy": "1.0.2",
|
||||
"@11ty/eleventy-img": "2.0.1",
|
||||
"@11ty/eleventy-plugin-syntaxhighlight": "4.2.0",
|
||||
"@fontsource/inter": "4.5.14",
|
||||
"@fortawesome/fontawesome-free": "6.2.0",
|
||||
"@fortawesome/fontawesome-free": "6.2.1",
|
||||
"@fullhuman/postcss-purgecss": "5.0.0",
|
||||
"@toycode/markdown-it-class": "1.2.4",
|
||||
"algoliasearch": "4.14.2",
|
||||
|
|
@ -40,8 +45,8 @@
|
|||
"cz-conventional-changelog": "3.3.0",
|
||||
"eleventy-plugin-edit-on-github": "1.1.0",
|
||||
"eleventy-plugin-metagen": "1.7.11",
|
||||
"esbuild": "0.15.13",
|
||||
"eslint": "8.26.0",
|
||||
"esbuild": "0.16.3",
|
||||
"eslint": "8.29.0",
|
||||
"eslint-config-airbnb-base": "15.0.0",
|
||||
"eslint-plugin-import": "2.26.0",
|
||||
"fontawesome-subset": "4.3.1",
|
||||
|
|
@ -51,11 +56,11 @@
|
|||
"markdown-it-div": "1.1.0",
|
||||
"markdown-it-imsize": "2.0.1",
|
||||
"outdent": "0.8.0",
|
||||
"postcss-cli": "10.0.0",
|
||||
"postcss-cli": "10.1.0",
|
||||
"postcss-nested": "6.0.0",
|
||||
"prettier": "2.7.1",
|
||||
"prettier": "2.8.1",
|
||||
"prismjs": "1.29.0",
|
||||
"sass": "1.56.0",
|
||||
"sass": "1.56.2",
|
||||
"slugify": "1.6.5"
|
||||
},
|
||||
"config": {
|
||||
|
|
|
|||
17
docs/readme.md
Normal file
17
docs/readme.md
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# djLint Docs
|
||||
|
||||
Docs are made with [11ty](https://www.11ty.dev).
|
||||
|
||||
## Running the docs website locally
|
||||
|
||||
1. change into the docs dir. `cd docs`
|
||||
2. install node deps. `npm install`
|
||||
3. turn on the website. `npm start`
|
||||
|
||||
## How the demo works
|
||||
|
||||
The demo is running python as a webworker in web assembly from [pyodide](https://pyodide.org/en/stable/index.html).
|
||||
|
||||
When the page is access a webworker starts, downloads python, installs djLint and deps (notice the wheels in `/src/static/py` that are updated when a new release is created.).
|
||||
|
||||
Once the worker responds "ready" the web UI is shown.
|
||||
|
|
@ -135,4 +135,20 @@ module.exports = {
|
|||
ru: 'Игнорирование Контент',
|
||||
fr: 'Ignorer le Contenu',
|
||||
},
|
||||
try_online: {
|
||||
'en-US': '🤩 Try Online',
|
||||
fr: '🤩 Essayez Ici',
|
||||
ru: '🤩 Попробуйте онлайн',
|
||||
},
|
||||
demo_description: {
|
||||
'en-US': 'Online HTML Template formatter using djLint!',
|
||||
ru: 'Онлайн форматировщик HTML-шаблонов с использованием djLint',
|
||||
fr: 'Formateur de modèles HTML en ligne utilisant djLint !',
|
||||
},
|
||||
footer_credits: {
|
||||
'en-US':
|
||||
'djLint was originally created for use in the <a href="https://atlas.bi" target="_blank">Atlas</a> projects by the <a href="https://github.com/riverside-Healthcare/" target="_blank">Riverside Healthcare Analytics</a> team.',
|
||||
fr: 'djLint a été créé à l\'origine pour être utilisé dans les projets <a href="https://atlas.bi" target="_blank">Atlas</a> par l\'équipe <a href="https://github.com/riverside-Healthcare/" target="_blank">Riverside Healthcare Analytics</a>.',
|
||||
ru: 'Изначально djLint был создан для использования в проектах <a href="https://atlas.bi" target="_blank">Atlas</a> командой <a href="https://github.com/riverside-Healthcare/" target="_blank">Riverside Healthcare Analytics</a>.',
|
||||
},
|
||||
};
|
||||
|
|
|
|||
154
docs/src/_includes/demo.njk
Normal file
154
docs/src/_includes/demo.njk
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
---
|
||||
layout: layout.njk
|
||||
date: Last Modified
|
||||
description: Online HTML Template formatter. Reformat your HTML templates online with djLint.
|
||||
keywords: online template formatter, djLint, HTML, templates, formatter, linter, rules, online html template formatter
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="container is-fluid pb-5">
|
||||
<hr class="mt-0" />
|
||||
<h1 class="title is-3">{{ "demo_description" | i18n | safe }}</h1>
|
||||
<div class="block" id="djlint-status">
|
||||
<span class="icon-text">
|
||||
<span class="icon">
|
||||
<i class="fas fa-spinner fa-spin"></i>
|
||||
</span>
|
||||
<span><strong>Loading djLint ..</strong></span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="columns is-hidden">
|
||||
<div class="column is-narrow">
|
||||
|
||||
<form id="djlint-settings">
|
||||
<div class="field">
|
||||
<label class="label">Custom Blocks <a href="/docs/configuration/#custom_blocks" target="_blank"><span class="icon has-text-grey-light">
|
||||
<i class="fas fa-circle-question"></i>
|
||||
</span></a></label>
|
||||
<div class="control">
|
||||
<input id="settings-custom-blocks" class="input" type="text" placeholder="toc,example">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label">Custom HTML <a href="/docs/configuration/#custom_html" target="_blank"><span class="icon has-text-grey-light">
|
||||
<i class="fas fa-circle-question"></i>
|
||||
</span></a></label>
|
||||
<div class="control">
|
||||
<input id="settings-custom-html" class="input" type="text" placeholder="mjml,simple-greeting,mj-\w+">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label">Indent <a href="/docs/configuration/#indent" target="_blank"><span class="icon has-text-grey-light">
|
||||
<i class="fas fa-circle-question"></i>
|
||||
</span></a></label>
|
||||
<div class="control">
|
||||
<input id="settings-indent" class="input" type="text" placeholder="4">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label">Blank Line after Tag <a href="/docs/configuration/#blank_line_after_tag" target="_blank"><span class="icon has-text-grey-light">
|
||||
<i class="fas fa-circle-question"></i>
|
||||
</span></a></label>
|
||||
<div class="control">
|
||||
<input id="settings-blank-line-after-tag" class="input" type="text" placeholder="load,extends,include">
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">Blank Line before Tag <a href="/docs/configuration/#blank_line_before_tag" target="_blank"><span class="icon has-text-grey-light">
|
||||
<i class="fas fa-circle-question"></i>
|
||||
</span></a></label>
|
||||
<div class="control">
|
||||
<input id="settings-blank-line-before-tag" class="input" type="text" placeholder="load,extends,include">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label">Profile <a href="/docs/configuration/#profile" target="_blank"><span class="icon has-text-grey-light">
|
||||
<i class="fas fa-circle-question"></i>
|
||||
</span></a></label>
|
||||
<div class="control">
|
||||
<div class="select">
|
||||
<select id="settings-profile" >
|
||||
<option value="html">html (default)</option>
|
||||
<option value="django">django</option>
|
||||
<option value="jinja">jinja</option>
|
||||
<option value="nunjucks">nunjucks (nunjucks and twig)</option>
|
||||
<option value="handlebars">handlebars (handlebars and mustache)</option>
|
||||
<option value="golang">golang</option>
|
||||
<option value="angular">angular</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label">Max Line Length <a href="/docs/configuration/#max_line_length" target="_blank"><span class="icon has-text-grey-light">
|
||||
<i class="fas fa-circle-question"></i>
|
||||
</span></a></label>
|
||||
<div class="control">
|
||||
<input id="settings-max-line-length" class="input" type="text" placeholder="80">
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">Max Attribute Length <a href="/docs/configuration/#max_attribute_length" target="_blank"><span class="icon has-text-grey-light">
|
||||
<i class="fas fa-circle-question"></i>
|
||||
</span></a></label>
|
||||
<div class="control">
|
||||
<input id="settings-max-attribute-length" class="input" type="text" placeholder="0">
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input id="settings-format-attribute-template-tags" type="checkbox">
|
||||
Format Attribute Template Tags <a href="/docs/configuration/#format_attribute_template_tags" target="_blank"><span class="icon has-text-grey-light">
|
||||
<i class="fas fa-circle-question"></i>
|
||||
</span></a>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input id="settings-preserve-leading-space" type="checkbox">
|
||||
Preserve Leading Space <a href="/docs/configuration/#preserve_leading_space" target="_blank"><span class="icon has-text-grey-light">
|
||||
<i class="fas fa-circle-question"></i>
|
||||
</span></a>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input id="settings-preserve-blank-space" type="checkbox">
|
||||
Preserve Blank Space <a href="/docs/configuration/#preserve_blank_lines" target="_blank"><span class="icon has-text-grey-light">
|
||||
<i class="fas fa-circle-question"></i>
|
||||
</span></a>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input id="settings-format-js" type="checkbox">
|
||||
Format JS <a href="/docs/configuration/#format_js" target="_blank"><span class="icon has-text-grey-light">
|
||||
<i class="fas fa-circle-question"></i>
|
||||
</span></a>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input id="settings-format-css" type="checkbox">
|
||||
Format CSS <a href="/docs/configuration/#format_css" target="_blank"><span class="icon has-text-grey-light">
|
||||
<i class="fas fa-circle-question"></i>
|
||||
</span></a>
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="column" id="djlint-input">
|
||||
</div>
|
||||
<div class="column" id="djlint-output">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% rollup "src/static/js/editor.js" | url %}
|
||||
|
|
@ -12,7 +12,10 @@
|
|||
<div class="column"></div>
|
||||
<div class="column">
|
||||
<p class="copyright has-text-grey-dark has-text-right">
|
||||
djLint | ©2021 Riverside Healthcare
|
||||
djLint | ©{{ page.date | year }} Riverside Healthcare
|
||||
</p>
|
||||
<p class="has-text-grey-dark has-text-right mt-2">
|
||||
<small>{{ "footer_credits" | i18n | safe }}</small>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -34,6 +34,9 @@
|
|||
<a class="navbar-item has-text-grey-dark umami--nav--bestpractices" href="{{ "lang_code_url" | i18n }}/docs/best-practices">
|
||||
{{ "best_practices" | i18n }}
|
||||
</a>
|
||||
<a class="navbar-item has-text-grey-dark umami--nav--tryonline" href="{{ "lang_code_url" | i18n }}/demo">
|
||||
{{ "try_online" | i18n }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="navbar-end mx-0">
|
||||
<a class="navbar-item button is-white animated fadeIn umami--nav--github"
|
||||
|
|
|
|||
91
docs/src/_utils/rollupper.js
Normal file
91
docs/src/_utils/rollupper.js
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
rollup plugin from https://www.hoeser.dev/blog/2021-02-28-11ty-and-rollup/
|
||||
*/
|
||||
|
||||
const rollup = require('rollup');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
|
||||
module.exports = (eleventyConfig, options) => {
|
||||
new Rollupper(eleventyConfig, options);
|
||||
};
|
||||
|
||||
class Rollupper {
|
||||
inputFiles = {};
|
||||
rollupOptions = {};
|
||||
|
||||
constructor(eleventyConfig, { shortcode = 'rollup', rollup } = {}) {
|
||||
this.rollupOptions = rollup;
|
||||
eleventyConfig.on('beforeBuild', () => this.beforeBuild());
|
||||
eleventyConfig.on('afterBuild', () => this.afterBuild());
|
||||
|
||||
// We want to use "this" in the callback function, so we save the class instance beforehand
|
||||
const thisRollupper = this;
|
||||
eleventyConfig.addAsyncShortcode(shortcode, function (...args) {
|
||||
return thisRollupper.rollupperShortcode(this, ...args);
|
||||
});
|
||||
}
|
||||
|
||||
beforeBuild() {
|
||||
this.inputFiles = {};
|
||||
}
|
||||
|
||||
async rollupperShortcode(eleventyInstance, src, fileRelative = false) {
|
||||
// Resolve to the correct relative location
|
||||
if (fileRelative) {
|
||||
src = path.join(path.dirname(eleventyInstance.page.inputPath), src);
|
||||
}
|
||||
|
||||
// resolve to absolute, since rollup uses absolute paths
|
||||
src = path.resolve(src);
|
||||
|
||||
// generate a unique name for the file.
|
||||
// we take the first 6 chars of the sha256 of the absolute paths.
|
||||
const fileHash = await new Promise(function (resolve, reject) {
|
||||
const hash = crypto.createHash('sha256');
|
||||
const input = fs.createReadStream(src);
|
||||
|
||||
input.on('error', reject);
|
||||
|
||||
input.on('data', function (chunk) {
|
||||
hash.update(chunk);
|
||||
});
|
||||
|
||||
input.on('close', function () {
|
||||
resolve(hash.digest('hex'));
|
||||
});
|
||||
});
|
||||
const scriptSrc = fileHash.substr(0, 6) + '.js';
|
||||
|
||||
// register for rollup bundling
|
||||
this.inputFiles[src] = scriptSrc;
|
||||
|
||||
// calculate script src after bundling
|
||||
const relativePath = path.relative(
|
||||
eleventyInstance.page.outputPath,
|
||||
path.join(this.rollupOptions.output.dir, scriptSrc),
|
||||
);
|
||||
|
||||
return `<script src="${relativePath}" type="module"></script>`;
|
||||
}
|
||||
|
||||
async afterBuild() {
|
||||
// Return early if no JS was used, since rollup throws on empty inputs
|
||||
if (!Object.keys(this.inputFiles).length) {
|
||||
return;
|
||||
}
|
||||
const bundle = await rollup.rollup({
|
||||
input: Object.keys(this.inputFiles),
|
||||
...this.rollupOptions,
|
||||
});
|
||||
const inputFiles = this.inputFiles;
|
||||
await bundle.write({
|
||||
entryFileNames: (chunk) => {
|
||||
return inputFiles[chunk.facadeModuleId];
|
||||
},
|
||||
...this.rollupOptions.output,
|
||||
});
|
||||
await bundle.close();
|
||||
}
|
||||
}
|
||||
4
docs/src/demo.njk
Normal file
4
docs/src/demo.njk
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
layout: demo.njk
|
||||
date: Last Modified
|
||||
---
|
||||
4
docs/src/fr/demo.njk
Normal file
4
docs/src/fr/demo.njk
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
layout: demo.njk
|
||||
date: Last Modified
|
||||
---
|
||||
4
docs/src/ru/demo.njk
Normal file
4
docs/src/ru/demo.njk
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
layout: demo.njk
|
||||
date: Last Modified
|
||||
---
|
||||
|
|
@ -380,7 +380,7 @@ pre .number {
|
|||
background-color: unset;
|
||||
}
|
||||
|
||||
pre {
|
||||
pre:not(.CodeMirror-line) {
|
||||
margin-bottom: 1.5rem !important;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
@import '../../../../node_modules/@fortawesome/fontawesome-free/scss/_mixins';
|
||||
@import '../../../../node_modules/@fortawesome/fontawesome-free/scss/_core';
|
||||
@import '../../../../node_modules/@fortawesome/fontawesome-free/scss/_sizing';
|
||||
@import '../../../../node_modules/@fortawesome/fontawesome-free/scss/_animated';
|
||||
|
||||
$fa-font-path: '/static/font/fontawesome/webfonts';
|
||||
@font-face {
|
||||
|
|
@ -66,6 +67,8 @@ $icons: (
|
|||
circle-arrow-right: $fa-var-circle-arrow-right,
|
||||
globe: $fa-var-globe,
|
||||
code-commit: $fa-var-code-commit,
|
||||
spinner: $fa-var-spinner,
|
||||
circle-question: $fa-var-circle-question,
|
||||
);
|
||||
|
||||
@each $key, $value in $icons {
|
||||
|
|
|
|||
167
docs/src/static/js/editor.js
Normal file
167
docs/src/static/js/editor.js
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
import { EditorView, basicSetup } from 'codemirror';
|
||||
import { EditorState, Compartment } from '@codemirror/state';
|
||||
import { html } from '@codemirror/lang-html';
|
||||
|
||||
let session_id = 0;
|
||||
if (typeof Worker !== 'undefined') {
|
||||
console.log('creating web worker ');
|
||||
let w;
|
||||
|
||||
if (typeof w == 'undefined') {
|
||||
w = new Worker('/static/js/worker.js');
|
||||
}
|
||||
|
||||
function getConfig() {
|
||||
let config = {};
|
||||
const customBlocks = document.getElementById(
|
||||
'settings-custom-blocks',
|
||||
).value;
|
||||
if (customBlocks) config['customBlocks'] = customBlocks;
|
||||
const customHtml = document.getElementById('settings-custom-html').value;
|
||||
if (customHtml) config['customHtml'] = customHtml;
|
||||
const indent = document.getElementById('settings-indent').value;
|
||||
if (indent) config['indent'] = indent;
|
||||
const blankLineAfterTag = document.getElementById(
|
||||
'settings-blank-line-after-tag',
|
||||
).value;
|
||||
if (blankLineAfterTag) config['blankLineAfterTag'] = blankLineAfterTag;
|
||||
const blankLineBeforeTag = document.getElementById(
|
||||
'settings-blank-line-before-tag',
|
||||
).value;
|
||||
if (blankLineBeforeTag) config['blankLineBeforeTag'] = blankLineBeforeTag;
|
||||
const profile = document.getElementById('settings-profile').value;
|
||||
if (profile) config['profile'] = profile;
|
||||
const maxLineLength = document.getElementById(
|
||||
'settings-max-line-length',
|
||||
).value;
|
||||
if (maxLineLength) config['maxLineLength'] = maxLineLength;
|
||||
const maxAttributeLength = document.getElementById(
|
||||
'settings-max-attribute-length',
|
||||
).value;
|
||||
if (maxAttributeLength) config['maxAttributeLength'] = maxAttributeLength;
|
||||
const formatAttributeTemplateTags = document.getElementById(
|
||||
'settings-format-attribute-template-tags',
|
||||
).checked;
|
||||
if (formatAttributeTemplateTags)
|
||||
config['formatAttributeTemplateTags'] = formatAttributeTemplateTags;
|
||||
const preserveLeadingSpace = document.getElementById(
|
||||
'settings-preserve-leading-space',
|
||||
).checked;
|
||||
if (preserveLeadingSpace)
|
||||
config['preserveLeadingSpace'] = preserveLeadingSpace;
|
||||
const preserveBlankSpace = document.getElementById(
|
||||
'settings-preserve-blank-space',
|
||||
).checked;
|
||||
if (preserveBlankSpace) config['preserveBlankSpace'] = preserveBlankSpace;
|
||||
const formatJs = document.getElementById('settings-format-js').checked;
|
||||
if (formatJs) config['formatJs'] = formatJs;
|
||||
const formatCss = document.getElementById('settings-format-css').checked;
|
||||
if (formatCss) config['formatCss'] = formatCss;
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
const runPython = (script) => {
|
||||
session_id += 1;
|
||||
w.postMessage({
|
||||
config: getConfig(),
|
||||
html: script,
|
||||
id: session_id,
|
||||
});
|
||||
};
|
||||
|
||||
w.onmessage = (event) => {
|
||||
const { id, type, message, ...data } = event.data;
|
||||
if (type == 'status') {
|
||||
const div = document.createElement('div');
|
||||
div.innerText = message;
|
||||
const status = document.getElementById('djlint-status');
|
||||
status.insertBefore(div, status.lastElementChild);
|
||||
|
||||
if (message === 'ready') {
|
||||
document.getElementById('djlint-status').classList.add('is-hidden');
|
||||
document
|
||||
.getElementById('djlint-settings')
|
||||
.closest('.columns.is-hidden')
|
||||
.classList.remove('is-hidden');
|
||||
runPython(editor.state.doc.toString());
|
||||
}
|
||||
}
|
||||
if ((type == 'error' || type == 'html') && id == session_id) {
|
||||
setOutput(message);
|
||||
} else {
|
||||
console.log(event.data);
|
||||
}
|
||||
};
|
||||
|
||||
let timer;
|
||||
|
||||
let editor = new EditorView({
|
||||
state: EditorState.create({
|
||||
extensions: [
|
||||
basicSetup,
|
||||
html(),
|
||||
EditorView.updateListener.of((v) => {
|
||||
if (v.docChanged) {
|
||||
if (timer) clearTimeout(timer);
|
||||
timer = setTimeout(() => {
|
||||
runPython(v.state.doc.toString());
|
||||
}, 100);
|
||||
}
|
||||
}),
|
||||
],
|
||||
doc: `<div>\n <p>Welcome to djLint online!</p>\n</div>`,
|
||||
}),
|
||||
|
||||
parent: document.getElementById('djlint-input'),
|
||||
});
|
||||
|
||||
let output = new EditorView({
|
||||
state: EditorState.create({
|
||||
extensions: [basicSetup, html()],
|
||||
doc: ``,
|
||||
readonly: true,
|
||||
}),
|
||||
parent: document.getElementById('djlint-output'),
|
||||
});
|
||||
|
||||
// add pyodide returned value to the output
|
||||
function setOutput(stdout) {
|
||||
const currentValue = output.state.doc.toString();
|
||||
const endPosition = currentValue.length;
|
||||
output.dispatch({
|
||||
changes: {
|
||||
from: 0,
|
||||
to: endPosition,
|
||||
insert: stdout,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function setInput(stdout) {
|
||||
const currentValue = editor.state.doc.toString();
|
||||
const endPosition = currentValue.length;
|
||||
editor.dispatch({
|
||||
changes: {
|
||||
from: 0,
|
||||
to: endPosition,
|
||||
insert: stdout,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById('djlint-settings').addEventListener('change', () => {
|
||||
runPython(editor.state.doc.toString());
|
||||
});
|
||||
} else {
|
||||
// Sorry! No Web Worker support..
|
||||
document
|
||||
.getElementById('djlint-status')
|
||||
.innerText(
|
||||
'Sorry, a browser that supports web workers is required to use this online tool.',
|
||||
);
|
||||
}
|
||||
|
||||
// pass the editor value to the pyodide.runPython function and show the result in the output section
|
||||
|
||||
// document.getElementById("djlint-settings").addEventListener("change", () => {evaluatePython()})
|
||||
143
docs/src/static/js/worker.js
Normal file
143
docs/src/static/js/worker.js
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
importScripts('https://cdn.jsdelivr.net/pyodide/v0.21.3/full/pyodide.js');
|
||||
|
||||
function capitalize(raw_word) {
|
||||
const word = raw_word.toString();
|
||||
return word.charAt(0).toUpperCase() + word.slice(1);
|
||||
}
|
||||
|
||||
async function loadPyodideAndPackages() {
|
||||
const origin = location.origin;
|
||||
|
||||
self.pyodide = await loadPyodide();
|
||||
// build wheels with pip wheel .
|
||||
|
||||
await self.pyodide.loadPackage([
|
||||
`${origin}/static/py/djlint-99-py3-none-any.whl`,
|
||||
`${origin}/static/py/click-99-py3-none-any.whl`,
|
||||
`${origin}/static/py/colorama-99-py3-none-any.whl`,
|
||||
`${origin}/static/py/cssbeautifier-99-py3-none-any.whl`,
|
||||
`${origin}/static/py/EditorConfig-99-py3-none-any.whl`,
|
||||
`${origin}/static/py/html_tag_names-99-py3-none-any.whl`,
|
||||
`${origin}/static/py/html_void_elements-99-py3-none-any.whl`,
|
||||
`${origin}/static/py/importlib_metadata-99-py3-none-any.whl`,
|
||||
`${origin}/static/py/jsbeautifier-99-py3-none-any.whl`,
|
||||
`${origin}/static/py/pathspec-99-py3-none-any.whl`,
|
||||
`${origin}/static/py/PyYAML-99-py3-none-any.whl`,
|
||||
`${origin}/static/py/zipp-99-py3-none-any.whl`,
|
||||
]);
|
||||
|
||||
postMessage({
|
||||
type: 'status',
|
||||
message:
|
||||
'Installing djlint, click, colorama, cssbeautifier, editorconfig, html_tag_names, html_void_elements, importlib_metadata, jsbeautifier, pathspec, pyyaml, zipp ..',
|
||||
});
|
||||
await self.pyodide.loadPackage('regex');
|
||||
postMessage({ type: 'status', message: 'Installing regex..' });
|
||||
await self.pyodide.loadPackage('six');
|
||||
postMessage({ type: 'status', message: 'Installing six..' });
|
||||
await self.pyodide.loadPackage('tomli');
|
||||
postMessage({ type: 'status', message: 'Installing tomli..' });
|
||||
await self.pyodide.loadPackage('tqdm');
|
||||
postMessage({ type: 'status', message: 'Installing tqdm..' });
|
||||
|
||||
postMessage({
|
||||
type: 'status',
|
||||
message:
|
||||
'Running Python ' +
|
||||
pyodide.runPython(`
|
||||
import sys
|
||||
sys.version
|
||||
`),
|
||||
});
|
||||
|
||||
postMessage({ type: 'status', message: 'ready' });
|
||||
return pyodide;
|
||||
}
|
||||
|
||||
let pyodideReadyPromise = loadPyodideAndPackages();
|
||||
|
||||
self.onmessage = async (event) => {
|
||||
await pyodideReadyPromise;
|
||||
|
||||
const { id, config, html } = event.data;
|
||||
|
||||
const profile = config.profile ? `\n,profile="${config.profile}"` : '';
|
||||
const indent = config.indent ? `\n,indent=${config.indent}` : '';
|
||||
const preserveLeadingSpace = config.preserveLeadingSpace
|
||||
? `\n,preserve_leading_space=${capitalize(config.preserveLeadingSpace)}`
|
||||
: '';
|
||||
const preserveBlankSpace = config.preserveBlankSpace
|
||||
? `\n,preserve_blank_lines=${capitalize(config.preserveBlankSpace)}`
|
||||
: '';
|
||||
const formatJs = config.formatJs
|
||||
? `\n,format_js=${capitalize(config.formatJs)}`
|
||||
: '';
|
||||
const formatCss = config.formatCss
|
||||
? `\n,format_css=${capitalize(config.formatCss)}`
|
||||
: '';
|
||||
const customBlocks = config.customBlocks
|
||||
? `config.custom_blocks="${config.customBlocks}"`
|
||||
: '';
|
||||
const customHtml = config.customHtml
|
||||
? `config.custom_html="${config.customHtml}"`
|
||||
: '';
|
||||
const maxLineLength = config.maxLineLength
|
||||
? `config.max_line_length=${config.maxLineLength}`
|
||||
: '';
|
||||
const maxAttributeLength = config.maxAttributeLength
|
||||
? `config.max_attribute_length=${config.maxAttributeLength}`
|
||||
: '';
|
||||
const formatAttributeTemplateTags = config.formatAttributeTemplateTags
|
||||
? `config.format_attribute_template_tags=${capitalize(
|
||||
config.formatAttributeTemplateTags,
|
||||
)}`
|
||||
: '';
|
||||
const blankLineAfterTag = config.blankLineAfterTag
|
||||
? `config.blank_line_after_tag="${config.blankLineAfterTag}"`
|
||||
: '';
|
||||
const blankLineBeforeTag = config.blankLineBeforeTag
|
||||
? `config.blank_line_before_tag="${config.blankLineBeforeTag}"`
|
||||
: '';
|
||||
|
||||
try {
|
||||
await self.pyodide.runPythonAsync(`
|
||||
import io
|
||||
import os
|
||||
sys.modules['_multiprocessing'] = object
|
||||
from multiprocessing.pool import ThreadPool
|
||||
sys.stdout = io.StringIO()
|
||||
|
||||
from pathlib import Path
|
||||
from djlint.reformat import reformat_file
|
||||
from djlint.settings import Config
|
||||
import tempfile
|
||||
|
||||
`);
|
||||
await self.pyodide.runPythonAsync('sys.stdout.flush()');
|
||||
|
||||
await pyodide.runPythonAsync(`
|
||||
temp_file = tempfile.NamedTemporaryFile(delete=False)
|
||||
temp_file.write(str.encode("""${html}"""))
|
||||
temp_file.seek(0)
|
||||
config = Config(
|
||||
temp_file.name${indent}${profile}${preserveLeadingSpace}${preserveBlankSpace}${formatJs}${formatCss}
|
||||
)
|
||||
${customBlocks}
|
||||
${customHtml}
|
||||
${maxLineLength}
|
||||
${maxAttributeLength}
|
||||
${formatAttributeTemplateTags}
|
||||
${blankLineAfterTag}
|
||||
${blankLineBeforeTag}
|
||||
print(Path(list(reformat_file(config, Path(temp_file.name)).keys())[0]).read_text().rstrip())
|
||||
temp_file.close()
|
||||
os.unlink(temp_file.name)
|
||||
`);
|
||||
|
||||
let stdout = await self.pyodide.runPythonAsync('sys.stdout.getvalue()');
|
||||
await self.pyodide.runPythonAsync('sys.stdout.flush()');
|
||||
postMessage({ type: 'html', message: stdout, id: id });
|
||||
} catch (err) {
|
||||
self.postMessage({ type: 'error', message: err.message, id: id });
|
||||
}
|
||||
};
|
||||
BIN
docs/src/static/py/EditorConfig-99-py3-none-any.whl
Normal file
BIN
docs/src/static/py/EditorConfig-99-py3-none-any.whl
Normal file
Binary file not shown.
BIN
docs/src/static/py/PyYAML-99-py3-none-any.whl
Normal file
BIN
docs/src/static/py/PyYAML-99-py3-none-any.whl
Normal file
Binary file not shown.
BIN
docs/src/static/py/click-99-py3-none-any.whl
Normal file
BIN
docs/src/static/py/click-99-py3-none-any.whl
Normal file
Binary file not shown.
BIN
docs/src/static/py/colorama-99-py3-none-any.whl
Normal file
BIN
docs/src/static/py/colorama-99-py3-none-any.whl
Normal file
Binary file not shown.
BIN
docs/src/static/py/cssbeautifier-99-py3-none-any.whl
Normal file
BIN
docs/src/static/py/cssbeautifier-99-py3-none-any.whl
Normal file
Binary file not shown.
BIN
docs/src/static/py/djlint-99-py3-none-any.whl
Normal file
BIN
docs/src/static/py/djlint-99-py3-none-any.whl
Normal file
Binary file not shown.
BIN
docs/src/static/py/html_tag_names-99-py3-none-any.whl
Normal file
BIN
docs/src/static/py/html_tag_names-99-py3-none-any.whl
Normal file
Binary file not shown.
BIN
docs/src/static/py/html_void_elements-99-py3-none-any.whl
Normal file
BIN
docs/src/static/py/html_void_elements-99-py3-none-any.whl
Normal file
Binary file not shown.
BIN
docs/src/static/py/importlib_metadata-99-py3-none-any.whl
Normal file
BIN
docs/src/static/py/importlib_metadata-99-py3-none-any.whl
Normal file
Binary file not shown.
BIN
docs/src/static/py/jsbeautifier-99-py3-none-any.whl
Normal file
BIN
docs/src/static/py/jsbeautifier-99-py3-none-any.whl
Normal file
Binary file not shown.
BIN
docs/src/static/py/pathspec-99-py3-none-any.whl
Normal file
BIN
docs/src/static/py/pathspec-99-py3-none-any.whl
Normal file
Binary file not shown.
Binary file not shown.
BIN
docs/src/static/py/six-1.16.0-py2.py3-none-any.whl
Normal file
BIN
docs/src/static/py/six-1.16.0-py2.py3-none-any.whl
Normal file
Binary file not shown.
BIN
docs/src/static/py/tomli-2.0.1-py3-none-any.whl
Normal file
BIN
docs/src/static/py/tomli-2.0.1-py3-none-any.whl
Normal file
Binary file not shown.
BIN
docs/src/static/py/tqdm-4.64.1-py2.py3-none-any.whl
Normal file
BIN
docs/src/static/py/tqdm-4.64.1-py2.py3-none-any.whl
Normal file
Binary file not shown.
BIN
docs/src/static/py/zipp-99-py3-none-any.whl
Normal file
BIN
docs/src/static/py/zipp-99-py3-none-any.whl
Normal file
Binary file not shown.
1453
package-lock.json
generated
1453
package-lock.json
generated
File diff suppressed because it is too large
Load diff
10
package.json
10
package.json
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "djlint",
|
||||
"version": "1.19.4",
|
||||
"version": "1.19.12",
|
||||
"description": "HTML Template Linter and Formatter",
|
||||
"main": "./bin/index.js",
|
||||
"directories": {
|
||||
|
|
@ -56,17 +56,17 @@
|
|||
"yargs": "17.6.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@semantic-release/changelog": "6.0.1",
|
||||
"@semantic-release/changelog": "6.0.2",
|
||||
"@semantic-release/commit-analyzer": "9.0.2",
|
||||
"@semantic-release/exec": "6.0.3",
|
||||
"@semantic-release/git": "10.0.1",
|
||||
"@semantic-release/github": "8.0.6",
|
||||
"@semantic-release/github": "8.0.7",
|
||||
"@semantic-release/npm": "9.0.1",
|
||||
"@semantic-release/release-notes-generator": "10.0.3",
|
||||
"cz-conventional-changelog": "3.3.0",
|
||||
"lint-staged": "13.0.3",
|
||||
"lint-staged": "13.1.0",
|
||||
"semantic-release": "19.0.5",
|
||||
"xo": "0.52.4"
|
||||
"xo": "0.53.1"
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
|
|
|
|||
1336
poetry.lock
generated
1336
poetry.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -7,7 +7,7 @@ build-backend = "poetry.core.masonry.api"
|
|||
|
||||
[tool.poetry]
|
||||
name="djlint"
|
||||
version="1.19.4"
|
||||
version="1.19.7"
|
||||
description="HTML Template Linter and Formatter"
|
||||
license="GPL-3.0-or-later"
|
||||
authors=["Christopher Pickering <cpickering@rhc.net>"]
|
||||
|
|
@ -48,10 +48,10 @@ pytest = "^7.1.2"
|
|||
pytest-cov = "^4.0.0"
|
||||
pytest-xdist = "^3.0.0"
|
||||
pylint = "^2.14.5"
|
||||
mypy = "^0.982"
|
||||
mypy = "^0.991"
|
||||
types-PyYAML = "^6.0.11"
|
||||
pep8-naming = "^0.13.1"
|
||||
tox = "^3.25.1"
|
||||
tox = "^4.0.0"
|
||||
|
||||
[tool.poetry.scripts]
|
||||
djlint = "djlint:main"
|
||||
|
|
|
|||
|
|
@ -135,14 +135,14 @@
|
|||
message: (Django) Internal links should use the {% url ... %} pattern.
|
||||
flags: re.DOTALL|re.I
|
||||
patterns:
|
||||
- <(?:a|div|span|input)\b[^>]*?\s(?:href|data-url|data-src|action)=[\"|'](?!(?:https?://)|javascript:|on\w+:|mailto:|tel:)[\w|/]+
|
||||
- <(?:a|div|span|input)\b[^>]*?\s(?:href|data-url|data-src|action)=[\"|'](?!(?:https?://)|javascript:|on\w+:|mailto:|tel:|data:)[\w|/]+
|
||||
- <form\s+?[^>]*?(?:action)=[\"|'](?!(?:https?://)|javascript:|on\w+:|mailto:|tel:)[\w|/]+
|
||||
- rule:
|
||||
name: J018
|
||||
message: (Jinja) Internal links should use the {{ url_for() ... }} pattern.
|
||||
flags: re.DOTALL|re.I
|
||||
patterns:
|
||||
- <(?:a|div|span|input)\b[^>]*?\s(?:href|data-url|data-src|action)=[\"|'](?!(?:https?://)|javascript:|on\w+:|mailto:|tel:)[\w|/]+
|
||||
- <(?:a|div|span|input)\b[^>]*?\s(?:href|data-url|data-src|action)=[\"|'](?!(?:https?://)|javascript:|on\w+:|mailto:|tel:|data:)[\w|/]+
|
||||
- <form\s+?[^>]*?(?:action)=[\"|'](?!(?:https?://)|javascript:|on\w+:|mailto:|tel:)[\w|/]+
|
||||
- rule:
|
||||
name: H019
|
||||
|
|
|
|||
|
|
@ -417,13 +417,29 @@ def test_DJ018(runner: CliRunner, tmp_file: TextIO) -> None:
|
|||
result = runner.invoke(djlint, [tmp_file.name, "--profile", "jinja"])
|
||||
assert "J018 1:" in result.output
|
||||
|
||||
# test mailto:
|
||||
# test mailto:, tel:
|
||||
write_to_file(
|
||||
tmp_file.name,
|
||||
b'<a href="mailto:joe"></a><a href="tel:joe"></a>',
|
||||
)
|
||||
result = runner.invoke(djlint, [tmp_file.name])
|
||||
result = runner.invoke(djlint, [tmp_file.name, "--profile", "django"])
|
||||
assert result.exit_code == 0
|
||||
assert "D018" not in result.output
|
||||
result = runner.invoke(djlint, [tmp_file.name, "--profile", "jinja"])
|
||||
assert result.exit_code == 0
|
||||
assert "J018" not in result.output
|
||||
|
||||
# test data:
|
||||
write_to_file(
|
||||
tmp_file.name,
|
||||
b'<a href="data:,Hello%2C%20World%21"></a>',
|
||||
)
|
||||
result = runner.invoke(djlint, [tmp_file.name, "--profile", "django"])
|
||||
assert result.exit_code == 0
|
||||
assert "D018" not in result.output
|
||||
result = runner.invoke(djlint, [tmp_file.name, "--profile", "jinja"])
|
||||
assert result.exit_code == 0
|
||||
assert "J018" not in result.output
|
||||
|
||||
# test attribute names
|
||||
write_to_file(
|
||||
|
|
|
|||
Loading…
Reference in a new issue