Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit c4fa487

Browse files
committed
feat(bootstrap): support code prettify and dropdown from bootstrap
1 parent cef3535 commit c4fa487

File tree

8 files changed

+6230
-0
lines changed

8 files changed

+6230
-0
lines changed

Rakefile

+4
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ task :package => [:clean, :compile, :docs] do
124124
path_to('angular.min.js'),
125125
path_to('angular-loader.js'),
126126
path_to('angular-loader.min.js'),
127+
path_to('angular-bootstrap.js'),
128+
path_to('angular-bootstrap.min.js'),
129+
path_to('angular-bootstrap-prettify.js'),
130+
path_to('angular-bootstrap-prettify.min.js'),
127131
path_to('angular-mocks.js'),
128132
path_to('angular-cookies.js'),
129133
path_to('angular-cookies.min.js'),

src/bootstrap/bootstrap-prettify.js

+264
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
'use strict';
2+
3+
var directive = {};
4+
var service = { value: {} };
5+
6+
var DEPENDENCIES = {
7+
'angular.js': 'http://code.angularjs.org/angular-' + angular.version.full + '.min.js',
8+
'angular-resource.js': 'http://code.angularjs.org/angular-resource-' + angular.version.full + '.min.js',
9+
'angular-sanitize.js': 'http://code.angularjs.org/angular-sanitize-' + angular.version.full + '.min.js',
10+
'angular-cookies.js': 'http://code.angularjs.org/angular-cookies-' + angular.version.full + '.min.js'
11+
};
12+
13+
14+
function escape(text) {
15+
return text.
16+
replace(/\&/g, '&').
17+
replace(/\</g, '&lt;').
18+
replace(/\>/g, '&gt;').
19+
replace(/"/g, '&quot;');
20+
}
21+
22+
23+
24+
directive.jsFiddle = function(getEmbededTemplate, escape, script) {
25+
return {
26+
terminal: true,
27+
link: function(scope, element, attr) {
28+
var name = '',
29+
stylesheet = '<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">\n',
30+
fields = {
31+
html: '',
32+
css: '',
33+
js: ''
34+
};
35+
36+
angular.forEach(attr.jsFiddle.split(' '), function(file, index) {
37+
var fileType = file.split('.')[1];
38+
39+
if (fileType == 'html') {
40+
if (index == 0) {
41+
fields[fileType] +=
42+
'<div ng-app' + (attr.module ? '="' + attr.module + '"' : '') + '>\n' +
43+
getEmbededTemplate(file, 2);
44+
} else {
45+
fields[fileType] += '\n\n\n <!-- CACHE FILE: ' + file + ' -->\n' +
46+
' <script type="text/ng-template" id="' + file + '">\n' +
47+
getEmbededTemplate(file, 4) +
48+
' </script>\n';
49+
}
50+
} else {
51+
fields[fileType] += getEmbededTemplate(file) + '\n';
52+
}
53+
});
54+
55+
fields.html += '</div>\n';
56+
57+
element.html(
58+
'<form class="jsfiddle" method="post" action="http://jsfiddle.net/api/post/library/pure/" target="_blank">' +
59+
hiddenField('title', 'AngularJS Example: ' + name) +
60+
hiddenField('css', '</style> <!-- Ugly Hack due to jsFiddle issue: http://goo.gl/BUfGZ --> \n' +
61+
stylesheet +
62+
script.angular +
63+
(attr.resource ? script.resource : '') +
64+
'<style>\n' +
65+
fields.css) +
66+
hiddenField('html', fields.html) +
67+
hiddenField('js', fields.js) +
68+
'<button class="btn btn-primary"><i class="icon-white icon-pencil"></i> Edit Me</button>' +
69+
'</form>');
70+
71+
function hiddenField(name, value) {
72+
return '<input type="hidden" name="' + name + '" value="' + escape(value) + '">';
73+
}
74+
}
75+
}
76+
};
77+
78+
79+
directive.code = function() {
80+
return {restrict: 'E', terminal: true};
81+
};
82+
83+
84+
directive.prettyprint = ['reindentCode', function(reindentCode) {
85+
return {
86+
restrict: 'C',
87+
terminal: true,
88+
compile: function(element) {
89+
element.html(window.prettyPrintOne(reindentCode(element.html()), undefined, true));
90+
}
91+
};
92+
}];
93+
94+
95+
directive.ngSetText = ['getEmbededTemplate', function(getEmbededTemplate) {
96+
return {
97+
restrict: 'CA',
98+
priority: 10,
99+
compile: function(element, attr) {
100+
element.text(getEmbededTemplate(attr.ngSetText));
101+
}
102+
}
103+
}]
104+
105+
106+
directive.ngHtmlWrap = ['reindentCode', 'templateMerge', function(reindentCode, templateMerge) {
107+
return {
108+
compile: function(element, attr) {
109+
var properties = {
110+
head: '',
111+
module: '',
112+
body: reindentCode(element.text(), 4)
113+
},
114+
html = "<!doctype html>\n<html ng-app{{module}}>\n <head>\n{{head}} </head>\n <body>\n{{body}} </body>\n</html>";
115+
116+
angular.forEach((attr.ngHtmlWrap || '').split(' '), function(dep) {
117+
if (!dep) return;
118+
dep = DEPENDENCIES[dep] || dep;
119+
120+
var ext = dep.split(/\./).pop();
121+
122+
if (ext == 'css') {
123+
properties.head += ' <link rel="stylesheet" href="' + dep + '" type="text/css">\n';
124+
} else if(ext == 'js') {
125+
properties.head += ' <script src="' + dep + '"></script>\n';
126+
} else {
127+
properties.module = '="' + dep + '"';
128+
}
129+
});
130+
131+
element.text(templateMerge(html, properties));
132+
}
133+
}
134+
}];
135+
136+
137+
directive.ngSetHtml = ['getEmbededTemplate', function(getEmbededTemplate) {
138+
return {
139+
restrict: 'CA',
140+
priority: 10,
141+
compile: function(element, attr) {
142+
element.html(getEmbededTemplate(attr.ngSetHtml));
143+
}
144+
}
145+
}];
146+
147+
148+
directive.ngEvalJavascript = ['getEmbededTemplate', function(getEmbededTemplate) {
149+
return {
150+
compile: function (element, attr) {
151+
var script = getEmbededTemplate(attr.ngEvalJavascript);
152+
153+
try {
154+
if (window.execScript) { // IE
155+
window.execScript(script || '""'); // IE complains when evaling empty string
156+
} else {
157+
window.eval(script);
158+
}
159+
} catch (e) {
160+
if (window.console) {
161+
window.console.log(script, '\n', e);
162+
} else {
163+
window.alert(e);
164+
}
165+
}
166+
}
167+
};
168+
}];
169+
170+
171+
directive.ngEmbedApp = ['$templateCache', '$browser', '$rootScope', '$location', function($templateCache, $browser, docsRootScope, $location) {
172+
return {
173+
terminal: true,
174+
link: function(scope, element, attrs) {
175+
var modules = [];
176+
177+
modules.push(['$provide', function($provide) {
178+
$provide.value('$templateCache', $templateCache);
179+
$provide.value('$anchorScroll', angular.noop);
180+
$provide.value('$browser', $browser);
181+
$provide.provider('$location', function() {
182+
this.$get = function() { return $location; };
183+
this.html5Mode = angular.noop;
184+
});
185+
$provide.decorator('$defer', ['$rootScope', '$delegate', function($rootScope, $delegate) {
186+
return angular.extend(function(fn, delay) {
187+
if (delay && delay > 50) {
188+
return setTimeout(function() {
189+
$rootScope.$apply(fn);
190+
}, delay);
191+
} else {
192+
return $delegate.apply(this, arguments);
193+
}
194+
}, $delegate);
195+
}]);
196+
$provide.decorator('$rootScope', ['$delegate', function(embedRootScope) {
197+
docsRootScope.$watch(function() {
198+
embedRootScope.$digest();
199+
});
200+
return embedRootScope;
201+
}]);
202+
}]);
203+
if (attrs.ngEmbedApp) modules.push(attrs.ngEmbedApp);
204+
205+
element.bind('click', function(event) {
206+
if (event.target.attributes.getNamedItem('ng-click')) {
207+
event.preventDefault();
208+
}
209+
});
210+
angular.bootstrap(element, modules);
211+
}
212+
};
213+
}];
214+
215+
service.reindentCode = function() {
216+
return function (text, spaces) {
217+
if (!text) return text;
218+
var lines = text.split(/\r?\n/);
219+
var prefix = ' '.substr(0, spaces || 0);
220+
var i;
221+
222+
// remove any leading blank lines
223+
while (lines.length && lines[0].match(/^\s*$/)) lines.shift();
224+
// remove any trailing blank lines
225+
while (lines.length && lines[lines.length - 1].match(/^\s*$/)) lines.pop();
226+
var minIndent = 999;
227+
for (i = 0; i < lines.length; i++) {
228+
var line = lines[0];
229+
var reindentCode = line.match(/^\s*/)[0];
230+
if (reindentCode !== line && reindentCode.length < minIndent) {
231+
minIndent = reindentCode.length;
232+
}
233+
}
234+
235+
for (i = 0; i < lines.length; i++) {
236+
lines[i] = prefix + lines[i].substring(minIndent);
237+
}
238+
lines.push('');
239+
return lines.join('\n');
240+
}
241+
};
242+
243+
service.templateMerge = ['reindentCode', function(indentCode) {
244+
return function(template, properties) {
245+
return template.replace(/\{\{(\w+)(?:\:(\d+))?\}\}/g, function(_, key, indent) {
246+
var value = properties[key];
247+
248+
if (indent) {
249+
value = indentCode(value, indent);
250+
}
251+
252+
return value == undefined ? '' : value;
253+
});
254+
};
255+
}];
256+
257+
service.getEmbededTemplate = ['reindentCode', function(reindentCode) {
258+
return function (id) {
259+
return reindentCode(angular.element(document.getElementById(id)).html(), 0);
260+
}
261+
}];
262+
263+
264+
angular.module('bootstrapPrettify', []).directive(directive).factory(service);

0 commit comments

Comments
 (0)