mirror of
https://github.com/zhigang1992/angular.js.git
synced 2026-01-12 22:45:52 +08:00
feat(ngdocs): support popover, foldouts and foldover annotations
This commit is contained in:
committed by
Misko Hevery
parent
07ef1667db
commit
ef22968810
186
docs/component-spec/annotationsSpec.js
Normal file
186
docs/component-spec/annotationsSpec.js
Normal file
@@ -0,0 +1,186 @@
|
||||
describe('Docs Annotations', function() {
|
||||
|
||||
beforeEach(module('docsApp'));
|
||||
|
||||
var body;
|
||||
beforeEach(function() {
|
||||
body = angular.element(document.body);
|
||||
body.html('');
|
||||
});
|
||||
|
||||
describe('popover directive', function() {
|
||||
|
||||
var $scope, element;
|
||||
beforeEach(inject(function($rootScope, $compile) {
|
||||
$scope = $rootScope.$new();
|
||||
element = angular.element(
|
||||
'<div style="margin:200px;" data-title="title_text" data-content="content_text" popover></div>'
|
||||
);
|
||||
element.attr('id','idx');
|
||||
body.append(element);
|
||||
$compile(element)($scope);
|
||||
$scope.$apply();
|
||||
}));
|
||||
|
||||
it('should be hidden by default', inject(function(popoverElement) {
|
||||
expect(popoverElement.visible()).toBe(false);
|
||||
}));
|
||||
|
||||
it('should capture the click event and set the title and content and position the tip', inject(function(popoverElement) {
|
||||
element.triggerHandler('click');
|
||||
expect(popoverElement.isSituatedAt(element)).toBe(true);
|
||||
expect(popoverElement.visible()).toBe(true);
|
||||
expect(popoverElement.title()).toBe('title_text');
|
||||
expect(popoverElement.content()).toContain('content_text');
|
||||
expect(popoverElement.besideElement.attr('id')).toBe('idx');
|
||||
}));
|
||||
|
||||
it('should hide and clear the title and content if the same element is clicked again', inject(function(popoverElement) {
|
||||
//show the element
|
||||
element.triggerHandler('click');
|
||||
expect(popoverElement.isSituatedAt(element)).toBe(true);
|
||||
|
||||
//hide the element
|
||||
element.triggerHandler('click');
|
||||
expect(popoverElement.isSituatedAt(element)).toBe(false);
|
||||
expect(popoverElement.visible()).toBe(false);
|
||||
expect(popoverElement.title()).toBe('');
|
||||
expect(popoverElement.content()).toBe('');
|
||||
}));
|
||||
|
||||
it('should parse markdown content', inject(function(popoverElement, $compile) {
|
||||
element = angular.element(
|
||||
'<div style="margin:200px;" data-title="#title_text" data-content="#heading" popover></div>'
|
||||
);
|
||||
body.append(element);
|
||||
$compile(element)($scope);
|
||||
$scope.$apply();
|
||||
element.triggerHandler('click');
|
||||
expect(popoverElement.title()).toBe('#title_text');
|
||||
expect(popoverElement.content()).toBe('<h1 id="heading">heading</h1>');
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('foldout directive', function() {
|
||||
|
||||
var $scope, parent, element, url, window;
|
||||
beforeEach(function() {
|
||||
module(function($provide, $animationProvider) {
|
||||
$provide.value('$window', window = angular.mock.createMockWindow());
|
||||
$animationProvider.register('foldout-enter', function($window) {
|
||||
return {
|
||||
start : function(element, done) {
|
||||
$window.setTimeout(done, 1000);
|
||||
}
|
||||
}
|
||||
});
|
||||
$animationProvider.register('foldout-hide', function($window) {
|
||||
return {
|
||||
start : function(element, done) {
|
||||
$window.setTimeout(done, 500);
|
||||
}
|
||||
}
|
||||
});
|
||||
$animationProvider.register('foldout-show', function($window) {
|
||||
return {
|
||||
start : function(element, done) {
|
||||
$window.setTimeout(done, 200);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
inject(function($rootScope, $compile, $templateCache) {
|
||||
url = '/page.html';
|
||||
$scope = $rootScope.$new();
|
||||
parent = angular.element('<div class="parent"></div>');
|
||||
element = angular.element('<div data-url="' + url + '" foldout></div>');
|
||||
body.append(parent);
|
||||
parent.append(element);
|
||||
$compile(parent)($scope);
|
||||
$scope.$apply();
|
||||
});
|
||||
});
|
||||
|
||||
it('should inform that it is loading', inject(function($httpBackend) {
|
||||
$httpBackend.expect('GET', url).respond('hello');
|
||||
element.triggerHandler('click');
|
||||
|
||||
var kids = body.children();
|
||||
var foldout = angular.element(kids[kids.length-1]);
|
||||
expect(foldout.html()).toContain('loading');
|
||||
}));
|
||||
|
||||
it('should download a foldout HTML page and animate the contents', inject(function($httpBackend) {
|
||||
$httpBackend.expect('GET', url).respond('hello');
|
||||
|
||||
element.triggerHandler('click');
|
||||
$httpBackend.flush();
|
||||
|
||||
window.setTimeout.expect(1).process();
|
||||
window.setTimeout.expect(1000).process();
|
||||
|
||||
var kids = body.children();
|
||||
var foldout = angular.element(kids[kids.length-1]);
|
||||
expect(foldout.text()).toContain('hello');
|
||||
}));
|
||||
|
||||
it('should hide then show when clicked again', inject(function($httpBackend) {
|
||||
$httpBackend.expect('GET', url).respond('hello');
|
||||
|
||||
//enter
|
||||
element.triggerHandler('click');
|
||||
$httpBackend.flush();
|
||||
window.setTimeout.expect(1).process();
|
||||
window.setTimeout.expect(1000).process();
|
||||
|
||||
//hide
|
||||
element.triggerHandler('click');
|
||||
window.setTimeout.expect(1).process();
|
||||
window.setTimeout.expect(500).process();
|
||||
|
||||
//show
|
||||
element.triggerHandler('click');
|
||||
window.setTimeout.expect(1).process();
|
||||
window.setTimeout.expect(200).process();
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
describe('DocsController fold', function() {
|
||||
|
||||
var window, $scope, ctrl;
|
||||
beforeEach(function() {
|
||||
module(function($provide, $animationProvider) {
|
||||
$provide.value('$window', window = angular.mock.createMockWindow());
|
||||
});
|
||||
inject(function($rootScope, $controller, $location, $cookies, sections) {
|
||||
$scope = $rootScope.$new();
|
||||
ctrl = $controller('DocsController',{
|
||||
$scope : $scope,
|
||||
$location : $location,
|
||||
$window : window,
|
||||
$cookies : $cookies,
|
||||
sections : sections
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should download and reveal the foldover container', inject(function($compile, $httpBackend) {
|
||||
var url = '/page.html';
|
||||
var fullUrl = '/notes/' + url;
|
||||
$httpBackend.expect('GET', fullUrl).respond('hello');
|
||||
|
||||
var element = angular.element('<div ng-include="docs_fold"></div>');
|
||||
$compile(element)($scope);
|
||||
$scope.$apply();
|
||||
|
||||
$scope.fold(url);
|
||||
|
||||
$httpBackend.flush();
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
@@ -96,9 +96,12 @@ directive.code = function() {
|
||||
directive.prettyprint = ['reindentCode', function(reindentCode) {
|
||||
return {
|
||||
restrict: 'C',
|
||||
terminal: true,
|
||||
compile: function(element) {
|
||||
element.html(window.prettyPrintOne(reindentCode(element.html()), undefined, true));
|
||||
var html = element.html();
|
||||
//ensure that angular won't compile {{ curly }} values
|
||||
html = html.replace(/\{\{/g, '<span>{{</span>')
|
||||
.replace(/\}\}/g, '<span>}}</span>');
|
||||
element.html(window.prettyPrintOne(reindentCode(html), undefined, true));
|
||||
}
|
||||
};
|
||||
}];
|
||||
|
||||
173
docs/components/angular-bootstrap/bootstrap.js
vendored
173
docs/components/angular-bootstrap/bootstrap.js
vendored
@@ -198,6 +198,133 @@ directive.table = function() {
|
||||
};
|
||||
};
|
||||
|
||||
var popoverElement = function() {
|
||||
var object = {
|
||||
init : function() {
|
||||
this.element = angular.element(
|
||||
'<div class="popover popover-incode top">' +
|
||||
'<div class="arrow"></div>' +
|
||||
'<div class="popover-inner">' +
|
||||
'<div class="popover-title"><code></code></div>' +
|
||||
'<div class="popover-content"></div>' +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
);
|
||||
this.node = this.element[0];
|
||||
this.element.css({
|
||||
'display':'block',
|
||||
'position':'absolute'
|
||||
});
|
||||
angular.element(document.body).append(this.element);
|
||||
|
||||
var inner = this.element.children()[1];
|
||||
this.titleElement = angular.element(inner.childNodes[0].firstChild);
|
||||
this.contentElement = angular.element(inner.childNodes[1]);
|
||||
|
||||
//stop the click on the tooltip
|
||||
this.element.bind('click', function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
var self = this;
|
||||
angular.element(document.body).bind('click',function(event) {
|
||||
if(self.visible()) self.hide();
|
||||
});
|
||||
},
|
||||
|
||||
show : function(x,y) {
|
||||
this.element.addClass('visible');
|
||||
this.position(x || 0, y || 0);
|
||||
},
|
||||
|
||||
hide : function() {
|
||||
this.element.removeClass('visible');
|
||||
this.position(-9999,-9999);
|
||||
},
|
||||
|
||||
visible : function() {
|
||||
return this.position().y >= 0;
|
||||
},
|
||||
|
||||
isSituatedAt : function(element) {
|
||||
return this.besideElement ? element[0] == this.besideElement[0] : false;
|
||||
},
|
||||
|
||||
title : function(value) {
|
||||
return this.titleElement.html(value);
|
||||
},
|
||||
|
||||
content : function(value) {
|
||||
if(value && value.length > 0) {
|
||||
value = new Showdown.converter().makeHtml(value);
|
||||
}
|
||||
return this.contentElement.html(value);
|
||||
},
|
||||
|
||||
positionArrow : function(position) {
|
||||
this.node.className = 'popover ' + position;
|
||||
},
|
||||
|
||||
positionAway : function() {
|
||||
this.besideElement = null;
|
||||
this.hide();
|
||||
},
|
||||
|
||||
positionBeside : function(element) {
|
||||
this.besideElement = element;
|
||||
|
||||
var elm = element[0];
|
||||
var x = elm.offsetLeft;
|
||||
var y = elm.offsetTop;
|
||||
x -= 30;
|
||||
y -= this.node.offsetHeight + 10;
|
||||
this.show(x,y);
|
||||
},
|
||||
|
||||
position : function(x,y) {
|
||||
if(x != null && y != null) {
|
||||
this.element.css('left',x + 'px');
|
||||
this.element.css('top', y + 'px');
|
||||
}
|
||||
else {
|
||||
return {
|
||||
x : this.node.offsetLeft,
|
||||
y : this.node.offsetTop
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
object.init();
|
||||
object.hide();
|
||||
|
||||
return object;
|
||||
};
|
||||
|
||||
directive.popover = ['popoverElement', function(popover) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
priority : 500,
|
||||
link: function(scope, element, attrs) {
|
||||
element.bind('click',function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
if(popover.isSituatedAt(element) && popover.visible()) {
|
||||
popover.title('');
|
||||
popover.content('');
|
||||
popover.positionAway();
|
||||
}
|
||||
else {
|
||||
popover.title(attrs.title);
|
||||
popover.content(attrs.content);
|
||||
popover.positionBeside(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}];
|
||||
|
||||
directive.tabPane = function() {
|
||||
return {
|
||||
require: '^tabbable',
|
||||
@@ -208,5 +335,49 @@ directive.tabPane = function() {
|
||||
};
|
||||
};
|
||||
|
||||
directive.foldout = ['$http', '$animator','$window', function($http, $animator, $window) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
priority : 500,
|
||||
link: function(scope, element, attrs) {
|
||||
var animator = $animator(scope, { ngAnimate: "'foldout'" });
|
||||
var container, loading, url = attrs.url;
|
||||
if(/\/build\//.test($window.location.href)) {
|
||||
url = '/build/docs' + url;
|
||||
}
|
||||
element.bind('click',function() {
|
||||
scope.$apply(function() {
|
||||
if(!container) {
|
||||
if(loading) return;
|
||||
|
||||
angular.module('bootstrap', []).directive(directive);
|
||||
loading = true;
|
||||
var par = element.parent();
|
||||
container = angular.element('<div class="foldout">loading...</div>');
|
||||
animator.enter(container, null, par);
|
||||
|
||||
$http.get(url, { cache : true }).success(function(html) {
|
||||
loading = false;
|
||||
|
||||
html = '<div class="foldout-inner">' +
|
||||
'<div calss="foldout-arrow"></div>' +
|
||||
html +
|
||||
'</div>';
|
||||
container.html(html);
|
||||
|
||||
//avoid showing the element if the user has already closed it
|
||||
if(container.css('display') == 'block') {
|
||||
container.css('display','none');
|
||||
animator.show(container);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
container.css('display') == 'none' ? animator.show(container) : animator.hide(container);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}];
|
||||
|
||||
angular.module('bootstrap', []).directive(directive).factory('popoverElement', popoverElement);
|
||||
|
||||
0
docs/content/notes/empty.tmp
Normal file
0
docs/content/notes/empty.tmp
Normal file
@@ -196,6 +196,28 @@ describe('ngdoc', function() {
|
||||
});
|
||||
|
||||
|
||||
describe('inline annotations', function() {
|
||||
it('should convert inline docs annotations into proper HTML', function() {
|
||||
expect(new Doc().markdown(
|
||||
"<pre>\n//!annotate supertext\n<br />\n</pre>"
|
||||
)
|
||||
).toContain('data-popover data-content="supertext"')
|
||||
});
|
||||
|
||||
it('should allow for a custom regular expression for matching', function() {
|
||||
expect(new Doc().markdown(
|
||||
"<pre>\n//!annotate=\"soon\" supertext\n<p>soon</p>\n</pre>"
|
||||
)
|
||||
).toContain('data-popover data-content="supertext" data-title="Info">soon</div>')
|
||||
});
|
||||
|
||||
it('should allow for a custom title to be set', function() {
|
||||
expect(new Doc().markdown(
|
||||
"<pre>\n//!annotate=\"soon\" coming soon|supertext\n<p>soon</p>\n</pre>"
|
||||
)
|
||||
).toContain('data-popover data-content="supertext" data-title="coming soon">soon</div>')
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('trim', function() {
|
||||
|
||||
@@ -8,7 +8,12 @@ exports.htmlEscape = htmlEscape;
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
function htmlEscape(text){
|
||||
return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
||||
return text
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/\{\{/g, '<span>{{</span>')
|
||||
.replace(/\}\}/g, '<span>}}</span>');
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ writer.makeDir('build/docs/', true).then(function() {
|
||||
function writeTheRest(writesFuture) {
|
||||
var metadata = ngdoc.metadata(docs);
|
||||
|
||||
writesFuture.push(writer.symlink('../../docs/content/notes', 'build/docs/notes', 'dir'));
|
||||
writesFuture.push(writer.symlinkTemplate('css', 'dir'));
|
||||
writesFuture.push(writer.symlink('../../docs/img', 'build/docs/img', 'dir'));
|
||||
writesFuture.push(writer.symlinkTemplate('js', 'dir'));
|
||||
|
||||
@@ -225,6 +225,44 @@ Doc.prototype = {
|
||||
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;
|
||||
},
|
||||
|
||||
|
||||
@@ -79,3 +79,26 @@
|
||||
-o-transition: color 0 ease-in; /* opera is special :) */
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.foldout-show, .foldout-enter, .foldout-hide {
|
||||
-webkit-transition:0.3s cubic-bezier(0.250, 0.460, 0.450, 0.940) all;
|
||||
-moz-transition:0.3s cubic-bezier(0.250, 0.460, 0.450, 0.940) all;
|
||||
-o-transition:0.3s cubic-bezier(0.250, 0.460, 0.450, 0.940) all;
|
||||
transition:0.3s cubic-bezier(0.250, 0.460, 0.450, 0.940) all;
|
||||
}
|
||||
|
||||
.foldout-show, .foldout-enter {
|
||||
opacity:0;
|
||||
}
|
||||
|
||||
.foldout-show.foldout-show-active, .foldout-hide.foldout-hide-active {
|
||||
opacity:1;
|
||||
}
|
||||
|
||||
.foldout-hide {
|
||||
opacity:1;
|
||||
}
|
||||
|
||||
.foldout-hide.foldout-hide-active {
|
||||
opacity:0;
|
||||
}
|
||||
|
||||
@@ -303,3 +303,162 @@ ul.events > li > h3 {
|
||||
top:0;
|
||||
right:0;
|
||||
}
|
||||
|
||||
.nocode-content {
|
||||
cursor:pointer;
|
||||
display:inline-block;
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
|
||||
-webkit-transition:0.5s linear all;
|
||||
-moz-transition:0.5s linear all;
|
||||
-o-transition:0.5s linear all;
|
||||
transition:0.5s linear all;
|
||||
color: #223f7a;
|
||||
background:#ddd;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.nocode-content:hover {
|
||||
background-color: #99c2ff;
|
||||
border: 1px solid #e1e1e8;
|
||||
}
|
||||
|
||||
.popover-incode .popover-inner {
|
||||
width:auto;
|
||||
min-width:200px;
|
||||
max-width:500px;
|
||||
}
|
||||
|
||||
.popover-incode {
|
||||
-webkit-transition:0.2s linear opacity;
|
||||
-moz-transition:0.2s linear opacity;
|
||||
-o-transition:0.2s linear opacity;
|
||||
transition:0.2s linear opacity;
|
||||
opacity:0;
|
||||
}
|
||||
|
||||
.popover-incode.visible {
|
||||
opacity:1;
|
||||
}
|
||||
|
||||
.popover-incode code,
|
||||
.popover-incode pre {
|
||||
white-space:nowrap;
|
||||
}
|
||||
|
||||
.popover-incode .arrow {
|
||||
left:50px!important;
|
||||
}
|
||||
|
||||
.foldover-content {
|
||||
display:none;
|
||||
}
|
||||
|
||||
.foldout:after {
|
||||
content:"";
|
||||
position:absolute;
|
||||
left:50%;
|
||||
top:-1px;
|
||||
margin-left:-10px;
|
||||
border-width:10px;
|
||||
border-style:solid;
|
||||
border-color:#f7f7f9 transparent transparent;
|
||||
}
|
||||
|
||||
.foldout:before {
|
||||
content:"";
|
||||
position:absolute;
|
||||
left:50%;
|
||||
top:0px;
|
||||
margin-left:-10px;
|
||||
border-width:10px;
|
||||
border-style:solid;
|
||||
border-color:#bbb transparent transparent;
|
||||
}
|
||||
|
||||
.foldout {
|
||||
padding:8px 15px 5px;
|
||||
position:relative;
|
||||
background:#eee;
|
||||
white-space:normal;
|
||||
box-shadow:inset 0 0 20px #ccc;
|
||||
border-top:1px solid #bbb;
|
||||
}
|
||||
|
||||
.prettyprint {
|
||||
padding-right:0!important;
|
||||
padding-bottom:0!important;
|
||||
}
|
||||
|
||||
pre ol li {
|
||||
padding-bottom:2px;
|
||||
padding-right:5px;
|
||||
}
|
||||
|
||||
#docs-fold {
|
||||
position:absolute;
|
||||
top:0;
|
||||
right:0;
|
||||
width:500px;
|
||||
min-height:100%;
|
||||
padding-top:50px;
|
||||
padding:50px 20px 20px 20px;
|
||||
background:white;
|
||||
border-left:1px solid #999;
|
||||
box-shadow:0 0 10px #555;
|
||||
z-index:1002;
|
||||
}
|
||||
|
||||
#docs-fold.fold-show {
|
||||
-webkit-transition:0.4s cubic-bezier(0.250, 0.460, 0.450, 0.940) all;
|
||||
-moz-transition:0.4s cubic-bezier(0.250, 0.460, 0.450, 0.940) all;
|
||||
-o-transition:0.4s cubic-bezier(0.250, 0.460, 0.450, 0.940) all;
|
||||
transition:0.4s cubic-bezier(0.250, 0.460, 0.450, 0.940) all;
|
||||
}
|
||||
|
||||
#docs-fold.fold-show {
|
||||
right:-200px;
|
||||
opacity:0;
|
||||
}
|
||||
|
||||
#docs-fold.fold-show.fold-show-active {
|
||||
right:0;
|
||||
opacity:1;
|
||||
}
|
||||
|
||||
#docs-fold-overlay {
|
||||
background:rgba(255,255,255,0.5);
|
||||
position:fixed;
|
||||
left:0;
|
||||
bottom:0;
|
||||
right:0;
|
||||
top:0;
|
||||
z-index:1001;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.fixed_body {
|
||||
position:fixed;
|
||||
top:0;
|
||||
z-index:1000;
|
||||
left:0;
|
||||
right:0;
|
||||
}
|
||||
|
||||
#docs-fold-close {
|
||||
z-index: 1029;
|
||||
position: absolute;
|
||||
left: -30px;
|
||||
top: 60px;
|
||||
cursor:pointer;
|
||||
text-align: center;
|
||||
width:50px;
|
||||
line-height:50px;
|
||||
font-size: 2em;
|
||||
background: #fff;
|
||||
box-shadow:-6px 0 5px #555;
|
||||
display:block;
|
||||
border-radius:10px;
|
||||
}
|
||||
|
||||
@@ -198,6 +198,15 @@
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div id="docs-fold-overlay" ng-show="docs_fold" ng-click="fold(null)"></div>
|
||||
<div id="docs-fold" ng-show="docs_fold" ng-animate="'fold'">
|
||||
<div id="docs-fold-close" ng-click="fold(null)">
|
||||
<span class="icon-remove-sign"></span>
|
||||
</div>
|
||||
<div ng-include="docs_fold"></div>
|
||||
</div>
|
||||
|
||||
<div ng-class="{fixed_body:docs_fold}">
|
||||
<div role="main" class="container">
|
||||
<div class="row clear-navbar"></div>
|
||||
|
||||
@@ -359,6 +368,7 @@
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -411,6 +411,18 @@ docsApp.serviceFactory.sections = function sections() {
|
||||
|
||||
|
||||
docsApp.controller.DocsController = function($scope, $location, $window, $cookies, sections) {
|
||||
$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;
|
||||
}
|
||||
};
|
||||
var OFFLINE_COOKIE_NAME = 'ng-offline',
|
||||
DOCS_PATH = /^\/(api)|(guide)|(cookbook)|(misc)|(tutorial)/,
|
||||
INDEX_PATH = /^(\/|\/index[^\.]*.html)$/,
|
||||
|
||||
@@ -33,11 +33,11 @@
|
||||
* <ANY ng-directive ng-animate="{event1: 'animation-name', event2: 'animation-name-2'}"></ANY>
|
||||
*
|
||||
* <!-- you can also use a short hand -->
|
||||
* //!annotate="animation" ngAnimate|This *expands* to `{ enter: 'animation-enter', leave: 'animation-leave', ...}`</strong>
|
||||
* <ANY ng-directive ng-animate=" 'animation' "></ANY>
|
||||
* <!-- which expands to -->
|
||||
* <ANY ng-directive ng-animate="{ enter: 'animation-enter', leave: 'animation-leave', ...}"></ANY>
|
||||
*
|
||||
* <!-- keep in mind that ng-animate can take expressions -->
|
||||
* //!annotate="computeCurrentAnimation\(\)" Scope Function|This will be called each time the scope changes...
|
||||
* <ANY ng-directive ng-animate=" computeCurrentAnimation() "></ANY>
|
||||
* </pre>
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user