draftail-text-utils 0.1.7__py3-none-any.whl

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 (39) hide show
  1. draftail_text_utils/__init__.py +4 -0
  2. draftail_text_utils/apps.py +7 -0
  3. draftail_text_utils/conf.py +482 -0
  4. draftail_text_utils/migrations/__init__.py +0 -0
  5. draftail_text_utils/rich_text/__init__.py +0 -0
  6. draftail_text_utils/rich_text/base.py +267 -0
  7. draftail_text_utils/rich_text/font_family.py +61 -0
  8. draftail_text_utils/rich_text/font_size.py +94 -0
  9. draftail_text_utils/rich_text/highlight_color.py +99 -0
  10. draftail_text_utils/rich_text/text_alignment.py +70 -0
  11. draftail_text_utils/rich_text/text_color.py +95 -0
  12. draftail_text_utils/static/draftail_text_utils/css/draftail_text_utils.css +5 -0
  13. draftail_text_utils/static/draftail_text_utils/css/font_family.css +57 -0
  14. draftail_text_utils/static/draftail_text_utils/css/font_size.css +102 -0
  15. draftail_text_utils/static/draftail_text_utils/css/highlight_color.css +117 -0
  16. draftail_text_utils/static/draftail_text_utils/css/text_alignment.css +72 -0
  17. draftail_text_utils/static/draftail_text_utils/css/text_color.css +117 -0
  18. draftail_text_utils/static/draftail_text_utils/js/font_family.js +149 -0
  19. draftail_text_utils/static/draftail_text_utils/js/font_size.js +408 -0
  20. draftail_text_utils/static/draftail_text_utils/js/font_size_entity.js +39 -0
  21. draftail_text_utils/static/draftail_text_utils/js/highlight_color.js +350 -0
  22. draftail_text_utils/static/draftail_text_utils/js/highlight_color_entity.js +43 -0
  23. draftail_text_utils/static/draftail_text_utils/js/text_alignment.js +139 -0
  24. draftail_text_utils/static/draftail_text_utils/js/text_color.js +343 -0
  25. draftail_text_utils/static/draftail_text_utils/js/text_color_entity.js +42 -0
  26. draftail_text_utils/templates/draftail_text_utils/icons/align-center.svg +1 -0
  27. draftail_text_utils/templates/draftail_text_utils/icons/align-justify.svg +1 -0
  28. draftail_text_utils/templates/draftail_text_utils/icons/align-left.svg +1 -0
  29. draftail_text_utils/templates/draftail_text_utils/icons/align-right.svg +1 -0
  30. draftail_text_utils/templates/draftail_text_utils/icons/font.svg +1 -0
  31. draftail_text_utils/templates/draftail_text_utils/icons/highlighter.svg +1 -0
  32. draftail_text_utils/templates/draftail_text_utils/icons/palette.svg +1 -0
  33. draftail_text_utils/templates/draftail_text_utils/icons/text-height.svg +1 -0
  34. draftail_text_utils/templatetags/__init__.py +0 -0
  35. draftail_text_utils/templatetags/draftail_text_utils_tags.py +29 -0
  36. draftail_text_utils/wagtail_hooks.py +266 -0
  37. draftail_text_utils-0.1.7.dist-info/METADATA +63 -0
  38. draftail_text_utils-0.1.7.dist-info/RECORD +39 -0
  39. draftail_text_utils-0.1.7.dist-info/WHEEL +4 -0
