mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-05-28 15:28:15 +00:00
Add doc:tutorial-instructions widget
This commit is contained in:
parent
d05e839920
commit
2da07127e4
5 changed files with 197 additions and 8 deletions
|
|
@ -165,11 +165,38 @@ describe('ngdoc', function(){
|
||||||
'<p>asdf x</p>');
|
'<p>asdf x</p>');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should ignore doc widgets', function() {
|
||||||
|
expect(new Doc().markdown('text<doc:example>do not touch</doc:example>')).
|
||||||
|
toEqual('<p>text</p><doc:example>do not touch</doc:example>');
|
||||||
|
|
||||||
|
expect(new Doc().markdown('text<doc:tutorial-instructions>do not touch</doc:tutorial-instructions>')).
|
||||||
|
toEqual('<p>text</p><doc:tutorial-instructions>do not touch</doc:tutorial-instructions>');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should ignore doc widgets with params', function() {
|
||||||
|
expect(new Doc().markdown('text<doc:tutorial-instructions id="10" show="true">do not touch</doc:tutorial-instructions>')).
|
||||||
|
toEqual('<p>text</p><doc:tutorial-instructions id="10" show="true">do not touch</doc:tutorial-instructions>');
|
||||||
|
});
|
||||||
|
|
||||||
it('should replace text between two <pre></pre> tags', function() {
|
it('should replace text between two <pre></pre> tags', function() {
|
||||||
expect(new Doc().markdown('<pre>x</pre># One<pre>b</pre>')).
|
expect(new Doc().markdown('<pre>x</pre># One<pre>b</pre>')).
|
||||||
toMatch('</div><h1>One</h1><div');
|
toMatch('</div><h1>One</h1><div');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should ignore nested doc widgets', function() {
|
||||||
|
expect(new Doc().markdown(
|
||||||
|
'before<doc:tutorial-instructions>\n' +
|
||||||
|
'<doc:tutorial-instruction id="git-mac" name="Git on Mac/Linux">' +
|
||||||
|
'\ngit bla bla\n</doc:tutorial-instruction>\n' +
|
||||||
|
'</doc:tutorial-instructions>')).toEqual(
|
||||||
|
|
||||||
|
'<p>before</p><doc:tutorial-instructions>\n' +
|
||||||
|
'<doc:tutorial-instruction id="git-mac" name="Git on Mac/Linux">\n' +
|
||||||
|
'git bla bla\n' +
|
||||||
|
'</doc:tutorial-instruction>\n' +
|
||||||
|
'</doc:tutorial-instructions>');
|
||||||
|
});
|
||||||
|
|
||||||
it('should unindent text before processing based on the second line', function() {
|
it('should unindent text before processing based on the second line', function() {
|
||||||
expect(new Doc().markdown('first line\n' +
|
expect(new Doc().markdown('first line\n' +
|
||||||
' second line\n\n' +
|
' second line\n\n' +
|
||||||
|
|
|
||||||
|
|
@ -78,16 +78,27 @@ Doc.prototype = {
|
||||||
},
|
},
|
||||||
|
|
||||||
markdown: function (text) {
|
markdown: function (text) {
|
||||||
var self = this;
|
|
||||||
var IS_URL = /^(https?:\/\/|ftps?:\/\/|mailto:|\.|\/)/;
|
|
||||||
var IS_ANGULAR = /^angular\./;
|
|
||||||
if (!text) return text;
|
if (!text) return text;
|
||||||
|
|
||||||
text = trim(text);
|
var self = this,
|
||||||
|
IS_URL = /^(https?:\/\/|ftps?:\/\/|mailto:|\.|\/)/,
|
||||||
|
IS_ANGULAR = /^angular\./,
|
||||||
|
parts = trim(text).split(/(<pre>[\s\S]*?<\/pre>|<doc:(\S*).*?>[\s\S]*?<\/doc:\2>)/);
|
||||||
|
|
||||||
var parts = text.split(/(<pre>[\s\S]*?<\/pre>|<doc:example>[\s\S]*?<\/doc:example>)/);
|
parts.forEach(function(text, i) {
|
||||||
|
|
||||||
|
function isDocWidget(name) {
|
||||||
|
if ((i + 1) % 3 != 2) return false;
|
||||||
|
if (name) return parts[i+1] == name;
|
||||||
|
return !!parts[i+1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore each third item which is doc widget tag
|
||||||
|
if (!((i + 1) % 3)) {
|
||||||
|
parts[i] = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
parts.forEach(function(text, i){
|
|
||||||
if (text.match(/^<pre>/)) {
|
if (text.match(/^<pre>/)) {
|
||||||
text = text.replace(/^<pre>([\s\S]*)<\/pre>/mi, function(_, content){
|
text = text.replace(/^<pre>([\s\S]*)<\/pre>/mi, function(_, content){
|
||||||
var clazz = 'brush: js;';
|
var clazz = 'brush: js;';
|
||||||
|
|
@ -99,7 +110,7 @@ Doc.prototype = {
|
||||||
content.replace(/</g, '<').replace(/>/g, '>') +
|
content.replace(/</g, '<').replace(/>/g, '>') +
|
||||||
'</pre></div>';
|
'</pre></div>';
|
||||||
});
|
});
|
||||||
} else if (text.match(/^<doc:example>/)) {
|
} else if (isDocWidget('example')) {
|
||||||
text = text.replace(/(<doc:source>)([\s\S]*)(<\/doc:source>)/mi,
|
text = text.replace(/(<doc:source>)([\s\S]*)(<\/doc:source>)/mi,
|
||||||
function(_, before, content, after){
|
function(_, before, content, after){
|
||||||
return '<pre class="doc-source">' + htmlEscape(content) + '</pre>';
|
return '<pre class="doc-source">' + htmlEscape(content) + '</pre>';
|
||||||
|
|
@ -109,7 +120,7 @@ Doc.prototype = {
|
||||||
self.scenarios.push(content);
|
self.scenarios.push(content);
|
||||||
return '<pre class="doc-scenario">' + htmlEscape(content) + '</pre>';
|
return '<pre class="doc-scenario">' + htmlEscape(content) + '</pre>';
|
||||||
});
|
});
|
||||||
} else {
|
} else if (!isDocWidget()) {
|
||||||
text = text.replace(/<angular\/>/gm, '<tt><angular/></tt>');
|
text = text.replace(/<angular\/>/gm, '<tt><angular/></tt>');
|
||||||
text = text.replace(/{@link\s+([^\s}]+)\s*([^}]*?)\s*}/g,
|
text = text.replace(/{@link\s+([^\s}]+)\s*([^}]*?)\s*}/g,
|
||||||
function(_all, url, title){
|
function(_all, url, title){
|
||||||
|
|
|
||||||
|
|
@ -33,3 +33,54 @@ li.doc-example-live {
|
||||||
div.syntaxhighlighter {
|
div.syntaxhighlighter {
|
||||||
padding-bottom: 1px !important; /* fix to remove unnecessary scrollbars http://is.gd/gSMgC */
|
padding-bottom: 1px !important; /* fix to remove unnecessary scrollbars http://is.gd/gSMgC */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TABS - tutorial environment navigation */
|
||||||
|
|
||||||
|
div.tabs-nav {
|
||||||
|
height: 25px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.tabs-nav ul li {
|
||||||
|
list-style: none;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 5px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.tabs-nav ul li.current a {
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.tabs-nav ul li.current {
|
||||||
|
background: #7989D6;
|
||||||
|
-moz-box-shadow: 4px 4px 6px #48577D;
|
||||||
|
-moz-border-radius-topright: 8px;
|
||||||
|
-moz-border-radius-topleft: 8px;
|
||||||
|
box-shadow: 4px 4px 6px #48577D;
|
||||||
|
border-radius-topright: 8px;
|
||||||
|
border-radius-topleft: 8px;
|
||||||
|
-webkit-box-shadow: 4px 4px 6px #48577D;
|
||||||
|
-webkit-border-top-right-radius: 8px;
|
||||||
|
-webkit-border-top-left-radius: 8px;
|
||||||
|
border-top-right-radius: 8px;
|
||||||
|
border-top-left-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.tabs-content {
|
||||||
|
padding: 4px;
|
||||||
|
position: relative;
|
||||||
|
background: #7989D6;
|
||||||
|
-moz-border-radius: 8px;
|
||||||
|
border-radius: 8px;
|
||||||
|
-webkit-border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.tabs-content-inner {
|
||||||
|
margin: 1px;
|
||||||
|
padding: 10px;
|
||||||
|
background: white;
|
||||||
|
border-radius: 6px;
|
||||||
|
-moz-border-radius: 6px;
|
||||||
|
-webkit-border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,4 +85,86 @@
|
||||||
return {html: lines.join('\n'), hilite: lineNo.join(',') };
|
return {html: lines.join('\n'), hilite: lineNo.join(',') };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var HTML_TPL =
|
||||||
|
'<a ng:init="showInstructions = {show}" ng:show="!showInstructions" ng:click="showInstructions = true" href>Show Instructions</a>' +
|
||||||
|
'<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>' +
|
||||||
|
'<li><p>Refresh your browser or check the app out on <a href="http://angular.github.com/angular-phonecat/step-{step}/app">anglar\'s server</a>.</p></li>' +
|
||||||
|
'</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>' +
|
||||||
|
'<li><p>Refresh your browser or check the app out on <a href="http://angular.github.com/angular-phonecat/step-{step}/app">anglar\'s server</a>.</p></li>' +
|
||||||
|
'</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>' +
|
||||||
|
'<li><p>Refresh your browser or check the app out on <a href="http://angular.github.com/angular-phonecat/step-{step}/app">anglar\'s server</a>.</p></li>' +
|
||||||
|
'</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>' +
|
||||||
|
'<li><p>Refresh your browser or check the app out on <a href="http://angular.github.com/angular-phonecat/step-{step}/app">anglar\'s server</a>.</p></li>' +
|
||||||
|
'</ol>' +
|
||||||
|
'</div>';
|
||||||
|
|
||||||
|
angular.widget('doc:tutorial-instructions', function(element) {
|
||||||
|
element.hide();
|
||||||
|
this.descend(true);
|
||||||
|
|
||||||
|
var tabs = angular.element(HTML_TPL.replace('{show}', element.attr('show') || 'false')),
|
||||||
|
nav = tabs.find('.tabs-nav ul'),
|
||||||
|
content = tabs.find('.tabs-content-inner'),
|
||||||
|
children = element.children();
|
||||||
|
|
||||||
|
if (children.length) {
|
||||||
|
// load custom content
|
||||||
|
angular.forEach(element.children(), function(elm) {
|
||||||
|
var elm = angular.element(elm),
|
||||||
|
id = elm.attr('id');
|
||||||
|
|
||||||
|
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);
|
||||||
|
element.show();
|
||||||
|
});
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
|
|
@ -65,3 +65,21 @@ angular.widget('code', function(element){
|
||||||
|
|
||||||
SyntaxHighlighter['defaults'].toolbar = false;
|
SyntaxHighlighter['defaults'].toolbar = false;
|
||||||
SyntaxHighlighter['defaults'].gutter = false;
|
SyntaxHighlighter['defaults'].gutter = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for tutorial instructions
|
||||||
|
* @param $cookieStore
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function TutorialInstructionsCtrl($cookieStore) {
|
||||||
|
this.selected = $cookieStore.get('selEnv') || 'git-mac';
|
||||||
|
|
||||||
|
this.currentCls = function(id, cls) {
|
||||||
|
return this.selected == id ? cls || 'current' : '';
|
||||||
|
};
|
||||||
|
|
||||||
|
this.select = function(id) {
|
||||||
|
this.selected = id;
|
||||||
|
$cookieStore.put('selEnv', id);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue