def blockquote_feature(features):
    # register a feature 'blockquote' which whitelists the <blockquote> element
    features.register_converter_rule('editorhtml', 'blockquote', [
        WhitelistRule('blockquote', allow_without_attributes),
    ])
    # register a feature 'a' which whitelists the <a> element
    features.register_converter_rule('editorhtml', 'a', [
        WhitelistRule(
            'a',
            attribute_rule({
                'href': check_url,
                'target': True,
                'data-toggle': True,
                'data-url': True,
                'data-target': True,
                'id': True
            })),
    ])
    # register a feature 'table' which whitelists the <table> element
    features.register_converter_rule('editorhtml', 'table', [
        WhitelistRule('table', attribute_rule({'style': True})),
    ])
    # register a feature 'table' which whitelists the <table> element
    features.register_converter_rule('editorhtml', 'tbody', [
        WhitelistRule('tbody', attribute_rule({'style': True})),
    ])
    # register a feature 'table' which whitelists the <table> element
    features.register_converter_rule('editorhtml', 'tr', [
        WhitelistRule('tr', attribute_rule({'style': True})),
    ])
    # register a feature 'table' which whitelists the <table> element
    features.register_converter_rule('editorhtml', 'td', [
        WhitelistRule('td', attribute_rule({'style': True})),
    ])
    # register a feature 'table' which whitelists the <table> element
    features.register_converter_rule('editorhtml', 'img', [
        WhitelistRule('img', attribute_rule({'alt': True})),
    ])
    # register a feature 'table' which whitelists the <table> element
    features.register_converter_rule('editorhtml', 'h1', [
        WhitelistRule('h1', attribute_rule({'id': True})),
    ])
    # add 'a' to the default feature set
    features.default_features.append('blockquote')
    # add 'a' to the default feature set
    features.default_features.append('a')
    # add 'table' to the default feature set
    features.default_features.append('table')
    # add 'tbody' to the default feature set
    features.default_features.append('tbody')
    # add 'tr' to the default feature set
    features.default_features.append('tr')
    # add 'td' to the default feature set
    features.default_features.append('td')
    # add 'img' to the default feature set
    features.default_features.append('img')
    # add 'h1' to the default feature set
    features.default_features.append('h1')
Example #2
0
    def register_span_feature(features):
        allow_html_class = attribute_rule({
            'class': True,
            'id': True,
        })

        # register a feature 'span'
        # which whitelists the <span> element
        features.register_converter_rule('editorhtml', 'span', [
            WhitelistRule('span', allow_html_class),
        ])

        # add 'span' to the default feature set
        features.default_features.append('span')
Example #3
0
def register_strikethrough_feature(features):
    """
    Registering the `strikethrough` feature, which uses the `STRIKETHROUGH` Draft.js inline style type,
    and is stored as HTML with an `<s>` tag.
    """
    feature_name = 'strikethrough'
    type_ = 'STRIKETHROUGH'
    tag = 's'

    control = {
        'type': type_,
        'label': 'S',
        # TODO
        # 'icon': 'icon icon-fa-strikethrough',
        # 'icon': ['M100 100 H 900 V 900 H 100 Z'],
        'description': ugettext('Strikethrough'),
        # This isn’t even required – Draftail has predefined styles for STRIKETHROUGH.
        # 'style': {'textDecoration': 'line-through'},
    }

    # features.default_features.append(feature_name)

    features.register_editor_plugin(
        'draftail', feature_name,
        draftail_features.InlineStyleFeature(control))

    db_conversion = {
        'from_database_format': {
            tag: InlineStyleElementHandler(type_)
        },
        'to_database_format': {
            'style_map': {
                type_: tag
            }
        },
    }

    features.register_converter_rule('contentstate', feature_name,
                                     db_conversion)

    features.register_converter_rule('editorhtml', feature_name, [
        WhitelistRule(feature_name, allow_without_attributes),
    ])
Example #4
0
def register_quotation_feature(features):
    """
    Registering the `quotation` feature, which uses the `QUOTATION` Draft.js inline style type,
    and is stored as HTML with an `<q>` tag.
    """
    feature_name = 'quotation'
    type_ = 'QUOTATION'
    tag = 'q'

    control = {
        'type': type_,
        'label': '❞',
        'description': ugettext('Quotation'),
        # This isn’t even required – Draftail has predefined styles for QUOTATION.
        # 'style': {'textDecoration': 'line-through'},
    }

    # features.default_features.append(feature_name)

    features.register_editor_plugin(
        'draftail', feature_name,
        draftail_features.InlineStyleFeature(control))

    db_conversion = {
        'from_database_format': {
            tag: InlineStyleElementHandler(type_)
        },
        'to_database_format': {
            'style_map': {
                type_: tag
            }
        },
    }

    features.register_converter_rule('contentstate', feature_name,
                                     db_conversion)

    features.register_converter_rule('editorhtml', feature_name, [
        WhitelistRule(feature_name, allow_without_attributes),
    ])
