├── 404.html ├── CNAME ├── LICENSE ├── README.md ├── about.html ├── assets ├── csp.html ├── detect.html └── modules.js ├── compare ├── browser │ └── index.html └── feature │ └── index.html ├── css ├── main.css └── reporting.css ├── fonts ├── html5test.dev.svg ├── html5test.eot ├── html5test.svg ├── html5test.ttf ├── html5test.woff ├── leaguegothic-condensed-italic-webfont.eot ├── leaguegothic-condensed-italic-webfont.svg ├── leaguegothic-condensed-italic-webfont.ttf ├── leaguegothic-condensed-italic-webfont.woff ├── leaguegothic-condensed-regular-webfont.eot ├── leaguegothic-condensed-regular-webfont.svg ├── leaguegothic-condensed-regular-webfont.ttf ├── leaguegothic-condensed-regular-webfont.woff ├── leaguegothic-italic-webfont.eot ├── leaguegothic-italic-webfont.svg ├── leaguegothic-italic-webfont.ttf ├── leaguegothic-italic-webfont.woff ├── leaguegothic-regular-webfont.eot ├── leaguegothic-regular-webfont.svg ├── leaguegothic-regular-webfont.ttf ├── leaguegothic-regular-webfont.woff └── stylesheet.css ├── images ├── external │ ├── ecma.png │ ├── khronos.png │ ├── mdn.svg │ ├── ricg.svg │ ├── w3c.png │ ├── whatwg.svg │ └── wp.png ├── html5.png ├── html5@2x.png ├── html5test.svg ├── icons │ ├── apple-touch-icon-114x114.png │ ├── apple-touch-icon-120x120.png │ ├── apple-touch-icon-144x144.png │ ├── apple-touch-icon-152x152.png │ ├── apple-touch-icon-57x57.png │ ├── apple-touch-icon-60x60.png │ ├── apple-touch-icon-72x72.png │ ├── apple-touch-icon-76x76.png │ ├── apple-touch-icon-precomposed.png │ ├── apple-touch-icon.png │ ├── browserconfig.xml │ ├── favicon-160x160.png │ ├── favicon-16x16.png │ ├── favicon-196x196.png │ ├── favicon-32x32.png │ ├── favicon-96x96.png │ ├── favicon.ico │ ├── mstile-144x144.png │ ├── mstile-150x150.png │ ├── mstile-310x150.png │ ├── mstile-310x310.png │ └── mstile-70x70.png ├── sponsors │ ├── blackberry.svg │ ├── cloudvps.png │ ├── cloudvps@2x.png │ ├── google.png │ ├── google.svg │ ├── labup.png │ ├── nokia.svg │ └── salonhub.png └── thumbnail.jpg ├── index.html ├── qr.html ├── results ├── desktop.html ├── latest.html ├── mobile.html ├── other.html ├── search.html └── tablet.html ├── s └── index.html └── scripts ├── 5 └── data.js ├── 6 ├── data.js └── engine.js ├── 7 ├── data.js └── engine.js ├── 8 ├── data.js └── engine.js ├── 9 ├── data.js └── engine.js ├── base.js ├── fullscreen.js ├── highcharts ├── adapters │ ├── mootools-adapter.js │ ├── mootools-adapter.src.js │ ├── prototype-adapter.js │ └── prototype-adapter.src.js ├── highcharts.js ├── highcharts.src.js ├── modules │ ├── canvas-tools.js │ ├── canvas-tools.src.js │ ├── exporting.js │ └── exporting.src.js └── themes │ ├── dark-blue.js │ ├── dark-green.js │ ├── gray.js │ ├── grid.js │ └── skies.js ├── jquery ├── jquery-1.7.2.min.js └── jquery.tablesorter.min.js └── reporting.js /404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HTML5test - How well does your browser support HTML5? 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | html5test.co -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 2010-2025 Niels Leenheer, Jerzy Głowacki 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ### Updated domain: [html5test.co](https://html5test.co) 4 | 5 | This is a website for testing web standards in the browser. The HTML5 test score is an indication 6 | of how well your browser supports the HTML5 standard and related specifications. Find out which 7 | parts of HTML5 are supported by your browser today and compare the results with other browsers. 8 | 9 | The HTML5 test does not try to test all of the new features offered by HTML5, nor does it try to 10 | test the functionality of each feature it does detect. Despite these shortcomings we hope that 11 | by quantifying the level of support users and web developers will get an idea of how hard the browser 12 | manufacturers work on improving their browsers and the web as a development platform. 13 | The score is calculated by testing for the many new features of HTML5. Each feature is worth one or 14 | more points. Apart from the main HTML5 specification and other specifications created the W3C HTML 15 | Working Group or WHATWG, this test also awards points for supporting related drafts and specifications. 16 | Please be aware that although the HTML5 specification is now an official recommendation, other 17 | specifications that are being tested are still in development and could change before receiving 18 | an official status. In the future new tests will be added for new specifications and existing 19 | tests will be updated when the specifications change. 20 | -------------------------------------------------------------------------------- /about.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HTML5test - How well does your browser support HTML5? 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |

HTML5test how well does your browser support HTML5?

32 | 42 |
43 | 44 |
45 |
46 |
47 | 50 | 51 |
52 |

Specifications

53 | 54 |

Why do you include specifications that are not part of HTML5?

55 |
56 |

57 | HTML5 means different things to different people. You could argue that HTML5 only includes features that are 58 | defined in the W3C HTML5 specification. Or you could argue that it includes every specification, draft or 59 | experimental feature that is added to browsers in the last couple of years. We decided to take the middle 60 | ground and split the test into three parts: the official HTML5 specification, specifications that are related 61 | to HTML5 and some experimental new features that are extensions of HTML5. 62 |

63 |

64 | Many of the related specifications were at one time part of HTML5. During the development of the specification 65 | they were moved to separate specifications. 66 |

67 |
68 | 69 |

But WebGL isn't even a W3C specification!

70 |
71 | The W3C isn't the only organization that creates open specifications for the web. The WebGL specification is 72 | published by Kronos, the same group that is also responsible for OpenGL. WebGL is related to HTML5 though and 73 | listed as one of the HTML5 technologies on the W3C HTML5 logo page. The W3C HTML5 specification allows the 74 | canvas element to be extended by new drawing methods and WebGL is one of them. 75 |
76 | 77 |

Why do you test for Web SQL?

78 |
79 | The Web SQL specification has been deprecated and replaced by the IndexedDB specification. It is however 80 | still commonly used on mobile phones and at least three vendors have shipped desktop browsers supporting Web SQL. We've decided to include 81 | this specification, but make it a special case. Web SQL is worth 5 points, but only if IndexedDB is not supported. 82 | IndexedDB is worth 10 points. If a browser supports both, only 10 points are awarded. This way browsers 83 | that only included IndexedDB are not penalized, but browsers that only support Web SQL do get some points. 84 |
85 | 86 |
87 | 88 | 89 |

Scoring

90 | 91 |

What is the maximum number of points you can score?

92 |
93 | If a browser passes all tests it would receive the maximum score of 555. Previous 94 | versions of the HTML5test had less tests and therefore also a lower maximum score, such as 160, 300, 450, 475 and 500 points. 95 | Previous versions of this test also awarded bonus points for some features, but as of version 5, we 96 | no longer do. 97 |
98 | 99 |

The scoring seems arbitrary, who decides how many points are awarded?

100 |
101 | We decided to award points for each feature depending on how important that feature is for web developers 102 | and how difficult it is to implement that feature. A small and simple feature would be worth less points than a 103 | large and complicated feature. We think this is the most honest way to grade browsers, because otherwise a browser 104 | that only supports the small and simple features would score as high or higher than a browser that went the 105 | extra mile and decided to tackle the big features. But in the end it is based on personal preference, 106 | but I doubt there is a truly objective alternative. 107 |
108 | 109 |
110 | 111 | 112 |

Reporting

113 | 114 |

Can my browser be included on the 'other browser' and 'compare' pages?

115 |
116 |

117 | We would love to add new browsers, but not all browsers are eligible. First of all we only accept browsers that 118 | are publicly available, either in beta form or a final release. We do not accept scores for internal development builds. 119 | Secondly we only accept browsers that are available in English. We want to check browsers before including them and 120 | unfortunately we do not speak Chinese, Japanese, Korean or Russian. And finally we only accept browsers which have a 121 | unique score. There are many browsers that are forks or modified versions of Chromium or Firefox. Similarly there 122 | are many browser that embed Internet Explorer or Webkit as provided by the operating system. These browser 123 | do not qualify. For comparisons, simply choose the original browser on which the browser was based instead. 124 |

125 |

126 | We retain the right to make exceptions to any of the rules above and to remove or refuse any browser we deem 127 | necessary. 128 |

129 |
130 | 131 |

What happens when a browser cheats?

132 |
133 |

134 | We cannot distinguish between a browser that supports a particular feature and a browser that lies about supporting 135 | that feature. The only way to deal with these situations it to manually confirm the test results. And if a browser 136 | is found to be overly confident about claiming support for certain features we can put that browser on a blacklist. 137 | That means that that even though the browser claims to support a particular feature, we ignore what the browser says and do 138 | not give any points. This is usually just a temporary problem and once the browser has been fixed we will remove 139 | the new version from the blacklist. 140 |

141 |

142 | Claiming to support a feature which isn't working is not just causing problems for the reliability of the 143 | test results, but there are other real-world problems. For example if you claim to support WebGL, a website may decide 144 | to serve WebGL content. If your browser does not support WebGL, the website may fail in an uncontrollable way. If you 145 | correctly denied support for WebGL, the website may have served alternative content that would work in your browser. 146 | If you claim to support features that you don't, you are breaking the web. 147 |

148 |

149 | If we find that a browser is structurally lying about which features they support - deliberately or not - we will 150 | usually give a warning to the developers of the browser and if the problem hasn't been fixed in the next version 151 | we will remove the browser from the 'other browser' and 'compare' pages and/or give other penalties. In extreme 152 | cases we may block the browser from showing test results and show a warning instead. 153 |

154 |
155 | 156 |
157 | 158 |

Methods

159 | 160 |

Why are you using browser sniffing?

161 |
162 |

163 | Unfortunately, in two very specific cases we are forced to use browser sniffing. The first case is contentEditable 164 | which was not supported on many older mobile devices. Yet almost all mobile browsers claim to support contentEditable. 165 | Fortunately modern mobile devices are starting to support contentEditable, but this left us with a problem. We 166 | cannot reliably detect if a browser has proper support. The only way around this is to use a whitelist of 167 | mobile browsers that do support this feature, otherwise you risk awarding points to mobile browsers that they 168 | do not deserve. The second case is drag and drop, which is also not supported on mobile phones and tablets.

169 |

170 | Please open a new issue on Github when you believe a 171 | browser should be included on the whitelist. 172 |

173 |
174 | 175 |
176 | 177 |

Privacy

178 | 179 |

What kind of data is collected from visitors?

180 |
181 |

182 | Each time you visit this website your score and test results are logged on our servers. 183 | We also store the user agent of your browser which contains information about the browser, 184 | operating system and device you are using. The collected information is solely used to 185 | generated anonymized reports about HTML5 support in browsers and improve the quality of 186 | our software. 187 |

188 |

189 | We do not store cookies in your browser. 190 |

191 |
192 |
193 |
194 | 195 | 208 |
209 |
210 | 211 | 212 | 213 | -------------------------------------------------------------------------------- /assets/csp.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /assets/detect.html: -------------------------------------------------------------------------------- 1 | &&< 2 | -------------------------------------------------------------------------------- /assets/modules.js: -------------------------------------------------------------------------------- 1 | var test_module_scope = true; 2 | window.callback_es6_modules(typeof window.test_module_scope === 'undefined') -------------------------------------------------------------------------------- /compare/browser/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | HTML5test - How well does your browser support HTML5? 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 |
43 |

HTML5test how well does your browser support HTML5?

44 | 54 |
55 | 56 |
57 |
58 |
59 | 63 | 64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | 73 |
74 | 75 |

About these scores

76 |
77 | The data above is compiled from automatically submitted test results. It is possible your results 78 | may differ slightly due to external factors such as settings and which operating system is used. 79 | If you believe the data above is incorrect, or if you think we are missing an important browser 80 | or device, please open a bug report at Github. 81 |
82 |
83 | 84 | 158 |
159 | 160 | 172 |
173 |
174 | 175 | 176 | -------------------------------------------------------------------------------- /compare/feature/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | HTML5test - How well does your browser support HTML5? 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
34 |

HTML5test how well does your browser support HTML5?

35 | 45 |
46 | 47 |
48 |
49 |
50 | 54 | 55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | 64 |
65 | 66 |

About these scores

