django-tiptap-editor 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- django_tiptap_editor-0.1.0/.github/workflows/release.yml +96 -0
- django_tiptap_editor-0.1.0/.github/workflows/tests.yml +249 -0
- django_tiptap_editor-0.1.0/.gitignore +87 -0
- django_tiptap_editor-0.1.0/.pre-commit-config.yaml +38 -0
- django_tiptap_editor-0.1.0/CHANGELOG.md +39 -0
- django_tiptap_editor-0.1.0/CLAUDE.md +218 -0
- django_tiptap_editor-0.1.0/LICENSE +21 -0
- django_tiptap_editor-0.1.0/Makefile +101 -0
- django_tiptap_editor-0.1.0/PKG-INFO +117 -0
- django_tiptap_editor-0.1.0/README.md +81 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/__init__.py +25 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/admin/__init__.py +7 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/admin/mixin.py +30 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/apps.py +11 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/constants.py +113 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/forms/__init__.py +7 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/forms/fields.py +13 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/py.typed +0 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/static/django_tiptap_editor/tiptap.bundle.css +1 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/static/django_tiptap_editor/tiptap.bundle.js +97 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/static/django_tiptap_editor/tiptap.glue.esm.css +1 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/static/django_tiptap_editor/tiptap.glue.esm.js +1 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/templatetags/__init__.py +0 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/templatetags/tiptap.py +62 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/utils/__init__.py +17 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/utils/get_asset_mode.py +21 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/utils/get_default_config.py +18 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/utils/get_extra_extensions.py +15 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/utils/get_import_map.py +28 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/utils/validate_config.py +36 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/version.py +5 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/views/__init__.py +8 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/views/base_image_upload_view.py +37 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/views/image_upload_error.py +7 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/widgets/__init__.py +8 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/widgets/admin_tiptap.py +23 -0
- django_tiptap_editor-0.1.0/django_tiptap_editor/widgets/tiptap_widget.py +47 -0
- django_tiptap_editor-0.1.0/docs/api.md +89 -0
- django_tiptap_editor-0.1.0/docs/asset-modes.md +54 -0
- django_tiptap_editor-0.1.0/docs/configuration.md +57 -0
- django_tiptap_editor-0.1.0/docs/contracts.md +61 -0
- django_tiptap_editor-0.1.0/docs/extending.md +72 -0
- django_tiptap_editor-0.1.0/docs/index.md +31 -0
- django_tiptap_editor-0.1.0/docs/installation.md +35 -0
- django_tiptap_editor-0.1.0/docs/quickstart.md +62 -0
- django_tiptap_editor-0.1.0/docs/recipes/migrating-from-tinymce.md +62 -0
- django_tiptap_editor-0.1.0/docs/recipes/preview.md +25 -0
- django_tiptap_editor-0.1.0/docs/security.md +34 -0
- django_tiptap_editor-0.1.0/docs/semver.md +33 -0
- django_tiptap_editor-0.1.0/docs/theming.md +49 -0
- django_tiptap_editor-0.1.0/js/esbuild.config.mjs +57 -0
- django_tiptap_editor-0.1.0/js/package-lock.json +3609 -0
- django_tiptap_editor-0.1.0/js/package.json +36 -0
- django_tiptap_editor-0.1.0/js/src/build-extensions.ts +134 -0
- django_tiptap_editor-0.1.0/js/src/default-config.ts +69 -0
- django_tiptap_editor-0.1.0/js/src/editor-config.ts +15 -0
- django_tiptap_editor-0.1.0/js/src/extensions/background-color.ts +30 -0
- django_tiptap_editor-0.1.0/js/src/extensions/block-style.ts +42 -0
- django_tiptap_editor-0.1.0/js/src/extensions/font-size.ts +26 -0
- django_tiptap_editor-0.1.0/js/src/extensions/inline-image.ts +31 -0
- django_tiptap_editor-0.1.0/js/src/globals.d.ts +3 -0
- django_tiptap_editor-0.1.0/js/src/i18n.ts +132 -0
- django_tiptap_editor-0.1.0/js/src/image-picker.ts +94 -0
- django_tiptap_editor-0.1.0/js/src/index.ts +158 -0
- django_tiptap_editor-0.1.0/js/src/registry.ts +27 -0
- django_tiptap_editor-0.1.0/js/src/styles.css +356 -0
- django_tiptap_editor-0.1.0/js/src/tiptap-runtime.ts +31 -0
- django_tiptap_editor-0.1.0/js/src/toolbar/built-in-buttons.ts +257 -0
- django_tiptap_editor-0.1.0/js/src/toolbar/button-registry.ts +34 -0
- django_tiptap_editor-0.1.0/js/src/toolbar/controls.ts +163 -0
- django_tiptap_editor-0.1.0/js/src/toolbar/dropdown.ts +84 -0
- django_tiptap_editor-0.1.0/js/src/toolbar/icons.ts +46 -0
- django_tiptap_editor-0.1.0/js/src/toolbar/render-toolbar.ts +98 -0
- django_tiptap_editor-0.1.0/js/src/toolbar/source-view.ts +78 -0
- django_tiptap_editor-0.1.0/js/src/ui.ts +20 -0
- django_tiptap_editor-0.1.0/js/src/upload.ts +104 -0
- django_tiptap_editor-0.1.0/js/src/version-check.ts +29 -0
- django_tiptap_editor-0.1.0/js/test/canonical.ts +119 -0
- django_tiptap_editor-0.1.0/js/test/fidelity.test.ts +59 -0
- django_tiptap_editor-0.1.0/js/test/fixtures/tinymce-corpus.json +245 -0
- django_tiptap_editor-0.1.0/js/tsconfig.json +16 -0
- django_tiptap_editor-0.1.0/js/vitest.config.ts +8 -0
- django_tiptap_editor-0.1.0/mkdocs.yml +88 -0
- django_tiptap_editor-0.1.0/pyproject.toml +139 -0
- django_tiptap_editor-0.1.0/scripts/release-publish.sh +211 -0
- django_tiptap_editor-0.1.0/tests/__init__.py +0 -0
- django_tiptap_editor-0.1.0/tests/admin/__init__.py +0 -0
- django_tiptap_editor-0.1.0/tests/admin/test_mixin.py +52 -0
- django_tiptap_editor-0.1.0/tests/conftest.py +0 -0
- django_tiptap_editor-0.1.0/tests/conftest_settings.py +36 -0
- django_tiptap_editor-0.1.0/tests/forms/__init__.py +0 -0
- django_tiptap_editor-0.1.0/tests/forms/test_fields.py +8 -0
- django_tiptap_editor-0.1.0/tests/templatetags/__init__.py +0 -0
- django_tiptap_editor-0.1.0/tests/templatetags/test_tiptap.py +31 -0
- django_tiptap_editor-0.1.0/tests/test_public_api.py +17 -0
- django_tiptap_editor-0.1.0/tests/test_version.py +13 -0
- django_tiptap_editor-0.1.0/tests/testapp/__init__.py +0 -0
- django_tiptap_editor-0.1.0/tests/testapp/models.py +12 -0
- django_tiptap_editor-0.1.0/tests/utils/__init__.py +0 -0
- django_tiptap_editor-0.1.0/tests/utils/test_get_asset_mode.py +22 -0
- django_tiptap_editor-0.1.0/tests/utils/test_get_default_config.py +14 -0
- django_tiptap_editor-0.1.0/tests/utils/test_get_extra_extensions.py +14 -0
- django_tiptap_editor-0.1.0/tests/utils/test_get_import_map.py +26 -0
- django_tiptap_editor-0.1.0/tests/utils/test_validate_config.py +31 -0
- django_tiptap_editor-0.1.0/tests/views/__init__.py +0 -0
- django_tiptap_editor-0.1.0/tests/views/test_base_image_upload_view.py +46 -0
- django_tiptap_editor-0.1.0/tests/widgets/__init__.py +0 -0
- django_tiptap_editor-0.1.0/tests/widgets/test_admin_tiptap.py +12 -0
- django_tiptap_editor-0.1.0/tests/widgets/test_tiptap_widget.py +35 -0
- django_tiptap_editor-0.1.0/uv.lock +1207 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
name: release
|
|
2
|
+
|
|
3
|
+
# Main-triggered: every merge to `main` runs `release-publish-prepare`, which
|
|
4
|
+
# short-circuits to a no-op unless the version in source has been bumped past
|
|
5
|
+
# the most recent `vX.Y.Z` tag. `make release-bump` + merge to main is the
|
|
6
|
+
# only release path.
|
|
7
|
+
on:
|
|
8
|
+
push:
|
|
9
|
+
branches: [main]
|
|
10
|
+
|
|
11
|
+
concurrency:
|
|
12
|
+
group: release-main
|
|
13
|
+
cancel-in-progress: false
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
release:
|
|
17
|
+
name: release
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
environment:
|
|
20
|
+
name: pypi
|
|
21
|
+
url: https://pypi.org/p/django-tiptap-editor
|
|
22
|
+
permissions:
|
|
23
|
+
id-token: write # PyPI OIDC trusted publishing
|
|
24
|
+
contents: write # tag push + gh release create
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v5
|
|
27
|
+
with:
|
|
28
|
+
fetch-depth: 0
|
|
29
|
+
- uses: astral-sh/setup-uv@v7
|
|
30
|
+
with:
|
|
31
|
+
enable-cache: true
|
|
32
|
+
- name: Install
|
|
33
|
+
run: uv sync --all-groups
|
|
34
|
+
|
|
35
|
+
- name: Prepare release (version check, test, build dist)
|
|
36
|
+
id: prepare
|
|
37
|
+
run: make release-publish-prepare
|
|
38
|
+
|
|
39
|
+
- name: Publish to PyPI
|
|
40
|
+
if: steps.prepare.outputs.released == 'true'
|
|
41
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
42
|
+
|
|
43
|
+
- name: Tag + GitHub Release
|
|
44
|
+
if: steps.prepare.outputs.released == 'true'
|
|
45
|
+
env:
|
|
46
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
47
|
+
run: make release-publish-finalize
|
|
48
|
+
|
|
49
|
+
# On release commits we own the single gh-pages push: embed the
|
|
50
|
+
# coverage badge JSON into the docs build so mkdocs gh-deploy carries
|
|
51
|
+
# it alongside the site, and tests.yml's coverage-badge job
|
|
52
|
+
# short-circuits to avoid a second push (and a second built-in
|
|
53
|
+
# "pages build and deployment" run).
|
|
54
|
+
- name: Render coverage badge for the docs site
|
|
55
|
+
if: steps.prepare.outputs.released == 'true' && hashFiles('mkdocs.yml') != ''
|
|
56
|
+
run: |
|
|
57
|
+
set -euo pipefail
|
|
58
|
+
# release-publish-prepare's pytest run wrote .coverage to the
|
|
59
|
+
# workspace root; convert to coverage.xml so the same parser
|
|
60
|
+
# we use in tests.yml can score it.
|
|
61
|
+
uv run coverage xml -o coverage.xml
|
|
62
|
+
python - <<'PY'
|
|
63
|
+
import json
|
|
64
|
+
import xml.etree.ElementTree as ET
|
|
65
|
+
|
|
66
|
+
tree = ET.parse("coverage.xml")
|
|
67
|
+
pct = round(float(tree.getroot().attrib["line-rate"]) * 100, 1)
|
|
68
|
+
if pct >= 95:
|
|
69
|
+
color = "brightgreen"
|
|
70
|
+
elif pct >= 85:
|
|
71
|
+
color = "green"
|
|
72
|
+
elif pct >= 70:
|
|
73
|
+
color = "yellow"
|
|
74
|
+
else:
|
|
75
|
+
color = "red"
|
|
76
|
+
payload = {
|
|
77
|
+
"schemaVersion": 1,
|
|
78
|
+
"label": "coverage",
|
|
79
|
+
"message": f"{pct}%",
|
|
80
|
+
"color": color,
|
|
81
|
+
}
|
|
82
|
+
# docs/ is mkdocs' source dir; non-.md files are copied verbatim
|
|
83
|
+
# into site/, which lands at the gh-pages root after gh-deploy.
|
|
84
|
+
with open("docs/coverage.json", "w") as fh:
|
|
85
|
+
json.dump(payload, fh)
|
|
86
|
+
fh.write("\n")
|
|
87
|
+
print(json.dumps(payload))
|
|
88
|
+
PY
|
|
89
|
+
|
|
90
|
+
- name: Deploy docs + coverage badge to gh-pages
|
|
91
|
+
if: steps.prepare.outputs.released == 'true' && hashFiles('mkdocs.yml') != ''
|
|
92
|
+
run: |
|
|
93
|
+
git config user.name 'github-actions[bot]'
|
|
94
|
+
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
|
|
95
|
+
DJANGO_SETTINGS_MODULE=tests.conftest_settings \
|
|
96
|
+
uv run mkdocs gh-deploy --force --clean --config-file mkdocs.yml
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
name: tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
concurrency:
|
|
9
|
+
group: tests-${{ github.ref }}
|
|
10
|
+
cancel-in-progress: true
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
lint:
|
|
14
|
+
name: lint
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v5
|
|
18
|
+
- uses: astral-sh/setup-uv@v7
|
|
19
|
+
with:
|
|
20
|
+
enable-cache: true
|
|
21
|
+
- name: Install
|
|
22
|
+
run: uv sync --all-groups
|
|
23
|
+
- name: ruff check
|
|
24
|
+
run: uv run ruff check .
|
|
25
|
+
- name: ruff format check
|
|
26
|
+
run: uv run ruff format --check --diff .
|
|
27
|
+
- name: ty
|
|
28
|
+
run: uv run ty check django_tiptap_editor
|
|
29
|
+
|
|
30
|
+
docs:
|
|
31
|
+
name: docs build
|
|
32
|
+
runs-on: ubuntu-latest
|
|
33
|
+
steps:
|
|
34
|
+
- uses: actions/checkout@v5
|
|
35
|
+
- uses: astral-sh/setup-uv@v7
|
|
36
|
+
with:
|
|
37
|
+
enable-cache: true
|
|
38
|
+
- name: Install with docs group
|
|
39
|
+
run: uv sync --all-groups
|
|
40
|
+
- name: mkdocs build --strict
|
|
41
|
+
# mkdocstrings imports the package, which transitively imports Django;
|
|
42
|
+
# Django reads settings at import time, so we point at the test
|
|
43
|
+
# settings module to keep the build hermetic.
|
|
44
|
+
run: DJANGO_SETTINGS_MODULE=tests.conftest_settings uv run mkdocs build --strict
|
|
45
|
+
|
|
46
|
+
js-build:
|
|
47
|
+
name: js (typecheck + tests + fresh artifacts)
|
|
48
|
+
runs-on: ubuntu-latest
|
|
49
|
+
steps:
|
|
50
|
+
- uses: actions/checkout@v5
|
|
51
|
+
- uses: actions/setup-node@v4
|
|
52
|
+
with:
|
|
53
|
+
node-version: "22"
|
|
54
|
+
- name: Install (npm ci — pinned lockfile)
|
|
55
|
+
working-directory: js
|
|
56
|
+
run: npm ci
|
|
57
|
+
- name: typecheck
|
|
58
|
+
working-directory: js
|
|
59
|
+
run: npm run typecheck
|
|
60
|
+
- name: unit tests (corpus round-trip fidelity)
|
|
61
|
+
working-directory: js
|
|
62
|
+
run: npm test
|
|
63
|
+
- name: Rebuild bundles
|
|
64
|
+
working-directory: js
|
|
65
|
+
run: npm run build
|
|
66
|
+
- name: Fail if committed artifacts are stale
|
|
67
|
+
run: |
|
|
68
|
+
if ! git diff --quiet -- django_tiptap_editor/static; then
|
|
69
|
+
echo "::error::Committed JS artifacts are stale — run 'make build-js' and commit the result."
|
|
70
|
+
git --no-pager diff --stat -- django_tiptap_editor/static
|
|
71
|
+
exit 1
|
|
72
|
+
fi
|
|
73
|
+
echo "Committed JS artifacts are up to date."
|
|
74
|
+
|
|
75
|
+
test:
|
|
76
|
+
name: ${{ matrix.python-version }} / Django ${{ matrix.django-version }}
|
|
77
|
+
runs-on: ubuntu-latest
|
|
78
|
+
strategy:
|
|
79
|
+
fail-fast: false
|
|
80
|
+
matrix:
|
|
81
|
+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
|
|
82
|
+
django-version: ["4.2", "5.0", "5.1", "5.2", "6.0"]
|
|
83
|
+
exclude:
|
|
84
|
+
# Django 4.2 supports Python 3.8–3.12
|
|
85
|
+
- python-version: "3.13"
|
|
86
|
+
django-version: "4.2"
|
|
87
|
+
- python-version: "3.14"
|
|
88
|
+
django-version: "4.2"
|
|
89
|
+
# Django 5.0 supports Python 3.10–3.12
|
|
90
|
+
- python-version: "3.13"
|
|
91
|
+
django-version: "5.0"
|
|
92
|
+
- python-version: "3.14"
|
|
93
|
+
django-version: "5.0"
|
|
94
|
+
# Django 5.1 supports Python 3.10–3.13
|
|
95
|
+
- python-version: "3.14"
|
|
96
|
+
django-version: "5.1"
|
|
97
|
+
# Django 6.0 requires Python 3.12+
|
|
98
|
+
- python-version: "3.10"
|
|
99
|
+
django-version: "6.0"
|
|
100
|
+
- python-version: "3.11"
|
|
101
|
+
django-version: "6.0"
|
|
102
|
+
|
|
103
|
+
steps:
|
|
104
|
+
- uses: actions/checkout@v5
|
|
105
|
+
- uses: astral-sh/setup-uv@v7
|
|
106
|
+
with:
|
|
107
|
+
enable-cache: true
|
|
108
|
+
- name: Install Python ${{ matrix.python-version }}
|
|
109
|
+
run: uv python install ${{ matrix.python-version }}
|
|
110
|
+
- name: Sync dev deps
|
|
111
|
+
run: uv sync --all-groups --python ${{ matrix.python-version }}
|
|
112
|
+
- name: Pin Django ${{ matrix.django-version }}
|
|
113
|
+
run: uv pip install --reinstall-package django "django~=${{ matrix.django-version }}.0"
|
|
114
|
+
- name: pytest
|
|
115
|
+
run: |
|
|
116
|
+
uv run --no-sync pytest \
|
|
117
|
+
--cov-report=xml:coverage.xml \
|
|
118
|
+
--cov-report=html:htmlcov
|
|
119
|
+
- name: Upload coverage artifact
|
|
120
|
+
if: always()
|
|
121
|
+
uses: actions/upload-artifact@v5
|
|
122
|
+
with:
|
|
123
|
+
name: coverage-py${{ matrix.python-version }}-django${{ matrix.django-version }}
|
|
124
|
+
path: |
|
|
125
|
+
coverage.xml
|
|
126
|
+
htmlcov/
|
|
127
|
+
if-no-files-found: ignore
|
|
128
|
+
|
|
129
|
+
coverage-badge:
|
|
130
|
+
name: coverage badge
|
|
131
|
+
needs: test
|
|
132
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
133
|
+
runs-on: ubuntu-latest
|
|
134
|
+
permissions:
|
|
135
|
+
contents: write
|
|
136
|
+
steps:
|
|
137
|
+
- uses: actions/checkout@v5
|
|
138
|
+
with:
|
|
139
|
+
# Need the parent commit so the gate step below can diff
|
|
140
|
+
# version.py against ${{ github.event.before }}. The default
|
|
141
|
+
# shallow checkout (depth 1) would make `git show "$before:…"`
|
|
142
|
+
# fail with exit 128 and turn the whole job red.
|
|
143
|
+
fetch-depth: 2
|
|
144
|
+
# release.yml runs in parallel on the same push and owns gh-pages
|
|
145
|
+
# publishing on release commits (it bundles coverage.json into the
|
|
146
|
+
# mkdocs gh-deploy). If we also push here we get a second built-in
|
|
147
|
+
# "pages build and deployment" run that the first one cancels. The
|
|
148
|
+
# version-diff against ${{ github.event.before }} is the reliable
|
|
149
|
+
# signal — release.yml's tag isn't pushed until after PyPI publish,
|
|
150
|
+
# so a tag-existence check would race.
|
|
151
|
+
- name: Skip when release.yml owns this push
|
|
152
|
+
id: gate
|
|
153
|
+
run: |
|
|
154
|
+
set -euo pipefail
|
|
155
|
+
before="${{ github.event.before }}"
|
|
156
|
+
if [[ -z "$before" || "$before" =~ ^0+$ ]]; then
|
|
157
|
+
# First push to main on a brand-new repo — no prior state to diff.
|
|
158
|
+
echo "skip=false" >> "$GITHUB_OUTPUT"
|
|
159
|
+
exit 0
|
|
160
|
+
fi
|
|
161
|
+
# `before` may not be in the local object DB if the push
|
|
162
|
+
# contained more than one commit (fetch-depth: 2 only guarantees
|
|
163
|
+
# HEAD + 1 parent). Try to fetch just that commit; if it's not
|
|
164
|
+
# reachable, fall back to "don't skip" — better to double-push
|
|
165
|
+
# to gh-pages once than to turn the pipeline red.
|
|
166
|
+
if ! git cat-file -e "$before^{commit}" 2>/dev/null; then
|
|
167
|
+
git fetch --depth=1 origin "$before" 2>/dev/null || true
|
|
168
|
+
fi
|
|
169
|
+
old=""
|
|
170
|
+
if git cat-file -e "$before:django_tiptap_editor/version.py" 2>/dev/null; then
|
|
171
|
+
old="$(git show "$before:django_tiptap_editor/version.py" \
|
|
172
|
+
| awk -F'"' '/^__version__/ { print $2; exit }')"
|
|
173
|
+
fi
|
|
174
|
+
new="$(awk -F'"' '/^__version__/ { print $2; exit }' \
|
|
175
|
+
django_tiptap_editor/version.py)"
|
|
176
|
+
if [[ -n "$old" && "$old" != "$new" ]]; then
|
|
177
|
+
echo "Version bumped $old → $new; release.yml will deploy gh-pages."
|
|
178
|
+
echo "skip=true" >> "$GITHUB_OUTPUT"
|
|
179
|
+
else
|
|
180
|
+
echo "skip=false" >> "$GITHUB_OUTPUT"
|
|
181
|
+
fi
|
|
182
|
+
- name: Download canonical coverage artifact
|
|
183
|
+
if: steps.gate.outputs.skip != 'true'
|
|
184
|
+
uses: actions/download-artifact@v5
|
|
185
|
+
with:
|
|
186
|
+
name: coverage-py3.13-django5.2
|
|
187
|
+
path: coverage-artifact/
|
|
188
|
+
- name: Render coverage.json
|
|
189
|
+
if: steps.gate.outputs.skip != 'true'
|
|
190
|
+
run: |
|
|
191
|
+
python - <<'PY'
|
|
192
|
+
import json
|
|
193
|
+
import xml.etree.ElementTree as ET
|
|
194
|
+
|
|
195
|
+
tree = ET.parse("coverage-artifact/coverage.xml")
|
|
196
|
+
pct = round(float(tree.getroot().attrib["line-rate"]) * 100, 1)
|
|
197
|
+
if pct >= 95:
|
|
198
|
+
color = "brightgreen"
|
|
199
|
+
elif pct >= 85:
|
|
200
|
+
color = "green"
|
|
201
|
+
elif pct >= 70:
|
|
202
|
+
color = "yellow"
|
|
203
|
+
else:
|
|
204
|
+
color = "red"
|
|
205
|
+
payload = {
|
|
206
|
+
"schemaVersion": 1,
|
|
207
|
+
"label": "coverage",
|
|
208
|
+
"message": f"{pct}%",
|
|
209
|
+
"color": color,
|
|
210
|
+
}
|
|
211
|
+
with open("coverage.json", "w") as fh:
|
|
212
|
+
json.dump(payload, fh)
|
|
213
|
+
fh.write("\n")
|
|
214
|
+
print(json.dumps(payload))
|
|
215
|
+
PY
|
|
216
|
+
- name: Publish coverage.json to gh-pages
|
|
217
|
+
if: steps.gate.outputs.skip != 'true'
|
|
218
|
+
env:
|
|
219
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
220
|
+
run: |
|
|
221
|
+
set -euo pipefail
|
|
222
|
+
git config user.name 'github-actions[bot]'
|
|
223
|
+
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
|
|
224
|
+
|
|
225
|
+
tmp="$(mktemp -d)"
|
|
226
|
+
cp coverage.json "$tmp/coverage.json"
|
|
227
|
+
|
|
228
|
+
git fetch origin gh-pages --depth=1 2>/dev/null || true
|
|
229
|
+
if git rev-parse --verify origin/gh-pages >/dev/null 2>&1; then
|
|
230
|
+
git worktree add gh-pages origin/gh-pages
|
|
231
|
+
cp "$tmp/coverage.json" gh-pages/coverage.json
|
|
232
|
+
cd gh-pages
|
|
233
|
+
if [[ -n "$(git status --porcelain coverage.json)" ]]; then
|
|
234
|
+
git add coverage.json
|
|
235
|
+
git commit -m "coverage badge: update from ${GITHUB_SHA::7}"
|
|
236
|
+
git push origin HEAD:gh-pages
|
|
237
|
+
else
|
|
238
|
+
echo "coverage.json unchanged, skipping push"
|
|
239
|
+
fi
|
|
240
|
+
else
|
|
241
|
+
git worktree add --detach gh-pages
|
|
242
|
+
cd gh-pages
|
|
243
|
+
git checkout --orphan gh-pages
|
|
244
|
+
git rm -rf . >/dev/null 2>&1 || true
|
|
245
|
+
cp "$tmp/coverage.json" coverage.json
|
|
246
|
+
git add coverage.json
|
|
247
|
+
git commit -m "coverage badge: initial publish from ${GITHUB_SHA::7}"
|
|
248
|
+
git push origin gh-pages
|
|
249
|
+
fi
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
|
|
7
|
+
# Distribution / packaging
|
|
8
|
+
build/
|
|
9
|
+
develop-eggs/
|
|
10
|
+
dist/
|
|
11
|
+
downloads/
|
|
12
|
+
eggs/
|
|
13
|
+
.eggs/
|
|
14
|
+
parts/
|
|
15
|
+
sdist/
|
|
16
|
+
wheels/
|
|
17
|
+
share/python-wheels/
|
|
18
|
+
*.egg-info/
|
|
19
|
+
.installed.cfg
|
|
20
|
+
*.egg
|
|
21
|
+
MANIFEST
|
|
22
|
+
.release-metadata/
|
|
23
|
+
|
|
24
|
+
# Unit test / coverage reports
|
|
25
|
+
htmlcov/
|
|
26
|
+
.tox/
|
|
27
|
+
.nox/
|
|
28
|
+
.coverage
|
|
29
|
+
.coverage.*
|
|
30
|
+
.cache
|
|
31
|
+
nosetests.xml
|
|
32
|
+
coverage.xml
|
|
33
|
+
*.cover
|
|
34
|
+
*.py,cover
|
|
35
|
+
.hypothesis/
|
|
36
|
+
.pytest_cache/
|
|
37
|
+
cover/
|
|
38
|
+
|
|
39
|
+
# release.yml renders this at workflow-time and drops it under docs/ so
|
|
40
|
+
# mkdocs gh-deploy carries it to the gh-pages root alongside the docs site.
|
|
41
|
+
# Not a source artifact — keep it out of the working tree.
|
|
42
|
+
docs/coverage.json
|
|
43
|
+
|
|
44
|
+
# Translations
|
|
45
|
+
*.mo
|
|
46
|
+
*.pot
|
|
47
|
+
|
|
48
|
+
# Django stuff
|
|
49
|
+
*.log
|
|
50
|
+
local_settings.py
|
|
51
|
+
db.sqlite3
|
|
52
|
+
db.sqlite3-journal
|
|
53
|
+
|
|
54
|
+
# Environments
|
|
55
|
+
.env
|
|
56
|
+
.venv
|
|
57
|
+
env/
|
|
58
|
+
venv/
|
|
59
|
+
ENV/
|
|
60
|
+
|
|
61
|
+
# mkdocs documentation
|
|
62
|
+
/site
|
|
63
|
+
|
|
64
|
+
# Type checkers / linters
|
|
65
|
+
.mypy_cache/
|
|
66
|
+
.dmypy.json
|
|
67
|
+
dmypy.json
|
|
68
|
+
.pyre/
|
|
69
|
+
.pytype/
|
|
70
|
+
.ruff_cache/
|
|
71
|
+
|
|
72
|
+
# Node (embedded esbuild JS build lives under js/)
|
|
73
|
+
node_modules/
|
|
74
|
+
|
|
75
|
+
# IDEs / editors
|
|
76
|
+
.idea/
|
|
77
|
+
.vscode/
|
|
78
|
+
*.swp
|
|
79
|
+
*~
|
|
80
|
+
.DS_Store
|
|
81
|
+
|
|
82
|
+
# AI-specific items (local design notes, not committed)
|
|
83
|
+
.ai/
|
|
84
|
+
|
|
85
|
+
# Dev-only corpus-generation scratchpad (TinyMCE harness + raw dumps).
|
|
86
|
+
# The curated, committed fidelity fixtures land elsewhere under js/ later.
|
|
87
|
+
corpus-lab/
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v6.0.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: trailing-whitespace
|
|
6
|
+
- id: end-of-file-fixer
|
|
7
|
+
- id: check-yaml
|
|
8
|
+
- id: check-added-large-files
|
|
9
|
+
|
|
10
|
+
- repo: local
|
|
11
|
+
hooks:
|
|
12
|
+
- id: ruff-check
|
|
13
|
+
name: "ruff check --fix"
|
|
14
|
+
entry: make lint-fix
|
|
15
|
+
pass_filenames: false
|
|
16
|
+
language: system
|
|
17
|
+
stages: [pre-commit]
|
|
18
|
+
|
|
19
|
+
- id: ruff-format
|
|
20
|
+
name: "ruff format"
|
|
21
|
+
entry: make format
|
|
22
|
+
pass_filenames: false
|
|
23
|
+
language: system
|
|
24
|
+
stages: [pre-commit]
|
|
25
|
+
|
|
26
|
+
- id: backend-type-check
|
|
27
|
+
name: "type check (ty)"
|
|
28
|
+
entry: make type-check
|
|
29
|
+
pass_filenames: false
|
|
30
|
+
language: system
|
|
31
|
+
stages: [pre-commit]
|
|
32
|
+
|
|
33
|
+
- id: forbid-local-paths
|
|
34
|
+
name: "forbid local filesystem paths / personal handles"
|
|
35
|
+
entry: "/Users/|arturveres"
|
|
36
|
+
language: pygrep
|
|
37
|
+
types: [text]
|
|
38
|
+
exclude: '^\.pre-commit-config\.yaml$'
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.1.0] — 2026-06-20
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Django integration**: `TipTapWidget`, `AdminTipTapWidget`,
|
|
15
|
+
`TipTapModelAdminMixin`, and `TipTapFormField`. Stores HTML (render with
|
|
16
|
+
`|safe`); the ProseMirror schema sanitizes on parse (scripts/unknown nodes
|
|
17
|
+
dropped, link/image protocol allowlists).
|
|
18
|
+
- **Editor**: full toolbar — formatting, font size/family, text colour,
|
|
19
|
+
highlight, headings, lists, alignment, links, images, tables, and a raw-HTML
|
|
20
|
+
source view — plus a button registry (`ui.registerButton`) and design-token
|
|
21
|
+
theming (`--tiptap-*` / `ui.setTokens`).
|
|
22
|
+
- **Images & content**: upload (toolbar/paste/drop, CSRF, protocol-validated)
|
|
23
|
+
with the `{file} → {location}` contract, a library picker, merge tags, an
|
|
24
|
+
`onChange` callback (explicit init / Path B), and `BaseImageUploadView` /
|
|
25
|
+
`ImageUploadError` helpers.
|
|
26
|
+
- **Extensibility & i18n**: `registerExtension` (+ `TIPTAP_EXTRA_EXTENSIONS`),
|
|
27
|
+
en/sv locales with `registerLocale`, and re-exported TipTap primitives for
|
|
28
|
+
no-build authoring.
|
|
29
|
+
- **Asset modes**: a committed, self-contained bundle (default, node-free) and a
|
|
30
|
+
glue-only ESM build for bring-your-own-TipTap via import maps, with a default
|
|
31
|
+
CDN import map and a startup version-skew check.
|
|
32
|
+
- **Settings**: `TIPTAP_DEFAULT_CONFIG`, `TIPTAP_ASSET_MODE`,
|
|
33
|
+
`TIPTAP_IMPORT_MAP`, `TIPTAP_EXTRA_EXTENSIONS`; `{% tiptap_media %}` and
|
|
34
|
+
`{% tiptap_config %}` template tags.
|
|
35
|
+
- **Quality**: a TinyMCE-corpus round-trip fidelity test, 100% line+branch
|
|
36
|
+
Python coverage, and full documentation.
|
|
37
|
+
|
|
38
|
+
[Unreleased]: https://github.com/Artui/django-tiptap-editor/compare/v0.1.0...HEAD
|
|
39
|
+
[0.1.0]: https://github.com/Artui/django-tiptap-editor/compare/v0.0.0...v0.1.0
|