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.
- draftail_text_utils/__init__.py +4 -0
- draftail_text_utils/apps.py +7 -0
- draftail_text_utils/conf.py +482 -0
- draftail_text_utils/migrations/__init__.py +0 -0
- draftail_text_utils/rich_text/__init__.py +0 -0
- draftail_text_utils/rich_text/base.py +267 -0
- draftail_text_utils/rich_text/font_family.py +61 -0
- draftail_text_utils/rich_text/font_size.py +94 -0
- draftail_text_utils/rich_text/highlight_color.py +99 -0
- draftail_text_utils/rich_text/text_alignment.py +70 -0
- draftail_text_utils/rich_text/text_color.py +95 -0
- draftail_text_utils/static/draftail_text_utils/css/draftail_text_utils.css +5 -0
- draftail_text_utils/static/draftail_text_utils/css/font_family.css +57 -0
- draftail_text_utils/static/draftail_text_utils/css/font_size.css +102 -0
- draftail_text_utils/static/draftail_text_utils/css/highlight_color.css +117 -0
- draftail_text_utils/static/draftail_text_utils/css/text_alignment.css +72 -0
- draftail_text_utils/static/draftail_text_utils/css/text_color.css +117 -0
- draftail_text_utils/static/draftail_text_utils/js/font_family.js +149 -0
- draftail_text_utils/static/draftail_text_utils/js/font_size.js +408 -0
- draftail_text_utils/static/draftail_text_utils/js/font_size_entity.js +39 -0
- draftail_text_utils/static/draftail_text_utils/js/highlight_color.js +350 -0
- draftail_text_utils/static/draftail_text_utils/js/highlight_color_entity.js +43 -0
- draftail_text_utils/static/draftail_text_utils/js/text_alignment.js +139 -0
- draftail_text_utils/static/draftail_text_utils/js/text_color.js +343 -0
- draftail_text_utils/static/draftail_text_utils/js/text_color_entity.js +42 -0
- draftail_text_utils/templates/draftail_text_utils/icons/align-center.svg +1 -0
- draftail_text_utils/templates/draftail_text_utils/icons/align-justify.svg +1 -0
- draftail_text_utils/templates/draftail_text_utils/icons/align-left.svg +1 -0
- draftail_text_utils/templates/draftail_text_utils/icons/align-right.svg +1 -0
- draftail_text_utils/templates/draftail_text_utils/icons/font.svg +1 -0
- draftail_text_utils/templates/draftail_text_utils/icons/highlighter.svg +1 -0
- draftail_text_utils/templates/draftail_text_utils/icons/palette.svg +1 -0
- draftail_text_utils/templates/draftail_text_utils/icons/text-height.svg +1 -0
- draftail_text_utils/templatetags/__init__.py +0 -0
- draftail_text_utils/templatetags/draftail_text_utils_tags.py +29 -0
- draftail_text_utils/wagtail_hooks.py +266 -0
- draftail_text_utils-0.1.7.dist-info/METADATA +63 -0
- draftail_text_utils-0.1.7.dist-info/RECORD +39 -0
- draftail_text_utils-0.1.7.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Shared utilities for registering Draftail rich-text features.
|
|
3
|
+
|
|
4
|
+
Provides helpers to reduce boilerplate when registering inline-style
|
|
5
|
+
features, converter rules, and control plugins.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from django.utils.html import json_script
|
|
9
|
+
from wagtail.admin.rich_text.converters.html_to_contentstate import (
|
|
10
|
+
BlockElementHandler,
|
|
11
|
+
InlineStyleElementHandler,
|
|
12
|
+
)
|
|
13
|
+
from wagtail.admin.rich_text.editors.draftail.features import (
|
|
14
|
+
BlockFeature,
|
|
15
|
+
ControlFeature,
|
|
16
|
+
EntityFeature,
|
|
17
|
+
InlineStyleFeature,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def control_json_script(type_, label, description, icon, data=None):
|
|
22
|
+
"""
|
|
23
|
+
Returns a JSON script for a toolbar control plugin for Draftail.
|
|
24
|
+
"""
|
|
25
|
+
return json_script(
|
|
26
|
+
{
|
|
27
|
+
"type": type_,
|
|
28
|
+
"label": label,
|
|
29
|
+
"description": description,
|
|
30
|
+
"icon": icon,
|
|
31
|
+
"data": data,
|
|
32
|
+
},
|
|
33
|
+
f"draftail-plugin-control-{type_}",
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def register_inline_style_feature(
|
|
38
|
+
features,
|
|
39
|
+
type_,
|
|
40
|
+
style,
|
|
41
|
+
css_selector,
|
|
42
|
+
element="span",
|
|
43
|
+
props=None,
|
|
44
|
+
label=None,
|
|
45
|
+
description=None,
|
|
46
|
+
icon=None,
|
|
47
|
+
):
|
|
48
|
+
"""
|
|
49
|
+
Register a single inline-style Draftail feature with its converter rules.
|
|
50
|
+
|
|
51
|
+
:param features: The Features registry from the hook.
|
|
52
|
+
:param type_: Unique type identifer (e.g. ``"TEXT_COLOR_RED"``).
|
|
53
|
+
:param style: Draftail style dict (e.g. ``{"color": "#EF4444"}``).
|
|
54
|
+
Property names must be camelCase, i.e. `textAlign` instead of `text-align`.
|
|
55
|
+
:param css_selector: CSS selector for `from_database_format` (e.g.
|
|
56
|
+
``'span[style="color: #EF4444;"]'``).
|
|
57
|
+
:param element: HTML element to use when converting back (default ``span``).
|
|
58
|
+
:param props: Extra HTML props for the output element.
|
|
59
|
+
:param label: Label for the control in the toolbar.
|
|
60
|
+
:param description: Description for the control in the toolbar.
|
|
61
|
+
:param icon: Icon name for the control in the toolbar.
|
|
62
|
+
"""
|
|
63
|
+
control = {
|
|
64
|
+
"type": type_,
|
|
65
|
+
"style": style,
|
|
66
|
+
}
|
|
67
|
+
props = props or {}
|
|
68
|
+
props["style"] = style
|
|
69
|
+
|
|
70
|
+
if label:
|
|
71
|
+
control["label"] = label
|
|
72
|
+
if description:
|
|
73
|
+
control["description"] = description
|
|
74
|
+
if icon:
|
|
75
|
+
control["icon"] = icon
|
|
76
|
+
|
|
77
|
+
features.register_editor_plugin(
|
|
78
|
+
"draftail",
|
|
79
|
+
type_,
|
|
80
|
+
InlineStyleFeature(control),
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
db_conversion = {
|
|
84
|
+
"from_database_format": {css_selector: InlineStyleElementHandler(type_)},
|
|
85
|
+
"to_database_format": {
|
|
86
|
+
"style_map": {type_: {"element": element, "props": props}}
|
|
87
|
+
},
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
features.register_converter_rule("contentstate", type_, db_conversion)
|
|
91
|
+
features.default_features.append(type_)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def register_block_feature(
|
|
95
|
+
features,
|
|
96
|
+
type_,
|
|
97
|
+
style,
|
|
98
|
+
css_selector,
|
|
99
|
+
element="div",
|
|
100
|
+
props=None,
|
|
101
|
+
label=None,
|
|
102
|
+
description=None,
|
|
103
|
+
icon=None,
|
|
104
|
+
):
|
|
105
|
+
"""
|
|
106
|
+
Register a single block Draftail feature with its converter rules.
|
|
107
|
+
|
|
108
|
+
:param features: The Features registry from the hook.
|
|
109
|
+
:param type_: Unique type identifer (e.g. ``"TEXT_COLOR_RED"``).
|
|
110
|
+
:param style: Draftail style dict (e.g. ``{"color": "#EF4444"}``).
|
|
111
|
+
Property names must be camelCase, i.e. `textAlign` instead of `text-align`.
|
|
112
|
+
:param css_selector: CSS selector for `from_database_format` (e.g.
|
|
113
|
+
``'span[style="color: #EF4444;"]'``).
|
|
114
|
+
:param element: HTML element to use when converting back (default ``span``).
|
|
115
|
+
:param props: Extra HTML props for the output element.
|
|
116
|
+
:param label: Label for the control in the toolbar.
|
|
117
|
+
:param description: Description for the control in the toolbar.
|
|
118
|
+
:param icon: Icon name for the control in the toolbar.
|
|
119
|
+
"""
|
|
120
|
+
control = {
|
|
121
|
+
"type": type_,
|
|
122
|
+
"style": style,
|
|
123
|
+
}
|
|
124
|
+
props = props or {}
|
|
125
|
+
props["style"] = style
|
|
126
|
+
|
|
127
|
+
if label:
|
|
128
|
+
control["label"] = label
|
|
129
|
+
if description:
|
|
130
|
+
control["description"] = description
|
|
131
|
+
if icon:
|
|
132
|
+
control["icon"] = icon
|
|
133
|
+
|
|
134
|
+
features.register_editor_plugin(
|
|
135
|
+
"draftail",
|
|
136
|
+
type_,
|
|
137
|
+
BlockFeature(control),
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
db_conversion = {
|
|
141
|
+
"from_database_format": {css_selector: BlockElementHandler(type_)},
|
|
142
|
+
"to_database_format": {
|
|
143
|
+
"block_map": {type_: {"element": element, "props": props}}
|
|
144
|
+
},
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
features.register_converter_rule("contentstate", type_, db_conversion)
|
|
148
|
+
features.default_features.append(type_)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def register_control_feature(
|
|
152
|
+
features,
|
|
153
|
+
feature_name,
|
|
154
|
+
label=None,
|
|
155
|
+
description=None,
|
|
156
|
+
icon=None,
|
|
157
|
+
js_files=None,
|
|
158
|
+
css_files=None,
|
|
159
|
+
js=None,
|
|
160
|
+
css=None,
|
|
161
|
+
):
|
|
162
|
+
"""
|
|
163
|
+
Register a toolbar control plugin for Draftail.
|
|
164
|
+
|
|
165
|
+
:param features: The Features registry.
|
|
166
|
+
:param feature_name: The control's type identifer (e.g. ``"text-color"``).
|
|
167
|
+
:param label: Label for the control in the toolbar.
|
|
168
|
+
:param description: Description for the control in the toolbar.
|
|
169
|
+
:param icon: Icon name for the control in the toolbar.
|
|
170
|
+
:param js_files: List of JS file paths (e.g. ``["js/draftail/text_color.js"]``).
|
|
171
|
+
:param css_files: Dict of CSS files (e.g. ``{"all": ("css/draftail/text_color.css",)}``).
|
|
172
|
+
"""
|
|
173
|
+
js_files = js_files or js or []
|
|
174
|
+
css_files = css_files or css or {}
|
|
175
|
+
control = {
|
|
176
|
+
"type": feature_name,
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if label:
|
|
180
|
+
control["label"] = label
|
|
181
|
+
if description:
|
|
182
|
+
control["description"] = description
|
|
183
|
+
if icon:
|
|
184
|
+
control["icon"] = icon
|
|
185
|
+
features.register_editor_plugin(
|
|
186
|
+
"draftail",
|
|
187
|
+
feature_name,
|
|
188
|
+
ControlFeature(
|
|
189
|
+
control,
|
|
190
|
+
js=js_files,
|
|
191
|
+
css=css_files,
|
|
192
|
+
),
|
|
193
|
+
)
|
|
194
|
+
features.default_features.append(feature_name)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def register_entity_feature(
|
|
198
|
+
features,
|
|
199
|
+
feature_name,
|
|
200
|
+
entity_type,
|
|
201
|
+
attributes,
|
|
202
|
+
decorator_fn,
|
|
203
|
+
handler_cls,
|
|
204
|
+
label=None,
|
|
205
|
+
description=None,
|
|
206
|
+
icon=None,
|
|
207
|
+
js_files=None,
|
|
208
|
+
css_files=None,
|
|
209
|
+
js=None,
|
|
210
|
+
css=None,
|
|
211
|
+
):
|
|
212
|
+
"""
|
|
213
|
+
Register an entity-based Draftail feature (used for custom/arbitrary values).
|
|
214
|
+
|
|
215
|
+
:param features: The Features registry.
|
|
216
|
+
:param feature_name: Feature name (e.g. ``"custom-text-color"``).
|
|
217
|
+
:param entity_type: Draftail entity type (e.g. ``"CUSTOM_TEXT_COLOR"``).
|
|
218
|
+
:param attributes: Entity attributes list.
|
|
219
|
+
:param decorator_fn: Callable that receives props and returns a DOM element.
|
|
220
|
+
:param handler_cls: Subclass of ``InlineEntityElementHandler``.
|
|
221
|
+
:param label: Label for the control in the toolbar.
|
|
222
|
+
:param description: Description for the control in the toolbar.
|
|
223
|
+
:param icon: Icon name for the control in the toolbar.
|
|
224
|
+
:param js_files: JS files for the entity plugin.
|
|
225
|
+
:param css_files: Dict of CSS files (e.g. ``{"all": ("css/draftail/text_color.css",)}``).
|
|
226
|
+
"""
|
|
227
|
+
js_files = js_files or js or []
|
|
228
|
+
css_files = css_files or css or {}
|
|
229
|
+
|
|
230
|
+
control = {
|
|
231
|
+
"type": entity_type,
|
|
232
|
+
"attributes": attributes,
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if label:
|
|
236
|
+
control["label"] = label
|
|
237
|
+
if description:
|
|
238
|
+
control["description"] = description
|
|
239
|
+
if icon:
|
|
240
|
+
control["icon"] = icon
|
|
241
|
+
|
|
242
|
+
features.register_editor_plugin(
|
|
243
|
+
"draftail",
|
|
244
|
+
feature_name,
|
|
245
|
+
EntityFeature(
|
|
246
|
+
control,
|
|
247
|
+
js=js_files,
|
|
248
|
+
css=css_files,
|
|
249
|
+
),
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
features.register_converter_rule(
|
|
253
|
+
"contentstate",
|
|
254
|
+
feature_name,
|
|
255
|
+
{
|
|
256
|
+
"from_database_format": {
|
|
257
|
+
f"span[data-entity-type='{entity_type}']": handler_cls(entity_type),
|
|
258
|
+
},
|
|
259
|
+
"to_database_format": {
|
|
260
|
+
"entity_decorators": {
|
|
261
|
+
entity_type: decorator_fn,
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
features.default_features.append(feature_name)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Draftail rich-text feature: Font family.
|
|
3
|
+
|
|
4
|
+
Registers:
|
|
5
|
+
- One ``InlineStyleFeature`` per configured custom font family.
|
|
6
|
+
- A ``"font-family"`` ControlFeature for the toolbar dropdown.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import re
|
|
10
|
+
|
|
11
|
+
from draftail_text_utils.conf import feature_enabled, load_font_families
|
|
12
|
+
|
|
13
|
+
from .base import (
|
|
14
|
+
control_json_script,
|
|
15
|
+
register_control_feature,
|
|
16
|
+
register_inline_style_feature,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def register(features):
|
|
21
|
+
if not feature_enabled("FONT_FAMILY"):
|
|
22
|
+
return
|
|
23
|
+
|
|
24
|
+
font_families = load_font_families()
|
|
25
|
+
|
|
26
|
+
if not font_families:
|
|
27
|
+
return
|
|
28
|
+
|
|
29
|
+
for font in font_families:
|
|
30
|
+
font_family = font["value"]
|
|
31
|
+
label = re.sub("[^0-9a-zA-Z]+", "_", font["label"]).upper()
|
|
32
|
+
type_ = font.get("type", f"FONT_FAMILY_{label}")
|
|
33
|
+
|
|
34
|
+
register_inline_style_feature(
|
|
35
|
+
features,
|
|
36
|
+
type_,
|
|
37
|
+
{"fontFamily": font_family},
|
|
38
|
+
f'span[style="font-family: {font_family};"]',
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
register_control_feature(
|
|
42
|
+
features,
|
|
43
|
+
"font-family",
|
|
44
|
+
icon="font",
|
|
45
|
+
label="Font Family",
|
|
46
|
+
description="Change font family",
|
|
47
|
+
js=["draftail_text_utils/js/font_family.js"],
|
|
48
|
+
css={"all": ("draftail_text_utils/css/font_family.css",)},
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def control():
|
|
53
|
+
if not feature_enabled("FONT_FAMILY"):
|
|
54
|
+
return
|
|
55
|
+
|
|
56
|
+
return control_json_script(
|
|
57
|
+
type_="font-family",
|
|
58
|
+
icon="font",
|
|
59
|
+
label="Font Family",
|
|
60
|
+
description="Change font family",
|
|
61
|
+
)
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Draftail rich-text feature: Font size.
|
|
3
|
+
|
|
4
|
+
Registers:
|
|
5
|
+
- A ``"font-size-entity"`` EntityFeature for arbitrary font sizes.
|
|
6
|
+
- A ``"font-size"`` ControlFeature for the toolbar control.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import cssutils
|
|
10
|
+
|
|
11
|
+
from draftjs_exporter.dom import DOM
|
|
12
|
+
from wagtail.admin.rich_text.converters.html_to_contentstate import (
|
|
13
|
+
InlineEntityElementHandler,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
from draftail_text_utils.conf import feature_enabled
|
|
17
|
+
|
|
18
|
+
from .base import (
|
|
19
|
+
control_json_script,
|
|
20
|
+
register_control_feature,
|
|
21
|
+
register_entity_feature,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class FontSizeEntityHandler(InlineEntityElementHandler):
|
|
26
|
+
"""
|
|
27
|
+
Database HTML to Draft.js ContentState.
|
|
28
|
+
Converts span elements with ``style="font-size: <size>px;"`` to
|
|
29
|
+
``FONT_SIZE_<size>`` entities.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
mutability = "MUTABLE"
|
|
33
|
+
|
|
34
|
+
def get_attribute_data(self, attrs):
|
|
35
|
+
"""
|
|
36
|
+
Extract the font size from the style attribute and return it as
|
|
37
|
+
an entity.
|
|
38
|
+
"""
|
|
39
|
+
try:
|
|
40
|
+
return {"size": cssutils.parseStyle(attrs["style"])["font-size"]}
|
|
41
|
+
except Exception:
|
|
42
|
+
return {}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def font_size_entity_decorator(props):
|
|
46
|
+
"""
|
|
47
|
+
Draft.js ContentState to database HTML.
|
|
48
|
+
Converts ``FONT_SIZE`` entities to span elements with
|
|
49
|
+
``style="font-size: <size>;"``.
|
|
50
|
+
"""
|
|
51
|
+
size = props.get("size")
|
|
52
|
+
children = props.get("children")
|
|
53
|
+
attrs = {}
|
|
54
|
+
if size:
|
|
55
|
+
attrs["style"] = f"font-size: {size};"
|
|
56
|
+
attrs["data-entity-type"] = "FONT_SIZE"
|
|
57
|
+
return DOM.create_element("span", attrs, children)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def register(features):
|
|
61
|
+
if not feature_enabled("FONT_SIZE"):
|
|
62
|
+
return
|
|
63
|
+
|
|
64
|
+
register_entity_feature(
|
|
65
|
+
features,
|
|
66
|
+
feature_name="font-size-entity",
|
|
67
|
+
entity_type="FONT_SIZE",
|
|
68
|
+
attributes=["size", "style", "data-entity-type"],
|
|
69
|
+
decorator_fn=font_size_entity_decorator,
|
|
70
|
+
handler_cls=FontSizeEntityHandler,
|
|
71
|
+
js=["draftail_text_utils/js/font_size_entity.js"],
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
register_control_feature(
|
|
75
|
+
features,
|
|
76
|
+
feature_name="font-size",
|
|
77
|
+
icon="text-height",
|
|
78
|
+
label="Font Size",
|
|
79
|
+
description="Change font size",
|
|
80
|
+
js=["draftail_text_utils/js/font_size.js"],
|
|
81
|
+
css={"all": ("draftail_text_utils/css/font_size.css",)},
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def control():
|
|
86
|
+
if not feature_enabled("FONT_SIZE"):
|
|
87
|
+
return
|
|
88
|
+
|
|
89
|
+
return control_json_script(
|
|
90
|
+
type_="font-size",
|
|
91
|
+
icon="text-height",
|
|
92
|
+
label="Font Size",
|
|
93
|
+
description="Change font size",
|
|
94
|
+
)
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Draftail rich-text feature: Highlight color.
|
|
3
|
+
|
|
4
|
+
Registers:
|
|
5
|
+
- A ``"highlight-color-entity"`` EntityFeature for arbitrary text colors.
|
|
6
|
+
- A ``"highlight-color"`` ControlFeature for the toolbar control.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import cssutils
|
|
10
|
+
|
|
11
|
+
from draftjs_exporter.dom import DOM
|
|
12
|
+
from wagtail.admin.rich_text.converters.html_to_contentstate import (
|
|
13
|
+
InlineEntityElementHandler,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
from draftail_text_utils.conf import feature_enabled
|
|
17
|
+
|
|
18
|
+
from .base import (
|
|
19
|
+
control_json_script,
|
|
20
|
+
register_control_feature,
|
|
21
|
+
register_entity_feature,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class HighlightColorEntityHandler(InlineEntityElementHandler):
|
|
26
|
+
"""
|
|
27
|
+
Database HTML to Draft.js ContentState.
|
|
28
|
+
Converts span elements with ``style="background-color: <color>;"`` to
|
|
29
|
+
``HIGHLIGHT_COLOR`` entities.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
mutability = "MUTABLE"
|
|
33
|
+
|
|
34
|
+
def get_attribute_data(self, attrs):
|
|
35
|
+
"""
|
|
36
|
+
Extract the color from the style attribute and return it as
|
|
37
|
+
an entity.
|
|
38
|
+
"""
|
|
39
|
+
try:
|
|
40
|
+
return {
|
|
41
|
+
"backgroundColor": cssutils.parseStyle(attrs["style"])[
|
|
42
|
+
"background-color"
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
except Exception:
|
|
46
|
+
return {}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def highlight_color_entity_decorator(props):
|
|
50
|
+
"""
|
|
51
|
+
Draft.js ContentState to database HTML.
|
|
52
|
+
Converts ``HIGHLIGHT_COLOR`` entities to span elements with
|
|
53
|
+
``style="background-color: <backgroundColor>;"``.
|
|
54
|
+
"""
|
|
55
|
+
background_color = props.get("backgroundColor", None)
|
|
56
|
+
children = props.get("children", None)
|
|
57
|
+
|
|
58
|
+
if not background_color and not children:
|
|
59
|
+
return None
|
|
60
|
+
|
|
61
|
+
attrs = {}
|
|
62
|
+
if background_color:
|
|
63
|
+
attrs["style"] = f"background-color: {background_color};"
|
|
64
|
+
attrs["data-entity-type"] = "HIGHLIGHT_COLOR"
|
|
65
|
+
return DOM.create_element("span", attrs, children)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def register(features):
|
|
69
|
+
if not feature_enabled("HIGHLIGHT_COLOR"):
|
|
70
|
+
return
|
|
71
|
+
|
|
72
|
+
register_entity_feature(
|
|
73
|
+
features,
|
|
74
|
+
feature_name="highlight-color-entity",
|
|
75
|
+
entity_type="HIGHLIGHT_COLOR",
|
|
76
|
+
attributes=["backgroundColor", "style", "data-entity-type"],
|
|
77
|
+
decorator_fn=highlight_color_entity_decorator,
|
|
78
|
+
handler_cls=HighlightColorEntityHandler,
|
|
79
|
+
js=["draftail_text_utils/js/highlight_color_entity.js"],
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
register_control_feature(
|
|
83
|
+
features,
|
|
84
|
+
feature_name="highlight-color",
|
|
85
|
+
js=["draftail_text_utils/js/highlight_color.js"],
|
|
86
|
+
css={"all": ("draftail_text_utils/css/highlight_color.css",)},
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def control():
|
|
91
|
+
if not feature_enabled("HIGHLIGHT_COLOR"):
|
|
92
|
+
return
|
|
93
|
+
|
|
94
|
+
return control_json_script(
|
|
95
|
+
type_="highlight-color",
|
|
96
|
+
icon="highlighter",
|
|
97
|
+
label="Highlight Color",
|
|
98
|
+
description="Change highlight color",
|
|
99
|
+
)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Draftail rich-text feature: Text alignment.
|
|
3
|
+
|
|
4
|
+
Registers:
|
|
5
|
+
- Four ``BlockFeature``s per alignment value.
|
|
6
|
+
- A ``"text-alignment"`` ControlFeature for the toolbar button group.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from django.utils.translation import gettext_lazy as _
|
|
10
|
+
|
|
11
|
+
from draftail_text_utils.conf import feature_enabled
|
|
12
|
+
|
|
13
|
+
from .base import (
|
|
14
|
+
control_json_script,
|
|
15
|
+
register_block_feature,
|
|
16
|
+
register_control_feature,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
ALIGNMENTS = [
|
|
21
|
+
("ALIGNMENT_LEFT", "left", "start", _("Left")),
|
|
22
|
+
("ALIGNMENT_CENTER", "center", "center", _("Center")),
|
|
23
|
+
("ALIGNMENT_RIGHT", "right", "end", _("Right")),
|
|
24
|
+
("ALIGNMENT_JUSTIFY", "justify", "justify", _("Justify")),
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def register(features):
|
|
29
|
+
if not feature_enabled("TEXT_ALIGNMENT"):
|
|
30
|
+
return
|
|
31
|
+
|
|
32
|
+
for type_, _value, styleValue, _label in ALIGNMENTS:
|
|
33
|
+
register_block_feature(
|
|
34
|
+
features,
|
|
35
|
+
type_,
|
|
36
|
+
{},
|
|
37
|
+
css_selector=f".dtu-block_text-align[data-dtu-text-align='{styleValue}']",
|
|
38
|
+
props={
|
|
39
|
+
"class": "dtu-block_text-align",
|
|
40
|
+
"data-dtu-text-align": styleValue,
|
|
41
|
+
},
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
register_control_feature(
|
|
45
|
+
features,
|
|
46
|
+
"text-alignment",
|
|
47
|
+
js=["draftail_text_utils/js/text_alignment.js"],
|
|
48
|
+
css={"all": ("draftail_text_utils/css/text_alignment.css",)},
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def control():
|
|
53
|
+
if not feature_enabled("TEXT_ALIGNMENT"):
|
|
54
|
+
return
|
|
55
|
+
|
|
56
|
+
return control_json_script(
|
|
57
|
+
type_="text-alignment",
|
|
58
|
+
label="Align Text",
|
|
59
|
+
description="Change text alignment",
|
|
60
|
+
icon="align-left",
|
|
61
|
+
data=[
|
|
62
|
+
{
|
|
63
|
+
"type": type_,
|
|
64
|
+
"label": label,
|
|
65
|
+
"style": {"textAlign": styleValue},
|
|
66
|
+
"icon": f"align-{value}",
|
|
67
|
+
}
|
|
68
|
+
for type_, value, styleValue, label in ALIGNMENTS
|
|
69
|
+
],
|
|
70
|
+
)
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Draftail rich-text feature: Text color.
|
|
3
|
+
|
|
4
|
+
Registers:
|
|
5
|
+
- A ``"text-color-entity"`` EntityFeature for arbitrary text colors.
|
|
6
|
+
- A ``"text-color"`` ControlFeature for the toolbar control.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import cssutils
|
|
10
|
+
|
|
11
|
+
from draftjs_exporter.dom import DOM
|
|
12
|
+
from wagtail.admin.rich_text.converters.html_to_contentstate import (
|
|
13
|
+
InlineEntityElementHandler,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
from draftail_text_utils.conf import feature_enabled
|
|
17
|
+
|
|
18
|
+
from .base import (
|
|
19
|
+
control_json_script,
|
|
20
|
+
register_control_feature,
|
|
21
|
+
register_entity_feature,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class TextColorEntityHandler(InlineEntityElementHandler):
|
|
26
|
+
"""
|
|
27
|
+
Database HTML to Draft.js ContentState.
|
|
28
|
+
Converts span elements with ``style="color: <color>;"`` to
|
|
29
|
+
``TEXT_COLOR`` entities.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
mutability = "MUTABLE"
|
|
33
|
+
|
|
34
|
+
def get_attribute_data(self, attrs):
|
|
35
|
+
"""
|
|
36
|
+
Extract the color from the style attribute and return it as
|
|
37
|
+
an entity.
|
|
38
|
+
"""
|
|
39
|
+
try:
|
|
40
|
+
return {"color": cssutils.parseStyle(attrs["style"])["color"]}
|
|
41
|
+
except Exception:
|
|
42
|
+
return {}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def text_color_entity_decorator(props):
|
|
46
|
+
"""
|
|
47
|
+
Draft.js ContentState to database HTML.
|
|
48
|
+
Converts ``TEXT_COLOR`` entities to span elements with
|
|
49
|
+
``style="color: <color>;"``.
|
|
50
|
+
"""
|
|
51
|
+
color = props.get("color", None)
|
|
52
|
+
children = props.get("children", None)
|
|
53
|
+
|
|
54
|
+
if not color and not children:
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
attrs = {}
|
|
58
|
+
if color:
|
|
59
|
+
attrs["style"] = f"color: {color};"
|
|
60
|
+
attrs["data-entity-type"] = "TEXT_COLOR"
|
|
61
|
+
return DOM.create_element("span", attrs, children)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def register(features):
|
|
65
|
+
if not feature_enabled("TEXT_COLOR"):
|
|
66
|
+
return
|
|
67
|
+
|
|
68
|
+
register_entity_feature(
|
|
69
|
+
features,
|
|
70
|
+
feature_name="text-color-entity",
|
|
71
|
+
entity_type="TEXT_COLOR",
|
|
72
|
+
attributes=["color", "style", "data-entity-type"],
|
|
73
|
+
decorator_fn=text_color_entity_decorator,
|
|
74
|
+
handler_cls=TextColorEntityHandler,
|
|
75
|
+
js=["draftail_text_utils/js/text_color_entity.js"],
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
register_control_feature(
|
|
79
|
+
features,
|
|
80
|
+
feature_name="text-color",
|
|
81
|
+
js=["draftail_text_utils/js/text_color.js"],
|
|
82
|
+
css={"all": ("draftail_text_utils/css/text_color.css",)},
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def control():
|
|
87
|
+
if not feature_enabled("TEXT_COLOR"):
|
|
88
|
+
return
|
|
89
|
+
|
|
90
|
+
return control_json_script(
|
|
91
|
+
type_="text-color",
|
|
92
|
+
icon="palette",
|
|
93
|
+
label="Text Color",
|
|
94
|
+
description="Change text color",
|
|
95
|
+
)
|