67 |
68 | The data above is compiled from automatically submitted test results. It is possible your results 69 | may differ slightly due to external factors such as settings and which operating system is used. 70 | If you believe the data above is incorrect, or if you think we are missing an important browser 71 | or device, please open a bug report at Github. 72 |
73 |
74 | 75 | 125 |
126 | 127 | 139 |
140 |
141 | 142 | 143 | -------------------------------------------------------------------------------- /fonts/html5test.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/fonts/html5test.eot -------------------------------------------------------------------------------- /fonts/html5test.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/fonts/html5test.ttf -------------------------------------------------------------------------------- /fonts/html5test.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/fonts/html5test.woff -------------------------------------------------------------------------------- /fonts/leaguegothic-condensed-italic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/fonts/leaguegothic-condensed-italic-webfont.eot -------------------------------------------------------------------------------- /fonts/leaguegothic-condensed-italic-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/fonts/leaguegothic-condensed-italic-webfont.ttf -------------------------------------------------------------------------------- /fonts/leaguegothic-condensed-italic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/fonts/leaguegothic-condensed-italic-webfont.woff -------------------------------------------------------------------------------- /fonts/leaguegothic-condensed-regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/fonts/leaguegothic-condensed-regular-webfont.eot -------------------------------------------------------------------------------- /fonts/leaguegothic-condensed-regular-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/fonts/leaguegothic-condensed-regular-webfont.ttf -------------------------------------------------------------------------------- /fonts/leaguegothic-condensed-regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/fonts/leaguegothic-condensed-regular-webfont.woff -------------------------------------------------------------------------------- /fonts/leaguegothic-italic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/fonts/leaguegothic-italic-webfont.eot -------------------------------------------------------------------------------- /fonts/leaguegothic-italic-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/fonts/leaguegothic-italic-webfont.ttf -------------------------------------------------------------------------------- /fonts/leaguegothic-italic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/fonts/leaguegothic-italic-webfont.woff -------------------------------------------------------------------------------- /fonts/leaguegothic-regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/fonts/leaguegothic-regular-webfont.eot -------------------------------------------------------------------------------- /fonts/leaguegothic-regular-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/fonts/leaguegothic-regular-webfont.ttf -------------------------------------------------------------------------------- /fonts/leaguegothic-regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/fonts/leaguegothic-regular-webfont.woff -------------------------------------------------------------------------------- /fonts/stylesheet.css: -------------------------------------------------------------------------------- 1 | /* Regular */ 2 | @font-face { 3 | font-family: 'League Gothic'; 4 | src: url('leaguegothic-italic-webfont.eot'); 5 | src: url('leaguegothic-italic-webfont.eot?#iefix') format('embedded-opentype'), 6 | url('leaguegothic-italic-webfont.woff') format('woff'), 7 | url('leaguegothic-italic-webfont.ttf') format('truetype'), 8 | url('leaguegothic-italic-webfont.svg#league_gothic_italicregular') format('svg'); 9 | font-weight: normal; 10 | font-style: italic; 11 | 12 | } 13 | 14 | /* Italic */ 15 | @font-face { 16 | font-family: 'League Gothic'; 17 | src: url('leaguegothic-regular-webfont.eot'); 18 | src: url('leaguegothic-regular-webfont.eot?#iefix') format('embedded-opentype'), 19 | url('leaguegothic-regular-webfont.woff') format('woff'), 20 | url('leaguegothic-regular-webfont.ttf') format('truetype'), 21 | url('leaguegothic-regular-webfont.svg#league_gothicregular') format('svg'); 22 | font-weight: normal; 23 | font-style: normal; 24 | 25 | } 26 | 27 | /* Condensed */ 28 | @font-face { 29 | font-family: 'League Gothic Condensed'; 30 | src: url('leaguegothic-condensed-regular-webfont.eot'); 31 | src: url('leaguegothic-condensed-regular-webfont.eot?#iefix') format('embedded-opentype'), 32 | url('leaguegothic-condensed-regular-webfont.woff') format('woff'), 33 | url('leaguegothic-condensed-regular-webfont.ttf') format('truetype'), 34 | url('leaguegothic-condensed-regular-webfont.svg#league_gothic_condensed-Rg') format('svg'); 35 | font-weight: normal; 36 | font-style: normal; 37 | 38 | } 39 | 40 | /* Condensed Italic */ 41 | @font-face { 42 | font-family: 'League Gothic Condensed'; 43 | src: url('leaguegothic-condensed-italic-webfont.eot'); 44 | src: url('leaguegothic-condensed-italic-webfont.eot?#iefix') format('embedded-opentype'), 45 | url('leaguegothic-condensed-italic-webfont.woff') format('woff'), 46 | url('leaguegothic-condensed-italic-webfont.ttf') format('truetype'), 47 | url('leaguegothic-condensed-italic-webfont.svg#league_gothic_condensed_itaRg') format('svg'); 48 | font-weight: normal; 49 | font-style: italic; 50 | } -------------------------------------------------------------------------------- /images/external/ecma.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/external/ecma.png -------------------------------------------------------------------------------- /images/external/khronos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/external/khronos.png -------------------------------------------------------------------------------- /images/external/mdn.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/external/ricg.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/external/w3c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/external/w3c.png -------------------------------------------------------------------------------- /images/external/whatwg.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/external/wp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/external/wp.png -------------------------------------------------------------------------------- /images/html5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/html5.png -------------------------------------------------------------------------------- /images/html5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/html5@2x.png -------------------------------------------------------------------------------- /images/html5test.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/icons/apple-touch-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/icons/apple-touch-icon-114x114.png -------------------------------------------------------------------------------- /images/icons/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/icons/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /images/icons/apple-touch-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/icons/apple-touch-icon-144x144.png -------------------------------------------------------------------------------- /images/icons/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/icons/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /images/icons/apple-touch-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/icons/apple-touch-icon-57x57.png -------------------------------------------------------------------------------- /images/icons/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/icons/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /images/icons/apple-touch-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/icons/apple-touch-icon-72x72.png -------------------------------------------------------------------------------- /images/icons/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/icons/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /images/icons/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/icons/apple-touch-icon-precomposed.png -------------------------------------------------------------------------------- /images/icons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/icons/apple-touch-icon.png -------------------------------------------------------------------------------- /images/icons/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | #0092bf 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /images/icons/favicon-160x160.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/icons/favicon-160x160.png -------------------------------------------------------------------------------- /images/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/icons/favicon-16x16.png -------------------------------------------------------------------------------- /images/icons/favicon-196x196.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/icons/favicon-196x196.png -------------------------------------------------------------------------------- /images/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/icons/favicon-32x32.png -------------------------------------------------------------------------------- /images/icons/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/icons/favicon-96x96.png -------------------------------------------------------------------------------- /images/icons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/icons/favicon.ico -------------------------------------------------------------------------------- /images/icons/mstile-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/icons/mstile-144x144.png -------------------------------------------------------------------------------- /images/icons/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/icons/mstile-150x150.png -------------------------------------------------------------------------------- /images/icons/mstile-310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/icons/mstile-310x150.png -------------------------------------------------------------------------------- /images/icons/mstile-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/icons/mstile-310x310.png -------------------------------------------------------------------------------- /images/icons/mstile-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/icons/mstile-70x70.png -------------------------------------------------------------------------------- /images/sponsors/blackberry.svg: -------------------------------------------------------------------------------- 1 | image/svg+xml -------------------------------------------------------------------------------- /images/sponsors/cloudvps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/sponsors/cloudvps.png -------------------------------------------------------------------------------- /images/sponsors/cloudvps@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/sponsors/cloudvps@2x.png -------------------------------------------------------------------------------- /images/sponsors/google.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/sponsors/google.png -------------------------------------------------------------------------------- /images/sponsors/google.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/sponsors/labup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/sponsors/labup.png -------------------------------------------------------------------------------- /images/sponsors/nokia.svg: -------------------------------------------------------------------------------- 1 | Nokia -------------------------------------------------------------------------------- /images/sponsors/salonhub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/sponsors/salonhub.png -------------------------------------------------------------------------------- /images/thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/niutech/html5test/bd580700b411dc93cb924e19654355393c34b7e9/images/thumbnail.jpg -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | HTML5test - How well does your browser support HTML5? 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 59 | 60 |
61 |
62 |

HTML5test how well does your browser support HTML5?

63 | 64 | 74 |
75 | 76 |
77 | 82 | 83 |
84 | 85 |
86 | 87 | 147 |
148 |
149 |
150 | 151 | 262 | 263 | 264 | -------------------------------------------------------------------------------- /qr.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | HTML5test - How well does your browser support HTML5? 5 | 6 | 7 | 8 | 30 | 31 | 32 | 33 | 34 | 35 |
36 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /results/latest.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HTML5test - How well does your browser support HTML5? 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
34 |

HTML5test how well does your browser support HTML5?

35 | 45 |
46 | 47 |
48 |
49 |
50 | 58 | 59 |
60 |
61 | 62 |

Latest results

63 | 64 |
65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 |
ScoreBrowserWhen
76 |

77 | Please note that all data shown above are unconfirmed test results. They could be fake or 78 | belong to a different browser than the one listed. 79 |

80 |
81 | 82 | 130 |
131 |
132 | 133 | 145 |
146 |
147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /results/search.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HTML5test - How well does your browser support HTML5? 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
34 |

HTML5test how well does your browser support HTML5?

35 | 45 |
46 | 47 |
48 |
49 |
50 | 58 | 59 |
60 |
61 |
62 | 63 |
64 |
65 |
66 |
67 |
68 | 69 | 95 |
96 | 97 | 180 | 181 |
182 | 183 |

Examples

184 |
185 |
186 |
deviceType:mobile osName:Windows 188 |
189 |
All mobile devices running Windows
190 | 191 |
deviceManufacturer:Samsung -osName:Android 193 |
194 |
All non-Android devices created by Samsung
195 | 196 |
osName:Android osVersion:4.4 198 |
199 |
All devices running Android 4.4
200 | 201 |
browserName:Chrome osName:"Mac OS X" 203 |
204 |
Chrome running on OS X
205 | 206 |
deviceModel:iPhone
207 |
All iPhones
208 | 209 |
engineName:Gecko -browserName:Firefox 211 |
212 |
All Gecko based browser except for Firefox
213 | 214 |
score:500+
215 |
All results with a score higher than or equal to 500
216 |
217 |
218 |
219 |
220 | 221 | 233 |
234 |
235 | 236 | 237 | 238 | -------------------------------------------------------------------------------- /s/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | HTML5test - How well does your browser support HTML5? 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
34 |

HTML5test how well does your browser support HTML5?

