comparison sat/tools/xml_tools.py @ 2782:b17e6fa1e607

core (XMLUI): new XHTMLBox widget: XHTMLBox is a textbox specialised in XHTML, i.e. it renders the XHTML when in read_only, and it allows to edit it. The XHTML is cleaned by default, the cleaning is done by Text Syntaxes plugin (actually there is a cleaning method which can be set by any plugin, but Text Syntaxes is the one which does it).
author Goffi <goffi@goffi.org>
date Sat, 19 Jan 2019 11:39:02 +0100
parents 003b8b4b56a7
children 777a582d9641
comparison
equal deleted inserted replaced
2781:816be0a23877 2782:b17e6fa1e607
39 SAT_FORM_PREFIX = "SAT_FORM_" 39 SAT_FORM_PREFIX = "SAT_FORM_"
40 SAT_PARAM_SEPARATOR = "_XMLUI_PARAM_" # used to have unique elements names 40 SAT_PARAM_SEPARATOR = "_XMLUI_PARAM_" # used to have unique elements names
41 html_entity_re = re.compile(r"&([a-zA-Z]+?);") 41 html_entity_re = re.compile(r"&([a-zA-Z]+?);")
42 XML_ENTITIES = ("quot", "amp", "apos", "lt", "gt") 42 XML_ENTITIES = ("quot", "amp", "apos", "lt", "gt")
43 43
44 # method to clean XHTML, receive raw unsecure XML or HTML, must return cleaned raw XHTML
45 # this method must be set during runtime
46 cleanXHTML = None
47
44 # TODO: move XMLUI stuff in a separate module 48 # TODO: move XMLUI stuff in a separate module
45 # TODO: rewrite this with lxml or ElementTree or domish.Element: it's complicated and difficult to maintain with current minidom implementation 49 # TODO: rewrite this with lxml or ElementTree or domish.Element: it's complicated and difficult to maintain with current minidom implementation
46 50
47 # Helper functions 51 # Helper functions
48 52
56 @param read_only (bool): if True and it makes sense, create a read only input widget 60 @param read_only (bool): if True and it makes sense, create a read only input widget
57 @return: a tuple (widget_type, widget_args, widget_kwargs) 61 @return: a tuple (widget_type, widget_args, widget_kwargs)
58 """ 62 """
59 widget_args = [field.value] 63 widget_args = [field.value]
60 widget_kwargs = {} 64 widget_kwargs = {}
61 if field.fieldType == "fixed" or field.fieldType is None: 65 if field.fieldType is None and field.ext_type is not None:
66 # we have an extended field
67 if field.ext_type == u"xml":
68 element = field.value
69 if element.uri == C.NS_XHTML:
70 widget_type = "xhtmlbox"
71 widget_args[0] = element.toXml()
72 widget_kwargs["read_only"] = read_only
73 else:
74 log.warning(u"unknown XML element, falling back to textbox")
75 widget_type = "textbox"
76 widget_args[0] = element.toXml()
77 widget_kwargs["read_only"] = read_only
78 else:
79 raise exceptions.DataError(u"unknown extended type {ext_type}".format(
80 ext_type = field.ext_type))
81
82 elif field.fieldType == "fixed" or field.fieldType is None:
62 widget_type = "text" 83 widget_type = "text"
63 if field.value is None: 84 if field.value is None:
64 if field.label is None: 85 if field.label is None:
65 log.warning(_("Fixed field has neither value nor label, ignoring it")) 86 log.warning(_(u"Fixed field has neither value nor label, ignoring it"))
66 field.value = "" 87 field.value = ""
67 else: 88 else:
68 field.value = field.label 89 field.value = field.label
69 field.label = None 90 field.label = None
70 widget_args[0] = field.value 91 widget_args[0] = field.value
1007 type = "password" 1028 type = "password"
1008 1029
1009 1030
1010 class TextBoxWidget(StringWidget): 1031 class TextBoxWidget(StringWidget):
1011 type = "textbox" 1032 type = "textbox"
1033
1034
1035 class XHTMLBoxWidget(StringWidget):
1036 """Specialized textbox to manipulate XHTML"""
1037 type = "xhtmlbox"
1038
1039 def __init__(self, xmlui, value, name=None, parent=None, read_only=False, clean=True):
1040 """
1041 @param clean(bool): if True, the XHTML is considered insecure and will be cleaned
1042 Only set to False if you are absolutely sure that the XHTML is safe (in other
1043 word, set to False only if you made the XHTML yourself)
1044 """
1045 if clean:
1046 if cleanXHTML is None:
1047 raise exceptions.NotFound(
1048 u"No cleaning method set, can't clean the XHTML")
1049 value = cleanXHTML(value)
1050
1051 super(XHTMLBoxWidget, self).__init__(
1052 xmlui, value=value, name=name, parent=parent, read_only=read_only)
1012 1053
1013 1054
1014 class JidInputWidget(StringWidget): 1055 class JidInputWidget(StringWidget):
1015 type = "jid_input" 1056 type = "jid_input"
1016 1057
1621 return d 1662 return d
1622 1663
1623 1664
1624 # Misc other funtions 1665 # Misc other funtions
1625 1666
1667 def isXHTMLField(field):
1668 """Check if a data_form.Field is an XHTML one"""
1669 return (field.fieldType is None and field.ext_type == u"xml" and
1670 field.value.uri == C.NS_XHTML)
1671
1626 1672
1627 class ElementParser(object): 1673 class ElementParser(object):
1628 """callable class to parse XML string into Element""" 1674 """callable class to parse XML string into Element"""
1629 1675
1630 # XXX: Found at http://stackoverflow.com/questions/2093400/how-to-create-twisted-words-xish-domish-element-entirely-from-raw-xml/2095942#2095942 1676 # XXX: Found at http://stackoverflow.com/questions/2093400/how-to-create-twisted-words-xish-domish-element-entirely-from-raw-xml/2095942#2095942