New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

grunt-ngdocs

Package Overview
Dependencies
Maintainers
1
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

grunt-ngdocs - npm Package Compare versions

Comparing version

to
0.1.9

spec/domSpec.js

15

CHANGELOG.md

@@ -0,1 +1,16 @@

# 0.1.9 (2014-01-09)
## Features
### ngdocs
* update parser to angularjs 1.2.7 code ([7261eade](https://github.com/m7r/grunt-ngdocs/commit/7261eade))
markdown parser has switched from showdown to marked.
* import parser unit tests from angularjs 1.2.7 ([fdeaddc1](https://github.com/m7r/grunt-ngdocs/commit/fdeaddc1))
* check broken links ([6d22869b](https://github.com/m7r/grunt-ngdocs/commit/6d22869b))
# 0.1.8 (2014-01-06)

@@ -2,0 +17,0 @@

16

Gruntfile.js

@@ -5,8 +5,22 @@ /*global module:false*/

grunt.loadNpmTasks('grunt-conventional-changelog');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-jasmine-node');
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
changelog: { options: { dest: 'CHANGELOG.md' } }
changelog: { options: { dest: 'CHANGELOG.md' } },
jasmine_node: {
forceexit: true,
captureExceptions: true
},
watch: {
parser: {
files: ['src/*.js', 'spec/*Spec.js'],
tasks: ['jasmine_node']
}
}
});
grunt.registerTask('test', 'Run tests for parser code', ['jasmine_node']);
};

9

package.json
{
"name": "grunt-ngdocs",
"version": "0.1.8",
"version": "0.1.9",
"description": "grunt plugin for angularjs documentation",

@@ -20,3 +20,3 @@ "main": "tasks",

"dependencies": {
"showdown": "0.3.1"
"marked": "0.2.9"
},

@@ -28,4 +28,7 @@ "peerDependencies": {

"grunt": "~0.4.1",
"grunt-conventional-changelog": "~0.1.0"
"grunt-conventional-changelog": "~0.1.0",
"grunt-contrib-watch": "~0.5.0",
"grunt-jasmine-node": "~0.1.0",
"jasmine-node": "~1.12.0"
}
}

@@ -7,2 +7,3 @@ /**

exports.htmlEscape = htmlEscape;
exports.normalizeHeaderToId = normalizeHeaderToId;

@@ -12,9 +13,40 @@ //////////////////////////////////////////////////////////

function htmlEscape(text){
return text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
return text
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/\{\{/g, '<span>{{</span>')
.replace(/\}\}/g, '<span>}}</span>');
}
function nonEmpty(header) {
return !!header;
}
function idFromCurrentHeaders(headers) {
if (headers.length === 1) return headers[0];
// Do not include the first level title, as that's the title of the page.
return headers.slice(1).filter(nonEmpty).join('_');
}
function normalizeHeaderToId(header) {
if (typeof header !== 'string') {
return '';
}
return header.toLowerCase()
.replace(/<.*>/g, '') // html tags
.replace(/[\!\?\:\.\']/g, '') // special characters
.replace(/&#\d\d;/g, '') // html entities
.replace(/\(.*\)/mg, '') // stuff in parenthesis
.replace(/\s$/, '') // trailing spaces
.replace(/\s+/g, '-'); // replace whitespaces with dashes
}
function DOM() {
this.out = [];
this.headingDepth = 0;
this.currentHeaders = [];
this.anchors = [];
}

@@ -44,12 +76,24 @@

html: function(html) {
if (html) {
var headingDepth = this.headingDepth;
for ( var i = 10; i > 0; --i) {
html = html
.replace(new RegExp('(<\/?h)' + i + '(>)', 'gm'), function(all, start, end){
return start + (i + headingDepth) + end;
});
}
this.out.push(html);
}
if (!html) return;
var self = this;
// rewrite header levels, add ids and collect the ids
html = html.replace(/<h(\d)(.*?)>([\s\S]+?)<\/h\1>/gm, function(_, level, attrs, content) {
level = parseInt(level, 10) + self.headingDepth; // change header level based on the context
self.currentHeaders[level - 1] = normalizeHeaderToId(content);
self.currentHeaders.length = level;
var id = idFromCurrentHeaders(self.currentHeaders);
self.anchors.push(id);
return '<h' + level + attrs + ' id="' + id + '">' + content + '</h' + level + '>';
});
// collect anchors
html = html.replace(/<a name="(\w*)">/g, function(match, anchor) {
self.anchors.push(anchor);
return match;
});
this.out.push(html);
},

@@ -85,13 +129,14 @@

if (content==undefined || (content instanceof Array && content.length == 0)) return;
this.headingDepth++;
this.currentHeaders[this.headingDepth - 1] = normalizeHeaderToId(heading);
this.currentHeaders.length = this.headingDepth;
var className = null,
anchor = null;
if (typeof heading == 'string') {
var id = heading.
replace(/\(.*\)/mg, '').
replace(/[^\d\w\$]/mg, '.').
replace(/-+/gm, '-').
replace(/-*$/gm, '');
var id = idFromCurrentHeaders(this.currentHeaders);
this.anchors.push(id);
anchor = {'id': id};
var classNameValue = id.toLowerCase().replace(/[._]/mg, '-');
var classNameValue = this.currentHeaders[this.headingDepth - 1]
if(classNameValue == 'hide') classNameValue = '';

@@ -98,0 +143,0 @@ className = {'class': classNameValue};

@@ -23,2 +23,3 @@ var seqCount = 0;

this.js = [];
this.json = [];
this.unit = [];

@@ -92,2 +93,3 @@ this.scenario = [];

out.push(' source-edit-js="' + ids(this.js) + '"');
out.push(' source-edit-json="' + ids(this.json) + '"');
out.push(' source-edit-unit="' + ids(this.unit) + '"');

@@ -107,2 +109,3 @@ out.push(' source-edit-scenario="' + ids(this.scenario) + '"');

htmlTabs(this.js);
htmlTabs(this.json);
htmlTabs(this.unit);

@@ -120,3 +123,3 @@ htmlTabs(this.scenario);

if (name === 'index.html') {
wrap = ' ng-html-wrap-loaded="' + self.module + ' ' + self.deps.join(' ') + '"';
wrap = ' ng-html-wrap="' + self.module + ' ' + self.deps.join(' ') + '"';
}

@@ -138,3 +141,3 @@ if (name == 'scenario.js') name = 'End to end test';

var out = [];
out.push('<div class="well doc-example-live animator-container"');
out.push('<div class="well doc-example-live animate-container"');
if(this.animations) {

@@ -141,0 +144,0 @@ out.push(" ng-class=\"{'animations-off':animationsOff == true}\"");

/**
* All parsing/transformation code goes here. All code here should be sync to ease testing.
*/
var Showdown = require('showdown');
var DOM = require('./dom.js').DOM;

@@ -13,3 +11,24 @@ var htmlEscape = require('./dom.js').htmlEscape;

var fspath = require('path');
var errorsJson;
var marked = require('marked');
marked.setOptions({
gfm: true,
tables: true
});
var lookupMinerrMsg = function (doc) {
var code, namespace;
if (errorsJson === undefined) {
errorsJson = require(exports.errorFile).errors;
}
namespace = doc.getMinerrNamespace();
code = doc.getMinerrCode();
if (namespace === undefined) {
return errorsJson[code];
}
return errorsJson[namespace][code];
};
exports.trim = trim;

@@ -19,2 +38,3 @@ exports.metadata = metadata;

exports.merge = merge;
exports.checkBrokenLinks = checkBrokenLinks;
exports.Doc = Doc;

@@ -46,5 +66,6 @@

this.links = this.links || [];
this.anchors = this.anchors || [];
}
Doc.METADATA_IGNORE = (function() {
var words = require('fs').readFileSync(__dirname + '/ignore.words', 'utf8');
var words = fs.readFileSync(__dirname + '/ignore.words', 'utf8');
return words.toString().split(/[,\s\n\r]+/gm);

@@ -81,2 +102,6 @@ })();

});
if (this.ngdoc === 'error') {
words.push(this.getMinerrNamespace());
words.push(this.getMinerrCode());
}
words.sort();

