Skip to content

Commit b49510e

Browse files
committed
unify dom name check (fix #380)
1 parent ddedb23 commit b49510e

File tree

4 files changed

+32
-27
lines changed

4 files changed

+32
-27
lines changed

pywebio/input.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,15 @@
7272
Functions doc
7373
--------------
7474
"""
75-
import os.path
75+
import copy
7676
import logging
77+
import os.path
7778
from collections.abc import Mapping
78-
import copy
7979

8080
from .io_ctrl import single_input, input_control, output_register_callback, send_msg, single_input_kwargs
81-
from .session import get_current_session, get_current_task_id
82-
from .utils import Setter, is_html_safe_value, parse_file_size
8381
from .platform import page as platform_setting
82+
from .session import get_current_session, get_current_task_id
83+
from .utils import Setter, parse_file_size, check_dom_name_value
8484

8585
logger = logging.getLogger(__name__)
8686

@@ -99,7 +99,8 @@
9999
SELECT = 'select'
100100
TEXTAREA = 'textarea'
101101

102-
__all__ = ['TEXT', 'NUMBER', 'FLOAT', 'PASSWORD', 'URL', 'DATE', 'TIME', 'COLOR', 'DATETIME_LOCAL', 'input', 'textarea', 'select',
102+
__all__ = ['TEXT', 'NUMBER', 'FLOAT', 'PASSWORD', 'URL', 'DATE', 'TIME', 'COLOR', 'DATETIME_LOCAL', 'input', 'textarea',
103+
'select',
103104
'checkbox', 'radio', 'actions', 'file_upload', 'slider', 'input_group', 'input_update']
104105

105106

@@ -112,7 +113,7 @@ def _parse_args(kwargs, excludes=()):
112113
:return:(spec,valid_func)
113114
"""
114115
kwargs = {k: v for k, v in kwargs.items() if v is not None and k not in excludes}
115-
assert is_html_safe_value(kwargs.get('name', '')), '`name` can only contains a-z、A-Z、0-9、_、-'
116+
check_dom_name_value(kwargs.get('name', ''), '`name`')
116117

117118
kwargs.update(kwargs.get('other_html_attrs', {}))
118119
kwargs.pop('other_html_attrs', None)

pywebio/output.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@
217217

218218
from .io_ctrl import output_register_callback, send_msg, Output, safely_destruct_output_when_exp, OutputList, scope2dom
219219
from .session import get_current_session, download
220-
from .utils import random_str, iscoroutinefunction, is_html_safe_value
220+
from .utils import random_str, iscoroutinefunction, check_dom_name_value
221221

222222
try:
223223
from PIL.Image import Image as PILImage
@@ -274,7 +274,7 @@ def set_scope(name, container_scope=None, position=OutputPosition.BOTTOM, if_exi
274274
"""
275275
if container_scope is None:
276276
container_scope = get_scope()
277-
assert is_html_safe_value(name), "Scope name only allow letter/digit/'_'/'-' char."
277+
check_dom_name_value(name, 'scope name')
278278
send_msg('output_ctl', dict(set_scope=scope2dom(name, no_css_selector=True),
279279
container=scope2dom(container_scope),
280280
position=position, if_exist=if_exist))
@@ -961,6 +961,7 @@ def put_processbar(name, init=0, label=None, auto_close=False, scope=None,
961961
962962
.. seealso:: use `set_processbar()` to set the progress of progress bar
963963
"""
964+
check_dom_name_value(name)
964965
processbar_id = 'webio-processbar-%s' % name
965966
percentage = init * 100
966967
label = '%.1f%%' % percentage if label is None else label
@@ -985,6 +986,8 @@ def set_processbar(name, value, label=None):
985986
"""
986987
from pywebio.session import run_js
987988

989+
check_dom_name_value(name)
990+
988991
processbar_id = 'webio-processbar-%s' % name
989992
percentage = value * 100
990993
label = '%.1f%%' % percentage if label is None else label
@@ -1410,7 +1413,7 @@ def put_scope(name, content=[], scope=None, position=OutputPosition.BOTTOM) -> O
14101413
if not isinstance(content, list):
14111414
content = [content]
14121415

1413-
assert is_html_safe_value(name), "Scope name only allow letter/digit/'_'/'-' char."
1416+
check_dom_name_value(name, 'scope name')
14141417
dom_id = scope2dom(name, no_css_selector=True)
14151418

14161419
spec = _get_output_spec('scope', dom_id=dom_id, contents=content, scope=scope, position=position)
@@ -1754,8 +1757,7 @@ def app():
17541757

17551758
if name is None:
17561759
name = random_str(10)
1757-
else:
1758-
assert is_html_safe_value(name), "Scope name only allow letter/digit/'_'/'-' char."
1760+
check_dom_name_value(name, 'scope name')
17591761

17601762
def before_enter():
17611763
if create_scope:

pywebio/pin.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -131,16 +131,14 @@
131131
from pywebio.output import _get_output_spec
132132
from .io_ctrl import send_msg, single_input_kwargs, output_register_callback
133133
from .session import next_client_event, chose_impl
134+
from .utils import check_dom_name_value
134135

135136
_pin_name_chars = set(string.ascii_letters + string.digits + '_-')
136137

137138
__all__ = ['put_input', 'put_textarea', 'put_select', 'put_checkbox', 'put_radio', 'put_slider', 'put_actions',
138139
'pin', 'pin_update', 'pin_wait_change', 'pin_on_change']
139140

140141

141-
def check_name(name):
142-
assert all(i in _pin_name_chars for i in name), "pin `name` can only contain letters, digits, " \
143-
"minus sign and underscore"
144142

145143

146144
def _pin_output(single_input_return, scope, position):
@@ -153,7 +151,7 @@ def put_input(name, type='text', *, label='', value=None, placeholder=None, read
153151
help_text=None, scope=None, position=OutputPosition.BOTTOM) -> Output:
154152
"""Output an input widget. Refer to: `pywebio.input.input()`"""
155153
from pywebio.input import input
156-
check_name(name)
154+
check_dom_name_value(name, 'pin `name`')
157155
single_input_return = input(name=name, label=label, value=value, type=type, placeholder=placeholder,
158156
readonly=readonly, datalist=datalist, help_text=help_text)
159157
return _pin_output(single_input_return, scope, position)
@@ -163,7 +161,7 @@ def put_textarea(name, *, label='', rows=6, code=None, maxlength=None, minlength
163161
readonly=None, help_text=None, scope=None, position=OutputPosition.BOTTOM) -> Output:
164162
"""Output a textarea widget. Refer to: `pywebio.input.textarea()`"""
165163
from pywebio.input import textarea
166-
check_name(name)
164+
check_dom_name_value(name, 'pin `name`')
167165
single_input_return = textarea(
168166
name=name, label=label, rows=rows, code=code, maxlength=maxlength,
169167
minlength=minlength, value=value, placeholder=placeholder, readonly=readonly, help_text=help_text)
@@ -174,7 +172,7 @@ def put_select(name, options=None, *, label='', multiple=None, value=None, help_
174172
scope=None, position=OutputPosition.BOTTOM) -> Output:
175173
"""Output a select widget. Refer to: `pywebio.input.select()`"""
176174
from pywebio.input import select
177-
check_name(name)
175+
check_dom_name_value(name, 'pin `name`')
178176
single_input_return = select(name=name, options=options, label=label, multiple=multiple,
179177
value=value, help_text=help_text)
180178
return _pin_output(single_input_return, scope, position)
@@ -184,7 +182,7 @@ def put_checkbox(name, options=None, *, label='', inline=None, value=None, help_
184182
scope=None, position=OutputPosition.BOTTOM) -> Output:
185183
"""Output a checkbox widget. Refer to: `pywebio.input.checkbox()`"""
186184
from pywebio.input import checkbox
187-
check_name(name)
185+
check_dom_name_value(name, 'pin `name`')
188186
single_input_return = checkbox(name=name, options=options, label=label, inline=inline, value=value,
189187
help_text=help_text)
190188
return _pin_output(single_input_return, scope, position)
@@ -194,7 +192,7 @@ def put_radio(name, options=None, *, label='', inline=None, value=None, help_tex
194192
scope=None, position=OutputPosition.BOTTOM) -> Output:
195193
"""Output a radio widget. Refer to: `pywebio.input.radio()`"""
196194
from pywebio.input import radio
197-
check_name(name)
195+
check_dom_name_value(name, 'pin `name`')
198196
single_input_return = radio(name=name, options=options, label=label, inline=inline, value=value,
199197
help_text=help_text)
200198
return _pin_output(single_input_return, scope, position)
@@ -204,7 +202,7 @@ def put_slider(name, *, label='', value=0, min_value=0, max_value=100, step=1, r
204202
scope=None, position=OutputPosition.BOTTOM) -> Output:
205203
"""Output a slide widget. Refer to: `pywebio.input.slider()`"""
206204
from pywebio.input import slider
207-
check_name(name)
205+
check_dom_name_value(name, 'pin `name`')
208206
single_input_return = slider(name=name, label=label, value=value, min_value=min_value, max_value=max_value,
209207
step=step, required=required, help_text=help_text)
210208
return _pin_output(single_input_return, scope, position)
@@ -220,7 +218,7 @@ def put_actions(name, *, label='', buttons=None, help_text=None,
220218
.. versionadded:: 1.4
221219
"""
222220
from pywebio.input import actions
223-
check_name(name)
221+
check_dom_name_value(name, 'pin `name`')
224222
single_input_return = actions(name=name, label=label, buttons=buttons, help_text=help_text)
225223
input_kwargs = single_input_kwargs(single_input_return)
226224
for btn in input_kwargs['item_spec']['buttons']:
@@ -329,7 +327,7 @@ def pin_update(name, **spec):
329327
:param spec: The pin widget parameters need to be updated.
330328
Note that those parameters can not be updated: ``type``, ``name``, ``code``, ``multiple``
331329
"""
332-
check_name(name)
330+
check_dom_name_value(name, 'pin `name`')
333331
attributes = parse_input_update_spec(spec)
334332
send_msg('pin_update', spec=dict(name=name, attributes=attributes))
335333

pywebio/utils.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -328,11 +328,6 @@ def __setitem__(self, key, value):
328328
_html_value_chars = set(string.ascii_letters + string.digits + '_-')
329329

330330

331-
def is_html_safe_value(val):
332-
"""检查是字符串是否可以作为html属性值"""
333-
return all(i in _html_value_chars for i in val)
334-
335-
336331
def check_webio_js():
337332
js_files = [os.path.join(STATIC_PATH, 'js', i) for i in ('pywebio.js', 'pywebio.min.js')]
338333
if any(os.path.isfile(f) for f in js_files):
@@ -378,3 +373,12 @@ def strip_space(text, n):
378373
for i in text.splitlines()
379374
)
380375
return '\n'.join(lines)
376+
377+
378+
def check_dom_name_value(value, name='`name`'):
379+
"""check the class name / id name of DOM element"""
380+
allowed_chars = set(string.ascii_letters + string.digits + '_-')
381+
382+
if not all(i in allowed_chars for i in value):
383+
raise ValueError(name + " can only contain letters, digits, "
384+
"hyphens ('-') and underscore ('_')")

0 commit comments

Comments
 (0)