diff --git a/apidoc/conf.json b/apidoc/conf.json
index 4b91b0d4b8..9ec1e68f20 100644
--- a/apidoc/conf.json
+++ b/apidoc/conf.json
@@ -14,16 +14,19 @@
],
"include": [
"src",
+ "externs/oli.js",
"externs/olx.js"
]
},
"plugins": [
"node_modules/jsdoc/plugins/markdown",
"apidoc/plugins/inheritdoc",
- "apidoc/plugins/exports",
+ "apidoc/plugins/interface",
+ "apidoc/plugins/typedefs",
+ "apidoc/plugins/inheritdoc",
+ "apidoc/plugins/api",
"apidoc/plugins/todo",
- "apidoc/plugins/observable",
- "apidoc/plugins/stability"
+ "apidoc/plugins/observable"
],
"markdown": {
"parser": "gfm"
diff --git a/apidoc/plugins/api.js b/apidoc/plugins/api.js
new file mode 100644
index 0000000000..824fb82334
--- /dev/null
+++ b/apidoc/plugins/api.js
@@ -0,0 +1,77 @@
+/**
+ * Define an @api tag
+ */
+var conf = env.conf.stability;
+var defaultLevels = ["deprecated","experimental","unstable","stable","frozen","locked"];
+var levels = conf.levels || defaultLevels;
+var util = require('util');
+exports.defineTags = function(dictionary) {
+ dictionary.defineTag('api', {
+ mustHaveValue: false,
+ canHaveType: false,
+ canHaveName: false,
+ onTagged: function(doclet, tag) {
+ var level = tag.text || "experimental";
+ if (levels.indexOf(level) >= 0) {
+ doclet.stability = level;
+ } else {
+ var errorText = util.format('Invalid stability level (%s) in %s line %s', tag.text, doclet.meta.filename, doclet.meta.lineno);
+ require('jsdoc/util/error').handle( new Error(errorText) );
+ }
+ }
+ });
+};
+
+
+
+/*
+ * Based on @stability annotations, and assuming that items with no @stability
+ * annotation should not be documented, this plugin removes undocumented symbols
+ * from the documentation. Undocumented classes with documented members get a
+ * 'hideConstructur' property, which is read by the template so it can hide the
+ * constructor.
+ */
+
+function hasApiMembers(doclet) {
+ return doclet.longname.split('#')[0] == this.longname;
+}
+
+var api = [];
+
+exports.handlers = {
+
+ newDoclet: function(e) {
+ var doclet = e.doclet;
+ // Keep track of api items - needed in parseComplete to determine classes
+ // with api members.
+ if (doclet.stability) {
+ api.push(doclet);
+ }
+ // Mark explicity defined namespaces - needed in parseComplete to keep
+ // namespaces that we need as containers for api items.
+ if (/.*\.jsdoc$/.test(doclet.meta.filename) && doclet.kind == 'namespace') {
+ doclet.namespace_ = true;
+ }
+ },
+
+ parseComplete: function(e) {
+ var doclets = e.doclets;
+ for (var i = doclets.length - 1; i >= 0; --i) {
+ var doclet = doclets[i];
+ // Always document namespaces and items with stability annotation
+ if (doclet.stability || doclet.namespace_) {
+ continue;
+ }
+ if (doclet.kind == 'class' && api.some(hasApiMembers, doclet)) {
+ // Mark undocumented classes with documented members as unexported.
+ // This is used in ../template/tmpl/container.tmpl to hide the
+ // constructor from the docs.
+ doclet.hideConstructor = true;
+ } else {
+ // Remove all other undocumented symbols
+ doclets.splice(i, 1);
+ }
+ }
+ }
+
+};
diff --git a/apidoc/plugins/exports.js b/apidoc/plugins/exports.js
deleted file mode 100644
index 2e7886d18f..0000000000
--- a/apidoc/plugins/exports.js
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * This plugin parses externs/oli.js as well as goog.exportSymbol and
- * goog.exportProperty calls to build a list of API symbols and properties.
- * Unexported modules linked from @param or @fires will be marked unexported,
- * and the documentation will not contain the constructor. Everything else is
- * marked undocumented, which will remove it from the docs.
- */
-
-var api = [];
-var unexported = [];
-
-function collectExports(source) {
- var i, ii, symbol, property;
- var syms = source.match(/goog\.exportSymbol\([^\)]*\)/g);
- if (syms) {
- i = 0; ii = syms.length;
- for (; i < ii; ++i) {
- symbol = syms[i].match(/'([^']*)'/)[1];
- api.push(symbol);
- }
- }
- var props = source.match(/goog\.exportProperty\([^\)]*\)/g);
- if (props) {
- i = 0; ii = props.length;
- for (; i < ii; ++i) {
- property = props[i].match(/[^,]*,[^,]*,\r?\n? *([^\)]*)\)/)[1]
- .replace('.prototype.', '#');
- api.push(property);
- }
- }
-}
-
-function collectOliExports(source) {
- var oli = source.match(/[^\{]oli\.([^;^ ]*);? ?/g);
- if (oli) {
- i = 0; ii = oli.length;
- for (; i < ii; ++i) {
- property = 'ol.' + oli[i].match(/oli.([^;]*)/)[1]
- .replace('.prototype.', '#');
- unexported.push(property);
- }
- }
-}
-
-var encoding = env.conf.encoding || 'utf8';
-var fs = require('jsdoc/fs');
-collectExports(fs.readFileSync('build/src/external/src/exports.js', encoding));
-collectOliExports(fs.readFileSync('externs/oli.js', encoding));
-
-
-exports.handlers = {
-
- beforeParse: function(e) {
- if (/\.js$/.test(e.filename)) {
- collectExports(e.source);
- }
- },
-
- newDoclet: function(e) {
- var i, ii, j, jj;
- if (e.doclet.meta.filename == "olx.js" && e.doclet.longname != 'olx') {
- api.push(e.doclet.longname);
- }
- if (api.indexOf(e.doclet.longname) > -1) {
- var names, name;
- var params = e.doclet.params;
- if (params) {
- for (i = 0, ii = params.length; i < ii; ++i) {
- names = params[i].type.names;
- if (names) {
- for (j = 0, jj=names.length; j < jj; ++j) {
- name = names[j];
- if (unexported.indexOf(name) === -1) {
- unexported.push(name);
- }
- }
- }
- }
- }
- var links = e.doclet.comment.match(/\{@link ([^\}]*)\}/g);
- if (links) {
- for (i=0, ii=links.length; i < ii; ++i) {
- var link = links[i].match(/\{@link (.*)\}/)[1];
- if (unexported.indexOf(link) === -1) {
- unexported.push(link);
- }
- }
- }
- }
- },
-
- parseComplete: function(e) {
- for (var j = e.doclets.length - 1; j >= 0; --j) {
- var doclet = e.doclets[j];
- if (doclet.meta.filename == 'olx.js' && doclet.kind == 'typedef') {
- for (var i = e.doclets.length - 1; i >= 0; --i) {
- var propertyDoclet = e.doclets[i];
- if (propertyDoclet.memberof == doclet.longname) {
- if (!doclet.properties) {
- doclet.properties = [];
- }
- doclet.properties.unshift(propertyDoclet);
- e.doclets.splice(i, 1)
- }
- }
- }
- if (doclet.kind == 'namespace' || doclet.kind == 'event' || doclet.fires) {
- continue;
- }
- var fqn = doclet.longname;
- if (fqn) {
- doclet.unexported = (api.indexOf(fqn) === -1 && unexported.indexOf(fqn) !== -1);
- if (api.indexOf(fqn) === -1 && unexported.indexOf(fqn) === -1) {
- e.doclets.splice(j, 1);
- }
- }
- }
- }
-
-};
diff --git a/apidoc/plugins/inheritdoc.js b/apidoc/plugins/inheritdoc.js
index 673017b702..8340e0b721 100644
--- a/apidoc/plugins/inheritdoc.js
+++ b/apidoc/plugins/inheritdoc.js
@@ -5,11 +5,104 @@
* TODO: Remove this hack when https://github.com/jsdoc3/jsdoc/issues/53
* is addressed.
*/
-exports.astNodeVisitor = {
- visitNode: function(node, e, parser, currentSourceName) {
- if (/@(inheritDoc)(\n|\r)/.test(e.comment)) {
- e.preventDefault = true;
+
+exports.defineTags = function(dictionary) {
+ dictionary.defineTag('inheritDoc', {
+ mustHaveValue: false,
+ canHaveType: false,
+ canHaveName: false,
+ onTagged: function(doclet, tag) {
+ doclet.inheritdoc = true;
+ }
+ });
+};
+
+
+var lookup = {};
+var incompleteByClass = {};
+var keepKeys = ['comment', 'meta', 'name', 'memberof', 'longname', 'augment',
+ 'stability'];
+
+exports.handlers = {
+
+ newDoclet: function(e) {
+ var doclet = e.doclet;
+ var incompletes;
+ if (!(doclet.longname in lookup)) {
+ lookup[doclet.longname] = [];
+ }
+ lookup[doclet.longname].push(doclet);
+ if (doclet.inheritdoc) {
+ if (!(doclet.memberof in incompleteByClass)) {
+ incompleteByClass[doclet.memberof] = [];
+ }
+ incompletes = incompleteByClass[doclet.memberof];
+ if (incompletes.indexOf(doclet.name) == -1) {
+ incompletes.push(doclet.name);
+ }
+ }
+ },
+
+ parseComplete: function(e) {
+ var ancestors, candidate, candidates, doclet, i, j, k, l, key;
+ var incompleteDoclet, stability, incomplete, incompletes;
+ var doclets = e.doclets;
+ for (i = doclets.length - 1; i >= 0; --i) {
+ doclet = doclets[i];
+ if (doclet.augments) {
+ ancestors = [].concat(doclet.augments);
+ }
+ incompletes = incompleteByClass[doclet.longname];
+ if (ancestors && incompletes) {
+ // collect ancestors from the whole hierarchy
+ for (j = 0; j < ancestors.length; ++j) {
+ candidates = lookup[ancestors[j]];
+ if (candidates) {
+ for (k = candidates.length - 1; k >= 0; --k) {
+ candidate = candidates[k];
+ if (candidate.augments) {
+ ancestors = ancestors.concat(candidate.augments);
+ }
+ }
+ }
+ }
+ // walk through all inheritDoc members
+ for (j = incompletes.length - 1; j >= 0; --j) {
+ incomplete = incompletes[j];
+ candidates = lookup[doclet.longname + '#' + incomplete];
+ if (candidates) {
+ // get the incomplete doclet that needs to be augmented
+ for (k = candidates.length - 1; k >= 0; --k) {
+ incompleteDoclet = candidates[k];
+ if (incompleteDoclet.inheritdoc) {
+ break;
+ }
+ }
+ }
+ // find the documented ancestor
+ for (k = ancestors.length - 1; k >= 0; --k) {
+ candidates = lookup[ancestors[k] + '#' + incomplete];
+ if (candidates) {
+ for (l = candidates.length - 1; l >= 0; --l) {
+ candidate = candidates[l];
+ if (candidate && !candidate.inheritdoc) {
+ stability = candidate.stability || incompleteDoclet.stability
+ if (stability) {
+ incompleteDoclet.stability = stability;
+ for (key in candidate) {
+ if (candidate.hasOwnProperty(key) &&
+ keepKeys.indexOf(key) == -1) {
+ incompleteDoclet[key] = candidate[key];
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
}
diff --git a/apidoc/plugins/interface.js b/apidoc/plugins/interface.js
new file mode 100644
index 0000000000..fd362aab41
--- /dev/null
+++ b/apidoc/plugins/interface.js
@@ -0,0 +1,26 @@
+var util = require('util');
+exports.defineTags = function(dictionary) {
+
+ var classTag = dictionary.lookUp('class');
+ dictionary.defineTag('interface', {
+ mustHaveValue: false,
+ onTagged: function(doclet, tag) {
+ classTag.onTagged.apply(this, arguments);
+ doclet.interface = true;
+ }
+ });
+
+ var augmentsTag = dictionary.lookUp('augments');
+ dictionary.defineTag('implements', {
+ mustHaveValue: true,
+ onTagged: function(doclet, tag) {
+ tag.value = tag.value.match(/^\{?([^\}]*)\}?$/)[1];
+ augmentsTag.onTagged.apply(this, arguments);
+ if (!doclet.implements) {
+ doclet.implements = [];
+ }
+ doclet.implements.push(tag.value);
+ }
+ });
+
+};
diff --git a/apidoc/plugins/stability.js b/apidoc/plugins/stability.js
deleted file mode 100644
index bd006cdbab..0000000000
--- a/apidoc/plugins/stability.js
+++ /dev/null
@@ -1,20 +0,0 @@
-var conf = env.conf.stability;
-var defaultLevels = ["deprecated","experimental","unstable","stable","frozen","locked"];
-var levels = conf.levels || defaultLevels;
-var util = require('util');
-exports.defineTags = function(dictionary) {
- dictionary.defineTag('stability', {
- mustHaveValue: true,
- canHaveType: false,
- canHaveName: true,
- onTagged: function(doclet, tag) {
- var level = tag.text;
- if (levels.indexOf(level) >=0) {
- doclet.stability = level;
- } else {
- var errorText = util.format('Invalid stability level (%s) in %s line %s', tag.text, doclet.meta.filename, doclet.meta.lineno);
- require('jsdoc/util/error').handle( new Error(errorText) );
- }
- }
- })
-};
diff --git a/apidoc/plugins/todo.js b/apidoc/plugins/todo.js
index 2a2d05a027..0a76e89e6e 100644
--- a/apidoc/plugins/todo.js
+++ b/apidoc/plugins/todo.js
@@ -6,8 +6,8 @@ exports.defineTags = function(dictionary) {
canHaveName: true,
onTagged: function(doclet, tag) {
var parts = tag.text.split(' ');
- if (parts[0] === 'stability') {
- doclet.stability = parts.slice(1).join(' ');
+ if (parts[0] === 'api') {
+ doclet.stability = parts.slice(1).join(' ') || 'experimental';
} else if (parts[0] === 'observable') {
if (!doclet.observables) {
doclet.observables = [];
diff --git a/apidoc/plugins/typedefs.js b/apidoc/plugins/typedefs.js
new file mode 100644
index 0000000000..35eb804335
--- /dev/null
+++ b/apidoc/plugins/typedefs.js
@@ -0,0 +1,61 @@
+/*
+ * Converts olx.js @type annotations into properties of the previous @typedef.
+ * Changes @enum annotations into @typedef.
+ */
+
+var lastOlxTypedef = null;
+var olxTypes = {};
+
+function addSubparams(params) {
+ for (var j = 0, jj = params.length; j < jj; ++j) {
+ var param = params[j];
+ var types = param.type.names;
+ for (var k = 0, kk = types.length; k < kk; ++k) {
+ var name = types[k];
+ if (name in olxTypes) {
+ param.subparams = olxTypes[name];
+ // TODO Change template before recursing here, because the table gets
+ // too wide.
+ //addSubparams(param.subparams);
+ // TODO Do we need to support multiple object literal types per
+ // param?
+ break;
+ }
+ }
+ }
+}
+
+exports.handlers = {
+
+ newDoclet: function(e) {
+ var doclet = e.doclet;
+ if (doclet.meta.filename == 'olx.js') {
+ if (doclet.kind == 'typedef') {
+ lastOlxTypedef = doclet;
+ olxTypes[doclet.longname] = [];
+ doclet.properties = [];
+ } else if (lastOlxTypedef && doclet.memberof == lastOlxTypedef.longname) {
+ lastOlxTypedef.properties.push(doclet);
+ olxTypes[lastOlxTypedef.longname].push(doclet);
+ } else {
+ lastOlxTypedef = null;
+ }
+ } else if (doclet.isEnum) {
+ // We never export enums, so we document them like typedefs
+ doclet.kind = 'typedef';
+ delete doclet.isEnum;
+ }
+ },
+
+ parseComplete: function(e) {
+ var doclets = e.doclets;
+ for (var i = doclets.length - 1; i >= 0; --i) {
+ var doclet = doclets[i];
+ var params = doclet.params;
+ if (params) {
+ addSubparams(params);
+ }
+ }
+ }
+
+};
diff --git a/apidoc/readme.md b/apidoc/readme.md
new file mode 100644
index 0000000000..bdedae5f89
--- /dev/null
+++ b/apidoc/readme.md
@@ -0,0 +1,74 @@
+# API Documentation
+
+This directory contains configuration (`conf.json`), static content (`index.md`), template (`template/`) and plugins (`plugins/`) for the [JSDoc3](http://usejsdoc.org/) API generator.
+
+## Documenting the source code
+
+JSDoc annotations are used for metadata used by the compiler, for defining the user facing API, and for user documentation.
+
+In the simplest case, a JSDoc block can look like this:
+```js
+/**
+ * Add the given control to the map.
+ * @param {ol.control.Control} control Control.
+ * @todo api
+ */
+ol.Map.prototype.addControl = function(control) {
+ // ...
+};
+```
+The first line is text for the user documentation. This can be long, and it can
+contain Markdown.
+
+The second line tells the Closure compiler the type of the argument.
+
+The third line (`@todo api`) marks the method as exportable. The stability can be added as value, e.g. `@todo api stable`. Once the documentation story is fully settled, we will remove the `todo ` and just write `@api` or `@api stable`. Without such an api note, the method will not be exported and not documented in the generated API documentation.
+
+### Events
+
+Events are documented using `@fires` and `@event` annotations:
+```js
+/**
+ * Constants for event names.
+ * @enum {string}
+ */
+ol.MapBrowserEvent.EventType = {
+ /**
+ * A true single click with no dragging and no double click. Note that this
+ * event is delayed by 250 ms to ensure that it is not a double click.
+ * @event ol.MapBrowserEvent#singleclick
+ * @todo api
+ */
+ SINGLECLICK: 'singleclick',
+ // ...
+};
+```
+Note the value of the `@event` annotation. The text before the hash refers to the event class that the event belongs to, and the text after the hash is the type of the event.
+
+To export event properties, they need to be defined in `externs/oli.js` (also see `readme.md` in `externs/`) and marked with an @api annotation:
+```js
+/** @interface */
+oli.MapBrowserEvent;
+
+/**
+ * @type {ol.Coordinate}
+ * @todo api
+ */
+oli.MapBrowserEvent.prototype.coordinate;
+
+// ...
+
+};
+```
+To document which events are fired by a class or method, the `@fires` annotation is used:
+```js
+ * @fires {@link ol.MapBrowserEvent} ol.MapBrowserEvent
+ * @fires {@link ol.MapEvent} ol.MapEvent
+ * @fires {@link ol.render.Event} ol.render.Event
+ * ...
+ */
+ol.Map = function(options) {
+ // ...
+};
+```
+Again, note the syntax of the `@fires` annotation. The link is necessary to provide a link to the documentation of the event, and the name of the event class is necessary for JSDoc3 to know which event we are talking about.
diff --git a/apidoc/template/tmpl/container.tmpl b/apidoc/template/tmpl/container.tmpl
index 67013b8021..7c744204b5 100644
--- a/apidoc/template/tmpl/container.tmpl
+++ b/apidoc/template/tmpl/container.tmpl
@@ -27,7 +27,7 @@
-
+
@@ -47,7 +47,8 @@
Extends
-
+ -
+ -1?'(Interface)':'') ?>
@@ -141,7 +142,7 @@
TypeDefs
-
+
diff --git a/bin/generate-exports.py b/bin/generate-exports.py
deleted file mode 100755
index 6d7d861eed..0000000000
--- a/bin/generate-exports.py
+++ /dev/null
@@ -1,97 +0,0 @@
-#!/usr/bin/env python
-
-from operator import attrgetter
-from optparse import OptionParser
-import re
-import sys
-
-
-def simplerepr(obj):
- keys = sorted(key for key in obj.__dict__.keys() if not key.startswith('_'))
- attrs = ''.join(' %s=%r' % (key, obj.__dict__[key]) for key in keys)
- return '<%s%s>' % (obj.__class__.__name__, attrs)
-
-
-class Exportable(object):
-
- def __init__(self, name):
- self.name = name
-
- __repr__ = simplerepr
-
- def export(self):
- return ''
-
-
-class Symbol(Exportable):
-
- def __init__(self, name, export_symbol):
- Exportable.__init__(self, name)
- self.export_symbol = export_symbol
- self.props = set()
-
- __repr__ = simplerepr
-
- def export(self):
- lines = []
- if self.export_symbol:
- lines.append('\n\ngoog.exportSymbol(\n \'%s\',\n %s);\n' % (self.name, self.name))
- lines.extend('goog.exportProperty(\n %s,\n \'%s\',\n %s.%s);\n' % (self.name, prop, self.name, prop) for prop in sorted(self.props))
- return ''.join(lines)
-
-
-def main(argv):
-
- option_parser = OptionParser()
- option_parser.add_option('--exports', action='store_true')
- options, args = option_parser.parse_args(argv[1:])
-
- objects = {}
- requires = set()
- for arg in args:
- for line in open(arg, 'rU'):
- line = line.strip()
- if not line:
- continue
- m = re.match(r'@exportProperty\s+(?P\S+)\Z', line)
- if m:
- components = m.group('prop').split('.')
- if components[-2] == 'prototype':
- requires.add('.'.join(components[:-2]))
- else:
- requires.add('.'.join(components[:-1]))
- name = '.'.join(components[:-1])
- prop = components[-1]
- if name in objects:
- symbol = objects[name]
- else:
- symbol = Symbol(name, False)
- objects[name] = symbol
- symbol.props.add(prop)
- continue
- m = re.match(r'@exportSymbol\s+(?P\S+)\Z', line)
- if m:
- name = m.group('name')
- if name in objects:
- raise RuntimeError(line) # Name already defined
- symbol = Symbol(name, True)
- objects[name] = symbol
- components = m.group('name').split('.')
- if re.match(r'[A-Z]', components[-1]):
- requires.add(name)
- else:
- requires.add('.'.join(components[:-1]))
- continue
- raise RuntimeError(line)
-
- objects = sorted(objects.values(), key=attrgetter('name'))
-
- if options.exports:
- if requires:
- for require in sorted(requires):
- sys.stdout.write('goog.require(\'%s\');\n' % (require,))
- for obj in objects:
- sys.stdout.write(obj.export())
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv))
diff --git a/build.py b/build.py
index 21f5e58485..4d8de9067d 100755
--- a/build.py
+++ b/build.py
@@ -86,11 +86,7 @@ EXECUTABLES = [variables.GIT, variables.GJSLINT, variables.JAVA, variables.JAR,
variables.JSDOC, variables.JSHINT, variables.PYTHON,
variables.PHANTOMJS]
-EXPORTS = [path
- for path in ifind('src')
- if path.endswith('.exports')]
-
-EXTERNAL_SRC = ['build/src/external/src/exports.js']
+EXPORTS = 'build/exports.js'
EXAMPLES = [path
for path in ifind('examples')
@@ -113,8 +109,6 @@ EXAMPLES_JSON = ['build/' + example.replace('.html', '.json')
EXAMPLES_COMBINED = ['build/' + example.replace('.html', '.combined.js')
for example in EXAMPLES]
-INTERNAL_SRC = ['build/src/internal/src/requireall.js']
-
GLSL_SRC = [path
for path in ifind('src')
if path.endswith('.glsl')]
@@ -182,15 +176,15 @@ def build_ol_css(t):
t.touch()
-@target('build/ol.js', PLOVR_JAR, SRC, EXTERNAL_SRC, SHADER_SRC,
- LIBTESS_JS_SRC, 'buildcfg/base.json', 'buildcfg/ol.json')
+@target('build/ol.js', PLOVR_JAR, SRC, EXPORTS, SHADER_SRC, LIBTESS_JS_SRC,
+ 'buildcfg/base.json', 'buildcfg/ol.json')
def build_ol_js(t):
t.output('%(JAVA)s', '-server', '-XX:+TieredCompilation', '-jar',
PLOVR_JAR, 'build', 'buildcfg/ol.json')
report_sizes(t)
-@target('build/ol-simple.js', PLOVR_JAR, SRC, INTERNAL_SRC, SHADER_SRC,
+@target('build/ol-simple.js', PLOVR_JAR, SRC, EXPORTS, SHADER_SRC,
LIBTESS_JS_SRC, 'buildcfg/base.json', 'buildcfg/ol.json',
'buildcfg/ol-simple.json')
def build_ol_simple_js(t):
@@ -199,8 +193,8 @@ def build_ol_simple_js(t):
report_sizes(t)
-@target('build/ol-whitespace.js', PLOVR_JAR, SRC, INTERNAL_SRC, SHADER_SRC,
- LIBTESS_JS_SRC, 'buildcfg/base.json', 'buildcfg/ol.json',
+@target('build/ol-whitespace.js', PLOVR_JAR, SRC, EXPORTS,
+ SHADER_SRC, LIBTESS_JS_SRC, 'buildcfg/base.json', 'buildcfg/ol.json',
'buildcfg/ol-whitespace.json')
def build_ol_whitespace_js(t):
t.output('%(JAVA)s', '-server', '-XX:+TieredCompilation', '-jar',
@@ -211,17 +205,16 @@ def build_ol_whitespace_js(t):
virtual('build-all', 'build/ol-all.js')
-@target('build/ol-all.js', PLOVR_JAR, SRC, EXTERNAL_SRC, INTERNAL_SRC,
- SHADER_SRC, LIBTESS_JS_SRC, 'buildcfg/base.json',
- 'buildcfg/ol-all.json')
+@target('build/ol-all.js', PLOVR_JAR, SRC, EXPORTS, SHADER_SRC, LIBTESS_JS_SRC,
+ 'buildcfg/base.json', 'buildcfg/ol-all.json')
def build_ol_all_js(t):
t.output('%(JAVA)s', '-server', '-XX:+TieredCompilation', '-jar',
PLOVR_JAR, 'build', 'buildcfg/ol-all.json')
-@target('build/src/external/src/exports.js', 'bin/generate-exports.py', EXPORTS)
-def build_src_external_src_exports_js(t):
- t.output('%(PYTHON)s', 'bin/generate-exports.py', '--exports', EXPORTS)
+@target(EXPORTS, SRC)
+def build_exports_js(t):
+ t.run('node', 'tasks/generate-exports.js', EXPORTS)
for glsl_src in GLSL_SRC:
@@ -236,29 +229,19 @@ for glsl_src in GLSL_SRC:
shader_src_helper(glsl_src)
-def _build_require_list(dependencies, output_file_name):
+@target('build/test/requireall.js', SPEC)
+def build_test_requireall_js(t):
requires = set()
- for dependency in dependencies:
+ for dependency in t.dependencies:
for line in open(dependency, 'rU'):
match = re.match(r'goog\.provide\(\'(.*)\'\);', line)
if match:
requires.add(match.group(1))
- with open(output_file_name, 'wb') as f:
+ with open(t.name, 'wb') as f:
for require in sorted(requires):
f.write('goog.require(\'%s\');\n' % (require,))
-@target('build/src/internal/src/requireall.js', SRC, SHADER_SRC,
- LIBTESS_JS_SRC)
-def build_src_internal_src_requireall_js(t):
- _build_require_list(t.dependencies, t.name)
-
-
-@target('build/test/requireall.js', SPEC)
-def build_test_requireall_js(t):
- _build_require_list(t.dependencies, t.name)
-
-
virtual('build-examples', 'examples', 'build/examples/all.combined.js',
EXAMPLES_COMBINED)
@@ -277,7 +260,7 @@ def examples_examples_list_js(t):
@target('build/examples/all.combined.js', 'build/examples/all.js', PLOVR_JAR,
- SRC, INTERNAL_SRC, SHADER_SRC, LIBTESS_JS_SRC,
+ SRC, SHADER_SRC, LIBTESS_JS_SRC,
'buildcfg/base.json', 'build/examples/all.json')
def build_examples_all_combined_js(t):
t.output('%(JAVA)s', '-server', '-XX:+TieredCompilation', '-jar',
@@ -332,7 +315,7 @@ def examples_star_combined_js(name, match):
PLOVR_JAR, 'build', 'build/examples/%(id)s.json' %
match.groupdict())
report_sizes(t)
- dependencies = [PLOVR_JAR, SRC, INTERNAL_SRC, SHADER_SRC, LIBTESS_JS_SRC,
+ dependencies = [PLOVR_JAR, SRC, SHADER_SRC, LIBTESS_JS_SRC,
'buildcfg/base.json',
'examples/%(id)s.js' % match.groupdict(),
'build/examples/%(id)s.json' % match.groupdict()]
@@ -345,18 +328,17 @@ def serve(t):
'buildcfg/ol-all.json', EXAMPLES_JSON, 'buildcfg/test.json')
-@target('serve-integration-test', PLOVR_JAR, INTERNAL_SRC)
+@target('serve-integration-test', PLOVR_JAR)
def serve_precommit(t):
t.run('%(JAVA)s', '-jar', PLOVR_JAR, 'serve',
'buildcfg/ol-all.json', 'buildcfg/test.json')
-virtual('lint', 'build/lint-timestamp', 'build/lint-generated-timestamp',
- 'build/lint-libtess.js-timestamp', 'build/check-requires-timestamp',
- 'build/check-whitespace-timestamp')
+virtual('lint', 'build/lint-timestamp', 'build/lint-libtess.js-timestamp',
+ 'build/check-requires-timestamp', 'build/check-whitespace-timestamp')
-@target('build/lint-timestamp', SRC, EXAMPLES_SRC, SPEC, precious=True)
+@target('build/lint-timestamp', SRC, EXPORTS, EXAMPLES_SRC, SPEC, precious=True)
def build_lint_src_timestamp(t):
t.run('%(GJSLINT)s',
'--jslint_error=all',
@@ -366,26 +348,6 @@ def build_lint_src_timestamp(t):
t.touch()
-@target('build/lint-generated-timestamp', INTERNAL_SRC, EXTERNAL_SRC,
- precious=True)
-def build_lint_generated_timestamp(t):
- limited_doc_files = [
- path
- for path in ifind('externs')
- if path.endswith('.js')]
- t.run('%(GJSLINT)s',
- '--jslint_error=all',
- # ignore error for max line length (for these auto-generated sources)
- '--disable=110',
- '--custom_jsdoc_tags=todo',
- # for a complete list of error codes to allow, see
- # http://closure-linter.googlecode.com/svn/trunk/closure_linter/errors.py
- '--limited_doc_files=%s' % (','.join(limited_doc_files),),
- '--strict',
- t.newer(t.dependencies))
- t.touch()
-
-
@target('build/lint-libtess.js-timestamp', LIBTESS_JS_SRC, precious=True)
def build_lint_libtess_js_timestamp(t):
t.run('%(GJSLINT)s',
@@ -398,8 +360,8 @@ def build_lint_libtess_js_timestamp(t):
virtual('jshint', 'build/jshint-timestamp')
-
-@target('build/jshint-timestamp', SRC, EXAMPLES_SRC, SPEC, precious=True)
+@target('build/jshint-timestamp', SRC, EXPORTS, EXAMPLES_SRC, SPEC,
+ precious=True)
def build_jshint_timestamp(t):
t.run(variables.JSHINT, '--verbose', t.newer(t.dependencies))
t.touch()
@@ -428,8 +390,8 @@ def _strip_comments(lines):
yield lineno, line
-@target('build/check-requires-timestamp', SRC, INTERNAL_SRC, EXTERNAL_SRC,
- EXAMPLES_SRC, SHADER_SRC, LIBTESS_JS_SRC, SPEC)
+@target('build/check-requires-timestamp', SRC, EXAMPLES_SRC,
+ SHADER_SRC, LIBTESS_JS_SRC, SPEC)
def build_check_requires_timestamp(t):
from zipfile import ZipFile
unused_count = 0
@@ -448,8 +410,6 @@ def build_check_requires_timestamp(t):
if m:
all_provides.add(m.group(1))
for filename in sorted(t.dependencies):
- if filename == 'build/src/internal/src/requireall.js':
- continue
require_linenos = {}
uses = set()
lines = open(filename, 'rU').readlines()
@@ -529,8 +489,6 @@ def build_check_requires_timestamp(t):
for key, child in root.children.iteritems()]
missing_count = 0
for filename in sorted(t.dependencies):
- if filename in INTERNAL_SRC or filename in EXTERNAL_SRC:
- continue
provides = set()
requires = set()
uses = set()
@@ -573,9 +531,8 @@ def build_check_requires_timestamp(t):
t.touch()
-@target('build/check-whitespace-timestamp', SRC, INTERNAL_SRC, EXTERNAL_SRC,
- EXAMPLES_SRC, SPEC, EXPORTS, JSDOC_SRC, LIBTESS_JS_SRC,
- precious=True)
+@target('build/check-whitespace-timestamp', SRC, EXPORTS, EXAMPLES_SRC,
+ SPEC, JSDOC_SRC, LIBTESS_JS_SRC, precious=True)
def build_check_whitespace_timestamp(t):
CR_RE = re.compile(r'\r')
LEADING_WHITESPACE_RE = re.compile(r'\s+')
@@ -622,7 +579,7 @@ virtual('apidoc', 'build/jsdoc-%(BRANCH)s-timestamp' % vars(variables))
@target('build/jsdoc-%(BRANCH)s-timestamp' % vars(variables), 'host-resources',
- 'build/src/external/src/exports.js', SRC, SHADER_SRC,
+ EXPORTS, SRC, SHADER_SRC,
ifind('apidoc/template'))
def jsdoc_BRANCH_timestamp(t):
t.run('%(JSDOC)s', 'apidoc/index.md', '-c', 'apidoc/conf.json',
@@ -735,7 +692,7 @@ def proj4js_zip(t):
t.info('downloaded %r', t.name)
-virtual('test-deps', INTERNAL_SRC, PROJ4JS, 'build/test/requireall.js')
+virtual('test-deps', PROJ4JS, 'build/test/requireall.js')
@target('test', 'test-deps', phony=True)
diff --git a/buildcfg/base.json b/buildcfg/base.json
index 63ae010258..72435a700e 100644
--- a/buildcfg/base.json
+++ b/buildcfg/base.json
@@ -68,7 +68,6 @@
],
"paths": [
- "../build/src/internal/src",
"../src"
],
diff --git a/buildcfg/jsdoc/symbols/conf.json b/buildcfg/jsdoc/symbols/conf.json
new file mode 100644
index 0000000000..29f6b31ecd
--- /dev/null
+++ b/buildcfg/jsdoc/symbols/conf.json
@@ -0,0 +1,15 @@
+{
+ "opts": {
+ "recurse": true,
+ "template": "buildcfg/jsdoc/symbols"
+ },
+ "tags": {
+ "allowUnknownTags": true
+ },
+ "source": {
+ "includePattern": "\\.js$"
+ },
+ "plugins": [
+ "buildcfg/jsdoc/symbols/todo-plugin"
+ ]
+}
diff --git a/buildcfg/jsdoc/symbols/publish.js b/buildcfg/jsdoc/symbols/publish.js
new file mode 100644
index 0000000000..7363f93c91
--- /dev/null
+++ b/buildcfg/jsdoc/symbols/publish.js
@@ -0,0 +1,45 @@
+/**
+ * @fileoverview Generates JSON output based on doclets with the "api" tag.
+ */
+var assert = require('assert');
+var fs = require('fs');
+var path = require('path');
+
+
+/**
+ * Publish hook for the JSDoc template. Writes to JSON stdout.
+ * @param {function} data The root of the Taffy DB containing doclet records.
+ * @param {Object} opts Options.
+ */
+exports.publish = function(data, opts) {
+ var cwd = process.cwd();
+
+ // get all doclets with the "api" property, but no enums, typedefs and events.
+ var docs = data(
+ {api: {isString: true}},
+ {isEnum: {'!is': true}},
+ {kind: {'!is': 'typedef'}},
+ {kind: {'!is': 'event'}}
+ ).get();
+
+ // get symbols data, filter out those that are members of private classes
+ var symbols = docs.filter(function(doc) {
+ var include = true;
+ var constructor = doc.memberof;
+ if (constructor && constructor.substr(-1) === '_') {
+ assert.strictEqual(doc.inherited, true,
+ 'Unexpected export on private class: ' + doc.longname);
+ include = false;
+ }
+ return include;
+ }).map(function(doc) {
+ return {
+ name: doc.longname,
+ extends: doc.augments,
+ path: path.join(doc.meta.path, doc.meta.filename)
+ };
+ });
+
+ process.stdout.write(JSON.stringify({symbols: symbols}, null, 2));
+
+};
diff --git a/buildcfg/jsdoc/symbols/todo-plugin.js b/buildcfg/jsdoc/symbols/todo-plugin.js
new file mode 100644
index 0000000000..4eed6567b2
--- /dev/null
+++ b/buildcfg/jsdoc/symbols/todo-plugin.js
@@ -0,0 +1,26 @@
+/**
+ * @fileoverview This plugin should go away when we get rid of Plovr and can
+ * use Closure Compiler's extra_annotation_name option. Until then, we hijack
+ * the todo tag to add doclet properties for other tags we eventually want to
+ * support. For example, the "todo api" tag can eventually be replaced with
+ * the "api" tag.
+ */
+
+
+/**
+ * Our hook to define new tags.
+ * @param {Object} dictionary The tag dictionary.
+ */
+exports.defineTags = function(dictionary) {
+
+ dictionary.defineTag('todo', {
+ mustHaveValue: true,
+ onTagged: function(doclet, tag) {
+ var parts = tag.text.split(' ');
+ if (parts[0] === 'api') {
+ doclet.api = parts.slice(1).join(' ').trim();
+ }
+ }
+ });
+
+};
diff --git a/buildcfg/ol-all.json b/buildcfg/ol-all.json
index ef96b4020d..7ce2c28f73 100644
--- a/buildcfg/ol-all.json
+++ b/buildcfg/ol-all.json
@@ -17,8 +17,7 @@
"inherits": "base.json",
"inputs": [
- "../build/src/internal/src/requireall.js",
- "../build/src/external/src/exports.js"
+ "../build/exports.js"
]
}
diff --git a/buildcfg/ol-simple.json b/buildcfg/ol-simple.json
index 3e5806794c..5cb4be99de 100644
--- a/buildcfg/ol-simple.json
+++ b/buildcfg/ol-simple.json
@@ -27,8 +27,7 @@
"inherits": "ol.json",
"inputs": [
- "../build/src/internal/src/requireall.js",
- "../build/src/external/src/exports.js"
+ "../build/exports.js"
],
"mode": "SIMPLE",
diff --git a/buildcfg/ol-whitespace.json b/buildcfg/ol-whitespace.json
index bb185fe275..c409225de4 100644
--- a/buildcfg/ol-whitespace.json
+++ b/buildcfg/ol-whitespace.json
@@ -28,7 +28,7 @@
"inherits": "ol.json",
"inputs": [
- "../build/src/internal/src/requireall.js"
+ "../build/exports.js"
],
"mode": "WHITESPACE",
diff --git a/buildcfg/ol.json b/buildcfg/ol.json
index 3871efc347..77513d9363 100644
--- a/buildcfg/ol.json
+++ b/buildcfg/ol.json
@@ -27,7 +27,7 @@
"inherits": "base.json",
"inputs": [
- "../build/src/external/src/exports.js"
+ "../build/exports.js"
],
"output-wrapper": "// OpenLayers 3. see http://ol3js.org/\n(function(){%output%})();",
diff --git a/externs/oli.js b/externs/oli.js
index 7a951c1a2c..1d3990a2ba 100644
--- a/externs/oli.js
+++ b/externs/oli.js
@@ -14,7 +14,11 @@ var oli;
oli.CollectionEvent;
-/** @type {*} */
+/**
+ * The element that is added to or removed from the collection.
+ * @type {*}
+ * @todo api
+ */
oli.CollectionEvent.prototype.element;
@@ -23,7 +27,10 @@ oli.CollectionEvent.prototype.element;
oli.DragBoxEvent;
-/** @type {ol.Coordinate} */
+/**
+ * @type {ol.Coordinate}
+ * @todo api
+ */
oli.DragBoxEvent.prototype.coordinate;
@@ -32,7 +39,11 @@ oli.DragBoxEvent.prototype.coordinate;
oli.DrawEvent;
-/** @type {ol.Feature} */
+/**
+ * The feature being drawn.
+ * @type {ol.Feature}
+ * @todo api
+ */
oli.DrawEvent.prototype.feature;
@@ -77,7 +88,10 @@ oli.FrameState.prototype.layerStatesArray;
oli.FrameState.prototype.logos;
-/** @type {number} */
+/**
+ * @type {number}
+ * @todo api
+ */
oli.FrameState.prototype.pixelRatio;
@@ -101,7 +115,10 @@ oli.FrameState.prototype.skippedFeatureUids_;
oli.FrameState.prototype.tileQueue;
-/** @type {number} */
+/**
+ * @type {number}
+ * @todo api
+ */
oli.FrameState.prototype.time;
@@ -109,7 +126,10 @@ oli.FrameState.prototype.time;
oli.FrameState.prototype.usedTiles;
-/** @type {oli.View2DState} */
+/**
+ * @type {oli.View2DState}
+ * @todo api
+ */
oli.FrameState.prototype.view2DState;
@@ -135,15 +155,24 @@ oli.ObjectEvent.prototype.key;
oli.MapBrowserEvent;
-/** @type {ol.Coordinate} */
+/**
+ * @type {ol.Coordinate}
+ * @todo api
+ */
oli.MapBrowserEvent.prototype.coordinate;
-/** @type {Event} */
+/**
+ * @type {Event}
+ * @todo api
+ */
oli.MapBrowserEvent.prototype.originalEvent;
-/** @type {ol.Pixel} */
+/**
+ * @type {ol.Pixel}
+ * @todo api
+ */
oli.MapBrowserEvent.prototype.pixel;
@@ -187,15 +216,24 @@ oli.control.Control.prototype.setMap = function(map) {};
oli.interaction.DragAndDropEvent;
-/** @type {Array.} */
+/**
+ * @type {Array.|undefined}
+ * @todo api
+ */
oli.interaction.DragAndDropEvent.prototype.features;
-/** @type {ol.proj.Projection} */
+/**
+ * @type {ol.proj.Projection|undefined}
+ * @todo api
+ */
oli.interaction.DragAndDropEvent.prototype.projection;
-/** @type {File} */
+/**
+ * @type {File}
+ * @todo api
+ */
oli.interaction.DragAndDropEvent.prototype.file;
@@ -203,19 +241,35 @@ oli.interaction.DragAndDropEvent.prototype.file;
oli.render.Event;
-/** @type {CanvasRenderingContext2D|null|undefined} */
+/**
+ * Canvas context. Only available when a Canvas renderer is used, null
+ * otherwise.
+ * @type {CanvasRenderingContext2D|null|undefined}
+ * @todo api
+ */
oli.render.Event.prototype.context;
-/** @type {oli.FrameState|undefined} */
+/**
+ * @type {oli.FrameState|undefined}
+ * @todo api
+ */
oli.render.Event.prototype.frameState;
-/** @type {ol.webgl.Context|null|undefined} */
+/**
+ * WebGL context. Only available when a WebGL renderer is used, null otherwise.
+ * @type {ol.webgl.Context|null|undefined}
+ * @todo api
+ */
oli.render.Event.prototype.glContext;
-/** @type {ol.render.IVectorContext|undefined} */
+/**
+ * For canvas, this is an instance of {@link ol.render.canvas.Immediate}.
+ * @type {ol.render.IVectorContext|undefined}
+ * @todo api
+ */
oli.render.Event.prototype.vectorContext;
@@ -224,5 +278,9 @@ oli.render.Event.prototype.vectorContext;
oli.source.VectorEvent;
-/** @type {ol.Feature} */
+/**
+ * The feature being added or removed.
+ * @type {ol.Feature}
+ * @todo api
+ */
oli.source.VectorEvent.prototype.feature;
diff --git a/externs/olx.js b/externs/olx.js
index 7d51dbbbfd..c939b81be9 100644
--- a/externs/olx.js
+++ b/externs/olx.js
@@ -7,7 +7,7 @@ var olx;
/**
* @typedef {{html: string,
* tileRanges: (Object.>|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.AttributionOptions;
@@ -29,7 +29,7 @@ olx.AttributionOptions.prototype.tileRanges;
/**
* @typedef {{loadTilesWhileAnimating: (boolean|undefined),
* loadTilesWhileInteracting: (boolean|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.DeviceOptions;
@@ -52,7 +52,7 @@ olx.DeviceOptions.prototype.loadTilesWhileInteracting;
/**
* @typedef {{tracking: (boolean|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.DeviceOrientationOptions;
@@ -68,7 +68,7 @@ olx.DeviceOrientationOptions.prototype.tracking;
* @typedef {{tracking: (boolean|undefined),
* trackingOptions: (GeolocationPositionOptions|undefined),
* projection: ol.proj.ProjectionLike}}
- * @todo stability experimental
+ * @todo api
*/
olx.GeolocationOptions;
@@ -107,7 +107,7 @@ olx.GeolocationOptions.prototype.projection;
* renderer: (ol.RendererHint|Array.|string|undefined),
* target: (Element|string|undefined),
* view: (ol.IView|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.MapOptions;
@@ -155,7 +155,8 @@ olx.MapOptions.prototype.keyboardEventTarget;
/**
- * Layers.
+ * Layers. Array or {@link ol.Collection} items are instances of
+ * {@link ol.layer.Layer} or any of its {@link ol.layer} subclasses.
* @type {Array.|ol.Collection|undefined}
*/
olx.MapOptions.prototype.layers;
@@ -205,7 +206,7 @@ olx.MapOptions.prototype.view;
* insertFirst: (boolean|undefined),
* offsetX: (number|undefined),
* offsetY: (number|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.OverlayOptions;
@@ -271,7 +272,7 @@ olx.OverlayOptions.prototype.offsetY;
* @typedef {{code: string,
* extent: (ol.Extent|undefined),
* global: (boolean|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.Proj4jsProjectionOptions;
@@ -304,7 +305,7 @@ olx.Proj4jsProjectionOptions.prototype.global;
* extent: (ol.Extent|undefined),
* axisOrientation: (string|undefined),
* global: (boolean|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.ProjectionOptions;
@@ -358,7 +359,7 @@ olx.ProjectionOptions.prototype.global;
* rotation: (number|undefined),
* zoom: (number|undefined),
* zoomFactor: (number|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.View2DOptions;
@@ -471,7 +472,7 @@ olx.View2DOptions.prototype.zoomFactor;
* start: (number|undefined),
* duration: (number|undefined),
* easing: (function(number):number|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.animation.BounceOptions;
@@ -510,7 +511,7 @@ olx.animation.BounceOptions.prototype.easing;
* start: (number|undefined),
* duration: (number|undefined),
* easing: (function(number):number|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.animation.PanOptions;
@@ -549,7 +550,7 @@ olx.animation.PanOptions.prototype.easing;
* start: (number|undefined),
* duration: (number|undefined),
* easing: (function(number):number|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.animation.RotateOptions;
@@ -596,7 +597,7 @@ olx.animation.RotateOptions.prototype.easing;
* start: (number|undefined),
* duration: (number|undefined),
* easing: (function(number):number|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.animation.ZoomOptions;
@@ -633,7 +634,7 @@ olx.animation.ZoomOptions.prototype.easing;
/**
* @typedef {{className: (string|undefined),
* target: (Element|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.control.AttributionOptions;
@@ -655,7 +656,7 @@ olx.control.AttributionOptions.prototype.target;
/**
* @typedef {{element: (Element|undefined),
* target: (Element|string|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.control.ControlOptions;
@@ -683,7 +684,7 @@ olx.control.ControlOptions.prototype.target;
* logoOptions: (olx.control.LogoOptions|undefined),
* zoom: (boolean|undefined),
* zoomOptions: (olx.control.ZoomOptions|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.control.DefaultsOptions;
@@ -735,7 +736,7 @@ olx.control.DefaultsOptions.prototype.zoomOptions;
* tipLabel: (string|undefined),
* keys: (boolean|undefined),
* target: (Element|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.control.FullScreenOptions;
@@ -771,7 +772,7 @@ olx.control.FullScreenOptions.prototype.target;
/**
* @typedef {{className: (string|undefined),
* target: (Element|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.control.LogoOptions;
@@ -796,7 +797,7 @@ olx.control.LogoOptions.prototype.target;
* projection: ol.proj.ProjectionLike,
* target: (Element|undefined),
* undefinedHTML: (string|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.control.MousePositionOptions;
@@ -841,7 +842,7 @@ olx.control.MousePositionOptions.prototype.undefinedHTML;
* minWidth: (number|undefined),
* target: (Element|undefined),
* units: (ol.control.ScaleLineUnits|string|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.control.ScaleLineOptions;
@@ -883,7 +884,7 @@ olx.control.ScaleLineOptions.prototype.units;
* zoomOutTipLabel: (string|undefined),
* delta: (number|undefined),
* target: (Element|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.control.ZoomOptions;
@@ -948,7 +949,7 @@ olx.control.ZoomOptions.prototype.target;
* @typedef {{className: (string|undefined),
* maxResolution: (number|undefined),
* minResolution: (number|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.control.ZoomSliderOptions;
@@ -979,7 +980,7 @@ olx.control.ZoomSliderOptions.prototype.minResolution;
* target: (Element|undefined),
* tipLabel: (string|undefined),
* extent: (ol.Extent|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.control.ZoomToExtentOptions;
@@ -1015,7 +1016,7 @@ olx.control.ZoomToExtentOptions.prototype.extent;
/**
* @typedef {{defaultProjection: ol.proj.ProjectionLike}}
- * @todo stability experimental
+ * @todo api
*/
olx.format.GeoJSONOptions;
@@ -1029,7 +1030,7 @@ olx.format.GeoJSONOptions.prototype.defaultProjection;
/**
* @typedef {{defaultProjection: ol.proj.ProjectionLike}}
- * @todo stability experimental
+ * @todo api
*/
olx.format.TopoJSONOptions;
@@ -1043,7 +1044,7 @@ olx.format.TopoJSONOptions.prototype.defaultProjection;
/**
* @typedef {{altitudeMode: (ol.format.IGCZ|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.format.IGCOptions;
@@ -1058,7 +1059,7 @@ olx.format.IGCOptions.prototype.altitudeMode;
/**
* @typedef {{defaultStyle: (Array.|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.format.KMLOptions;
@@ -1079,7 +1080,7 @@ olx.format.KMLOptions.prototype.defaultStyle;
* multiCurve: (boolean|undefined),
* multiSurface: (boolean|undefined),
* schemaLocation: (string|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.format.GMLOptions;
@@ -1149,7 +1150,7 @@ olx.format.GMLOptions.prototype.schemaLocation;
* @typedef {{featureNS: string,
* featureType: string,
* schemaLocation: (string|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.format.WFSOptions;
@@ -1186,7 +1187,7 @@ olx.format.WFSOptions.prototype.schemaLocation;
* maxFeatures: (number|undefined),
* geometryName: (string|undefined),
* bbox: (ol.Extent|undefined)}}
- * @todo stability experimental
+ * @todo api
*/
olx.format.WFSWriteGetFeatureOptions;
@@ -1262,7 +1263,7 @@ olx.format.WFSWriteGetFeatureOptions.prototype.bbox;
* srsName: (string|undefined),
* handle: (string|undefined),
* nativeElements: Array.