- Breaking change: Require `new` with `EmbeddedSVGEdit` (allows us to use `class` internally)
- Breaking change: If `svgcanvas.setUiStrings` must now be called if not using editor in order
to get strings (for sake of i18n) (and if using path.js alone, must also have its `setUiStrings` called)
- Breaking change (ext-overview-window): Avoid global `overviewWindowGlobals`
- Breaking change (ext-imagelib): Change to object-based encoding for namespacing of
messages (though keep stringifying/parsing ourselves until we remove IE9 support)
- Breaking change: Rename `jquery.js` to `jquery.min.js`
- Breaking change: Remove `scoped` attribute from `style`; it is now deprecated and
obsolete; also move to head (after other stylesheets)
- Enhancement: Make SpinButton plugin independent of SVGEdit via
generic state object for tool_scale
- Enhancement: Remove now unused Python l10n scripts (#238)
- Enhancement: ES6 Modules (including jQuery plugins but not jQuery)
- Enhancement: Further JSDoc (incomplete)
- Enhancement (Optimization): Compress images using imageoptim (and add
npm script) (per #215)
- Fix: i18nize path.js strings and canvas notifications
- Fix: Attempt i18n for ext-markers
- Refactoring (ext-storage): Move locale info to own file imported by the extension (toward modularity; still should be split into separate files by language and *dynamically* imported, but we'll wait for better `import` support to refactor this)
- Refactoring: For imagelib, add local jQuery copy (using old 1.4.4 as had
been using from server)
- Refactoring: For MathJax, add local copy (using old 2.3 as had been using from
server); server had not been working
- Refactoring: Remove `use strict` (implicit in modules)
- Refactoring: Remove trailing whitespace, fix some code within comments
- Refactoring: Expect `jQuery` global rather than `$` for better modularity
(also to adapt line later once available via `import`)
- Refactoring: Prefer `const` (and then `let`)
- Refactoring: Add block scope keywords closer to first block in which they appear
- Refactoring: Use ES6 `class`
- Refactoring `$.isArray` -> `Array.isArray` and avoid some other jQuery core methods
with simple VanillaJS replacements
- Refactoring: Use abbreviated object property syntax
- Refactoring: Object destructuring
- Refactoring: Remove `uiStrings` contents in svg-editor.js (obtains from locale)
- Refactoring: Add favicon to embedded API file
- Refactoring: Use arrow functions for brief functions (incomplete)
- Refactoring: Use `Array.prototype.includes`/`String.prototype.includes`;
`String.prototype.startsWith`, `String.prototype.trim`
- Refactoring: Remove now unnecessary svgutils do/while resetting of variables
- Refactoring: Use shorthand methods for object literals (avoid ": function")
- Refactoring: Avoid quoting object property keys where unnecessary
- Refactoring: Just do truthy/falsey check for lengths in place of comparison to 0
- Refactoring (Testing): Avoid jQuery usage within most test files (defer script,
also in preparation for future switch to ES6 modules for tests)
- Refactoring: Make jpicker variable declaration indent bearable
- Refactoring (Linting): Finish svgcanvas.js
- Docs: Mention in comment no longer an entry file as before
- Docs: Migrate old config, extensions, and FAQ docs
- Licensing: Indicate MIT is license type of rgbcolor; rename/add license file name for
jgraduate and screencast to reflect type (Apache 2.0); rename file to reflect it
contains license information (of type MIT) for Raphael icons
155 lines
4.2 KiB
Python
Executable File
155 lines
4.2 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# ship.py
|
|
#
|
|
# Licensed under the Apache 2 License as is the rest of the project
|
|
# Copyright (c) 2011 Jeff Schiller
|
|
#
|
|
# This script has very little real-world application. It is only used in our pure-client web app
|
|
# served on GoogleCode so we can have one HTML file, run a build script and generate a 'release'
|
|
# version without having to maintain two separate HTML files. It does this by evaluating
|
|
# 'processing comments' that are suspicously similar to IE conditional comments and then outputting
|
|
# a new HTML file after evaluating particular variables.
|
|
#
|
|
# This script takes the following inputs:
|
|
#
|
|
# * a HTML file (--i=in.html)
|
|
# * a series of flag names (--on=Foo --on=Bar)
|
|
#
|
|
# Example:
|
|
#
|
|
# in.html:
|
|
# <!--{if foo}>
|
|
# FOO!
|
|
# <!{else}-->
|
|
# BAR!
|
|
# <!--{endif}-->
|
|
#
|
|
# $ ship.py --i in.html --on foo
|
|
#
|
|
# out.html:
|
|
# <!--{if foo}-->
|
|
# FOO!
|
|
# <!--{else}>
|
|
# BAR!
|
|
# <!{endif}-->
|
|
#
|
|
# It has the following limitations:
|
|
#
|
|
# 1) Only if-else-endif are currently supported.
|
|
# 2) All processing comments must be on one line with no other non-whitespace characters.
|
|
# 3) Comments cannot be nested.
|
|
|
|
import optparse
|
|
import os
|
|
|
|
inside_if = False
|
|
last_if_true = False
|
|
|
|
_options_parser = optparse.OptionParser(
|
|
usage='%prog --i input.html [--on flag1]',
|
|
description=('Rewrites an HTML file based on conditional comments and flags'))
|
|
_options_parser.add_option('--i',
|
|
action='store', dest='input_html_file', help='Input HTML filename')
|
|
_options_parser.add_option('--on',
|
|
action='append', type='string', dest='enabled_flags',
|
|
help='name of flag to enable')
|
|
|
|
def parse_args(args=None):
|
|
options, rargs = _options_parser.parse_args(args)
|
|
return options, (None, None)
|
|
|
|
def parseComment(line, line_num, enabled_flags):
|
|
global inside_if
|
|
global last_if_true
|
|
|
|
start = line.find('{')
|
|
end = line.find('}')
|
|
statement = line[start+1:end].strip()
|
|
if statement.startswith('if '):
|
|
if inside_if == True:
|
|
print 'Fatal Error: Nested {if} found on line ' + str(line_num)
|
|
print line
|
|
quit()
|
|
|
|
# Evaluate whether the expression is true/false.
|
|
# only one variable name allowed for now
|
|
variable_name = statement[3:].strip()
|
|
if variable_name in enabled_flags:
|
|
last_if_true = True
|
|
line = '<!--{if ' + variable_name + '}-->'
|
|
else:
|
|
last_if_true = False
|
|
line = '<!--{if ' + variable_name + '}>'
|
|
|
|
inside_if = True
|
|
|
|
elif statement == 'else':
|
|
if inside_if == False:
|
|
print 'Fatal Error: {else} found without {if} on line ' + str(line_num)
|
|
print line
|
|
quit()
|
|
if inside_if == 'else':
|
|
print 'Fatal Error: Multiple {else} clauses found in the same if on line ' + str(line_num)
|
|
print line
|
|
quit()
|
|
|
|
if last_if_true:
|
|
line = '<!--{else}>'
|
|
else:
|
|
line = '<!{else}-->'
|
|
|
|
# invert the logic so the endif clause is closed properly
|
|
last_if_true = not last_if_true
|
|
|
|
# ensure we don't have two else statements in the same if
|
|
inside_if = 'else'
|
|
|
|
elif statement == 'endif':
|
|
if inside_if == False:
|
|
print 'Fatal Error: {endif} found without {if} on line ' + str(line_num)
|
|
print line
|
|
quit()
|
|
|
|
if last_if_true:
|
|
line = '<!--{endif}-->'
|
|
else:
|
|
line = '<!{endif}-->'
|
|
|
|
inside_if = False
|
|
|
|
return line
|
|
|
|
def ship(inFileName, enabled_flags):
|
|
# read in HTML file
|
|
lines = file(inFileName, 'r').readlines()
|
|
out_lines = []
|
|
i = 0
|
|
|
|
# loop for each line of markup
|
|
for line in lines:
|
|
strline = line.strip()
|
|
# if we find a comment, process it and print out
|
|
if strline.startswith('<!--{') or strline.startswith('<!{'):
|
|
# using the same indentation as the previous line
|
|
start = line.find('<')
|
|
out_lines.append(line[:start] \
|
|
+ parseComment(strline, i, enabled_flags) \
|
|
+ os.linesep)
|
|
else: # else append line to the output list
|
|
out_lines.append(line)
|
|
i += 1
|
|
|
|
return ''.join(out_lines)
|
|
|
|
if __name__ == '__main__':
|
|
options, (input, output) = parse_args()
|
|
|
|
if options.input_html_file != None:
|
|
enabled_flags = []
|
|
if options.enabled_flags != None:
|
|
enabled_flags.extend(options.enabled_flags)
|
|
out_file = ship(options.input_html_file, enabled_flags)
|
|
print out_file
|