35 | 45 |
46 | 47 |
48 |
49 |
50 |
51 | 52 | 65 |
66 |
67 | 68 | 69 | 170 | 171 | 172 | -------------------------------------------------------------------------------- /scripts/fullscreen.js: -------------------------------------------------------------------------------- 1 | (function (doc) { 2 | 3 | var 4 | pollute = true, 5 | api, vendor, 6 | apis = { 7 | // http://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html 8 | w3: { 9 | enabled: "fullscreenEnabled", 10 | element: "fullscreenElement", 11 | request: "requestFullscreen", 12 | exit: "exitFullscreen", 13 | events: { 14 | change: "fullscreenchange", 15 | error: "fullscreenerror" 16 | } 17 | }, 18 | webkit: { 19 | enabled: "webkitIsFullScreen", 20 | element: "webkitCurrentFullScreenElement", 21 | request: "webkitRequestFullScreen", 22 | exit: "webkitCancelFullScreen", 23 | events: { 24 | change: "webkitfullscreenchange", 25 | error: "webkitfullscreenerror" 26 | } 27 | }, 28 | moz: { 29 | enabled: "mozFullScreen", 30 | element: "mozFullScreenElement", 31 | request: "mozRequestFullScreen", 32 | exit: "mozCancelFullScreen", 33 | events: { 34 | change: "mozfullscreenchange", 35 | error: "mozfullscreenerror" 36 | } 37 | } 38 | }, 39 | w3 = apis.w3; 40 | 41 | // Loop through each vendor's specific API 42 | for (vendor in apis) { 43 | // Check if document has the "enabled" property 44 | if (apis[vendor].enabled in doc) { 45 | // It seems this browser support the fullscreen API 46 | api = apis[vendor]; 47 | break; 48 | } 49 | } 50 | 51 | function dispatch(type, target) { 52 | var event = doc.createEvent("Event"); 53 | event.initEvent(type, true, false); 54 | target.dispatchEvent(event); 55 | } // end of dispatch() 56 | 57 | function handleChange(e) { 58 | // Recopy the enabled and element values 59 | doc[w3.enabled] = doc[api.enabled]; 60 | doc[w3.element] = doc[api.element]; 61 | 62 | dispatch(w3.events.change, e.target); 63 | } // end of handleChange() 64 | 65 | function handleError(e) { 66 | dispatch(w3.events.error, e.target); 67 | } // end of handleError() 68 | 69 | if (pollute && api && vendor !== "w3") { 70 | // Add listeners for fullscreen events 71 | doc.addEventListener(api.events.change, handleChange, false); 72 | doc.addEventListener(api.events.error, handleError, false); 73 | 74 | // Copy the default value 75 | doc[w3.enabled] = doc[api.enabled]; 76 | doc[w3.element] = doc[api.element]; 77 | 78 | // Match the reference for exitFullscreen 79 | doc[w3.exit] = doc[api.exit]; 80 | 81 | // Add the request method to the Element's prototype 82 | Element.prototype[w3.request] = function () { 83 | return this[api.request].apply(this, arguments); 84 | }; 85 | } 86 | 87 | // Return the API found (or undefined if the Fullscreen API is unavailable) 88 | return api; 89 | 90 | }(document)); -------------------------------------------------------------------------------- /scripts/highcharts/adapters/mootools-adapter.js: -------------------------------------------------------------------------------- 1 | /* 2 | Highcharts JS v2.2.1 (2012-03-15) 3 | MooTools adapter 4 | 5 | (c) 2010-2011 Torstein H?nsi 6 | 7 | License: www.highcharts.com/license 8 | */ 9 | (function(){var e=window,i=document,f=e.MooTools.version.substring(0,3),g=f==="1.2"||f==="1.1",j=g||f==="1.3",h=e.$extend||function(){return Object.append.apply(Object,arguments)};e.HighchartsAdapter={init:function(a){var b=Fx.prototype,c=b.start,d=Fx.Morph.prototype,e=d.compute;b.start=function(b,d){var e=this.element;if(b.d)this.paths=a.init(e,e.d,this.toD);c.apply(this,arguments);return this};d.compute=function(b,c,d){var f=this.paths;if(f)this.element.attr("d",a.step(f[0],f[1],d,this.toD));else return e.apply(this, 10 | arguments)}},getScript:function(a,b){var c=i.getElementsByTagName("head")[0],d=i.createElement("script");d.type="text/javascript";d.src=a;d.onload=b;c.appendChild(d)},animate:function(a,b,c){var d=a.attr,f=c&&c.complete;if(d&&!a.setStyle)a.getStyle=a.attr,a.setStyle=function(){var b=arguments;a.attr.call(a,b[0],b[1][0])},a.$family=function(){return!0};e.HighchartsAdapter.stop(a);c=new Fx.Morph(d?a:$(a),h({transition:Fx.Transitions.Quad.easeInOut},c));if(d)c.element=a;if(b.d)c.toD=b.d;f&&c.addEvent("complete", 11 | f);c.start(b);a.fx=c},each:function(a,b){return g?$each(a,b):Array.each(a,b)},map:function(a,b){return a.map(b)},grep:function(a,b){return a.filter(b)},merge:function(){var a=arguments,b=[{}],c=a.length;if(g)a=$merge.apply(null,a);else{for(;c--;)typeof a[c]!=="boolean"&&(b[c+1]=a[c]);a=Object.merge.apply(Object,b)}return a},offset:function(a){a=$(a).getOffsets();return{left:a.x,top:a.y}},extendWithEvents:function(a){a.addEvent||(a.nodeName?$(a):h(a,new Events))},addEvent:function(a,b,c){typeof b=== 12 | "string"&&(b==="unload"&&(b="beforeunload"),e.HighchartsAdapter.extendWithEvents(a),a.addEvent(b,c))},removeEvent:function(a,b,c){typeof a!=="string"&&(e.HighchartsAdapter.extendWithEvents(a),b?(b==="unload"&&(b="beforeunload"),c?a.removeEvent(b,c):a.removeEvents(b)):a.removeEvents())},fireEvent:function(a,b,c,d){b={type:b,target:a};b=j?new Event(b):new DOMEvent(b);b=h(b,c);b.preventDefault=function(){d=null};a.fireEvent&&a.fireEvent(b.type,b);d&&d(b)},stop:function(a){a.fx&&a.fx.cancel()}}})(); 13 | -------------------------------------------------------------------------------- /scripts/highcharts/adapters/mootools-adapter.src.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license Highcharts JS v2.2.1 (2012-03-15) 3 | * MooTools adapter 4 | * 5 | * (c) 2010-2011 Torstein Hønsi 6 | * 7 | * License: www.highcharts.com/license 8 | */ 9 | 10 | // JSLint options: 11 | /*global Fx, $, $extend, $each, $merge, Events, Event, DOMEvent */ 12 | 13 | (function () { 14 | 15 | var win = window, 16 | doc = document, 17 | mooVersion = win.MooTools.version.substring(0, 3), // Get the first three characters of the version number 18 | legacy = mooVersion === '1.2' || mooVersion === '1.1', // 1.1 && 1.2 considered legacy, 1.3 is not. 19 | legacyEvent = legacy || mooVersion === '1.3', // In versions 1.1 - 1.3 the event class is named Event, in newer versions it is named DOMEvent. 20 | $extend = win.$extend || function () { 21 | return Object.append.apply(Object, arguments); 22 | }; 23 | 24 | win.HighchartsAdapter = { 25 | /** 26 | * Initialize the adapter. This is run once as Highcharts is first run. 27 | * @param {Object} pathAnim The helper object to do animations across adapters. 28 | */ 29 | init: function (pathAnim) { 30 | var fxProto = Fx.prototype, 31 | fxStart = fxProto.start, 32 | morphProto = Fx.Morph.prototype, 33 | morphCompute = morphProto.compute; 34 | 35 | // override Fx.start to allow animation of SVG element wrappers 36 | /*jslint unparam: true*//* allow unused parameters in fx functions */ 37 | fxProto.start = function (from, to) { 38 | var fx = this, 39 | elem = fx.element; 40 | 41 | // special for animating paths 42 | if (from.d) { 43 | //this.fromD = this.element.d.split(' '); 44 | fx.paths = pathAnim.init( 45 | elem, 46 | elem.d, 47 | fx.toD 48 | ); 49 | } 50 | fxStart.apply(fx, arguments); 51 | 52 | return this; // chainable 53 | }; 54 | 55 | // override Fx.step to allow animation of SVG element wrappers 56 | morphProto.compute = function (from, to, delta) { 57 | var fx = this, 58 | paths = fx.paths; 59 | 60 | if (paths) { 61 | fx.element.attr( 62 | 'd', 63 | pathAnim.step(paths[0], paths[1], delta, fx.toD) 64 | ); 65 | } else { 66 | return morphCompute.apply(fx, arguments); 67 | } 68 | }; 69 | /*jslint unparam: false*/ 70 | }, 71 | 72 | /** 73 | * Downloads a script and executes a callback when done. 74 | * @param {String} scriptLocation 75 | * @param {Function} callback 76 | */ 77 | getScript: function (scriptLocation, callback) { 78 | // We cannot assume that Assets class from mootools-more is available so instead insert a script tag to download script. 79 | var head = doc.getElementsByTagName('head')[0]; 80 | var script = doc.createElement('script'); 81 | 82 | script.type = 'text/javascript'; 83 | script.src = scriptLocation; 84 | script.onload = callback; 85 | 86 | head.appendChild(script); 87 | }, 88 | 89 | /** 90 | * Animate a HTML element or SVG element wrapper 91 | * @param {Object} el 92 | * @param {Object} params 93 | * @param {Object} options jQuery-like animation options: duration, easing, callback 94 | */ 95 | animate: function (el, params, options) { 96 | var isSVGElement = el.attr, 97 | effect, 98 | complete = options && options.complete; 99 | 100 | if (isSVGElement && !el.setStyle) { 101 | // add setStyle and getStyle methods for internal use in Moo 102 | el.getStyle = el.attr; 103 | el.setStyle = function () { // property value is given as array in Moo - break it down 104 | var args = arguments; 105 | el.attr.call(el, args[0], args[1][0]); 106 | }; 107 | // dirty hack to trick Moo into handling el as an element wrapper 108 | el.$family = function () { return true; }; 109 | } 110 | 111 | // stop running animations 112 | win.HighchartsAdapter.stop(el); 113 | 114 | // define and run the effect 115 | effect = new Fx.Morph( 116 | isSVGElement ? el : $(el), 117 | $extend({ 118 | transition: Fx.Transitions.Quad.easeInOut 119 | }, options) 120 | ); 121 | 122 | // Make sure that the element reference is set when animating svg elements 123 | if (isSVGElement) { 124 | effect.element = el; 125 | } 126 | 127 | // special treatment for paths 128 | if (params.d) { 129 | effect.toD = params.d; 130 | } 131 | 132 | // jQuery-like events 133 | if (complete) { 134 | effect.addEvent('complete', complete); 135 | } 136 | 137 | // run 138 | effect.start(params); 139 | 140 | // record for use in stop method 141 | el.fx = effect; 142 | }, 143 | 144 | /** 145 | * MooTool's each function 146 | * 147 | */ 148 | each: function (arr, fn) { 149 | return legacy ? 150 | $each(arr, fn) : 151 | Array.each(arr, fn); 152 | }, 153 | 154 | /** 155 | * Map an array 156 | * @param {Array} arr 157 | * @param {Function} fn 158 | */ 159 | map: function (arr, fn) { 160 | return arr.map(fn); 161 | }, 162 | 163 | /** 164 | * Grep or filter an array 165 | * @param {Array} arr 166 | * @param {Function} fn 167 | */ 168 | grep: function (arr, fn) { 169 | return arr.filter(fn); 170 | }, 171 | 172 | /** 173 | * Deep merge two objects and return a third 174 | */ 175 | merge: function () { 176 | var args = arguments, 177 | args13 = [{}], // MooTools 1.3+ 178 | i = args.length, 179 | ret; 180 | 181 | if (legacy) { 182 | ret = $merge.apply(null, args); 183 | } else { 184 | while (i--) { 185 | // Boolean argumens should not be merged. 186 | // JQuery explicitly skips this, so we do it here as well. 187 | if (typeof args[i] !== 'boolean') { 188 | args13[i + 1] = args[i]; 189 | } 190 | } 191 | ret = Object.merge.apply(Object, args13); 192 | } 193 | 194 | return ret; 195 | }, 196 | 197 | /** 198 | * Get the offset of an element relative to the top left corner of the web page 199 | */ 200 | offset: function (el) { 201 | var offsets = $(el).getOffsets(); 202 | return { 203 | left: offsets.x, 204 | top: offsets.y 205 | }; 206 | }, 207 | 208 | /** 209 | * Extends an object with Events, if its not done 210 | */ 211 | extendWithEvents: function (el) { 212 | // if the addEvent method is not defined, el is a custom Highcharts object 213 | // like series or point 214 | if (!el.addEvent) { 215 | if (el.nodeName) { 216 | el = $(el); // a dynamically generated node 217 | } else { 218 | $extend(el, new Events()); // a custom object 219 | } 220 | } 221 | }, 222 | 223 | /** 224 | * Add an event listener 225 | * @param {Object} el HTML element or custom object 226 | * @param {String} type Event type 227 | * @param {Function} fn Event handler 228 | */ 229 | addEvent: function (el, type, fn) { 230 | if (typeof type === 'string') { // chart broke due to el being string, type function 231 | 232 | if (type === 'unload') { // Moo self destructs before custom unload events 233 | type = 'beforeunload'; 234 | } 235 | 236 | win.HighchartsAdapter.extendWithEvents(el); 237 | 238 | el.addEvent(type, fn); 239 | } 240 | }, 241 | 242 | removeEvent: function (el, type, fn) { 243 | if (typeof el === 'string') { 244 | // el.removeEvents below apperantly calls this method again. Do not quite understand why, so for now just bail out. 245 | return; 246 | } 247 | win.HighchartsAdapter.extendWithEvents(el); 248 | if (type) { 249 | if (type === 'unload') { // Moo self destructs before custom unload events 250 | type = 'beforeunload'; 251 | } 252 | 253 | if (fn) { 254 | el.removeEvent(type, fn); 255 | } else { 256 | el.removeEvents(type); 257 | } 258 | } else { 259 | el.removeEvents(); 260 | } 261 | }, 262 | 263 | fireEvent: function (el, event, eventArguments, defaultFunction) { 264 | var eventArgs = { 265 | type: event, 266 | target: el 267 | }; 268 | // create an event object that keeps all functions 269 | event = legacyEvent ? new Event(eventArgs) : new DOMEvent(eventArgs); 270 | event = $extend(event, eventArguments); 271 | // override the preventDefault function to be able to use 272 | // this for custom events 273 | event.preventDefault = function () { 274 | defaultFunction = null; 275 | }; 276 | // if fireEvent is not available on the object, there hasn't been added 277 | // any events to it above 278 | if (el.fireEvent) { 279 | el.fireEvent(event.type, event); 280 | } 281 | 282 | // fire the default if it is passed and it is not prevented above 283 | if (defaultFunction) { 284 | defaultFunction(event); 285 | } 286 | }, 287 | 288 | /** 289 | * Stop running animations on the object 290 | */ 291 | stop: function (el) { 292 | if (el.fx) { 293 | el.fx.cancel(); 294 | } 295 | } 296 | }; 297 | 298 | }()); 299 | -------------------------------------------------------------------------------- /scripts/highcharts/adapters/prototype-adapter.js: -------------------------------------------------------------------------------- 1 | /* 2 | Highcharts JS v2.2.1 (2012-03-15) 3 | Prototype adapter 4 | 5 | @author Michael Nelson, Torstein H?nsi. 6 | 7 | Feel free to use and modify this script. 8 | Highcharts license: www.highcharts.com/license. 9 | */ 10 | var HighchartsAdapter=function(){var g=typeof Effect!=="undefined";return{init:function(c){if(g)Effect.HighchartsTransition=Class.create(Effect.Base,{initialize:function(a,b,d,e){var f;this.element=a;this.key=b;f=a.attr?a.attr(b):$(a).getStyle(b);if(b==="d")this.paths=c.init(a,a.d,d),this.toD=d,f=0,d=1;this.start(Object.extend(e||{},{from:f,to:d,attribute:b}))},setup:function(){HighchartsAdapter._extend(this.element);if(!this.element._highchart_animation)this.element._highchart_animation={};this.element._highchart_animation[this.key]= 11 | this},update:function(a){var b=this.paths,d=this.element;b&&(a=c.step(b[0],b[1],a,this.toD));d.attr?d.attr(this.options.attribute,a):(b={},b[this.options.attribute]=a,$(d).setStyle(b))},finish:function(){delete this.element._highchart_animation[this.key]}})},getScript:function(c,a){var b=$$("head")[0];b&&b.appendChild((new Element("script",{type:"text/javascript",src:c})).observe("load",a))},addNS:function(c){var a=/^(?:click|mouse(?:down|up|over|move|out))$/;return/^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/.test(c)|| 12 | a.test(c)?c:"h:"+c},addEvent:function(c,a,b){c.addEventListener||c.attachEvent?Event.observe($(c),HighchartsAdapter.addNS(a),b):(HighchartsAdapter._extend(c),c._highcharts_observe(a,b))},animate:function(c,a,b){var d,b=b||{};b.delay=0;b.duration=(b.duration||500)/1E3;b.afterFinish=b.complete;if(g)for(d in a)new Effect.HighchartsTransition($(c),d,a[d],b);else{if(c.attr)for(d in a)c.attr(d,a[d]);b.complete&&b.complete()}c.attr||$(c).setStyle(a)},stop:function(c){var a;if(c._highcharts_extended&&c._highchart_animation)for(a in c._highchart_animation)c._highchart_animation[a].cancel()}, 13 | each:function(c,a){$A(c).each(a)},offset:function(c){return $(c).cumulativeOffset()},fireEvent:function(c,a,b,d){c.fire?c.fire(HighchartsAdapter.addNS(a),b):c._highcharts_extended&&(b=b||{},c._highcharts_fire(a,b));b&&b.defaultPrevented&&(d=null);d&&d(b)},removeEvent:function(c,a,b){$(c).stopObserving&&(a&&(a=HighchartsAdapter.addNS(a)),$(c).stopObserving(a,b));window===c?Event.stopObserving(c,a,b):(HighchartsAdapter._extend(c),c._highcharts_stop_observing(a,b))},grep:function(c,a){return c.findAll(a)}, 14 | map:function(c,a){return c.map(a)},merge:function(){function c(a,b){var d,e;for(e in b)d=b[e],a[e]=d&&typeof d==="object"&&d.constructor!==Array&&typeof d.nodeType!=="number"?c(a[e]||{},d):b[e];return a}return function(){var a=arguments,b,d={};for(b=0;b {a : 'a', b : {b1 : 'b1', b2 : 'b2_prime'}, c : 'c'} 244 | /*merge: function(){ 245 | function doCopy(copy, original) { 246 | var value, 247 | key, 248 | undef, 249 | nil, 250 | same, 251 | obj, 252 | arr, 253 | node; 254 | 255 | for (key in original) { 256 | value = original[key]; 257 | undef = typeof(value) === 'undefined'; 258 | nil = value === null; 259 | same = original === copy[key]; 260 | 261 | if (undef || nil || same) { 262 | continue; 263 | } 264 | 265 | obj = typeof(value) === 'object'; 266 | arr = value && obj && value.constructor == Array; 267 | node = !!value.nodeType; 268 | 269 | if (obj && !arr && !node) { 270 | copy[key] = doCopy(typeof copy[key] == 'object' ? copy[key] : {}, value); 271 | } 272 | else { 273 | copy[key] = original[key]; 274 | } 275 | } 276 | return copy; 277 | } 278 | 279 | var args = arguments, retVal = {}; 280 | 281 | for (var i = 0; i < args.length; i++) { 282 | retVal = doCopy(retVal, args[i]); 283 | } 284 | 285 | return retVal; 286 | },*/ 287 | merge: function () { // the built-in prototype merge function doesn't do deep copy 288 | function doCopy(copy, original) { 289 | var value, key; 290 | 291 | for (key in original) { 292 | value = original[key]; 293 | if (value && typeof value === 'object' && value.constructor !== Array && 294 | typeof value.nodeType !== 'number') { 295 | copy[key] = doCopy(copy[key] || {}, value); // copy 296 | 297 | } else { 298 | copy[key] = original[key]; 299 | } 300 | } 301 | return copy; 302 | } 303 | 304 | function merge() { 305 | var args = arguments, 306 | i, 307 | retVal = {}; 308 | 309 | for (i = 0; i < args.length; i++) { 310 | retVal = doCopy(retVal, args[i]); 311 | 312 | } 313 | return retVal; 314 | } 315 | 316 | return merge.apply(this, arguments); 317 | }, 318 | 319 | // extend an object to handle highchart events (highchart objects, not svg elements). 320 | // this is a very simple way of handling events but whatever, it works (i think) 321 | _extend: function (object) { 322 | if (!object._highcharts_extended) { 323 | Object.extend(object, { 324 | _highchart_events: {}, 325 | _highchart_animation: null, 326 | _highcharts_extended: true, 327 | _highcharts_observe: function (name, fn) { 328 | this._highchart_events[name] = [this._highchart_events[name], fn].compact().flatten(); 329 | }, 330 | _highcharts_stop_observing: function (name, fn) { 331 | if (name) { 332 | if (fn) { 333 | this._highchart_events[name] = [this._highchart_events[name]].compact().flatten().without(fn); 334 | } else { 335 | delete this._highchart_events[name]; 336 | } 337 | } else { 338 | this._highchart_events = {}; 339 | } 340 | }, 341 | _highcharts_fire: function (name, args) { 342 | (this._highchart_events[name] || []).each(function (fn) { 343 | // args is never null here 344 | if (args.stopped) { 345 | return; // "throw $break" wasn't working. i think because of the scope of 'this'. 346 | } 347 | 348 | // Attach a simple preventDefault function to skip default handler if called 349 | args.preventDefault = function () { 350 | args.defaultPrevented = true; 351 | }; 352 | 353 | // If the event handler return false, prevent the default handler from executing 354 | if (fn.bind(this)(args) === false) { 355 | args.preventDefault(); 356 | } 357 | } 358 | .bind(this)); 359 | } 360 | }); 361 | } 362 | } 363 | }; 364 | }()); 365 | -------------------------------------------------------------------------------- /scripts/highcharts/modules/exporting.js: -------------------------------------------------------------------------------- 1 | /* 2 | Highcharts JS v2.2.1 (2012-03-15) 3 | Exporting module 4 | 5 | (c) 2010-2011 Torstein H?nsi 6 | 7 | License: www.highcharts.com/license 8 | */ 9 | (function(){function x(a){for(var b=a.length;b--;)typeof a[b]==="number"&&(a[b]=Math.round(a[b])-0.5);return a}var f=Highcharts,y=f.Chart,z=f.addEvent,B=f.removeEvent,r=f.createElement,u=f.discardElement,t=f.css,s=f.merge,k=f.each,n=f.extend,C=Math.max,h=document,D=window,A=h.documentElement.ontouchstart!==void 0,v=f.getOptions();n(v.lang,{downloadPNG:"Download PNG image",downloadJPEG:"Download JPEG image",downloadPDF:"Download PDF document",downloadSVG:"Download SVG vector image",exportButtonTitle:"Export to raster or vector image", 10 | printButtonTitle:"Print the chart"});v.navigation={menuStyle:{border:"1px solid #A0A0A0",background:"#FFFFFF"},menuItemStyle:{padding:"0 5px",background:"none",color:"#303030",fontSize:A?"14px":"11px"},menuItemHoverStyle:{background:"#4572A5",color:"#FFFFFF"},buttonOptions:{align:"right",backgroundColor:{linearGradient:[0,0,0,20],stops:[[0.4,"#F7F7F7"],[0.6,"#E3E3E3"]]},borderColor:"#B0B0B0",borderRadius:3,borderWidth:1,height:20,hoverBorderColor:"#909090",hoverSymbolFill:"#81A7CF",hoverSymbolStroke:"#4572A5", 11 | symbolFill:"#E0E0E0",symbolStroke:"#A0A0A0",symbolX:11.5,symbolY:10.5,verticalAlign:"top",width:24,y:10}};v.exporting={type:"image/png",url:"http://export.highcharts.com/",width:800,buttons:{exportButton:{symbol:"exportIcon",x:-10,symbolFill:"#A8BF77",hoverSymbolFill:"#768F3E",_id:"exportButton",_titleKey:"exportButtonTitle",menuItems:[{textKey:"downloadPNG",onclick:function(){this.exportChart()}},{textKey:"downloadJPEG",onclick:function(){this.exportChart({type:"image/jpeg"})}},{textKey:"downloadPDF", 12 | onclick:function(){this.exportChart({type:"application/pdf"})}},{textKey:"downloadSVG",onclick:function(){this.exportChart({type:"image/svg+xml"})}}]},printButton:{symbol:"printIcon",x:-36,symbolFill:"#B5C9DF",hoverSymbolFill:"#779ABF",_id:"printButton",_titleKey:"printButtonTitle",onclick:function(){this.print()}}}};n(y.prototype,{getSVG:function(a){var b=this,c,d,e,g=s(b.options,a);if(!h.createElementNS)h.createElementNS=function(a,b){var c=h.createElement(b);c.getBBox=function(){return f.Renderer.prototype.Element.prototype.getBBox.apply({element:c})}; 13 | return c};a=r("div",null,{position:"absolute",top:"-9999em",width:b.chartWidth+"px",height:b.chartHeight+"px"},h.body);n(g.chart,{renderTo:a,forExport:!0});g.exporting.enabled=!1;g.chart.plotBackgroundImage=null;g.series=[];k(b.series,function(a){e=s(a.options,{animation:!1,showCheckbox:!1,visible:a.visible});if(!e.isInternal){if(e&&e.marker&&/^url\(/.test(e.marker.symbol))e.marker.symbol="circle";g.series.push(e)}});c=new Highcharts.Chart(g);k(["xAxis","yAxis"],function(a){k(b[a],function(b,d){var e= 14 | c[a][d],g=b.getExtremes(),f=g.userMin,g=g.userMax;(f!==void 0||g!==void 0)&&e.setExtremes(f,g,!0,!1)})});d=c.container.innerHTML;g=null;c.destroy();u(a);d=d.replace(/zIndex="[^"]+"/g,"").replace(/isShadow="[^"]+"/g,"").replace(/symbolName="[^"]+"/g,"").replace(/jQuery[0-9]+="[^"]+"/g,"").replace(/isTracker="[^"]+"/g,"").replace(/url\([^#]+#/g,"url(#").replace(//g,'xlink:href="$1"/>').replace(/id=([^" >]+)/g,'id="$1"').replace(/class=([^" ]+)/g,'class="$1"').replace(/ transform /g," ").replace(/:(path|rect)/g,"$1").replace(/style="([^"]+)"/g,function(a){return a.toLowerCase()});d=d.replace(/(url\(#highcharts-[0-9]+)"/g,"$1").replace(/"/g,"'");d.match(/ xmlns="/g).length===2&&(d=d.replace(/xmlns="[^"]+"/, 16 | ""));return d},exportChart:function(a,b){var c,d=this.getSVG(s(this.options.exporting.chartOptions,b)),a=s(this.options.exporting,a);c=r("form",{method:"post",action:a.url},{display:"none"},h.body);k(["filename","type","width","svg"],function(b){r("input",{type:"hidden",name:b,value:{filename:a.filename||"chart",type:a.type,width:a.width,svg:d}[b]},null,c)});c.submit();u(c)},print:function(){var a=this,b=a.container,c=[],d=b.parentNode,e=h.body,g=e.childNodes;if(!a.isPrinting)a.isPrinting=!0,k(g, 17 | function(a,b){if(a.nodeType===1)c[b]=a.style.display,a.style.display="none"}),e.appendChild(b),D.print(),setTimeout(function(){d.appendChild(b);k(g,function(a,b){if(a.nodeType===1)a.style.display=c[b]});a.isPrinting=!1},1E3)},contextMenu:function(a,b,c,d,e,g){var i=this,f=i.options.navigation,h=f.menuItemStyle,o=i.chartWidth,p=i.chartHeight,q="cache-"+a,j=i[q],l=C(e,g),m,w;if(!j)i[q]=j=r("div",{className:"highcharts-"+a},{position:"absolute",zIndex:1E3,padding:l+"px"},i.container),m=r("div",null, 18 | n({MozBoxShadow:"3px 3px 10px #888",WebkitBoxShadow:"3px 3px 10px #888",boxShadow:"3px 3px 10px #888"},f.menuStyle),j),w=function(){t(j,{display:"none"})},z(j,"mouseleave",w),k(b,function(a){if(a){var b=r("div",{onmouseover:function(){t(this,f.menuItemHoverStyle)},onmouseout:function(){t(this,h)},innerHTML:a.text||i.options.lang[a.textKey]},n({cursor:"pointer"},h),m);b[A?"ontouchstart":"onclick"]=function(){w();a.onclick.apply(i,arguments)};i.exportDivElements.push(b)}}),i.exportDivElements.push(m, 19 | j),i.exportMenuWidth=j.offsetWidth,i.exportMenuHeight=j.offsetHeight;a={display:"block"};c+i.exportMenuWidth>o?a.right=o-c-e-l+"px":a.left=c-l+"px";d+g+i.exportMenuHeight>p?a.bottom=p-d-l+"px":a.top=d+g-l+"px";t(j,a)},addButton:function(a){function b(){p.attr(l);o.attr(j)}var c=this,d=c.renderer,e=s(c.options.navigation.buttonOptions,a),g=e.onclick,f=e.menuItems,h=e.width,k=e.height,o,p,q,a=e.borderWidth,j={stroke:e.borderColor},l={stroke:e.symbolStroke,fill:e.symbolFill},m=e.symbolSize||12;if(!c.exportDivElements)c.exportDivElements= 20 | [],c.exportSVGElements=[];e.enabled!==!1&&(o=d.rect(0,0,h,k,e.borderRadius,a).align(e,!0).attr(n({fill:e.backgroundColor,"stroke-width":a,zIndex:19},j)).add(),q=d.rect(0,0,h,k,0).align(e).attr({id:e._id,fill:"rgba(255, 255, 255, 0.001)",title:c.options.lang[e._titleKey],zIndex:21}).css({cursor:"pointer"}).on("mouseover",function(){p.attr({stroke:e.hoverSymbolStroke,fill:e.hoverSymbolFill});o.attr({stroke:e.hoverBorderColor})}).on("mouseout",b).on("click",b).add(),f&&(g=function(){b();var a=q.getBBox(); 21 | c.contextMenu("export-menu",f,a.x,a.y,h,k)}),q.on("click",function(){g.apply(c,arguments)}),p=d.symbol(e.symbol,e.symbolX-m/2,e.symbolY-m/2,m,m).align(e,!0).attr(n(l,{"stroke-width":e.symbolStrokeWidth||1,zIndex:20})).add(),c.exportSVGElements.push(o,q,p))},destroyExport:function(){var a,b;for(a=0;a/g, '>'); 153 | 154 | doc.body.innerHTML = '
' + svg + '
'; 155 | } 156 | } // */ 157 | ] 158 | 159 | }, 160 | printButton: { 161 | //enabled: true, 162 | symbol: 'printIcon', 163 | x: -36, 164 | symbolFill: '#B5C9DF', 165 | hoverSymbolFill: '#779ABF', 166 | _id: 'printButton', 167 | _titleKey: 'printButtonTitle', 168 | onclick: function () { 169 | this.print(); 170 | } 171 | } 172 | } 173 | }; 174 | 175 | 176 | 177 | extend(Chart.prototype, { 178 | /** 179 | * Return an SVG representation of the chart 180 | * 181 | * @param additionalOptions {Object} Additional chart options for the generated SVG representation 182 | */ 183 | getSVG: function (additionalOptions) { 184 | var chart = this, 185 | chartCopy, 186 | sandbox, 187 | svg, 188 | seriesOptions, 189 | options = merge(chart.options, additionalOptions); // copy the options and add extra options 190 | 191 | // IE compatibility hack for generating SVG content that it doesn't really understand 192 | if (!doc.createElementNS) { 193 | /*jslint unparam: true*//* allow unused parameter ns in function below */ 194 | doc.createElementNS = function (ns, tagName) { 195 | var elem = doc.createElement(tagName); 196 | elem.getBBox = function () { 197 | return HC.Renderer.prototype.Element.prototype.getBBox.apply({ element: elem }); 198 | }; 199 | return elem; 200 | }; 201 | /*jslint unparam: false*/ 202 | } 203 | 204 | // create a sandbox where a new chart will be generated 205 | sandbox = createElement(DIV, null, { 206 | position: ABSOLUTE, 207 | top: '-9999em', 208 | width: chart.chartWidth + PX, 209 | height: chart.chartHeight + PX 210 | }, doc.body); 211 | 212 | // override some options 213 | extend(options.chart, { 214 | renderTo: sandbox, 215 | forExport: true 216 | }); 217 | options.exporting.enabled = false; // hide buttons in print 218 | options.chart.plotBackgroundImage = null; // the converter doesn't handle images 219 | 220 | // prepare for replicating the chart 221 | options.series = []; 222 | each(chart.series, function (serie) { 223 | seriesOptions = merge(serie.options, { 224 | animation: false, // turn off animation 225 | showCheckbox: false, 226 | visible: serie.visible 227 | }); 228 | 229 | if (!seriesOptions.isInternal) { // used for the navigator series that has its own option set 230 | 231 | // remove image markers 232 | if (seriesOptions && seriesOptions.marker && /^url\(/.test(seriesOptions.marker.symbol)) { 233 | seriesOptions.marker.symbol = 'circle'; 234 | } 235 | 236 | options.series.push(seriesOptions); 237 | } 238 | }); 239 | 240 | // generate the chart copy 241 | chartCopy = new Highcharts.Chart(options); 242 | 243 | // reflect axis extremes in the export 244 | each(['xAxis', 'yAxis'], function (axisType) { 245 | each(chart[axisType], function (axis, i) { 246 | var axisCopy = chartCopy[axisType][i], 247 | extremes = axis.getExtremes(), 248 | userMin = extremes.userMin, 249 | userMax = extremes.userMax; 250 | 251 | if (userMin !== UNDEFINED || userMax !== UNDEFINED) { 252 | axisCopy.setExtremes(userMin, userMax, true, false); 253 | } 254 | }); 255 | }); 256 | 257 | // get the SVG from the container's innerHTML 258 | svg = chartCopy.container.innerHTML; 259 | 260 | // free up memory 261 | options = null; 262 | chartCopy.destroy(); 263 | discardElement(sandbox); 264 | 265 | // sanitize 266 | svg = svg 267 | .replace(/zIndex="[^"]+"/g, '') 268 | .replace(/isShadow="[^"]+"/g, '') 269 | .replace(/symbolName="[^"]+"/g, '') 270 | .replace(/jQuery[0-9]+="[^"]+"/g, '') 271 | .replace(/isTracker="[^"]+"/g, '') 272 | .replace(/url\([^#]+#/g, 'url(#') 273 | .replace(//g, 'xlink:href="$1"/>') 289 | .replace(/id=([^" >]+)/g, 'id="$1"') 290 | .replace(/class=([^" ]+)/g, 'class="$1"') 291 | .replace(/ transform /g, ' ') 292 | .replace(/:(path|rect)/g, '$1') 293 | .replace(/style="([^"]+)"/g, function (s) { 294 | return s.toLowerCase(); 295 | }); 296 | 297 | // IE9 beta bugs with innerHTML. Test again with final IE9. 298 | svg = svg.replace(/(url\(#highcharts-[0-9]+)"/g, '$1') 299 | .replace(/"/g, "'"); 300 | if (svg.match(/ xmlns="/g).length === 2) { 301 | svg = svg.replace(/xmlns="[^"]+"/, ''); 302 | } 303 | 304 | return svg; 305 | }, 306 | 307 | /** 308 | * Submit the SVG representation of the chart to the server 309 | * @param {Object} options Exporting options. Possible members are url, type and width. 310 | * @param {Object} chartOptions Additional chart options for the SVG representation of the chart 311 | */ 312 | exportChart: function (options, chartOptions) { 313 | var form, 314 | chart = this, 315 | svg = chart.getSVG(merge(chart.options.exporting.chartOptions, chartOptions)); // docs 316 | 317 | // merge the options 318 | options = merge(chart.options.exporting, options); 319 | 320 | // create the form 321 | form = createElement('form', { 322 | method: 'post', 323 | action: options.url 324 | }, { 325 | display: NONE 326 | }, doc.body); 327 | 328 | // add the values 329 | each(['filename', 'type', 'width', 'svg'], function (name) { 330 | createElement('input', { 331 | type: HIDDEN, 332 | name: name, 333 | value: { 334 | filename: options.filename || 'chart', 335 | type: options.type, 336 | width: options.width, 337 | svg: svg 338 | }[name] 339 | }, null, form); 340 | }); 341 | 342 | // submit 343 | form.submit(); 344 | 345 | // clean up 346 | discardElement(form); 347 | }, 348 | 349 | /** 350 | * Print the chart 351 | */ 352 | print: function () { 353 | 354 | var chart = this, 355 | container = chart.container, 356 | origDisplay = [], 357 | origParent = container.parentNode, 358 | body = doc.body, 359 | childNodes = body.childNodes; 360 | 361 | if (chart.isPrinting) { // block the button while in printing mode 362 | return; 363 | } 364 | 365 | chart.isPrinting = true; 366 | 367 | // hide all body content 368 | each(childNodes, function (node, i) { 369 | if (node.nodeType === 1) { 370 | origDisplay[i] = node.style.display; 371 | node.style.display = NONE; 372 | } 373 | }); 374 | 375 | // pull out the chart 376 | body.appendChild(container); 377 | 378 | // print 379 | win.print(); 380 | 381 | // allow the browser to prepare before reverting 382 | setTimeout(function () { 383 | 384 | // put the chart back in 385 | origParent.appendChild(container); 386 | 387 | // restore all body content 388 | each(childNodes, function (node, i) { 389 | if (node.nodeType === 1) { 390 | node.style.display = origDisplay[i]; 391 | } 392 | }); 393 | 394 | chart.isPrinting = false; 395 | 396 | }, 1000); 397 | 398 | }, 399 | 400 | /** 401 | * Display a popup menu for choosing the export type 402 | * 403 | * @param {String} name An identifier for the menu 404 | * @param {Array} items A collection with text and onclicks for the items 405 | * @param {Number} x The x position of the opener button 406 | * @param {Number} y The y position of the opener button 407 | * @param {Number} width The width of the opener button 408 | * @param {Number} height The height of the opener button 409 | */ 410 | contextMenu: function (name, items, x, y, width, height) { 411 | var chart = this, 412 | navOptions = chart.options.navigation, 413 | menuItemStyle = navOptions.menuItemStyle, 414 | chartWidth = chart.chartWidth, 415 | chartHeight = chart.chartHeight, 416 | cacheName = 'cache-' + name, 417 | menu = chart[cacheName], 418 | menuPadding = mathMax(width, height), // for mouse leave detection 419 | boxShadow = '3px 3px 10px #888', 420 | innerMenu, 421 | hide, 422 | menuStyle; 423 | 424 | // create the menu only the first time 425 | if (!menu) { 426 | 427 | // create a HTML element above the SVG 428 | chart[cacheName] = menu = createElement(DIV, { 429 | className: PREFIX + name 430 | }, { 431 | position: ABSOLUTE, 432 | zIndex: 1000, 433 | padding: menuPadding + PX 434 | }, chart.container); 435 | 436 | innerMenu = createElement(DIV, null, 437 | extend({ 438 | MozBoxShadow: boxShadow, 439 | WebkitBoxShadow: boxShadow, 440 | boxShadow: boxShadow 441 | }, navOptions.menuStyle), menu); 442 | 443 | // hide on mouse out 444 | hide = function () { 445 | css(menu, { display: NONE }); 446 | }; 447 | 448 | addEvent(menu, 'mouseleave', hide); 449 | 450 | 451 | // create the items 452 | each(items, function (item) { 453 | if (item) { 454 | var div = createElement(DIV, { 455 | onmouseover: function () { 456 | css(this, navOptions.menuItemHoverStyle); 457 | }, 458 | onmouseout: function () { 459 | css(this, menuItemStyle); 460 | }, 461 | innerHTML: item.text || chart.options.lang[item.textKey] 462 | }, extend({ 463 | cursor: 'pointer' 464 | }, menuItemStyle), innerMenu); 465 | 466 | div[hasTouch ? 'ontouchstart' : 'onclick'] = function () { 467 | hide(); 468 | item.onclick.apply(chart, arguments); 469 | }; 470 | 471 | // Keep references to menu divs to be able to destroy them 472 | chart.exportDivElements.push(div); 473 | } 474 | }); 475 | 476 | // Keep references to menu and innerMenu div to be able to destroy them 477 | chart.exportDivElements.push(innerMenu, menu); 478 | 479 | chart.exportMenuWidth = menu.offsetWidth; 480 | chart.exportMenuHeight = menu.offsetHeight; 481 | } 482 | 483 | menuStyle = { display: 'block' }; 484 | 485 | // if outside right, right align it 486 | if (x + chart.exportMenuWidth > chartWidth) { 487 | menuStyle.right = (chartWidth - x - width - menuPadding) + PX; 488 | } else { 489 | menuStyle.left = (x - menuPadding) + PX; 490 | } 491 | // if outside bottom, bottom align it 492 | if (y + height + chart.exportMenuHeight > chartHeight) { 493 | menuStyle.bottom = (chartHeight - y - menuPadding) + PX; 494 | } else { 495 | menuStyle.top = (y + height - menuPadding) + PX; 496 | } 497 | 498 | css(menu, menuStyle); 499 | }, 500 | 501 | /** 502 | * Add the export button to the chart 503 | */ 504 | addButton: function (options) { 505 | var chart = this, 506 | renderer = chart.renderer, 507 | btnOptions = merge(chart.options.navigation.buttonOptions, options), 508 | onclick = btnOptions.onclick, 509 | menuItems = btnOptions.menuItems, 510 | buttonWidth = btnOptions.width, 511 | buttonHeight = btnOptions.height, 512 | box, 513 | symbol, 514 | button, 515 | borderWidth = btnOptions.borderWidth, 516 | boxAttr = { 517 | stroke: btnOptions.borderColor 518 | 519 | }, 520 | symbolAttr = { 521 | stroke: btnOptions.symbolStroke, 522 | fill: btnOptions.symbolFill 523 | }, 524 | symbolSize = btnOptions.symbolSize || 12; 525 | 526 | // Keeps references to the button elements 527 | if (!chart.exportDivElements) { 528 | chart.exportDivElements = []; 529 | chart.exportSVGElements = []; 530 | } 531 | 532 | if (btnOptions.enabled === false) { 533 | return; 534 | } 535 | 536 | // element to capture the click 537 | function revert() { 538 | symbol.attr(symbolAttr); 539 | box.attr(boxAttr); 540 | } 541 | 542 | // the box border 543 | box = renderer.rect( 544 | 0, 545 | 0, 546 | buttonWidth, 547 | buttonHeight, 548 | btnOptions.borderRadius, 549 | borderWidth 550 | ) 551 | //.translate(buttonLeft, buttonTop) // to allow gradients 552 | .align(btnOptions, true) 553 | .attr(extend({ 554 | fill: btnOptions.backgroundColor, 555 | 'stroke-width': borderWidth, 556 | zIndex: 19 557 | }, boxAttr)).add(); 558 | 559 | // the invisible element to track the clicks 560 | button = renderer.rect( 561 | 0, 562 | 0, 563 | buttonWidth, 564 | buttonHeight, 565 | 0 566 | ) 567 | .align(btnOptions) 568 | .attr({ 569 | id: btnOptions._id, 570 | fill: 'rgba(255, 255, 255, 0.001)', 571 | title: chart.options.lang[btnOptions._titleKey], 572 | zIndex: 21 573 | }).css({ 574 | cursor: 'pointer' 575 | }) 576 | .on('mouseover', function () { 577 | symbol.attr({ 578 | stroke: btnOptions.hoverSymbolStroke, 579 | fill: btnOptions.hoverSymbolFill 580 | }); 581 | box.attr({ 582 | stroke: btnOptions.hoverBorderColor 583 | }); 584 | }) 585 | .on('mouseout', revert) 586 | .on('click', revert) 587 | .add(); 588 | 589 | // add the click event 590 | if (menuItems) { 591 | onclick = function () { 592 | revert(); 593 | var bBox = button.getBBox(); 594 | chart.contextMenu('export-menu', menuItems, bBox.x, bBox.y, buttonWidth, buttonHeight); 595 | }; 596 | } 597 | /*addEvent(button.element, 'click', function() { 598 | onclick.apply(chart, arguments); 599 | });*/ 600 | button.on('click', function () { 601 | onclick.apply(chart, arguments); 602 | }); 603 | 604 | // the icon 605 | symbol = renderer.symbol( 606 | btnOptions.symbol, 607 | btnOptions.symbolX - (symbolSize / 2), 608 | btnOptions.symbolY - (symbolSize / 2), 609 | symbolSize, 610 | symbolSize 611 | ) 612 | .align(btnOptions, true) 613 | .attr(extend(symbolAttr, { 614 | 'stroke-width': btnOptions.symbolStrokeWidth || 1, 615 | zIndex: 20 616 | })).add(); 617 | 618 | // Keep references to the renderer element so to be able to destroy them later. 619 | chart.exportSVGElements.push(box, button, symbol); 620 | }, 621 | 622 | /** 623 | * Destroy the buttons. 624 | */ 625 | destroyExport: function () { 626 | var i, 627 | chart = this, 628 | elem; 629 | 630 | // Destroy the extra buttons added 631 | for (i = 0; i < chart.exportSVGElements.length; i++) { 632 | elem = chart.exportSVGElements[i]; 633 | // Destroy and null the svg/vml elements 634 | elem.onclick = elem.ontouchstart = null; 635 | chart.exportSVGElements[i] = elem.destroy(); 636 | } 637 | 638 | // Destroy the divs for the menu 639 | for (i = 0; i < chart.exportDivElements.length; i++) { 640 | elem = chart.exportDivElements[i]; 641 | 642 | // Remove the event handler 643 | removeEvent(elem, 'mouseleave'); 644 | 645 | // Remove inline events 646 | chart.exportDivElements[i] = elem.onmouseout = elem.onmouseover = elem.ontouchstart = elem.onclick = null; 647 | 648 | // Destroy the div by moving to garbage bin 649 | discardElement(elem); 650 | } 651 | } 652 | }); 653 | 654 | /** 655 | * Crisp for 1px stroke width, which is default. In the future, consider a smarter, 656 | * global function. 657 | */ 658 | function crisp(arr) { 659 | var i = arr.length; 660 | while (i--) { 661 | if (typeof arr[i] === 'number') { 662 | arr[i] = Math.round(arr[i]) - 0.5; 663 | } 664 | } 665 | return arr; 666 | } 667 | 668 | // Create the export icon 669 | HC.Renderer.prototype.symbols.exportIcon = function (x, y, width, height) { 670 | return crisp([ 671 | M, // the disk 672 | x, y + width, 673 | L, 674 | x + width, y + height, 675 | x + width, y + height * 0.8, 676 | x, y + height * 0.8, 677 | 'Z', 678 | M, // the arrow 679 | x + width * 0.5, y + height * 0.8, 680 | L, 681 | x + width * 0.8, y + height * 0.4, 682 | x + width * 0.4, y + height * 0.4, 683 | x + width * 0.4, y, 684 | x + width * 0.6, y, 685 | x + width * 0.6, y + height * 0.4, 686 | x + width * 0.2, y + height * 0.4, 687 | 'Z' 688 | ]); 689 | }; 690 | // Create the print icon 691 | HC.Renderer.prototype.symbols.printIcon = function (x, y, width, height) { 692 | return crisp([ 693 | M, // the printer 694 | x, y + height * 0.7, 695 | L, 696 | x + width, y + height * 0.7, 697 | x + width, y + height * 0.4, 698 | x, y + height * 0.4, 699 | 'Z', 700 | M, // the upper sheet 701 | x + width * 0.2, y + height * 0.4, 702 | L, 703 | x + width * 0.2, y, 704 | x + width * 0.8, y, 705 | x + width * 0.8, y + height * 0.4, 706 | 'Z', 707 | M, // the lower sheet 708 | x + width * 0.2, y + height * 0.7, 709 | L, 710 | x, y + height, 711 | x + width, y + height, 712 | x + width * 0.8, y + height * 0.7, 713 | 'Z' 714 | ]); 715 | }; 716 | 717 | 718 | // Add the buttons on chart load 719 | Chart.prototype.callbacks.push(function (chart) { 720 | var n, 721 | exportingOptions = chart.options.exporting, 722 | buttons = exportingOptions.buttons; 723 | 724 | if (exportingOptions.enabled !== false) { 725 | 726 | for (n in buttons) { 727 | chart.addButton(buttons[n]); 728 | } 729 | 730 | // Destroy the export elements at chart destroy 731 | addEvent(chart, 'destroy', chart.destroyExport); 732 | } 733 | 734 | }); 735 | 736 | 737 | }()); 738 | -------------------------------------------------------------------------------- /scripts/highcharts/themes/dark-blue.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Dark blue theme for Highcharts JS 3 | * @author Torstein Hønsi 4 | */ 5 | 6 | Highcharts.theme = { 7 | colors: ["#DDDF0D", "#55BF3B", "#DF5353", "#7798BF", "#aaeeee", "#ff0066", "#eeaaee", 8 | "#55BF3B", "#DF5353", "#7798BF", "#aaeeee"], 9 | chart: { 10 | backgroundColor: { 11 | linearGradient: [0, 0, 250, 500], 12 | stops: [ 13 | [0, 'rgb(48, 48, 96)'], 14 | [1, 'rgb(0, 0, 0)'] 15 | ] 16 | }, 17 | borderColor: '#000000', 18 | borderWidth: 2, 19 | className: 'dark-container', 20 | plotBackgroundColor: 'rgba(255, 255, 255, .1)', 21 | plotBorderColor: '#CCCCCC', 22 | plotBorderWidth: 1 23 | }, 24 | title: { 25 | style: { 26 | color: '#C0C0C0', 27 | font: 'bold 16px "Trebuchet MS", Verdana, sans-serif' 28 | } 29 | }, 30 | subtitle: { 31 | style: { 32 | color: '#666666', 33 | font: 'bold 12px "Trebuchet MS", Verdana, sans-serif' 34 | } 35 | }, 36 | xAxis: { 37 | gridLineColor: '#333333', 38 | gridLineWidth: 1, 39 | labels: { 40 | style: { 41 | color: '#A0A0A0' 42 | } 43 | }, 44 | lineColor: '#A0A0A0', 45 | tickColor: '#A0A0A0', 46 | title: { 47 | style: { 48 | color: '#CCC', 49 | fontWeight: 'bold', 50 | fontSize: '12px', 51 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 52 | 53 | } 54 | } 55 | }, 56 | yAxis: { 57 | gridLineColor: '#333333', 58 | labels: { 59 | style: { 60 | color: '#A0A0A0' 61 | } 62 | }, 63 | lineColor: '#A0A0A0', 64 | minorTickInterval: null, 65 | tickColor: '#A0A0A0', 66 | tickWidth: 1, 67 | title: { 68 | style: { 69 | color: '#CCC', 70 | fontWeight: 'bold', 71 | fontSize: '12px', 72 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 73 | } 74 | } 75 | }, 76 | tooltip: { 77 | backgroundColor: 'rgba(0, 0, 0, 0.75)', 78 | style: { 79 | color: '#F0F0F0' 80 | } 81 | }, 82 | toolbar: { 83 | itemStyle: { 84 | color: 'silver' 85 | } 86 | }, 87 | plotOptions: { 88 | line: { 89 | dataLabels: { 90 | color: '#CCC' 91 | }, 92 | marker: { 93 | lineColor: '#333' 94 | } 95 | }, 96 | spline: { 97 | marker: { 98 | lineColor: '#333' 99 | } 100 | }, 101 | scatter: { 102 | marker: { 103 | lineColor: '#333' 104 | } 105 | }, 106 | candlestick: { 107 | lineColor: 'white' 108 | } 109 | }, 110 | legend: { 111 | itemStyle: { 112 | font: '9pt Trebuchet MS, Verdana, sans-serif', 113 | color: '#A0A0A0' 114 | }, 115 | itemHoverStyle: { 116 | color: '#FFF' 117 | }, 118 | itemHiddenStyle: { 119 | color: '#444' 120 | } 121 | }, 122 | credits: { 123 | style: { 124 | color: '#666' 125 | } 126 | }, 127 | labels: { 128 | style: { 129 | color: '#CCC' 130 | } 131 | }, 132 | 133 | navigation: { 134 | buttonOptions: { 135 | backgroundColor: { 136 | linearGradient: [0, 0, 0, 20], 137 | stops: [ 138 | [0.4, '#606060'], 139 | [0.6, '#333333'] 140 | ] 141 | }, 142 | borderColor: '#000000', 143 | symbolStroke: '#C0C0C0', 144 | hoverSymbolStroke: '#FFFFFF' 145 | } 146 | }, 147 | 148 | exporting: { 149 | buttons: { 150 | exportButton: { 151 | symbolFill: '#55BE3B' 152 | }, 153 | printButton: { 154 | symbolFill: '#7797BE' 155 | } 156 | } 157 | }, 158 | 159 | // scroll charts 160 | rangeSelector: { 161 | buttonTheme: { 162 | fill: { 163 | linearGradient: [0, 0, 0, 20], 164 | stops: [ 165 | [0.4, '#888'], 166 | [0.6, '#555'] 167 | ] 168 | }, 169 | stroke: '#000000', 170 | style: { 171 | color: '#CCC', 172 | fontWeight: 'bold' 173 | }, 174 | states: { 175 | hover: { 176 | fill: { 177 | linearGradient: [0, 0, 0, 20], 178 | stops: [ 179 | [0.4, '#BBB'], 180 | [0.6, '#888'] 181 | ] 182 | }, 183 | stroke: '#000000', 184 | style: { 185 | color: 'white' 186 | } 187 | }, 188 | select: { 189 | fill: { 190 | linearGradient: [0, 0, 0, 20], 191 | stops: [ 192 | [0.1, '#000'], 193 | [0.3, '#333'] 194 | ] 195 | }, 196 | stroke: '#000000', 197 | style: { 198 | color: 'yellow' 199 | } 200 | } 201 | } 202 | }, 203 | inputStyle: { 204 | backgroundColor: '#333', 205 | color: 'silver' 206 | }, 207 | labelStyle: { 208 | color: 'silver' 209 | } 210 | }, 211 | 212 | navigator: { 213 | handles: { 214 | backgroundColor: '#666', 215 | borderColor: '#AAA' 216 | }, 217 | outlineColor: '#CCC', 218 | maskFill: 'rgba(16, 16, 16, 0.5)', 219 | series: { 220 | color: '#7798BF', 221 | lineColor: '#A6C7ED' 222 | } 223 | }, 224 | 225 | scrollbar: { 226 | barBackgroundColor: { 227 | linearGradient: [0, 0, 0, 20], 228 | stops: [ 229 | [0.4, '#888'], 230 | [0.6, '#555'] 231 | ] 232 | }, 233 | barBorderColor: '#CCC', 234 | buttonArrowColor: '#CCC', 235 | buttonBackgroundColor: { 236 | linearGradient: [0, 0, 0, 20], 237 | stops: [ 238 | [0.4, '#888'], 239 | [0.6, '#555'] 240 | ] 241 | }, 242 | buttonBorderColor: '#CCC', 243 | rifleColor: '#FFF', 244 | trackBackgroundColor: { 245 | linearGradient: [0, 0, 0, 10], 246 | stops: [ 247 | [0, '#000'], 248 | [1, '#333'] 249 | ] 250 | }, 251 | trackBorderColor: '#666' 252 | }, 253 | 254 | // special colors for some of the 255 | legendBackgroundColor: 'rgba(0, 0, 0, 0.5)', 256 | legendBackgroundColorSolid: 'rgb(35, 35, 70)', 257 | dataLabelsColor: '#444', 258 | textColor: '#C0C0C0', 259 | maskColor: 'rgba(255,255,255,0.3)' 260 | }; 261 | 262 | // Apply the theme 263 | var highchartsOptions = Highcharts.setOptions(Highcharts.theme); 264 | -------------------------------------------------------------------------------- /scripts/highcharts/themes/dark-green.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Dark blue theme for Highcharts JS 3 | * @author Torstein Hønsi 4 | */ 5 | 6 | Highcharts.theme = { 7 | colors: ["#DDDF0D", "#55BF3B", "#DF5353", "#7798BF", "#aaeeee", "#ff0066", "#eeaaee", 8 | "#55BF3B", "#DF5353", "#7798BF", "#aaeeee"], 9 | chart: { 10 | backgroundColor: { 11 | linearGradient: [0, 0, 250, 500], 12 | stops: [ 13 | [0, 'rgb(48, 96, 48)'], 14 | [1, 'rgb(0, 0, 0)'] 15 | ] 16 | }, 17 | borderColor: '#000000', 18 | borderWidth: 2, 19 | className: 'dark-container', 20 | plotBackgroundColor: 'rgba(255, 255, 255, .1)', 21 | plotBorderColor: '#CCCCCC', 22 | plotBorderWidth: 1 23 | }, 24 | title: { 25 | style: { 26 | color: '#C0C0C0', 27 | font: 'bold 16px "Trebuchet MS", Verdana, sans-serif' 28 | } 29 | }, 30 | subtitle: { 31 | style: { 32 | color: '#666666', 33 | font: 'bold 12px "Trebuchet MS", Verdana, sans-serif' 34 | } 35 | }, 36 | xAxis: { 37 | gridLineColor: '#333333', 38 | gridLineWidth: 1, 39 | labels: { 40 | style: { 41 | color: '#A0A0A0' 42 | } 43 | }, 44 | lineColor: '#A0A0A0', 45 | tickColor: '#A0A0A0', 46 | title: { 47 | style: { 48 | color: '#CCC', 49 | fontWeight: 'bold', 50 | fontSize: '12px', 51 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 52 | 53 | } 54 | } 55 | }, 56 | yAxis: { 57 | gridLineColor: '#333333', 58 | labels: { 59 | style: { 60 | color: '#A0A0A0' 61 | } 62 | }, 63 | lineColor: '#A0A0A0', 64 | minorTickInterval: null, 65 | tickColor: '#A0A0A0', 66 | tickWidth: 1, 67 | title: { 68 | style: { 69 | color: '#CCC', 70 | fontWeight: 'bold', 71 | fontSize: '12px', 72 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 73 | } 74 | } 75 | }, 76 | tooltip: { 77 | backgroundColor: 'rgba(0, 0, 0, 0.75)', 78 | style: { 79 | color: '#F0F0F0' 80 | } 81 | }, 82 | toolbar: { 83 | itemStyle: { 84 | color: 'silver' 85 | } 86 | }, 87 | plotOptions: { 88 | line: { 89 | dataLabels: { 90 | color: '#CCC' 91 | }, 92 | marker: { 93 | lineColor: '#333' 94 | } 95 | }, 96 | spline: { 97 | marker: { 98 | lineColor: '#333' 99 | } 100 | }, 101 | scatter: { 102 | marker: { 103 | lineColor: '#333' 104 | } 105 | }, 106 | candlestick: { 107 | lineColor: 'white' 108 | } 109 | }, 110 | legend: { 111 | itemStyle: { 112 | font: '9pt Trebuchet MS, Verdana, sans-serif', 113 | color: '#A0A0A0' 114 | }, 115 | itemHoverStyle: { 116 | color: '#FFF' 117 | }, 118 | itemHiddenStyle: { 119 | color: '#444' 120 | } 121 | }, 122 | credits: { 123 | style: { 124 | color: '#666' 125 | } 126 | }, 127 | labels: { 128 | style: { 129 | color: '#CCC' 130 | } 131 | }, 132 | 133 | navigation: { 134 | buttonOptions: { 135 | backgroundColor: { 136 | linearGradient: [0, 0, 0, 20], 137 | stops: [ 138 | [0.4, '#606060'], 139 | [0.6, '#333333'] 140 | ] 141 | }, 142 | borderColor: '#000000', 143 | symbolStroke: '#C0C0C0', 144 | hoverSymbolStroke: '#FFFFFF' 145 | } 146 | }, 147 | 148 | exporting: { 149 | buttons: { 150 | exportButton: { 151 | symbolFill: '#55BE3B' 152 | }, 153 | printButton: { 154 | symbolFill: '#7797BE' 155 | } 156 | } 157 | }, 158 | 159 | // scroll charts 160 | rangeSelector: { 161 | buttonTheme: { 162 | fill: { 163 | linearGradient: [0, 0, 0, 20], 164 | stops: [ 165 | [0.4, '#888'], 166 | [0.6, '#555'] 167 | ] 168 | }, 169 | stroke: '#000000', 170 | style: { 171 | color: '#CCC', 172 | fontWeight: 'bold' 173 | }, 174 | states: { 175 | hover: { 176 | fill: { 177 | linearGradient: [0, 0, 0, 20], 178 | stops: [ 179 | [0.4, '#BBB'], 180 | [0.6, '#888'] 181 | ] 182 | }, 183 | stroke: '#000000', 184 | style: { 185 | color: 'white' 186 | } 187 | }, 188 | select: { 189 | fill: { 190 | linearGradient: [0, 0, 0, 20], 191 | stops: [ 192 | [0.1, '#000'], 193 | [0.3, '#333'] 194 | ] 195 | }, 196 | stroke: '#000000', 197 | style: { 198 | color: 'yellow' 199 | } 200 | } 201 | } 202 | }, 203 | inputStyle: { 204 | backgroundColor: '#333', 205 | color: 'silver' 206 | }, 207 | labelStyle: { 208 | color: 'silver' 209 | } 210 | }, 211 | 212 | navigator: { 213 | handles: { 214 | backgroundColor: '#666', 215 | borderColor: '#AAA' 216 | }, 217 | outlineColor: '#CCC', 218 | maskFill: 'rgba(16, 16, 16, 0.5)', 219 | series: { 220 | color: '#7798BF', 221 | lineColor: '#A6C7ED' 222 | } 223 | }, 224 | 225 | scrollbar: { 226 | barBackgroundColor: { 227 | linearGradient: [0, 0, 0, 20], 228 | stops: [ 229 | [0.4, '#888'], 230 | [0.6, '#555'] 231 | ] 232 | }, 233 | barBorderColor: '#CCC', 234 | buttonArrowColor: '#CCC', 235 | buttonBackgroundColor: { 236 | linearGradient: [0, 0, 0, 20], 237 | stops: [ 238 | [0.4, '#888'], 239 | [0.6, '#555'] 240 | ] 241 | }, 242 | buttonBorderColor: '#CCC', 243 | rifleColor: '#FFF', 244 | trackBackgroundColor: { 245 | linearGradient: [0, 0, 0, 10], 246 | stops: [ 247 | [0, '#000'], 248 | [1, '#333'] 249 | ] 250 | }, 251 | trackBorderColor: '#666' 252 | }, 253 | 254 | // special colors for some of the 255 | legendBackgroundColor: 'rgba(0, 0, 0, 0.5)', 256 | legendBackgroundColorSolid: 'rgb(35, 35, 70)', 257 | dataLabelsColor: '#444', 258 | textColor: '#C0C0C0', 259 | maskColor: 'rgba(255,255,255,0.3)' 260 | }; 261 | 262 | // Apply the theme 263 | var highchartsOptions = Highcharts.setOptions(Highcharts.theme); 264 | -------------------------------------------------------------------------------- /scripts/highcharts/themes/gray.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Gray theme for Highcharts JS 3 | * @author Torstein Hønsi 4 | */ 5 | 6 | Highcharts.theme = { 7 | colors: ["#DDDF0D", "#7798BF", "#55BF3B", "#DF5353", "#aaeeee", "#ff0066", "#eeaaee", 8 | "#55BF3B", "#DF5353", "#7798BF", "#aaeeee"], 9 | chart: { 10 | backgroundColor: { 11 | linearGradient: [0, 0, 0, 400], 12 | stops: [ 13 | [0, 'rgb(96, 96, 96)'], 14 | [1, 'rgb(16, 16, 16)'] 15 | ] 16 | }, 17 | borderWidth: 0, 18 | borderRadius: 15, 19 | plotBackgroundColor: null, 20 | plotShadow: false, 21 | plotBorderWidth: 0 22 | }, 23 | title: { 24 | style: { 25 | color: '#FFF', 26 | font: '16px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif' 27 | } 28 | }, 29 | subtitle: { 30 | style: { 31 | color: '#DDD', 32 | font: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif' 33 | } 34 | }, 35 | xAxis: { 36 | gridLineWidth: 0, 37 | lineColor: '#999', 38 | tickColor: '#999', 39 | labels: { 40 | style: { 41 | color: '#999', 42 | fontWeight: 'bold' 43 | } 44 | }, 45 | title: { 46 | style: { 47 | color: '#AAA', 48 | font: 'bold 12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif' 49 | } 50 | } 51 | }, 52 | yAxis: { 53 | alternateGridColor: null, 54 | minorTickInterval: null, 55 | gridLineColor: 'rgba(255, 255, 255, .1)', 56 | lineWidth: 0, 57 | tickWidth: 0, 58 | labels: { 59 | style: { 60 | color: '#999', 61 | fontWeight: 'bold' 62 | } 63 | }, 64 | title: { 65 | style: { 66 | color: '#AAA', 67 | font: 'bold 12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif' 68 | } 69 | } 70 | }, 71 | legend: { 72 | itemStyle: { 73 | color: '#CCC' 74 | }, 75 | itemHoverStyle: { 76 | color: '#FFF' 77 | }, 78 | itemHiddenStyle: { 79 | color: '#333' 80 | } 81 | }, 82 | labels: { 83 | style: { 84 | color: '#CCC' 85 | } 86 | }, 87 | tooltip: { 88 | backgroundColor: { 89 | linearGradient: [0, 0, 0, 50], 90 | stops: [ 91 | [0, 'rgba(96, 96, 96, .8)'], 92 | [1, 'rgba(16, 16, 16, .8)'] 93 | ] 94 | }, 95 | borderWidth: 0, 96 | style: { 97 | color: '#FFF' 98 | } 99 | }, 100 | 101 | 102 | plotOptions: { 103 | line: { 104 | dataLabels: { 105 | color: '#CCC' 106 | }, 107 | marker: { 108 | lineColor: '#333' 109 | } 110 | }, 111 | spline: { 112 | marker: { 113 | lineColor: '#333' 114 | } 115 | }, 116 | scatter: { 117 | marker: { 118 | lineColor: '#333' 119 | } 120 | }, 121 | candlestick: { 122 | lineColor: 'white' 123 | } 124 | }, 125 | 126 | toolbar: { 127 | itemStyle: { 128 | color: '#CCC' 129 | } 130 | }, 131 | 132 | navigation: { 133 | buttonOptions: { 134 | backgroundColor: { 135 | linearGradient: [0, 0, 0, 20], 136 | stops: [ 137 | [0.4, '#606060'], 138 | [0.6, '#333333'] 139 | ] 140 | }, 141 | borderColor: '#000000', 142 | symbolStroke: '#C0C0C0', 143 | hoverSymbolStroke: '#FFFFFF' 144 | } 145 | }, 146 | 147 | exporting: { 148 | buttons: { 149 | exportButton: { 150 | symbolFill: '#55BE3B' 151 | }, 152 | printButton: { 153 | symbolFill: '#7797BE' 154 | } 155 | } 156 | }, 157 | 158 | // scroll charts 159 | rangeSelector: { 160 | buttonTheme: { 161 | fill: { 162 | linearGradient: [0, 0, 0, 20], 163 | stops: [ 164 | [0.4, '#888'], 165 | [0.6, '#555'] 166 | ] 167 | }, 168 | stroke: '#000000', 169 | style: { 170 | color: '#CCC', 171 | fontWeight: 'bold' 172 | }, 173 | states: { 174 | hover: { 175 | fill: { 176 | linearGradient: [0, 0, 0, 20], 177 | stops: [ 178 | [0.4, '#BBB'], 179 | [0.6, '#888'] 180 | ] 181 | }, 182 | stroke: '#000000', 183 | style: { 184 | color: 'white' 185 | } 186 | }, 187 | select: { 188 | fill: { 189 | linearGradient: [0, 0, 0, 20], 190 | stops: [ 191 | [0.1, '#000'], 192 | [0.3, '#333'] 193 | ] 194 | }, 195 | stroke: '#000000', 196 | style: { 197 | color: 'yellow' 198 | } 199 | } 200 | } 201 | }, 202 | inputStyle: { 203 | backgroundColor: '#333', 204 | color: 'silver' 205 | }, 206 | labelStyle: { 207 | color: 'silver' 208 | } 209 | }, 210 | 211 | navigator: { 212 | handles: { 213 | backgroundColor: '#666', 214 | borderColor: '#AAA' 215 | }, 216 | outlineColor: '#CCC', 217 | maskFill: 'rgba(16, 16, 16, 0.5)', 218 | series: { 219 | color: '#7798BF', 220 | lineColor: '#A6C7ED' 221 | } 222 | }, 223 | 224 | scrollbar: { 225 | barBackgroundColor: { 226 | linearGradient: [0, 0, 0, 20], 227 | stops: [ 228 | [0.4, '#888'], 229 | [0.6, '#555'] 230 | ] 231 | }, 232 | barBorderColor: '#CCC', 233 | buttonArrowColor: '#CCC', 234 | buttonBackgroundColor: { 235 | linearGradient: [0, 0, 0, 20], 236 | stops: [ 237 | [0.4, '#888'], 238 | [0.6, '#555'] 239 | ] 240 | }, 241 | buttonBorderColor: '#CCC', 242 | rifleColor: '#FFF', 243 | trackBackgroundColor: { 244 | linearGradient: [0, 0, 0, 10], 245 | stops: [ 246 | [0, '#000'], 247 | [1, '#333'] 248 | ] 249 | }, 250 | trackBorderColor: '#666' 251 | }, 252 | 253 | // special colors for some of the demo examples 254 | legendBackgroundColor: 'rgba(48, 48, 48, 0.8)', 255 | legendBackgroundColorSolid: 'rgb(70, 70, 70)', 256 | dataLabelsColor: '#444', 257 | textColor: '#E0E0E0', 258 | maskColor: 'rgba(255,255,255,0.3)' 259 | }; 260 | 261 | // Apply the theme 262 | var highchartsOptions = Highcharts.setOptions(Highcharts.theme); 263 | -------------------------------------------------------------------------------- /scripts/highcharts/themes/grid.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Grid theme for Highcharts JS 3 | * @author Torstein Hønsi 4 | */ 5 | 6 | Highcharts.theme = { 7 | colors: ['#058DC7', '#50B432', '#ED561B', '#DDDF00', '#24CBE5', '#64E572', '#FF9655', '#FFF263', '#6AF9C4'], 8 | chart: { 9 | backgroundColor: { 10 | linearGradient: [0, 0, 500, 500], 11 | stops: [ 12 | [0, 'rgb(255, 255, 255)'], 13 | [1, 'rgb(240, 240, 255)'] 14 | ] 15 | }, 16 | borderWidth: 2, 17 | plotBackgroundColor: 'rgba(255, 255, 255, .9)', 18 | plotShadow: true, 19 | plotBorderWidth: 1 20 | }, 21 | title: { 22 | style: { 23 | color: '#000', 24 | font: 'bold 16px "Trebuchet MS", Verdana, sans-serif' 25 | } 26 | }, 27 | subtitle: { 28 | style: { 29 | color: '#666666', 30 | font: 'bold 12px "Trebuchet MS", Verdana, sans-serif' 31 | } 32 | }, 33 | xAxis: { 34 | gridLineWidth: 1, 35 | lineColor: '#000', 36 | tickColor: '#000', 37 | labels: { 38 | style: { 39 | color: '#000', 40 | font: '11px Trebuchet MS, Verdana, sans-serif' 41 | } 42 | }, 43 | title: { 44 | style: { 45 | color: '#333', 46 | fontWeight: 'bold', 47 | fontSize: '12px', 48 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 49 | 50 | } 51 | } 52 | }, 53 | yAxis: { 54 | minorTickInterval: 'auto', 55 | lineColor: '#000', 56 | lineWidth: 1, 57 | tickWidth: 1, 58 | tickColor: '#000', 59 | labels: { 60 | style: { 61 | color: '#000', 62 | font: '11px Trebuchet MS, Verdana, sans-serif' 63 | } 64 | }, 65 | title: { 66 | style: { 67 | color: '#333', 68 | fontWeight: 'bold', 69 | fontSize: '12px', 70 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 71 | } 72 | } 73 | }, 74 | legend: { 75 | itemStyle: { 76 | font: '9pt Trebuchet MS, Verdana, sans-serif', 77 | color: 'black' 78 | 79 | }, 80 | itemHoverStyle: { 81 | color: '#039' 82 | }, 83 | itemHiddenStyle: { 84 | color: 'gray' 85 | } 86 | }, 87 | labels: { 88 | style: { 89 | color: '#99b' 90 | } 91 | } 92 | }; 93 | 94 | // Apply the theme 95 | var highchartsOptions = Highcharts.setOptions(Highcharts.theme); 96 | -------------------------------------------------------------------------------- /scripts/highcharts/themes/skies.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Skies theme for Highcharts JS 3 | * @author Torstein Hønsi 4 | */ 5 | 6 | Highcharts.theme = { 7 | colors: ["#514F78", "#42A07B", "#9B5E4A", "#72727F", "#1F949A", "#82914E", "#86777F", "#42A07B"], 8 | chart: { 9 | className: 'skies', 10 | borderWidth: 0, 11 | plotShadow: true, 12 | plotBackgroundImage: '/demo/gfx/skies.jpg', 13 | plotBackgroundColor: { 14 | linearGradient: [0, 0, 250, 500], 15 | stops: [ 16 | [0, 'rgba(255, 255, 255, 1)'], 17 | [1, 'rgba(255, 255, 255, 0)'] 18 | ] 19 | }, 20 | plotBorderWidth: 1 21 | }, 22 | title: { 23 | style: { 24 | color: '#3E576F', 25 | font: '16px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif' 26 | } 27 | }, 28 | subtitle: { 29 | style: { 30 | color: '#6D869F', 31 | font: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif' 32 | } 33 | }, 34 | xAxis: { 35 | gridLineWidth: 0, 36 | lineColor: '#C0D0E0', 37 | tickColor: '#C0D0E0', 38 | labels: { 39 | style: { 40 | color: '#666', 41 | fontWeight: 'bold' 42 | } 43 | }, 44 | title: { 45 | style: { 46 | color: '#666', 47 | font: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif' 48 | } 49 | } 50 | }, 51 | yAxis: { 52 | alternateGridColor: 'rgba(255, 255, 255, .5)', 53 | lineColor: '#C0D0E0', 54 | tickColor: '#C0D0E0', 55 | tickWidth: 1, 56 | labels: { 57 | style: { 58 | color: '#666', 59 | fontWeight: 'bold' 60 | } 61 | }, 62 | title: { 63 | style: { 64 | color: '#666', 65 | font: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif' 66 | } 67 | } 68 | }, 69 | legend: { 70 | itemStyle: { 71 | font: '9pt Trebuchet MS, Verdana, sans-serif', 72 | color: '#3E576F' 73 | }, 74 | itemHoverStyle: { 75 | color: 'black' 76 | }, 77 | itemHiddenStyle: { 78 | color: 'silver' 79 | } 80 | }, 81 | labels: { 82 | style: { 83 | color: '#3E576F' 84 | } 85 | } 86 | }; 87 | 88 | // Apply the theme 89 | var highchartsOptions = Highcharts.setOptions(Highcharts.theme); 90 | -------------------------------------------------------------------------------- /scripts/jquery/jquery.tablesorter.min.js: -------------------------------------------------------------------------------- 1 | 2 | (function($){$.extend({tablesorter:new 3 | function(){var parsers=[],widgets=[];this.defaults={cssHeader:"header",cssAsc:"headerSortUp",cssDesc:"headerSortDown",cssChildRow:"expand-child",sortInitialOrder:"asc",sortMultiSortKey:"shiftKey",sortForce:null,sortAppend:null,sortLocaleCompare:true,textExtraction:"simple",parsers:{},widgets:[],widgetZebra:{css:["even","odd"]},headers:{},widthFixed:false,cancelSelection:true,sortList:[],headerList:[],dateFormat:"us",decimal:'/\.|\,/g',onRenderHeader:null,selectorHeaders:'thead th',debug:false};function benchmark(s,d){log(s+","+(new Date().getTime()-d.getTime())+"ms");}this.benchmark=benchmark;function log(s){if(typeof console!="undefined"&&typeof console.debug!="undefined"){console.log(s);}else{alert(s);}}function buildParserCache(table,$headers){if(table.config.debug){var parsersDebug="";}if(table.tBodies.length==0)return;var rows=table.tBodies[0].rows;if(rows[0]){var list=[],cells=rows[0].cells,l=cells.length;for(var i=0;i1){arr=arr.concat(checkCellColSpan(table,headerArr,row++));}else{if(table.tHead.length==1||(cell.rowSpan>1||!r[row+1])){arr.push(cell);}}}return arr;};function checkHeaderMetadata(cell){if(($.metadata)&&($(cell).metadata().sorter===false)){return true;};return false;}function checkHeaderOptions(table,i){if((table.config.headers[i])&&(table.config.headers[i].sorter===false)){return true;};return false;}function checkHeaderOptionsSortingLocked(table,i){if((table.config.headers[i])&&(table.config.headers[i].lockedOrder))return table.config.headers[i].lockedOrder;return false;}function applyWidget(table){var c=table.config.widgets;var l=c.length;for(var i=0;i');$("tr:first td",table.tBodies[0]).each(function(){colgroup.append($('').css('width',$(this).width()));});$(table).prepend(colgroup);};}function updateHeaderSortCount(table,sortList){var c=table.config,l=sortList.length;for(var i=0;i b["+i+"]) ? 1 : 0));";};function makeSortTextDesc(i){return"((b["+i+"] < a["+i+"]) ? -1 : ((b["+i+"] > a["+i+"]) ? 1 : 0));";};function makeSortNumeric(i){return"a["+i+"]-b["+i+"];";};function makeSortNumericDesc(i){return"b["+i+"]-a["+i+"];";};function sortText(a,b){if(table.config.sortLocaleCompare)return a.localeCompare(b);return((ab)?1:0));};function sortTextDesc(a,b){if(table.config.sortLocaleCompare)return b.localeCompare(a);return((ba)?1:0));};function sortNumeric(a,b){return a-b;};function sortNumericDesc(a,b){return b-a;};function getCachedSortType(parsers,i){return parsers[i].type;};this.construct=function(settings){return this.each(function(){if(!this.tHead||!this.tBodies)return;var $this,$document,$headers,cache,config,shiftDown=0,sortOrder;this.config={};config=$.extend(this.config,$.tablesorter.defaults,settings);$this=$(this);$.data(this,"tablesorter",config);$headers=buildHeaders(this);this.config.parsers=buildParserCache(this,$headers);cache=buildCache(this);var sortCSS=[config.cssDesc,config.cssAsc];fixColumnWidth(this);$headers.click(function(e){var totalRows=($this[0].tBodies[0]&&$this[0].tBodies[0].rows.length)||0;if(!this.sortDisabled&&totalRows>0){$this.trigger("sortStart");var $cell=$(this);var i=this.column;this.order=this.count++%2;if(this.lockedOrder)this.order=this.lockedOrder;if(!e[config.sortMultiSortKey]){config.sortList=[];if(config.sortForce!=null){var a=config.sortForce;for(var j=0;j0){$this.trigger("sorton",[config.sortList]);}applyWidget(this);});};this.addParser=function(parser){var l=parsers.length,a=true;for(var i=0;i