@@ -86,2 +111,27 @@ 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];
},
/**

@@ -103,3 +153,11 @@ * Converts relative urls (without section) into absolute

var prefix = this.options.html5Mode ? '' : '#/';
if (url.substr(-1) == '/') return url + 'index';
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 prefix + url + 'index';
if (url.match(/\//)) return prefix + url;

@@ -116,3 +174,3 @@ return prefix + this.section + '/' + url;

IS_HASH = /^#/,
parts = trim(text).split(/(<pre>[\s\S]*?<\/pre>|<doc:example(\S*).*?>[\s\S]*?<\/doc:example>|<example[^>]*>[\s\S]*?<\/example>)/),
parts = trim(text).split(/(<pre.*?>[\s\S]*?<\/pre>|<doc:example(\S*).*?>[\s\S]*?<\/doc:example>|<example[^>]*>[\s\S]*?<\/example>)/),
seq = 0,

@@ -148,2 +206,3 @@ placeholderMap = {};

example.enableAnimations();
example.addDeps('angular-animate.js');
}

@@ -157,3 +216,3 @@

content.replace(/<file\s+src="([^"]+)"(?:\s+tag="([^"]+)")?(?:\s+name="([^"]+)")?\s*\/?>/gmi, function(_, file, tag, name) {
if(fspath.existsSync(file)) {
if(fs.existsSync(file)) {
var content = fs.readFileSync(file, 'utf8');

@@ -173,3 +232,3 @@ if(content && content.length > 0) {

replace(/(?:\*\s+)?<file.+?src="([^"]+)"(?:\s+tag="([^"]+)")?\s*\/?>/i, function(_, file, tag) {
if(fspath.existsSync(file)) {
if(fs.existsSync(file)) {
var content = fs.readFileSync(file, 'utf8');

@@ -206,5 +265,5 @@ if(tag && tag.length > 0) {

}).
replace(/^<pre>([\s\S]*?)<\/pre>/mi, function(_, content){
replace(/^<pre(.*?)>([\s\S]*?)<\/pre>/mi, function(_, attrs, content){
return placeholder(
'<pre class="prettyprint linenums">' +
'<pre'+attrs+' class="prettyprint linenums">' +
content.replace(/</g, '&lt;').replace(/>/g, '&gt;') +

@@ -229,9 +288,72 @@ '</pre>');

'</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('');
text = new Showdown.converter({ extensions : ['table'] }).makeHtml(text);
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;

@@ -262,2 +384,3 @@ },

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

@@ -291,11 +414,9 @@ this.name; // default to name

optional: optional,
'default':match[5]
default: match[5]
};
//if param name is a part of an object passed to a method
//mark it, so it's not included in the rendering later
// if param name is a part of an object passed to a method
// mark it, so it's not included in the rendering later
if(param.name.indexOf(".") > 0){
param.isProperty = true;
param.isProperty = true;
}
self.param.push(param);

@@ -342,7 +463,43 @@ } else if (atName == 'returns' || atName == 'return') {

var dom = new DOM(),
self = this;
self = this,
minerrMsg;
dom.h(title(this.moduleName, this.name, this.ngdoc == 'overview'), function() {
var gitTagFromFullVersion = function(version) {
var match = version.match(/-(\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') {

@@ -367,2 +524,4 @@ dom.h('Description', self.description, dom.html);

self.anchors = dom.anchors;
return dom.toString();

@@ -373,3 +532,3 @@

function notice(name, legend, msg){
if (self[name] == undefined) return;
if (self[name] === undefined) return;
dom.tag('fieldset', {'class':name}, function(dom){

@@ -383,24 +542,11 @@ dom.tag('legend', legend);

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) {
dom.h('Parameters', this.param, function(param){
dom.tag('code', function() {
dom.text(param.name);
if (param.optional) {
dom.tag('i', function() {
dom.text('(optional');
if(param['default']) {
dom.text('=' + param['default']);
}
dom.text(')');
});
}
dom.text(' – {');
dom.text(param.type);
if (param.optional) {
dom.text('=');
}
dom.text('} – ');
});
dom.html(param.description);
});
var self = this;
var params = this.param ? this.param : [];
if(this.animations) {

@@ -417,3 +563,54 @@ dom.h('Animations', this.animations, function(animations){

});
// 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>');
}
},

@@ -424,7 +621,15 @@

if (self.returns) {
dom.h('Returns', function() {
dom.tag('code', '{' + self.returns.type + '}');
dom.text('– ');
dom.html(self.returns.description);
});
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>');
}

@@ -446,3 +651,3 @@ },

var self = this;
var name = self.name.match(/^angular(\.mock)?\.(\w+)$/) ? self.name : self.name.split(/\./).pop();
var name = self.name.match(/^angular(\.mock)?\.(\w+)$/) ? self.name : self.name.split(/\./).pop()

@@ -468,3 +673,3 @@ dom.h('Usage', function() {

dom.code(function() {
dom.text(self.name);
dom.text(self.name.split(':').pop());
});

@@ -479,11 +684,13 @@

dom.h('Usage', function() {
var restrict = self.restrict || 'AC';
var restrict = self.restrict || 'A';
/*if (restrict.match(/E/)) {
/*
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:'http://docs.angularjs.org/guide/ie'}, 'IE restrictions');
dom.tag('a', {href:'guide/ie'}, 'IE restrictions');
dom.text('.');
dom.html('</p>');
}*/
}
*/

