diff --git a/.gitignore b/.gitignore index 3417dba628..ee709e6258 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,6 @@ /build/ol-all.js /build/proj4js-combined.js /build/require-all.js +/build/src /examples/*.json /examples/*.combined.js diff --git a/Makefile b/Makefile index 7d4d5df3ec..fb31ffff86 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ build: build/ol.css build/ol.js build/ol.css: build/ol.js touch $@ -build/ol.js: $(PLOVR_JAR) $(SRC) base.json build/ol.json +build/ol.js: $(PLOVR_JAR) $(SRC) base.json build/ol.json build/src/externs.js build/src/literals.js java -jar $(PLOVR_JAR) build build/ol.json >$@ @echo $@ "uncompressed:" $$(wc -c <$@) bytes @echo $@ " compressed:" $$(gzip -9 -c <$@ | wc -c) bytes @@ -28,12 +28,20 @@ build/ol.js: $(PLOVR_JAR) $(SRC) base.json build/ol.json .PHONY: build-all build-all: build/ol-all.js -build/ol-all.js: $(PLOVR_JAR) $(SRC) base.json build/ol-all.json build/require-all.js +build/ol-all.js: $(PLOVR_JAR) $(SRC) base.json build/ol-all.json build/require-all.js build/src/externs.js build/src/literals.js java -jar $(PLOVR_JAR) build build/ol-all.json >$@ || ( rm -f $@ ; false ) build/require-all.js: $(SRC) ( echo "goog.require('goog.dom');" ; find src/ol -name \*.js | xargs grep -rh ^goog.provide | sort | uniq | sed -e 's/provide/require/g' ) >$@ +build/src/externs.js: bin/generate-externs src/ol/literals.txt + mkdir -p $(dir $@) + bin/generate-externs --externs src/ol/literals.txt >$@ + +build/src/literals.js: bin/generate-externs src/ol/literals.txt + mkdir -p $(dir $@) + bin/generate-externs --typedef src/ol/literals.txt >$@ + .PHONY: examples examples: $(subst .html,.json,$(EXAMPLES)) @@ -84,6 +92,7 @@ clean: rm -f build/ol.js rm -f build/ol-all.js rm -f build/require-all.js + rm -f build/src/* rm -f examples/*.json rm -f examples/*.combined.js rm -rf build/apidoc diff --git a/base.json b/base.json index f138e63776..f33513673d 100644 --- a/base.json +++ b/base.json @@ -48,7 +48,10 @@ "mode": "ADVANCED", - "paths": "src", + "paths": [ + "build/src", + "src" + ], "treat-warnings-as-errors": false diff --git a/bin/generate-externs b/bin/generate-externs new file mode 100755 index 0000000000..cdc93c3281 --- /dev/null +++ b/bin/generate-externs @@ -0,0 +1,101 @@ +#!/usr/bin/env python + +import fileinput +from optparse import OptionParser +import re +import sys + + +class Type(object): + + def __init__(self, name, members=None): + self.name = name + self.namespace = '.'.join(self.name.split('.')[:-1]) or None + self.members = members or {} + + def extern(self): + lines = [] + lines.append('/**\n') + lines.append(' * @interface\n') + lines.append(' */\n') + lines.append('%s = function() {};\n' % (self.name,)) + for key in sorted(self.members.keys()): + lines.append('\n') + lines.append('\n') + lines.append('/**\n') + lines.append(' * @type {%s}\n' % (self.members[key],)) + lines.append(' */\n') + lines.append('%s.prototype.%s;\n' % (self.name, key)) + return ''.join(lines) + + def provide(self): + return 'goog.provide(\'%s\');\n' % (self.name,) + + def typedef(self): + lines = [] + lines.append('/**\n') + for i, key in enumerate(sorted(self.members.keys())): + prefix = ' * @typedef {{' if i == 0 else ' * ' + suffix = '}}' if i == len(self.members) - 1 else ',' + type = self.members[key] + if '|' in type: + type = '(%s)' % (type,) + lines.append('%s%s: %s%s\n' % (prefix, key, type, suffix)) + lines.append(' */\n') + lines.append('%s;\n' % (self.name,)) + return ''.join(lines) + + +def main(argv): + + option_parser = OptionParser() + option_parser.add_option('--externs', action='store_true') + option_parser.add_option('--typedef', action='store_true') + options, args = option_parser.parse_args(argv[1:]) + + types = [] + for arg in args: + for line in open(arg): + line = line.strip() + if not line: + continue + m = re.match('@externtype\s*(?P\S+)\Z', line) + if m: + name = m.group('name') + if options.externs: + name = re.sub('\Aol\.', 'olx.', name + 'Extern') + if options.typedef: + name = name + 'Literal' + type = Type(name) + types.append(type) + continue + m = re.match('(?P\S+):\s+(?P\S+)', line) + if m: + type.members[m.group('key')] = m.group('value') + continue + raise RuntimeError(line) + + if options.externs: + sys.stdout.write('/**\n') + sys.stdout.write(' * @externs\n') + sys.stdout.write(' */\n') + namespaces = sorted(set(filter(None, (type.namespace for type in types)))) + for namespace in namespaces: + sys.stdout.write('\n\n') + sys.stdout.write('/**\n') + sys.stdout.write(' * @type {Object}\n') + sys.stdout.write(' */\n') + sys.stdout.write('var %s;\n' % (namespace,)) + for type in types: + sys.stdout.write('\n\n\n') + sys.stdout.write(type.extern()) + + if options.typedef: + sys.stdout.write(''.join(type.provide() for type in types)) + for type in types: + sys.stdout.write('\n\n') + sys.stdout.write(type.typedef()) + + +if __name__ == '__main__': + sys.exit(main(sys.argv)) diff --git a/build/ol.json b/build/ol.json index 30b7d124c1..f9c8f085f3 100644 --- a/build/ol.json +++ b/build/ol.json @@ -13,8 +13,8 @@ "css-output-file": "build/ol.css", "externs": [ + "build/src/externs.js", "externs/bingmaps.js", - "externs/ol.js", "externs/proj4js.js", "externs/tilejson.js" ], diff --git a/externs/ol.js b/externs/ol.js deleted file mode 100644 index a1b22f9c27..0000000000 --- a/externs/ol.js +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @externs - */ - - -/** - * @type {Object} - */ -var olx; - - - -/** - * @interface - */ -olx.MapOptionsExtern = function() {}; - - -/** - * @type {ol.Coordinate|undefined} - */ -olx.MapOptionsExtern.prototype.center; - - -/** - * @type {ol.Collection|undefined} - */ -olx.MapOptionsExtern.prototype.controls; - - -/** - * @type {boolean|undefined} - */ -olx.MapOptionsExtern.prototype.doubleClickZoom; - - -/** - * @type {boolean|undefined} - */ -olx.MapOptionsExtern.prototype.dragPan; - - -/** - * @type {ol.Collection|undefined} - */ -olx.MapOptionsExtern.prototype.interactions; - - -/** - * @type {boolean|undefined} - */ -olx.MapOptionsExtern.prototype.keyboard; - - -/** - * @type {number|undefined} - */ -olx.MapOptionsExtern.prototype.keyboardPanOffset; - - -/** - * @type {ol.Collection|undefined} - */ -olx.MapOptionsExtern.prototype.layers; - - -/** - * @type {number|undefined} - */ -olx.MapOptionsExtern.prototype.maxResolution; - - -/** - * @type {boolean|undefined} - */ -olx.MapOptionsExtern.prototype.mouseWheelZoom; - - -/** - * @type {number|undefined} - */ -olx.MapOptionsExtern.prototype.mouseWheelZoomDelta; - - -/** - * @type {number|undefined} - */ -olx.MapOptionsExtern.prototype.numZoomLevels; - - -/** - * @type {ol.Projection|string|undefined} - */ -olx.MapOptionsExtern.prototype.projection; - - -/** - * @type {ol.RendererHint|undefined} - */ -olx.MapOptionsExtern.prototype.renderer; - - -/** - * @type {Array.|undefined} - */ -olx.MapOptionsExtern.prototype.renderers; - - -/** - * @type {number|undefined} - */ -olx.MapOptionsExtern.prototype.resolution; - - -/** - * @type {Array.|undefined} - */ -olx.MapOptionsExtern.prototype.resolutions; - - -/** - * @type {boolean|undefined} - */ -olx.MapOptionsExtern.prototype.rotate; - - -/** - * @type {boolean|undefined} - */ -olx.MapOptionsExtern.prototype.shiftDragZoom; - - -/** - * @type {ol.Projection|string|undefined} - */ -olx.MapOptionsExtern.prototype.userProjection; - - -/** - * @type {number|undefined} - */ -olx.MapOptionsExtern.prototype.zoom; - - -/** - * @type {number|undefined} - */ -olx.MapOptionsExtern.prototype.zoomDelta; - - -/** - * @type {number|undefined} - */ -olx.MapOptionsExtern.prototype.zoomFactor; diff --git a/src/ol/literals.txt b/src/ol/literals.txt new file mode 100644 index 0000000000..baa36464ef --- /dev/null +++ b/src/ol/literals.txt @@ -0,0 +1,24 @@ +@externtype ol.MapOptions +center: ol.Coordinate|undefined +controls: ol.Collection|undefined +doubleClickZoom: boolean|undefined +dragPan: boolean|undefined +interactions: ol.Collection|undefined +keyboard: boolean|undefined +keyboardPanOffset: number|undefined +layers: ol.Collection|undefined +maxResolution: number|undefined +mouseWheelZoom: boolean|undefined +mouseWheelZoomDelta: number|undefined +numZoomLevels: number|undefined +projection: ol.Projection|string|undefined +renderer: ol.RendererHint|undefined +renderers: Array.|undefined +resolution: number|undefined +resolutions: Array.|undefined +rotate: boolean|undefined +shiftDragZoom: boolean|undefined +userProjection: ol.Projection|string|undefined +zoom: number|undefined +zoomDelta: number|undefined +zoomFactor: number|undefined diff --git a/src/ol/mapoptions.js b/src/ol/mapoptions.js index 56b3617500..7fd20a4b62 100644 --- a/src/ol/mapoptions.js +++ b/src/ol/mapoptions.js @@ -2,12 +2,12 @@ // FIXME MapOptions should create a Zoom control goog.provide('ol.MapOptions'); -goog.provide('ol.MapOptionsLiteral'); goog.provide('ol.MapOptionsType'); goog.provide('ol.RendererHint'); goog.require('ol.Collection'); goog.require('ol.Constraints'); +goog.require('ol.MapOptionsLiteral'); goog.require('ol.Projection'); goog.require('ol.ResolutionConstraint'); goog.require('ol.RotationConstraint'); @@ -57,34 +57,6 @@ ol.DEFAULT_RENDERER_HINTS = [ ]; -/** - * @typedef {{center: (ol.Coordinate|undefined), - * controls: (ol.Collection|undefined), - * doubleClickZoom: (boolean|undefined), - * dragPan: (boolean|undefined), - * interactions: (ol.Collection|undefined), - * keyboard: (boolean|undefined), - * keyboardPanOffset: (number|undefined), - * layers: (ol.Collection|undefined), - * maxResolution: (number|undefined), - * mouseWheelZoom: (boolean|undefined), - * mouseWheelZoomDelta: (number|undefined), - * numZoomLevels: (number|undefined), - * projection: (ol.Projection|string|undefined), - * renderer: (ol.RendererHint|undefined), - * renderers: (Array.|undefined), - * resolution: (number|undefined), - * resolutions: (Array.|undefined), - * rotate: (boolean|undefined), - * shiftDragZoom: (boolean|undefined), - * userProjection: (ol.Projection|string|undefined), - * zoom: (number|undefined), - * zoomDelta: (number|undefined), - * zoomFactor: (number|undefined)}} - */ -ol.MapOptionsLiteral; - - /** * @typedef {{controls: ol.Collection, * constraints: ol.Constraints,