2012-04-29 05:45:28 +00:00
var docsApp = {
controller : { } ,
directive : { } ,
serviceFactory : { }
} ;
2013-06-14 02:37:13 +00:00
docsApp . controller . DocsVersionsCtrl = [ '$scope' , '$window' , 'NG_VERSIONS' , function ( $scope , $window , NG _VERSIONS ) {
$scope . versions = expandVersions ( NG _VERSIONS ) ;
$scope . version = ( $scope . version || angular . version . full ) . match ( /^([\d\.]+\d+)/ ) [ 1 ] ; //match only the number
$scope . jumpToDocsVersion = function ( value ) {
var isLastStable ,
version ,
versions = $scope . versions ;
for ( var i = versions . length - 1 ; i >= 0 ; i -- ) {
var v = versions [ i ] ;
if ( v . version == value ) {
var next = versions [ i - 1 ] ;
isLastStable = v . stable && ( ! next || next && ! next . stable ) ;
version = v ;
break ;
}
} ;
if ( version && version . version >= '1.0.0' ) {
//the older versions have a different path to the docs within their repo directory
var docsPath = version . version < '1.0.2' ? 'docs-' + version . version : 'docs' ;
//the last stable version should redirect to docs.angularjs.org instead of code.angularjs.org
var url = 'http://' +
( isLastStable ?
'docs.angularjs.org' :
'code.angularjs.org/' + version . version + '/' + docsPath ) ;
$window . location = url ;
}
} ;
function expandVersions ( angularVersions ) {
var unstableVersionStart = 0 ;
angularVersions . forEach ( function ( version ) {
var split = version . split ( '.' ) ;
unstableVersionStart = split [ 1 ] % 2 == 1 ?
Math . max ( unstableVersionStart , parseInt ( split [ 0 ] + '' + split [ 1 ] ) ) :
unstableVersionStart ;
} ) ;
var versions = [ ] ;
for ( var i = angularVersions . length - 1 ; i >= 0 ; i -- ) {
var version = angularVersions [ i ] ;
var split = version . split ( '.' ) ;
var stable = parseInt ( split [ 0 ] + '' + split [ 1 ] ) < unstableVersionStart ;
versions . push ( {
version : version ,
stable : stable ,
title : 'AngularJS - v' + version ,
group : ( stable ? 'Stable' : 'Unstable' )
} ) ;
} ;
return versions ;
} ;
} ] ;
2013-06-18 13:37:29 +00:00
docsApp . controller . DocsNavigationCtrl = [ '$scope' , '$location' , 'docsSearch' , function ( $scope , $location , docsSearch ) {
function clearResults ( ) {
$scope . results = [ ] ;
$scope . colClassName = null ;
$scope . hasResults = false ;
}
2013-05-10 01:53:07 +00:00
$scope . search = function ( q ) {
2013-06-18 13:40:13 +00:00
var MIN _SEARCH _LENGTH = 3 ;
2013-06-18 13:37:29 +00:00
if ( q . length >= MIN _SEARCH _LENGTH ) {
var results = docsSearch ( q ) ;
var totalSections = 0 ;
for ( var i in results ) {
++ totalSections ;
2013-05-10 01:53:07 +00:00
}
2013-06-18 13:37:29 +00:00
if ( totalSections > 0 ) {
$scope . colClassName = 'cols-' + totalSections ;
$scope . hasResults = true ;
2013-05-10 01:53:07 +00:00
}
2013-06-18 13:37:29 +00:00
$scope . results = results ;
}
else {
clearResults ( ) ;
}
if ( ! $scope . $$phase ) $scope . $apply ( ) ;
2013-05-10 01:53:07 +00:00
} ;
$scope . submit = function ( ) {
var result ;
for ( var i in $scope . results ) {
result = $scope . results [ i ] [ 0 ] ;
if ( result ) {
break ;
}
}
if ( result ) {
$location . path ( result . url ) ;
$scope . hideResults ( ) ;
}
} ;
$scope . hideResults = function ( ) {
2013-06-18 13:37:29 +00:00
clearResults ( ) ;
2013-05-10 01:53:07 +00:00
$scope . q = '' ;
} ;
} ] ;
2013-06-18 13:37:29 +00:00
docsApp . serviceFactory . lunrSearch = function ( ) {
return function ( properties ) {
var engine = lunr ( properties ) ;
return {
store : function ( values ) {
engine . add ( values ) ;
} ,
search : function ( q ) {
return engine . search ( q ) ;
}
} ;
} ;
} ;
2013-05-10 01:53:07 +00:00
2013-06-18 13:37:29 +00:00
docsApp . serviceFactory . docsSearch = [ '$rootScope' , 'lunrSearch' , 'NG_PAGES' ,
function ( $rootScope , lunrSearch , NG _PAGES ) {
2013-05-10 01:53:07 +00:00
2013-06-18 13:37:29 +00:00
var index = lunrSearch ( function ( ) {
this . ref ( 'id' ) ;
this . field ( 'title' , { boost : 50 } ) ;
this . field ( 'description' , { boost : 20 } ) ;
} ) ;
2013-05-10 01:53:07 +00:00
2013-06-18 13:37:29 +00:00
angular . forEach ( NG _PAGES , function ( page , i ) {
var title = page . shortName ;
if ( title . charAt ( 0 ) == 'n' && title . charAt ( 1 ) == 'g' ) {
title = title + ' ' + title . charAt ( 2 ) . toLowerCase ( ) + title . substr ( 3 ) ;
}
index . store ( {
id : i ,
title : title ,
description : page . keywords
} ) ;
} ) ;
return function ( q ) {
var results = { } ;
angular . forEach ( index . search ( q ) , function ( result ) {
var item = NG _PAGES [ result . ref ] ;
var section = item . section ;
if ( section == 'cookbook' ) {
section = 'tutorial' ;
2013-05-10 01:53:07 +00:00
}
2013-06-18 13:37:29 +00:00
results [ section ] = results [ section ] || [ ] ;
if ( results [ section ] . length < 15 ) {
results [ section ] . push ( item ) ;
2013-05-10 01:53:07 +00:00
}
2013-06-18 13:37:29 +00:00
} ) ;
return results ;
2013-05-10 01:53:07 +00:00
} ;
} ] ;
2012-04-29 05:45:28 +00:00
2012-06-12 07:11:04 +00:00
docsApp . directive . focused = function ( $timeout ) {
2012-04-29 05:45:28 +00:00
return function ( scope , element , attrs ) {
element [ 0 ] . focus ( ) ;
2013-06-19 19:52:50 +00:00
element . on ( 'focus' , function ( ) {
2012-04-29 05:45:28 +00:00
scope . $apply ( attrs . focused + '=true' ) ;
} ) ;
2013-06-19 19:52:50 +00:00
element . on ( 'blur' , function ( ) {
2012-06-12 07:11:04 +00:00
// have to use $timeout, so that we close the drop-down after the user clicks,
2012-04-29 05:45:28 +00:00
// otherwise when the user clicks we process the closing before we process the click.
2012-06-12 07:11:04 +00:00
$timeout ( function ( ) {
scope . $eval ( attrs . focused + '=false' ) ;
} ) ;
2012-04-29 05:45:28 +00:00
} ) ;
2013-05-21 21:52:38 +00:00
scope . $eval ( attrs . focused + '=true' ) ;
} ;
2012-04-29 05:45:28 +00:00
} ;
2013-06-14 02:30:11 +00:00
docsApp . directive . docsSearchInput = function ( ) {
return function ( scope , element , attrs ) {
var ESCAPE _KEY _KEYCODE = 27 ;
element . bind ( 'keydown' , function ( event ) {
if ( event . keyCode == ESCAPE _KEY _KEYCODE ) {
event . stopPropagation ( ) ;
event . preventDefault ( ) ;
scope . $apply ( function ( ) {
scope . hideResults ( ) ;
} ) ;
}
} ) ;
} ;
} ;
2012-04-29 05:45:28 +00:00
docsApp . directive . code = function ( ) {
return { restrict : 'E' , terminal : true } ;
} ;
docsApp . directive . sourceEdit = function ( getEmbeddedTemplate ) {
return {
2012-10-25 15:27:15 +00:00
template : '<div class="btn-group pull-right">' +
'<a class="btn dropdown-toggle btn-primary" data-toggle="dropdown" href>' +
' <i class="icon-pencil icon-white"></i> Edit<span class="caret"></span>' +
'</a>' +
'<ul class="dropdown-menu">' +
' <li><a ng-click="plunkr($event)" href="">In Plunkr</a></li>' +
' <li><a ng-click="fiddle($event)" href="">In JsFiddle</a></li>' +
2012-11-21 08:45:43 +00:00
'</ul>' +
'</div>' ,
2012-04-29 05:45:28 +00:00
scope : true ,
2012-10-25 15:27:15 +00:00
controller : function ( $scope , $attrs , openJsFiddle , openPlunkr ) {
2012-04-29 05:45:28 +00:00
var sources = {
module : $attrs . sourceEdit ,
deps : read ( $attrs . sourceEditDeps ) ,
html : read ( $attrs . sourceEditHtml ) ,
css : read ( $attrs . sourceEditCss ) ,
js : read ( $attrs . sourceEditJs ) ,
unit : read ( $attrs . sourceEditUnit ) ,
scenario : read ( $attrs . sourceEditScenario )
} ;
$scope . fiddle = function ( e ) {
e . stopPropagation ( ) ;
openJsFiddle ( sources ) ;
2012-10-25 15:27:15 +00:00
} ;
$scope . plunkr = function ( e ) {
e . stopPropagation ( ) ;
openPlunkr ( sources ) ;
} ;
2012-04-29 05:45:28 +00:00
}
2013-05-21 21:52:38 +00:00
} ;
2012-04-29 05:45:28 +00:00
function read ( text ) {
var files = [ ] ;
angular . forEach ( text ? text . split ( ' ' ) : [ ] , function ( refId ) {
2012-10-31 19:56:55 +00:00
// refId is index.html-343, so we need to strip the unique ID when exporting the name
files . push ( { name : refId . replace ( /-\d+$/ , '' ) , content : getEmbeddedTemplate ( refId ) } ) ;
2012-04-29 05:45:28 +00:00
} ) ;
return files ;
}
} ;
docsApp . directive . docTutorialNav = function ( templateMerge ) {
var pages = [
'' ,
'step_00' , 'step_01' , 'step_02' , 'step_03' , 'step_04' ,
'step_05' , 'step_06' , 'step_07' , 'step_08' , 'step_09' ,
'step_10' , 'step_11' , 'the_end'
] ;
return {
compile : function ( element , attrs ) {
var seq = 1 * attrs . docTutorialNav ,
props = {
seq : seq ,
prev : pages [ seq ] ,
next : pages [ 2 + seq ] ,
diffLo : seq ? ( seq - 1 ) : '0~1' ,
diffHi : seq
} ;
element . addClass ( 'btn-group' ) ;
element . addClass ( 'tutorial-nav' ) ;
element . append ( templateMerge (
'<li class="btn btn-primary"><a href="tutorial/{{prev}}"><i class="icon-step-backward"></i> Previous</a></li>\n' +
'<li class="btn btn-primary"><a href="http://angular.github.com/angular-phonecat/step-{{seq}}/app"><i class="icon-play"></i> Live Demo</a></li>\n' +
'<li class="btn btn-primary"><a href="https://github.com/angular/angular-phonecat/compare/step-{{diffLo}}...step-{{diffHi}}"><i class="icon-search"></i> Code Diff</a></li>\n' +
'<li class="btn btn-primary"><a href="tutorial/{{next}}">Next <i class="icon-step-forward"></i></a></li>' , props ) ) ;
}
} ;
} ;
2012-05-23 05:22:14 +00:00
2012-04-29 05:45:28 +00:00
docsApp . directive . docTutorialReset = function ( ) {
function tab ( name , command , id , step ) {
return '' +
' <div class=\'tab-pane well\' title="' + name + '" value="' + id + '">\n' +
' <ol>\n' +
' <li><p>Reset the workspace to step ' + step + '.</p>' +
' <pre>' + command + '</pre></li>\n' +
2012-07-15 16:18:42 +00:00
' <li><p>Refresh your browser or check the app out on <a href="http://angular.github.com/angular-phonecat/step-' + step + '/app">Angular\'s server</a>.</p></li>\n' +
2012-04-29 05:45:28 +00:00
' </ol>\n' +
' </div>\n' ;
}
return {
compile : function ( element , attrs ) {
var step = attrs . docTutorialReset ;
element . html (
'<div ng-hide="show">' +
'<p><a href="" ng-click="show=true;$event.stopPropagation()">Workspace Reset Instructions ➤</a></p>' +
'</div>\n' +
'<div class="tabbable" ng-show="show" ng-model="$cookies.platformPreference">\n' +
tab ( 'Git on Mac/Linux' , 'git checkout -f step-' + step , 'gitUnix' , step ) +
tab ( 'Git on Windows' , 'git checkout -f step-' + step , 'gitWin' , step ) +
'</div>\n' ) ;
}
} ;
2013-05-21 21:52:38 +00:00
} ;
2012-04-29 05:45:28 +00:00
2013-07-13 00:42:27 +00:00
docsApp . directive . errorDisplay = [ '$location' , function ( $location ) {
var interpolate = function ( formatString ) {
var formatArgs = arguments ;
return formatString . replace ( /\{\d+\}/g , function ( match ) {
// Drop the braces and use the unary plus to convert to an integer.
// The index will be off by one because of the formatString.
var index = + match . slice ( 1 , - 1 ) ;
if ( index + 1 >= formatArgs . length ) {
return match ;
}
return formatArgs [ index + 1 ] ;
} ) ;
} ;
return {
link : function ( scope , element , attrs ) {
var search = $location . search ( ) ,
formatArgs = [ attrs . errorDisplay ] ,
i ;
for ( i = 0 ; search [ 'p' + i ] ; i ++ ) {
formatArgs . push ( search [ 'p' + i ] ) ;
}
element . text ( interpolate . apply ( null , formatArgs ) ) ;
}
} ;
} ] ;
2012-04-29 05:45:28 +00:00
docsApp . serviceFactory . angularUrls = function ( $document ) {
var urls = { } ;
angular . forEach ( $document . find ( 'script' ) , function ( script ) {
var match = script . src . match ( /^.*\/(angular[^\/]*\.js)$/ ) ;
if ( match ) {
urls [ match [ 1 ] . replace ( /(\-\d.*)?(\.min)?\.js$/ , '.js' ) ] = match [ 0 ] ;
}
} ) ;
return urls ;
2013-05-21 21:52:38 +00:00
} ;
2012-04-29 05:45:28 +00:00
docsApp . serviceFactory . formPostData = function ( $document ) {
return function ( url , fields ) {
var form = angular . element ( '<form style="display: none;" method="post" action="' + url + '" target="_blank"></form>' ) ;
angular . forEach ( fields , function ( value , name ) {
var input = angular . element ( '<input type="hidden" name="' + name + '">' ) ;
input . attr ( 'value' , value ) ;
form . append ( input ) ;
} ) ;
$document . find ( 'body' ) . append ( form ) ;
form [ 0 ] . submit ( ) ;
form . remove ( ) ;
} ;
} ;
2012-10-25 15:27:15 +00:00
docsApp . serviceFactory . openPlunkr = function ( templateMerge , formPostData , angularUrls ) {
return function ( content ) {
var allFiles = [ ] . concat ( content . js , content . css , content . html ) ;
var indexHtmlContent = '<!doctype html>\n' +
2013-06-19 22:14:45 +00:00
'<html ng-app="{{module}}">\n' +
2012-10-25 15:27:15 +00:00
' <head>\n' +
' <script src="{{angularJSUrl}}"></script>\n' +
'{{scriptDeps}}\n' +
' </head>\n' +
' <body>\n\n' +
'{{indexContents}}' +
'\n\n </body>\n' +
'</html>\n' ;
var scriptDeps = '' ;
angular . forEach ( content . deps , function ( file ) {
if ( file . name !== 'angular.js' ) {
2013-05-21 21:52:38 +00:00
scriptDeps += ' <script src="' + file . name + '"></script>\n' ;
2012-10-25 15:27:15 +00:00
}
} ) ;
indexProp = {
2013-06-19 22:14:45 +00:00
module : content . module ,
2012-10-25 15:27:15 +00:00
angularJSUrl : angularUrls [ 'angular.js' ] ,
scriptDeps : scriptDeps ,
indexContents : content . html [ 0 ] . content
} ;
var postData = { } ;
angular . forEach ( allFiles , function ( file , index ) {
if ( file . content && file . name != 'index.html' ) {
postData [ 'files[' + file . name + ']' ] = file . content ;
}
} ) ;
postData [ 'files[index.html]' ] = templateMerge ( indexHtmlContent , indexProp ) ;
2012-12-11 16:42:00 +00:00
postData [ 'tags[]' ] = "angularjs" ;
2013-05-21 21:52:38 +00:00
2012-12-11 16:42:00 +00:00
postData . private = true ;
2012-10-25 15:27:15 +00:00
postData . description = 'AngularJS Example Plunkr' ;
formPostData ( 'http://plnkr.co/edit/?p=preview' , postData ) ;
} ;
} ;
docsApp . serviceFactory . openJsFiddle = function ( templateMerge , formPostData , angularUrls ) {
2012-04-29 05:45:28 +00:00
var HTML = '<div ng-app=\"{{module}}\">\n{{html:2}}</div>' ,
CSS = '</style> <!-- Ugly Hack due to jsFiddle issue: http://goo.gl/BUfGZ --> \n' +
'{{head:0}}<style>\n .ng-invalid { border: 1px solid red; } \n{{css}}' ,
SCRIPT = '{{script}}' ,
SCRIPT _CACHE = '\n\n<!-- {{name}} -->\n<script type="text/ng-template" id="{{name}}">\n{{content:2}}</script>' ;
return function ( content ) {
var prop = {
module : content . module ,
html : '' ,
css : '' ,
script : ''
} ;
prop . head = templateMerge ( '<script src="{{url}}"></script>' , { url : angularUrls [ 'angular.js' ] } ) ;
angular . forEach ( content . html , function ( file , index ) {
if ( index ) {
prop . html += templateMerge ( SCRIPT _CACHE , file ) ;
} else {
prop . html += file . content ;
}
} ) ;
angular . forEach ( content . js , function ( file , index ) {
prop . script += file . content ;
} ) ;
angular . forEach ( content . css , function ( file , index ) {
prop . css += file . content ;
} ) ;
formPostData ( "http://jsfiddle.net/api/post/library/pure/" , {
title : 'AngularJS Example' ,
html : templateMerge ( HTML , prop ) ,
js : templateMerge ( SCRIPT , prop ) ,
css : templateMerge ( CSS , prop )
} ) ;
} ;
} ;
2013-06-14 02:37:13 +00:00
docsApp . serviceFactory . sections = [ 'NG_PAGES' , function sections ( NG _PAGES ) {
2012-04-29 05:45:28 +00:00
var sections = {
guide : [ ] ,
api : [ ] ,
tutorial : [ ] ,
misc : [ ] ,
cookbook : [ ] ,
2013-07-13 00:42:27 +00:00
error : [ ] ,
2012-04-29 05:45:28 +00:00
getPage : function ( sectionId , partialId ) {
var pages = sections [ sectionId ] ;
partialId = partialId || 'index' ;
for ( var i = 0 , ii = pages . length ; i < ii ; i ++ ) {
if ( pages [ i ] . id == partialId ) {
return pages [ i ] ;
}
}
return null ;
}
} ;
angular . forEach ( NG _PAGES , function ( page ) {
page . url = page . section + '/' + page . id ;
if ( page . id == 'angular.Module' ) {
page . partialUrl = 'partials/api/angular.IModule.html' ;
} else {
page . partialUrl = 'partials/' + page . url + '.html' ;
}
sections [ page . section ] . push ( page ) ;
} ) ;
return sections ;
2013-06-14 02:37:13 +00:00
} ] ;
2012-04-29 05:45:28 +00:00
docsApp . controller . DocsController = function ( $scope , $location , $window , $cookies , sections ) {
2013-06-06 05:28:50 +00:00
$scope . fold = function ( url ) {
if ( url ) {
$scope . docs _fold = '/notes/' + url ;
if ( /\/build/ . test ( $window . location . href ) ) {
$scope . docs _fold = '/build/docs' + $scope . docs _fold ;
}
window . scrollTo ( 0 , 0 ) ;
}
else {
$scope . docs _fold = null ;
}
} ;
2012-04-29 05:45:28 +00:00
var OFFLINE _COOKIE _NAME = 'ng-offline' ,
2013-07-13 00:42:27 +00:00
DOCS _PATH = /^\/(api)|(guide)|(cookbook)|(misc)|(tutorial)|(error)/ ,
2012-04-29 05:45:28 +00:00
INDEX _PATH = /^(\/|\/index[^\.]*.html)$/ ,
2012-06-12 06:49:24 +00:00
GLOBALS = /^angular\.([^\.]+)$/ ,
2013-07-13 00:42:27 +00:00
ERROR = /^([a-zA-Z0-9_$]+:)?([a-zA-Z0-9_$]+)$/ ,
2012-06-12 06:49:24 +00:00
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][^\.]+)$/ ,
2012-04-29 05:45:28 +00:00
URL = {
module : 'guide/module' ,
directive : 'guide/directive' ,
2012-06-12 06:49:24 +00:00
input : 'api/ng.directive:input' ,
2012-04-29 05:45:28 +00:00
filter : 'guide/dev_guide.templates.filters' ,
service : 'guide/dev_guide.services' ,
type : 'guide/types'
} ;
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Publish methods
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
$scope . navClass = function ( page1 , page2 ) {
return {
2012-05-25 22:52:44 +00:00
last : this . $last ,
2012-04-29 05:45:28 +00:00
active : page1 && this . currentPage == page1 || page2 && this . currentPage == page2
} ;
2013-05-21 21:52:38 +00:00
} ;
2012-04-29 05:45:28 +00:00
$scope . submitForm = function ( ) {
$scope . bestMatch && $location . path ( $scope . bestMatch . page . url ) ;
} ;
$scope . afterPartialLoaded = function ( ) {
var currentPageId = $location . path ( ) ;
$scope . partialTitle = $scope . currentPage . shortName ;
$window . _gaq . push ( [ '_trackPageview' , currentPageId ] ) ;
loadDisqus ( currentPageId ) ;
} ;
/** stores a cookie that is used by apache to decide which manifest ot send */
$scope . enableOffline = function ( ) {
//The cookie will be good for one year!
var date = new Date ( ) ;
date . setTime ( date . getTime ( ) + ( 365 * 24 * 60 * 60 * 1000 ) ) ;
var expires = "; expires=" + date . toGMTString ( ) ;
var value = angular . version . full ;
document . cookie = OFFLINE _COOKIE _NAME + "=" + value + expires + "; path=" + $location . path ;
//force the page to reload so server can serve new manifest file
window . location . reload ( true ) ;
} ;
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Watches
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
var SECTION _NAME = {
api : 'API Reference' ,
guide : 'Developer Guide' ,
misc : 'Miscellaneous' ,
tutorial : 'Tutorial' ,
2013-07-13 00:42:27 +00:00
cookbook : 'Examples' ,
error : 'Error Reference'
2012-04-29 05:45:28 +00:00
} ;
2012-07-06 09:53:40 +00:00
$scope . $watch ( function docsPathWatch ( ) { return $location . path ( ) ; } , function docsPathWatchAction ( path ) {
2012-04-29 05:45:28 +00:00
// ignore non-doc links which are used in examples
if ( DOCS _PATH . test ( path ) ) {
var parts = path . split ( '/' ) ,
sectionId = parts [ 1 ] ,
2013-07-13 00:42:27 +00:00
partialId = parts . slice ( 2 ) . join ( '/' ) ,
2012-04-29 05:45:28 +00:00
sectionName = SECTION _NAME [ sectionId ] || sectionId ,
page = sections . getPage ( sectionId , partialId ) ;
$scope . currentPage = sections . getPage ( sectionId , partialId ) ;
if ( ! $scope . currentPage ) {
$scope . partialTitle = 'Error: Page Not Found!' ;
}
updateSearch ( ) ;
// Update breadcrumbs
var breadcrumb = $scope . breadcrumb = [ ] ,
match ;
if ( partialId ) {
breadcrumb . push ( { name : sectionName , url : sectionId } ) ;
if ( partialId == 'angular.Module' ) {
breadcrumb . push ( { name : 'angular.Module' } ) ;
} else if ( match = partialId . match ( GLOBALS ) ) {
breadcrumb . push ( { name : partialId } ) ;
} else if ( match = partialId . match ( MODULE ) ) {
breadcrumb . push ( { name : match [ 1 ] } ) ;
} else if ( match = partialId . match ( MODULE _FILTER ) ) {
2012-06-12 06:49:24 +00:00
breadcrumb . push ( { name : match [ 1 ] , url : sectionId + '/' + match [ 1 ] } ) ;
2012-04-29 05:45:28 +00:00
breadcrumb . push ( { name : match [ 2 ] } ) ;
} else if ( match = partialId . match ( MODULE _DIRECTIVE ) ) {
2012-06-12 06:49:24 +00:00
breadcrumb . push ( { name : match [ 1 ] , url : sectionId + '/' + match [ 1 ] } ) ;
2012-04-29 05:45:28 +00:00
breadcrumb . push ( { name : match [ 2 ] } ) ;
} else if ( match = partialId . match ( MODULE _DIRECTIVE _INPUT ) ) {
2012-06-12 06:49:24 +00:00
breadcrumb . push ( { name : match [ 1 ] , url : sectionId + '/' + match [ 1 ] } ) ;
2012-04-29 05:45:28 +00:00
breadcrumb . push ( { name : 'input' , url : URL . input } ) ;
breadcrumb . push ( { name : match [ 2 ] } ) ;
} else if ( match = partialId . match ( MODULE _TYPE ) ) {
2012-06-12 06:49:24 +00:00
breadcrumb . push ( { name : match [ 1 ] , url : sectionId + '/' + match [ 1 ] } ) ;
2012-04-29 05:45:28 +00:00
breadcrumb . push ( { name : match [ 2 ] } ) ;
2012-06-12 06:49:24 +00:00
} else if ( match = partialId . match ( MODULE _SERVICE ) ) {
breadcrumb . push ( { name : match [ 1 ] , url : sectionId + '/' + match [ 1 ] } ) ;
breadcrumb . push ( { name : match [ 2 ] + ( match [ 3 ] || '' ) } ) ;
2012-04-29 05:45:28 +00:00
} else if ( match = partialId . match ( MODULE _MOCK ) ) {
breadcrumb . push ( { name : 'angular.mock.' + match [ 1 ] } ) ;
} else {
breadcrumb . push ( { name : page . shortName } ) ;
}
} else {
breadcrumb . push ( { name : sectionName } ) ;
}
}
} ) ;
$scope . $watch ( 'search' , updateSearch ) ;
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Initialize
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
$scope . versionNumber = angular . version . full ;
$scope . version = angular . version . full + " " + angular . version . codeName ;
$scope . subpage = false ;
$scope . offlineEnabled = ( $cookies [ OFFLINE _COOKIE _NAME ] == angular . version . full ) ;
$scope . futurePartialTitle = null ;
$scope . loading = 0 ;
$scope . URL = URL ;
$scope . $cookies = $cookies ;
$cookies . platformPreference = $cookies . platformPreference || 'gitUnix' ;
if ( ! $location . path ( ) || INDEX _PATH . test ( $location . path ( ) ) ) {
$location . path ( '/api' ) . replace ( ) ;
}
// bind escape to hash reset callback
2013-06-19 19:52:50 +00:00
angular . element ( window ) . on ( 'keydown' , function ( e ) {
2012-04-29 05:45:28 +00:00
if ( e . keyCode === 27 ) {
$scope . $apply ( function ( ) {
$scope . subpage = false ;
} ) ;
}
} ) ;
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Private methods
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
function updateSearch ( ) {
2013-07-13 00:42:27 +00:00
var moduleCache = { } ,
namespaceCache = { } ,
2012-04-29 05:45:28 +00:00
pages = sections [ $location . path ( ) . split ( '/' ) [ 1 ] ] ,
modules = $scope . modules = [ ] ,
2013-07-13 00:42:27 +00:00
namespaces = $scope . namespaces = [ ] ,
globalErrors = $scope . globalErrors = [ ] ,
2012-04-29 05:45:28 +00:00
otherPages = $scope . pages = [ ] ,
search = $scope . search ,
bestMatch = { page : null , rank : 0 } ;
angular . forEach ( pages , function ( page ) {
var match ,
id = page . id ;
if ( ! ( match = rank ( page , search ) ) ) return ;
if ( match . rank > bestMatch . rank ) {
bestMatch = match ;
}
2012-06-12 06:49:24 +00:00
if ( page . id == 'index' ) {
//skip
} else if ( page . section != 'api' ) {
2013-07-13 00:42:27 +00:00
if ( page . section === 'error' ) {
match = id . match ( ERROR ) ;
if ( match [ 1 ] !== undefined ) {
namespace ( match [ 1 ] . replace ( /:/g , '' ) ) . errors . push ( page ) ;
} else {
globalErrors . push ( page ) ;
}
}
2012-06-12 06:49:24 +00:00
} else if ( id == 'angular.Module' ) {
2012-04-29 05:45:28 +00:00
module ( 'ng' ) . types . push ( page ) ;
} else if ( match = id . match ( GLOBALS ) ) {
module ( 'ng' ) . globals . push ( page ) ;
} else if ( match = id . match ( MODULE ) ) {
module ( match [ 1 ] ) ;
} else if ( match = id . match ( MODULE _FILTER ) ) {
module ( match [ 1 ] ) . filters . push ( page ) ;
} else if ( match = id . match ( MODULE _DIRECTIVE ) ) {
module ( match [ 1 ] ) . directives . push ( page ) ;
} else if ( match = id . match ( MODULE _DIRECTIVE _INPUT ) ) {
module ( match [ 1 ] ) . directives . push ( page ) ;
2012-06-12 06:49:24 +00:00
} else if ( match = id . match ( MODULE _SERVICE ) ) {
module ( match [ 1 ] ) . service ( match [ 2 ] ) [ match [ 3 ] ? 'provider' : 'instance' ] = page ;
2012-04-29 05:45:28 +00:00
} else if ( match = id . match ( MODULE _TYPE ) ) {
module ( match [ 1 ] ) . types . push ( page ) ;
} else if ( match = id . match ( MODULE _MOCK ) ) {
module ( 'ngMock' ) . globals . push ( page ) ;
}
} ) ;
$scope . bestMatch = bestMatch ;
/*************/
function module ( name ) {
2013-07-13 00:42:27 +00:00
var module = moduleCache [ name ] ;
2012-04-29 05:45:28 +00:00
if ( ! module ) {
2013-07-13 00:42:27 +00:00
module = moduleCache [ name ] = {
2012-04-29 05:45:28 +00:00
name : name ,
2012-06-12 06:49:24 +00:00
url : 'api/' + name ,
2012-04-29 05:45:28 +00:00
globals : [ ] ,
directives : [ ] ,
services : [ ] ,
service : function ( name ) {
2013-07-13 00:42:27 +00:00
var service = moduleCache [ this . name + ':' + name ] ;
2012-04-29 05:45:28 +00:00
if ( ! service ) {
service = { name : name } ;
2013-07-13 00:42:27 +00:00
moduleCache [ this . name + ':' + name ] = service ;
2012-04-29 05:45:28 +00:00
this . services . push ( service ) ;
}
return service ;
} ,
types : [ ] ,
filters : [ ]
2013-05-21 21:52:38 +00:00
} ;
2012-04-29 05:45:28 +00:00
modules . push ( module ) ;
}
return module ;
}
2013-07-13 00:42:27 +00:00
function namespace ( name ) {
var namespace = namespaceCache [ name ] ;
if ( ! namespace ) {
namespace = namespaceCache [ name ] = {
name : name ,
url : 'error/' + name ,
errors : [ ]
} ;
namespaces . push ( namespace ) ;
}
return namespace ;
}
2012-04-29 05:45:28 +00:00
function rank ( page , terms ) {
var ranking = { page : page , rank : 0 } ,
keywords = page . keywords ,
title = page . shortName . toLowerCase ( ) ;
terms && angular . forEach ( terms . toLowerCase ( ) . split ( ' ' ) , function ( term ) {
var index ;
if ( ranking ) {
if ( keywords . indexOf ( term ) == - 1 ) {
ranking = null ;
} else {
ranking . rank ++ ; // one point for each term found
if ( ( index = title . indexOf ( term ) ) != - 1 ) {
ranking . rank += 20 - index ; // ten points if you match title
}
}
}
} ) ;
return ranking ;
}
}
function loadDisqus ( currentPageId ) {
// http://docs.disqus.com/help/2/
window . disqus _shortname = 'angularjs-next' ;
window . disqus _identifier = currentPageId ;
window . disqus _url = 'http://docs.angularjs.org' + currentPageId ;
if ( $location . host ( ) == 'localhost' ) {
return ; // don't display disqus on localhost, comment this out if needed
//window.disqus_developer = 1;
}
// http://docs.disqus.com/developers/universal/
( function ( ) {
var dsq = document . createElement ( 'script' ) ; dsq . type = 'text/javascript' ; dsq . async = true ;
dsq . src = 'http://angularjs.disqus.com/embed.js' ;
( document . getElementsByTagName ( 'head' ) [ 0 ] ||
document . getElementsByTagName ( 'body' ) [ 0 ] ) . appendChild ( dsq ) ;
} ) ( ) ;
angular . element ( document . getElementById ( 'disqus_thread' ) ) . html ( '' ) ;
}
2013-05-21 21:52:38 +00:00
} ;
2012-04-29 05:45:28 +00:00
2013-06-14 02:37:13 +00:00
angular . module ( 'docsApp' , [ 'ngResource' , 'ngRoute' , 'ngCookies' , 'ngSanitize' , 'bootstrap' , 'bootstrapPrettify' , 'docsData' ] ) .
2012-04-29 05:45:28 +00:00
config ( function ( $locationProvider ) {
$locationProvider . html5Mode ( true ) . hashPrefix ( '!' ) ;
} ) .
factory ( docsApp . serviceFactory ) .
directive ( docsApp . directive ) .
controller ( docsApp . controller ) ;