Example #5
0
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 all_tags_features(features):

    allowed_tags = [
        'iframe',
        'small',
        '[document]',
        'a',
        'b',
        'br',
        'div',
        'em',
        'h1',
        'h2',
        'h3',
        'h4',
        'h5',
        'h6',
        'hr',
        'i',
        'img',
        'li',
        'ol',
        'p',
        'strong',
        'sub',
        'sup',
        'ul',
    ]

    for html_tag in allowed_tags:
        # register a feature 'blockquote' which whitelists the <blockquote> element
        features.register_converter_rule('editorhtml', html_tag, [
            WhitelistRule(html_tag, allow_without_attributes),
        ])
        # add 'blockquote' to the default feature set
        features.default_features.append(html_tag)
Example #7
0
def whitelist_table(features):
    cell_attributes = attribute_rule({
        'rowspan': True,
        'colspan': True,
        'width': True,
        'height': True,
        'style': True
    })

    features.register_converter_rule('editorhtml', 'table', [
        WhitelistRule('table', attribute_rule({
            'style': True,
            'border': True
        })),
        WhitelistRule('thead', allow_without_attributes),
        WhitelistRule('tbody', allow_without_attributes),
        WhitelistRule('tfoot', allow_without_attributes),
        WhitelistRule('tr', allow_without_attributes),
        WhitelistRule('th', cell_attributes),
        WhitelistRule('td', cell_attributes),
    ])

    features.default_features.append('table')
Example #8
0
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'
                }
            }
        })
Example #9
0
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"
                }
            },
        },
    )
Example #10
0
def register_core_features(features):
    features.register_editor_plugin(
        'hallo', 'hr',
        HalloPlugin(
            name='hallohr',
            js=['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=['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),
    ])

    for element in ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']:
        features.register_editor_plugin('hallo', element,
                                        HalloHeadingPlugin(element=element))
        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),
    ])
Example #11
0
def whitelist_blockquote(features):
    features.register_converter_rule('editorhtml', 'blockquote', [
        WhitelistRule('style', handler=blacklist_tag()),
        WhitelistRule('style', handler=unwrap_tag()),
        WhitelistRule('style', handler=unwrap_tag()),
        WhitelistRule('blockquote', attribute_rule({'class': True})),
        WhitelistRule('p', attribute_rule({'class': True})),
        WhitelistRule('h2', attribute_rule({'class': True})),
        WhitelistRule('h3', attribute_rule({'class': True})),
        WhitelistRule('h4', attribute_rule({'class': True})),
        WhitelistRule('h5', attribute_rule({'class': True})),
        WhitelistRule(
            'iframe',
            attribute_rule({
                'style': True,
                'src': True,
                'width': True,
                'height': True
            })),
        WhitelistRule(
            'img',
            attribute_rule({
                'srcset': True,
                'class': True,
                'alt': True,
                'sizes': True,
                'width': True,
                'height': True,
                'src': True
            })),
        WhitelistRule(
            'audio',
            attribute_rule({
                'class': True,
                'src': True,
                'controls': True,
            })),
        WhitelistRule(
            'source',
            attribute_rule({
                'class': True,
                'src': True,
                'type': True,
            })),
    ])
    features.default_features.append('blockquote')
Example #12
0
    allow_without_attributes,
    'sup':
    allow_without_attributes,
    'table':
    attribute_rule(allRules),
    'tr':
    allow_without_attributes,
    'td':
    allow_without_attributes,
    'th':
    allow_without_attributes,
}

RULES = []
for k, v in ELEMENT_RULES.items():
    RULES.append(WhitelistRule(k, v))


class TinyMCERichTextArea(WidgetWithScript, widgets.Textarea):
    @classmethod
    def getDefaultArgs(cls):
        return {
            'buttons': [[
                ['undo', 'redo'],
                ['styleselect'],
                ['bold', 'italic'],
                ['bullist', 'numlist', 'outdent', 'indent'],
                ['table'],
                ['link', 'unlink'],
                ['wagtaildoclink', 'wagtailimage', 'wagtailembed'],
                ['pastetext', 'fullscreen'],