├── .gitignore ├── .jshintrc ├── Gruntfile.js ├── LICENSE ├── README.md ├── angular-highlightjs.js ├── angular-highlightjs.min.js ├── bower.json ├── build ├── angular-highlightjs.js └── angular-highlightjs.min.js ├── example ├── index.html ├── lesshat.less ├── partials │ ├── hljs-include.html │ ├── hljs-interpolate.html │ ├── hljs-language.html │ ├── hljs-source.html │ ├── hljs.html │ ├── lang-perl │ └── lang-php ├── scripts │ ├── app.js │ └── controllers.js └── styles.less ├── package.json ├── plunk-source ├── README.md ├── index.html ├── partials │ └── main.html ├── plunk-source-template.html ├── scripts │ ├── app.js │ ├── auto-height.js │ ├── controllers.js │ └── modules │ │ └── plunkSource.js └── styles │ ├── dark.css │ └── light.css ├── src └── angular-highlightjs.js └── with-browserify ├── index.html ├── package.json ├── scripts ├── app.js ├── bundle.js └── main-ctrl.js └── style.css /.gitignore: -------------------------------------------------------------------------------- 1 | bower_components 2 | node_modules 3 | angular-highlightjs.sublime-* 4 | .tern-port 5 | .DS_Store 6 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "curly": true, 3 | "multistr": true, 4 | "expr": true, 5 | "boss": true, 6 | "undef": true, 7 | "predef": [ 8 | "require", "define", "escape", "module" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | var config = { 2 | instanceName: { 3 | highlightjs: 'hljs', 4 | angular: 'angular' 5 | }, 6 | npmName: { 7 | highlightjs: 'highlight.js', 8 | angular: 'angular' 9 | }, 10 | amdName: { 11 | highlightjs: 'hljs', 12 | angular: 'angular' 13 | }, 14 | moduleName: 'hljs' 15 | }; 16 | 17 | module.exports = function(grunt) { 18 | grunt.initConfig({ 19 | config: config, 20 | pkg: grunt.file.readJSON('package.json'), 21 | 22 | dir: { 23 | src: 'src', 24 | build: 'build' 25 | }, 26 | meta: { 27 | banner: 28 | '/*! <%= pkg.name %>\n' + 29 | 'version: <%= pkg.version %>\n' + 30 | 'build date: <%= grunt.template.today("yyyy-mm-dd") %>\n' + 31 | 'author: <%= pkg.author.name %>\n' + 32 | '<%= pkg.repository.url %> */' 33 | }, 34 | jshint: { 35 | beforeuglify: ['<%= dir.src %>/<%= pkg.name %>.js'], 36 | gruntfile: ['Gruntfile.js'] 37 | }, 38 | concat: { 39 | options: { 40 | banner: '<%= meta.banner %>\n\n'+ 41 | '(function (root, factory) {\n'+ 42 | ' if (typeof exports === "object" || (typeof module === "object" && module.exports)) {\n'+ 43 | ' module.exports = factory(require("<%= config.npmName.angular %>"), require("<%= config.npmName.highlightjs %>"));\n'+ 44 | ' } else if (typeof define === "function" && define.amd) {\n'+ 45 | ' define(["<%= config.amdName.angular %>", "<%= config.amdName.highlightjs %>"], factory);\n'+ 46 | ' } else {\n'+ 47 | ' root.returnExports = factory(root.<%= config.instanceName.angular %>, root.<%= config.instanceName.highlightjs %>);\n'+ 48 | ' }\n'+ 49 | '}(this, function (angular, hljs) {\n\n', 50 | footer: '\n\n'+ 51 | ' return "<%= config.moduleName %>";\n'+ 52 | '}));' 53 | }, 54 | build: { 55 | src: '<%= ngAnnotate.build.dest %>', 56 | dest: '<%= ngAnnotate.build.dest %>' 57 | } 58 | }, 59 | uglify: { 60 | options: { 61 | mangle: true, 62 | compress: {}, 63 | banner: '<%= meta.banner %>\n' 64 | }, 65 | build: { 66 | src: '<%= concat.build.dest %>', 67 | dest: '<%= dir.build %>/<%= pkg.name %>.min.js' 68 | } 69 | }, 70 | copy: { 71 | build: { 72 | expand: true, 73 | flatten: true, 74 | src: '<%= dir.build %>/*', 75 | dest: '.' 76 | } 77 | }, 78 | watch: { 79 | gruntfile: { 80 | files: 'Gruntfile.js', 81 | tasks: ['jshint:gruntfile'], 82 | }, 83 | src: { 84 | files: '<%= dir.src %>/<%= pkg.name %>.js', 85 | tasks: ['default'], 86 | } 87 | }, 88 | connect: { 89 | server: { 90 | options: { 91 | port: 8080, 92 | base: '', 93 | keepalive: true 94 | } 95 | } 96 | }, 97 | ngAnnotate: { 98 | build: { 99 | src: '<%= dir.src %>/<%= pkg.name %>.js', 100 | dest: '<%= dir.build %>/<%= pkg.name %>.js' 101 | } 102 | } 103 | }); 104 | 105 | grunt.loadNpmTasks('grunt-contrib-jshint'); 106 | grunt.loadNpmTasks('grunt-contrib-uglify'); 107 | grunt.loadNpmTasks('grunt-contrib-watch'); 108 | grunt.loadNpmTasks('grunt-contrib-connect'); 109 | grunt.loadNpmTasks('grunt-contrib-concat'); 110 | grunt.loadNpmTasks('grunt-contrib-copy'); 111 | grunt.loadNpmTasks('grunt-ng-annotate'); 112 | 113 | grunt.registerTask('default', [ 114 | 'jshint:beforeuglify', 115 | 'ngAnnotate:build', 'concat:build', 'uglify:build', 'copy:build' 116 | ]); 117 | }; 118 | 119 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Robin Fan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # angular-highlightjs [](https://www.npmjs.com/package/angular-highlightjs) [](http://bower.io/search/?q=angular-highlightjs) [](https://gitter.im/pc035860/angular-highlightjs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 2 | 3 | AngularJS directive for syntax highlighting with [highlight.js](http://highlightjs.org/). 4 | 5 | #### Demos 6 | 7 | * [Self-highlight plunk](http://plnkr.co/edit/OPxzDu?p=preview) 8 | * [JSON pretty print](http://plnkr.co/edit/WCmBTQ?p=preview) 9 | 10 | ## Requirements 11 | 12 | * Highlight.js v7.0.0+ 13 | * AngularJS v1.0.1+ 14 | 15 | 16 | ## Getting started 17 | 18 | Follow the instructions [here](http://softwaremaniacs.org/soft/highlight/en/download/) to setup highlight.js. 19 | 20 | Using a prebuilt version of highlight.js hosted at cdnjs here. 21 | 22 | ```html 23 | 24 | 25 | 26 | ``` 27 | 28 | Include `angular-highlightjs` module script with AngularJS script on your page. 29 | ```html 30 | 31 | 32 | ``` 33 | 34 | Add `hljs` to your app module's dependency. 35 | ```js 36 | angular.module('myApp', ['hljs']); 37 | ``` 38 | 39 | ## Install with npm 40 | 41 | ```sh 42 | npm install angular-highlightjs 43 | ``` 44 | 45 | ## Install with Bower 46 | 47 | There's currently no official bower package of highlight.js ([see here](https://github.com/isagalaev/highlight.js/issues/182#issuecomment-29251147)). You should either build highlight.js yourself or use the [pre-built one on cdnjs](https://cdnjs.com/libraries/highlight.js). 48 | 49 | ```sh 50 | bower install angular-highlightjs 51 | ``` 52 | 53 | ## Configuration 54 | 55 | **Configuration works with highlight.js >= 8.0** 56 | 57 | In configuration phase, call `hljsServiceProvider.setOptions()` to configure with [highlight.js options](http://highlightjs.readthedocs.org/en/latest/api.html#configure-options). 58 | 59 | ```js 60 | myApp.config(function (hljsServiceProvider) { 61 | hljsServiceProvider.setOptions({ 62 | // replace tab with 4 spaces 63 | tabReplace: ' ' 64 | }); 65 | }); 66 | ``` 67 | 68 | ## Directive usage 69 | 70 | ### hljs 71 | This is a required directive. Without any other supportive directives, it provides basic inline highlight function. For better understanding, some notes about using it are specified in the live example page. 72 | 73 | The directive automatically escapes its content HTML entities by default. Can be turned off with explicitly configuration `hljs-escape="{expression evaled to false}"` or `hljs-no-escape`, and **they're only applicable for "just-`hljs`" usage**. 74 | 75 | [Live example](http://pc035860.github.io/angular-highlightjs/example/#/hljs) 76 | 77 | ```html 78 | 79 |
tag
192 | _elm.addClass(res.language);
193 |
194 | if (_hlCb !== null && angular.isFunction(_hlCb)) {
195 | _hlCb();
196 | }
197 | };
198 | ctrl.highlight = debounce(ctrl._highlight, 17);
199 |
200 | ctrl.clear = function () {
201 | if (!_elm) {
202 | return;
203 | }
204 | _code = null;
205 | _elm.text('');
206 | };
207 |
208 | ctrl.release = function () {
209 | _elm = null;
210 | _interpolateScope = null;
211 | (_stopInterpolateWatch||angular.noop)();
212 | _stopInterpolateWatch = null;
213 | };
214 |
215 | ctrl._cacheKey = function () {
216 | var args = Array.prototype.slice.call(arguments),
217 | glue = "!angular-highlightjs!";
218 | return args.join(glue);
219 | };
220 |
221 |
222 | // http://davidwalsh.name/function-debounce
223 | function debounce(func, wait, immediate) {
224 | var timeout;
225 | return function() {
226 | var context = this, args = arguments;
227 | var later = function() {
228 | timeout = null;
229 | if (!immediate) {
230 | func.apply(context, args);
231 | }
232 | };
233 | var callNow = immediate && !timeout;
234 | $window.clearTimeout(timeout);
235 | timeout = $window.setTimeout(later, wait);
236 | if (callNow) {
237 | func.apply(context, args);
238 | }
239 | };
240 | }
241 |
242 | // Ref: http://stackoverflow.com/questions/3115150/how-to-escape-regular-expression-special-characters-using-javascript
243 | function escapeRe(text, asString) {
244 | var replacement = asString ? "\\\\$&" : "\\$&";
245 | return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, replacement);
246 | }
247 |
248 | function extractInterpolations(code) {
249 | var interpolateTokens = [],
250 | re = new RegExp(RE_INTERPOLATION_STR, 'g'),
251 | newCode = '',
252 | lastIndex = 0,
253 | arr;
254 |
255 | while ((arr = re.exec(code)) !== null) {
256 | newCode += code.substring(lastIndex, arr.index) + INTERPOLATION_SYMBOL;
257 | lastIndex = arr.index + arr[0].length;
258 | interpolateTokens.push(arr[0]);
259 | }
260 |
261 | newCode += code.substr(lastIndex);
262 |
263 | return {
264 | code: newCode,
265 | tokens: interpolateTokens
266 | };
267 | }
268 |
269 | function recoverInterpolations(code, tokens) {
270 | var re = new RegExp(INTERPOLATION_SYMBOL, 'g'),
271 | newCode = '',
272 | lastIndex = 0,
273 | arr;
274 |
275 | while ((arr = re.exec(code)) !== null) {
276 | newCode += code.substring(lastIndex, arr.index ) + tokens.shift();
277 | lastIndex = arr.index + arr[0].length;
278 | }
279 |
280 | newCode += code.substr(lastIndex);
281 |
282 | return newCode;
283 | }
284 | }]);
285 |
286 |
287 | var hljsDir, interpolateDirFactory, languageDirFactory, sourceDirFactory, includeDirFactory;
288 |
289 | /**
290 | * hljs directive
291 | */
292 | hljsDir = /*@ngInject*/ ["$parse", function ($parse) {
293 | return {
294 | restrict: 'EA',
295 | controller: 'HljsCtrl',
296 | compile: function(tElm, tAttrs, transclude) {
297 | // get static code
298 | // strip the starting "new line" character
299 | var staticHTML = tElm[0].innerHTML.replace(/^(\r\n|\r|\n)/, ''),
300 | staticText = tElm[0].textContent.replace(/^(\r\n|\r|\n)/, '');
301 |
302 | // put template
303 | tElm.html('
');
304 |
305 | return function postLink(scope, iElm, iAttrs, ctrl) {
306 | var escapeCheck;
307 |
308 | var attrs = attrGetter(iAttrs);
309 |
310 | if (angular.isDefined(attrs('escape'))) {
311 | escapeCheck = $parse(attrs('escape'));
312 | } else if (angular.isDefined(attrs('no-escape'))) {
313 | escapeCheck = $parse('false');
314 | }
315 |
316 | ctrl.init(iElm.find('code'));
317 |
318 | if (attrs('onhighlight')) {
319 | ctrl.highlightCallback(function () {
320 | scope.$eval(attrs('onhighlight'));
321 | });
322 | }
323 |
324 | if ((staticHTML || staticText) && shouldHighlightStatics(iAttrs)) {
325 |
326 | var code;
327 |
328 | // Auto-escape check
329 | // default to "true"
330 | if (escapeCheck && !escapeCheck(scope)) {
331 | code = staticText;
332 | }
333 | else {
334 | code = staticHTML;
335 | }
336 |
337 | ctrl.highlight(code);
338 | }
339 |
340 | scope.$on('$destroy', function () {
341 | ctrl.release();
342 | });
343 | };
344 | }
345 | };
346 | }];
347 |
348 | /**
349 | * language directive
350 | */
351 | languageDirFactory = function (dirName) {
352 | return /*@ngInject*/ function () {
353 | return {
354 | require: '?hljs',
355 | restrict: 'A',
356 | link: function (scope, iElm, iAttrs, ctrl) {
357 | if (!ctrl) {
358 | return;
359 | }
360 | iAttrs.$observe(dirName, function (lang) {
361 | if (angular.isDefined(lang)) {
362 | ctrl.setLanguage(lang);
363 | }
364 | });
365 | }
366 | };
367 | };
368 | };
369 |
370 | /**
371 | * interpolate directive
372 | */
373 | interpolateDirFactory = function (dirName) {
374 | /*@ngInject*/
375 | return function () {
376 | return {
377 | require: '?hljs',
378 | restrict: 'A',
379 | link: function (scope, iElm, iAttrs, ctrl) {
380 | if (!ctrl) {
381 | return;
382 | }
383 | scope.$watch(iAttrs[dirName], function (newVal, oldVal) {
384 | if (newVal || newVal !== oldVal) {
385 | ctrl.setInterpolateScope(newVal ? scope : null);
386 | }
387 | });
388 | }
389 | };
390 | };
391 | };
392 |
393 | /**
394 | * source directive
395 | */
396 | sourceDirFactory = function (dirName) {
397 | return /*@ngInject*/ function () {
398 | return {
399 | require: '?hljs',
400 | restrict: 'A',
401 | link: function(scope, iElm, iAttrs, ctrl) {
402 | if (!ctrl) {
403 | return;
404 | }
405 |
406 | scope.$watch(iAttrs[dirName], function (newCode, oldCode) {
407 | if (newCode) {
408 | ctrl.highlight(newCode);
409 | }
410 | else {
411 | ctrl.clear();
412 | }
413 | });
414 | }
415 | };
416 | };
417 | };
418 |
419 | /**
420 | * include directive
421 | */
422 | includeDirFactory = function (dirName) {
423 | return /*@ngInject*/ ["$http", "$templateCache", "$q", function ($http, $templateCache, $q) {
424 | return {
425 | require: '?hljs',
426 | restrict: 'A',
427 | compile: function(tElm, tAttrs, transclude) {
428 | var srcExpr = tAttrs[dirName];
429 |
430 | return function postLink(scope, iElm, iAttrs, ctrl) {
431 | var changeCounter = 0;
432 |
433 | if (!ctrl) {
434 | return;
435 | }
436 |
437 | scope.$watch(srcExpr, function (src) {
438 | var thisChangeId = ++changeCounter;
439 |
440 | if (src && angular.isString(src)) {
441 | var templateCachePromise, dfd;
442 |
443 | templateCachePromise = $templateCache.get(src);
444 | if (!templateCachePromise) {
445 | dfd = $q.defer();
446 | $http.get(src, {
447 | cache: $templateCache,
448 | transformResponse: function(data, headersGetter) {
449 | // Return the raw string, so $http doesn't parse it
450 | // if it's json.
451 | return data;
452 | }
453 | }).then(function (code) {
454 | if (thisChangeId !== changeCounter) {
455 | return;
456 | }
457 | dfd.resolve(code);
458 | }).catch(function() {
459 | if (thisChangeId === changeCounter) {
460 | ctrl.clear();
461 | }
462 | dfd.resolve();
463 | });
464 | templateCachePromise = dfd.promise;
465 | }
466 |
467 | $q.when(templateCachePromise)
468 | .then(function (code) {
469 | if (!code) {
470 | return;
471 | }
472 |
473 | // $templateCache from $http
474 | if (angular.isArray(code)) {
475 | // 1.1.5
476 | code = code[1];
477 | }
478 | else if (angular.isObject(code)) {
479 | // 1.0.7
480 | code = code.data;
481 | }
482 |
483 | code = code.replace(/^(\r\n|\r|\n)/, '');
484 | ctrl.highlight(code);
485 | });
486 | }
487 | else {
488 | ctrl.clear();
489 | }
490 | });
491 | };
492 | }
493 | };
494 | }];
495 | };
496 |
497 | /**
498 | * Add directives
499 | */
500 | (function (module) {
501 | module.directive('hljs', hljsDir);
502 |
503 | angular.forEach(['interpolate', 'hljsInterpolate', 'compile', 'hljsCompile'], function (name) {
504 | module.directive(name, interpolateDirFactory(name));
505 | });
506 |
507 | angular.forEach(['language', 'hljsLanguage'], function (name) {
508 | module.directive(name, languageDirFactory(name));
509 | });
510 |
511 | angular.forEach(['source', 'hljsSource'], function (name) {
512 | module.directive(name, sourceDirFactory(name));
513 | });
514 |
515 | angular.forEach(['include', 'hljsInclude'], function (name) {
516 | module.directive(name, includeDirFactory(name));
517 | });
518 | })(ngModule);
519 |
520 |
521 | return "hljs";
522 | }));
--------------------------------------------------------------------------------
/angular-highlightjs.min.js:
--------------------------------------------------------------------------------
1 | /*! angular-highlightjs
2 | version: 0.7.1
3 | build date: 2017-02-28
4 | author: Chih-Hsuan Fan
5 | https://github.com/pc035860/angular-highlightjs.git */
6 | !function(a,b){"object"==typeof exports||"object"==typeof module&&module.exports?module.exports=b(require("angular"),require("highlight.js")):"function"==typeof define&&define.amd?define(["angular","hljs"],b):a.returnExports=b(a.angular,a.hljs)}(this,function(a,b){function c(b){return function(c){switch(c){case"escape":return a.isDefined(b.hljsEscape)?b.hljsEscape:b.escape;case"no-escape":return a.isDefined(b.hljsNoEscape)?b.hljsNoEscape:b.noEscape;case"onhighlight":return a.isDefined(b.hljsOnhighlight)?b.hljsOnhighlight:b.onhighlight}}}function d(b){var c=!0;return a.forEach(["source","include"],function(a){b[a]&&(c=!1)}),c}var e=a.module("hljs",[]);e.provider("hljsService",function(){var c={};return{setOptions:function(b){a.extend(c,b)},getOptions:function(){return a.copy(c)},$get:function(){return(b.configure||a.noop)(c),b}}}),e.factory("hljsCache",["$cacheFactory",function(a){return a("hljsCache")}]),e.controller("HljsCtrl",["hljsCache","hljsService","$interpolate","$window",function(b,c,d,e){function f(a,b,c){var d;return function(){var f=this,g=arguments,h=function(){d=null,c||a.apply(f,g)},i=c&&!d;e.clearTimeout(d),d=e.setTimeout(h,b),i&&a.apply(f,g)}}function g(a,b){var c=b?"\\\\$&":"\\$&";return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,c)}function h(a){for(var b,c=[],d=new RegExp(q,"g"),e="",f=0;null!==(b=d.exec(a));)e+=a.substring(f,b.index)+r,f=b.index+b[0].length,c.push(b[0]);return e+=a.substr(f),{code:e,tokens:c}}function i(a,b){for(var c,d=new RegExp(r,"g"),e="",f=0;null!==(c=d.exec(a));)e+=a.substring(f,c.index)+b.shift(),f=c.index+c[0].length;return e+=a.substr(f)}var j=this,k=null,l=null,m=null,n=!1,o=null,p=null,q=g(d.startSymbol())+"((.|\\s)+?)"+g(d.endSymbol()),r="∫";j.init=function(a){k=a},j.setInterpolateScope=function(a){n=a,m&&j.highlight(m)},j.setLanguage=function(a){l=a,m&&j.highlight(m)},j.highlightCallback=function(a){p=a},j._highlight=function(e){if(k){var f,g,q;if(m=e,n&&(q=h(e),e=q.code),l?(g=j._cacheKey(l,!!n,e),f=b.get(g),f||(f=c.highlight(l,c.fixMarkup(e),!0),b.put(g,f))):(g=j._cacheKey(!!n,e),f=b.get(g),f||(f=c.highlightAuto(c.fixMarkup(e)),b.put(g,f))),e=f.value,n){(o||a.noop)(),q&&(e=i(e,q.tokens));var r=d(e);o=n.$watch(r,function(a,b){a!==b&&k.html(a)}),n.$apply(),k.html(r(n))}else k.html(e);k.addClass(f.language),null!==p&&a.isFunction(p)&&p()}},j.highlight=f(j._highlight,17),j.clear=function(){k&&(m=null,k.text(""))},j.release=function(){k=null,n=null,(o||a.noop)(),o=null},j._cacheKey=function(){var a=Array.prototype.slice.call(arguments),b="!angular-highlightjs!";return a.join(b)}}]);var f,g,h,i,j;return f=["$parse",function(b){return{restrict:"EA",controller:"HljsCtrl",compile:function(e,f,g){var h=e[0].innerHTML.replace(/^(\r\n|\r|\n)/,""),i=e[0].textContent.replace(/^(\r\n|\r|\n)/,"");return e.html('
'),function(e,f,g,j){var k,l=c(g);if(a.isDefined(l("escape"))?k=b(l("escape")):a.isDefined(l("no-escape"))&&(k=b("false")),j.init(f.find("code")),l("onhighlight")&&j.highlightCallback(function(){e.$eval(l("onhighlight"))}),(h||i)&&d(g)){var m;m=k&&!k(e)?i:h,j.highlight(m)}e.$on("$destroy",function(){j.release()})}}}}],h=function(b){return function(){return{require:"?hljs",restrict:"A",link:function(c,d,e,f){f&&e.$observe(b,function(b){a.isDefined(b)&&f.setLanguage(b)})}}}},g=function(a){return function(){return{require:"?hljs",restrict:"A",link:function(b,c,d,e){e&&b.$watch(d[a],function(a,c){(a||a!==c)&&e.setInterpolateScope(a?b:null)})}}}},i=function(a){return function(){return{require:"?hljs",restrict:"A",link:function(b,c,d,e){e&&b.$watch(d[a],function(a,b){a?e.highlight(a):e.clear()})}}}},j=function(b){return["$http","$templateCache","$q",function(c,d,e){return{require:"?hljs",restrict:"A",compile:function(f,g,h){var i=g[b];return function(b,f,g,h){var j=0;h&&b.$watch(i,function(b){var f=++j;if(b&&a.isString(b)){var g,i;g=d.get(b),g||(i=e.defer(),c.get(b,{cache:d,transformResponse:function(a,b){return a}}).then(function(a){f===j&&i.resolve(a)}).catch(function(){f===j&&h.clear(),i.resolve()}),g=i.promise),e.when(g).then(function(b){b&&(a.isArray(b)?b=b[1]:a.isObject(b)&&(b=b.data),b=b.replace(/^(\r\n|\r|\n)/,""),h.highlight(b))})}else h.clear()})}}}}]},function(b){b.directive("hljs",f),a.forEach(["interpolate","hljsInterpolate","compile","hljsCompile"],function(a){b.directive(a,g(a))}),a.forEach(["language","hljsLanguage"],function(a){b.directive(a,h(a))}),a.forEach(["source","hljsSource"],function(a){b.directive(a,i(a))}),a.forEach(["include","hljsInclude"],function(a){b.directive(a,j(a))})}(e),"hljs"});
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-highlightjs",
3 | "version": "0.7.1",
4 | "description": "AngularJS directive for syntax highlighting with highlight.js.",
5 | "main": "./build/angular-highlightjs.js",
6 | "ignore": [
7 | "**/.*",
8 | "node_modules",
9 | "bower_components",
10 | "example",
11 | "with-browserify",
12 | "plunk-source",
13 | "Gruntfile.js",
14 | "package.json",
15 | "test",
16 | "tests"
17 | ],
18 | "dependencies": {
19 | "angular" : "^1.0.1"
20 | },
21 | "devDependencies": {}
22 | }
23 |
--------------------------------------------------------------------------------
/build/angular-highlightjs.js:
--------------------------------------------------------------------------------
1 | /*! angular-highlightjs
2 | version: 0.7.1
3 | build date: 2017-02-28
4 | author: Chih-Hsuan Fan
5 | https://github.com/pc035860/angular-highlightjs.git */
6 |
7 | (function (root, factory) {
8 | if (typeof exports === "object" || (typeof module === "object" && module.exports)) {
9 | module.exports = factory(require("angular"), require("highlight.js"));
10 | } else if (typeof define === "function" && define.amd) {
11 | define(["angular", "hljs"], factory);
12 | } else {
13 | root.returnExports = factory(root.angular, root.hljs);
14 | }
15 | }(this, function (angular, hljs) {
16 |
17 | /*global angular, hljs*/
18 |
19 | /**
20 | * returns a function to transform attrs to supported ones
21 | *
22 | * escape:
23 | * hljs-escape or escape
24 | * no-escape:
25 | * hljs-no-escape or no-escape
26 | * onhighlight:
27 | * hljs-onhighlight or onhighlight
28 | */
29 | function attrGetter(attrs) {
30 | return function (name) {
31 | switch (name) {
32 | case 'escape':
33 | return angular.isDefined(attrs.hljsEscape) ?
34 | attrs.hljsEscape :
35 | attrs.escape;
36 |
37 | case 'no-escape':
38 | return angular.isDefined(attrs.hljsNoEscape) ?
39 | attrs.hljsNoEscape :
40 | attrs.noEscape;
41 |
42 | case 'onhighlight':
43 | return angular.isDefined(attrs.hljsOnhighlight) ?
44 | attrs.hljsOnhighlight :
45 | attrs.onhighlight;
46 | }
47 | };
48 | }
49 |
50 | function shouldHighlightStatics(attrs) {
51 | var should = true;
52 | angular.forEach([
53 | 'source', 'include'
54 | ], function (name) {
55 | if (attrs[name]) {
56 | should = false;
57 | }
58 | });
59 | return should;
60 | }
61 |
62 | var ngModule = angular.module('hljs', []);
63 |
64 | /**
65 | * hljsService service
66 | */
67 | ngModule.provider('hljsService', function () {
68 | var _hljsOptions = {};
69 |
70 | return {
71 | setOptions: function (options) {
72 | angular.extend(_hljsOptions, options);
73 | },
74 | getOptions: function () {
75 | return angular.copy(_hljsOptions);
76 | },
77 | $get: function () {
78 | (hljs.configure || angular.noop)(_hljsOptions);
79 | return hljs;
80 | }
81 | };
82 | });
83 |
84 | /**
85 | * hljsCache service
86 | */
87 | ngModule.factory('hljsCache', ["$cacheFactory", function ($cacheFactory) {
88 | return $cacheFactory('hljsCache');
89 | }]);
90 |
91 | /**
92 | * HljsCtrl controller
93 | */
94 | ngModule.controller('HljsCtrl',
95 | ["hljsCache", "hljsService", "$interpolate", "$window", function HljsCtrl (hljsCache, hljsService, $interpolate, $window) {
96 | var ctrl = this;
97 |
98 | var _elm = null,
99 | _lang = null,
100 | _code = null,
101 | _interpolateScope = false,
102 | _stopInterpolateWatch = null,
103 | _hlCb = null;
104 |
105 | var RE_INTERPOLATION_STR = escapeRe($interpolate.startSymbol()) +
106 | '((.|\\s)+?)' + escapeRe($interpolate.endSymbol());
107 |
108 | var INTERPOLATION_SYMBOL = '∫';
109 |
110 | ctrl.init = function (codeElm) {
111 | _elm = codeElm;
112 | };
113 |
114 | ctrl.setInterpolateScope = function (scope) {
115 | _interpolateScope = scope;
116 |
117 | if (_code) {
118 | ctrl.highlight(_code);
119 | }
120 | };
121 |
122 | ctrl.setLanguage = function (lang) {
123 | _lang = lang;
124 |
125 | if (_code) {
126 | ctrl.highlight(_code);
127 | }
128 | };
129 |
130 | ctrl.highlightCallback = function (cb) {
131 | _hlCb = cb;
132 | };
133 |
134 | ctrl._highlight = function (code) {
135 | if (!_elm) {
136 | return;
137 | }
138 |
139 | var res, cacheKey, interpolateData;
140 |
141 | _code = code; // preserve raw code
142 |
143 | if (_interpolateScope) {
144 | interpolateData = extractInterpolations(code);
145 | code = interpolateData.code;
146 | }
147 |
148 | if (_lang) {
149 | // cache key: language, scope, code
150 | cacheKey = ctrl._cacheKey(_lang, !!_interpolateScope, code);
151 | res = hljsCache.get(cacheKey);
152 |
153 | if (!res) {
154 | res = hljsService.highlight(_lang, hljsService.fixMarkup(code), true);
155 | hljsCache.put(cacheKey, res);
156 | }
157 | }
158 | else {
159 | // cache key: scope, code
160 | cacheKey = ctrl._cacheKey(!!_interpolateScope, code);
161 | res = hljsCache.get(cacheKey);
162 |
163 | if (!res) {
164 | res = hljsService.highlightAuto(hljsService.fixMarkup(code));
165 | hljsCache.put(cacheKey, res);
166 | }
167 | }
168 |
169 | code = res.value;
170 |
171 | if (_interpolateScope) {
172 | (_stopInterpolateWatch||angular.noop)();
173 |
174 | if (interpolateData) {
175 | code = recoverInterpolations(code, interpolateData.tokens);
176 | }
177 |
178 | var interpolateFn = $interpolate(code);
179 | _stopInterpolateWatch = _interpolateScope.$watch(interpolateFn, function (newVal, oldVal) {
180 | if (newVal !== oldVal) {
181 | _elm.html(newVal);
182 | }
183 | });
184 | _interpolateScope.$apply();
185 | _elm.html(interpolateFn(_interpolateScope));
186 | }
187 | else {
188 | _elm.html(code);
189 | }
190 |
191 | // language as class on the tag
192 | _elm.addClass(res.language);
193 |
194 | if (_hlCb !== null && angular.isFunction(_hlCb)) {
195 | _hlCb();
196 | }
197 | };
198 | ctrl.highlight = debounce(ctrl._highlight, 17);
199 |
200 | ctrl.clear = function () {
201 | if (!_elm) {
202 | return;
203 | }
204 | _code = null;
205 | _elm.text('');
206 | };
207 |
208 | ctrl.release = function () {
209 | _elm = null;
210 | _interpolateScope = null;
211 | (_stopInterpolateWatch||angular.noop)();
212 | _stopInterpolateWatch = null;
213 | };
214 |
215 | ctrl._cacheKey = function () {
216 | var args = Array.prototype.slice.call(arguments),
217 | glue = "!angular-highlightjs!";
218 | return args.join(glue);
219 | };
220 |
221 |
222 | // http://davidwalsh.name/function-debounce
223 | function debounce(func, wait, immediate) {
224 | var timeout;
225 | return function() {
226 | var context = this, args = arguments;
227 | var later = function() {
228 | timeout = null;
229 | if (!immediate) {
230 | func.apply(context, args);
231 | }
232 | };
233 | var callNow = immediate && !timeout;
234 | $window.clearTimeout(timeout);
235 | timeout = $window.setTimeout(later, wait);
236 | if (callNow) {
237 | func.apply(context, args);
238 | }
239 | };
240 | }
241 |
242 | // Ref: http://stackoverflow.com/questions/3115150/how-to-escape-regular-expression-special-characters-using-javascript
243 | function escapeRe(text, asString) {
244 | var replacement = asString ? "\\\\$&" : "\\$&";
245 | return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, replacement);
246 | }
247 |
248 | function extractInterpolations(code) {
249 | var interpolateTokens = [],
250 | re = new RegExp(RE_INTERPOLATION_STR, 'g'),
251 | newCode = '',
252 | lastIndex = 0,
253 | arr;
254 |
255 | while ((arr = re.exec(code)) !== null) {
256 | newCode += code.substring(lastIndex, arr.index) + INTERPOLATION_SYMBOL;
257 | lastIndex = arr.index + arr[0].length;
258 | interpolateTokens.push(arr[0]);
259 | }
260 |
261 | newCode += code.substr(lastIndex);
262 |
263 | return {
264 | code: newCode,
265 | tokens: interpolateTokens
266 | };
267 | }
268 |
269 | function recoverInterpolations(code, tokens) {
270 | var re = new RegExp(INTERPOLATION_SYMBOL, 'g'),
271 | newCode = '',
272 | lastIndex = 0,
273 | arr;
274 |
275 | while ((arr = re.exec(code)) !== null) {
276 | newCode += code.substring(lastIndex, arr.index ) + tokens.shift();
277 | lastIndex = arr.index + arr[0].length;
278 | }
279 |
280 | newCode += code.substr(lastIndex);
281 |
282 | return newCode;
283 | }
284 | }]);
285 |
286 |
287 | var hljsDir, interpolateDirFactory, languageDirFactory, sourceDirFactory, includeDirFactory;
288 |
289 | /**
290 | * hljs directive
291 | */
292 | hljsDir = /*@ngInject*/ ["$parse", function ($parse) {
293 | return {
294 | restrict: 'EA',
295 | controller: 'HljsCtrl',
296 | compile: function(tElm, tAttrs, transclude) {
297 | // get static code
298 | // strip the starting "new line" character
299 | var staticHTML = tElm[0].innerHTML.replace(/^(\r\n|\r|\n)/, ''),
300 | staticText = tElm[0].textContent.replace(/^(\r\n|\r|\n)/, '');
301 |
302 | // put template
303 | tElm.html('
');
304 |
305 | return function postLink(scope, iElm, iAttrs, ctrl) {
306 | var escapeCheck;
307 |
308 | var attrs = attrGetter(iAttrs);
309 |
310 | if (angular.isDefined(attrs('escape'))) {
311 | escapeCheck = $parse(attrs('escape'));
312 | } else if (angular.isDefined(attrs('no-escape'))) {
313 | escapeCheck = $parse('false');
314 | }
315 |
316 | ctrl.init(iElm.find('code'));
317 |
318 | if (attrs('onhighlight')) {
319 | ctrl.highlightCallback(function () {
320 | scope.$eval(attrs('onhighlight'));
321 | });
322 | }
323 |
324 | if ((staticHTML || staticText) && shouldHighlightStatics(iAttrs)) {
325 |
326 | var code;
327 |
328 | // Auto-escape check
329 | // default to "true"
330 | if (escapeCheck && !escapeCheck(scope)) {
331 | code = staticText;
332 | }
333 | else {
334 | code = staticHTML;
335 | }
336 |
337 | ctrl.highlight(code);
338 | }
339 |
340 | scope.$on('$destroy', function () {
341 | ctrl.release();
342 | });
343 | };
344 | }
345 | };
346 | }];
347 |
348 | /**
349 | * language directive
350 | */
351 | languageDirFactory = function (dirName) {
352 | return /*@ngInject*/ function () {
353 | return {
354 | require: '?hljs',
355 | restrict: 'A',
356 | link: function (scope, iElm, iAttrs, ctrl) {
357 | if (!ctrl) {
358 | return;
359 | }
360 | iAttrs.$observe(dirName, function (lang) {
361 | if (angular.isDefined(lang)) {
362 | ctrl.setLanguage(lang);
363 | }
364 | });
365 | }
366 | };
367 | };
368 | };
369 |
370 | /**
371 | * interpolate directive
372 | */
373 | interpolateDirFactory = function (dirName) {
374 | /*@ngInject*/
375 | return function () {
376 | return {
377 | require: '?hljs',
378 | restrict: 'A',
379 | link: function (scope, iElm, iAttrs, ctrl) {
380 | if (!ctrl) {
381 | return;
382 | }
383 | scope.$watch(iAttrs[dirName], function (newVal, oldVal) {
384 | if (newVal || newVal !== oldVal) {
385 | ctrl.setInterpolateScope(newVal ? scope : null);
386 | }
387 | });
388 | }
389 | };
390 | };
391 | };
392 |
393 | /**
394 | * source directive
395 | */
396 | sourceDirFactory = function (dirName) {
397 | return /*@ngInject*/ function () {
398 | return {
399 | require: '?hljs',
400 | restrict: 'A',
401 | link: function(scope, iElm, iAttrs, ctrl) {
402 | if (!ctrl) {
403 | return;
404 | }
405 |
406 | scope.$watch(iAttrs[dirName], function (newCode, oldCode) {
407 | if (newCode) {
408 | ctrl.highlight(newCode);
409 | }
410 | else {
411 | ctrl.clear();
412 | }
413 | });
414 | }
415 | };
416 | };
417 | };
418 |
419 | /**
420 | * include directive
421 | */
422 | includeDirFactory = function (dirName) {
423 | return /*@ngInject*/ ["$http", "$templateCache", "$q", function ($http, $templateCache, $q) {
424 | return {
425 | require: '?hljs',
426 | restrict: 'A',
427 | compile: function(tElm, tAttrs, transclude) {
428 | var srcExpr = tAttrs[dirName];
429 |
430 | return function postLink(scope, iElm, iAttrs, ctrl) {
431 | var changeCounter = 0;
432 |
433 | if (!ctrl) {
434 | return;
435 | }
436 |
437 | scope.$watch(srcExpr, function (src) {
438 | var thisChangeId = ++changeCounter;
439 |
440 | if (src && angular.isString(src)) {
441 | var templateCachePromise, dfd;
442 |
443 | templateCachePromise = $templateCache.get(src);
444 | if (!templateCachePromise) {
445 | dfd = $q.defer();
446 | $http.get(src, {
447 | cache: $templateCache,
448 | transformResponse: function(data, headersGetter) {
449 | // Return the raw string, so $http doesn't parse it
450 | // if it's json.
451 | return data;
452 | }
453 | }).then(function (code) {
454 | if (thisChangeId !== changeCounter) {
455 | return;
456 | }
457 | dfd.resolve(code);
458 | }).catch(function() {
459 | if (thisChangeId === changeCounter) {
460 | ctrl.clear();
461 | }
462 | dfd.resolve();
463 | });
464 | templateCachePromise = dfd.promise;
465 | }
466 |
467 | $q.when(templateCachePromise)
468 | .then(function (code) {
469 | if (!code) {
470 | return;
471 | }
472 |
473 | // $templateCache from $http
474 | if (angular.isArray(code)) {
475 | // 1.1.5
476 | code = code[1];
477 | }
478 | else if (angular.isObject(code)) {
479 | // 1.0.7
480 | code = code.data;
481 | }
482 |
483 | code = code.replace(/^(\r\n|\r|\n)/, '');
484 | ctrl.highlight(code);
485 | });
486 | }
487 | else {
488 | ctrl.clear();
489 | }
490 | });
491 | };
492 | }
493 | };
494 | }];
495 | };
496 |
497 | /**
498 | * Add directives
499 | */
500 | (function (module) {
501 | module.directive('hljs', hljsDir);
502 |
503 | angular.forEach(['interpolate', 'hljsInterpolate', 'compile', 'hljsCompile'], function (name) {
504 | module.directive(name, interpolateDirFactory(name));
505 | });
506 |
507 | angular.forEach(['language', 'hljsLanguage'], function (name) {
508 | module.directive(name, languageDirFactory(name));
509 | });
510 |
511 | angular.forEach(['source', 'hljsSource'], function (name) {
512 | module.directive(name, sourceDirFactory(name));
513 | });
514 |
515 | angular.forEach(['include', 'hljsInclude'], function (name) {
516 | module.directive(name, includeDirFactory(name));
517 | });
518 | })(ngModule);
519 |
520 |
521 | return "hljs";
522 | }));
--------------------------------------------------------------------------------
/build/angular-highlightjs.min.js:
--------------------------------------------------------------------------------
1 | /*! angular-highlightjs
2 | version: 0.7.1
3 | build date: 2017-02-28
4 | author: Chih-Hsuan Fan
5 | https://github.com/pc035860/angular-highlightjs.git */
6 | !function(a,b){"object"==typeof exports||"object"==typeof module&&module.exports?module.exports=b(require("angular"),require("highlight.js")):"function"==typeof define&&define.amd?define(["angular","hljs"],b):a.returnExports=b(a.angular,a.hljs)}(this,function(a,b){function c(b){return function(c){switch(c){case"escape":return a.isDefined(b.hljsEscape)?b.hljsEscape:b.escape;case"no-escape":return a.isDefined(b.hljsNoEscape)?b.hljsNoEscape:b.noEscape;case"onhighlight":return a.isDefined(b.hljsOnhighlight)?b.hljsOnhighlight:b.onhighlight}}}function d(b){var c=!0;return a.forEach(["source","include"],function(a){b[a]&&(c=!1)}),c}var e=a.module("hljs",[]);e.provider("hljsService",function(){var c={};return{setOptions:function(b){a.extend(c,b)},getOptions:function(){return a.copy(c)},$get:function(){return(b.configure||a.noop)(c),b}}}),e.factory("hljsCache",["$cacheFactory",function(a){return a("hljsCache")}]),e.controller("HljsCtrl",["hljsCache","hljsService","$interpolate","$window",function(b,c,d,e){function f(a,b,c){var d;return function(){var f=this,g=arguments,h=function(){d=null,c||a.apply(f,g)},i=c&&!d;e.clearTimeout(d),d=e.setTimeout(h,b),i&&a.apply(f,g)}}function g(a,b){var c=b?"\\\\$&":"\\$&";return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,c)}function h(a){for(var b,c=[],d=new RegExp(q,"g"),e="",f=0;null!==(b=d.exec(a));)e+=a.substring(f,b.index)+r,f=b.index+b[0].length,c.push(b[0]);return e+=a.substr(f),{code:e,tokens:c}}function i(a,b){for(var c,d=new RegExp(r,"g"),e="",f=0;null!==(c=d.exec(a));)e+=a.substring(f,c.index)+b.shift(),f=c.index+c[0].length;return e+=a.substr(f)}var j=this,k=null,l=null,m=null,n=!1,o=null,p=null,q=g(d.startSymbol())+"((.|\\s)+?)"+g(d.endSymbol()),r="∫";j.init=function(a){k=a},j.setInterpolateScope=function(a){n=a,m&&j.highlight(m)},j.setLanguage=function(a){l=a,m&&j.highlight(m)},j.highlightCallback=function(a){p=a},j._highlight=function(e){if(k){var f,g,q;if(m=e,n&&(q=h(e),e=q.code),l?(g=j._cacheKey(l,!!n,e),f=b.get(g),f||(f=c.highlight(l,c.fixMarkup(e),!0),b.put(g,f))):(g=j._cacheKey(!!n,e),f=b.get(g),f||(f=c.highlightAuto(c.fixMarkup(e)),b.put(g,f))),e=f.value,n){(o||a.noop)(),q&&(e=i(e,q.tokens));var r=d(e);o=n.$watch(r,function(a,b){a!==b&&k.html(a)}),n.$apply(),k.html(r(n))}else k.html(e);k.addClass(f.language),null!==p&&a.isFunction(p)&&p()}},j.highlight=f(j._highlight,17),j.clear=function(){k&&(m=null,k.text(""))},j.release=function(){k=null,n=null,(o||a.noop)(),o=null},j._cacheKey=function(){var a=Array.prototype.slice.call(arguments),b="!angular-highlightjs!";return a.join(b)}}]);var f,g,h,i,j;return f=["$parse",function(b){return{restrict:"EA",controller:"HljsCtrl",compile:function(e,f,g){var h=e[0].innerHTML.replace(/^(\r\n|\r|\n)/,""),i=e[0].textContent.replace(/^(\r\n|\r|\n)/,"");return e.html('
'),function(e,f,g,j){var k,l=c(g);if(a.isDefined(l("escape"))?k=b(l("escape")):a.isDefined(l("no-escape"))&&(k=b("false")),j.init(f.find("code")),l("onhighlight")&&j.highlightCallback(function(){e.$eval(l("onhighlight"))}),(h||i)&&d(g)){var m;m=k&&!k(e)?i:h,j.highlight(m)}e.$on("$destroy",function(){j.release()})}}}}],h=function(b){return function(){return{require:"?hljs",restrict:"A",link:function(c,d,e,f){f&&e.$observe(b,function(b){a.isDefined(b)&&f.setLanguage(b)})}}}},g=function(a){return function(){return{require:"?hljs",restrict:"A",link:function(b,c,d,e){e&&b.$watch(d[a],function(a,c){(a||a!==c)&&e.setInterpolateScope(a?b:null)})}}}},i=function(a){return function(){return{require:"?hljs",restrict:"A",link:function(b,c,d,e){e&&b.$watch(d[a],function(a,b){a?e.highlight(a):e.clear()})}}}},j=function(b){return["$http","$templateCache","$q",function(c,d,e){return{require:"?hljs",restrict:"A",compile:function(f,g,h){var i=g[b];return function(b,f,g,h){var j=0;h&&b.$watch(i,function(b){var f=++j;if(b&&a.isString(b)){var g,i;g=d.get(b),g||(i=e.defer(),c.get(b,{cache:d,transformResponse:function(a,b){return a}}).then(function(a){f===j&&i.resolve(a)}).catch(function(){f===j&&h.clear(),i.resolve()}),g=i.promise),e.when(g).then(function(b){b&&(a.isArray(b)?b=b[1]:a.isObject(b)&&(b=b.data),b=b.replace(/^(\r\n|\r|\n)/,""),h.highlight(b))})}else h.clear()})}}}}]},function(b){b.directive("hljs",f),a.forEach(["interpolate","hljsInterpolate","compile","hljsCompile"],function(a){b.directive(a,g(a))}),a.forEach(["language","hljsLanguage"],function(a){b.directive(a,h(a))}),a.forEach(["source","hljsSource"],function(a){b.directive(a,i(a))}),a.forEach(["include","hljsInclude"],function(a){b.directive(a,j(a))})}(e),"hljs"});
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | angular-highlightjs examples
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/example/lesshat.less:
--------------------------------------------------------------------------------
1 | // LESS Hat 1.0.3
2 | // CSSHat.com
3 | // 2012
4 | // Petr Brzek & Jan Kuca
5 |
6 |
7 | // TABLE OF MIXINS:
8 | // .animation
9 | // .animation-delay
10 | // .animation-direction
11 | // .animation-duration
12 | // .animation-timing-function
13 | // .animation-iteration-count
14 | // .animation-name
15 | // .animation-play-state
16 | // .keyframes - in future
17 | // .appearance
18 | // .backface-visibility
19 | // .background-clip
20 | // .background-origin
21 | // .background-size
22 | // .border-radius
23 | // .border-top-left-radius
24 | // .border-top-right-radius
25 | // .border-bottom-left-radius
26 | // .border-bottom-right-radius
27 | // .border-image
28 | // .box-shadow
29 | // .box-sizing
30 | // .columns
31 | // .column-count
32 | // .column-gap
33 | // .column-rule
34 | // .column-width
35 | // .font-face
36 | // .gradient
37 | // .opacity
38 | // .perspective
39 | // .perspective-origin
40 | // .size
41 | // .transform
42 | // .transform-origin
43 | // .transform-style
44 | // .translate
45 | // .translate3d
46 | // .translateX
47 | // .translateY
48 | // .translateZ
49 | // .scale
50 | // .scale3d
51 | // .scaleX
52 | // .scaleY
53 | // .scaleZ
54 | // .rotate
55 | // .rotate3d
56 | // .rotateX
57 | // .rotateY
58 | // .rotateZ
59 | // .skew
60 | // .skewX
61 | // .skewY
62 | // .transition
63 | // .transition-property
64 | // .transition-duration
65 | // .transition-timing-function
66 | // .transition-delay
67 | // .user-select
68 |
69 |
70 | // @GlobalConfig
71 |
72 | // Config supported browsers for your project
73 |
74 | @w3c: true; // Unprefixed W3C syntax
75 | @webkit: true; // Chrome 7+, Safari 5+, iOS5, Android
76 | @moz: true; // Firefox 4+
77 | @opera: true; // Opera 10.5+
78 | @ms: true; // IE 10+
79 | @oldWebkit: true; // iOS4, Safari 4, Chrome < 6. Old webkit gradient syntax
80 |
81 | // Signals
82 |
83 | @webkitSignal: 1;
84 | @mozSignal: 2;
85 | @operaSignal: 3;
86 | @msSignal: 4;
87 | @w3cSignal: 5;
88 |
89 |
90 | // .animation
91 |
92 | .animation(@arguments: none){
93 |
94 | // Local config for disabling properties
95 |
96 | @w3cLocal: true; // Unprefixed W3C syntax
97 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
98 | @mozLocal: true; // Firefox 4+
99 | @operaLocal: true; // Opera 10.5+
100 | @msLocal: true; // IE 10+
101 |
102 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
103 | .inception (@signal, @arguments) when (@signal = 1) { -webkit-animation: @arguments;}
104 | .inception (@signal, @arguments) when (@signal = 2) { -moz-animation: @arguments;}
105 | .inception (@signal, @arguments) when (@signal = 3) { -o-animation: @arguments;}
106 | .inception (@signal, @arguments) when (@signal = 4) { -ms-animation: @arguments;}
107 | .inception (@signal, @arguments) when (@signal = 5) { animation: @arguments;}
108 | .inception (@signal, @arguments) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
109 | .inception(@signal, @arguments);
110 | }
111 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
112 |
113 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
114 | // -- this comment must be here because of LESS bug
115 | .result(@arguments, @mozSignal, @moz, @mozLocal);
116 | // --
117 | .result(@arguments, @operaSignal, @opera, @operaLocal);
118 | // --
119 | .result(@arguments, @msSignal, @ms, @msLocal);
120 | // --
121 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
122 | }
123 |
124 | // element{ .animation(~"yourAnimation1 6s backwards 2s, yourAnimation2 3s linear alternate infinite"); }
125 |
126 |
127 | // .animation-delay
128 |
129 | .animation-delay(@arguments: 0){
130 |
131 | // Local config for disabling properties
132 |
133 | @w3cLocal: true; // Unprefixed W3C syntax
134 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
135 | @mozLocal: true; // Firefox 4+
136 | @operaLocal: true; // Opera 10.5+
137 | @msLocal: true; // IE 10+
138 |
139 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
140 | .inception (@signal, @arguments) when (@signal = 1) { -webkit-animation-delay: @arguments;}
141 | .inception (@signal, @arguments) when (@signal = 2) { -moz-animation-delay: @arguments;}
142 | .inception (@signal, @arguments) when (@signal = 3) { -o-animation-delay: @arguments;}
143 | .inception (@signal, @arguments) when (@signal = 4) { -ms-animation-delay: @arguments;}
144 | .inception (@signal, @arguments) when (@signal = 5) { animation-delay: @arguments;}
145 | .inception (@signal, @arguments) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
146 | .inception(@signal, @arguments);
147 | }
148 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
149 |
150 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
151 | // -- this comment must be here because of LESS bug
152 | .result(@arguments, @mozSignal, @moz, @mozLocal);
153 | // --
154 | .result(@arguments, @operaSignal, @opera, @operaLocal);
155 | // --
156 | .result(@arguments, @msSignal, @ms, @msLocal);
157 | // --
158 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
159 | }
160 |
161 | // element{ .animation-delay(1s); }
162 | // element{ .animation-delay(~"750ms, 2s"); // For multiple animation-direction }
163 |
164 |
165 | // .animation-direction
166 |
167 | .animation-direction(@arguments: normal){
168 |
169 | // Local config for disabling properties
170 |
171 | @w3cLocal: true; // Unprefixed W3C syntax
172 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
173 | @mozLocal: true; // Firefox 4+
174 | @operaLocal: true; // Opera 10.5+
175 | @msLocal: true; // IE 10+
176 |
177 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
178 | .inception (@signal, @arguments) when (@signal = 1) { -webkit-animation-direction: @arguments;}
179 | .inception (@signal, @arguments) when (@signal = 2) { -moz-animation-direction: @arguments;}
180 | .inception (@signal, @arguments) when (@signal = 3) { -o-animation-direction: @arguments;}
181 | .inception (@signal, @arguments) when (@signal = 4) { -ms-animation-direction: @arguments;}
182 | .inception (@signal, @arguments) when (@signal = 5) { animation-direction: @arguments;}
183 | .inception (@signal, @arguments) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
184 | .inception(@signal, @arguments);
185 | }
186 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
187 |
188 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
189 | // -- this comment must be here because of LESS bug
190 | .result(@arguments, @mozSignal, @moz, @mozLocal);
191 | // --
192 | .result(@arguments, @operaSignal, @opera, @operaLocal);
193 | // --
194 | .result(@arguments, @msSignal, @ms, @msLocal);
195 | // --
196 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
197 | }
198 |
199 | // element{ .animation-direction(); }
200 | // element{ .animation-direction(~"normal, alternate"); }
201 |
202 |
203 | // .animation-duration
204 |
205 | .animation-duration(@arguments: 0){
206 |
207 | // Local config for disabling properties
208 |
209 | @w3cLocal: true; // Unprefixed W3C syntax
210 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
211 | @mozLocal: true; // Firefox 4+
212 | @operaLocal: true; // Opera 10.5+
213 | @msLocal: true; // IE 10+
214 |
215 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
216 | .inception (@signal, @arguments) when (@signal = 1) { -webkit-animation-duration: @arguments;}
217 | .inception (@signal, @arguments) when (@signal = 2) { -moz-animation-duration: @arguments;}
218 | .inception (@signal, @arguments) when (@signal = 3) { -o-animation-duration: @arguments;}
219 | .inception (@signal, @arguments) when (@signal = 4) { -ms-animation-duration: @arguments;}
220 | .inception (@signal, @arguments) when (@signal = 5) { animation-duration: @arguments;}
221 | .inception (@signal, @arguments) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
222 | .inception(@signal, @arguments);
223 | }
224 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
225 |
226 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
227 | // -- this comment must be here because of LESS bug
228 | .result(@arguments, @mozSignal, @moz, @mozLocal);
229 | // --
230 | .result(@arguments, @operaSignal, @opera, @operaLocal);
231 | // --
232 | .result(@arguments, @msSignal, @ms, @msLocal);
233 | // --
234 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
235 | }
236 |
237 | // element{ .animation-duration(2s); }
238 |
239 |
240 | // .animation-timing-function
241 |
242 | .animation-timing-function(@arguments: ease){
243 |
244 | // Local config for disabling properties
245 |
246 | @w3cLocal: true; // Unprefixed W3C syntax
247 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
248 | @mozLocal: true; // Firefox 4+
249 | @operaLocal: true; // Opera 10.5+
250 | @msLocal: true; // IE 10+
251 |
252 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
253 | .inception (@signal, @arguments) when (@signal = 1) { -webkit-animation-timing-function: @arguments;}
254 | .inception (@signal, @arguments) when (@signal = 2) { -moz-animation-timing-function: @arguments;}
255 | .inception (@signal, @arguments) when (@signal = 3) { -o-animation-timing-function: @arguments;}
256 | .inception (@signal, @arguments) when (@signal = 4) { -ms-animation-timing-function: @arguments;}
257 | .inception (@signal, @arguments) when (@signal = 5) { animation-timing-function: @arguments;}
258 | .inception (@signal, @arguments) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
259 | .inception(@signal, @arguments);
260 | }
261 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
262 |
263 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
264 | // -- this comment must be here because of LESS bug
265 | .result(@arguments, @mozSignal, @moz, @mozLocal);
266 | // --
267 | .result(@arguments, @operaSignal, @opera, @operaLocal);
268 | // --
269 | .result(@arguments, @msSignal, @ms, @msLocal);
270 | // --
271 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
272 | }
273 |
274 | // element{ .animation-timing-function(ease-in-out); }
275 |
276 |
277 | // .animation-iteration-count
278 |
279 | .animation-iteration-count(@arguments: 0){
280 |
281 | // Local config for disabling properties
282 |
283 | @w3cLocal: true; // Unprefixed W3C syntax
284 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
285 | @mozLocal: true; // Firefox 4+
286 | @operaLocal: true; // Opera 10.5+
287 | @msLocal: true; // IE 10+
288 |
289 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
290 | .inception (@signal, @arguments) when (@signal = 1) { -webkit-animation-iteration-count: @arguments;}
291 | .inception (@signal, @arguments) when (@signal = 2) { -moz-animation-iteration-count: @arguments;}
292 | .inception (@signal, @arguments) when (@signal = 3) { -o-animation-iteration-count: @arguments;}
293 | .inception (@signal, @arguments) when (@signal = 4) { -ms-animation-iteration-count: @arguments;}
294 | .inception (@signal, @arguments) when (@signal = 5) { animation-iteration-count: @arguments;}
295 | .inception (@signal, @arguments) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
296 | .inception(@signal, @arguments);
297 | }
298 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
299 |
300 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
301 | // -- this comment must be here because of LESS bug
302 | .result(@arguments, @mozSignal, @moz, @mozLocal);
303 | // --
304 | .result(@arguments, @operaSignal, @opera, @operaLocal);
305 | // --
306 | .result(@arguments, @msSignal, @ms, @msLocal);
307 | // --
308 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
309 | }
310 |
311 | // element{ .animation-iteration-count(3); }
312 |
313 |
314 | // .animation-name
315 |
316 | .animation-name(@arguments: none){
317 |
318 | // Local config for disabling properties
319 |
320 | @w3cLocal: true; // Unprefixed W3C syntax
321 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
322 | @mozLocal: true; // Firefox 4+
323 | @operaLocal: true; // Opera 10.5+
324 | @msLocal: true; // IE 10+
325 |
326 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
327 | .inception (@signal, @arguments) when (@signal = 1) { -webkit-animation-name: @arguments;}
328 | .inception (@signal, @arguments) when (@signal = 2) { -moz-animation-name: @arguments;}
329 | .inception (@signal, @arguments) when (@signal = 3) { -o-animation-name: @arguments;}
330 | .inception (@signal, @arguments) when (@signal = 4) { -ms-animation-name: @arguments;}
331 | .inception (@signal, @arguments) when (@signal = 5) { animation-name: @arguments;}
332 | .inception (@signal, @arguments) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
333 | .inception(@signal, @arguments);
334 | }
335 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
336 |
337 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
338 | // -- this comment must be here because of LESS bug
339 | .result(@arguments, @mozSignal, @moz, @mozLocal);
340 | // --
341 | .result(@arguments, @operaSignal, @opera, @operaLocal);
342 | // --
343 | .result(@arguments, @msSignal, @ms, @msLocal);
344 | // --
345 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
346 | }
347 |
348 | // element{ .animation-name(myReallyCoolAnimationName); }
349 |
350 |
351 | // .animation-play-state
352 |
353 | .animation-play-state(@arguments: running){
354 |
355 | // Local config for disabling properties
356 |
357 | @w3cLocal: true; // Unprefixed W3C syntax
358 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
359 | @mozLocal: true; // Firefox 4+
360 | @operaLocal: true; // Opera 10.5+
361 | @msLocal: true; // IE 10+
362 |
363 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
364 | .inception (@signal, @arguments) when (@signal = 1) { -webkit-animation-play-state: @arguments;}
365 | .inception (@signal, @arguments) when (@signal = 2) { -moz-animation-play-state: @arguments;}
366 | .inception (@signal, @arguments) when (@signal = 3) { -o-animation-play-state: @arguments;}
367 | .inception (@signal, @arguments) when (@signal = 4) { -ms-animation-play-state: @arguments;}
368 | .inception (@signal, @arguments) when (@signal = 5) { animation-play-state: @arguments;}
369 | .inception (@signal, @arguments) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
370 | .inception(@signal, @arguments);
371 | }
372 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
373 |
374 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
375 | // -- this comment must be here because of LESS bug
376 | .result(@arguments, @mozSignal, @moz, @mozLocal);
377 | // --
378 | .result(@arguments, @operaSignal, @opera, @operaLocal);
379 | // --
380 | .result(@arguments, @msSignal, @ms, @msLocal);
381 | // --
382 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
383 | }
384 |
385 | // element{ .animation-play-state(paused); }
386 |
387 |
388 | // .appearance
389 |
390 | .appearance(@argument:none){
391 |
392 | // Local config for disabling properties
393 |
394 | @w3cLocal: true; // Unprefixed W3C syntax
395 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
396 | @mozLocal: true; // Firefox 4+
397 |
398 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
399 | .inception (@signal, @argument) when (@signal = 1) { -webkit-appearance: @argument;}
400 | .inception (@signal, @argument) when (@signal = 2) { -moz-appearance: @argument;}
401 | .inception (@signal, @argument) when (@signal = 5) { appearance: @argument;}
402 | .inception (@signal, @argument) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
403 | .inception(@signal, @argument);
404 | }
405 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
406 |
407 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
408 | // -- this comment must be here because of LESS bug
409 | .result(@arguments, @mozSignal, @moz, @mozLocal);
410 | // --
411 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
412 | }
413 |
414 | // element{ .appearance(button); }
415 |
416 |
417 | // .backface-visibility
418 |
419 | .backface-visibility(@argument:visible){
420 |
421 | // Local config for disabling properties
422 |
423 | @w3cLocal: true; // Unprefixed W3C syntax
424 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
425 | @mozLocal: true; // Firefox 4+
426 |
427 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
428 | .inception (@signal, @argument) when (@signal = 1) { -webkit-backface-visibility: @argument;}
429 | .inception (@signal, @argument) when (@signal = 2) { -moz-backface-visibility: @argument;}
430 | .inception (@signal, @argument) when (@signal = 5) { backface-visibility: @argument;}
431 | .inception (@signal, @argument) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
432 | .inception(@signal, @argument);
433 | }
434 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
435 |
436 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
437 | // -- this comment must be here because of LESS bug
438 | .result(@arguments, @mozSignal, @moz, @mozLocal);
439 | // --
440 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
441 | }
442 |
443 | // element{ .backface-visibility(hidden); }
444 |
445 |
446 | // .background-clip
447 |
448 | .background-clip(@arguments:border-box){
449 |
450 | // Local config for disabling properties
451 |
452 | @w3cLocal: true; // Unprefixed W3C syntax
453 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
454 | @mozLocal: true; // Firefox 4+
455 |
456 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
457 | .inception (@signal, @arguments) when (@signal = 1) { -webkit-background-clip: @arguments;}
458 | .inception (@signal, @arguments) when (@signal = 2) { -moz-background-clip: @arguments;}
459 | .inception (@signal, @arguments) when (@signal = 5) { background-clip: @arguments;}
460 | .inception (@signal, @arguments) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
461 | .inception(@signal, @arguments);
462 | }
463 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
464 |
465 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
466 | // -- this comment must be here because of LESS bug
467 | .result(@arguments, @mozSignal, @moz, @mozLocal);
468 | // --
469 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
470 | }
471 |
472 | // element{ .background-clip(padding-box); }
473 |
474 |
475 | // .background-origin
476 |
477 | .background-origin(@arguments:padding-box){
478 |
479 | // Local config for disabling properties
480 |
481 | @w3cLocal: true; // Unprefixed W3C syntax
482 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
483 | @mozLocal: true; // Firefox 4+
484 |
485 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
486 | .inception (@signal, @arguments) when (@signal = 1) { -webkit-background-origin: @arguments;}
487 | .inception (@signal, @arguments) when (@signal = 2) { -moz-background-origin: @arguments;}
488 | .inception (@signal, @arguments) when (@signal = 5) { background-origin: @arguments;}
489 | .inception (@signal, @arguments) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
490 | .inception(@signal, @arguments);
491 | }
492 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
493 |
494 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
495 | // -- this comment must be here because of LESS bug
496 | .result(@arguments, @mozSignal, @moz, @mozLocal);
497 | // --
498 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
499 | }
500 |
501 | // element{ .background-origin(content-box); }
502 |
503 |
504 | // .background-size
505 |
506 | .background-size(@arguments:auto){
507 |
508 | // Local config for disabling properties
509 |
510 | @w3cLocal: true; // Unprefixed W3C syntax
511 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
512 | @mozLocal: true; // Firefox 4+
513 |
514 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
515 | .inception (@signal, @arguments) when (@signal = 1) { -webkit-background-size: @arguments;}
516 | .inception (@signal, @arguments) when (@signal = 2) { -moz-background-size: @arguments;}
517 | .inception (@signal, @arguments) when (@signal = 5) { background-size: @arguments;}
518 | .inception (@signal, @arguments) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
519 | .inception(@signal, @arguments);
520 | }
521 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
522 |
523 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
524 | // -- this comment must be here because of LESS bug
525 | .result(@arguments, @mozSignal, @moz, @mozLocal);
526 | // --
527 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
528 | }
529 |
530 | // element{ .background-size(~"auto, 100%"); }
531 |
532 |
533 | // .border-radius
534 |
535 | .border-radius(@arguments:0) {
536 |
537 | // Local config for disabling properties
538 |
539 | @w3cLocal: true; // Unprefixed W3C syntax
540 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
541 | @mozLocal: true; // Firefox 4+
542 |
543 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
544 | .inception (@signal, @arguments) when (@signal = 1) { -webkit-border-radius: @arguments; -webkit-background-clip: padding-box;}
545 | .inception (@signal, @arguments) when (@signal = 2) { -moz-border-radius: @arguments; -moz-background-clip: padding;}
546 | .inception (@signal, @arguments) when (@signal = 5) { border-radius: @arguments; background-clip: padding-box; }
547 | .inception (@signal, @arguments) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
548 | .inception(@signal, @arguments);
549 | }
550 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
551 |
552 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
553 | // -- this comment must be here because of LESS bug
554 | .result(@arguments, @mozSignal, @moz, @mozLocal);
555 | // --
556 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
557 | }
558 |
559 | // element{ .border-radius(10px); // all corner rounded }
560 | // element{ .border-radius(~"10px / 20px"); // horizontal and vertical rounded differently }
561 | // element{ .border-radius(~"0 10px 0 0"); // only top right corner rounded }
562 |
563 |
564 | // .border-top-left-radius
565 |
566 | .border-top-left-radius(@arguments:0) {
567 |
568 | // Local config for disabling properties
569 |
570 | @w3cLocal: true; // Unprefixed W3C syntax
571 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
572 | @mozLocal: true; // Firefox 4+
573 |
574 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
575 | .inception (@signal, @arguments) when (@signal = 1) { -webkit-border-top-left-radius: @arguments; -webkit-background-clip: padding-box;}
576 | .inception (@signal, @arguments) when (@signal = 2) { -moz-border-radius-topleft: @arguments; -moz-background-clip: padding;}
577 | .inception (@signal, @arguments) when (@signal = 5) { border-top-left-radius: @arguments; background-clip: padding-box; }
578 | .inception (@signal, @arguments) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
579 | .inception(@signal, @arguments);
580 | }
581 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
582 |
583 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
584 | // -- this comment must be here because of LESS bug
585 | .result(@arguments, @mozSignal, @moz, @mozLocal);
586 | // --
587 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
588 | }
589 |
590 | // element{ .border-top-left-radius(10px); }
591 |
592 |
593 | // .border-top-right-radius
594 |
595 | .border-top-right-radius(@arguments:0) {
596 |
597 | // Local config for disabling properties
598 |
599 | @w3cLocal: true; // Unprefixed W3C syntax
600 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
601 | @mozLocal: true; // Firefox 4+
602 |
603 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
604 | .inception (@signal, @arguments) when (@signal = 1) { -webkit-border-top-right-radius: @arguments; -webkit-background-clip: padding-box;}
605 | .inception (@signal, @arguments) when (@signal = 2) { -moz-border-radius-topright: @arguments; -moz-background-clip: padding;}
606 | .inception (@signal, @arguments) when (@signal = 5) { border-top-right-radius: @arguments; background-clip: padding-box; }
607 | .inception (@signal, @arguments) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
608 | .inception(@signal, @arguments);
609 | }
610 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
611 |
612 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
613 | // -- this comment must be here because of LESS bug
614 | .result(@arguments, @mozSignal, @moz, @mozLocal);
615 | // --
616 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
617 | }
618 |
619 | // element{ .border-top-right-radius(10px); }
620 |
621 |
622 | // .border-bottom-left-radius
623 |
624 | .border-bottom-left-radius(@arguments:0) {
625 |
626 | // Local config for disabling properties
627 |
628 | @w3cLocal: true; // Unprefixed W3C syntax
629 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
630 | @mozLocal: true; // Firefox 4+
631 |
632 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
633 | .inception (@signal, @arguments) when (@signal = 1) { -webkit-border-bottom-left-radius: @arguments; -webkit-background-clip: padding-box;}
634 | .inception (@signal, @arguments) when (@signal = 2) { -moz-border-radius-bottomleft: @arguments; -moz-background-clip: padding;}
635 | .inception (@signal, @arguments) when (@signal = 5) { border-bottom-left-radius: @arguments; background-clip: padding-box; }
636 | .inception (@signal, @arguments) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
637 | .inception(@signal, @arguments);
638 | }
639 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
640 |
641 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
642 | // -- this comment must be here because of LESS bug
643 | .result(@arguments, @mozSignal, @moz, @mozLocal);
644 | // --
645 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
646 | }
647 |
648 | // element{ .border-bottom-left-radius(10px); }
649 |
650 |
651 | // .border-bottom-right-radius
652 |
653 | .border-bottom-right-radius(@arguments:0) {
654 |
655 | // Local config for disabling properties
656 |
657 | @w3cLocal: true; // Unprefixed W3C syntax
658 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
659 | @mozLocal: true; // Firefox 4+
660 |
661 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
662 | .inception (@signal, @arguments) when (@signal = 1) { -webkit-border-bottom-right-radius: @arguments; -webkit-background-clip: padding-box;}
663 | .inception (@signal, @arguments) when (@signal = 2) { -moz-border-radius-bottomright: @arguments; -moz-background-clip: padding;}
664 | .inception (@signal, @arguments) when (@signal = 5) { border-bottom-right-radius: @arguments; background-clip: padding-box; }
665 | .inception (@signal, @arguments) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
666 | .inception(@signal, @arguments);
667 | }
668 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
669 |
670 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
671 | // -- this comment must be here because of LESS bug
672 | .result(@arguments, @mozSignal, @moz, @mozLocal);
673 | // --
674 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
675 | }
676 |
677 | // element{ .border-bottom-right-radius(10px); }
678 |
679 |
680 | // .border-image
681 |
682 | .border-image(@arguments:none) {
683 |
684 | // Local config for disabling properties
685 |
686 | @w3cLocal: true; // Unprefixed W3C syntax
687 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
688 | @mozLocal: true; // Firefox 4+
689 | @operaLocal: true; // Opera 10.5+
690 |
691 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
692 | .inception (@signal, @arguments) when (@signal = 1) { -webkit-border-image: @arguments;}
693 | .inception (@signal, @arguments) when (@signal = 2) { -moz-border-image: @arguments;}
694 | .inception (@signal, @arguments) when (@signal = 3) { -o-border-image: @arguments;}
695 | .inception (@signal, @arguments) when (@signal = 5) { border-image: @arguments; }
696 | .inception (@signal, @arguments) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
697 | .inception(@signal, @arguments);
698 | }
699 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
700 |
701 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
702 | // -- this comment must be here because of LESS bug
703 | .result(@arguments, @mozSignal, @moz, @mozLocal);
704 | // --
705 | .result(@arguments, @operaSignal, @opera, @operaLocal);
706 | // --
707 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
708 | }
709 |
710 | // element{ .border-image(url(border.png) 30 30 round); }
711 |
712 |
713 | // .box-shadow
714 |
715 | .box-shadow(@arguments:none){
716 |
717 | // Local config for disabling properties
718 |
719 | @w3cLocal: true; // Unprefixed W3C syntax
720 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
721 | @mozLocal: true; // Firefox 4+
722 |
723 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
724 | .inception (@signal, @arguments) when (@signal = 1) { -webkit-box-shadow: @arguments;}
725 | .inception (@signal, @arguments) when (@signal = 2) { -moz-box-shadow: @arguments;}
726 | .inception (@signal, @arguments) when (@signal = 5) { box-shadow: @arguments;}
727 | .inception (@signal, @arguments) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
728 | .inception(@signal, @arguments);
729 | }
730 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
731 |
732 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
733 | // -- this comment must be here because of LESS bug
734 | .result(@arguments, @mozSignal, @moz, @mozLocal);
735 | // --
736 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
737 | }
738 |
739 | // element{ .box-shadow(~"0 1px 10px #000, inset 0 -2px 5px red"); }
740 |
741 |
742 | // .box-sizing
743 |
744 | .box-sizing(@arguments:content-box){
745 |
746 | // Local config for disabling properties
747 |
748 | @w3cLocal: true; // Unprefixed W3C syntax
749 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
750 | @mozLocal: true; // Firefox 4+
751 |
752 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
753 | .inception (@signal, @arguments) when (@signal = 1) { -webkit-box-sizing: @arguments;}
754 | .inception (@signal, @arguments) when (@signal = 2) { -moz-box-sizing: @arguments;}
755 | .inception (@signal, @arguments) when (@signal = 5) { box-sizing: @arguments;}
756 | .inception (@signal, @arguments) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
757 | .inception(@signal, @arguments);
758 | }
759 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
760 |
761 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
762 | // -- this comment must be here because of LESS bug
763 | .result(@arguments, @mozSignal, @moz, @mozLocal);
764 | // --
765 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
766 | }
767 |
768 | // element{ .box-sizing(border-box); }
769 |
770 |
771 | // .columns
772 |
773 | .columns(@arguments:auto auto){
774 |
775 | // Local config for disabling properties
776 |
777 | @w3cLocal: true; // Unprefixed W3C syntax
778 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
779 | @mozLocal: true; // Firefox 4+
780 |
781 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
782 | .inception (@signal, @arguments) when (@signal = 1) { -webkit-columns: @arguments;}
783 | .inception (@signal, @arguments) when (@signal = 2) { -moz-columns: @arguments;}
784 | .inception (@signal, @arguments) when (@signal = 5) { columns: @arguments;}
785 | .inception (@signal, @arguments) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
786 | .inception(@signal, @arguments);
787 | }
788 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
789 |
790 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
791 | // -- this comment must be here because of LESS bug
792 | .result(@arguments, @mozSignal, @moz, @mozLocal);
793 | // --
794 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
795 | }
796 |
797 | // element{ .columns(100px 3); }
798 |
799 |
800 | // .column-count
801 |
802 | .column-count(@arguments:auto){
803 |
804 | // Local config for disabling properties
805 |
806 | @w3cLocal: true; // Unprefixed W3C syntax
807 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
808 | @mozLocal: true; // Firefox 4+
809 |
810 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
811 | .inception (@signal, @arguments) when (@signal = 1) { -webkit-column-count: @arguments;}
812 | .inception (@signal, @arguments) when (@signal = 2) { -moz-column-count: @arguments;}
813 | .inception (@signal, @arguments) when (@signal = 5) { column-count: @arguments;}
814 | .inception (@signal, @arguments) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
815 | .inception(@signal, @arguments);
816 | }
817 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
818 |
819 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
820 | // -- this comment must be here because of LESS bug
821 | .result(@arguments, @mozSignal, @moz, @mozLocal);
822 | // --
823 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
824 | }
825 |
826 | // element{ .column-count(3); }
827 |
828 |
829 | // .column-gap
830 |
831 | .column-gap(@arguments:normal){
832 |
833 | // Local config for disabling properties
834 |
835 | @w3cLocal: true; // Unprefixed W3C syntax
836 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
837 | @mozLocal: true; // Firefox 4+
838 |
839 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
840 | .inception (@signal, @arguments) when (@signal = 1) { -webkit-column-gap: @arguments;}
841 | .inception (@signal, @arguments) when (@signal = 2) { -moz-column-gap: @arguments;}
842 | .inception (@signal, @arguments) when (@signal = 5) { column-gap: @arguments;}
843 | .inception (@signal, @arguments) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
844 | .inception(@signal, @arguments);
845 | }
846 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
847 |
848 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
849 | // -- this comment must be here because of LESS bug
850 | .result(@arguments, @mozSignal, @moz, @mozLocal);
851 | // --
852 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
853 | }
854 |
855 | // element{ .column-gap(40px); }
856 |
857 |
858 | // .column-rule
859 |
860 | .column-rule(@arguments:medium none black){
861 |
862 | // Local config for disabling properties
863 |
864 | @w3cLocal: true; // Unprefixed W3C syntax
865 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
866 | @mozLocal: true; // Firefox 4+
867 |
868 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
869 | .inception (@signal, @arguments) when (@signal = 1) { -webkit-column-rule: @arguments;}
870 | .inception (@signal, @arguments) when (@signal = 2) { -moz-column-rule: @arguments;}
871 | .inception (@signal, @arguments) when (@signal = 5) { column-rule: @arguments;}
872 | .inception (@signal, @arguments) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
873 | .inception(@signal, @arguments);
874 | }
875 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
876 |
877 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
878 | // -- this comment must be here because of LESS bug
879 | .result(@arguments, @mozSignal, @moz, @mozLocal);
880 | // --
881 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
882 | }
883 |
884 | // element{ .column-rule(3px outset #ff00ff); }
885 |
886 |
887 | // .column-width
888 |
889 | .column-width(@arguments:auto){
890 |
891 | // Local config for disabling properties
892 |
893 | @w3cLocal: true; // Unprefixed W3C syntax
894 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
895 | @mozLocal: true; // Firefox 4+
896 |
897 | .result (@arguments, @signal, @boolean, @localBoolean) when (@boolean = true) and (@localBoolean = true) {
898 | .inception (@signal, @arguments) when (@signal = 1) { -webkit-column-width: @arguments;}
899 | .inception (@signal, @arguments) when (@signal = 2) { -moz-column-width: @arguments;}
900 | .inception (@signal, @arguments) when (@signal = 5) { column-width: @arguments;}
901 | .inception (@signal, @arguments) when (@signal > 5),(@signal < 1) { error: "Signal is out of range"; }
902 | .inception(@signal, @arguments);
903 | }
904 | .result (@arguments, @signal, @boolean, @localBoolean) when not (@boolean = true), not (@localBoolean = true) { }
905 |
906 | .result(@arguments, @webkitSignal, @webkit, @webkitLocal);
907 | // -- this comment must be here because of LESS bug
908 | .result(@arguments, @mozSignal, @moz, @mozLocal);
909 | // --
910 | .result(@arguments, @w3cSignal, @w3c, @w3cLocal);
911 | }
912 |
913 | // element{ .column-width(100px); }
914 |
915 |
916 | // .font-face
917 |
918 | .font-face(@fontname, @fontfile) {
919 |
920 | font-family: "@{fontname}";
921 | src: url("@{fontfile}-webfont.eot");
922 | src: url("@{fontfile}-webfont.eot?#iefix") format("embedded-opentype"),
923 | url("@{fontfile}-webfont.woff") format("woff"),
924 | url("@{fontfile}-webfont.ttf") format("truetype"),
925 | url("@{fontfile}-webfont.svg#@{fontname}") format("svg");
926 | font-weight: normal;
927 | font-style: normal;
928 | }
929 |
930 | // element{ .font-face(ZendaRegular, zenda-webfont); }
931 |
932 |
933 | // .gradient
934 |
935 | .gradient(@arguments:none){
936 |
937 | // Local config for disabling properties
938 |
939 | @svg: true; // SVG gradient for IE9
940 | @mozLocal: true; // Firefox 4+
941 | @oldWebkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
942 | @webkitLocal: true; // Chrome 7+, Safari 5+, iOS5, Android
943 | @operaLocal: true; // Opera 10.5+
944 | @w3cLocal: true; // Unprefixed W3C syntax
945 |
946 | @gradientSVG: ~`(function(){function G(a){var b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",c,d,e,f,g,h,i,j,k=0,l=0,m="",n=[];if(!a)return a;do c=a.charCodeAt(k++),d=a.charCodeAt(k++),e=a.charCodeAt(k++),j=c<<16|d<<8|e,f=j>>18&63,g=j>>12&63,h=j>>6&63,i=j&63,n[l++]=b.charAt(f)+b.charAt(g)+b.charAt(h)+b.charAt(i);while(k)';var t=d.join("@@@"),u=t.match(/rgba?\(\d+,\s*\d+,\s*\d+,\s*(?:0|1|\.\d+|0\.\d+)\)\s*\d*%*/g)||0,v=t.match(/hsla?\(\d+,\s*\d+%,\s*\d+%,\s*(?:0|1|\.\d+|0\.\d+)\)\s*\d*%*/g)||0,w=[],x=[];for(var y=0;y ').replace(/(rgba?\(\d+--\s*\d+--\s*\d+--\s*(0|1|\.\d+|0\.\d+)\))\s*(\d*%)*/g,' ').replace(/rgba/g,"rgb").replace(/(hsla?\(\d+--\s*\d+%--\s*\d+%--\s*(0|1|\.\d+|0\.\d+)\))\s*(\d*%)*/g,' ').replace(/hsla/g,"hsl").replace(/((?:aqua|black|blue|fuchsia|gray|grey|green|lime|maroon|navy|olive|purple|red|silver|teal|white|yellow))\s*(\d*%)*/g,' ').replace(/\*\*\*/,"#grad-ucgg-generated");try{"".trim(),b=!0}catch(s){b=!1}b&&(C[D]=C[D].trim())}C=C.toString().replace(/,/g,"").replace(/--/g,",").replace(/(rgb?\(\d+,\s*\d+,\s*\d+),\s*(?:0|1|\.\d+|0\.\d+)\)/g,"$1)").replace(/(hsl?\(\d+,\s*\d+%,\s*\d+%),\s*(?:0|1|\.\d+|0\.\d+)\)/g,"$1)")}}/radial/.test(C)&&(/((ellipse).*(center)|(circle).*(center))/g.test(C)?C=C.replace(/<\/linearGradient>/g,"").replace(/radial-gradient[^<]+/g,'