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.
Files changed (110) hide show
  1. django_tiptap_editor-0.1.0/.github/workflows/release.yml +96 -0
  2. django_tiptap_editor-0.1.0/.github/workflows/tests.yml +249 -0
  3. django_tiptap_editor-0.1.0/.gitignore +87 -0
  4. django_tiptap_editor-0.1.0/.pre-commit-config.yaml +38 -0
  5. django_tiptap_editor-0.1.0/CHANGELOG.md +39 -0
  6. django_tiptap_editor-0.1.0/CLAUDE.md +218 -0
  7. django_tiptap_editor-0.1.0/LICENSE +21 -0
  8. django_tiptap_editor-0.1.0/Makefile +101 -0
  9. django_tiptap_editor-0.1.0/PKG-INFO +117 -0
  10. django_tiptap_editor-0.1.0/README.md +81 -0
  11. django_tiptap_editor-0.1.0/django_tiptap_editor/__init__.py +25 -0
  12. django_tiptap_editor-0.1.0/django_tiptap_editor/admin/__init__.py +7 -0
  13. django_tiptap_editor-0.1.0/django_tiptap_editor/admin/mixin.py +30 -0
  14. django_tiptap_editor-0.1.0/django_tiptap_editor/apps.py +11 -0
  15. django_tiptap_editor-0.1.0/django_tiptap_editor/constants.py +113 -0
  16. django_tiptap_editor-0.1.0/django_tiptap_editor/forms/__init__.py +7 -0
  17. django_tiptap_editor-0.1.0/django_tiptap_editor/forms/fields.py +13 -0
  18. django_tiptap_editor-0.1.0/django_tiptap_editor/py.typed +0 -0
  19. django_tiptap_editor-0.1.0/django_tiptap_editor/static/django_tiptap_editor/tiptap.bundle.css +1 -0
  20. django_tiptap_editor-0.1.0/django_tiptap_editor/static/django_tiptap_editor/tiptap.bundle.js +97 -0
  21. django_tiptap_editor-0.1.0/django_tiptap_editor/static/django_tiptap_editor/tiptap.glue.esm.css +1 -0
  22. django_tiptap_editor-0.1.0/django_tiptap_editor/static/django_tiptap_editor/tiptap.glue.esm.js +1 -0
  23. django_tiptap_editor-0.1.0/django_tiptap_editor/templatetags/__init__.py +0 -0
  24. django_tiptap_editor-0.1.0/django_tiptap_editor/templatetags/tiptap.py +62 -0
  25. django_tiptap_editor-0.1.0/django_tiptap_editor/utils/__init__.py +17 -0
  26. django_tiptap_editor-0.1.0/django_tiptap_editor/utils/get_asset_mode.py +21 -0
  27. django_tiptap_editor-0.1.0/django_tiptap_editor/utils/get_default_config.py +18 -0
  28. django_tiptap_editor-0.1.0/django_tiptap_editor/utils/get_extra_extensions.py +15 -0
  29. django_tiptap_editor-0.1.0/django_tiptap_editor/utils/get_import_map.py +28 -0
  30. django_tiptap_editor-0.1.0/django_tiptap_editor/utils/validate_config.py +36 -0
  31. django_tiptap_editor-0.1.0/django_tiptap_editor/version.py +5 -0
  32. django_tiptap_editor-0.1.0/django_tiptap_editor/views/__init__.py +8 -0
  33. django_tiptap_editor-0.1.0/django_tiptap_editor/views/base_image_upload_view.py +37 -0
  34. django_tiptap_editor-0.1.0/django_tiptap_editor/views/image_upload_error.py +7 -0
  35. django_tiptap_editor-0.1.0/django_tiptap_editor/widgets/__init__.py +8 -0
  36. django_tiptap_editor-0.1.0/django_tiptap_editor/widgets/admin_tiptap.py +23 -0
  37. django_tiptap_editor-0.1.0/django_tiptap_editor/widgets/tiptap_widget.py +47 -0
  38. django_tiptap_editor-0.1.0/docs/api.md +89 -0
  39. django_tiptap_editor-0.1.0/docs/asset-modes.md +54 -0
  40. django_tiptap_editor-0.1.0/docs/configuration.md +57 -0
  41. django_tiptap_editor-0.1.0/docs/contracts.md +61 -0
  42. django_tiptap_editor-0.1.0/docs/extending.md +72 -0
  43. django_tiptap_editor-0.1.0/docs/index.md +31 -0
  44. django_tiptap_editor-0.1.0/docs/installation.md +35 -0
  45. django_tiptap_editor-0.1.0/docs/quickstart.md +62 -0
  46. django_tiptap_editor-0.1.0/docs/recipes/migrating-from-tinymce.md +62 -0
  47. django_tiptap_editor-0.1.0/docs/recipes/preview.md +25 -0
  48. django_tiptap_editor-0.1.0/docs/security.md +34 -0
  49. django_tiptap_editor-0.1.0/docs/semver.md +33 -0
  50. django_tiptap_editor-0.1.0/docs/theming.md +49 -0
  51. django_tiptap_editor-0.1.0/js/esbuild.config.mjs +57 -0
  52. django_tiptap_editor-0.1.0/js/package-lock.json +3609 -0
  53. django_tiptap_editor-0.1.0/js/package.json +36 -0
  54. django_tiptap_editor-0.1.0/js/src/build-extensions.ts +134 -0
  55. django_tiptap_editor-0.1.0/js/src/default-config.ts +69 -0
  56. django_tiptap_editor-0.1.0/js/src/editor-config.ts +15 -0
  57. django_tiptap_editor-0.1.0/js/src/extensions/background-color.ts +30 -0
  58. django_tiptap_editor-0.1.0/js/src/extensions/block-style.ts +42 -0
  59. django_tiptap_editor-0.1.0/js/src/extensions/font-size.ts +26 -0
  60. django_tiptap_editor-0.1.0/js/src/extensions/inline-image.ts +31 -0
  61. django_tiptap_editor-0.1.0/js/src/globals.d.ts +3 -0
  62. django_tiptap_editor-0.1.0/js/src/i18n.ts +132 -0
  63. django_tiptap_editor-0.1.0/js/src/image-picker.ts +94 -0
  64. django_tiptap_editor-0.1.0/js/src/index.ts +158 -0
  65. django_tiptap_editor-0.1.0/js/src/registry.ts +27 -0
  66. django_tiptap_editor-0.1.0/js/src/styles.css +356 -0
  67. django_tiptap_editor-0.1.0/js/src/tiptap-runtime.ts +31 -0
  68. django_tiptap_editor-0.1.0/js/src/toolbar/built-in-buttons.ts +257 -0
  69. django_tiptap_editor-0.1.0/js/src/toolbar/button-registry.ts +34 -0
  70. django_tiptap_editor-0.1.0/js/src/toolbar/controls.ts +163 -0
  71. django_tiptap_editor-0.1.0/js/src/toolbar/dropdown.ts +84 -0
  72. django_tiptap_editor-0.1.0/js/src/toolbar/icons.ts +46 -0
  73. django_tiptap_editor-0.1.0/js/src/toolbar/render-toolbar.ts +98 -0
  74. django_tiptap_editor-0.1.0/js/src/toolbar/source-view.ts +78 -0
  75. django_tiptap_editor-0.1.0/js/src/ui.ts +20 -0
  76. django_tiptap_editor-0.1.0/js/src/upload.ts +104 -0
  77. django_tiptap_editor-0.1.0/js/src/version-check.ts +29 -0
  78. django_tiptap_editor-0.1.0/js/test/canonical.ts +119 -0
  79. django_tiptap_editor-0.1.0/js/test/fidelity.test.ts +59 -0
  80. django_tiptap_editor-0.1.0/js/test/fixtures/tinymce-corpus.json +245 -0
  81. django_tiptap_editor-0.1.0/js/tsconfig.json +16 -0
  82. django_tiptap_editor-0.1.0/js/vitest.config.ts +8 -0
  83. django_tiptap_editor-0.1.0/mkdocs.yml +88 -0
  84. django_tiptap_editor-0.1.0/pyproject.toml +139 -0
  85. django_tiptap_editor-0.1.0/scripts/release-publish.sh +211 -0
  86. django_tiptap_editor-0.1.0/tests/__init__.py +0 -0
  87. django_tiptap_editor-0.1.0/tests/admin/__init__.py +0 -0
  88. django_tiptap_editor-0.1.0/tests/admin/test_mixin.py +52 -0
  89. django_tiptap_editor-0.1.0/tests/conftest.py +0 -0
  90. django_tiptap_editor-0.1.0/tests/conftest_settings.py +36 -0
  91. django_tiptap_editor-0.1.0/tests/forms/__init__.py +0 -0
  92. django_tiptap_editor-0.1.0/tests/forms/test_fields.py +8 -0
  93. django_tiptap_editor-0.1.0/tests/templatetags/__init__.py +0 -0
  94. django_tiptap_editor-0.1.0/tests/templatetags/test_tiptap.py +31 -0
  95. django_tiptap_editor-0.1.0/tests/test_public_api.py +17 -0
  96. django_tiptap_editor-0.1.0/tests/test_version.py +13 -0
  97. django_tiptap_editor-0.1.0/tests/testapp/__init__.py +0 -0
  98. django_tiptap_editor-0.1.0/tests/testapp/models.py +12 -0
  99. django_tiptap_editor-0.1.0/tests/utils/__init__.py +0 -0
  100. django_tiptap_editor-0.1.0/tests/utils/test_get_asset_mode.py +22 -0
  101. django_tiptap_editor-0.1.0/tests/utils/test_get_default_config.py +14 -0
  102. django_tiptap_editor-0.1.0/tests/utils/test_get_extra_extensions.py +14 -0
  103. django_tiptap_editor-0.1.0/tests/utils/test_get_import_map.py +26 -0
  104. django_tiptap_editor-0.1.0/tests/utils/test_validate_config.py +31 -0
  105. django_tiptap_editor-0.1.0/tests/views/__init__.py +0 -0
  106. django_tiptap_editor-0.1.0/tests/views/test_base_image_upload_view.py +46 -0
  107. django_tiptap_editor-0.1.0/tests/widgets/__init__.py +0 -0
  108. django_tiptap_editor-0.1.0/tests/widgets/test_admin_tiptap.py +12 -0
  109. django_tiptap_editor-0.1.0/tests/widgets/test_tiptap_widget.py +35 -0
  110. 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