@@ -0,0 +1,266 @@
1
+ """
2
+ Wagtail hooks for draftail_text_utils.
3
+
4
+ Integrates all rich-text feature registrations and injects the
5
+ necessary CSS / JS assets into the Wagtail admin.
6
+ """
7
+
8
+ import json
9
+
10
+ from urllib.parse import urljoin
11
+
12
+ from django.core.serializers.json import DjangoJSONEncoder
13
+ from django.templatetags.static import static
14
+ from django.utils.html import format_html, mark_safe
15
+ from wagtail import hooks
16
+
17
+ from draftail_text_utils.conf import (
18
+ feature_enabled,
19
+ get_font_sizes,
20
+ load_color_palette,
21
+ load_font_families,
22
+ load_font_urls,
23
+ )
24
+ from draftail_text_utils.rich_text import (
25
+ font_family,
26
+ font_size,
27
+ highlight_color,
28
+ text_alignment,
29
+ text_color,
30
+ )
31
+
32
+
33
+ @hooks.register("register_icons")
34
+ def register_icons(icons):
35
+ return icons + [
36
+ "draftail_text_utils/icons/align-center.svg",
37
+ "draftail_text_utils/icons/align-justify.svg",
38
+ "draftail_text_utils/icons/align-left.svg",
39
+ "draftail_text_utils/icons/align-right.svg",
40
+ "draftail_text_utils/icons/font.svg",
41
+ "draftail_text_utils/icons/highlighter.svg",
42
+ "draftail_text_utils/icons/palette.svg",
43
+ "draftail_text_utils/icons/text-height.svg",
44
+ ]
45
+
46
+
47
+ # ---------------------------------------------------------------------------
48
+ # Feature registration
49
+ # ---------------------------------------------------------------------------
50
+
51
+
52
+ @hooks.register("register_rich_text_features")
53
+ def register_text_alignment_feature(features):
54
+ text_alignment.register(features)
55
+
56
+
57
+ @hooks.register("register_rich_text_features")
58
+ def register_text_color(features):
59
+ text_color.register(features)
60
+
61
+
62
+ @hooks.register("register_rich_text_features")
63
+ def register_highlight_color(features):
64
+ highlight_color.register(features)
65
+
66
+
67
+ @hooks.register("register_rich_text_features")
68
+ def register_font_family_feature(features):
69
+ font_family.register(features)
70
+
71
+
72
+ @hooks.register("register_rich_text_features")
73
+ def register_font_size_feature(features):
74
+ font_size.register(features)
75
+
76
+
77
+ # ---------------------------------------------------------------------------
78
+ # Asset injection
79
+ # ---------------------------------------------------------------------------
80
+
81
+
82
+ def _feature_static(path):
83
+ return static(f"draftail_text_utils/{path}")
84
+
85
+
86
+ @hooks.register("insert_global_admin_css")
87
+ def global_admin_css():
88
+ links = set()
89
+ preconnect_links = set()
90
+
91
+ css_map = {
92
+ "TEXT_COLOR": "css/text_color.css",
93
+ "HIGHLIGHT_COLOR": "css/highlight_color.css",
94
+ "FONT_FAMILY": "css/font_family.css",
95
+ "FONT_SIZE": "css/font_size.css",
96
+ "TEXT_ALIGNMENT": "css/text_alignment.css",
97
+ }
98
+
99
+ for feature_name, css_path in css_map.items():
100
+ if feature_enabled(feature_name):
101
+ links.add(f'<link rel="stylesheet" href="{_feature_static(css_path)}">')
102
+
103
+ # Load font stylesheets
104
+ for url in load_font_urls():
105
+ if url:
106
+ preconnect_links.add(f'<link rel="preconnect" href="{urljoin(url, "/")}">')
107
+ links.add(f'<link rel="stylesheet" href="{url}">')
108
+
109
+ return mark_safe("\n".join(links.union(preconnect_links))) # noqa: S308
110
+
111
+
112
+ @hooks.register("insert_global_admin_js")
113
+ def global_admin_js():
114
+ """
115
+ Injects JS assets for draftail_text_utils rich-text
116
+ features into the Wagtail admin
117
+ """
118
+ scripts = [
119
+ format_html(
120
+ "<script type='text/javascript'>{}</script>",
121
+ mark_safe("window.draftailTextUtils = window.draftailTextUtils || {};"),
122
+ ),
123
+ ]
124
+
125
+ if feature_enabled("TEXT_COLOR") or feature_enabled("HIGHLIGHT_COLOR"):
126
+ colors = load_color_palette()
127
+ scripts.append(
128
+ format_html(
129
+ "<script type='module'>{}</script>",
130
+ mark_safe(
131
+ "import 'https://cdn.jsdelivr.net/gh/argyleink/css-color-component/dist/index.js';"
132
+ ),
133
+ )
134
+ )
135
+ scripts.append(_color_script(colors))
136
+
137
+ if feature_enabled("TEXT_COLOR"):
138
+ scripts.append(text_color.control())
139
+
140
+ if feature_enabled("HIGHLIGHT_COLOR"):
141
+ scripts.append(highlight_color.control())
142
+
143
+ if feature_enabled("FONT_FAMILY"):
144
+ families = load_font_families()
145
+ scripts.append(_font_family_script(families))
146
+ scripts.append(font_family.control())
147
+
148
+ if feature_enabled("FONT_SIZE"):
149
+ sizes = get_font_sizes()
150
+ scripts.append(_font_size_script(sizes))
151
+ scripts.append(font_size.control())
152
+
153
+ if feature_enabled("TEXT_ALIGNMENT"):
154
+ scripts.append(text_alignment.control())
155
+
156
+ return mark_safe("\n".join(scripts)) # noqa: S308
157
+
158
+
159
+ # ---------------------------------------------------------------------------
160
+ # Inline data injection helpers
161
+ # ---------------------------------------------------------------------------
162
+
163
+
164
+ def _color_script(colors):
165
+ text_colors = [
166
+ {
167
+ "type": f"TEXT_COLOR_{c['key'].upper()}",
168
+ "label": c["label"],
169
+ "value": c["value"],
170
+ "key": c["key"],
171
+ "style": {"color": c["value"]},
172
+ }
173
+ for c in colors
174
+ ]
175
+ highlight_colors = [
176
+ {
177
+ "type": f"HIGHLIGHT_COLOR_{c['key'].upper()}",
178
+ "label": c["label"],
179
+ "value": c["value"],
180
+ "key": c["key"],
181
+ "style": {"backgroundColor": c["value"]},
182
+ }
183
+ for c in colors
184
+ ]
185
+ text_color_style_map = {
186
+ f"TEXT_COLOR_{c['key'].upper()}": {"color": c["value"]} for c in colors
187
+ }
188
+ highlight_color_style_map = {
189
+ f"HIGHLIGHT_COLOR_{c['key'].upper()}": {"backgroundColor": c["value"]}
190
+ for c in colors
191
+ }
192
+
193
+ data = {
194
+ "customTextColors": text_colors,
195
+ "customHighlightColors": highlight_colors,
196
+ "customTextColorStyleMap": text_color_style_map,
197
+ "customHighlightColorStyleMap": highlight_color_style_map,
198
+ }
199
+ json_str = json.dumps(data, cls=DjangoJSONEncoder)
200
+ return format_html(
201
+ "<script type='text/javascript'>{}</script>",
202
+ mark_safe( # noqa: S308
203
+ f"Object.assign(window.draftailTextUtils, {json_str});"
204
+ ),
205
+ )
206
+
207
+
208
+ def _font_family_script(families):
209
+ data = {
210
+ "customFontFamilies": [
211
+ {
212
+ "label": f["label"],
213
+ "value": f["value"],
214
+ "type": f.get(
215
+ "type", f"FONT_FAMILY_{f['label'].upper().replace(' ', '_')}"
216
+ ),
217
+ "style": {"fontFamily": f["value"]},
218
+ }
219
+ for f in families
220
+ ]
221
+ }
222
+ json_str = json.dumps(data, cls=DjangoJSONEncoder)
223
+ return format_html(
224
+ "<script type='text/javascript'>{}</script>",
225
+ mark_safe( # noqa: S308
226
+ f"Object.assign(window.draftailTextUtils, {json_str});"
227
+ ),
228
+ )
229
+
230
+
231
+ def _font_size_script(sizes):
232
+ data = {"customFontSizes": sizes}
233
+ json_str = json.dumps(data, cls=DjangoJSONEncoder)
234
+ return format_html(
235
+ "<script type='text/javascript'>{}</script>",
236
+ mark_safe( # noqa: S308
237
+ f"Object.assign(window.draftailTextUtils, {json_str});"
238
+ ),
239
+ )
240
+
241
+
242
+ # Keep original admin URL registration from the template
243
+
244
+
245
+ @hooks.register("register_admin_urls")
246
+ def register_admin_urls():
247
+ from django.urls import include, path
248
+ from django.views.i18n import JavaScriptCatalog
249
+
250
+ urls = [
251
+ path(
252
+ "jsi18n/",
253
+ JavaScriptCatalog.as_view(packages=["draftail_text_utils"]),
254
+ name="javascript_catalog",
255
+ ),
256
+ ]
257
+
258
+ return [
259
+ path(
260
+ "draftail_text_utils/",
261
+ include(
262
+ (urls, "draftail_text_utils"),
263
+ namespace="draftail_text_utils",
264
+ ),
265
+ )
266
+ ]
@@ -0,0 +1,63 @@
1
+ Metadata-Version: 2.4
2
+ Name: draftail-text-utils
3
+ Version: 0.1.7
4
+ Summary: Extends Draftail's text customization
5
+ Keywords: wagtail,draftail,rich text,text color,highlight,font size,font family,text alignment
6
+ Author: baldwinboy
7
+ License-Expression: BSD-3-Clause
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Programming Language :: Python
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Programming Language :: Python :: 3.14
15
+ Classifier: Framework :: Django
16
+ Classifier: Framework :: Django :: 5.0
17
+ Classifier: Framework :: Django :: 5.1
18
+ Classifier: Framework :: Django :: 6.0
19
+ Classifier: Framework :: Wagtail
20
+ Classifier: Framework :: Wagtail :: 6
21
+ Classifier: Framework :: Wagtail :: 7
22
+ Requires-Dist: cssutils>=2.15.0
23
+ Requires-Dist: django>=5.0
24
+ Requires-Dist: wagtail>=6.0
25
+ Requires-Dist: wagtail-traverse>=1.0.1
26
+ Requires-Python: >=3.13
27
+ Project-URL: Homepage, https://github.com/baldwinboy/draftail-text-utils
28
+ Project-URL: Repository, https://github.com/baldwinboy/draftail-text-utils
29
+ Project-URL: Changelog, https://github.com/baldwinboy/draftail-text-utils/blob/main/CHANGELOG.md
30
+ Project-URL: Documentation, https://github.com/baldwinboy/draftail-text-utils/tree/main/docs
31
+ Project-URL: Issues, https://github.com/baldwinboy/draftail-text-utils/issues
32
+ Description-Content-Type: text/markdown
33
+
34
+ # Draftail Text Utils
35
+
36
+ Extends Draftail's text customization. Includes:
37
+ - Text Color (with optional palettes)
38
+ - Highlight Color
39
+ - Font Family
40
+ - Font Size
41
+ - Text Alignment
42
+
43
+ ## Links
44
+
45
+ - [Documentation](https://github.com/baldwinboy/draftail-text-utils/blob/main/README.md)
46
+ - [Changelog](https://github.com/baldwinboy/draftail-text-utils/blob/main/CHANGELOG.md)
47
+ - [Contributing](https://github.com/baldwinboy/draftail-text-utils/blob/main/CONTRIBUTING.md)
48
+ - [Discussions](https://github.com/baldwinboy/draftail-text-utils/discussions)
49
+ - [Security](https://github.com/baldwinboy/draftail-text-utils/security)
50
+
51
+ ## Supported versions
52
+
53
+ This package supports Wagtail 7.0 and up, and all [compatible versions of Python and Django](https://docs.wagtail.org/en/stable/releases/upgrading.html#compatible-django-python-versions).
54
+
55
+ ## Installation
56
+
57
+ Pick the command for your preferred package installer:
58
+
59
+ ```bash
60
+ uv add draftail-text-utils
61
+ poetry add draftail-text-utils
62
+ pip install draftail-text-utils
63
+ ```
@@ -0,0 +1,39 @@
1
+ draftail_text_utils/__init__.py,sha256=C5mTSbp9UtWw-Ob2qELjYnL7Pxy2TF0HU_P77hERi6I,138
2
+ draftail_text_utils/apps.py,sha256=hqB4f_S5EtGnNqzHax0buabxzhOKrAKdOsk0nOigBqU,189
3
+ draftail_text_utils/conf.py,sha256=eiutiNC4x9vtti6cTck5FNPmn8eBmWaNKCrnEyVyi_A,14837
4
+ draftail_text_utils/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ draftail_text_utils/rich_text/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ draftail_text_utils/rich_text/base.py,sha256=g-sBgA4IyjcrASavnaRsNT7qoRkxr9vU6Egq87YQmzY,7658
7
+ draftail_text_utils/rich_text/font_family.py,sha256=6V1sb4yEwrBFaglqu8kKM7fnzNgwnPBNMKJ1HQGN9_Y,1463
8
+ draftail_text_utils/rich_text/font_size.py,sha256=SmIkA42lyGY3tSOwcx-tq9IyYPH-7KV8gafBcWiqTy0,2441
9
+ draftail_text_utils/rich_text/highlight_color.py,sha256=7rf9mAhxxmrLv7bouOfG-CzZ-b6eQqv1gmtXQrU7KEU,2717
10
+ draftail_text_utils/rich_text/text_alignment.py,sha256=yYhRp7pecbYRDh2rbleJikn1gHAx9m-Q0t8jYiEzwP8,1838
11
+ draftail_text_utils/rich_text/text_color.py,sha256=wLx0zvm0vTmgSFnZLHgfV9vwTeLG-rD9fi2c4wDdHzY,2412
12
+ draftail_text_utils/static/draftail_text_utils/css/draftail_text_utils.css,sha256=-Jvc-XHXsLBUzPLjilhCSjmP1D9ppL7Bd0Xf09sGe7A,205
13
+ draftail_text_utils/static/draftail_text_utils/css/font_family.css,sha256=YvGKHrM8L7jePE5O9s92KDXVPvlgh4Zg0KQBIA0IRYs,1412
14
+ draftail_text_utils/static/draftail_text_utils/css/font_size.css,sha256=AzW9VFUth8uVfm30BAeWITVrrOpj66OMpG3yuskNbBw,2277
15
+ draftail_text_utils/static/draftail_text_utils/css/highlight_color.css,sha256=nQ8BKwk-EZ0vskNSgc7iANgRV5x0ko851Hu57YFMf0M,2861
16
+ draftail_text_utils/static/draftail_text_utils/css/text_alignment.css,sha256=9OHixNAxg23yFpUzU0LNZoDrxzkfKn0oFlqqwnyVJpI,1645
17
+ draftail_text_utils/static/draftail_text_utils/css/text_color.css,sha256=RbyoMYANvyoxR6rIFmACmSLdeAHpFN01lwlzceXubFw,2791
18
+ draftail_text_utils/static/draftail_text_utils/js/font_family.js,sha256=eE2wbud9O51U-4_Y6K_q_8G39wWXz4Uhw98sSTveSPU,4326
19
+ draftail_text_utils/static/draftail_text_utils/js/font_size.js,sha256=Z5QERAH80AvkErW5nQ8SJmgde1TLZmJlP_1R7LTjn-Q,11444
20
+ draftail_text_utils/static/draftail_text_utils/js/font_size_entity.js,sha256=xx1T1Ml6_9_FHoynwwQZKZFxQN4oWfSLJsDunTjN7RI,1016
21
+ draftail_text_utils/static/draftail_text_utils/js/highlight_color.js,sha256=KwOsq7RXh-4cOX7BmWRg2lOpWXl856Wh0J26rxE2J24,10557
22
+ draftail_text_utils/static/draftail_text_utils/js/highlight_color_entity.js,sha256=0VLsyVOmJyCLh8Gm9luy57bgNl_Ho19AUn-IHHMQt5s,1238
23
+ draftail_text_utils/static/draftail_text_utils/js/text_alignment.js,sha256=fKLgJ3ubyumvlVkBMxBMc5SEpL3GswTFgQLNLLRdf_s,4077
24
+ draftail_text_utils/static/draftail_text_utils/js/text_color.js,sha256=F0m80Bg0PC1JE3_rcffi1WQs7IU_5kYVw11sVM6GijA,10212
25
+ draftail_text_utils/static/draftail_text_utils/js/text_color_entity.js,sha256=XfY0EyI9bfhcNXBGIMwL8EcuyAAzmCbVog_-yHzYK3M,1147
26
+ draftail_text_utils/templates/draftail_text_utils/icons/align-center.svg,sha256=gm7rWinhbV6iJgWMWtz-kPlelM2Fbmc4yQFKmYNnUxE,653
27
+ draftail_text_utils/templates/draftail_text_utils/icons/align-justify.svg,sha256=hdzEcC4pDVmWkp9yfhy9woS4UObQmZNV2RNP5rvFWnU,650
28
+ draftail_text_utils/templates/draftail_text_utils/icons/align-left.svg,sha256=Fah5OQ_cbPLUqvQ8VMw7mkC1K3d6RUrBBSIsiFyPLIk,647
29
+ draftail_text_utils/templates/draftail_text_utils/icons/align-right.svg,sha256=2RUZCk7FG6yxIG99xxdaIuO_t_qLe73A-at4987ssII,651
30
+ draftail_text_utils/templates/draftail_text_utils/icons/font.svg,sha256=gKw_zMN9Ln0kvLn5OCwpRM_VQCuSbdrFdXi-WXMhglI,563
31
+ draftail_text_utils/templates/draftail_text_utils/icons/highlighter.svg,sha256=7YXvEXy-3BHbbPV1ZybXClR7r2QB1DQZdIr7Z8dF2Es,709
32
+ draftail_text_utils/templates/draftail_text_utils/icons/palette.svg,sha256=CwwKj-h1dXCpnIF8mKseTU-5W7Ed7HC91-1t2dHzya0,678
33
+ draftail_text_utils/templates/draftail_text_utils/icons/text-height.svg,sha256=-x2wxFzdPkP5YAnrQ8zZeA3o04L-w71HOkOaN_ow2c4,830
34
+ draftail_text_utils/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
+ draftail_text_utils/templatetags/draftail_text_utils_tags.py,sha256=q4liXr4q4IKQ6FLueB7IuhKi61Xvw_1pY2-N0BHxS6g,799
36
+ draftail_text_utils/wagtail_hooks.py,sha256=mwYOkU5QwOScBrdEDq0JHTehoXrcUvAnYk39eVZYROU,7719
37
+ draftail_text_utils-0.1.7.dist-info/WHEEL,sha256=f5fWSvWsg5Knq5GWa6t1nJIug0Tqo69GqAWD_9LbBKw,81
38
+ draftail_text_utils-0.1.7.dist-info/METADATA,sha256=VWckHk0Q1kTpfs-9KJB64iDMGSU9ayCvQFrVh2Y4WUA,2443
39
+ draftail_text_utils-0.1.7.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: uv 0.11.16
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any