@@ -530,44 +737,2 @@ if (self.usage) {

}
if(self.animations) {
var animations = [], matches = self.animations.split("\n");
matches.forEach(function(ani) {
var name = ani.match(/^\s*(.+?)\s*-/)[1];
animations.push(name);
});
dom.html('with <span id="animations">animations</span>');
var comment;
if(animations.length == 1) {
comment = 'The ' + animations[0] + ' animation is supported';
}
else {
var rhs = animations[animations.length-1];
var lhs = '';
for(var i=0;i<animations.length-1;i++) {
if(i>0) {
lhs += ', ';
}
lhs += animations[i];
}
comment = 'The ' + lhs + ' and ' + rhs + ' animations are supported';
}
var element = self.element || 'ANY';
dom.code(function() {
dom.text('//' + comment + "\n");
dom.text('<' + element + ' ');
dom.text(dashCase(self.shortName));
renderParams('\n ', '="', '"', true);
dom.text(' ng-animate="{');
animations.forEach(function(ani, index) {
if (index) {
dom.text(', ');
}
dom.text(ani + ': \'' + ani + '-animation\'');
});
dom.text('}">\n ...\n');
dom.text('</' + element + '>');
});
dom.html('<a href="api/ng.$animator#Methods">Click here</a> to learn more about the steps involved in the animation.');
}
}

