├── .gitignore ├── .jshintrc ├── .travis.yml ├── Gruntfile.js ├── LICENSE ├── README.md ├── bower.json ├── coverage ├── Chrome 43.0.2357 (Mac OS X 10.10.3) │ ├── lcov-report │ │ ├── base.css │ │ ├── index.html │ │ ├── prettify.css │ │ ├── prettify.js │ │ ├── sort-arrow-sprite.png │ │ ├── sorter.js │ │ └── src │ │ │ ├── index.html │ │ │ └── ng-reading-indicator.js.html │ └── lcov.info └── PhantomJS 1.9.8 (Mac OS X 0.0.0) │ ├── lcov-report │ ├── base.css │ ├── index.html │ ├── prettify.css │ ├── prettify.js │ ├── sort-arrow-sprite.png │ ├── sorter.js │ └── src │ │ ├── index.html │ │ └── ng-reading-indicator.js.html │ └── lcov.info ├── demo ├── app.js └── index.html ├── dist ├── ng-reading-indicator.min.css ├── ng-reading-indicator.min.js └── ng-reading-indicator.min.js.map ├── karma.conf.js ├── package.json ├── src ├── ng-reading-indicator.css ├── ng-reading-indicator.js ├── ng-reading-indicator.less ├── time-white.png └── time.png └── tests.js /.gitignore: -------------------------------------------------------------------------------- 1 | /bower_components/ 2 | /node_modules/ 3 | /demo 4 | /coverage 5 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "browser": true, 4 | "esnext": true, 5 | "bitwise": true, 6 | "camelcase": true, 7 | "curly": true, 8 | "eqeqeq": true, 9 | "immed": true, 10 | "indent": 2, 11 | "latedef": true, 12 | "newcap": true, 13 | "noarg": true, 14 | "quotmark": "single", 15 | "regexp": true, 16 | "undef": true, 17 | "unused": true, 18 | "strict": true, 19 | "trailing": true, 20 | "smarttabs": true, 21 | "maxdepth": 2, 22 | "maxcomplexity": 10, 23 | "globals": { 24 | "angular": false 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | before_script: 5 | - npm run bower 6 | after_success: 7 | - cat ./coverage/*/lcov.info | ./node_modules/coveralls/bin/coveralls.js 8 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 'use strict'; 3 | // ngReadingIndicator grunt configuration. 4 | grunt.initConfig({ 5 | 6 | // LESS compile task configuration. 7 | less: { 8 | option: { 9 | compress: true, 10 | yuicompress: true, 11 | }, 12 | ngReadingIndicator: { 13 | files: { 14 | 'src/ng-reading-indicator.css': 'src/ng-reading-indicator.less' 15 | } 16 | } 17 | }, 18 | 19 | // Autoprefixer compile task configuration. 20 | autoprefixer: { 21 | options: { 22 | browsers: ['last 2 versions', 'ie 8', 'ie 9'] 23 | }, 24 | ngReadingIndicator: { 25 | src: ['src/ng-reading-indicator.css'] 26 | } 27 | }, 28 | 29 | // CSSmin task configuration. 30 | cssmin: { 31 | target: { 32 | files: [{ 33 | expand: true, 34 | cwd: 'src', 35 | src: ['*.css'], 36 | dest: 'dist', 37 | ext: '.min.css' 38 | }] 39 | } 40 | }, 41 | 42 | jshint: { 43 | options: { 44 | jshintrc: '.jshintrc' 45 | }, 46 | all: [ 47 | 'Gruntfile.js', 48 | 'src/ng-reading-indicator.js', 49 | 'tests.js' 50 | ] 51 | }, 52 | 53 | karma: { 54 | unit: { 55 | configFile: 'karma.conf.js', 56 | singleRun: true, 57 | } 58 | }, 59 | 60 | // Uglify task configuration. 61 | uglify: { 62 | options: { 63 | sourceMap: true 64 | }, 65 | ngReadingIndicator: { 66 | files: { 67 | 'dist/ng-reading-indicator.min.js': ['src/ng-reading-indicator.js'] 68 | } 69 | } 70 | } 71 | 72 | }); 73 | 74 | grunt.loadNpmTasks('grunt-contrib-less'); 75 | grunt.loadNpmTasks('grunt-contrib-jshint'); 76 | grunt.loadNpmTasks('grunt-autoprefixer'); 77 | grunt.loadNpmTasks('grunt-karma'); 78 | grunt.loadNpmTasks('grunt-contrib-cssmin'); 79 | grunt.loadNpmTasks('grunt-contrib-uglify'); 80 | 81 | // Default task. 82 | grunt.registerTask('build', ['less', 'autoprefixer', 'cssmin', 'uglify']); 83 | grunt.registerTask('test', ['jshint', 'karma']); 84 | 85 | }; 86 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Dominic Rico-Gomez 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, 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, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | angular-reading-indicator 2 | =========================== 3 | 4 | AngularJS directive which shows a progress bar with the current reading progress of a given article or the whole website with a reading time estimate. 5 | 6 | Copyright (C) 2015 - 2016, Dominic Rico-Gomez 7 | 8 | [![Build Status](https://travis-ci.org/dominicrico/angular-reading-indicator.png?branch=master)](https://travis-ci.org/dominicrico/angular-reading-indicator) 9 | [![Coverage Status](https://coveralls.io/repos/dominicrico/angular-reading-indicator/badge.png)](https://coveralls.io/r/dominicrico/angular-reading-indicator) 10 | 11 | Installation 12 | ------------ 13 | 14 | You can choose your preferred method of installation: 15 | * Through bower: `bower install angular-reading-indicator --save` 16 | * Through npm: `npm install angular-reading-indicator --save` 17 | * From a CDN: [jsDelivr](http://www.jsdelivr.com/#!angular.reading-indicator) 18 | * Download from github: [angular-reading-indicator](https://github.com/dominicrico/angular-reading-indicator) 19 | 20 | Usage 21 | ----- 22 | Include both ng-reading-indicator.min.js and ng-reading-indicator.min.css in your application. 23 | 24 | ```html 25 | 26 | 27 | 28 | ``` 29 | 30 | Add the module `ngReadingIndicator` as a dependency to your app module: 31 | 32 | ```js 33 | var myapp = angular.module('myapp', ['ngReadingIndicator']); 34 | ``` 35 | 36 | ### Configuration 37 | 38 | Set your prefered options to customize the look of the progress bar and reading estimate. 39 | Available/Default options: 40 | 41 | ```js 42 | options = { 43 | calcFrom: 'middle', // "top", "bottom", "middle" - From where of the viewport should we calc the process of reading defaults to "middle" 44 | showHeadline: true, // Show headline in the progress bar (only works if expand is true or type is "big") 45 | expand: true, // Show small bar and expand to big after passing the headline 46 | type: 'small', // Type of bar if expand is "false" available options are "small" or "big" 47 | topOffset: 150, // Offset relative to first headline to expand the progress bar 48 | readingTime: { 49 | enable: true, // Show the estimate reading time 50 | prefix: 'estimate ca. ', // Prefix of estimate 51 | minutesSuffix: 'min', // suffix for remaining minutes 52 | secondsSuffix: 'sec', // suffix for remaining seconds 53 | speed: 150, // Reading speed in words per minute 54 | seconds: true, // show remaining seconds else shows just 0min 55 | secondInterval: 5 // steps of remaining seconds 56 | } 57 | }; 58 | ``` 59 | 60 | ```html 61 | 62 | ``` 63 | 64 | ### ngReadingIndicator directive 65 | Use ng-reading-indicator directive to display the reading progress on top of the window: 66 | 67 | ```html 68 | 69 | 70 | ``` 71 | 72 | If you want to display a different text then the headline use the "indicator-headline"-attribute. 73 | 74 | ```js 75 | $scope.myHeadline = 'Lorem Ipsum'; 76 | ``` 77 | 78 | ```html 79 | 80 | ``` 81 | 82 | This directive can wait for a scope to load before initializing! Just put in the scope to wait for change and then everything gets build. 83 | 84 | ```html 85 | 86 | ``` 87 | 88 | If you want to use the progress bar just for one special element use the indicator-element-attribute and insert the classname (only the first element with class will be used, will be extendet to id in future release) 89 | 90 | ```html 91 | 92 | ``` 93 | 94 | You are also able to create your own template and use it via indicator-template-url. 95 | If you want to display the headline just add a {{ headline }} in your template. Do you want to display the reading time estimate then add {{ readingTime }} inside your template. And last but not least we need an element with the class "ng-reading-indicator-progress" as progress bar. 96 | ```html 97 | 98 | ``` 99 | 100 | License 101 | ---- 102 | 103 | Released under the terms of the [MIT License](LICENSE). 104 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-reading-indicator", 3 | "version": "1.0.9", 4 | "authors": [ 5 | "Dominic Rico-Gomez " 6 | ], 7 | "description": "AngularJS Reading Indicator", 8 | "main": "ng-reading-indicator.js", 9 | "keywords": [ 10 | "angular", 11 | "angularjs", 12 | "reading", 13 | "indicator", 14 | "progress", 15 | "progressbar" 16 | ], 17 | "license": "MIT", 18 | "homepage": "http://dominicrico.github.io/angular-reading-indicator", 19 | "repository": { 20 | "type": "git", 21 | "url": "git://github.com/dominicrico/angular-reading-indicator.git" 22 | }, 23 | "ignore": [ 24 | "**/.*", 25 | "node_modules", 26 | "bower_components", 27 | "test", 28 | "tests" 29 | ], 30 | "devDependencies": { 31 | "angular": "~1.4.2", 32 | "angular-mocks": "~1.4.2" 33 | }, 34 | "dependencies": { 35 | "angular-sanitize": "~1.4.2" 36 | }, 37 | "resolutions": { 38 | "angular": "~1.4.2" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /coverage/Chrome 43.0.2357 (Mac OS X 10.10.3)/lcov-report/base.css: -------------------------------------------------------------------------------- 1 | body, html { 2 | margin:0; padding: 0; 3 | } 4 | body { 5 | font-family: Helvetica Neue, Helvetica,Arial; 6 | font-size: 10pt; 7 | } 8 | div.header, div.footer { 9 | background: #eee; 10 | padding: 1em; 11 | } 12 | div.header { 13 | z-index: 100; 14 | position: fixed; 15 | top: 0; 16 | border-bottom: 1px solid #666; 17 | width: 100%; 18 | } 19 | div.footer { 20 | border-top: 1px solid #666; 21 | } 22 | div.body { 23 | margin-top: 10em; 24 | } 25 | div.meta { 26 | font-size: 90%; 27 | text-align: center; 28 | } 29 | h1, h2, h3 { 30 | font-weight: normal; 31 | } 32 | h1 { 33 | font-size: 12pt; 34 | } 35 | h2 { 36 | font-size: 10pt; 37 | } 38 | pre { 39 | font-family: Consolas, Menlo, Monaco, monospace; 40 | margin: 0; 41 | padding: 0; 42 | line-height: 14px; 43 | font-size: 14px; 44 | -moz-tab-size: 2; 45 | -o-tab-size: 2; 46 | tab-size: 2; 47 | } 48 | 49 | div.path { font-size: 110%; } 50 | div.path a:link, div.path a:visited { color: #000; } 51 | table.coverage { border-collapse: collapse; margin:0; padding: 0 } 52 | 53 | table.coverage td { 54 | margin: 0; 55 | padding: 0; 56 | color: #111; 57 | vertical-align: top; 58 | } 59 | table.coverage td.line-count { 60 | width: 50px; 61 | text-align: right; 62 | padding-right: 5px; 63 | } 64 | table.coverage td.line-coverage { 65 | color: #777 !important; 66 | text-align: right; 67 | border-left: 1px solid #666; 68 | border-right: 1px solid #666; 69 | } 70 | 71 | table.coverage td.text { 72 | } 73 | 74 | table.coverage td span.cline-any { 75 | display: inline-block; 76 | padding: 0 5px; 77 | width: 40px; 78 | } 79 | table.coverage td span.cline-neutral { 80 | background: #eee; 81 | } 82 | table.coverage td span.cline-yes { 83 | background: #b5d592; 84 | color: #999; 85 | } 86 | table.coverage td span.cline-no { 87 | background: #fc8c84; 88 | } 89 | 90 | .cstat-yes { color: #111; } 91 | .cstat-no { background: #fc8c84; color: #111; } 92 | .fstat-no { background: #ffc520; color: #111 !important; } 93 | .cbranch-no { background: yellow !important; color: #111; } 94 | 95 | .cstat-skip { background: #ddd; color: #111; } 96 | .fstat-skip { background: #ddd; color: #111 !important; } 97 | .cbranch-skip { background: #ddd !important; color: #111; } 98 | 99 | .missing-if-branch { 100 | display: inline-block; 101 | margin-right: 10px; 102 | position: relative; 103 | padding: 0 4px; 104 | background: black; 105 | color: yellow; 106 | } 107 | 108 | .skip-if-branch { 109 | display: none; 110 | margin-right: 10px; 111 | position: relative; 112 | padding: 0 4px; 113 | background: #ccc; 114 | color: white; 115 | } 116 | 117 | .missing-if-branch .typ, .skip-if-branch .typ { 118 | color: inherit !important; 119 | } 120 | 121 | .entity, .metric { font-weight: bold; } 122 | .metric { display: inline-block; border: 1px solid #333; padding: 0.3em; background: white; } 123 | .metric small { font-size: 80%; font-weight: normal; color: #666; } 124 | 125 | div.coverage-summary table { border-collapse: collapse; margin: 3em; font-size: 110%; } 126 | div.coverage-summary td, div.coverage-summary table th { margin: 0; padding: 0.25em 1em; border-top: 1px solid #666; border-bottom: 1px solid #666; } 127 | div.coverage-summary th { text-align: left; border: 1px solid #666; background: #eee; font-weight: normal; } 128 | div.coverage-summary th.file { border-right: none !important; } 129 | div.coverage-summary th.pic { border-left: none !important; text-align: right; } 130 | div.coverage-summary th.pct { border-right: none !important; } 131 | div.coverage-summary th.abs { border-left: none !important; text-align: right; } 132 | div.coverage-summary td.pct { text-align: right; border-left: 1px solid #666; } 133 | div.coverage-summary td.abs { text-align: right; font-size: 90%; color: #444; border-right: 1px solid #666; } 134 | div.coverage-summary td.file { border-left: 1px solid #666; white-space: nowrap; } 135 | div.coverage-summary td.pic { min-width: 120px !important; } 136 | div.coverage-summary a:link { text-decoration: none; color: #000; } 137 | div.coverage-summary a:visited { text-decoration: none; color: #777; } 138 | div.coverage-summary a:hover { text-decoration: underline; } 139 | div.coverage-summary tfoot td { border-top: 1px solid #666; } 140 | 141 | div.coverage-summary .sorter { 142 | height: 10px; 143 | width: 7px; 144 | display: inline-block; 145 | margin-left: 0.5em; 146 | background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; 147 | } 148 | div.coverage-summary .sorted .sorter { 149 | background-position: 0 -20px; 150 | } 151 | div.coverage-summary .sorted-desc .sorter { 152 | background-position: 0 -10px; 153 | } 154 | 155 | .high { background: #b5d592 !important; } 156 | .medium { background: #ffe87c !important; } 157 | .low { background: #fc8c84 !important; } 158 | 159 | span.cover-fill, span.cover-empty { 160 | display:inline-block; 161 | border:1px solid #444; 162 | background: white; 163 | height: 12px; 164 | } 165 | span.cover-fill { 166 | background: #ccc; 167 | border-right: 1px solid #444; 168 | } 169 | span.cover-empty { 170 | background: white; 171 | border-left: none; 172 | } 173 | span.cover-full { 174 | border-right: none !important; 175 | } 176 | pre.prettyprint { 177 | border: none !important; 178 | padding: 0 !important; 179 | margin: 0 !important; 180 | } 181 | .com { color: #999 !important; } 182 | .ignore-none { color: #999; font-weight: normal; } 183 | -------------------------------------------------------------------------------- /coverage/Chrome 43.0.2357 (Mac OS X 10.10.3)/lcov-report/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Code coverage report for All files 5 | 6 | 7 | 8 | 13 | 14 | 15 |
16 |

Code coverage report for All files

17 |

18 | Statements: 34.07% (31 / 91)      19 | Branches: 18.56% (18 / 97)      20 | Functions: 50% (8 / 16)      21 | Lines: 34.07% (31 / 91)      22 | Ignored: none      23 |

24 |
25 |
26 |
27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 |
FileStatementsBranchesFunctionsLines
src/34.07%(31 / 91)18.56%(18 / 97)50%(8 / 16)34.07%(31 / 91)
58 |
59 |
60 | 63 | 64 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /coverage/Chrome 43.0.2357 (Mac OS X 10.10.3)/lcov-report/prettify.css: -------------------------------------------------------------------------------- 1 | .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} 2 | -------------------------------------------------------------------------------- /coverage/Chrome 43.0.2357 (Mac OS X 10.10.3)/lcov-report/prettify.js: -------------------------------------------------------------------------------- 1 | window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); 2 | -------------------------------------------------------------------------------- /coverage/Chrome 43.0.2357 (Mac OS X 10.10.3)/lcov-report/sort-arrow-sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dominicrico/angular-reading-indicator/4da42d100bfec62a2954ffb61b856d2224bdb826/coverage/Chrome 43.0.2357 (Mac OS X 10.10.3)/lcov-report/sort-arrow-sprite.png -------------------------------------------------------------------------------- /coverage/Chrome 43.0.2357 (Mac OS X 10.10.3)/lcov-report/sorter.js: -------------------------------------------------------------------------------- 1 | var addSorting = (function () { 2 | "use strict"; 3 | var cols, 4 | currentSort = { 5 | index: 0, 6 | desc: false 7 | }; 8 | 9 | // returns the summary table element 10 | function getTable() { return document.querySelector('.coverage-summary table'); } 11 | // returns the thead element of the summary table 12 | function getTableHeader() { return getTable().querySelector('thead tr'); } 13 | // returns the tbody element of the summary table 14 | function getTableBody() { return getTable().querySelector('tbody'); } 15 | // returns the th element for nth column 16 | function getNthColumn(n) { return getTableHeader().querySelectorAll('th')[n]; } 17 | 18 | // loads all columns 19 | function loadColumns() { 20 | var colNodes = getTableHeader().querySelectorAll('th'), 21 | colNode, 22 | cols = [], 23 | col, 24 | i; 25 | 26 | for (i = 0; i < colNodes.length; i += 1) { 27 | colNode = colNodes[i]; 28 | col = { 29 | key: colNode.getAttribute('data-col'), 30 | sortable: !colNode.getAttribute('data-nosort'), 31 | type: colNode.getAttribute('data-type') || 'string' 32 | }; 33 | cols.push(col); 34 | if (col.sortable) { 35 | col.defaultDescSort = col.type === 'number'; 36 | colNode.innerHTML = colNode.innerHTML + ''; 37 | } 38 | } 39 | return cols; 40 | } 41 | // attaches a data attribute to every tr element with an object 42 | // of data values keyed by column name 43 | function loadRowData(tableRow) { 44 | var tableCols = tableRow.querySelectorAll('td'), 45 | colNode, 46 | col, 47 | data = {}, 48 | i, 49 | val; 50 | for (i = 0; i < tableCols.length; i += 1) { 51 | colNode = tableCols[i]; 52 | col = cols[i]; 53 | val = colNode.getAttribute('data-value'); 54 | if (col.type === 'number') { 55 | val = Number(val); 56 | } 57 | data[col.key] = val; 58 | } 59 | return data; 60 | } 61 | // loads all row data 62 | function loadData() { 63 | var rows = getTableBody().querySelectorAll('tr'), 64 | i; 65 | 66 | for (i = 0; i < rows.length; i += 1) { 67 | rows[i].data = loadRowData(rows[i]); 68 | } 69 | } 70 | // sorts the table using the data for the ith column 71 | function sortByIndex(index, desc) { 72 | var key = cols[index].key, 73 | sorter = function (a, b) { 74 | a = a.data[key]; 75 | b = b.data[key]; 76 | return a < b ? -1 : a > b ? 1 : 0; 77 | }, 78 | finalSorter = sorter, 79 | tableBody = document.querySelector('.coverage-summary tbody'), 80 | rowNodes = tableBody.querySelectorAll('tr'), 81 | rows = [], 82 | i; 83 | 84 | if (desc) { 85 | finalSorter = function (a, b) { 86 | return -1 * sorter(a, b); 87 | }; 88 | } 89 | 90 | for (i = 0; i < rowNodes.length; i += 1) { 91 | rows.push(rowNodes[i]); 92 | tableBody.removeChild(rowNodes[i]); 93 | } 94 | 95 | rows.sort(finalSorter); 96 | 97 | for (i = 0; i < rows.length; i += 1) { 98 | tableBody.appendChild(rows[i]); 99 | } 100 | } 101 | // removes sort indicators for current column being sorted 102 | function removeSortIndicators() { 103 | var col = getNthColumn(currentSort.index), 104 | cls = col.className; 105 | 106 | cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); 107 | col.className = cls; 108 | } 109 | // adds sort indicators for current column being sorted 110 | function addSortIndicators() { 111 | getNthColumn(currentSort.index).className += currentSort.desc ? ' sorted-desc' : ' sorted'; 112 | } 113 | // adds event listeners for all sorter widgets 114 | function enableUI() { 115 | var i, 116 | el, 117 | ithSorter = function ithSorter(i) { 118 | var col = cols[i]; 119 | 120 | return function () { 121 | var desc = col.defaultDescSort; 122 | 123 | if (currentSort.index === i) { 124 | desc = !currentSort.desc; 125 | } 126 | sortByIndex(i, desc); 127 | removeSortIndicators(); 128 | currentSort.index = i; 129 | currentSort.desc = desc; 130 | addSortIndicators(); 131 | }; 132 | }; 133 | for (i =0 ; i < cols.length; i += 1) { 134 | if (cols[i].sortable) { 135 | el = getNthColumn(i).querySelector('.sorter'); 136 | if (el.addEventListener) { 137 | el.addEventListener('click', ithSorter(i)); 138 | } else { 139 | el.attachEvent('onclick', ithSorter(i)); 140 | } 141 | } 142 | } 143 | } 144 | // adds sorting functionality to the UI 145 | return function () { 146 | if (!getTable()) { 147 | return; 148 | } 149 | cols = loadColumns(); 150 | loadData(cols); 151 | addSortIndicators(); 152 | enableUI(); 153 | }; 154 | })(); 155 | 156 | window.addEventListener('load', addSorting); 157 | -------------------------------------------------------------------------------- /coverage/Chrome 43.0.2357 (Mac OS X 10.10.3)/lcov-report/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Code coverage report for src/ 5 | 6 | 7 | 8 | 13 | 14 | 15 |
16 |

Code coverage report for src/

17 |

18 | Statements: 34.07% (31 / 91)      19 | Branches: 18.56% (18 / 97)      20 | Functions: 50% (8 / 16)      21 | Lines: 34.07% (31 / 91)      22 | Ignored: none      23 |

24 |
All files » src/
25 |
26 |
27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 |
FileStatementsBranchesFunctionsLines
ng-reading-indicator.js34.07%(31 / 91)18.56%(18 / 97)50%(8 / 16)34.07%(31 / 91)
58 |
59 |
60 | 63 | 64 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /coverage/Chrome 43.0.2357 (Mac OS X 10.10.3)/lcov-report/src/ng-reading-indicator.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Code coverage report for src/ng-reading-indicator.js 5 | 6 | 7 | 8 | 13 | 14 | 15 |
16 |

Code coverage report for src/ng-reading-indicator.js

17 |

18 | Statements: 34.07% (31 / 91)      19 | Branches: 18.56% (18 / 97)      20 | Functions: 50% (8 / 16)      21 | Lines: 34.07% (31 / 91)      22 | Ignored: none      23 |

24 |
All files » src/ » ng-reading-indicator.js
25 |
26 |
27 |

 28 | 
623 | 
1 29 | 2 30 | 3 31 | 4 32 | 5 33 | 6 34 | 7 35 | 8 36 | 9 37 | 10 38 | 11 39 | 12 40 | 13 41 | 14 42 | 15 43 | 16 44 | 17 45 | 18 46 | 19 47 | 20 48 | 21 49 | 22 50 | 23 51 | 24 52 | 25 53 | 26 54 | 27 55 | 28 56 | 29 57 | 30 58 | 31 59 | 32 60 | 33 61 | 34 62 | 35 63 | 36 64 | 37 65 | 38 66 | 39 67 | 40 68 | 41 69 | 42 70 | 43 71 | 44 72 | 45 73 | 46 74 | 47 75 | 48 76 | 49 77 | 50 78 | 51 79 | 52 80 | 53 81 | 54 82 | 55 83 | 56 84 | 57 85 | 58 86 | 59 87 | 60 88 | 61 89 | 62 90 | 63 91 | 64 92 | 65 93 | 66 94 | 67 95 | 68 96 | 69 97 | 70 98 | 71 99 | 72 100 | 73 101 | 74 102 | 75 103 | 76 104 | 77 105 | 78 106 | 79 107 | 80 108 | 81 109 | 82 110 | 83 111 | 84 112 | 85 113 | 86 114 | 87 115 | 88 116 | 89 117 | 90 118 | 91 119 | 92 120 | 93 121 | 94 122 | 95 123 | 96 124 | 97 125 | 98 126 | 99 127 | 100 128 | 101 129 | 102 130 | 103 131 | 104 132 | 105 133 | 106 134 | 107 135 | 108 136 | 109 137 | 110 138 | 111 139 | 112 140 | 113 141 | 114 142 | 115 143 | 116 144 | 117 145 | 118 146 | 119 147 | 120 148 | 121 149 | 122 150 | 123 151 | 124 152 | 125 153 | 126 154 | 127 155 | 128 156 | 129 157 | 130 158 | 131 159 | 132 160 | 133 161 | 134 162 | 135 163 | 136 164 | 137 165 | 138 166 | 139 167 | 140 168 | 141 169 | 142 170 | 143 171 | 144 172 | 145 173 | 146 174 | 147 175 | 148 176 | 149 177 | 150 178 | 151 179 | 152 180 | 153 181 | 154 182 | 155 183 | 156 184 | 157 185 | 158 186 | 159 187 | 160 188 | 161 189 | 162 190 | 163 191 | 164 192 | 165 193 | 166 194 | 167 195 | 168 196 | 169 197 | 170 198 | 171 199 | 172 200 | 173 201 | 174 202 | 175 203 | 176 204 | 177 205 | 178 206 | 179 207 | 180 208 | 181 209 | 182 210 | 183 211 | 184 212 | 185 213 | 186 214 | 187 215 | 188 216 | 189 217 | 190 218 | 191 219 | 192 220 | 193 221 | 194 222 | 195 223 | 196 224 | 197 225 | 198 226 | 1991 227 |   228 |   229 | 1 230 |   231 | 1 232 |   233 |   234 |   235 | 3 236 |   237 | 3 238 |   239 | 3 240 |   241 | 3 242 |   243 |   244 |   245 |   246 |   247 |   248 |   249 |   250 | 3 251 |   252 |   253 | 3 254 |   255 |   256 |   257 |   258 |   259 |   260 |   261 |   262 |   263 |   264 |   265 |   266 |   267 |   268 |   269 |   270 |   271 |   272 |   273 |   274 |   275 |   276 |   277 |   278 |   279 | 1 280 | 3 281 | 6 282 | 3 283 | 1 284 |   285 |   286 |   287 | 1 288 |   289 |   290 |   291 |   292 | 3 293 |   294 |   295 | 3 296 |   297 | 3 298 |   299 | 3 300 |   301 |   302 |   303 | 3 304 | 3 305 | 3 306 |   307 | 1 308 | 3 309 |   310 |   311 |   312 |   313 |   314 |   315 |   316 |   317 |   318 |   319 |   320 |   321 |   322 |   323 |   324 |   325 |   326 |   327 |   328 |   329 | 1 330 |   331 |   332 |   333 |   334 |   335 |   336 |   337 |   338 |   339 |   340 | 1 341 |   342 |   343 |   344 |   345 |   346 |   347 |   348 | 1 349 |   350 |   351 |   352 |   353 |   354 |   355 |   356 |   357 |   358 |   359 |   360 |   361 |   362 |   363 |   364 |   365 |   366 |   367 |   368 |   369 |   370 |   371 |   372 |   373 |   374 |   375 |   376 |   377 |   378 |   379 |   380 |   381 | 1 382 |   383 |   384 |   385 |   386 |   387 |   388 |   389 |   390 |   391 |   392 |   393 |   394 |   395 |   396 |   397 |   398 |   399 |   400 |   401 |   402 |   403 |   404 | 3 405 |   406 |   407 |   408 |   409 |   410 |   411 | 3 412 |   413 |   414 | 3 415 |   416 |   417 |   418 |   419 |   420 |   421 |   422 |   423 |   424 |  
(function(angular, undefined){
425 |   'use strict';
426 |  
427 |   var ngReadingIndicator = angular.module('ngReadingIndicator', ['ngSanitize']);
428 |  
429 |   ngReadingIndicator.directive('ngReadingIndicator', [
430 |     '$window', '$document', '$templateCache', '$sce', '$timeout',
431 |     function($window, $document, $templateCache, $sce, $timeout) {
432 |  
433 |       var TEMPLATE_URL = '';
434 |  
435 |       var template ='<div class="ng-reading-indicator-progress"></div><div class="ng-reading-indicator-headline"><h2 ng-bind-html="headline"></h2></div><div class="ng-reading-indicator-time" ng-if="readingTime"> {{ readingTime }}</div>';
436 |  
437 |       $templateCache.put(TEMPLATE_URL, template);
438 |  
439 |       return {
440 |         restrict: 'AE',
441 |         scope: {
442 |           elementClass: '@indicatorElement',
443 |           userOptions: '&indicatorOptions',
444 |           headline: '=indicatorHeadline',
445 |           lazy: '=indicatorLazy'
446 |         },
447 |         templateUrl: function (element, attributes) {
448 |           return (attributes.indicatorTemplateUrl || TEMPLATE_URL);
449 |         },
450 |         link: function(scope, element, attributes) {
451 |           var headline = null,
452 |               article = null,
453 |               bottom = null,
454 |               top = null,
455 |               height = null,
456 |               progress = null,
457 |               progressBar = null,
458 |               elem = null,
459 |               expandOffset = null,
460 |               expandOnHeadline = false,
461 |               options = {
462 |                 showHeadline: true,
463 |                 expand: true,
464 |                 type: 'small',
465 |                 topOffset: 150,
466 |                 readingTime: {
467 |                   enable: true,
468 |                   prefix: 'remaining estimate ',
469 |                   minutesSuffix: 'min',
470 |                   secondsSuffix: 'sec',
471 |                   speed: 150,
472 |                   seconds: true,
473 |                   secondInterval: 5
474 |                 }
475 |               };
476 |  
477 |           function extendDeep(dst) {
478 |             angular.forEach(arguments, function (obj) {
479 |               if (obj !== dst) {
480 |                 angular.forEach(obj, function (value, key) {
481 |                   Iif (dst[key] && dst[key].constructor && dst[key].constructor === Object) {
482 |                     extendDeep(dst[key], value);
483 |                   }
484 |                   else {
485 |                     dst[key] = value;
486 |                   }
487 |                 });
488 |               }
489 |             });
490 |             return dst;
491 |           }
492 |  
493 |           extendDeep(options, scope.userOptions());
494 |  
495 |           Iif (!options.expand && options.type !== 'small') {
496 |             angular.element(element).addClass('ng-reading-indicator-expanded');
497 |           } else Iif (!options.expand && options.type !== 'big') {
498 |             angular.element(element).addClass('ng-reading-indicator-shrink');
499 |           }
500 |  
501 |           elem = (!scope.elementClass || scope.elementClass === '') ? $window : scope.elementClass;
502 |           article = (!scope.elementClass || scope.elementClass === '') ? angular.element(document.body) : angular.element(document.getElementsByClassName(elem.replace('.', ''))[0]);
503 |           progressBar = document.getElementsByClassName('ng-reading-indicator-progress')[0];
504 |  
505 |           function initizalize() {
506 |             $timeout(function(){
507 |               if (options.expand || (!options.expand && options.type !== 'small')) {
508 |                 if (options.showHeadline && scope.headline) {
509 |                   headline = scope.headline;
510 |                 } else if (options.showHeadline && !scope.headline && article.find('h1').length > 0) {
511 |                   headline = angular.element(article.find('h1')[0]).html();
512 |                   expandOnHeadline = false;
513 |                 } else {
514 |                   headline = false;
515 |                 }
516 |  
517 |                 scope.headline = (headline) ? headline : null;
518 |               }
519 |  
520 |               updateSize();
521 |  
522 |               angular.element($window).on('scroll', updateProgress);
523 |               angular.element($window).on('resize', updateSize);
524 |             });
525 |           }
526 |  
527 |           function findEdges(elem) {
528 |             var bodyRect = document.body.getBoundingClientRect(),
529 |                 elemRect = elem.getBoundingClientRect();
530 |  
531 |             return {
532 |               top: (elemRect.top - bodyRect.top),
533 |               bottom: (elem.scrollHeight - window.innerHeight > 0 ) ? elem.scrollHeight - window.innerHeight : elem.scrollHeight,
534 |               height: elemRect.height
535 |             };
536 |           }
537 |  
538 |           function updateSize() {
539 |             bottom = findEdges(article[0]).bottom;
540 |             top = findEdges(article[0]).top;
541 |             height = findEdges(article[0]).height;
542 |             expandOffset = (expandOnHeadline) ? findEdges(article.find('h1')[0]) : {top: 50};
543 |             updateProgress();
544 |           }
545 |  
546 |           function updateProgress() {
547 |             var scrollPos = angular.element($window)[0].scrollY || angular.element($window)[0].pageYOffset;
548 |  
549 |             if (article[0].scrollHeight - window.innerHeight > 0) {
550 |               progress = (scrollPos <= top) ? 0 : ((scrollPos-top) / bottom) * 100;
551 |             } else {
552 |               progress = (scrollPos <= top) ? 0 : (((scrollPos-top)+((top + bottom) - (document.body.offsetHeight - window.innerHeight))) / bottom) * 100;
553 |             }
554 |  
555 |             if (options.readingTime.enable) {
556 |               scope.$apply( function(){
557 |                 scope.readingTime = calculateReadingTime();
558 |               });
559 |             } else {
560 |               scope.readingTime = null;
561 |             }
562 |  
563 |             progressBar.style.width = progress + '%';
564 |             if ((!options.expand && options.type === 'small' && scrollPos >= (top + expandOffset.top + options.topOffset)) || (options.expand && scrollPos > top && scrollPos < (top + expandOffset.top + options.topOffset))) {
565 |               angular.element(element)[0].style.height = '5px';
566 |               angular.element(element).addClass('ng-reading-indicator-shrink');
567 |               angular.element(element).removeClass('ng-reading-indicator-expanded');
568 |             } else if (((!options.expand && options.type === 'big') || options.expand) && scrollPos >= (top + expandOffset.top + options.topOffset)) {
569 |               angular.element(element).removeClass('ng-reading-indicator-shrink');
570 |               angular.element(element).addClass('ng-reading-indicator-expanded');
571 |               angular.element(element)[0].style.height = '';
572 |             } else {
573 |               angular.element(element)[0].style.height = '0';
574 |               angular.element(element).addClass('ng-reading-indicator-shrink');
575 |               angular.element(element).removeClass('ng-reading-indicator-expanded');
576 |             }
577 |           }
578 |  
579 |           function calculateReadingTime(){
580 |             var wordCount = article.text().split(' ').length;
581 |             var minutes = Math.floor(wordCount / options.readingTime.speed);
582 |             var seconds = Math.floor(wordCount % options.readingTime.speed / (options.readingTime.speed / 60));
583 |             var estimate = 	options.readingTime.prefix;
584 |  
585 |             if (!options.readingTime.seconds && seconds >= 30) {
586 |               minutes++;
587 |             }
588 |  
589 |             if (Math.floor((minutes <= 9 ? minutes + '0' : minutes) * (1 - (progress/100))) > 0 || !options.readingTime.seconds) {
590 |               estimate += Math.floor((minutes <= 9 ? minutes + '0' : minutes) * (1 - (progress/100)));
591 |               estimate += options.readingTime.minutesSuffix;
592 |             } else if (Math.floor((minutes <= 9 ? minutes + '0' : minutes) * (1 - (progress/100))) === 0 && options.readingTime.seconds) {
593 |               estimate += Math.round((((minutes <= 9 ? minutes + '0' : minutes)*60) * (1 - (progress/100))) / 10) * options.readingTime.secondInterval;
594 |               estimate += options.readingTime.secondsSuffix;
595 |             } else {
596 |               estimate += 0 + options.readingTime.secondsSuffix;
597 |             }
598 |  
599 |             return estimate;
600 |           }
601 |  
602 |           Iif (attributes.indicatorLazy && attributes.indicatorLazy !== '') {
603 |             scope.$watch('lazy', function(newVal){
604 |               if (newVal !== '' || newVal.length > 0) {
605 |                 initizalize();
606 |               }
607 |             });
608 |           } else {
609 |             initizalize();
610 |           }
611 |  
612 |           scope.$on('$destroy', function () {
613 |             angular.element($window).off('scroll', updateProgress);
614 |             angular.element($window).off('resize', updateSize);
615 |           });
616 |         }
617 |       };
618 |     }
619 |   ]);
620 |  
621 | })(window.angular);
622 |  
624 | 625 |
626 | 629 | 630 | 637 | 638 | 639 | 640 | -------------------------------------------------------------------------------- /coverage/Chrome 43.0.2357 (Mac OS X 10.10.3)/lcov.info: -------------------------------------------------------------------------------- 1 | TN: 2 | SF:./src/ng-reading-indicator.js 3 | FN:1,(anonymous_1) 4 | FN:8,(anonymous_2) 5 | FN:24,(anonymous_3) 6 | FN:27,(anonymous_4) 7 | FN:54,extendDeep 8 | FN:55,(anonymous_6) 9 | FN:57,(anonymous_7) 10 | FN:82,initizalize 11 | FN:83,(anonymous_9) 12 | FN:104,findEdges 13 | FN:115,updateSize 14 | FN:123,updateProgress 15 | FN:133,(anonymous_13) 16 | FN:156,calculateReadingTime 17 | FN:180,(anonymous_15) 18 | FN:189,(anonymous_16) 19 | FNF:16 20 | FNH:8 21 | FNDA:1,(anonymous_1) 22 | FNDA:3,(anonymous_2) 23 | FNDA:3,(anonymous_3) 24 | FNDA:3,(anonymous_4) 25 | FNDA:3,extendDeep 26 | FNDA:6,(anonymous_6) 27 | FNDA:1,(anonymous_7) 28 | FNDA:3,initizalize 29 | FNDA:0,(anonymous_9) 30 | FNDA:0,findEdges 31 | FNDA:0,updateSize 32 | FNDA:0,updateProgress 33 | FNDA:0,(anonymous_13) 34 | FNDA:0,calculateReadingTime 35 | FNDA:0,(anonymous_15) 36 | FNDA:0,(anonymous_16) 37 | DA:1,1 38 | DA:4,1 39 | DA:6,1 40 | DA:10,3 41 | DA:12,3 42 | DA:14,3 43 | DA:16,3 44 | DA:25,3 45 | DA:28,3 46 | DA:54,1 47 | DA:55,3 48 | DA:56,6 49 | DA:57,3 50 | DA:58,1 51 | DA:59,0 52 | DA:62,1 53 | DA:67,3 54 | DA:70,3 55 | DA:72,3 56 | DA:73,0 57 | DA:74,3 58 | DA:75,0 59 | DA:78,3 60 | DA:79,3 61 | DA:80,3 62 | DA:82,1 63 | DA:83,3 64 | DA:84,0 65 | DA:85,0 66 | DA:86,0 67 | DA:87,0 68 | DA:88,0 69 | DA:89,0 70 | DA:91,0 71 | DA:94,0 72 | DA:97,0 73 | DA:99,0 74 | DA:100,0 75 | DA:104,1 76 | DA:105,0 77 | DA:108,0 78 | DA:115,1 79 | DA:116,0 80 | DA:117,0 81 | DA:118,0 82 | DA:119,0 83 | DA:120,0 84 | DA:123,1 85 | DA:124,0 86 | DA:126,0 87 | DA:127,0 88 | DA:129,0 89 | DA:132,0 90 | DA:133,0 91 | DA:134,0 92 | DA:137,0 93 | DA:140,0 94 | DA:141,0 95 | DA:142,0 96 | DA:143,0 97 | DA:144,0 98 | DA:145,0 99 | DA:146,0 100 | DA:147,0 101 | DA:148,0 102 | DA:150,0 103 | DA:151,0 104 | DA:152,0 105 | DA:156,1 106 | DA:157,0 107 | DA:158,0 108 | DA:159,0 109 | DA:160,0 110 | DA:162,0 111 | DA:163,0 112 | DA:166,0 113 | DA:167,0 114 | DA:168,0 115 | DA:169,0 116 | DA:170,0 117 | DA:171,0 118 | DA:173,0 119 | DA:176,0 120 | DA:179,3 121 | DA:180,0 122 | DA:181,0 123 | DA:182,0 124 | DA:186,3 125 | DA:189,3 126 | DA:190,0 127 | DA:191,0 128 | LF:91 129 | LH:31 130 | BRDA:25,1,0,3 131 | BRDA:25,1,1,3 132 | BRDA:56,2,0,3 133 | BRDA:56,2,1,3 134 | BRDA:58,3,0,0 135 | BRDA:58,3,1,1 136 | BRDA:58,4,0,1 137 | BRDA:58,4,1,1 138 | BRDA:58,4,2,1 139 | BRDA:72,5,0,0 140 | BRDA:72,5,1,3 141 | BRDA:72,6,0,3 142 | BRDA:72,6,1,0 143 | BRDA:74,7,0,0 144 | BRDA:74,7,1,3 145 | BRDA:74,8,0,3 146 | BRDA:74,8,1,0 147 | BRDA:78,9,0,3 148 | BRDA:78,9,1,0 149 | BRDA:78,10,0,3 150 | BRDA:78,10,1,0 151 | BRDA:79,11,0,3 152 | BRDA:79,11,1,0 153 | BRDA:79,12,0,3 154 | BRDA:79,12,1,0 155 | BRDA:84,13,0,0 156 | BRDA:84,13,1,0 157 | BRDA:84,14,0,0 158 | BRDA:84,14,1,0 159 | BRDA:84,14,2,0 160 | BRDA:85,15,0,0 161 | BRDA:85,15,1,0 162 | BRDA:85,16,0,0 163 | BRDA:85,16,1,0 164 | BRDA:87,17,0,0 165 | BRDA:87,17,1,0 166 | BRDA:87,18,0,0 167 | BRDA:87,18,1,0 168 | BRDA:87,18,2,0 169 | BRDA:94,19,0,0 170 | BRDA:94,19,1,0 171 | BRDA:110,20,0,0 172 | BRDA:110,20,1,0 173 | BRDA:119,21,0,0 174 | BRDA:119,21,1,0 175 | BRDA:124,22,0,0 176 | BRDA:124,22,1,0 177 | BRDA:126,23,0,0 178 | BRDA:126,23,1,0 179 | BRDA:127,24,0,0 180 | BRDA:127,24,1,0 181 | BRDA:129,25,0,0 182 | BRDA:129,25,1,0 183 | BRDA:132,26,0,0 184 | BRDA:132,26,1,0 185 | BRDA:141,27,0,0 186 | BRDA:141,27,1,0 187 | BRDA:141,28,0,0 188 | BRDA:141,28,1,0 189 | BRDA:141,28,2,0 190 | BRDA:141,28,3,0 191 | BRDA:141,28,4,0 192 | BRDA:141,28,5,0 193 | BRDA:145,29,0,0 194 | BRDA:145,29,1,0 195 | BRDA:145,30,0,0 196 | BRDA:145,30,1,0 197 | BRDA:145,30,2,0 198 | BRDA:145,30,3,0 199 | BRDA:162,31,0,0 200 | BRDA:162,31,1,0 201 | BRDA:162,32,0,0 202 | BRDA:162,32,1,0 203 | BRDA:166,33,0,0 204 | BRDA:166,33,1,0 205 | BRDA:166,34,0,0 206 | BRDA:166,34,1,0 207 | BRDA:166,35,0,0 208 | BRDA:166,35,1,0 209 | BRDA:167,36,0,0 210 | BRDA:167,36,1,0 211 | BRDA:169,37,0,0 212 | BRDA:169,37,1,0 213 | BRDA:169,38,0,0 214 | BRDA:169,38,1,0 215 | BRDA:169,39,0,0 216 | BRDA:169,39,1,0 217 | BRDA:170,40,0,0 218 | BRDA:170,40,1,0 219 | BRDA:179,41,0,0 220 | BRDA:179,41,1,3 221 | BRDA:179,42,0,3 222 | BRDA:179,42,1,0 223 | BRDA:181,43,0,0 224 | BRDA:181,43,1,0 225 | BRDA:181,44,0,0 226 | BRDA:181,44,1,0 227 | BRF:97 228 | BRH:18 229 | end_of_record 230 | -------------------------------------------------------------------------------- /coverage/PhantomJS 1.9.8 (Mac OS X 0.0.0)/lcov-report/base.css: -------------------------------------------------------------------------------- 1 | body, html { 2 | margin:0; padding: 0; 3 | } 4 | body { 5 | font-family: Helvetica Neue, Helvetica,Arial; 6 | font-size: 10pt; 7 | } 8 | div.header, div.footer { 9 | background: #eee; 10 | padding: 1em; 11 | } 12 | div.header { 13 | z-index: 100; 14 | position: fixed; 15 | top: 0; 16 | border-bottom: 1px solid #666; 17 | width: 100%; 18 | } 19 | div.footer { 20 | border-top: 1px solid #666; 21 | } 22 | div.body { 23 | margin-top: 10em; 24 | } 25 | div.meta { 26 | font-size: 90%; 27 | text-align: center; 28 | } 29 | h1, h2, h3 { 30 | font-weight: normal; 31 | } 32 | h1 { 33 | font-size: 12pt; 34 | } 35 | h2 { 36 | font-size: 10pt; 37 | } 38 | pre { 39 | font-family: Consolas, Menlo, Monaco, monospace; 40 | margin: 0; 41 | padding: 0; 42 | line-height: 14px; 43 | font-size: 14px; 44 | -moz-tab-size: 2; 45 | -o-tab-size: 2; 46 | tab-size: 2; 47 | } 48 | 49 | div.path { font-size: 110%; } 50 | div.path a:link, div.path a:visited { color: #000; } 51 | table.coverage { border-collapse: collapse; margin:0; padding: 0 } 52 | 53 | table.coverage td { 54 | margin: 0; 55 | padding: 0; 56 | color: #111; 57 | vertical-align: top; 58 | } 59 | table.coverage td.line-count { 60 | width: 50px; 61 | text-align: right; 62 | padding-right: 5px; 63 | } 64 | table.coverage td.line-coverage { 65 | color: #777 !important; 66 | text-align: right; 67 | border-left: 1px solid #666; 68 | border-right: 1px solid #666; 69 | } 70 | 71 | table.coverage td.text { 72 | } 73 | 74 | table.coverage td span.cline-any { 75 | display: inline-block; 76 | padding: 0 5px; 77 | width: 40px; 78 | } 79 | table.coverage td span.cline-neutral { 80 | background: #eee; 81 | } 82 | table.coverage td span.cline-yes { 83 | background: #b5d592; 84 | color: #999; 85 | } 86 | table.coverage td span.cline-no { 87 | background: #fc8c84; 88 | } 89 | 90 | .cstat-yes { color: #111; } 91 | .cstat-no { background: #fc8c84; color: #111; } 92 | .fstat-no { background: #ffc520; color: #111 !important; } 93 | .cbranch-no { background: yellow !important; color: #111; } 94 | 95 | .cstat-skip { background: #ddd; color: #111; } 96 | .fstat-skip { background: #ddd; color: #111 !important; } 97 | .cbranch-skip { background: #ddd !important; color: #111; } 98 | 99 | .missing-if-branch { 100 | display: inline-block; 101 | margin-right: 10px; 102 | position: relative; 103 | padding: 0 4px; 104 | background: black; 105 | color: yellow; 106 | } 107 | 108 | .skip-if-branch { 109 | display: none; 110 | margin-right: 10px; 111 | position: relative; 112 | padding: 0 4px; 113 | background: #ccc; 114 | color: white; 115 | } 116 | 117 | .missing-if-branch .typ, .skip-if-branch .typ { 118 | color: inherit !important; 119 | } 120 | 121 | .entity, .metric { font-weight: bold; } 122 | .metric { display: inline-block; border: 1px solid #333; padding: 0.3em; background: white; } 123 | .metric small { font-size: 80%; font-weight: normal; color: #666; } 124 | 125 | div.coverage-summary table { border-collapse: collapse; margin: 3em; font-size: 110%; } 126 | div.coverage-summary td, div.coverage-summary table th { margin: 0; padding: 0.25em 1em; border-top: 1px solid #666; border-bottom: 1px solid #666; } 127 | div.coverage-summary th { text-align: left; border: 1px solid #666; background: #eee; font-weight: normal; } 128 | div.coverage-summary th.file { border-right: none !important; } 129 | div.coverage-summary th.pic { border-left: none !important; text-align: right; } 130 | div.coverage-summary th.pct { border-right: none !important; } 131 | div.coverage-summary th.abs { border-left: none !important; text-align: right; } 132 | div.coverage-summary td.pct { text-align: right; border-left: 1px solid #666; } 133 | div.coverage-summary td.abs { text-align: right; font-size: 90%; color: #444; border-right: 1px solid #666; } 134 | div.coverage-summary td.file { border-left: 1px solid #666; white-space: nowrap; } 135 | div.coverage-summary td.pic { min-width: 120px !important; } 136 | div.coverage-summary a:link { text-decoration: none; color: #000; } 137 | div.coverage-summary a:visited { text-decoration: none; color: #777; } 138 | div.coverage-summary a:hover { text-decoration: underline; } 139 | div.coverage-summary tfoot td { border-top: 1px solid #666; } 140 | 141 | div.coverage-summary .sorter { 142 | height: 10px; 143 | width: 7px; 144 | display: inline-block; 145 | margin-left: 0.5em; 146 | background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; 147 | } 148 | div.coverage-summary .sorted .sorter { 149 | background-position: 0 -20px; 150 | } 151 | div.coverage-summary .sorted-desc .sorter { 152 | background-position: 0 -10px; 153 | } 154 | 155 | .high { background: #b5d592 !important; } 156 | .medium { background: #ffe87c !important; } 157 | .low { background: #fc8c84 !important; } 158 | 159 | span.cover-fill, span.cover-empty { 160 | display:inline-block; 161 | border:1px solid #444; 162 | background: white; 163 | height: 12px; 164 | } 165 | span.cover-fill { 166 | background: #ccc; 167 | border-right: 1px solid #444; 168 | } 169 | span.cover-empty { 170 | background: white; 171 | border-left: none; 172 | } 173 | span.cover-full { 174 | border-right: none !important; 175 | } 176 | pre.prettyprint { 177 | border: none !important; 178 | padding: 0 !important; 179 | margin: 0 !important; 180 | } 181 | .com { color: #999 !important; } 182 | .ignore-none { color: #999; font-weight: normal; } 183 | -------------------------------------------------------------------------------- /coverage/PhantomJS 1.9.8 (Mac OS X 0.0.0)/lcov-report/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Code coverage report for All files 5 | 6 | 7 | 8 | 13 | 14 | 15 |
16 |

Code coverage report for All files

17 |

18 | Statements: 35.71% (35 / 98)      19 | Branches: 28.26% (26 / 92)      20 | Functions: 50% (8 / 16)      21 | Lines: 35.71% (35 / 98)      22 | Ignored: none      23 |

24 |
25 |
26 |
27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 |
FileStatementsBranchesFunctionsLines
src/35.71%(35 / 98)28.26%(26 / 92)50%(8 / 16)35.71%(35 / 98)
58 |
59 |
60 | 63 | 64 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /coverage/PhantomJS 1.9.8 (Mac OS X 0.0.0)/lcov-report/prettify.css: -------------------------------------------------------------------------------- 1 | .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} 2 | -------------------------------------------------------------------------------- /coverage/PhantomJS 1.9.8 (Mac OS X 0.0.0)/lcov-report/prettify.js: -------------------------------------------------------------------------------- 1 | window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); 2 | -------------------------------------------------------------------------------- /coverage/PhantomJS 1.9.8 (Mac OS X 0.0.0)/lcov-report/sort-arrow-sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dominicrico/angular-reading-indicator/4da42d100bfec62a2954ffb61b856d2224bdb826/coverage/PhantomJS 1.9.8 (Mac OS X 0.0.0)/lcov-report/sort-arrow-sprite.png -------------------------------------------------------------------------------- /coverage/PhantomJS 1.9.8 (Mac OS X 0.0.0)/lcov-report/sorter.js: -------------------------------------------------------------------------------- 1 | var addSorting = (function () { 2 | "use strict"; 3 | var cols, 4 | currentSort = { 5 | index: 0, 6 | desc: false 7 | }; 8 | 9 | // returns the summary table element 10 | function getTable() { return document.querySelector('.coverage-summary table'); } 11 | // returns the thead element of the summary table 12 | function getTableHeader() { return getTable().querySelector('thead tr'); } 13 | // returns the tbody element of the summary table 14 | function getTableBody() { return getTable().querySelector('tbody'); } 15 | // returns the th element for nth column 16 | function getNthColumn(n) { return getTableHeader().querySelectorAll('th')[n]; } 17 | 18 | // loads all columns 19 | function loadColumns() { 20 | var colNodes = getTableHeader().querySelectorAll('th'), 21 | colNode, 22 | cols = [], 23 | col, 24 | i; 25 | 26 | for (i = 0; i < colNodes.length; i += 1) { 27 | colNode = colNodes[i]; 28 | col = { 29 | key: colNode.getAttribute('data-col'), 30 | sortable: !colNode.getAttribute('data-nosort'), 31 | type: colNode.getAttribute('data-type') || 'string' 32 | }; 33 | cols.push(col); 34 | if (col.sortable) { 35 | col.defaultDescSort = col.type === 'number'; 36 | colNode.innerHTML = colNode.innerHTML + ''; 37 | } 38 | } 39 | return cols; 40 | } 41 | // attaches a data attribute to every tr element with an object 42 | // of data values keyed by column name 43 | function loadRowData(tableRow) { 44 | var tableCols = tableRow.querySelectorAll('td'), 45 | colNode, 46 | col, 47 | data = {}, 48 | i, 49 | val; 50 | for (i = 0; i < tableCols.length; i += 1) { 51 | colNode = tableCols[i]; 52 | col = cols[i]; 53 | val = colNode.getAttribute('data-value'); 54 | if (col.type === 'number') { 55 | val = Number(val); 56 | } 57 | data[col.key] = val; 58 | } 59 | return data; 60 | } 61 | // loads all row data 62 | function loadData() { 63 | var rows = getTableBody().querySelectorAll('tr'), 64 | i; 65 | 66 | for (i = 0; i < rows.length; i += 1) { 67 | rows[i].data = loadRowData(rows[i]); 68 | } 69 | } 70 | // sorts the table using the data for the ith column 71 | function sortByIndex(index, desc) { 72 | var key = cols[index].key, 73 | sorter = function (a, b) { 74 | a = a.data[key]; 75 | b = b.data[key]; 76 | return a < b ? -1 : a > b ? 1 : 0; 77 | }, 78 | finalSorter = sorter, 79 | tableBody = document.querySelector('.coverage-summary tbody'), 80 | rowNodes = tableBody.querySelectorAll('tr'), 81 | rows = [], 82 | i; 83 | 84 | if (desc) { 85 | finalSorter = function (a, b) { 86 | return -1 * sorter(a, b); 87 | }; 88 | } 89 | 90 | for (i = 0; i < rowNodes.length; i += 1) { 91 | rows.push(rowNodes[i]); 92 | tableBody.removeChild(rowNodes[i]); 93 | } 94 | 95 | rows.sort(finalSorter); 96 | 97 | for (i = 0; i < rows.length; i += 1) { 98 | tableBody.appendChild(rows[i]); 99 | } 100 | } 101 | // removes sort indicators for current column being sorted 102 | function removeSortIndicators() { 103 | var col = getNthColumn(currentSort.index), 104 | cls = col.className; 105 | 106 | cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); 107 | col.className = cls; 108 | } 109 | // adds sort indicators for current column being sorted 110 | function addSortIndicators() { 111 | getNthColumn(currentSort.index).className += currentSort.desc ? ' sorted-desc' : ' sorted'; 112 | } 113 | // adds event listeners for all sorter widgets 114 | function enableUI() { 115 | var i, 116 | el, 117 | ithSorter = function ithSorter(i) { 118 | var col = cols[i]; 119 | 120 | return function () { 121 | var desc = col.defaultDescSort; 122 | 123 | if (currentSort.index === i) { 124 | desc = !currentSort.desc; 125 | } 126 | sortByIndex(i, desc); 127 | removeSortIndicators(); 128 | currentSort.index = i; 129 | currentSort.desc = desc; 130 | addSortIndicators(); 131 | }; 132 | }; 133 | for (i =0 ; i < cols.length; i += 1) { 134 | if (cols[i].sortable) { 135 | el = getNthColumn(i).querySelector('.sorter'); 136 | if (el.addEventListener) { 137 | el.addEventListener('click', ithSorter(i)); 138 | } else { 139 | el.attachEvent('onclick', ithSorter(i)); 140 | } 141 | } 142 | } 143 | } 144 | // adds sorting functionality to the UI 145 | return function () { 146 | if (!getTable()) { 147 | return; 148 | } 149 | cols = loadColumns(); 150 | loadData(cols); 151 | addSortIndicators(); 152 | enableUI(); 153 | }; 154 | })(); 155 | 156 | window.addEventListener('load', addSorting); 157 | -------------------------------------------------------------------------------- /coverage/PhantomJS 1.9.8 (Mac OS X 0.0.0)/lcov-report/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Code coverage report for src/ 5 | 6 | 7 | 8 | 13 | 14 | 15 |
16 |

Code coverage report for src/

17 |

18 | Statements: 35.71% (35 / 98)      19 | Branches: 28.26% (26 / 92)      20 | Functions: 50% (8 / 16)      21 | Lines: 35.71% (35 / 98)      22 | Ignored: none      23 |

24 |
All files » src/
25 |
26 |
27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 |
FileStatementsBranchesFunctionsLines
ng-reading-indicator.js35.71%(35 / 98)28.26%(26 / 92)50%(8 / 16)35.71%(35 / 98)
58 |
59 |
60 | 63 | 64 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /coverage/PhantomJS 1.9.8 (Mac OS X 0.0.0)/lcov-report/src/ng-reading-indicator.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Code coverage report for src/ng-reading-indicator.js 5 | 6 | 7 | 8 | 13 | 14 | 15 |
16 |

Code coverage report for src/ng-reading-indicator.js

17 |

18 | Statements: 35.71% (35 / 98)      19 | Branches: 28.26% (26 / 92)      20 | Functions: 50% (8 / 16)      21 | Lines: 35.71% (35 / 98)      22 | Ignored: none      23 |

24 |
All files » src/ » ng-reading-indicator.js
25 |
26 |
27 |

 28 | 
659 | 
1 29 | 2 30 | 3 31 | 4 32 | 5 33 | 6 34 | 7 35 | 8 36 | 9 37 | 10 38 | 11 39 | 12 40 | 13 41 | 14 42 | 15 43 | 16 44 | 17 45 | 18 46 | 19 47 | 20 48 | 21 49 | 22 50 | 23 51 | 24 52 | 25 53 | 26 54 | 27 55 | 28 56 | 29 57 | 30 58 | 31 59 | 32 60 | 33 61 | 34 62 | 35 63 | 36 64 | 37 65 | 38 66 | 39 67 | 40 68 | 41 69 | 42 70 | 43 71 | 44 72 | 45 73 | 46 74 | 47 75 | 48 76 | 49 77 | 50 78 | 51 79 | 52 80 | 53 81 | 54 82 | 55 83 | 56 84 | 57 85 | 58 86 | 59 87 | 60 88 | 61 89 | 62 90 | 63 91 | 64 92 | 65 93 | 66 94 | 67 95 | 68 96 | 69 97 | 70 98 | 71 99 | 72 100 | 73 101 | 74 102 | 75 103 | 76 104 | 77 105 | 78 106 | 79 107 | 80 108 | 81 109 | 82 110 | 83 111 | 84 112 | 85 113 | 86 114 | 87 115 | 88 116 | 89 117 | 90 118 | 91 119 | 92 120 | 93 121 | 94 122 | 95 123 | 96 124 | 97 125 | 98 126 | 99 127 | 100 128 | 101 129 | 102 130 | 103 131 | 104 132 | 105 133 | 106 134 | 107 135 | 108 136 | 109 137 | 110 138 | 111 139 | 112 140 | 113 141 | 114 142 | 115 143 | 116 144 | 117 145 | 118 146 | 119 147 | 120 148 | 121 149 | 122 150 | 123 151 | 124 152 | 125 153 | 126 154 | 127 155 | 128 156 | 129 157 | 130 158 | 131 159 | 132 160 | 133 161 | 134 162 | 135 163 | 136 164 | 137 165 | 138 166 | 139 167 | 140 168 | 141 169 | 142 170 | 143 171 | 144 172 | 145 173 | 146 174 | 147 175 | 148 176 | 149 177 | 150 178 | 151 179 | 152 180 | 153 181 | 154 182 | 155 183 | 156 184 | 157 185 | 158 186 | 159 187 | 160 188 | 161 189 | 162 190 | 163 191 | 164 192 | 165 193 | 166 194 | 167 195 | 168 196 | 169 197 | 170 198 | 171 199 | 172 200 | 173 201 | 174 202 | 175 203 | 176 204 | 177 205 | 178 206 | 179 207 | 180 208 | 181 209 | 182 210 | 183 211 | 184 212 | 185 213 | 186 214 | 187 215 | 188 216 | 189 217 | 190 218 | 191 219 | 192 220 | 193 221 | 194 222 | 195 223 | 196 224 | 197 225 | 198 226 | 199 227 | 200 228 | 201 229 | 202 230 | 203 231 | 204 232 | 205 233 | 206 234 | 207 235 | 208 236 | 209 237 | 210 238 | 2111 239 |   240 |   241 | 1 242 |   243 | 1 244 |   245 |   246 |   247 | 4 248 |   249 | 4 250 |   251 | 4 252 |   253 | 4 254 |   255 |   256 |   257 |   258 |   259 |   260 |   261 |   262 | 4 263 |   264 |   265 | 4 266 |   267 |   268 |   269 |   270 |   271 |   272 |   273 |   274 |   275 |   276 |   277 |   278 |   279 |   280 |   281 |   282 |   283 |   284 |   285 |   286 |   287 |   288 |   289 |   290 |   291 |   292 | 1 293 | 4 294 | 8 295 | 4 296 | 5 297 |   298 |   299 |   300 | 5 301 |   302 |   303 |   304 |   305 | 4 306 |   307 |   308 | 4 309 |   310 | 4 311 | 4 312 |   313 |   314 | 4 315 | 1 316 | 3 317 | 1 318 |   319 |   320 | 4 321 | 4 322 | 4 323 |   324 | 1 325 | 4 326 |   327 |   328 |   329 |   330 |   331 |   332 |   333 |   334 |   335 |   336 |   337 |   338 |   339 |   340 |   341 |   342 |   343 |   344 |   345 |   346 |   347 |   348 | 1 349 |   350 |   351 |   352 |   353 |   354 |   355 |   356 |   357 |   358 |   359 | 1 360 |   361 |   362 |   363 |   364 |   365 |   366 |   367 | 1 368 |   369 |   370 |   371 |   372 |   373 |   374 |   375 |   376 |   377 |   378 |   379 |   380 |   381 |   382 |   383 |   384 |   385 |   386 |   387 |   388 |   389 |   390 |   391 |   392 |   393 |   394 |   395 |   396 |   397 |   398 |   399 |   400 |   401 |   402 |   403 |   404 | 1 405 |   406 |   407 |   408 |   409 |   410 |   411 |   412 |   413 |   414 |   415 |   416 |   417 |   418 |   419 |   420 |   421 |   422 |   423 |   424 |   425 |   426 |   427 |   428 | 4 429 |   430 |   431 |   432 |   433 |   434 |   435 | 4 436 |   437 |   438 | 4 439 |   440 |   441 |   442 |   443 |   444 |   445 |   446 |   447 |   448 |  
(function(angular, undefined){
449 |   'use strict';
450 |  
451 |   var ngReadingIndicator = angular.module('ngReadingIndicator', ['ngSanitize']);
452 |  
453 |   ngReadingIndicator.directive('ngReadingIndicator', [
454 |     '$window', '$document', '$templateCache', '$sce', '$timeout',
455 |     function($window, $document, $templateCache, $sce, $timeout) {
456 |  
457 |       var TEMPLATE_URL = '';
458 |  
459 |       var template ='<div class="ng-reading-indicator-progress"></div><div class="ng-reading-indicator-headline"><h2 ng-bind-html="headline"></h2></div><div class="ng-reading-indicator-time" ng-if="readingTime"> {{ readingTime }}</div>';
460 |  
461 |       $templateCache.put(TEMPLATE_URL, template);
462 |  
463 |       return {
464 |         restrict: 'AE',
465 |         scope: {
466 |           elementClass: '@indicatorElement',
467 |           userOptions: '&indicatorOptions',
468 |           headline: '=?indicatorHeadline',
469 |           lazy: '=?indicatorLazy'
470 |         },
471 |         templateUrl: function (element, attributes) {
472 |           return (attributes.indicatorTemplateUrl || TEMPLATE_URL);
473 |         },
474 |         link: function(scope, element, attributes) {
475 |           var headline = null,
476 |               article = null,
477 |               bottom = null,
478 |               top = null,
479 |               height = null,
480 |               progress = null,
481 |               progressBar = null,
482 |               elem = null,
483 |               expandOffset = null,
484 |               expandOnHeadline = false,
485 |               options = {
486 |                 calcFrom: 'middle',
487 |                 showHeadline: true,
488 |                 expand: true,
489 |                 type: 'small',
490 |                 topOffset: 150,
491 |                 readingTime: {
492 |                   enable: true,
493 |                   prefix: 'remaining estimate ',
494 |                   minutesSuffix: 'min',
495 |                   secondsSuffix: 'sec',
496 |                   speed: 150,
497 |                   seconds: true,
498 |                   secondInterval: 5
499 |                 }
500 |               };
501 |  
502 |           function extendDeep(dst) {
503 |             angular.forEach(arguments, function (obj) {
504 |               if (obj !== dst) {
505 |                 angular.forEach(obj, function (value, key) {
506 |                   Iif (dst[key] && dst[key].constructor && dst[key].constructor === Object) {
507 |                     extendDeep(dst[key], value);
508 |                   }
509 |                   else {
510 |                     dst[key] = value;
511 |                   }
512 |                 });
513 |               }
514 |             });
515 |             return dst;
516 |           }
517 |  
518 |           extendDeep(options, scope.userOptions());
519 |  
520 |           Eif (options.calcFrom !== 'bottom' && options.calcFrom !== 'top' && options.calcFrom !== 'bottom') {
521 |             options.calcFrom = 'middle';
522 |           }
523 |  
524 |           if (!options.expand && options.type !== 'small') {
525 |             angular.element(element).addClass('ng-reading-indicator-expanded');
526 |           } else if (!options.expand && options.type !== 'big') {
527 |             angular.element(element).addClass('ng-reading-indicator-shrink');
528 |           }
529 |  
530 |           elem = (!scope.elementClass || scope.elementClass === '') ? $window : scope.elementClass;
531 |           article = (!scope.elementClass || scope.elementClass === '') ? angular.element(document.body) : angular.element(document.getElementsByClassName(elem.replace('.', ''))[0]);
532 |           progressBar = document.getElementsByClassName('ng-reading-indicator-progress')[0];
533 |  
534 |           function initizalize() {
535 |             $timeout(function(){
536 |               if (options.expand || (!options.expand && options.type !== 'small')) {
537 |                 if (options.showHeadline && scope.headline) {
538 |                   headline = scope.headline;
539 |                 } else if (options.showHeadline && !scope.headline && article.find('h1').length > 0) {
540 |                   headline = angular.element(article.find('h1')[0]).html();
541 |                   expandOnHeadline = false;
542 |                 } else {
543 |                   headline = false;
544 |                 }
545 |  
546 |                 scope.headline = (headline) ? headline : null;
547 |               } else {
548 |                 scope.headine = null;
549 |               }
550 |  
551 |               updateSize();
552 |  
553 |               angular.element($window).on('scroll', updateProgress);
554 |               angular.element($window).on('resize', updateSize);
555 |             });
556 |           }
557 |  
558 |           function findEdges(elem) {
559 |             var bodyRect = document.body.getBoundingClientRect(),
560 |                 elemRect = elem.getBoundingClientRect();
561 |  
562 |             return {
563 |               top: (elemRect.top - bodyRect.top),
564 |               bottom: (elem.scrollHeight - window.innerHeight > 0 ) ? elem.scrollHeight - window.innerHeight : elem.scrollHeight,
565 |               height: elemRect.height
566 |             };
567 |           }
568 |  
569 |           function updateSize() {
570 |             bottom = findEdges(article[0]).bottom;
571 |             top = findEdges(article[0]).top;
572 |             height = findEdges(article[0]).height;
573 |             expandOffset = (expandOnHeadline) ? findEdges(article.find('h1')[0]) : {top: 0};
574 |             updateProgress();
575 |           }
576 |  
577 |           function updateProgress() {
578 |             var scrollPos = angular.element($window)[0].scrollY || angular.element($window)[0].pageYOffset;
579 |             var origScrollPos = scrollPos;
580 |  
581 |             if (options.calcFrom === 'middle') {
582 |               scrollPos = origScrollPos + (window.innerHeight / 2);
583 |             } else if (options.calcFrom === 'bottom') {
584 |               scrollPos = origScrollPos + window.innerHeight;
585 |             }
586 |  
587 |             progress = (scrollPos <= top) ? 0 : ((scrollPos-top) / (article[0].offsetHeight)) * 100;
588 |  
589 |             if (options.readingTime.enable) {
590 |               scope.$apply( function(){
591 |                 scope.readingTime = calculateReadingTime();
592 |               });
593 |             } else {
594 |               scope.readingTime = null;
595 |             }
596 |  
597 |             progressBar.style.width = progress + '%';
598 |  
599 |             if ((!options.expand && options.type === 'small' && origScrollPos >= (top + expandOffset.top + options.topOffset)) || (options.expand && origScrollPos > top && origScrollPos < (top + expandOffset.top + options.topOffset))) {
600 |               angular.element(element)[0].style.height = '5px';
601 |               angular.element(element).addClass('ng-reading-indicator-shrink');
602 |               angular.element(element).removeClass('ng-reading-indicator-expanded');
603 |             } else if (((!options.expand && options.type === 'big') || options.expand) && origScrollPos >= (top + expandOffset.top + options.topOffset)) {
604 |               angular.element(element).removeClass('ng-reading-indicator-shrink');
605 |               angular.element(element).addClass('ng-reading-indicator-expanded');
606 |               angular.element(element)[0].style.height = '';
607 |             } else {
608 |               angular.element(element)[0].style.height = '0';
609 |               angular.element(element).addClass('ng-reading-indicator-shrink');
610 |               angular.element(element).removeClass('ng-reading-indicator-expanded');
611 |             }
612 |           }
613 |  
614 |           function calculateReadingTime(){
615 |             var wordCount = angular.element(article[0]).text().trim().split(' ').length;
616 |             var minutes = Math.floor(wordCount / options.readingTime.speed);
617 |             var seconds = Math.floor(wordCount % options.readingTime.speed / (options.readingTime.speed / 60));
618 |             var estimate = 	options.readingTime.prefix;
619 |  
620 |             if (seconds >= 30) {
621 |               minutes++;
622 |             }
623 |  
624 |             if (Math.floor(minutes * (1 - (progress/100))) > 0 || !options.readingTime.seconds) {
625 |               minutes = minutes * (1 - (progress/100));
626 |               estimate += Math.floor(minutes);
627 |               estimate += options.readingTime.minutesSuffix;
628 |             } else if (Math.floor(minutes * (1 - (progress/100))) === 0 && options.readingTime.seconds) {
629 |               estimate += Math.round((((minutes)*60) * (1 - (progress/100))) / 10) * options.readingTime.secondInterval;
630 |               estimate += options.readingTime.secondsSuffix;
631 |             } else {
632 |               estimate += 0 + options.readingTime.secondsSuffix;
633 |             }
634 |  
635 |             return estimate;
636 |           }
637 |  
638 |           Iif (attributes.indicatorLazy && attributes.indicatorLazy !== '') {
639 |             scope.$watch('lazy', function(newVal){
640 |               if (newVal !== '' || newVal.length > 0) {
641 |                 initizalize();
642 |               }
643 |             });
644 |           } else {
645 |             initizalize();
646 |           }
647 |  
648 |           scope.$on('$destroy', function () {
649 |             angular.element($window).off('scroll', updateProgress);
650 |             angular.element($window).off('resize', updateSize);
651 |           });
652 |         }
653 |       };
654 |     }
655 |   ]);
656 |  
657 | })(window.angular);
658 |  
660 | 661 |
662 | 665 | 666 | 673 | 674 | 675 | 676 | -------------------------------------------------------------------------------- /coverage/PhantomJS 1.9.8 (Mac OS X 0.0.0)/lcov.info: -------------------------------------------------------------------------------- 1 | TN: 2 | SF:./src/ng-reading-indicator.js 3 | FN:1,(anonymous_1) 4 | FN:8,(anonymous_2) 5 | FN:24,(anonymous_3) 6 | FN:27,(anonymous_4) 7 | FN:55,extendDeep 8 | FN:56,(anonymous_6) 9 | FN:58,(anonymous_7) 10 | FN:87,initizalize 11 | FN:88,(anonymous_9) 12 | FN:111,findEdges 13 | FN:122,updateSize 14 | FN:130,updateProgress 15 | FN:143,(anonymous_13) 16 | FN:167,calculateReadingTime 17 | FN:192,(anonymous_15) 18 | FN:201,(anonymous_16) 19 | FNF:16 20 | FNH:8 21 | FNDA:1,(anonymous_1) 22 | FNDA:4,(anonymous_2) 23 | FNDA:4,(anonymous_3) 24 | FNDA:4,(anonymous_4) 25 | FNDA:4,extendDeep 26 | FNDA:8,(anonymous_6) 27 | FNDA:5,(anonymous_7) 28 | FNDA:4,initizalize 29 | FNDA:0,(anonymous_9) 30 | FNDA:0,findEdges 31 | FNDA:0,updateSize 32 | FNDA:0,updateProgress 33 | FNDA:0,(anonymous_13) 34 | FNDA:0,calculateReadingTime 35 | FNDA:0,(anonymous_15) 36 | FNDA:0,(anonymous_16) 37 | DA:1,1 38 | DA:4,1 39 | DA:6,1 40 | DA:10,4 41 | DA:12,4 42 | DA:14,4 43 | DA:16,4 44 | DA:25,4 45 | DA:28,4 46 | DA:55,1 47 | DA:56,4 48 | DA:57,8 49 | DA:58,4 50 | DA:59,5 51 | DA:60,0 52 | DA:63,5 53 | DA:68,4 54 | DA:71,4 55 | DA:73,4 56 | DA:74,4 57 | DA:77,4 58 | DA:78,1 59 | DA:79,3 60 | DA:80,1 61 | DA:83,4 62 | DA:84,4 63 | DA:85,4 64 | DA:87,1 65 | DA:88,4 66 | DA:89,0 67 | DA:90,0 68 | DA:91,0 69 | DA:92,0 70 | DA:93,0 71 | DA:94,0 72 | DA:96,0 73 | DA:99,0 74 | DA:101,0 75 | DA:104,0 76 | DA:106,0 77 | DA:107,0 78 | DA:111,1 79 | DA:112,0 80 | DA:115,0 81 | DA:122,1 82 | DA:123,0 83 | DA:124,0 84 | DA:125,0 85 | DA:126,0 86 | DA:127,0 87 | DA:130,1 88 | DA:131,0 89 | DA:132,0 90 | DA:134,0 91 | DA:135,0 92 | DA:136,0 93 | DA:137,0 94 | DA:140,0 95 | DA:142,0 96 | DA:143,0 97 | DA:144,0 98 | DA:147,0 99 | DA:150,0 100 | DA:152,0 101 | DA:153,0 102 | DA:154,0 103 | DA:155,0 104 | DA:156,0 105 | DA:157,0 106 | DA:158,0 107 | DA:159,0 108 | DA:161,0 109 | DA:162,0 110 | DA:163,0 111 | DA:167,1 112 | DA:168,0 113 | DA:169,0 114 | DA:170,0 115 | DA:171,0 116 | DA:173,0 117 | DA:174,0 118 | DA:177,0 119 | DA:178,0 120 | DA:179,0 121 | DA:180,0 122 | DA:181,0 123 | DA:182,0 124 | DA:183,0 125 | DA:185,0 126 | DA:188,0 127 | DA:191,4 128 | DA:192,0 129 | DA:193,0 130 | DA:194,0 131 | DA:198,4 132 | DA:201,4 133 | DA:202,0 134 | DA:203,0 135 | LF:98 136 | LH:35 137 | BRDA:25,1,0,4 138 | BRDA:25,1,1,4 139 | BRDA:57,2,0,4 140 | BRDA:57,2,1,4 141 | BRDA:59,3,0,0 142 | BRDA:59,3,1,5 143 | BRDA:59,4,0,5 144 | BRDA:59,4,1,5 145 | BRDA:59,4,2,5 146 | BRDA:73,5,0,4 147 | BRDA:73,5,1,0 148 | BRDA:73,6,0,4 149 | BRDA:73,6,1,4 150 | BRDA:73,6,2,4 151 | BRDA:77,7,0,1 152 | BRDA:77,7,1,3 153 | BRDA:77,8,0,4 154 | BRDA:77,8,1,2 155 | BRDA:79,9,0,1 156 | BRDA:79,9,1,2 157 | BRDA:79,10,0,3 158 | BRDA:79,10,1,1 159 | BRDA:83,11,0,4 160 | BRDA:83,11,1,0 161 | BRDA:83,12,0,4 162 | BRDA:83,12,1,0 163 | BRDA:84,13,0,4 164 | BRDA:84,13,1,0 165 | BRDA:84,14,0,4 166 | BRDA:84,14,1,0 167 | BRDA:89,15,0,0 168 | BRDA:89,15,1,0 169 | BRDA:89,16,0,0 170 | BRDA:89,16,1,0 171 | BRDA:89,16,2,0 172 | BRDA:90,17,0,0 173 | BRDA:90,17,1,0 174 | BRDA:90,18,0,0 175 | BRDA:90,18,1,0 176 | BRDA:92,19,0,0 177 | BRDA:92,19,1,0 178 | BRDA:92,20,0,0 179 | BRDA:92,20,1,0 180 | BRDA:92,20,2,0 181 | BRDA:99,21,0,0 182 | BRDA:99,21,1,0 183 | BRDA:117,22,0,0 184 | BRDA:117,22,1,0 185 | BRDA:126,23,0,0 186 | BRDA:126,23,1,0 187 | BRDA:131,24,0,0 188 | BRDA:131,24,1,0 189 | BRDA:134,25,0,0 190 | BRDA:134,25,1,0 191 | BRDA:136,26,0,0 192 | BRDA:136,26,1,0 193 | BRDA:140,27,0,0 194 | BRDA:140,27,1,0 195 | BRDA:142,28,0,0 196 | BRDA:142,28,1,0 197 | BRDA:152,29,0,0 198 | BRDA:152,29,1,0 199 | BRDA:152,30,0,0 200 | BRDA:152,30,1,0 201 | BRDA:152,30,2,0 202 | BRDA:152,30,3,0 203 | BRDA:152,30,4,0 204 | BRDA:152,30,5,0 205 | BRDA:156,31,0,0 206 | BRDA:156,31,1,0 207 | BRDA:156,32,0,0 208 | BRDA:156,32,1,0 209 | BRDA:156,32,2,0 210 | BRDA:156,32,3,0 211 | BRDA:173,33,0,0 212 | BRDA:173,33,1,0 213 | BRDA:177,34,0,0 214 | BRDA:177,34,1,0 215 | BRDA:177,35,0,0 216 | BRDA:177,35,1,0 217 | BRDA:181,36,0,0 218 | BRDA:181,36,1,0 219 | BRDA:181,37,0,0 220 | BRDA:181,37,1,0 221 | BRDA:191,38,0,0 222 | BRDA:191,38,1,4 223 | BRDA:191,39,0,4 224 | BRDA:191,39,1,0 225 | BRDA:193,40,0,0 226 | BRDA:193,40,1,0 227 | BRDA:193,41,0,0 228 | BRDA:193,41,1,0 229 | BRF:92 230 | BRH:26 231 | end_of_record 232 | -------------------------------------------------------------------------------- /demo/app.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ngEmoticonApp Module 3 | * 4 | * Description 5 | */ 6 | angular.module('ngReadingIndicatorApp', ['ngReadingIndicator']) 7 | 8 | .controller('ngReadingIndicatorCtrl', ['$scope', '$timeout', function ($scope, $timeout) { 9 | $scope.myHeadline = 'ngReadingIndicator can show a different Headline!' 10 | 11 | $scope.options = {expand: false, type: 'big', calcFrom: 'middle'}; 12 | 13 | $timeout(function(){ 14 | $scope.text = 'At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.

Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus.

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At veroAt vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.

Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus.

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At veroAt vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.

Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus.

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At veroAt vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.

Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus.

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At veroAt vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.

Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus.

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero'; 15 | }, 2000) 16 | 17 | }]); 18 | -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ngReadingIndicator 7 | 8 | 9 | 26 | 27 | 28 |

29 | 30 |
31 |

Totaly useless Article

32 |

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.

33 |
34 | 35 |
36 |

ngReadingIndicator is just aweseome

37 | {{ text }} 38 |
39 |
40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /dist/ng-reading-indicator.min.css: -------------------------------------------------------------------------------- 1 | [ng-reading-indicator],ng-reading-indicator{position:fixed;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;width:100%;height:0;transition:height .15s ease-out;top:0;left:0;z-index:9999;background:rgba(19,146,176,.8);box-shadow:2px 2px 2px rgba(19,146,176,.5)}[ng-reading-indicator].ng-reading-indicator-expanded,ng-reading-indicator.ng-reading-indicator-expanded{height:auto;height:52px}[ng-reading-indicator].ng-reading-indicator-expanded .ng-reading-indicator-headline,[ng-reading-indicator].ng-reading-indicator-expanded .ng-reading-indicator-time,ng-reading-indicator.ng-reading-indicator-expanded .ng-reading-indicator-headline,ng-reading-indicator.ng-reading-indicator-expanded .ng-reading-indicator-time{-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-name:fadeIn;animation-name:fadeIn;display:inline-block}[ng-reading-indicator].ng-reading-indicator-shrink .ng-reading-indicator-headline,[ng-reading-indicator].ng-reading-indicator-shrink .ng-reading-indicator-time,ng-reading-indicator.ng-reading-indicator-shrink .ng-reading-indicator-headline,ng-reading-indicator.ng-reading-indicator-shrink .ng-reading-indicator-time{-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-name:fadeOut;animation-name:fadeOut;display:none}[ng-reading-indicator] .ng-reading-indicator-progress,ng-reading-indicator .ng-reading-indicator-progress{content:'';position:absolute;margin:auto;top:0;bottom:0;height:100%;z-index:-1;background:rgba(19,146,176,.9)}[ng-reading-indicator] .ng-reading-indicator-headline,ng-reading-indicator .ng-reading-indicator-headline{display:none}[ng-reading-indicator] .ng-reading-indicator-headline h2,ng-reading-indicator .ng-reading-indicator-headline h2{display:inline-block;padding:10px 30px;font-family:inherit;color:rgba(255,255,255,.85);margin:5px 0;font-size:24px}[ng-reading-indicator] .ng-reading-indicator-time,ng-reading-indicator .ng-reading-indicator-time{display:none;color:rgba(255,255,255,.85);font-weight:500;float:right;padding-right:30px;padding-left:10px;border-left:1px solid rgba(255,255,255,.85)}[ng-reading-indicator] .ng-reading-indicator-time:before,ng-reading-indicator .ng-reading-indicator-time:before{content:'';position:relative;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAvZJREFUeNqM1ltIVEEcx/Gzxw0spYguWl4qSQrEB3szosIuYiGmLxmFSWBXSAyMQigrSKiHiqTL9mJBBN2zEoIoQsieupmZ3a9mJRWbGUS2fUd+B6blrDrwWc7OOTszZ+b/n9lAJBJxBigTMQszMQWjVB/Ga7SgGe9jNRCI0cF4rEYRRjoDl59oRAidQ+lgLnYg2aozI36HbpgfjMGkqM7NvZ249l9rpgNLCdrRIY1YgkTdjxNzPQKFOG89byyz27TfYDaOwtX3QzigdViOOUgyb43PmvuTeIt1qNQ9UzZ6b+J1MBYXMU4P1OAsqrBGc3sLrZqiLHWYjgbUoRB7NMDvWr8u71VqrFesVN1BPMZSBFWXgnRruorRimOqq7DaqesfPB9JuKvKJj1YhSfIseYzE4/UabZVn4U2DdJ8v6C2HpgBuZr7BE1NSCG6Fttxz4qHFAxDHCZb9W3YgjKkoV718ch3lUSm/NDClPXPneOciQrfPuu6N+reZS12hRY/rPrcIB8Z+mIe+IU83MTfAZIrB38UNZ/QjiYt9G88xwykBq1k6dbrm0jq8Gk0aF1XiPdmRYqwFWrjo+4luH7bR4xRd2nU0cXVb/z2nEBQc+8o/c1oviDT52EzDaVa7Ig1EJMjT7FIc9+nhDSlx3TwCtOUNPGaf/PwLp9RtYpfKcBtRZo3wE5XlY7WYgFOYAJKnKGXAoVuSNu7t623mMRIxn0lxxUlS7U2veyozdDPdGVzrb6fU1sPkeY9VGul+AbVHVGGFls7qM3FYg2uQXXlVjt77d3UhOYlLbSp2KxDZCvK8QbX8Uz3p2KecugUak3WYp/CNKzQ7bS36zxt0V507MdhHSwrNbejde+bjsvjeIlVqLa2+k246nfglGqT817THCb5SLCmxdX1cMzH6agDpyzWgeOVhdhmnQ3ekflCB01EcZ5hRYspX7Fb+9Kgh74J0/XKh8RBQrRXm2S937+LwCB/W1K1Nrnair3OevABd3BDQeBb/gkwAL82fwDk50ljAAAAAElFTkSuQmCC);opacity:.85;display:inline-block;background-size:contain;width:12px;height:12px;top:1px}@-webkit-keyframes fadeIn{0%{display:none;opacity:0}1%{display:inline-block;opacity:0}100%{display:inline-block;opacity:1}}@keyframes fadeIn{0%{display:none;opacity:0}1%{display:inline-block;opacity:0}100%{display:inline-block;opacity:1}}@-webkit-keyframes fadeOut{0%,1%{display:inline-block;opacity:1}100%{display:none;opacity:0}}@keyframes fadeOut{0%,1%{display:inline-block;opacity:1}100%{display:none;opacity:0}} -------------------------------------------------------------------------------- /dist/ng-reading-indicator.min.js: -------------------------------------------------------------------------------- 1 | !function(a,b){"use strict";var c=a.module("ngReadingIndicator",["ngSanitize"]);c.directive("ngReadingIndicator",["$window","$document","$templateCache","$sce","$timeout",function(b,c,d,e,f){var g="",h='

{{ readingTime }}
';return d.put(g,h),{restrict:"AE",scope:{elementClass:"@indicatorElement",userOptions:"&indicatorOptions",headline:"=?indicatorHeadline",lazy:"=?indicatorLazy"},templateUrl:function(a,b){return b.indicatorTemplateUrl||g},link:function(c,d,e){function g(b){return a.forEach(arguments,function(c){c!==b&&a.forEach(c,function(a,c){b[c]&&b[c].constructor&&b[c].constructor===Object?g(b[c],a):b[c]=a})}),b}function h(){f(function(){w.expand||!w.expand&&"small"!==w.type?(w.showHeadline&&c.headline?m=c.headline:w.showHeadline&&!c.headline&&n.find("h1").length>0?(m=a.element(n.find("h1")[0]).html(),v=!1):m=!1,c.headline=m?m:null):c.headine=null,j(),a.element(b).on("scroll",k),a.element(b).on("resize",j)})}function i(a){var b=document.body.getBoundingClientRect(),c=a.getBoundingClientRect();return{top:c.top-b.top,bottom:a.scrollHeight-window.innerHeight>0?a.scrollHeight-window.innerHeight:a.scrollHeight,height:c.height}}function j(){o=i(n[0]).bottom,p=i(n[0]).top,q=i(n[0]).height,u=v?i(n.find("h1")[0]):{top:0},k()}function k(){var e=a.element(b)[0].scrollY||a.element(b)[0].pageYOffset,f=e;"middle"===w.calcFrom?e=f+window.innerHeight/2:"bottom"===w.calcFrom&&(e=f+window.innerHeight),r=p>=e?0:(e-p)/n[0].offsetHeight*100,w.readingTime.enable?c.$apply(function(){c.readingTime=l()}):c.readingTime=null,s.style.width=r+"%",!w.expand&&"small"===w.type&&f>=p+u.top+w.topOffset||w.expand&&f>p&&f=p+u.top+w.topOffset?(a.element(d).removeClass("ng-reading-indicator-shrink"),a.element(d).addClass("ng-reading-indicator-expanded"),a.element(d)[0].style.height=""):(a.element(d)[0].style.height="0",a.element(d).addClass("ng-reading-indicator-shrink"),a.element(d).removeClass("ng-reading-indicator-expanded"))}function l(){var b=a.element(n[0]).text().trim().split(" ").length,c=Math.floor(b/w.readingTime.speed),d=Math.floor(b%w.readingTime.speed/(w.readingTime.speed/60)),e=w.readingTime.prefix;return d>=30&&c++,Math.floor(c*(1-r/100))>0||!w.readingTime.seconds?(c*=1-r/100,e+=Math.floor(c),e+=w.readingTime.minutesSuffix):0===Math.floor(c*(1-r/100))&&w.readingTime.seconds?(e+=Math.round(60*c*(1-r/100)/10)*w.readingTime.secondInterval,e+=w.readingTime.secondsSuffix):e+=0+w.readingTime.secondsSuffix,e}var m=null,n=null,o=null,p=null,q=null,r=null,s=null,t=null,u=null,v=!1,w={calcFrom:"middle",showHeadline:!0,expand:!0,type:"small",topOffset:150,readingTime:{enable:!0,prefix:"remaining estimate ",minutesSuffix:"min",secondsSuffix:"sec",speed:150,seconds:!0,secondInterval:5}};g(w,c.userOptions()),"bottom"!==w.calcFrom&&"top"!==w.calcFrom&&"bottom"!==w.calcFrom&&(w.calcFrom="middle"),w.expand||"small"===w.type?w.expand||"big"===w.type||a.element(d).addClass("ng-reading-indicator-shrink"):a.element(d).addClass("ng-reading-indicator-expanded"),t=c.elementClass&&""!==c.elementClass?c.elementClass:b,n=c.elementClass&&""!==c.elementClass?a.element(document.getElementsByClassName(t.replace(".",""))[0]):a.element(document.body),s=document.getElementsByClassName("ng-reading-indicator-progress")[0],e.indicatorLazy&&""!==e.indicatorLazy?c.$watch("lazy",function(a){(""!==a||a.length>0)&&h()}):h(),c.$on("$destroy",function(){a.element(b).off("scroll",k),a.element(b).off("resize",j)})}}}])}(window.angular); 2 | //# sourceMappingURL=ng-reading-indicator.min.js.map -------------------------------------------------------------------------------- /dist/ng-reading-indicator.min.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"ng-reading-indicator.min.js","sources":["../src/ng-reading-indicator.js"],"names":["angular","undefined","ngReadingIndicator","module","directive","$window","$document","$templateCache","$sce","$timeout","TEMPLATE_URL","template","put","restrict","scope","elementClass","userOptions","headline","lazy","templateUrl","element","attributes","indicatorTemplateUrl","link","extendDeep","dst","forEach","arguments","obj","value","key","constructor","Object","initizalize","options","expand","type","showHeadline","article","find","length","html","expandOnHeadline","headine","updateSize","on","updateProgress","findEdges","elem","bodyRect","document","body","getBoundingClientRect","elemRect","top","bottom","scrollHeight","window","innerHeight","height","expandOffset","scrollPos","scrollY","pageYOffset","origScrollPos","calcFrom","progress","readingTime","enable","$apply","calculateReadingTime","progressBar","style","width","topOffset","addClass","removeClass","wordCount","text","trim","split","minutes","Math","floor","speed","seconds","estimate","prefix","minutesSuffix","round","secondInterval","secondsSuffix","getElementsByClassName","replace","indicatorLazy","$watch","newVal","$on","off"],"mappings":"CAAA,SAAUA,EAASC,GACjB,YAEA,IAAIC,GAAqBF,EAAQG,OAAO,sBAAuB,cAE/DD,GAAmBE,UAAU,sBAC3B,UAAW,YAAa,iBAAkB,OAAQ,WAClD,SAASC,EAASC,EAAWC,EAAgBC,EAAMC,GAEjD,GAAIC,GAAe,GAEfC,EAAU,wNAId,OAFAJ,GAAeK,IAAIF,EAAcC,IAG/BE,SAAU,KACVC,OACEC,aAAc,oBACdC,YAAa,oBACbC,SAAU,sBACVC,KAAM,mBAERC,YAAa,SAAUC,EAASC,GAC9B,MAAQA,GAAWC,sBAAwBZ,GAE7Ca,KAAM,SAAST,EAAOM,EAASC,GA4B7B,QAASG,GAAWC,GAalB,MAZAzB,GAAQ0B,QAAQC,UAAW,SAAUC,GAC/BA,IAAQH,GACVzB,EAAQ0B,QAAQE,EAAK,SAAUC,EAAOC,GAChCL,EAAIK,IAAQL,EAAIK,GAAKC,aAAeN,EAAIK,GAAKC,cAAgBC,OAC/DR,EAAWC,EAAIK,GAAMD,GAGrBJ,EAAIK,GAAOD,MAKZJ,EAmBT,QAASQ,KACPxB,EAAS,WACHyB,EAAQC,SAAYD,EAAQC,QAA2B,UAAjBD,EAAQE,MAC5CF,EAAQG,cAAgBvB,EAAMG,SAChCA,EAAWH,EAAMG,SACRiB,EAAQG,eAAiBvB,EAAMG,UAAYqB,EAAQC,KAAK,MAAMC,OAAS,GAChFvB,EAAWjB,EAAQoB,QAAQkB,EAAQC,KAAK,MAAM,IAAIE,OAClDC,GAAmB,GAEnBzB,GAAW,EAGbH,EAAMG,SAAW,EAAaA,EAAW,MAEzCH,EAAM6B,QAAU,KAGlBC,IAEA5C,EAAQoB,QAAQf,GAASwC,GAAG,SAAUC,GACtC9C,EAAQoB,QAAQf,GAASwC,GAAG,SAAUD,KAI1C,QAASG,GAAUC,GACjB,GAAIC,GAAWC,SAASC,KAAKC,wBACzBC,EAAWL,EAAKI,uBAEpB,QACEE,IAAMD,EAASC,IAAML,EAASK,IAC9BC,OAASP,EAAKQ,aAAeC,OAAOC,YAAc,EAAMV,EAAKQ,aAAeC,OAAOC,YAAcV,EAAKQ,aACtGG,OAAQN,EAASM,QAIrB,QAASf,KACPW,EAASR,EAAUT,EAAQ,IAAIiB,OAC/BD,EAAMP,EAAUT,EAAQ,IAAIgB,IAC5BK,EAASZ,EAAUT,EAAQ,IAAIqB,OAC/BC,EAAe,EAAqBb,EAAUT,EAAQC,KAAK,MAAM,KAAOe,IAAK,GAC7ER,IAGF,QAASA,KACP,GAAIe,GAAY7D,EAAQoB,QAAQf,GAAS,GAAGyD,SAAW9D,EAAQoB,QAAQf,GAAS,GAAG0D,YAC/EC,EAAgBH,CAEK,YAArB3B,EAAQ+B,SACVJ,EAAYG,EAAiBP,OAAOC,YAAc,EACpB,WAArBxB,EAAQ+B,WACjBJ,EAAYG,EAAgBP,OAAOC,aAGrCQ,EAAyBZ,GAAbO,EAAoB,GAAMA,EAAUP,GAAQhB,EAAQ,GAAe,aAAK,IAEhFJ,EAAQiC,YAAYC,OACtBtD,EAAMuD,OAAQ,WACZvD,EAAMqD,YAAcG,MAGtBxD,EAAMqD,YAAc,KAGtBI,EAAYC,MAAMC,MAAQP,EAAW,KAE/BhC,EAAQC,QAA2B,UAAjBD,EAAQE,MAAoB4B,GAAkBV,EAAMM,EAAaN,IAAMpB,EAAQwC,WAAgBxC,EAAQC,QAAU6B,EAAgBV,GAAOU,EAAiBV,EAAMM,EAAaN,IAAMpB,EAAQwC,WAChN1E,EAAQoB,QAAQA,GAAS,GAAGoD,MAAMb,OAAS,MAC3C3D,EAAQoB,QAAQA,GAASuD,SAAS,+BAClC3E,EAAQoB,QAAQA,GAASwD,YAAY,oCACzB1C,EAAQC,QAA2B,QAAjBD,EAAQE,MAAmBF,EAAQC,SAAW6B,GAAkBV,EAAMM,EAAaN,IAAMpB,EAAQwC,WAC/H1E,EAAQoB,QAAQA,GAASwD,YAAY,+BACrC5E,EAAQoB,QAAQA,GAASuD,SAAS,iCAClC3E,EAAQoB,QAAQA,GAAS,GAAGoD,MAAMb,OAAS,KAE3C3D,EAAQoB,QAAQA,GAAS,GAAGoD,MAAMb,OAAS,IAC3C3D,EAAQoB,QAAQA,GAASuD,SAAS,+BAClC3E,EAAQoB,QAAQA,GAASwD,YAAY,kCAIzC,QAASN,KACP,GAAIO,GAAY7E,EAAQoB,QAAQkB,EAAQ,IAAIwC,OAAOC,OAAOC,MAAM,KAAKxC,OACjEyC,EAAUC,KAAKC,MAAMN,EAAY3C,EAAQiC,YAAYiB,OACrDC,EAAUH,KAAKC,MAAMN,EAAY3C,EAAQiC,YAAYiB,OAASlD,EAAQiC,YAAYiB,MAAQ,KAC1FE,EAAYpD,EAAQiC,YAAYoB,MAiBpC,OAfIF,IAAW,IACbJ,IAGEC,KAAKC,MAAMF,GAAW,EAAKf,EAAS,MAAS,IAAMhC,EAAQiC,YAAYkB,SACzEJ,GAAqB,EAAKf,EAAS,IACnCoB,GAAYJ,KAAKC,MAAMF,GACvBK,GAAYpD,EAAQiC,YAAYqB,eACwB,IAA/CN,KAAKC,MAAMF,GAAW,EAAKf,EAAS,OAAgBhC,EAAQiC,YAAYkB,SACjFC,GAAYJ,KAAKO,MAAkB,GAAV,GAAiB,EAAKvB,EAAS,KAAS,IAAMhC,EAAQiC,YAAYuB,eAC3FJ,GAAYpD,EAAQiC,YAAYwB,eAEhCL,GAAY,EAAIpD,EAAQiC,YAAYwB,cAG/BL,EAhKT,GAAIrE,GAAW,KACXqB,EAAU,KACViB,EAAS,KACTD,EAAM,KACNK,EAAS,KACTO,EAAW,KACXK,EAAc,KACdvB,EAAO,KACPY,EAAe,KACflB,GAAmB,EACnBR,GACE+B,SAAU,SACV5B,cAAc,EACdF,QAAQ,EACRC,KAAM,QACNsC,UAAW,IACXP,aACEC,QAAQ,EACRmB,OAAQ,sBACRC,cAAe,MACfG,cAAe,MACfP,MAAO,IACPC,SAAS,EACTK,eAAgB,GAoBxBlE,GAAWU,EAASpB,EAAME,eAED,WAArBkB,EAAQ+B,UAA8C,QAArB/B,EAAQ+B,UAA2C,WAArB/B,EAAQ+B,WACzE/B,EAAQ+B,SAAW,UAGhB/B,EAAQC,QAA2B,UAAjBD,EAAQE,KAEnBF,EAAQC,QAA2B,QAAjBD,EAAQE,MACpCpC,EAAQoB,QAAQA,GAASuD,SAAS,+BAFlC3E,EAAQoB,QAAQA,GAASuD,SAAS,iCAKpC3B,EAASlC,EAAMC,cAAuC,KAAvBD,EAAMC,aAAiCD,EAAMC,aAAhBV,EAC5DiC,EAAYxB,EAAMC,cAAuC,KAAvBD,EAAMC,aAAwDf,EAAQoB,QAAQ8B,SAAS0C,uBAAuB5C,EAAK6C,QAAQ,IAAK,KAAK,IAAxG7F,EAAQoB,QAAQ8B,SAASC,MACxFoB,EAAcrB,SAAS0C,uBAAuB,iCAAiC,GA0G3EvE,EAAWyE,eAA8C,KAA7BzE,EAAWyE,cACzChF,EAAMiF,OAAO,OAAQ,SAASC,IACb,KAAXA,GAAiBA,EAAOxD,OAAS,IACnCP,MAIJA,IAGFnB,EAAMmF,IAAI,WAAY,WACpBjG,EAAQoB,QAAQf,GAAS6F,IAAI,SAAUpD,GACvC9C,EAAQoB,QAAQf,GAAS6F,IAAI,SAAUtD,WAOhDa,OAAOzD"} -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | /* License: MIT. 2 | * Copyright (C) 2015, Dominic Rico-Gomez. 3 | */ 4 | 5 | 'use strict'; 6 | 7 | module.exports = function (config) { 8 | config.set({ 9 | basePath: '', 10 | frameworks: ['jasmine'], 11 | logLevel: config.LOG_INFO, 12 | colors: true, 13 | singleRun: false, 14 | browsers: ['PhantomJS_custom'], 15 | customLaunchers: { 16 | 'PhantomJS_custom': { 17 | base: 'PhantomJS', 18 | options: { 19 | viewportSize: { width: 1024, height: 100 } 20 | } 21 | }, 22 | }, 23 | autoWatch: true, 24 | reporters: ['dots', 'coverage'], 25 | files: [ 26 | 'bower_components/angular/angular.js', 27 | 'bower_components/angular-mocks/angular-mocks.js', 28 | 'bower_components/angular-sanitize/angular-sanitize.js', 29 | 'src/ng-reading-indicator.js', 30 | 'tests.js' 31 | ], 32 | preprocessors: { 33 | 'src/ng-reading-indicator.js': 'coverage' 34 | }, 35 | coverageReporter: { 36 | type: 'lcov', 37 | dir: 'coverage/' 38 | } 39 | }); 40 | }; 41 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-reading-indicator", 3 | "version": "1.0.9", 4 | "description": "AngularJS Reading Indicator Directive", 5 | "main": "/src/ng-reading-indicator.js", 6 | "dependencies": {}, 7 | "devDependencies": { 8 | "bower": "^1.3.12", 9 | "coveralls": "~2.11.0", 10 | "grunt": "~0.4.1", 11 | "grunt-autoprefixer": "^3.0.3", 12 | "grunt-cli": "^0.1.13", 13 | "grunt-contrib-cssmin": "^0.12.3", 14 | "grunt-contrib-jshint": "~0.11.0", 15 | "grunt-contrib-less": "^1.0.1", 16 | "grunt-contrib-uglify": "^0.9.1", 17 | "grunt-karma": "~0.10.1", 18 | "karma": "~0.12.0", 19 | "karma-coverage": "~0.2.0", 20 | "karma-jasmine": "~0.3.5", 21 | "karma-phantomjs-launcher": "~0.1.1" 22 | }, 23 | "repository": { 24 | "type": "git", 25 | "url": "https://github.com/dominicrico/angular-reading-indicator.git" 26 | }, 27 | "keywords": [ 28 | "angular", 29 | "angularjs", 30 | "reading", 31 | "reading", 32 | "indicator", 33 | "progress", 34 | "progressbar" 35 | ], 36 | "author": "Dominic Rico-Gomez ", 37 | "license": "MIT", 38 | "bugs": { 39 | "url": "https://github.com/dominicrico/angular-reading-indicator/issues" 40 | }, 41 | "homepage": "http://dominicrico.github.io/angular-reading-indicator", 42 | "engines": { 43 | "node": ">=0.10.0" 44 | }, 45 | "scripts": { 46 | "bower": "node_modules/.bin/bower install", 47 | "test": "node_modules/.bin/grunt test", 48 | "build": "node_modules/.bin/grunt default" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/ng-reading-indicator.css: -------------------------------------------------------------------------------- 1 | ng-reading-indicator, 2 | [ng-reading-indicator] { 3 | position: fixed; 4 | display: -webkit-flex; 5 | display: -ms-flexbox; 6 | display: flex; 7 | -webkit-align-items: center; 8 | -ms-flex-align: center; 9 | align-items: center; 10 | width: 100%; 11 | height: 0; 12 | transition: height 0.15s ease-out; 13 | top: 0; 14 | left: 0; 15 | z-index: 9999; 16 | background: rgba(19, 146, 176, 0.8); 17 | box-shadow: 2px 2px 2px rgba(19, 146, 176, 0.5); 18 | } 19 | ng-reading-indicator.ng-reading-indicator-expanded, 20 | [ng-reading-indicator].ng-reading-indicator-expanded { 21 | height: auto; 22 | height: 52px; 23 | } 24 | ng-reading-indicator.ng-reading-indicator-expanded .ng-reading-indicator-headline, 25 | [ng-reading-indicator].ng-reading-indicator-expanded .ng-reading-indicator-headline, 26 | ng-reading-indicator.ng-reading-indicator-expanded .ng-reading-indicator-time, 27 | [ng-reading-indicator].ng-reading-indicator-expanded .ng-reading-indicator-time { 28 | -webkit-animation-duration: 0.5s; 29 | animation-duration: 0.5s; 30 | -webkit-animation-name: fadeIn; 31 | animation-name: fadeIn; 32 | display: inline-block; 33 | } 34 | ng-reading-indicator.ng-reading-indicator-shrink .ng-reading-indicator-headline, 35 | [ng-reading-indicator].ng-reading-indicator-shrink .ng-reading-indicator-headline, 36 | ng-reading-indicator.ng-reading-indicator-shrink .ng-reading-indicator-time, 37 | [ng-reading-indicator].ng-reading-indicator-shrink .ng-reading-indicator-time { 38 | -webkit-animation-duration: 0.5s; 39 | animation-duration: 0.5s; 40 | -webkit-animation-name: fadeOut; 41 | animation-name: fadeOut; 42 | display: none; 43 | } 44 | ng-reading-indicator .ng-reading-indicator-progress, 45 | [ng-reading-indicator] .ng-reading-indicator-progress { 46 | content: ''; 47 | position: absolute; 48 | margin: auto; 49 | top: 0; 50 | bottom: 0; 51 | height: 100%; 52 | z-index: -1; 53 | background: rgba(19, 146, 176, 0.9); 54 | } 55 | ng-reading-indicator .ng-reading-indicator-headline, 56 | [ng-reading-indicator] .ng-reading-indicator-headline { 57 | display: none; 58 | } 59 | ng-reading-indicator .ng-reading-indicator-headline h2, 60 | [ng-reading-indicator] .ng-reading-indicator-headline h2 { 61 | display: inline-block; 62 | padding: 10px 30px; 63 | font-family: inherit; 64 | color: rgba(255, 255, 255, 0.85); 65 | margin: 5px 0; 66 | font-size: 24px; 67 | } 68 | ng-reading-indicator .ng-reading-indicator-time, 69 | [ng-reading-indicator] .ng-reading-indicator-time { 70 | display: none; 71 | color: rgba(255, 255, 255, 0.85); 72 | font-weight: 500; 73 | float: right; 74 | padding-right: 30px; 75 | padding-left: 10px; 76 | border-left: 1px solid rgba(255, 255, 255, 0.85); 77 | } 78 | ng-reading-indicator .ng-reading-indicator-time:before, 79 | [ng-reading-indicator] .ng-reading-indicator-time:before { 80 | content: ''; 81 | position: relative; 82 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAvZJREFUeNqM1ltIVEEcx/Gzxw0spYguWl4qSQrEB3szosIuYiGmLxmFSWBXSAyMQigrSKiHiqTL9mJBBN2zEoIoQsieupmZ3a9mJRWbGUS2fUd+B6blrDrwWc7OOTszZ+b/n9lAJBJxBigTMQszMQWjVB/Ga7SgGe9jNRCI0cF4rEYRRjoDl59oRAidQ+lgLnYg2aozI36HbpgfjMGkqM7NvZ249l9rpgNLCdrRIY1YgkTdjxNzPQKFOG89byyz27TfYDaOwtX3QzigdViOOUgyb43PmvuTeIt1qNQ9UzZ6b+J1MBYXMU4P1OAsqrBGc3sLrZqiLHWYjgbUoRB7NMDvWr8u71VqrFesVN1BPMZSBFWXgnRruorRimOqq7DaqesfPB9JuKvKJj1YhSfIseYzE4/UabZVn4U2DdJ8v6C2HpgBuZr7BE1NSCG6Fttxz4qHFAxDHCZb9W3YgjKkoV718ch3lUSm/NDClPXPneOciQrfPuu6N+reZS12hRY/rPrcIB8Z+mIe+IU83MTfAZIrB38UNZ/QjiYt9G88xwykBq1k6dbrm0jq8Gk0aF1XiPdmRYqwFWrjo+4luH7bR4xRd2nU0cXVb/z2nEBQc+8o/c1oviDT52EzDaVa7Ig1EJMjT7FIc9+nhDSlx3TwCtOUNPGaf/PwLp9RtYpfKcBtRZo3wE5XlY7WYgFOYAJKnKGXAoVuSNu7t623mMRIxn0lxxUlS7U2veyozdDPdGVzrb6fU1sPkeY9VGul+AbVHVGGFls7qM3FYg2uQXXlVjt77d3UhOYlLbSp2KxDZCvK8QbX8Uz3p2KecugUak3WYp/CNKzQ7bS36zxt0V507MdhHSwrNbejde+bjsvjeIlVqLa2+k246nfglGqT817THCb5SLCmxdX1cMzH6agDpyzWgeOVhdhmnQ3ekflCB01EcZ5hRYspX7Fb+9Kgh74J0/XKh8RBQrRXm2S937+LwCB/W1K1Nrnair3OevABd3BDQeBb/gkwAL82fwDk50ljAAAAAElFTkSuQmCC); 83 | opacity: .85; 84 | display: inline-block; 85 | background-size: contain; 86 | width: 12px; 87 | height: 12px; 88 | top: 1px; 89 | } 90 | @-webkit-keyframes fadeIn { 91 | 0% { 92 | display: none; 93 | opacity: 0; 94 | } 95 | 1% { 96 | display: inline-block; 97 | opacity: 0; 98 | } 99 | 100% { 100 | display: inline-block; 101 | opacity: 1; 102 | } 103 | } 104 | @keyframes fadeIn { 105 | 0% { 106 | display: none; 107 | opacity: 0; 108 | } 109 | 1% { 110 | display: inline-block; 111 | opacity: 0; 112 | } 113 | 100% { 114 | display: inline-block; 115 | opacity: 1; 116 | } 117 | } 118 | @-webkit-keyframes fadeOut { 119 | 0% { 120 | display: inline-block; 121 | opacity: 1; 122 | } 123 | 1% { 124 | display: inline-block; 125 | opacity: 1; 126 | } 127 | 100% { 128 | display: none; 129 | opacity: 0; 130 | } 131 | } 132 | @keyframes fadeOut { 133 | 0% { 134 | display: inline-block; 135 | opacity: 1; 136 | } 137 | 1% { 138 | display: inline-block; 139 | opacity: 1; 140 | } 141 | 100% { 142 | display: none; 143 | opacity: 0; 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/ng-reading-indicator.js: -------------------------------------------------------------------------------- 1 | (function(angular, undefined){ 2 | 'use strict'; 3 | 4 | var ngReadingIndicator = angular.module('ngReadingIndicator', ['ngSanitize']); 5 | 6 | ngReadingIndicator.directive('ngReadingIndicator', [ 7 | '$window', '$document', '$templateCache', '$sce', '$timeout', 8 | function($window, $document, $templateCache, $sce, $timeout) { 9 | 10 | var TEMPLATE_URL = ''; 11 | 12 | var template ='

{{ readingTime }}
'; 13 | 14 | $templateCache.put(TEMPLATE_URL, template); 15 | 16 | return { 17 | restrict: 'AE', 18 | scope: { 19 | elementClass: '@indicatorElement', 20 | userOptions: '&indicatorOptions', 21 | headline: '=?indicatorHeadline', 22 | lazy: '=?indicatorLazy' 23 | }, 24 | templateUrl: function (element, attributes) { 25 | return (attributes.indicatorTemplateUrl || TEMPLATE_URL); 26 | }, 27 | link: function(scope, element, attributes) { 28 | var headline = null, 29 | article = null, 30 | bottom = null, 31 | top = null, 32 | height = null, 33 | progress = null, 34 | progressBar = null, 35 | elem = null, 36 | expandOffset = null, 37 | expandOnHeadline = false, 38 | options = { 39 | calcFrom: 'middle', 40 | showHeadline: true, 41 | expand: true, 42 | type: 'small', 43 | topOffset: 150, 44 | readingTime: { 45 | enable: true, 46 | prefix: 'remaining estimate ', 47 | minutesSuffix: 'min', 48 | secondsSuffix: 'sec', 49 | speed: 150, 50 | seconds: true, 51 | secondInterval: 5 52 | } 53 | }; 54 | 55 | function extendDeep(dst) { 56 | angular.forEach(arguments, function (obj) { 57 | if (obj !== dst) { 58 | angular.forEach(obj, function (value, key) { 59 | if (dst[key] && dst[key].constructor && dst[key].constructor === Object) { 60 | extendDeep(dst[key], value); 61 | } 62 | else { 63 | dst[key] = value; 64 | } 65 | }); 66 | } 67 | }); 68 | return dst; 69 | } 70 | 71 | extendDeep(options, scope.userOptions()); 72 | 73 | if (options.calcFrom !== 'bottom' && options.calcFrom !== 'top' && options.calcFrom !== 'bottom') { 74 | options.calcFrom = 'middle'; 75 | } 76 | 77 | if (!options.expand && options.type !== 'small') { 78 | angular.element(element).addClass('ng-reading-indicator-expanded'); 79 | } else if (!options.expand && options.type !== 'big') { 80 | angular.element(element).addClass('ng-reading-indicator-shrink'); 81 | } 82 | 83 | elem = (!scope.elementClass || scope.elementClass === '') ? $window : scope.elementClass; 84 | article = (!scope.elementClass || scope.elementClass === '') ? angular.element(document.body) : angular.element(document.getElementsByClassName(elem.replace('.', ''))[0]); 85 | progressBar = document.getElementsByClassName('ng-reading-indicator-progress')[0]; 86 | 87 | function initizalize() { 88 | $timeout(function(){ 89 | if (options.expand || (!options.expand && options.type !== 'small')) { 90 | if (options.showHeadline && scope.headline) { 91 | headline = scope.headline; 92 | } else if (options.showHeadline && !scope.headline && article.find('h1').length > 0) { 93 | headline = angular.element(article.find('h1')[0]).html(); 94 | expandOnHeadline = false; 95 | } else { 96 | headline = false; 97 | } 98 | 99 | scope.headline = (headline) ? headline : null; 100 | } else { 101 | scope.headine = null; 102 | } 103 | 104 | updateSize(); 105 | 106 | angular.element($window).on('scroll', updateProgress); 107 | angular.element($window).on('resize', updateSize); 108 | }); 109 | } 110 | 111 | function findEdges(elem) { 112 | var bodyRect = document.body.getBoundingClientRect(), 113 | elemRect = elem.getBoundingClientRect(); 114 | 115 | return { 116 | top: (elemRect.top - bodyRect.top), 117 | bottom: (elem.scrollHeight - window.innerHeight > 0 ) ? elem.scrollHeight - window.innerHeight : elem.scrollHeight, 118 | height: elemRect.height 119 | }; 120 | } 121 | 122 | function updateSize() { 123 | bottom = findEdges(article[0]).bottom; 124 | top = findEdges(article[0]).top; 125 | height = findEdges(article[0]).height; 126 | expandOffset = (expandOnHeadline) ? findEdges(article.find('h1')[0]) : {top: 0}; 127 | updateProgress(); 128 | } 129 | 130 | function updateProgress() { 131 | var scrollPos = angular.element($window)[0].scrollY || angular.element($window)[0].pageYOffset; 132 | var origScrollPos = scrollPos; 133 | 134 | if (options.calcFrom === 'middle') { 135 | scrollPos = origScrollPos + (window.innerHeight / 2); 136 | } else if (options.calcFrom === 'bottom') { 137 | scrollPos = origScrollPos + window.innerHeight; 138 | } 139 | 140 | progress = (scrollPos <= top) ? 0 : ((scrollPos-top) / (article[0].offsetHeight)) * 100; 141 | 142 | if (options.readingTime.enable) { 143 | scope.$apply( function(){ 144 | scope.readingTime = calculateReadingTime(); 145 | }); 146 | } else { 147 | scope.readingTime = null; 148 | } 149 | 150 | progressBar.style.width = progress + '%'; 151 | 152 | if ((!options.expand && options.type === 'small' && origScrollPos >= (top + expandOffset.top + options.topOffset)) || (options.expand && origScrollPos > top && origScrollPos < (top + expandOffset.top + options.topOffset))) { 153 | angular.element(element)[0].style.height = '5px'; 154 | angular.element(element).addClass('ng-reading-indicator-shrink'); 155 | angular.element(element).removeClass('ng-reading-indicator-expanded'); 156 | } else if (((!options.expand && options.type === 'big') || options.expand) && origScrollPos >= (top + expandOffset.top + options.topOffset)) { 157 | angular.element(element).removeClass('ng-reading-indicator-shrink'); 158 | angular.element(element).addClass('ng-reading-indicator-expanded'); 159 | angular.element(element)[0].style.height = ''; 160 | } else { 161 | angular.element(element)[0].style.height = '0'; 162 | angular.element(element).addClass('ng-reading-indicator-shrink'); 163 | angular.element(element).removeClass('ng-reading-indicator-expanded'); 164 | } 165 | } 166 | 167 | function calculateReadingTime(){ 168 | var wordCount = angular.element(article[0]).text().trim().split(' ').length; 169 | var minutes = Math.floor(wordCount / options.readingTime.speed); 170 | var seconds = Math.floor(wordCount % options.readingTime.speed / (options.readingTime.speed / 60)); 171 | var estimate = options.readingTime.prefix; 172 | 173 | if (seconds >= 30) { 174 | minutes++; 175 | } 176 | 177 | if (Math.floor(minutes * (1 - (progress/100))) > 0 || !options.readingTime.seconds) { 178 | minutes = minutes * (1 - (progress/100)); 179 | estimate += Math.floor(minutes); 180 | estimate += options.readingTime.minutesSuffix; 181 | } else if (Math.floor(minutes * (1 - (progress/100))) === 0 && options.readingTime.seconds) { 182 | estimate += Math.round((((minutes)*60) * (1 - (progress/100))) / 10) * options.readingTime.secondInterval; 183 | estimate += options.readingTime.secondsSuffix; 184 | } else { 185 | estimate += 0 + options.readingTime.secondsSuffix; 186 | } 187 | 188 | return estimate; 189 | } 190 | 191 | if (attributes.indicatorLazy && attributes.indicatorLazy !== '') { 192 | scope.$watch('lazy', function(newVal){ 193 | if (newVal !== '' || newVal.length > 0) { 194 | initizalize(); 195 | } 196 | }); 197 | } else { 198 | initizalize(); 199 | } 200 | 201 | scope.$on('$destroy', function () { 202 | angular.element($window).off('scroll', updateProgress); 203 | angular.element($window).off('resize', updateSize); 204 | }); 205 | } 206 | }; 207 | } 208 | ]); 209 | 210 | })(window.angular); 211 | -------------------------------------------------------------------------------- /src/ng-reading-indicator.less: -------------------------------------------------------------------------------- 1 | // Color variables 2 | @fontColor: #fff; 3 | @baseColor: #1392B0; 4 | 5 | 6 | // Basic reading indicator 7 | ng-reading-indicator, [ng-reading-indicator] { 8 | position: fixed; 9 | display: flex; 10 | align-items: center; 11 | width: 100%; 12 | height: 0; 13 | transition: height 0.15s ease-out; 14 | top: 0; 15 | left: 0; 16 | z-index: 9999; 17 | background: fade(@baseColor, 80%); 18 | box-shadow: 2px 2px 2px fade(@baseColor, 50%); 19 | 20 | &.ng-reading-indicator-expanded { 21 | height: auto; 22 | height: 52px; 23 | 24 | .ng-reading-indicator-headline, 25 | .ng-reading-indicator-time { 26 | animation-duration: 0.5s; 27 | animation-name: fadeIn; 28 | display: inline-block; 29 | } 30 | } 31 | 32 | &.ng-reading-indicator-shrink { 33 | 34 | .ng-reading-indicator-headline, 35 | .ng-reading-indicator-time { 36 | animation-duration: 0.5s; 37 | animation-name: fadeOut; 38 | display: none; 39 | } 40 | 41 | } 42 | 43 | // Reading indicator progressbar 44 | .ng-reading-indicator-progress { 45 | content: ''; 46 | position: absolute; 47 | margin: auto; 48 | top: 0; 49 | bottom: 0; 50 | height: 100%; 51 | z-index: -1; 52 | background: fade(@baseColor, 90%); 53 | } 54 | 55 | // Reading indicator headline 56 | .ng-reading-indicator-headline { 57 | display: none; 58 | 59 | h2 { 60 | display: inline-block; 61 | padding: 10px 30px; 62 | font-family: inherit; 63 | color: fade(@fontColor, 85%); 64 | margin: 5px 0; 65 | font-size: 24px; 66 | } 67 | } 68 | 69 | // Reading time indicator 70 | .ng-reading-indicator-time { 71 | display: none; 72 | color: fade(@fontColor, 85%); 73 | font-weight: 500; 74 | float: right; 75 | padding-right: 30px; 76 | padding-left: 10px; 77 | border-left: 1px solid fade(@fontColor, 85%); 78 | 79 | &:before { 80 | content: ''; 81 | position: relative; 82 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAvZJREFUeNqM1ltIVEEcx/Gzxw0spYguWl4qSQrEB3szosIuYiGmLxmFSWBXSAyMQigrSKiHiqTL9mJBBN2zEoIoQsieupmZ3a9mJRWbGUS2fUd+B6blrDrwWc7OOTszZ+b/n9lAJBJxBigTMQszMQWjVB/Ga7SgGe9jNRCI0cF4rEYRRjoDl59oRAidQ+lgLnYg2aozI36HbpgfjMGkqM7NvZ249l9rpgNLCdrRIY1YgkTdjxNzPQKFOG89byyz27TfYDaOwtX3QzigdViOOUgyb43PmvuTeIt1qNQ9UzZ6b+J1MBYXMU4P1OAsqrBGc3sLrZqiLHWYjgbUoRB7NMDvWr8u71VqrFesVN1BPMZSBFWXgnRruorRimOqq7DaqesfPB9JuKvKJj1YhSfIseYzE4/UabZVn4U2DdJ8v6C2HpgBuZr7BE1NSCG6Fttxz4qHFAxDHCZb9W3YgjKkoV718ch3lUSm/NDClPXPneOciQrfPuu6N+reZS12hRY/rPrcIB8Z+mIe+IU83MTfAZIrB38UNZ/QjiYt9G88xwykBq1k6dbrm0jq8Gk0aF1XiPdmRYqwFWrjo+4luH7bR4xRd2nU0cXVb/z2nEBQc+8o/c1oviDT52EzDaVa7Ig1EJMjT7FIc9+nhDSlx3TwCtOUNPGaf/PwLp9RtYpfKcBtRZo3wE5XlY7WYgFOYAJKnKGXAoVuSNu7t623mMRIxn0lxxUlS7U2veyozdDPdGVzrb6fU1sPkeY9VGul+AbVHVGGFls7qM3FYg2uQXXlVjt77d3UhOYlLbSp2KxDZCvK8QbX8Uz3p2KecugUak3WYp/CNKzQ7bS36zxt0V507MdhHSwrNbejde+bjsvjeIlVqLa2+k246nfglGqT817THCb5SLCmxdX1cMzH6agDpyzWgeOVhdhmnQ3ekflCB01EcZ5hRYspX7Fb+9Kgh74J0/XKh8RBQrRXm2S937+LwCB/W1K1Nrnair3OevABd3BDQeBb/gkwAL82fwDk50ljAAAAAElFTkSuQmCC); 83 | opacity: .85; 84 | display: inline-block; 85 | background-size: contain; 86 | width: 12px; 87 | height: 12px; 88 | top: 1px; 89 | } 90 | 91 | } 92 | 93 | } 94 | 95 | // Animation for headline and read time indicator 96 | 97 | @keyframes fadeIn { 98 | 0% { 99 | display:none; 100 | opacity: 0; 101 | } 102 | 103 | 1% { 104 | display: inline-block; 105 | opacity: 0; 106 | } 107 | 108 | 100% { 109 | display: inline-block; 110 | opacity: 1; 111 | } 112 | } 113 | 114 | @keyframes fadeOut { 115 | 0% { 116 | display: inline-block; 117 | opacity: 1; 118 | } 119 | 120 | 1% { 121 | display: inline-block; 122 | opacity: 1; 123 | } 124 | 125 | 100% { 126 | display: none; 127 | opacity: 0; 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/time-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dominicrico/angular-reading-indicator/4da42d100bfec62a2954ffb61b856d2224bdb826/src/time-white.png -------------------------------------------------------------------------------- /src/time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dominicrico/angular-reading-indicator/4da42d100bfec62a2954ffb61b856d2224bdb826/src/time.png -------------------------------------------------------------------------------- /tests.js: -------------------------------------------------------------------------------- 1 | /* License: MIT. 2 | * Copyright (C) 2015, Dominic Rico-Gomez. 3 | */ 4 | 5 | /* global describe, inject, module, beforeEach, it, expect */ 6 | 7 | 'use strict'; 8 | 9 | describe('Testing the ngReadingIndicator', function () { 10 | var $rootScope, $compile, $scope, elem; 11 | 12 | beforeEach(module('ngReadingIndicator')); 13 | 14 | beforeEach(inject(function (_$compile_, _$rootScope_) { 15 | $compile = _$compile_; 16 | $rootScope = _$rootScope_; 17 | 18 | elem = angular.element(''); 19 | 20 | $scope = $rootScope.$new(); 21 | })); 22 | 23 | 24 | describe('directive test', function () { 25 | it('should show 100% on bottom of page', inject(function () { 26 | return true; 27 | })); 28 | 29 | it('shouldn\'t show a headline', inject(function () { 30 | 31 | $scope.options = { showHeadline: false }; 32 | 33 | $compile(elem)($scope); 34 | $scope.$digest(); 35 | 36 | expect(elem.find('h2').text()).toBe(''); 37 | })); 38 | it('should show the headline given by the scope', inject(function () { 39 | 40 | elem.attr('indicator-headline', 'headline'); 41 | 42 | $scope.$apply(function(){ 43 | $scope.headline = 'Headline'; 44 | }); 45 | 46 | $compile(elem)($scope); 47 | $scope.$digest(); 48 | 49 | expect(elem.find('h2').text()).toBe('Headline'); 50 | })); 51 | 52 | it('should show the first headline of the article', inject(function () { 53 | return true; 54 | })); 55 | 56 | it('should be the big reading indicator', inject(function(){ 57 | $scope.options = { expand: false, type: 'big' }; 58 | 59 | $compile(elem)($scope); 60 | $scope.$digest(); 61 | 62 | expect(elem.eq(0).hasClass('ng-reading-indicator-expanded')).toBe(true); 63 | expect(elem.eq(0).hasClass('ng-reading-indicator-shrink')).toBe(false); 64 | })); 65 | 66 | it('should be the small reading indicator', inject(function(){ 67 | $scope.options = { expand: false, type: 'small' }; 68 | 69 | $compile(elem)($scope); 70 | $scope.$digest(); 71 | 72 | expect(elem.eq(0).hasClass('ng-reading-indicator-expanded')).toBe(false); 73 | expect(elem.eq(0).hasClass('ng-reading-indicator-shrink')).toBe(true); 74 | })); 75 | 76 | }); 77 | 78 | }); 79 | --------------------------------------------------------------------------------