aboutsummaryrefslogtreecommitdiffstats
path: root/docs/src/ngdoc.js
diff options
context:
space:
mode:
Diffstat (limited to 'docs/src/ngdoc.js')
-rw-r--r--docs/src/ngdoc.js1435
1 files changed, 0 insertions, 1435 deletions
diff --git a/docs/src/ngdoc.js b/docs/src/ngdoc.js
deleted file mode 100644
index 78f968d9..00000000
--- a/docs/src/ngdoc.js
+++ /dev/null
@@ -1,1435 +0,0 @@
-/**
- * All parsing/transformation code goes here. All code here should be sync to ease testing.
- */
-var DOM = require('./dom.js').DOM;
-var htmlEscape = require('./dom.js').htmlEscape;
-var Example = require('./example.js').Example;
-var NEW_LINE = /\n\r?/;
-var globalID = 0;
-var fs = require('fs');
-var fspath = require('path');
-var shell = require('shelljs');
-var gruntUtil = require('../../lib/grunt/utils.js');
-var errorsJson;
-var marked = require('marked');
-marked.setOptions({
- gfm: true,
- tables: true
-});
-
-var lookupMinerrMsg = function (doc) {
- var code, namespace;
-
- if (errorsJson === undefined) {
- errorsJson = require('../../build/errors.json').errors;
- }
-
- namespace = doc.getMinerrNamespace();
- code = doc.getMinerrCode();
- if (namespace === undefined) {
- return errorsJson[code];
- }
- return errorsJson[namespace][code];
-};
-
-exports.trim = trim;
-exports.metadata = metadata;
-exports.scenarios = scenarios;
-exports.writeProtractorTest = writeProtractorTest;
-exports.merge = merge;
-exports.checkBrokenLinks = checkBrokenLinks;
-exports.Doc = Doc;
-
-exports.ngVersions = function() {
- var versions = [], regex = /^v([1-9]\d*(?:\.\d+\S+)+)$/; //only fetch >= 1.0.0 versions
- shell.exec('git tag', {silent: true}).output.split(/\s*\n\s*/)
- .forEach(function(line) {
- var matches = regex.exec(line);
- if(matches && matches.length > 0) {
- versions.push(matches[1]);
- }
- });
-
- //match the future version of AngularJS that is set in the package.json file
- return expandVersions(sortVersionsNaturally(versions), exports.ngCurrentVersion().full);
-
- function expandVersions(versions, latestVersion) {
- var RC_VERSION = /rc\d/;
- //copy the array to avoid changing the versions param data
- //the latest version is not on the git tags list, but
- //docs.angularjs.org will always point to master as of 1.2
- versions = versions.concat([latestVersion]);
-
- var firstUnstable, expanded = [];
- for(var i=versions.length-1;i>=0;i--) {
- var version = versions[i],
- split = version.split('.'),
- isMaster = version == latestVersion,
- isStable = split[1] % 2 === 0 && !RC_VERSION.test(version);
-
- var title = 'AngularJS - v' + version;
-
- var docsPath = version < '1.0.2' ? 'docs-' + version : 'docs';
-
- var url = isMaster ?
- 'http://docs.angularjs.org' :
- 'http://code.angularjs.org/' + version + '/' + docsPath;
-
- expanded.push({
- version : version,
- stable : isStable,
- title : title,
- group : (isStable ? 'Stable' : 'Unstable'),
- url : url
- });
- };
-
- return expanded;
- };
-
- function sortVersionsNaturally(versions) {
- var versionMap = {},
- NON_RC_RELEASE_NUMBER = 999;
- for(var i = versions.length - 1; i >= 0; i--) {
- var version = versions[i];
- var split = version.split(/\.|rc/);
- var baseVersion = split[0] + '.' + split[1] + '.' + split[2];
-
- //create a map of RC versions for each version
- //this way each RC version can be sorted in "natural" order
- versionMap[baseVersion] = versionMap[baseVersion] || [];
-
- //NON_RC_RELEASE_NUMBER is used to signal the non-RC version for the release and
- //it will always appear at the top of the list since the number is so high!
- versionMap[baseVersion].push(
- version == baseVersion ? NON_RC_RELEASE_NUMBER : parseInt(version.match(/rc\.?(\d+)/)[1]));
- };
-
- //flatten the map so that the RC versions occur in a natural sorted order
- //and the official non-RC version shows up at the top of the list of sorted
- //RC versions!
- var angularVersions = [];
- sortedKeys(versionMap).forEach(function(key) {
- var versions = versionMap[key];
-
- //basic numerical sort
- versions.sort(function(a,b) {
- return a - b;
- });
-
- versions.forEach(function(v) {
- angularVersions.push(v == NON_RC_RELEASE_NUMBER ? key : key + 'rc' + v);
- });
- });
-
- return angularVersions;
- };
-
- function sortedKeys(obj) {
- var keys = [];
- for(var key in obj) {
- keys.push(key);
- };
- keys.sort(true);
- return keys;
- };
-};
-
-exports.ngCurrentVersion = function() {
- return gruntUtil.getVersion();
-};
-
-var BOOLEAN_ATTR = {};
-['multiple', 'selected', 'checked', 'disabled', 'readOnly', 'required'].forEach(function(value) {
- BOOLEAN_ATTR[value] = true;
-});
-
-//////////////////////////////////////////////////////////
-function Doc(text, file, line) {
- if (typeof text == 'object') {
- for ( var key in text) {
- this[key] = text[key];
- }
- } else {
- this.text = text;
- this.file = file;
- this.line = line;
- }
- this.scenarios = this.scenarios || [];
- this.protractorTests = this.protractorTests || [];
- this.requires = this.requires || [];
- this.param = this.param || [];
- this.properties = this.properties || [];
- this.methods = this.methods || [];
- this.events = this.events || [];
- this.links = this.links || [];
- this.anchors = this.anchors || [];
-}
-Doc.METADATA_IGNORE = (function() {
- var words = fs.readFileSync(__dirname + '/ignore.words', 'utf8');
- return words.toString().split(/[,\s\n\r]+/gm);
-})();
-
-
-Doc.prototype = {
- keywords: function keywords() {
- var keywords = {};
- var words = [];
- Doc.METADATA_IGNORE.forEach(function(ignore){ keywords[ignore] = true; });
-
- function extractWords(text) {
- var tokens = text.toLowerCase().split(/[\.\s,`'"#]+/mg);
- tokens.forEach(function(key){
- var match = key.match(/^((ng:|[\$_a-z])[\w\-_]+)/);
- if (match){
- key = match[1];
- if (!keywords[key]) {
- keywords[key] = true;
- words.push(key);
- }
- }
- });
- }
-
- extractWords(this.text);
- this.properties.forEach(function(prop) {
- extractWords(prop.text || prop.description || '');
- });
- this.methods.forEach(function(method) {
- extractWords(method.text || method.description || '');
- });
- if (this.ngdoc === 'error') {
- words.push(this.getMinerrNamespace());
- words.push(this.getMinerrCode());
- }
- words.sort();
- return words.join(' ');
- },
-
- shortDescription : function() {
- if (!this.description) return this.description;
- var text = this.description.split("\n")[0];
- text = text.replace(/<.+?\/?>/g, '');
- text = text.replace(/{/g,'&#123;');
- text = text.replace(/}/g,'&#125;');
- return text;
- },
-
- getMinerrNamespace: function () {
- if (this.ngdoc !== 'error') {
- throw new Error('Tried to get the minErr namespace, but @ngdoc ' +
- this.ngdoc + ' was supplied. It should be @ngdoc error');
- }
- return this.name.split(':')[0];
- },
-
- getMinerrCode: function () {
- if (this.ngdoc !== 'error') {
- throw new Error('Tried to get the minErr error code, but @ngdoc ' +
- this.ngdoc + ' was supplied. It should be @ngdoc error');
- }
- return this.name.split(':')[1];
- },
-
- /**
- * Converts relative urls (without section) into absolute
- * Absolute url means url with section
- *
- * @example
- * - if the link is inside any api doc:
- * angular.widget -> api/angular.widget
- *
- * - if the link is inside any guid doc:
- * intro -> guide/intro
- *
- * @param {string} url Absolute or relative url
- * @returns {string} Absolute url
- */
- convertUrlToAbsolute: function(url) {
- var hashIdx = url.indexOf('#');
-
- // Lowercase hash parts of the links,
- // so that we can keep correct API names even when the urls are lowercased.
- if (hashIdx !== -1) {
- url = url.substr(0, hashIdx) + url.substr(hashIdx).toLowerCase();
- }
-
- if (url.substr(-1) == '/') return url + 'index';
- if (url.match(/\//)) return url;
- return this.section + '/' + url;
- },
-
- markdown: function(text) {
- if (!text) return text;
-
- var self = this,
- IS_URL = /^(https?:\/\/|ftps?:\/\/|mailto:|\.|\/)/,
- IS_ANGULAR = /^(api\/)?(angular|ng|AUTO)\./,
- IS_HASH = /^#/,
- parts = trim(text).split(/(<pre.*?>[\s\S]*?<\/pre>|<doc:example(\S*).*?>[\s\S]*?<\/doc:example>|<example[^>]*>[\s\S]*?<\/example>)/),
- seq = 0,
- placeholderMap = {};
-
- function placeholder(text) {
- var id = 'REPLACEME' + (seq++);
- placeholderMap[id] = text;
- return id;
- }
-
- function extractInlineDocCode(text, tag) {
- if(tag == 'all') {
- //use a greedy operator to match the last </docs> tag
- regex = /\/\/<docs.*?>([.\s\S]+)\/\/<\/docs>/im;
- }
- else {
- //use a non-greedy operator to match the next </docs> tag
- regex = new RegExp("\/\/<docs\\s*tag=\"" + tag + "\".*?>([.\\s\\S]+?)\/\/<\/docs>","im");
- }
- var matches = regex.exec(text.toString());
- return matches && matches.length > 1 ? matches[1] : "";
- }
-
- parts.forEach(function(text, i) {
- parts[i] = (text || '').
- replace(/<example(?:\s+module="([^"]*)")?(?:\s+deps="([^"]*)")?(\s+animations="true")?>([\s\S]*?)<\/example>/gmi,
- function(_, module, deps, animations, content) {
-
- var example = new Example(self.scenarios, self.protractorTests);
- if(animations) {
- example.enableAnimations();
- example.addDeps('angular-animate.js');
- }
-
- example.setModule(module);
- example.addDeps(deps);
- content.replace(/<file\s+name="([^"]*)"\s*>([\s\S]*?)<\/file>/gmi, function(_, name, content) {
- example.addSource(name, content);
- });
- content.replace(/<file\s+src="([^"]+)"(?:\s+tag="([^"]+)")?(?:\s+name="([^"]+)")?\s*\/?>/gmi, function(_, file, tag, name) {
- if(fs.existsSync(file)) {
- var content = fs.readFileSync(file, 'utf8');
- if(content && content.length > 0) {
- if(tag && tag.length > 0) {
- content = extractInlineDocCode(content, tag);
- }
- name = name && name.length > 0 ? name : fspath.basename(file);
- example.addSource(name, content);
- }
- }
- return '';
- })
- return placeholder(example.toHtml());
- }).
- replace(/(?:\*\s+)?<file.+?src="([^"]+)"(?:\s+tag="([^"]+)")?\s*\/?>/i, function(_, file, tag) {
- if(fs.existsSync(file)) {
- var content = fs.readFileSync(file, 'utf8');
- if(tag && tag.length > 0) {
- content = extractInlineDocCode(content, tag);
- }
- return content;
- }
- }).
- replace(/^<doc:example(\s+[^>]*)?>([\s\S]*)<\/doc:example>/mi, function(_, attrs, content) {
- var html, script, scenario,
- example = new Example(self.scenarios, self.protractorTests);
-
- example.setModule((attrs||'module=""').match(/^\s*module=["'](.*)["']\s*$/)[1]);
- content.
- replace(/<doc:source(\s+[^>]*)?>([\s\S]*)<\/doc:source>/mi, function(_, attrs, content) {
- example.addSource('index.html', content.
- replace(/<script>([\s\S]*)<\/script>/mi, function(_, script) {
- example.addSource('script.js', script);
- return '';
- }).
- replace(/<style>([\s\S]*)<\/style>/mi, function(_, style) {
- example.addSource('style.css', style);
- return '';
- })
- );
- }).
- replace(/(<doc:scenario>)([\s\S]*)(<\/doc:scenario>)/mi, function(_, before, content){
- example.addSource('scenario.js', content);
- }).replace(/(<doc:protractor>)([\s\S]*)(<\/doc:protractor>)/mi, function(_, before, content){
- example.addSource('protractorTest.js', content);
- });
-
- return placeholder(example.toHtml());
- }).
- replace(/^<pre(.*?)>([\s\S]*?)<\/pre>/mi, function(_, attrs, content){
- return placeholder(
- '<pre'+attrs+' class="prettyprint linenums">' +
- content.replace(/</g, '&lt;').replace(/>/g, '&gt;') +
- '</pre>');
- }).
- replace(/<div([^>]*)><\/div>/, '<div$1>\n<\/div>').
- replace(/{@link\s+([^\s}]+)\s*([^}]*?)\s*}/g, function(_all, url, title){
- var isFullUrl = url.match(IS_URL),
- isAngular = url.match(IS_ANGULAR),
- isHash = url.match(IS_HASH),
- absUrl = isHash
- ? url
- : (isFullUrl ? url : self.convertUrlToAbsolute(url));
-
- if (!isFullUrl) self.links.push(absUrl);
-
- return '<a href="' + absUrl + '">' +
- (isAngular ? '<code>' : '') +
- (title || url).replace(/^#/g, '').replace(/\n/g, ' ') +
- (isAngular ? '</code>' : '') +
- '</a>';
- }).
- replace(/{@type\s+(\S+)(?:\s+(\S+))?}/g, function(_, type, url) {
- url = url || '#';
- return '<a href="' + url + '" class="' + self.prepare_type_hint_class_name(type) + '">' + type + '</a>';
- }).
- replace(/{@installModule\s+(\S+)?}/g, function(_, module) {
- return explainModuleInstallation(module);
- });
- });
- text = parts.join('');
-
- function prepareClassName(text) {
- return text.toLowerCase().replace(/[_\W]+/g, '-');
- };
-
- var pageClassName, suffix = '-page';
- if(this.name) {
- var split = this.name.match(/^\s*(.+?)\s*:\s*(.+)/);
- if(split && split.length > 1) {
- var before = prepareClassName(split[1]);
- var after = prepareClassName(split[2]);
- pageClassName = before + suffix + ' ' + before + '-' + after + suffix;
- }
- }
- pageClassName = pageClassName || prepareClassName(this.name || 'docs') + suffix;
-
- text = '<div class="' + pageClassName + '">' +
- marked(text) +
- '</div>';
- text = text.replace(/(?:<p>)?(REPLACEME\d+)(?:<\/p>)?/g, function(_, id) {
- return placeholderMap[id];
- });
-
- //!annotate CONTENT
- //!annotate="REGEX" CONTENT
- //!annotate="REGEX" TITLE|CONTENT
- text = text.replace(/\n?\/\/!annotate\s*(?:=\s*['"](.+?)['"])?\s+(.+?)\n\s*(.+?\n)/img,
- function(_, pattern, content, line) {
- var pattern = new RegExp(pattern || '.+');
- var title, text, split = content.split(/\|/);
- if(split.length > 1) {
- text = split[1];
- title = split[0];
- }
- else {
- title = 'Info';
- text = content;
- }
- return "\n" + line.replace(pattern, function(match) {
- return '<div class="nocode nocode-content" data-popover ' +
- 'data-content="' + text + '" ' +
- 'data-title="' + title + '">' +
- match +
- '</div>';
- });
- }
- );
-
- //!details /path/to/local/docs/file.html
- //!details="REGEX" /path/to/local/docs/file.html
- text = text.replace(/\/\/!details\s*(?:=\s*['"](.+?)['"])?\s+(.+?)\n\s*(.+?\n)/img,
- function(_, pattern, url, line) {
- url = '/notes/' + url;
- var pattern = new RegExp(pattern || '.+');
- return line.replace(pattern, function(match) {
- return '<div class="nocode nocode-content" data-foldout data-url="' + url + '">' + match + '</div>';
- });
- }
- );
-
- return text;
- },
-
- parse: function() {
- var atName;
- var atText;
- var match;
- var self = this;
- self.text.split(NEW_LINE).forEach(function(line){
- if ((match = line.match(/^\s*@(\w+)(\s+(.*))?/))) {
- // we found @name ...
- // if we have existing name
- flush();
- atName = match[1];
- atText = [];
- if(match[3]) atText.push(match[3]);
- } else {
- if (atName) {
- atText.push(line);
- }
- }
- });
- flush();
- this.shortName = this.name.split(/[\.:#]/).pop().trim();
- this.id = this.id || // if we have an id just use it
- (this.ngdoc === 'error' ? this.name : '') ||
- (((this.file||'').match(/.*(\/|\\)([^(\/|\\)]*)\.ngdoc/)||{})[2]) || // try to extract it from file name
- this.name; // default to name
- this.moduleName = parseModuleName(this.id);
- this.description = this.markdown(this.description);
- this.example = this.markdown(this.example);
- this['this'] = this.markdown(this['this']);
- return this;
-
- function parseModuleName(id) {
- var module = id.split('.')[0];
- if(module == 'angular') {
- module = 'ng';
- }
- return module;
- }
-
- function flush() {
- if (atName) {
- var text = trim(atText.join('\n')), match;
- if (atName == 'param') {
- match = text.match(/^\{([^}]+)\}\s+(([^\s=]+)|\[(\S+)=([^\]]+)\])\s+(.*)/);
- // 1 1 23 3 4 4 5 5 2 6 6
- if (!match) {
- throw new Error("Not a valid 'param' format: " + text + ' (found in: ' + self.file + ':' + self.line + ')');
- }
-
- var optional = (match[1].slice(-1) === '=');
- var param = {
- name: match[4] || match[3],
- description:self.markdown(text.replace(match[0], match[6])),
- type: optional ? match[1].substring(0, match[1].length-1) : match[1],
- optional: optional,
- default: match[5]
- };
- self.param.push(param);
- } else if (atName == 'returns' || atName == 'return') {
- match = text.match(/^\{([^}]+)\}\s+(.*)/);
- if (!match) {
- throw new Error("Not a valid 'returns' format: " + text + ' (found in: ' + self.file + ':' + self.line + ')');
- }
- self.returns = {
- type: match[1],
- description: self.markdown(text.replace(match[0], match[2]))
- };
- } else if(atName == 'requires') {
- match = text.match(/^([^\s]*)\s*([\S\s]*)/);
- self.requires.push({
- name: match[1],
- text: self.markdown(match[2])
- });
- } else if(atName == 'property') {
- match = text.match(/^\{(\S+)\}\s+(\S+)(\s+(.*))?/);
- if (!match) {
- throw new Error("Not a valid 'property' format: " + text + ' (found in: ' + self.file + ':' + self.line + ')');
- }
- var property = new Doc({
- type: match[1],
- name: match[2],
- shortName: match[2],
- description: self.markdown(text.replace(match[0], match[4]))
- });
- self.properties.push(property);
- } else if(atName == 'eventType') {
- match = text.match(/^([^\s]*)\s+on\s+([\S\s]*)/);
- self.type = match[1];
- self.target = match[2];
- } else {
- self[atName] = text;
- }
- }
- }
- },
-
- html: function() {
- var dom = new DOM(),
- self = this,
- minerrMsg;
-
- var gitTagFromFullVersion = function(version) {
- var match = version.match(/sha\.(\w{7})/);
-
- if (match) {
- // git sha
- return match[1];
- }
-
- // git tag
- return 'v' + version;
- };
-
- if (this.section === 'api') {
- dom.tag('a', {
- href: 'http://github.com/angular/angular.js/tree/' +
- gitTagFromFullVersion(gruntUtil.getVersion().full) + '/' + self.file + '#L' + self.line,
- class: 'view-source btn btn-action' }, function(dom) {
- dom.tag('i', {class:'icon-zoom-in'}, ' ');
- dom.text(' View source');
- });
- }
- dom.tag('a', {
- href: 'http://github.com/angular/angular.js/edit/master/' + self.file,
- class: 'improve-docs btn btn-primary' }, function(dom) {
- dom.tag('i', {class:'icon-edit'}, ' ');
- dom.text(' Improve this doc');
- });
- dom.h(title(this), function() {
- notice('deprecated', 'Deprecated API', self.deprecated);
- if (self.ngdoc === 'error') {
- minerrMsg = lookupMinerrMsg(self);
- dom.tag('pre', {
- class:'minerr-errmsg',
- 'error-display': minerrMsg.replace(/"/g, '&quot;')
- }, minerrMsg);
- }
- if (self.ngdoc != 'overview') {
- dom.h('Description', self.description, dom.html);
- }
- dom.h('Dependencies', self.requires, function(require){
- dom.tag('code', function() {
- dom.tag('a', {href: 'api/ng.' + require.name}, require.name);
- });
- dom.html(require.text);
- });
-
- (self['html_usage_' + self.ngdoc] || function() {
- throw new Error("Don't know how to format @ngdoc: " + self.ngdoc);
- }).call(self, dom);
-
- dom.h('Example', self.example, dom.html);
- });
-
- self.anchors = dom.anchors;
-
- return dom.toString();
-
- //////////////////////////
-
- function notice(name, legend, msg){
- if (self[name] === undefined) return;
- dom.tag('fieldset', {'class':name}, function(dom){
- dom.tag('legend', legend);
- dom.text(msg);
- });
- }
-
- },
-
- prepare_type_hint_class_name : function(type) {
- var typeClass = type.toLowerCase().match(/^[-\w]+/) || [];
- typeClass = typeClass[0] ? typeClass[0] : 'object';
- return 'label type-hint type-hint-' + typeClass;
- },
-
- html_usage_parameters: function(dom) {
- var self = this;
- var params = this.param ? this.param : [];
- if(this.animations) {
- dom.h('Animations', this.animations, function(animations){
- dom.html('<ul>');
- var animations = animations.split("\n");
- animations.forEach(function(ani) {
- dom.html('<li>');
- dom.text(ani);
- dom.html('</li>');
- });
- dom.html('</ul>');
- });
- dom.html('<a href="api/ngAnimate.$animate">Click here</a> to learn more about the steps involved in the animation.');
- }
- if(params.length > 0) {
- dom.html('<h2>Parameters</h2>');
- dom.html('<table class="variables-matrix table table-bordered table-striped">');
- dom.html('<thead>');
- dom.html('<tr>');
- dom.html('<th>Param</th>');
- dom.html('<th>Type</th>');
- dom.html('<th>Details</th>');
- dom.html('</tr>');
- dom.html('</thead>');
- dom.html('<tbody>');
- for(var i=0;i<params.length;i++) {
- param = params[i];
- var name = param.name;
- var types = param.type;
- if(types[0]=='(') {
- types = types.substr(1);
- }
-
- var limit = types.length - 1;
- if(types.charAt(limit) == ')' && types.charAt(limit-1) != '(') {
- types = types.substr(0,limit);
- }
- types = types.split(/\|(?![\(\)\w\|\s]+>)/);
- if (param.optional) {
- name += ' <div><em>(optional)</em></div>';
- }
- dom.html('<tr>');
- dom.html('<td>' + name + '</td>');
- dom.html('<td>');
- for(var j=0;j<types.length;j++) {
- var type = types[j];
- dom.html('<a href="" class="' + self.prepare_type_hint_class_name(type) + '">');
- dom.text(type);
- dom.html('</a>');
- }
-
- dom.html('</td>');
- var description = '<td>';
- description += param.description;
- if (param.default) {
- description += ' <p><em>(default: ' + param.default + ')</em></p>';
- }
- description += '</td>';
- dom.html(description);
- dom.html('</tr>');
- };
- dom.html('</tbody>');
- dom.html('</table>');
- }
- },
-
- html_usage_returns: function(dom) {
- var self = this;
- if (self.returns) {
- dom.html('<h2>Returns</h2>');
- dom.html('<table class="variables-matrix">');
- dom.html('<tr>');
- dom.html('<td>');
- dom.html('<a href="" class="' + self.prepare_type_hint_class_name(self.returns.type) + '">');
- dom.text(self.returns.type);
- dom.html('</a>');
- dom.html('</td>');
- dom.html('<td>');
- dom.html(self.returns.description);
- dom.html('</td>');
- dom.html('</tr>');
- dom.html('</table>');
- }
- },
-
- html_usage_this: function(dom) {
- var self = this;
- if (self['this']) {
- dom.h(function(dom){
- dom.html("Method's <code>this</code>");
- }, function(dom){
- dom.html(self['this']);
- });
- }
- },
-
- html_usage_function: function(dom){
- var self = this;
- var name = self.name.match(/^angular(\.mock)?\.(\w+)$/) ? self.name : self.name.split(/\./).pop()
-
- dom.h('Usage', function() {
- dom.code(function() {
- dom.text(name);
- dom.text('(');
- self.parameters(dom, ', ');
- dom.text(');');
- });
-
- self.html_usage_parameters(dom);
- self.html_usage_this(dom);
- self.html_usage_returns(dom);
- });
- this.method_properties_events(dom);
- },
-
- html_usage_property: function(dom){
- var self = this;
- dom.h('Usage', function() {
- dom.code(function() {
- dom.text(self.name);
- });
-
- self.html_usage_returns(dom);
- });
- },
-
- html_usage_directive: function(dom){
- var self = this;
- dom.h('Usage', function() {
- var restrict = self.restrict || 'A';
-
- if (restrict.match(/E/)) {
- dom.html('<p>');
- dom.text('This directive can be used as custom element, but be aware of ');
- dom.tag('a', {href:'guide/ie'}, 'IE restrictions');
- dom.text('.');
- dom.html('</p>');
- }
-
- if (self.usage) {
- dom.tag('pre', function() {
- dom.tag('code', function() {
- dom.text(self.usage);
- });
- });
- } else {
- if (restrict.match(/E/)) {
- dom.text('as element:');
- dom.code(function() {
- dom.text('<');
- dom.text(dashCase(self.shortName));
- renderParams('\n ', '="', '"');
- dom.text('>\n</');
- dom.text(dashCase(self.shortName));
- dom.text('>');
- });
- }
- if (restrict.match(/A/)) {
- var element = self.element || 'ANY';
- dom.text('as attribute');
- dom.code(function() {
- dom.text('<' + element + ' ');
- dom.text(dashCase(self.shortName));
- renderParams('\n ', '="', '"', true);
- dom.text('>\n ...\n');
- dom.text('</' + element + '>');
- });
- }
- if (restrict.match(/C/)) {
- dom.text('as class');
- var element = self.element || 'ANY';
- dom.code(function() {
- dom.text('<' + element + ' class="');
- dom.text(dashCase(self.shortName));
- renderParams(' ', ': ', ';', true);
- dom.text('">\n ...\n');
- dom.text('</' + element + '>');
- });
- }
- }
- self.html_usage_directiveInfo(dom);
- self.html_usage_parameters(dom);
- });
-
- self.method_properties_events(dom);
-
- function renderParams(prefix, infix, suffix, skipSelf) {
- (self.param||[]).forEach(function(param) {
- var skip = skipSelf && (param.name == self.shortName || param.name.indexOf(self.shortName + '|') == 0);
- if (!skip) {
- dom.text(prefix);
- dom.text(param.optional ? '[' : '');
- var parts = param.name.split('|');
- dom.text(dashCase(parts[skipSelf ? 0 : 1] || parts[0]));
- }
- if (BOOLEAN_ATTR[param.name]) {
- dom.text(param.optional ? ']' : '');
- } else {
- dom.text(BOOLEAN_ATTR[param.name] ? '' : infix );
- dom.text(('{' + param.type + '}').replace(/^\{\'(.*)\'\}$/, '$1'));
- dom.text(suffix);
- dom.text(param.optional && !skip ? ']' : '');
- }
- });
- }
-
- },
-
- html_usage_filter: function(dom){
- var self = this;
- dom.h('Usage', function() {
- dom.h('In HTML Template Binding', function() {
- dom.tag('code', function() {
- if (self.usage) {
- dom.text(self.usage);
- } else {
- dom.text('{{ ');
- dom.text(self.shortName);
- dom.text('_expression | ');
- dom.text(self.shortName);
- self.parameters(dom, ':', true);
- dom.text(' }}');
- }
- });
- });
-
- dom.h('In JavaScript', function() {
- dom.tag('code', function() {
- dom.text('$filter(\'');
- dom.text(self.shortName);
- dom.text('\')(');
- self.parameters(dom, ', ');
- dom.text(')');
- });
- });
-
- self.html_usage_parameters(dom);
- self.html_usage_this(dom);
- self.html_usage_returns(dom);
- });
- },
-
- html_usage_inputType: function(dom){
- var self = this;
- dom.h('Usage', function() {
- dom.code(function() {
- dom.text('<input type="' + self.shortName + '"');
- (self.param||[]).forEach(function(param){
- dom.text('\n ');
- dom.text(param.optional ? ' [' : ' ');
- dom.text(dashCase(param.name));
- dom.text(BOOLEAN_ATTR[param.name] ? '' : '="{' + param.type + '}"');
- dom.text(param.optional ? ']' : '');
- });
- dom.text('>');
- });
- self.html_usage_parameters(dom);
- });
- },
-
- html_usage_directiveInfo: function(dom) {
- var self = this;
- var list = [];
-
-
- if (self.scope !== undefined) {
- list.push('This directive creates new scope.');
- }
- if (self.priority !== undefined) {
- list.push('This directive executes at priority level ' + self.priority + '.');
- }
-
- if (list.length) {
- dom.h('Directive info', function() {
- dom.ul(list);
- });
- }
- },
-
- html_usage_overview: function(dom){
- dom.html(this.description);
- },
-
- html_usage_error: function (dom) {
- dom.html();
- },
-
- html_usage_interface: function(dom){
- var self = this;
-
- if (this.param.length) {
- dom.h('Usage', function() {
- dom.code(function() {
- dom.text(self.name.split('.').pop());
- dom.text('(');
- self.parameters(dom, ', ');
- dom.text(');');
- });
-
- self.html_usage_parameters(dom);
- self.html_usage_this(dom);
- self.html_usage_returns(dom);
- });
- }
- this.method_properties_events(dom);
- },
-
- html_usage_service: function(dom) {
- this.html_usage_interface(dom)
- },
-
- html_usage_object: function(dom) {
- this.html_usage_interface(dom)
- },
-
- method_properties_events: function(dom) {
- var self = this;
- if (self.methods.length) {
- dom.div({class:'member method'}, function(){
- dom.h('Methods', self.methods, function(method){
- var signature = (method.param || []).map(property('name'));
- dom.h(method.shortName + '(' + signature.join(', ') + ')', method, function() {
- dom.html(method.description);
- method.html_usage_parameters(dom);
- self.html_usage_this(dom);
- method.html_usage_returns(dom);
-
- dom.h('Example', method.example, dom.html);
- });
- });
- });
- }
- if (self.properties.length) {
- dom.div({class:'member property'}, function(){
- dom.h('Properties', self.properties, function(property){
- dom.h(property.shortName, function() {
- dom.html(property.description);
- if (!property.html_usage_returns) {
- console.log(property);
- }
- property.html_usage_returns(dom);
- dom.h('Example', property.example, dom.html);
- });
- });
- });
- }
- if (self.events.length) {
- dom.div({class:'member event'}, function(){
- dom.h('Events', self.events, function(event){
- dom.h(event.shortName, event, function() {
- dom.html(event.description);
- if (event.type == 'listen') {
- dom.tag('div', {class:'inline'}, function() {
- dom.h('Listen on:', event.target);
- });
- } else {
- dom.tag('div', {class:'inline'}, function() {
- dom.h('Type:', event.type);
- });
- dom.tag('div', {class:'inline'}, function() {
- dom.h('Target:', event.target);
- });
- }
- event.html_usage_parameters(dom);
- self.html_usage_this(dom);
-
- dom.h('Example', event.example, dom.html);
- });
- });
- });
- }
- },
-
- parameters: function(dom, separator, skipFirst, prefix) {
- var sep = prefix ? separator : '';
- (this.param||[]).forEach(function(param, i){
- if (!(skipFirst && i==0)) {
- if (param.optional) {
- dom.text('[' + sep + param.name + ']');
- } else {
- dom.text(sep + param.name);
- }
- }
- sep = separator;
- });
- }
-
-};
-//////////////////////////////////////////////////////////
-
-
-//////////////////////////////////////////////////////////
-var GLOBALS = /^angular\.([^\.]+)$/,
- MODULE = /^((?:(?!^angular\.)[^\.])+)$/,
- MODULE_MOCK = /^angular\.mock\.([^\.]+)$/,
- MODULE_DIRECTIVE = /^((?:(?!^angular\.)[^\.])+)\.directive:([^\.]+)$/,
- MODULE_DIRECTIVE_INPUT = /^((?:(?!^angular\.)[^\.])+)\.directive:input\.([^\.]+)$/,
- MODULE_FILTER = /^((?:(?!^angular\.)[^\.])+)\.filter:([^\.]+)$/,
- MODULE_SERVICE = /^((?:(?!^angular\.)[^\.])+)\.([^\.]+?)(Provider)?$/,
- MODULE_TYPE = /^((?:(?!^angular\.)[^\.])+)\..+\.([A-Z][^\.]+)$/;
-
-
-function title(doc) {
- if (!doc.name) return doc.name;
- var match,
- text = doc.name;
-
- var makeTitle = function (name, type, componentType, component) {
- // Makes title markup.
- // makeTitle('Foo', 'directive', 'module', 'ng') ->
- // Foo is a directive in module ng
- return function () {
- this.tag('code', name);
- this.tag('div', function () {
- this.tag('span', {class: 'hint'}, function () {
- if (type && component) {
- this.text(type + ' in ' + componentType + ' ');
- this.tag('code', component);
- }
- });
- });
- };
- };
-
- if (doc.ngdoc === 'error') {
- return makeTitle(doc.fullName, 'error', 'component', doc.getMinerrNamespace());
- } else if (text == 'angular.Module') {
- return makeTitle('Module', 'Type', 'module', 'ng');
- } else if (match = text.match(GLOBALS)) {
- return makeTitle('angular.' + match[1], 'API', 'module', 'ng');
- } else if (match = text.match(MODULE)) {
- return makeTitle('', '', 'module', match[1]);
- } else if (match = text.match(MODULE_MOCK)) {
- return makeTitle('angular.mock.' + match[1], 'API', 'module', 'ng');
- } else if (match = text.match(MODULE_DIRECTIVE)) {
- return makeTitle(match[2], 'directive', 'module', match[1]);
- } else if (match = text.match(MODULE_DIRECTIVE_INPUT)) {
- return makeTitle('input [' + match[2] + ']', 'directive', 'module', match[1]);
- } else if (match = text.match(MODULE_FILTER)) {
- return makeTitle(match[2], 'filter', 'module', match[1]);
- } else if (match = text.match(MODULE_SERVICE)) {
- return makeTitle(match[2] + (match[3] || ''), 'service', 'module', match[1]);
- } else if (match = text.match(MODULE_TYPE)) {
- return makeTitle(match[2], 'type', 'module', match[1]);
- }
- return text;
-}
-
-
-function scenarios(docs){
- var specs = [];
-
- specs.push('describe("angular+jqlite", function() {');
- appendSpecs('index-nocache.html#!/');
- specs.push('});');
-
- specs.push('');
- specs.push('');
-
- specs.push('describe("angular+jquery", function() {');
- appendSpecs('index-jq-nocache.html#!/');
- specs.push('});');
-
- return specs.join('\n');
-
- function appendSpecs(urlPrefix) {
- docs.forEach(function(doc){
- specs.push(' describe("' + doc.section + '/' + doc.id + '", function() {');
- specs.push(' beforeEach(function() {');
- specs.push(' browser().navigateTo("' + urlPrefix + doc.section + '/' + doc.id + '");');
- specs.push(' });');
- specs.push(' ');
- doc.scenarios.forEach(function(scenario){
- specs.push(indentCode(trim(scenario), 4));
- specs.push('');
- });
- specs.push('});');
- specs.push('');
- });
- }
-}
-
-function writeProtractorTest(doc, pathPrefix){
- var lines = [];
- lines.push('describe("' + doc.section + '/' + doc.id + '", function() {');
- lines.push(' beforeEach(function() {');
- lines.push(' browser.get("' + pathPrefix + doc.section + '/' + doc.id + '");');
- lines.push(' });');
- lines.push('');
- doc.protractorTests.forEach(function(test){
- lines.push(indentCode(trim(test), 0));
- lines.push('');
- });
- lines.push('});');
- lines.push('');
- return lines.join('\n');
-}
-
-
-//////////////////////////////////////////////////////////
-function metadata(docs){
- var pages = [];
- docs.forEach(function(doc){
- var path = (doc.name || '').split(/(\:\s*)/);
- for ( var i = 1; i < path.length; i++) {
- path.splice(i, 1);
- }
- var shortName = path.pop().trim();
-
- if (path.pop() == 'input') {
- shortName = 'input [' + shortName + ']';
- }
-
- pages.push({
- section: doc.section,
- id: doc.id,
- name: title(doc),
- shortName: shortName,
- type: doc.ngdoc,
- moduleName: doc.moduleName,
- shortDescription: doc.shortDescription(),
- keywords: doc.keywords()
- });
- });
- pages.sort(sidebarSort);
- return pages;
-}
-
-var KEYWORD_PRIORITY = {
- '.index': 1,
- '.overview': 1,
- '.bootstrap': 2,
- '.mvc': 3,
- '.scopes': 4,
- '.compiler': 5,
- '.templates': 6,
- '.services': 7,
- '.di': 8,
- '.unit-testing': 9,
- '.dev_guide': 9,
- '.dev_guide.overview': 1,
- '.dev_guide.bootstrap': 2,
- '.dev_guide.bootstrap.auto_bootstrap': 1,
- '.dev_guide.bootstrap.manual_bootstrap': 2,
- '.dev_guide.mvc': 3,
- '.dev_guide.mvc.understanding_model': 1,
- '.dev_guide.mvc.understanding_controller': 2,
- '.dev_guide.mvc.understanding_view': 3,
- '.dev_guide.scopes': 4,
- '.dev_guide.scopes.understanding_scopes': 1,
- '.dev_guide.scopes.internals': 2,
- '.dev_guide.compiler': 5,
- '.dev_guide.templates': 6,
- '.dev_guide.services': 7,
- '.dev_guide.di': 8,
- '.dev_guide.unit-testing': 9
-};
-
-var GUIDE_PRIORITY = [
- 'introduction',
- 'overview',
- 'concepts',
- 'dev_guide.mvc',
-
- 'dev_guide.mvc.understanding_controller',
- 'dev_guide.mvc.understanding_model',
- 'dev_guide.mvc.understanding_view',
-
- 'dev_guide.services.understanding_services',
- 'dev_guide.services.managing_dependencies',
- 'dev_guide.services.creating_services',
- 'dev_guide.services.injecting_controllers',
- 'dev_guide.services.testing_services',
- 'dev_guide.services.$location',
- 'dev_guide.services',
-
- 'databinding',
- 'dev_guide.templates.css-styling',
- 'dev_guide.templates.filters.creating_filters',
- 'dev_guide.templates.filters',
- 'dev_guide.templates.filters.using_filters',
- 'dev_guide.templates',
-
- 'di',
- 'providers',
- 'module',
- 'scope',
- 'expression',
- 'bootstrap',
- 'directive',
- 'compiler',
-
- 'forms',
- 'animations',
-
- 'dev_guide.e2e-testing',
- 'dev_guide.unit-testing',
-
- 'i18n',
- 'ie',
- 'migration',
-];
-
-function sidebarSort(a, b){
- priorityA = GUIDE_PRIORITY.indexOf(a.id);
- priorityB = GUIDE_PRIORITY.indexOf(b.id);
-
- if (priorityA > -1 || priorityB > -1) {
- return priorityA < priorityB ? -1 : (priorityA > priorityB ? 1 : 0);
- }
-
- function mangleName(doc) {
- var path = doc.id.split(/\./);
- var mangled = [];
- var partialName = '';
- path.forEach(function(name){
- partialName += '.' + name;
- mangled.push(KEYWORD_PRIORITY[partialName] || 5);
- mangled.push(name);
- });
- return (doc.section + '/' + mangled.join('.')).toLowerCase();
- }
- var nameA = mangleName(a);
- var nameB = mangleName(b);
- return nameA < nameB ? -1 : (nameA > nameB ? 1 : 0);
-}
-
-
-//////////////////////////////////////////////////////////
-function trim(text) {
- var MAX_INDENT = 9999;
- var empty = RegExp.prototype.test.bind(/^\s*$/);
- var lines = text.split('\n');
- var minIndent = MAX_INDENT;
- var indentRegExp;
- var ignoreLine = (lines[0][0] != ' ' && lines.length > 1);
- // ignore first line if it has no indentation and there is more than one line
-
- lines.forEach(function(line){
- if (ignoreLine) {
- ignoreLine = false;
- return;
- }
-
- var indent = line.match(/^\s*/)[0].length;
- if (indent > 0 || minIndent == MAX_INDENT) {
- minIndent = Math.min(minIndent, indent);
- }
- });
-
- indentRegExp = new RegExp('^\\s{0,' + minIndent + '}');
-
- for ( var i = 0; i < lines.length; i++) {
- lines[i] = lines[i].replace(indentRegExp, '');
- }
-
- // remove leading lines
- while (empty(lines[0])) {
- lines.shift();
- }
-
- // remove trailing
- while (empty(lines[lines.length - 1])) {
- lines.pop();
- }
- return lines.join('\n');
-}
-
-function indentCode(text, spaceCount) {
- var lines = text.split('\n'),
- indent = '',
- fixedLines = [];
-
- while(spaceCount--) indent += ' ';
-
- lines.forEach(function(line) {
- fixedLines.push(indent + line);
- });
-
- return fixedLines.join('\n');
-}
-
-//////////////////////////////////////////////////////////
-function merge(docs){
- var byFullId = {};
-
- docs.forEach(function(doc) {
- byFullId[doc.section + '/' + doc.id] = doc;
- });
-
- for(var i = 0; i < docs.length;) {
- if (findParent(docs[i], 'method') || findParent(docs[i], 'property') || findParent(docs[i], 'event')) {
- docs.splice(i, 1);
- } else {
- i++;
- }
- }
-
- function findParent(doc, name) {
- var parentName = doc[name + 'Of'];
- if (!parentName) return false;
-
- var parent = byFullId['api/' + parentName];
- if (!parent)
- throw new Error("No parent named '" + parentName + "' for '" +
- doc.name + "' in @" + name + "Of.");
-
- var listName = (name + 's').replace(/ys$/, 'ies');
- var list = parent[listName] = (parent[listName] || []);
- list.push(doc);
- list.sort(orderByName);
- return true;
- }
-
- function orderByName(a, b){
- return a.name < b.name ? -1 : (a.name > b.name ? 1 : 0);
- }
-}
-//////////////////////////////////////////////////////////
-
-
-function checkBrokenLinks(docs) {
- var byFullId = Object.create(null);
-
- docs.forEach(function(doc) {
- byFullId[doc.section + '/' + doc.id] = doc;
- if (doc.section === 'api') {
- doc.anchors.push('directive', 'service', 'filter', 'function');
- }
- });
-
- docs.forEach(function(doc) {
- doc.links.forEach(function(link) {
- // convert #id to path#id
- if (link[0] == '#') {
- link = doc.section + '/' + doc.id.split('#').shift() + link;
- }
-
- var parts = link.split('#');
- var pageLink = parts[0];
- var anchorLink = parts[1];
- var linkedPage = byFullId[pageLink];
-
- if (!linkedPage) {
- console.log('WARNING: ' + doc.section + '/' + doc.id + ' (defined in ' + doc.file + ') points to a non existing page "' + link + '"!');
- } else if (anchorLink && linkedPage.anchors.indexOf(anchorLink) === -1) {
- console.log('WARNING: ' + doc.section + '/' + doc.id + ' (defined in ' + doc.file + ') points to a non existing anchor "' + link + '"!');
- }
- });
- });
-}
-
-
-function property(name) {
- return function(value){
- return value[name];
- };
-}
-
-
-var DASH_CASE_REGEXP = /[A-Z]/g;
-function dashCase(name){
- return name.replace(DASH_CASE_REGEXP, function(letter, pos) {
- return (pos ? '-' : '') + letter.toLowerCase();
- });
-}
-//////////////////////////////////////////////////////////
-
-function explainModuleInstallation(moduleName){
- var ngMod = ngModule(moduleName),
- modulePackage = 'angular-' + moduleName,
- modulePackageFile = modulePackage + '.js';
-
- // Deal with inconsistent ngMock naming - doing it verbosely and explicitly here
- // rather than cleverly interweaving it in the previous lines to make it obvious
- // what is going on
- if ( moduleName == 'mock' ) {
- modulePackage = 'angular-mocks';
- modulePackageFile = modulePackage + '.js';
- }
-
- return '<h1>Installation</h1>' +
- '<p>First include <code>' + modulePackageFile +'</code> in your HTML:</p><pre><code>' +
- ' &lt;script src=&quot;angular.js&quot;&gt;\n' +
- ' &lt;script src=&quot;' + modulePackageFile + '&quot;&gt;</pre></code>' +
-
- '<p>You can download this file from the following places:</p>' +
- '<ul>' +
- '<li>[Google CDN](https://developers.google.com/speed/libraries/devguide#angularjs)<br>' +
- 'e.g. <code>"//ajax.googleapis.com/ajax/libs/angularjs/X.Y.Z/' + modulePackageFile + '"</code></li>' +
- '<li>[Bower](http://bower.io)<br>' +
- 'e.g. <code>bower install ' + modulePackage + '@X.Y.Z</code></li>' +
- '<li><a href="http://code.angularjs.org/">code.angularjs.org</a><br>' +
- 'e.g. <code>"//code.angularjs.org/X.Y.Z/' + modulePackageFile + '"</code></li>' +
- '</ul>' +
- '<p>where X.Y.Z is the AngularJS version you are running.</p>' +
- '<p>Then load the module in your application by adding it as a dependent module:</p><pre><code>' +
- ' angular.module(\'app\', [\'' + ngMod + '\']);</pre></code>' +
-
- '<p>With that you\'re ready to get started!</p>';
-}
-
-function ngModule(moduleName) {
- return 'ng' + moduleName[0].toUpperCase() + moduleName.substr(1);
-}