diff --git a/tools/build/build.py b/tools/build/build.py index 9c1e3592..ba21d522 100755 --- a/tools/build/build.py +++ b/tools/build/build.py @@ -1,7 +1,6 @@ #!/usr/bin/env python #vim: et:ts=4:sw=4:sts=4 -import base64 import json import os import ox @@ -30,26 +29,41 @@ def build_oxjs(downloads=False, geo=False): year = time.strftime('%Y', time.gmtime()) comment = ' OxJS %s (c) %s 0x2620, dual-licensed GPL/MIT, see https://oxjs.org for details ' % (version, year) - # SVGs - path = source_path + 'Ox.UI/themes/classic/svg/' - for filename in os.listdir(path): + # Ox.UI Theme Data + theme_data = {} + themes = [dirname for dirname in os.listdir(source_path + 'Ox.UI/themes/') if not dirname[0] in '._'] + for theme in themes: + theme_data[theme] = read_jsonc(source_path + 'Ox.UI/themes/%s/json/theme.jsonc' % theme) + theme_data[theme]['themeClass'] = 'OxTheme' + theme[0].upper() + theme[1:] + + # Ox.UI CSS + css = read_file(source_path + 'Ox.UI/css/Ox.UI.css') + css = css.replace('$import', '\n'.join([ + '@import url("../themes/%s/css/theme.css");' % theme for theme in themes + ])) + write_file('%sOx.UI/css/Ox.UI.css' % build_path, css) + write_file('%sOx.UI/css/Ox.UI.css' % dev_path, css) + + # Ox.UI Theme CSS + css = read_file(source_path + 'Ox.UI/css/theme.css') + for theme in themes: + theme_css = parse_css(css, theme_data[theme]) + write_file('%sOx.UI/themes/%s/css/theme.css' % (build_path, theme), theme_css) + write_file('%sOx.UI/themes/%s/css/theme.css' % (dev_path, theme), theme_css) + + # Ox.UI SVGs + ui_images = {} + path = source_path + 'Ox.UI/svg/' + for filename in [filename for filename in os.listdir(path) if not filename[0] in '._']: svg = read_file(path + filename) - svg = svg.replace('#000000', '#XXXXXX').replace('#404040', '#C0C0C0').replace('#FFFFFF', '#000000').replace('#XXXXXX', '#FFFFFF') - write_file(path.replace('/classic/', '/modern/') + filename, svg) - imageURLs = {} - imageDataURLs = {} - for theme in ['classic', 'modern']: - path = source_path + 'Ox.UI/themes/' + theme + '/svg/' - for filename in os.listdir(path): - if not filename[0] in '._' and not filename.endswith('~'): - key = theme + '/' + filename[:-4] - imageURLs[key] = os.path.join(path, filename).replace(source_path, '') - data = re.sub('\n\s+', '', read_file(path + filename)) - imageDataURLs[key] = 'data:image/svg+xml;base64,' + base64.b64encode(data) - write_file(build_path + 'Ox.UI/json/Ox.UI.imageURLs.json', json.dumps(imageURLs, sort_keys=True)) - write_file(build_path + 'Ox.UI/json/Ox.UI.imageDataURLs.json', json.dumps(imageDataURLs, sort_keys=True)) - write_file(dev_path + 'Ox.UI/json/Ox.UI.imageURLs.json', json.dumps(imageURLs, indent=4, sort_keys=True)) - write_file(dev_path + 'Ox.UI/json/Ox.UI.imageDataURLs.json', json.dumps(imageDataURLs, indent=4, sort_keys=True)) + svg = re.sub('\n\s*', '', svg) + svg = re.sub('', '', svg) + ui_images[filename[:-4]] = svg + if filename.startswith('symbolLoading'): + for theme in themes: + theme_svg = re.sub('#808080', format_hex(theme_data[theme]['symbolDefaultColor']), svg) + write_file('%sOx.UI/themes/%s/svg/%s' % (build_path, theme, filename), theme_svg) + write_file('%sOx.UI/themes/%s/svg/%s' % (dev_path, theme, filename), theme_svg) # copy & link ui_files = {'build': [], 'dev': []} @@ -57,12 +71,15 @@ def build_oxjs(downloads=False, geo=False): for filename in filenames: if not '_' in path and not filename[0] in '._' \ and not filename.endswith('~') \ + and not filename.endswith('.css') \ + and not '/Ox.UI/svg' in path \ and (geo or not '/Ox.Geo/' in path): # write copies in build path source = os.path.join(path, filename) - is_jquery = re.match('^jquery-[\d\.]+\.js$', filename) - is_jquery_min = re.match('^jquery-[\d\.]+\.min\.js$', filename) - is_jquery_plugin = re.match('^jquery\..*?\.js$', filename) + is_jquery = re.search('^jquery-[\d\.]+\.js$', filename) + is_jquery_min = re.search('^jquery-[\d\.]+\.min\.js$', filename) + is_jquery_plugin = re.search('^jquery\..*?\.js$', filename) + is_jsonc = re.search('\.jsonc$', filename) if is_jquery or is_jquery_min: target = os.path.join(path.replace(source_path, build_path), 'jquery.js') else: @@ -71,9 +88,9 @@ def build_oxjs(downloads=False, geo=False): ui_files['build'].append(target.replace(build_path, '')) ui_files['dev'].append(target.replace(build_path, '')) if not '/Ox/js' in source and not '/Ox.UI/js/' in source and not is_jquery: - if re.match('^Ox\..+\.js$', filename): + if re.match('^Ox\..+\.js$', filename) or is_jsonc: js = read_file(source) - write_file(target, ox.js.minify(js, comment)) + write_file(target, ox.js.minify(js, '' if is_jsonc else comment)) else: copy_file(source, target) # write links in dev path @@ -141,14 +158,14 @@ def build_oxjs(downloads=False, geo=False): for path, dirnames, filenames in os.walk(root): for filename in sorted(filenames): # jquery gets included by Ox.UI loader - # theme css files get included by main css + # Ox.UI.css imports all other css files # svgs are loaded as URLs or dataURLs # browser images appear before load - if path != root and not '_' in path and not filename[0] in '._'\ - and not filename.endswith('~')\ - and not 'jquery' in filename\ - and not ('/themes/' in path and filename.endswith('.css'))\ - and not filename.endswith('.svg')\ + if path != root and not '_' in path and not filename[0] in '._' \ + and not filename.endswith('~') \ + and not 'jquery' in filename \ + and not filename.endswith('theme.css') \ + and not filename.endswith('.svg') \ and not filename.startswith('browser'): ui_files['dev'].append(os.path.join(path.replace(source_path, ''), filename)) if not '/js/' in path: @@ -158,10 +175,14 @@ def build_oxjs(downloads=False, geo=False): filename = build_path + 'Ox.UI/js/Ox.UI.js' write_file(filename, ox.js.minify(js, comment)) ui_files['build'].append(filename.replace(build_path, '')) - files = json.dumps(sorted(ui_files['build'])) - write_file(build_path + 'Ox.UI/json/Ox.UI.files.json', files) - files = json.dumps(sorted(ui_files['dev']), indent=4) - write_file(dev_path + 'Ox.UI/json/Ox.UI.files.json', files) + write_file(build_path + 'Ox.UI/json/Ox.UI.json', json.dumps({ + 'files': sorted(ui_files['build']), + 'images': ui_images + }, sort_keys=True)) + write_file(dev_path + 'Ox.UI/json/Ox.UI.json', json.dumps({ + 'files': sorted(ui_files['dev']), + 'images': ui_images + }, indent=4, sort_keys=True)) ui_files['dev'].append('Ox.UI/Ox.UI.js') # index @@ -250,10 +271,32 @@ def filter_source(tarinfo): return None return tarinfo +def format_hex(rgb): + return '#%s' % ''.join([hex(c)[-2:].replace('x', '0').upper() for c in rgb]) + def get_title(file): match = re.search('

(.+)

', read_file(file)) return match.groups()[0] if match else 'Untitled' +def parse_css(css, values): + def sub(match): + key = match.group(1) + index = match.group(2) + value = values[key] if index == None else values[key][int(index[1:-1])] + if isinstance(value, str): + string = value + else: + if isinstance(value[0], int): + value = [value] + string = ', '.join( + ['rgb%s(%s)' % ( + 'a' if len(vals) == 4 else '', + ', '.join([str(val) for val in vals]) + ) for vals in value] + ) + return string + return re.sub('\$(\w+)(\[\d+\])?', sub, css) + def read_file(file): print 'reading', file f = open(file) @@ -261,6 +304,9 @@ def read_file(file): f.close() return data +def read_jsonc(file): + return ox.jsonc.loads(read_file(file)) + def write_file(file, data): print 'writing', file write_path(file)