def register_blockquote_feature(features): """ Registering the `blockquote` feature, which uses the `blockquote` Draft.js block type, and is stored as HTML with a `<blockquote>` tag. """ feature_name = 'blockquote' type_ = 'blockquote' tag = 'blockquote' control = { 'type': type_, 'label': '❝', 'description': 'Blockquote', # Optionally, we can tell Draftail what element to use when displaying those blocks in the editor. # 'element': 'blockquote', 'style': {'textDecoration': 'line-through'}, } features.register_editor_plugin( 'draftail', feature_name, draftail_features.BlockFeature(control) ) features.register_converter_rule('contentstate', feature_name, { 'from_database_format': {tag: BlockElementHandler(type_)}, 'to_database_format': {'block_map': {type_: tag}}, }) features.default_features.append('blockquote')
def register_blockquote_feature(features): """Register the `blockquote` feature using the `blockquote` Draft.js block type.""" feature_name = "blockquote" type_ = "BLOCKQUOTE" tag = "blockquote" control = { "type": type_, "icon": " fas fa-quote-right", "description": gettext("Blockquote"), "element": "blockquote", } features.register_editor_plugin("draftail", feature_name, draftail_features.BlockFeature(control)) features.register_converter_rule( "contentstate", feature_name, { "from_database_format": { tag: BlockElementHandler(type_) }, "to_database_format": { "block_map": { type_: { "element": tag, "props": { "class": "blockquote text-right" } } } }, }, )
def register_blockquote_feature(features): """ Registering the `blockquote` feature, which uses the `blockquote` Draft.js block type, and is stored as HTML with a `<blockquote>` tag. """ feature_name = 'blockquote' type_ = 'blockquote' tag = 'blockquote' control = { 'type': type_, 'label': '❝', 'description': 'Blockquote', 'element': 'blockquote', } features.register_editor_plugin('draftail', feature_name, draftail_features.BlockFeature(control)) features.register_converter_rule( 'contentstate', feature_name, { 'from_database_format': { tag: BlockElementHandler(type_) }, 'to_database_format': { 'block_map': { type_: tag } }, }) features.default_features.append('blockquote')
def register_left_feature(features): """ Registering the `blockquote` feature, which uses the `blockquote` Draft.js block type, and is stored as HTML with a `<blockquote>` tag. """ feature_name = 'left' type_ = 'paragraph-left' tag = 'p' control = { 'type': type_, 'label': 'Left', 'description': 'p left', 'element': 'p', } features.register_editor_plugin('draftail', feature_name, draftail_features.BlockFeature(control)) features.register_converter_rule( 'contentstate', feature_name, { 'from_database_format': { 'blockquote[class]': BlockElementHandler(type_) }, 'to_database_format': { 'block_map': { type_: { 'element': tag, 'props': { 'class': 'text-left', }, }, }, }, }) features.default_features.append(feature_name)
def register_blockquote_feature(features): feature_name = 'blockquote' type_ = 'blockquote' tag = 'blockquote' control = { 'type': type_, 'label': '❝', 'description': 'Blockquote' } features.register_editor_plugin( 'draftail', feature_name, draftail_features.BlockFeature(control) ) db_conversion = { 'from_database_format': { tag: html_to_contentstate.BlockElementHandler(type_) }, 'to_database_format': {'block_map': {type_: tag}}, } features.register_converter_rule( 'contentstate', feature_name, db_conversion) features.default_features.append('blockquote')
def register_help_text_feature(features): feature_name = 'brand-color' type_ = 'brand-color' control = { 'type': type_, 'label': 'Brand', 'description': 'Brand Color', # Optionally, we can tell Draftail what element to use when displaying those blocks in the editor. 'element': 'span', } features.register_editor_plugin( 'draftail', feature_name, draftail_features.BlockFeature(control, css={'all': ['custom-theme.css']})) features.register_converter_rule( 'contentstate', feature_name, { 'from_database_format': { 'span[class=brand-color]': BlockElementHandler(type_) }, 'to_database_format': { 'block_map': { type_: { 'element': 'span', 'props': { 'class': 'brand-color' } } } }, })
def register_rich_text_drop_cap(features): feature_name = 'dropcap' type_ = 'DROPCAP' control = { 'type': type_, 'icon': 'title', 'description': 'Drop cap', 'element': 'div', } features.register_editor_plugin('draftail', feature_name, draftail_features.BlockFeature(control, )) features.register_converter_rule( 'contentstate', feature_name, { 'from_database_format': { 'div[class=drop-caps]': BlockElementHandler(type_) }, 'to_database_format': { 'block_map': { type_: { 'element': 'div', 'props': { 'class': 'drop-caps' } } } }, })
def register_help_text_feature(features): """ Registering the `inset-text` feature, which uses the `govuk-inset-text` class Stored as HTML with a `<div class="govuk-inset-text">` tag. """ feature_name = 'govuk-inset-text' type_ = 'govuk-inset-text' control = { 'type': type_, 'label': 'Q', 'description': 'GOVUK inset text', 'element': 'div', } features.register_editor_plugin('draftail', feature_name, draftail_features.BlockFeature(control)) features.register_converter_rule( 'contentstate', feature_name, { 'from_database_format': { 'div[class=govuk-inset-text]': BlockElementHandler(type_) }, 'to_database_format': { 'block_map': { type_: { 'element': 'div', 'props': { 'class': 'govuk-inset-text' } } } }, }) features.default_features.append('govuk-inset-text')
def register_strikethrough_feature(features): feature_name = 'div' type_ = 'div' tag = 'div' control = { 'type': type_, 'label': 'Toggle', 'description': 'Expansion Toggle', 'element': 'div' } features.register_editor_plugin('draftail', feature_name, draftail_features.BlockFeature(control)) db_conversion = { 'from_database_format': { tag: BlockElementHandler(type_) }, 'to_database_format': { 'block_map': { type_: tag } }, } features.register_converter_rule('contentstate', feature_name, db_conversion) features.default_features.append('div')
def register_blockquote_feature(features): """ https://docs.wagtail.io/en/v2.3/advanced_topics/customisation/extending_draftail.html#creating-new-blocks Registering the `blockquote` feature, which uses the `blockquote` Draft.js block type, and is stored as HTML with a `<blockquote>` tag. """ feature_name = "blockquote" type_ = "blockquote" tag = "blockquote" control = { "type": type_, "label": "❝", "description": "Blockquote", # Optionally, we can tell Draftail what element to use when displaying those blocks in the editor. "element": "blockquote", } features.register_editor_plugin( "draftail", feature_name, draftail_features.BlockFeature(control) ) features.register_converter_rule( "contentstate", feature_name, { "from_database_format": {tag: BlockElementHandler(type_)}, "to_database_format": {"block_map": {type_: tag}}, }, ) features.default_features.append("blockquote")
def register_button_feature(features): """ Registering the `button` feature, which allows you to assign the given css classes to a highlighted element, which makes it look like a button on the frontend """ feature_name = 'rich-text-button-link' type_ = 'rich-text-button-link' tag = 'div' control = { 'type': type_, 'label': 'Button', 'description': 'Make me look like a button', # Optionally, we can tell Draftail what element to use when displaying those blocks in the editor. 'element': 'div', } features.register_editor_plugin( 'draftail', feature_name, draftail_features.BlockFeature(control) ) features.register_converter_rule('contentstate', feature_name, { 'from_database_format': {tag: BlockElementHandler(type_)}, 'to_database_format': {'block_map': {type_: {'element': 'div', 'props': {'class': 'usa-button-primary rich-text-button-link'}}}}, })
def _register_block_plugin(features, plugin): features.register_editor_plugin( 'draftail', plugin.feature_name, draftail_features.BlockFeature(plugin.control)) features.register_converter_rule( 'contentstate', plugin.feature_name, { 'from_database_format': { plugin.tag: BlockElementHandler(plugin.type), }, 'to_database_format': { 'block_map': { plugin.type: plugin.tag, }, }, })
def register_help_text_feature(features): """ Registering the `help-text` feature, which uses the `help-text` Draft.js block type, and is stored as HTML with a `<div class="help-text">` tag. """ feature_name = 'blockquote-text' type_ = 'blockquote-text' control = { 'type': type_, 'label': '"', 'description': 'blockquote', # Optionally, we can tell Draftail what element to use when displaying those blocks in the editor. 'element': 'div', 'style': { 'display': 'block', 'background': 'yellow', }, } features.register_editor_plugin( 'draftail', feature_name, draftail_features.BlockFeature(control, css={'all': ['help-text.css']})) features.register_converter_rule( 'contentstate', feature_name, { 'from_database_format': { 'div[class=blockquote-holder with-bg-2]': BlockElementHandler(type_) }, 'to_database_format': { 'block_map': { type_: { 'element': 'div', 'props': { 'class': 'blockquote-holder with-bg-2' } } } }, }) features.default_features.append('blockquote-text')
def register_button_section_feature(features): """Support marking a group of links as buttons within Draftail (which can then be styled with custom CSS in the Admin) + ensure the block enclosing the links is rendered with a custom CSS class we can target in the published page.""" feature_name = "button-block" type_ = "button-block" tag = "div" # The value of _type contributes to an Admin CSS classname # of `.Draftail-block--button-block` control = { "type": type_, "label": "", "description": "Add a block will that render any links inside it as buttons", "element": "div", "icon": "icon icon-placeholder", } features.register_editor_plugin("draftail", feature_name, draftail_features.BlockFeature(control)) features.register_converter_rule( "contentstate", feature_name, { "from_database_format": { tag: BlockElementHandler(type_) }, "to_database_format": { "block_map": { type_: { "element": "div", "props": { "class": "links-as-buttons" }, # This CSS class is what's used on the rendered page } } }, }, ) features.default_features.append("button-block")
def register_roofline_feature(features): feature_name = 'roofline' type_ = 'roofline' control = { 'type': type_, 'label': '⛅', 'description': 'Dachzeile', 'element': 'p', } features.register_editor_plugin( 'draftail', feature_name, draftail_features.BlockFeature(control, css={'all': ['base.css']}) ) features.register_converter_rule('contentstate', feature_name, { 'from_database_format': {'p[class=roofline]': BlockElementHandler(type_)}, 'to_database_format': {'block_map': {type_: {'element': 'p', 'props': {'class': 'roofline'}}}}, }) features.default_features.append('roofline')
def register_revised_label_feature(features): feature_name = 'revised_label' type_ = 'revised_label' control = { 'type': type_, 'label': '♻️', 'description': 'Überarbeitet Label', 'element': 'span', } features.register_editor_plugin( 'draftail', feature_name, draftail_features.BlockFeature(control, css={'all': ['base.css']}) ) features.register_converter_rule('contentstate', feature_name, { 'from_database_format': {'p[label revised]': BlockElementHandler(type_)}, 'to_database_format': {'block_map': {type_: {'element': 'div', 'props': {'class': 'label revised'}}}}, }) features.default_features.append('revised_label')
def register_button_section_feature(features): """Register the button-block with Draftail.""" feature_name = 'button-block' type_ = 'button-block' tag = 'div' control = { 'type': type_, 'label': ' ', 'description': 'Button Section', 'element': 'div', 'icon': 'icon icon-grip', } features.register_editor_plugin('draftail', feature_name, draftail_features.BlockFeature(control)) features.register_converter_rule( 'contentstate', feature_name, { 'from_database_format': { tag: BlockElementHandler(type_) }, 'to_database_format': { 'block_map': { type_: { 'element': 'div', 'props': { 'class': 'rich-text-buttons' } } } }, }) if hasattr(settings, 'APPEND_BUTTON_BLOCK') and getattr( settings, 'APPEND_BUTTON_BLOCK', False): # Auto append feature to Draftail features.default_features.append('button-block')
def register_big_text_feature(features): """ Registering the `big-text` Draftail feature, which adds a paragraph around the selected text with its classs set to `big-text`. """ feature_name = "big-text" type_ = "big-text" control = { "type": type_, "label": "BT", "description": "Big Text", "element": "p", } features.register_editor_plugin( "draftail", feature_name, draftail_features.BlockFeature(control), ) db_conversion = { "from_database_format": { "p[class=big-text]": BlockElementHandler(type_) }, "to_database_format": { "block_map": { type_: { "element": "p", "props": { "class": "big-text" } } }, }, } features.register_converter_rule("contentstate", feature_name, db_conversion)
def register_centertext_feature(features): """Add <center>""" feature_name = 'center' type_ = 'CENTERTEXT' tag = 'div' control = { 'type': type_, 'label': '=', 'description': 'Center Text', 'style': { 'display': 'block', 'text-align': 'center' }, } features.register_editor_plugin('draftail', feature_name, draftail_features.BlockFeature(control)) db_conversion = { 'from_database_format': { tag: InlineStyleElementHandler(type_) }, 'to_database_format': { 'style_map': { type_: { "element": tag, "props": { "style": "text-align:center;" } } } } } features.register_converter_rule('contentstate', feature_name, db_conversion) features.default_features.append(feature_name)
def register_blockquote_feature(features): """ Registering the `blockquote` feature, which uses the `blockquote` Draft.js block type, and is stored as HTML with a `<blockquote>` tag. """ feature_name = 'blockquote' type_ = 'BLOCKQUOTE', tag = 'blockquote' control = { 'type': 'BLOCKQUOTE', 'label': '❝', 'description': ugettext('Blockquote'), # Optionally, we can tell Draftail what element to use when displaying those blocks in the editor. 'element': 'blockquote', } # features.default_features.append(feature_name) features.register_editor_plugin('draftail', feature_name, draftail_features.BlockFeature(control)) features.register_converter_rule( 'contentstate', feature_name, { 'from_database_format': { tag: BlockElementHandler(type_) }, 'to_database_format': { 'block_map': { type_: tag } }, }) features.register_converter_rule('editorhtml', feature_name, [ WhitelistRule(feature_name, allow_without_attributes), ])
def register_code_block_feature(features): feature_name = 'code-block' feature_type = 'CODE' features.register_editor_plugin( 'draftail', feature_name, draftail_features.BlockFeature({ 'type': feature_type, 'label': 'Code', 'description': 'Code block', 'element': 'pre', })) features.register_converter_rule( 'contentstate', feature_name, { 'from_database_format': { 'pre': BlockElementHandler(feature_type) }, 'to_database_format': { 'block_map': { feature_type: 'pre' } } }) features.default_features.append('code-block')
def register_code_block_feature(features): """ Register the `code-block` feature, which uses the `code-block` Draft.js block type and store it as HTML within a `<pre class="code">` tag. """ feature_name = 'code-block' feature_type = 'code-block' control = { 'type': feature_type, 'label': '{}', 'description': 'Code', } features.register_editor_plugin( 'draftail', feature_name, draftail_features.BlockFeature(control) ) features.register_converter_rule('contentstate', feature_name, { 'from_database_format': { 'pre': PreformattedTextElementHandler(feature_type), }, 'to_database_format': { 'block_map': { feature_type: { 'element': 'pre', 'props': {'class': 'code'}, }, }, }, }) features.default_features.append(feature_name) features.default_features.append('code') features.default_features.append('blockquote')
def register_pullquote_feature(features): """ Registering the `blockquote` feature, which uses the `blockquote` Draft.js block type, and is stored as HTML with a `<blockquote>` tag. """ feature_name = 'pullquote' type_ = 'pullquote' tag = 'blockquote' control = { 'type': type_, 'icon': 'icon icon-openquote', 'description': 'Pullquote', 'element': 'blockquote' } features.register_editor_plugin('draftail', feature_name, draftail_features.BlockFeature(control)) features.default_features.append(feature_name) features.register_converter_rule( 'contentstate', feature_name, { 'from_database_format': { 'blockquote[class="pullquote"]': BlockElementHandler(type_) }, 'to_database_format': { 'block_map': { type_: { 'element': tag, 'props': { 'class': 'pullquote' } } } }, })
def register_rich_text_end_of_article(features): feature_name = 'endofarticle' type_ = 'ENDOFARTICLE' control = { 'type': type_, 'icon': 'pick', 'description': 'End of Article', 'element': 'div', 'style': { 'background-color': 'black', 'height': '25px', 'margin': '10px auto', 'width': '25px', } } features.register_editor_plugin('draftail', feature_name, draftail_features.BlockFeature(control, )) features.register_converter_rule( 'contentstate', feature_name, { 'from_database_format': { 'div[class=end-of-article]': BlockElementHandler(type_) }, 'to_database_format': { 'block_map': { type_: { 'element': 'div', 'props': { 'class': 'end-of-article' } } } }, })
def register_core_features(features): # Hallo.js features.register_editor_plugin( 'hallo', 'hr', HalloPlugin( name='hallohr', js=[versioned_static('wagtailadmin/js/hallo-plugins/hallo-hr.js')], order=45, )) features.register_converter_rule( 'editorhtml', 'hr', [WhitelistRule('hr', allow_without_attributes)]) features.register_editor_plugin( 'hallo', 'link', HalloPlugin( name='hallowagtaillink', js=[ versioned_static('wagtailadmin/js/page-chooser-modal.js'), versioned_static( 'wagtailadmin/js/hallo-plugins/hallo-wagtaillink.js'), ], )) features.register_converter_rule('editorhtml', 'link', [ WhitelistRule('a', attribute_rule({'href': check_url})), LinkTypeRule('page', PageLinkHandler), ]) features.register_editor_plugin('hallo', 'bold', HalloFormatPlugin(format_name='bold')) features.register_converter_rule('editorhtml', 'bold', [ WhitelistRule('b', allow_without_attributes), WhitelistRule('strong', allow_without_attributes), ]) features.register_editor_plugin('hallo', 'italic', HalloFormatPlugin(format_name='italic')) features.register_converter_rule('editorhtml', 'italic', [ WhitelistRule('i', allow_without_attributes), WhitelistRule('em', allow_without_attributes), ]) headings_elements = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] headings_order_start = HalloHeadingPlugin.default_order + 1 for order, element in enumerate(headings_elements, start=headings_order_start): features.register_editor_plugin( 'hallo', element, HalloHeadingPlugin(element=element, order=order)) features.register_converter_rule( 'editorhtml', element, [WhitelistRule(element, allow_without_attributes)]) features.register_editor_plugin('hallo', 'ol', HalloListPlugin(list_type='ordered')) features.register_converter_rule('editorhtml', 'ol', [ WhitelistRule('ol', allow_without_attributes), WhitelistRule('li', allow_without_attributes), ]) features.register_editor_plugin('hallo', 'ul', HalloListPlugin(list_type='unordered')) features.register_converter_rule('editorhtml', 'ul', [ WhitelistRule('ul', allow_without_attributes), WhitelistRule('li', allow_without_attributes), ]) # Draftail features.register_editor_plugin( 'draftail', 'hr', draftail_features.BooleanFeature('enableHorizontalRule')) features.register_converter_rule( 'contentstate', 'hr', { 'from_database_format': { 'hr': HorizontalRuleHandler(), }, 'to_database_format': { 'entity_decorators': { 'HORIZONTAL_RULE': lambda props: DOM.create_element('hr') } } }) features.register_editor_plugin( 'draftail', 'h1', draftail_features.BlockFeature({ 'label': 'H1', 'type': 'header-one', 'description': ugettext('Heading {level}').format(level=1), })) features.register_converter_rule( 'contentstate', 'h1', { 'from_database_format': { 'h1': BlockElementHandler('header-one'), }, 'to_database_format': { 'block_map': { 'header-one': 'h1' } } }) features.register_editor_plugin( 'draftail', 'h2', draftail_features.BlockFeature({ 'label': 'H2', 'type': 'header-two', 'description': ugettext('Heading {level}').format(level=2), })) features.register_converter_rule( 'contentstate', 'h2', { 'from_database_format': { 'h2': BlockElementHandler('header-two'), }, 'to_database_format': { 'block_map': { 'header-two': 'h2' } } }) features.register_editor_plugin( 'draftail', 'h3', draftail_features.BlockFeature({ 'label': 'H3', 'type': 'header-three', 'description': ugettext('Heading {level}').format(level=3), })) features.register_converter_rule( 'contentstate', 'h3', { 'from_database_format': { 'h3': BlockElementHandler('header-three'), }, 'to_database_format': { 'block_map': { 'header-three': 'h3' } } }) features.register_editor_plugin( 'draftail', 'h4', draftail_features.BlockFeature({ 'label': 'H4', 'type': 'header-four', 'description': ugettext('Heading {level}').format(level=4), })) features.register_converter_rule( 'contentstate', 'h4', { 'from_database_format': { 'h4': BlockElementHandler('header-four'), }, 'to_database_format': { 'block_map': { 'header-four': 'h4' } } }) features.register_editor_plugin( 'draftail', 'h5', draftail_features.BlockFeature({ 'label': 'H5', 'type': 'header-five', 'description': ugettext('Heading {level}').format(level=5), })) features.register_converter_rule( 'contentstate', 'h5', { 'from_database_format': { 'h5': BlockElementHandler('header-five'), }, 'to_database_format': { 'block_map': { 'header-five': 'h5' } } }) features.register_editor_plugin( 'draftail', 'h6', draftail_features.BlockFeature({ 'label': 'H6', 'type': 'header-six', 'description': ugettext('Heading {level}').format(level=6), })) features.register_converter_rule( 'contentstate', 'h6', { 'from_database_format': { 'h6': BlockElementHandler('header-six'), }, 'to_database_format': { 'block_map': { 'header-six': 'h6' } } }) features.register_editor_plugin( 'draftail', 'ul', draftail_features.BlockFeature({ 'type': 'unordered-list-item', 'icon': 'list-ul', 'description': ugettext('Bulleted list'), })) features.register_converter_rule( 'contentstate', 'ul', { 'from_database_format': { 'ul': ListElementHandler('unordered-list-item'), 'li': ListItemElementHandler(), }, 'to_database_format': { 'block_map': { 'unordered-list-item': { 'element': 'li', 'wrapper': 'ul' } } } }) features.register_editor_plugin( 'draftail', 'ol', draftail_features.BlockFeature({ 'type': 'ordered-list-item', 'icon': 'list-ol', 'description': ugettext('Numbered list'), })) features.register_converter_rule( 'contentstate', 'ol', { 'from_database_format': { 'ol': ListElementHandler('ordered-list-item'), 'li': ListItemElementHandler(), }, 'to_database_format': { 'block_map': { 'ordered-list-item': { 'element': 'li', 'wrapper': 'ol' } } } }) features.register_editor_plugin( 'draftail', 'blockquote', draftail_features.BlockFeature({ 'type': 'blockquote', 'icon': 'openquote', 'description': ugettext('Blockquote'), })) features.register_converter_rule( 'contentstate', 'blockquote', { 'from_database_format': { 'blockquote': BlockElementHandler('blockquote'), }, 'to_database_format': { 'block_map': { 'blockquote': 'blockquote' } } }) features.register_editor_plugin( 'draftail', 'bold', draftail_features.InlineStyleFeature({ 'type': 'BOLD', 'icon': 'bold', 'description': ugettext('Bold'), })) features.register_converter_rule( 'contentstate', 'bold', { 'from_database_format': { 'b': InlineStyleElementHandler('BOLD'), 'strong': InlineStyleElementHandler('BOLD'), }, 'to_database_format': { 'style_map': { 'BOLD': 'b' } } }) features.register_editor_plugin( 'draftail', 'italic', draftail_features.InlineStyleFeature({ 'type': 'ITALIC', 'icon': 'italic', 'description': ugettext('Italic'), })) features.register_converter_rule( 'contentstate', 'italic', { 'from_database_format': { 'i': InlineStyleElementHandler('ITALIC'), 'em': InlineStyleElementHandler('ITALIC'), }, 'to_database_format': { 'style_map': { 'ITALIC': 'i' } } }) features.register_editor_plugin( 'draftail', 'link', draftail_features.EntityFeature( { 'type': 'LINK', 'icon': 'link', 'description': ugettext('Link'), # We want to enforce constraints on which links can be pasted into rich text. # Keep only the attributes Wagtail needs. 'attributes': ['url', 'id', 'parentId'], 'whitelist': { # Keep pasted links with http/https protocol, and not-pasted links (href = undefined). 'href': "^(http:|https:|undefined$)", } }, js=[ versioned_static('wagtailadmin/js/page-chooser-modal.js'), ])) features.register_converter_rule( 'contentstate', 'link', { 'from_database_format': { 'a[href]': ExternalLinkElementHandler('LINK'), 'a[linktype="page"]': PageLinkElementHandler('LINK'), }, 'to_database_format': { 'entity_decorators': { 'LINK': link_entity } } }) features.register_editor_plugin( 'draftail', 'superscript', draftail_features.InlineStyleFeature({ 'type': 'SUPERSCRIPT', 'icon': 'superscript', 'description': ugettext('Superscript'), })) features.register_converter_rule( 'contentstate', 'superscript', { 'from_database_format': { 'sup': InlineStyleElementHandler('SUPERSCRIPT'), }, 'to_database_format': { 'style_map': { 'SUPERSCRIPT': 'sup' } } }) features.register_editor_plugin( 'draftail', 'subscript', draftail_features.InlineStyleFeature({ 'type': 'SUBSCRIPT', 'icon': 'subscript', 'description': ugettext('Subscript'), })) features.register_converter_rule( 'contentstate', 'subscript', { 'from_database_format': { 'sub': InlineStyleElementHandler('SUBSCRIPT'), }, 'to_database_format': { 'style_map': { 'SUBSCRIPT': 'sub' } } }) features.register_editor_plugin( 'draftail', 'strikethrough', draftail_features.InlineStyleFeature({ 'type': 'STRIKETHROUGH', 'icon': 'strikethrough', 'description': ugettext('Strikethrough'), })) features.register_converter_rule( 'contentstate', 'strikethrough', { 'from_database_format': { 's': InlineStyleElementHandler('STRIKETHROUGH'), }, 'to_database_format': { 'style_map': { 'STRIKETHROUGH': 's' } } }) features.register_editor_plugin( 'draftail', 'code', draftail_features.InlineStyleFeature({ 'type': 'CODE', 'icon': 'code', 'description': ugettext('Code'), })) features.register_converter_rule( 'contentstate', 'code', { 'from_database_format': { 'code': InlineStyleElementHandler('CODE'), }, 'to_database_format': { 'style_map': { 'CODE': 'code' } } })
def register_core_features(features): features.register_converter_rule( "editorhtml", "link", [ WhitelistRule("a", attribute_rule({"href": check_url})), LinkTypeRule("page", PageLinkHandler), ], ) features.register_converter_rule( "editorhtml", "bold", [ WhitelistRule("b", allow_without_attributes), WhitelistRule("strong", allow_without_attributes), ], ) features.register_converter_rule( "editorhtml", "italic", [ WhitelistRule("i", allow_without_attributes), WhitelistRule("em", allow_without_attributes), ], ) headings_elements = ["h1", "h2", "h3", "h4", "h5", "h6"] for order, element in enumerate(headings_elements): features.register_converter_rule( "editorhtml", element, [WhitelistRule(element, allow_without_attributes)]) features.register_converter_rule( "editorhtml", "ol", [ WhitelistRule("ol", allow_without_attributes), WhitelistRule("li", allow_without_attributes), ], ) features.register_converter_rule( "editorhtml", "ul", [ WhitelistRule("ul", allow_without_attributes), WhitelistRule("li", allow_without_attributes), ], ) # Draftail features.register_editor_plugin( "draftail", "hr", draftail_features.BooleanFeature("enableHorizontalRule")) features.register_converter_rule( "contentstate", "hr", { "from_database_format": { "hr": HorizontalRuleHandler(), }, "to_database_format": { "entity_decorators": { "HORIZONTAL_RULE": lambda props: DOM.create_element("hr") } }, }, ) features.register_editor_plugin( "draftail", "h1", draftail_features.BlockFeature({ "label": "H1", "type": "header-one", "description": gettext("Heading %(level)d") % { "level": 1 }, }), ) features.register_converter_rule( "contentstate", "h1", { "from_database_format": { "h1": BlockElementHandler("header-one"), }, "to_database_format": { "block_map": { "header-one": "h1" } }, }, ) features.register_editor_plugin( "draftail", "h2", draftail_features.BlockFeature({ "label": "H2", "type": "header-two", "description": gettext("Heading %(level)d") % { "level": 2 }, }), ) features.register_converter_rule( "contentstate", "h2", { "from_database_format": { "h2": BlockElementHandler("header-two"), }, "to_database_format": { "block_map": { "header-two": "h2" } }, }, ) features.register_editor_plugin( "draftail", "h3", draftail_features.BlockFeature({ "label": "H3", "type": "header-three", "description": gettext("Heading %(level)d") % { "level": 3 }, }), ) features.register_converter_rule( "contentstate", "h3", { "from_database_format": { "h3": BlockElementHandler("header-three"), }, "to_database_format": { "block_map": { "header-three": "h3" } }, }, ) features.register_editor_plugin( "draftail", "h4", draftail_features.BlockFeature({ "label": "H4", "type": "header-four", "description": gettext("Heading %(level)d") % { "level": 4 }, }), ) features.register_converter_rule( "contentstate", "h4", { "from_database_format": { "h4": BlockElementHandler("header-four"), }, "to_database_format": { "block_map": { "header-four": "h4" } }, }, ) features.register_editor_plugin( "draftail", "h5", draftail_features.BlockFeature({ "label": "H5", "type": "header-five", "description": gettext("Heading %(level)d") % { "level": 5 }, }), ) features.register_converter_rule( "contentstate", "h5", { "from_database_format": { "h5": BlockElementHandler("header-five"), }, "to_database_format": { "block_map": { "header-five": "h5" } }, }, ) features.register_editor_plugin( "draftail", "h6", draftail_features.BlockFeature({ "label": "H6", "type": "header-six", "description": gettext("Heading %(level)d") % { "level": 6 }, }), ) features.register_converter_rule( "contentstate", "h6", { "from_database_format": { "h6": BlockElementHandler("header-six"), }, "to_database_format": { "block_map": { "header-six": "h6" } }, }, ) features.register_editor_plugin( "draftail", "ul", draftail_features.BlockFeature({ "type": "unordered-list-item", "icon": "list-ul", "description": gettext("Bulleted list"), }), ) features.register_converter_rule( "contentstate", "ul", { "from_database_format": { "ul": ListElementHandler("unordered-list-item"), "li": ListItemElementHandler(), }, "to_database_format": { "block_map": { "unordered-list-item": { "element": "li", "wrapper": "ul" } } }, }, ) features.register_editor_plugin( "draftail", "ol", draftail_features.BlockFeature({ "type": "ordered-list-item", "icon": "list-ol", "description": gettext("Numbered list"), }), ) features.register_converter_rule( "contentstate", "ol", { "from_database_format": { "ol": ListElementHandler("ordered-list-item"), "li": ListItemElementHandler(), }, "to_database_format": { "block_map": { "ordered-list-item": { "element": "li", "wrapper": "ol" } } }, }, ) features.register_editor_plugin( "draftail", "blockquote", draftail_features.BlockFeature({ "type": "blockquote", "icon": "openquote", "description": gettext("Blockquote"), }), ) features.register_converter_rule( "contentstate", "blockquote", { "from_database_format": { "blockquote": BlockElementHandler("blockquote"), }, "to_database_format": { "block_map": { "blockquote": "blockquote" } }, }, ) features.register_editor_plugin( "draftail", "bold", draftail_features.InlineStyleFeature({ "type": "BOLD", "icon": "bold", "description": gettext("Bold"), }), ) features.register_converter_rule( "contentstate", "bold", { "from_database_format": { "b": InlineStyleElementHandler("BOLD"), "strong": InlineStyleElementHandler("BOLD"), }, "to_database_format": { "style_map": { "BOLD": "b" } }, }, ) features.register_editor_plugin( "draftail", "italic", draftail_features.InlineStyleFeature({ "type": "ITALIC", "icon": "italic", "description": gettext("Italic"), }), ) features.register_converter_rule( "contentstate", "italic", { "from_database_format": { "i": InlineStyleElementHandler("ITALIC"), "em": InlineStyleElementHandler("ITALIC"), }, "to_database_format": { "style_map": { "ITALIC": "i" } }, }, ) features.register_editor_plugin( "draftail", "link", draftail_features.EntityFeature( { "type": "LINK", "icon": "link", "description": gettext("Link"), # We want to enforce constraints on which links can be pasted into rich text. # Keep only the attributes Wagtail needs. "attributes": ["url", "id", "parentId"], "whitelist": { # Keep pasted links with http/https protocol, and not-pasted links (href = undefined). "href": "^(http:|https:|undefined$)", }, }, js=[ "wagtailadmin/js/page-chooser-modal.js", ], ), ) features.register_converter_rule( "contentstate", "link", { "from_database_format": { "a[href]": ExternalLinkElementHandler("LINK"), 'a[linktype="page"]': PageLinkElementHandler("LINK"), }, "to_database_format": { "entity_decorators": { "LINK": link_entity } }, }, ) features.register_editor_plugin( "draftail", "superscript", draftail_features.InlineStyleFeature({ "type": "SUPERSCRIPT", "icon": "superscript", "description": gettext("Superscript"), }), ) features.register_converter_rule( "contentstate", "superscript", { "from_database_format": { "sup": InlineStyleElementHandler("SUPERSCRIPT"), }, "to_database_format": { "style_map": { "SUPERSCRIPT": "sup" } }, }, ) features.register_editor_plugin( "draftail", "subscript", draftail_features.InlineStyleFeature({ "type": "SUBSCRIPT", "icon": "subscript", "description": gettext("Subscript"), }), ) features.register_converter_rule( "contentstate", "subscript", { "from_database_format": { "sub": InlineStyleElementHandler("SUBSCRIPT"), }, "to_database_format": { "style_map": { "SUBSCRIPT": "sub" } }, }, ) features.register_editor_plugin( "draftail", "strikethrough", draftail_features.InlineStyleFeature({ "type": "STRIKETHROUGH", "icon": "strikethrough", "description": gettext("Strikethrough"), }), ) features.register_converter_rule( "contentstate", "strikethrough", { "from_database_format": { "s": InlineStyleElementHandler("STRIKETHROUGH"), }, "to_database_format": { "style_map": { "STRIKETHROUGH": "s" } }, }, ) features.register_editor_plugin( "draftail", "code", draftail_features.InlineStyleFeature({ "type": "CODE", "icon": "code", "description": gettext("Code"), }), ) features.register_converter_rule( "contentstate", "code", { "from_database_format": { "code": InlineStyleElementHandler("CODE"), }, "to_database_format": { "style_map": { "CODE": "code" } }, }, )