@@ -587,3 +752,3 @@ self.html_usage_directiveInfo(dom);

var parts = param.name.split('|');
dom.text(parts[skipSelf ? 0 : 1] || parts[0]);
dom.text(dashCase(parts[skipSelf ? 0 : 1] || parts[0]));
}

@@ -678,2 +843,6 @@ if (BOOLEAN_ATTR[param.name]) {

html_usage_error: function (dom) {
dom.html();
},
html_usage_interface: function(dom){

@@ -685,3 +854,3 @@ var self = this;

dom.code(function() {
dom.text(self.name.split('.').pop());
dom.text(self.name.split('.').pop().split(':').pop());
dom.text('(');

@@ -714,4 +883,3 @@ self.parameters(dom, ', ');

//filters out .IsProperty parameters from the method signature
var signature = (method.param || []).filter(function(e) { return e.isProperty !== true}).map(property('name'));
var signature = (method.param || []).filter(function(e) { return e.isProperty !== true; }).map(property('name'));
dom.h(method.shortName + '(' + signature.join(', ') + ')', method, function() {

@@ -773,3 +941,3 @@ dom.html(method.description);

if (!(skipFirst && i==0)) {
if (param.isProperty) { return; }
if (param.isProperty) { return; }
if (param.optional) {

@@ -800,64 +968,59 @@ dom.text('[' + sep + param.name + ']');

function title(module, text, overview) {
if (!text) return text;
function title(doc) {
if (!doc.name) return doc.name;
var match,
module,
type,
name;
module = doc.moduleName,
overview = doc.ngdoc == 'overview',
text = doc.name;
if (text == 'angular.Module') {
module = 'ng';
name = 'Module';
type = 'Type';
var makeTitle = function (name, type, componentType, component) {
if (!module) {
module = component;
if (module == 'angular') {
module = 'ng';
}
doc.moduleName = module;
}
// 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)) {
module = 'ng';
name = 'angular.' + match[1];
type = 'API';
return makeTitle('angular.' + match[1], 'API', 'module', 'ng');
} else if (match = text.match(MODULE)) {
module = match[1];
if (!overview) { name = match[1]; }
return makeTitle(overview ? '' : match[1], '', 'module', match[1]);
} else if (match = text.match(MODULE_MOCK)) {
module = 'ng';
name = 'angular.mock.' + match[1];
type = 'API';
return makeTitle('angular.mock.' + match[1], 'API', 'module', 'ng');
} else if (match = text.match(MODULE_DIRECTIVE)) {
module = match[1];
name = match[2];
type = 'directive';
return makeTitle(match[2], 'directive', 'module', match[1]);
} else if (match = text.match(MODULE_DIRECTIVE_INPUT)) {
module = match[1];
name = 'input [' + match[2] + ']';
type = 'directive';
return makeTitle('input [' + match[2] + ']', 'directive', 'module', match[1]);
} else if (match = text.match(MODULE_CUSTOM)) {
module = match[1];
name = match[3];
type = match[2];
return makeTitle(match[3], match[2], 'module', match[1]);
} else if (match = text.match(MODULE_TYPE)) {
module = module || match[1];
name = match[2];
type = 'type';
return makeTitle(match[2], 'type', 'module', module || match[1]);
} else if (match = text.match(MODULE_SERVICE)) {
if (overview) {
// module name with dots looks like a service
module = text;
} else {
module = module || match[1];
name = match[2] + (match[3] || '');
type = 'service';
return makeTitle('', '', 'module', text);
}
} else {
return text;
return makeTitle(match[2] + (match[3] || ''), 'service', 'module', module || match[1]);
}
return function() {
this.tag('code', name);
this.tag('span', { class: 'hint'}, function() {
if (type) {
this.text('(');
this.text(type);
this.text(' in module ');
this.tag('code', module);
this.text(')');
}
});
};
return text;
}

@@ -904,3 +1067,3 @@

docs.forEach(function(doc){
var path = (doc.name || '').split(/(\.|\:\s*)/);
var path = (doc.name || '').split(/(\:\s*)/);
for ( var i = 1; i < path.length; i++) {

@@ -918,10 +1081,11 @@ path.splice(i, 1);

id: doc.id,
name: title(doc.moduleName, doc.name),
moduleName: doc.moduleName,
name: title(doc),
shortName: shortName,
type: doc.ngdoc,
keywords:doc.keywords()
moduleName: doc.moduleName,
shortDescription: doc.shortDescription(),
keywords: doc.keywords()
});
});
pages.sort(keywordSort);
pages.sort(sidebarSort);
return pages;

@@ -959,3 +1123,56 @@ }

};
function keywordSort(a, b){
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) {

@@ -1041,18 +1258,3 @@ var path = doc.id.split(/\./);

for(var i = 0; i < docs.length;) {
var doc = docs[i];
// check links - do they exist ?
doc.links.forEach(function(link) {
// convert #id to path#id
if (link[0] == '#') {
link = doc.section + '/' + doc.id.split('#').shift() + link;
}
link = link.split('#').shift();
if (!byFullId[link]) {
console.log('WARNING: In ' + doc.section + '/' + doc.id + ', non existing link: "' + link + '"');
}
});
// merge into parents
if (findParent(doc, 'method') || findParent(doc, 'property') || findParent(doc, 'event')) {
if (findParent(docs[i], 'method') || findParent(docs[i], 'property') || findParent(docs[i], 'event')) {
docs.splice(i, 1);

@@ -1086,2 +1288,38 @@ } else {

function checkBrokenLinks(docs, apis, options) {
var byFullId = Object.create(null);
docs.forEach(function(doc) {
byFullId[doc.section + '/' + doc.id] = doc;
if (apis[doc.section]) {
doc.anchors.push('directive', 'service', 'filter', 'function');
}
});
docs.forEach(function(doc) {
doc.links.forEach(function(link) {
if (options && !options.html5mode) {
link = link.substring(2);
}
// 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) {

@@ -1100,1 +1338,32 @@ return function(value){

}
//////////////////////////////////////////////////////////
function explainModuleInstallation(moduleName){
var ngMod = ngModule(moduleName),
modulePackage = 'angular-' + moduleName,
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);
}

@@ -94,2 +94,3 @@ /*

ngdoc.merge(reader.docs);
ngdoc.checkBrokenLinks(reader.docs, setup.apis, options);

@@ -96,0 +97,0 @@ reader.docs.forEach(function(doc){

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet