mirror of https://github.com/zulip/zulip.git
117 lines
3.7 KiB
Python
117 lines
3.7 KiB
Python
|
|
from typing import List, Set, Tuple
|
|
|
|
import os
|
|
import re
|
|
|
|
GENERIC_KEYWORDS = [
|
|
'active',
|
|
'alert',
|
|
'danger',
|
|
'condensed',
|
|
'disabled',
|
|
'error',
|
|
'expanded',
|
|
'fade-out',
|
|
'first',
|
|
'hide',
|
|
'in',
|
|
'show',
|
|
'notdisplayed',
|
|
'popover',
|
|
'no-border',
|
|
'rtl',
|
|
'second',
|
|
'selected',
|
|
'slide-left',
|
|
'success',
|
|
'text-error',
|
|
'warning',
|
|
'zoom-in', # TODO: clean these up, they are confusing
|
|
'zoom-out',
|
|
]
|
|
|
|
def raise_error(fn, i, line):
|
|
# type: (str, int, str) -> None
|
|
error = '''
|
|
In %s line %d there is the following line of code:
|
|
|
|
%s
|
|
|
|
Our tools want to be able to identify which modules
|
|
add which HTML/CSS classes, and we need two things to
|
|
happen:
|
|
|
|
- The code must explicitly name the class.
|
|
- Only one module can refer to that class (unless
|
|
it is something generic like an alert class).
|
|
|
|
If you get this error, you can usually address it by
|
|
refactoring your code to be more explicit, or you can
|
|
move the common code that sets the class to a library
|
|
module. If neither of those applies, you need to
|
|
modify %s
|
|
''' % (fn, i, line, __file__)
|
|
raise Exception(error)
|
|
|
|
def generic(html_class):
|
|
# type: (str) -> bool
|
|
for kw in GENERIC_KEYWORDS:
|
|
if kw in html_class:
|
|
return True
|
|
return False
|
|
|
|
def display(fns):
|
|
# type: (List[str]) -> None
|
|
for tup in find(fns):
|
|
# this format is for code generation purposes
|
|
print(' ' * 8 + repr(tup) + ',')
|
|
|
|
def find(fns):
|
|
# type: (List[str]) -> List[Tuple[str, str]]
|
|
encountered = set() # type: Set[str]
|
|
tups = [] # type: List[Tuple[str, str]]
|
|
for full_fn in fns:
|
|
# Don't check frontend tests, since they may do all sorts of
|
|
# extra hackery that isn't of interest to us.
|
|
if full_fn.startswith("frontend_tests"):
|
|
continue
|
|
lines = list(open(full_fn))
|
|
fn = os.path.basename(full_fn)
|
|
module_classes = set() # type: Set[str]
|
|
for i, line in enumerate(lines):
|
|
if 'addClass' in line:
|
|
html_classes = [] # type: List[str]
|
|
m = re.search(r'''addClass\(['"](.*?)['"]''', line)
|
|
if m:
|
|
html_classes = [m.group(1)]
|
|
if not html_classes:
|
|
if 'bar-success' in line:
|
|
html_classes = ['bar-success', 'bar-danger']
|
|
elif fn == 'hotspots.js' and 'arrow_placement' in line:
|
|
html_classes = ['arrow-top', 'arrow-left', 'arrow-bottom', 'arrow-right']
|
|
elif 'color_class' in line:
|
|
continue
|
|
elif 'stream_dark' in line:
|
|
continue
|
|
elif 'opts.' in line:
|
|
continue
|
|
elif fn == 'signup.js' and 'class_to_add' in line:
|
|
html_classes = ['error', 'success']
|
|
elif fn == 'ui_report.js' and 'status_classes' in line:
|
|
html_classes = ['alert']
|
|
|
|
if not html_classes:
|
|
raise_error(full_fn, i, line)
|
|
for html_class in html_classes:
|
|
if generic(html_class):
|
|
continue
|
|
if html_class in module_classes:
|
|
continue
|
|
if html_class in encountered:
|
|
raise_error(full_fn, i, line)
|
|
tups.append((fn, html_class))
|
|
module_classes.add(html_class)
|
|
encountered.add(html_class)
|
|
return tups
|