2011-10-07 18:27:49 +00:00
( function ( ) {
2011-01-19 23:42:11 +00:00
2010-11-10 23:31:15 +00:00
var angularJsUrl ;
var scripts = document . getElementsByTagName ( "script" ) ;
2011-02-22 22:48:53 +00:00
var angularJsRegex = /^(|.*\/)angular(-.*?)?(\.min)?.js(\?[^#]*)?(#(.*))?$/ ;
2010-11-10 23:31:15 +00:00
for ( var j = 0 ; j < scripts . length ; j ++ ) {
var src = scripts [ j ] . src ;
2011-02-04 22:09:17 +00:00
if ( src && src . match ( angularJsRegex ) ) {
2011-01-18 22:15:53 +00:00
angularJsUrl = src . replace ( 'docs.angularjs.org' , 'code.angularjs.org' ) ;
2011-02-04 22:09:17 +00:00
continue ;
2010-11-10 23:31:15 +00:00
}
}
2011-01-19 23:42:11 +00:00
2010-11-06 04:12:37 +00:00
var HTML _TEMPLATE =
2012-01-07 02:10:47 +00:00
'<!doctype html>\n' +
'<html xmlns:ng="http://angularjs.org" ng:app_MODULE_>\n' +
' <script src="' + angularJsUrl + '"></script>\n' +
'_SCRIPT_SOURCE_' +
' <body>\n' +
'_HTML_SOURCE_\n' +
' </body>\n' +
'</html>' ;
2010-11-06 04:12:37 +00:00
2011-11-14 23:58:40 +00:00
angular . widget ( 'doc:example' , [ '$injector' , '$element' , function ( $injector , element ) {
2010-11-06 04:12:37 +00:00
this . descend ( true ) ; //compile the example code
2012-01-07 02:10:47 +00:00
var module = element . attr ( 'module' ) || '' ;
2010-11-06 04:12:37 +00:00
2011-07-15 01:28:15 +00:00
//jQuery find() methods in this widget contain primitive selectors on purpose so that we can use
//jqlite instead. jqlite's find() method currently supports onlt getElementsByTagName!
var example = element . find ( 'pre' ) . eq ( 0 ) , //doc-source
2012-01-07 02:10:47 +00:00
scriptSrc = '' ,
htmlSrc = example . text ( ) . replace ( /<script[^\>]*>([\s\S]+)<\/script>/im , function ( _ , script ) {
scriptSrc = script ;
return '' ;
} ) ,
2011-11-12 00:50:19 +00:00
showSource = example . attr ( 'source' ) !== 'false' ,
2011-08-19 19:06:59 +00:00
jsfiddle = example . attr ( 'jsfiddle' ) || true ,
2011-07-15 01:28:15 +00:00
scenario = element . find ( 'pre' ) . eq ( 1 ) ; //doc-scenario
2010-11-06 04:12:37 +00:00
2011-02-01 18:01:02 +00:00
var tabHtml =
2011-11-12 00:50:19 +00:00
'<ul class="doc-example">' ;
// show source tab, if not disabled
if ( showSource ) {
tabHtml +=
2011-02-01 18:01:02 +00:00
'<li class="doc-example-heading"><h3>Source</h3></li>' +
'<li class="doc-example-source" ng:non-bindable>' +
2011-08-11 03:53:56 +00:00
jsFiddleButton ( jsfiddle ) + // may or may not have value
2012-01-07 02:10:47 +00:00
'<pre class="brush: js; html-script: true; toolbar: false;"></pre></li>' ;
2011-11-12 00:50:19 +00:00
}
// show live preview tab
tabHtml +=
2011-02-01 18:01:02 +00:00
'<li class="doc-example-heading"><h3>Live Preview</h3></li>' +
2012-01-07 02:10:47 +00:00
'<li class="doc-example-live">' + htmlSrc + '</li>' ;
2011-11-12 00:50:19 +00:00
// show scenario tab, if present
2011-02-01 18:01:02 +00:00
if ( scenario . text ( ) ) {
tabHtml +=
'<li class="doc-example-heading"><h3>Scenario Test</h3></li>' +
'<li class="doc-example-scenario"><pre class="brush: js">' + scenario . text ( ) + '</pre></li>' ;
}
tabHtml +=
'</ul>' ;
var tabs = angular . element ( tabHtml ) ;
2011-01-19 23:42:11 +00:00
2011-11-14 23:58:40 +00:00
tabs . find ( 'li' ) . eq ( 1 ) . find ( 'pre' ) . text (
HTML _TEMPLATE .
2012-01-07 02:10:47 +00:00
replace ( '_SCRIPT_SOURCE_' , scriptSrc ? ' <script>\n' + indent ( scriptSrc , ' ' ) + '\n </script>\n' : '' ) .
replace ( '_HTML_SOURCE_' , indent ( htmlSrc , ' ' ) ) .
replace ( '_MODULE_' , module ? '="' + module + '"' : '' ) ) ;
2010-11-06 04:12:37 +00:00
element . html ( '' ) ;
element . append ( tabs ) ;
try {
2011-09-06 20:59:27 +00:00
if ( window . execScript ) { // IE
2012-01-07 02:10:47 +00:00
window . execScript ( scriptSrc || '"stupid IE!"' ) ; // IE complains when evaling empty string
2011-09-06 20:59:27 +00:00
} else {
2012-01-07 02:10:47 +00:00
window . eval ( scriptSrc ) ;
2011-09-06 20:59:27 +00:00
}
2010-11-06 04:12:37 +00:00
} catch ( e ) {
alert ( e ) ;
}
2011-08-11 03:53:56 +00:00
2011-11-14 23:58:40 +00:00
if ( module ) {
$injector . invoke ( null , angular . module [ module ] ) ;
}
2011-08-11 03:53:56 +00:00
function jsFiddleButton ( jsfiddle ) {
2012-01-07 02:10:47 +00:00
var fixJsFiddleIssue132 = true ;
2011-08-11 03:53:56 +00:00
if ( jsfiddle !== 'false' ) {
2011-11-12 01:15:22 +00:00
if ( jsfiddle === true ) {
2011-08-11 03:53:56 +00:00
//dynamically generate a fiddle
2012-01-07 02:10:47 +00:00
var fiddleUrl = 'http://jsfiddle.net/api/post/library/pure/' ;
2011-08-11 03:53:56 +00:00
2012-01-07 02:10:47 +00:00
function jsFiddleEscape ( text , prefix ) {
return indent ( text . replace ( /<\/textarea>/gi , '</textarea>' ) , prefix ) ;
}
2011-08-11 03:53:56 +00:00
return '<form class="jsfiddle" method="post" action="' + fiddleUrl + '" target="_blank">' +
2012-01-07 02:10:47 +00:00
( fixJsFiddleIssue132 ? '' : '<textarea name="resources">' + angularJsUrl + '</textarea>' ) +
'<textarea name="css">\n' +
( fixJsFiddleIssue132 ? '</style>\n<script src="' + angularJsUrl + '"></script>\n<style>\n' : '' ) +
2011-09-08 20:56:29 +00:00
'.ng-invalid { border: 1px solid red; } \n' +
2011-08-11 03:53:56 +00:00
'body { font-family: Arial,Helvetica,sans-serif; }\n' +
'body, td, th { font-size: 14px; margin: 0; }\n' +
'table { border-collapse: separate; border-spacing: 2px; display: table; margin-bottom: 0; margin-top: 0; -moz-box-sizing: border-box; text-indent: 0; }\n' +
'a:link, a:visited, a:hover { color: #5D6DB6; text-decoration: none; }\n' +
2011-09-08 20:56:29 +00:00
'.error { color: red; }\n' +
2011-08-11 03:53:56 +00:00
'</textarea>' +
2011-10-14 15:31:00 +00:00
'<input type="text" name="title" value="AngularJS Live Example">' +
'<textarea name="html">' +
2012-01-07 02:10:47 +00:00
'<div ng:app' + ( module ? '="' + module + '"' : '' ) + '>\n' + jsFiddleEscape ( htmlSrc , ' ' ) + '\n</div>' +
2011-08-11 03:53:56 +00:00
'</textarea>' +
2012-01-07 02:10:47 +00:00
'<textarea name="js">' + jsFiddleEscape ( scriptSrc ) + '</textarea>' +
2011-08-11 03:53:56 +00:00
'<button>edit at jsFiddle</button>' +
'</form>' ;
} else {
//use existing fiddle
fiddleUrl = "http://jsfiddle.net" + jsfiddle ;
return '<form class="jsfiddle" method="get" action="' + fiddleUrl + '" target="_blank">' +
'<button>edit at jsFiddle</button>' +
'</form>' ;
}
}
return '' ;
}
2011-11-14 23:58:40 +00:00
} ] ) ;
2011-01-19 23:42:11 +00:00
2012-01-07 02:10:47 +00:00
function indent ( text , prefix ) {
prefix = prefix || '' ;
2011-01-31 19:55:44 +00:00
if ( ! text ) return text ;
2011-04-07 19:34:34 +00:00
var lines = text . split ( /\r?\n/ ) ;
2011-11-12 01:15:22 +00:00
var i ;
2011-01-26 05:55:11 +00:00
// remove any leading blank lines
2010-11-10 23:31:15 +00:00
while ( lines [ 0 ] . match ( /^\s*$/ ) ) lines . shift ( ) ;
2011-01-26 05:55:11 +00:00
// remove any trailing blank lines
2010-11-10 23:31:15 +00:00
while ( lines [ lines . length - 1 ] . match ( /^\s*$/ ) ) lines . pop ( ) ;
2011-01-26 05:55:11 +00:00
var minIndent = 999 ;
2011-11-12 01:15:22 +00:00
for ( i = 0 ; i < lines . length ; i ++ ) {
2011-01-26 05:55:11 +00:00
var line = lines [ 0 ] ;
var indent = line . match ( /^\s*/ ) [ 0 ] ;
if ( indent !== line && indent . length < minIndent ) {
minIndent = indent . length ;
}
}
2011-11-12 01:15:22 +00:00
for ( i = 0 ; i < lines . length ; i ++ ) {
2012-01-07 02:10:47 +00:00
lines [ i ] = prefix + lines [ i ] . substring ( minIndent ) ;
2010-11-10 23:31:15 +00:00
}
2012-01-07 02:10:47 +00:00
return lines . join ( '\n' ) ;
2011-11-12 01:15:22 +00:00
}
2011-01-19 23:42:11 +00:00
2011-05-23 22:49:33 +00:00
var HTML _TPL =
2011-07-29 18:43:12 +00:00
'<p><a ng:init="showInstructions = {show}" ng:show="!showInstructions" ng:click="showInstructions = true" href>Workspace Reset Instructions ➤</a></p>' +
2011-05-23 22:49:33 +00:00
'<div ng:controller="TutorialInstructionsCtrl" ng:show="showInstructions">' +
'<div class="tabs-nav">' +
'<ul>' +
'</ul>' +
'</div>' +
'<div class="tabs-content"><div class="tabs-content-inner">' +
'</div></div>' +
'</div>' ;
var HTML _NAV = '<li ng:class="currentCls(\'{id}\')"><a ng:click="select(\'{id}\')" href>{title}</a></li>' ;
var HTML _CONTENT = '<div ng:show="selected==\'{id}\'">{content}</div>' ;
var DEFAULT _NAV =
'<li ng:class="currentCls(\'git-mac\')"><a ng:click="select(\'git-mac\')" href>Git on Mac/Linux</a></li>' +
'<li ng:class="currentCls(\'git-win\')"><a ng:click="select(\'git-win\')" href>Git on Windows</a></li>' +
'<li ng:class="currentCls(\'ss-mac\')"><a ng:click="select(\'ss-mac\')" href>Snapshots on Mac/Linux</a></li>' +
'<li ng:class="currentCls(\'ss-win\')"><a ng:click="select(\'ss-win\')" href>Snapshots on Windows</a></li>' ;
var DEFAULT _CONTENT =
'<div ng:show="selected==\'git-mac\'">' +
'<ol>' +
'<li><p>Reset the workspace to step {step}.</p>' +
'<pre><code> git checkout -f step-{step}</code></pre></li>' +
2011-06-06 15:52:02 +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>' +
2011-05-23 22:49:33 +00:00
'</ol>' +
'</div>' +
'<div ng:show="selected==\'git-win\'">' +
'<ol>' +
'<li><p>Reset the workspace to step {step}.</p>' +
'<pre><code> git checkout -f step-{step}</code></pre></li>' +
2011-06-10 16:30:55 +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>' +
2011-05-23 22:49:33 +00:00
'</ol>' +
'</div>' +
'<div ng:show="selected==\'ss-mac\'">' +
'<ol>' +
'<li><p>Reset the workspace to step {step}.</p>' +
'<pre><code> ./goto_step.sh {step}</code></pre></li>' +
2011-06-10 16:30:55 +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>' +
2011-05-23 22:49:33 +00:00
'</ol>' +
'</div>' +
'<div ng:show="selected==\'ss-win\'">' +
'<ol>' +
'<li><p>Reset the workspace to step {step}.</p>' +
'<pre><code> ./goto_step.bat {step}</code></pre></li>' +
2011-06-06 15:52:02 +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>' +
2011-05-23 22:49:33 +00:00
'</ol>' +
'</div>' ;
angular . widget ( 'doc:tutorial-instructions' , function ( element ) {
this . descend ( true ) ;
var tabs = angular . element ( HTML _TPL . replace ( '{show}' , element . attr ( 'show' ) || 'false' ) ) ,
2011-07-26 21:16:39 +00:00
nav = tabs . find ( 'ul' ) ,
// use simple selectors because jqLite find() supports getElementsByTagName only
content = tabs . find ( 'div' ) . find ( 'div' ) ,
2011-05-23 22:49:33 +00:00
children = element . children ( ) ;
if ( children . length ) {
// load custom content
angular . forEach ( element . children ( ) , function ( elm ) {
2011-11-12 01:15:22 +00:00
elm = angular . element ( elm ) ;
var id = elm . attr ( 'id' ) ;
2011-05-23 22:49:33 +00:00
nav . append ( HTML _NAV . replace ( '{title}' , elm . attr ( 'title' ) ) . replace ( /\{id\}/g , id ) ) ;
content . append ( HTML _CONTENT . replace ( '{id}' , id ) . replace ( '{content}' , elm . html ( ) ) ) ;
} ) ;
} else {
// default
nav . append ( DEFAULT _NAV ) ;
content . append ( DEFAULT _CONTENT . replace ( /\{step\}/g , element . attr ( 'step' ) ) ) ;
}
element . html ( '' ) ;
element . append ( tabs ) ;
} ) ;
2011-06-06 15:52:02 +00:00
2011-06-06 21:03:04 +00:00
angular . directive ( 'doc:tutorial-nav' , function ( step ) {
2011-06-06 15:52:02 +00:00
return function ( element ) {
var prevStep , codeDiff , nextStep ,
content ;
step = parseInt ( step , 10 ) ;
if ( step === 0 ) {
prevStep = '' ;
nextStep = 'step_01' ;
codeDiff = 'step-0~7...step-0' ;
} else if ( step === 11 ) {
prevStep = 'step_10' ;
nextStep = 'the_end' ;
codeDiff = 'step-10...step-11' ;
} else {
2011-06-06 21:03:04 +00:00
prevStep = 'step_' + pad ( step - 1 ) ;
2011-06-06 15:52:02 +00:00
nextStep = 'step_' + pad ( step + 1 ) ;
codeDiff = 'step-' + step + '...step-' + step ;
}
content = angular . element (
2011-06-07 00:21:45 +00:00
'<li><a href="#!/tutorial/' + prevStep + '">Previous</a></li>' +
2011-06-06 15:52:02 +00:00
'<li><a href="http://angular.github.com/angular-phonecat/step-' + step + '/app">Live Demo</a></li>' +
'<li><a href="https://github.com/angular/angular-phonecat/compare/' + codeDiff + '">Code Diff</a></li>' +
2011-06-07 00:21:45 +00:00
'<li><a href="#!/tutorial/' + nextStep + '">Next</a></li>'
2011-06-06 15:52:02 +00:00
) ;
element . attr ( 'id' , 'tutorial-nav' ) ;
element . append ( content ) ;
2011-06-06 21:03:04 +00:00
} ;
2011-06-06 15:52:02 +00:00
function pad ( step ) {
return ( step < 10 ) ? ( '0' + step ) : step ;
}
} ) ;
2011-01-19 23:42:11 +00:00
} ) ( ) ;