├── LICENSE ├── README.md ├── css ├── app.css ├── codemirror.css ├── foundation.min.css └── normalize.css ├── index.html └── js ├── app.js ├── codemirror.js ├── codemirror ├── css.js ├── htmlmixed.js ├── javascript.js └── xml.js ├── foundation ├── foundation.forms.js ├── foundation.js └── foundation.reveal.js └── jquery.js /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | HTML5 Notifications 2 | =================== 3 | 4 | The Notifications API allows you to display notifications to the user on desktop computers and mobile devices. 5 | 6 | [Demo online](http://elfoxero.github.io/html5notifications) 7 | 8 | This demo works in latest versions of Firefox, Google Chrome, Safari, Opera and Vivaldi ([view details](http://caniuse.com/#feat=notifications)). 9 | -------------------------------------------------------------------------------- /css/app.css: -------------------------------------------------------------------------------- 1 | header { 2 | margin-top: 10px; 3 | } 4 | 5 | #txtFile { 6 | display: none !important; 7 | } 8 | 9 | #txtUrl:disabled, #txtFile:disabled + #spnFile { 10 | display: none; 11 | } 12 | 13 | #spnFile { 14 | position: relative; 15 | } 16 | 17 | #filIcon { 18 | cursor: pointer; 19 | opacity: 0; 20 | position: absolute; 21 | z-index: 1; 22 | } 23 | 24 | #txtFileName { 25 | background-color: rgb(255, 255, 255); 26 | border: none; 27 | box-shadow: none; 28 | -webkit-box-shadow: none; 29 | -moz-box-shadow: none; 30 | -ms-box-shadow: none; 31 | color: rgba(0, 0, 0, 0.75); 32 | padding-left: 10px; 33 | } 34 | 35 | #txtSeconds { 36 | text-align: right; 37 | } 38 | 39 | #frmMain { 40 | margin-bottom: 0; 41 | } 42 | 43 | #msgUnsupported { 44 | display: none; 45 | } 46 | 47 | .CodeMirror { 48 | border: 1px solid #eee; 49 | height: 150px; 50 | } 51 | .CodeMirror-scroll { 52 | overflow-y: hidden; 53 | overflow-x: auto; 54 | } 55 | 56 | footer { 57 | margin-bottom: 20px; 58 | } -------------------------------------------------------------------------------- /css/codemirror.css: -------------------------------------------------------------------------------- 1 | /* BASICS */ 2 | 3 | .CodeMirror { 4 | /* Set height, width, borders, and global font properties here */ 5 | font-family: monospace; 6 | height: 300px; 7 | } 8 | .CodeMirror-scroll { 9 | /* Set scrolling behaviour here */ 10 | overflow: auto; 11 | } 12 | 13 | /* PADDING */ 14 | 15 | .CodeMirror-lines { 16 | padding: 4px 0; /* Vertical padding around content */ 17 | } 18 | .CodeMirror pre { 19 | padding: 0 4px; /* Horizontal padding of content */ 20 | } 21 | 22 | .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { 23 | background-color: white; /* The little square between H and V scrollbars */ 24 | } 25 | 26 | /* GUTTER */ 27 | 28 | .CodeMirror-gutters { 29 | border-right: 1px solid #ddd; 30 | background-color: #f7f7f7; 31 | white-space: nowrap; 32 | } 33 | .CodeMirror-linenumbers {} 34 | .CodeMirror-linenumber { 35 | padding: 0 3px 0 5px; 36 | min-width: 20px; 37 | text-align: right; 38 | color: #999; 39 | } 40 | 41 | /* CURSOR */ 42 | 43 | .CodeMirror div.CodeMirror-cursor { 44 | border-left: 1px solid black; 45 | z-index: 3; 46 | } 47 | /* Shown when moving in bi-directional text */ 48 | .CodeMirror div.CodeMirror-secondarycursor { 49 | border-left: 1px solid silver; 50 | } 51 | .CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor { 52 | width: auto; 53 | border: 0; 54 | background: #7e7; 55 | z-index: 1; 56 | } 57 | /* Can style cursor different in overwrite (non-insert) mode */ 58 | .CodeMirror div.CodeMirror-cursor.CodeMirror-overwrite {} 59 | 60 | .cm-tab { display: inline-block; } 61 | 62 | /* DEFAULT THEME */ 63 | 64 | .cm-s-default .cm-keyword {color: #708;} 65 | .cm-s-default .cm-atom {color: #219;} 66 | .cm-s-default .cm-number {color: #164;} 67 | .cm-s-default .cm-def {color: #00f;} 68 | .cm-s-default .cm-variable {color: black;} 69 | .cm-s-default .cm-variable-2 {color: #05a;} 70 | .cm-s-default .cm-variable-3 {color: #085;} 71 | .cm-s-default .cm-property {color: black;} 72 | .cm-s-default .cm-operator {color: black;} 73 | .cm-s-default .cm-comment {color: #a50;} 74 | .cm-s-default .cm-string {color: #a11;} 75 | .cm-s-default .cm-string-2 {color: #f50;} 76 | .cm-s-default .cm-meta {color: #555;} 77 | .cm-s-default .cm-error {color: #f00;} 78 | .cm-s-default .cm-qualifier {color: #555;} 79 | .cm-s-default .cm-builtin {color: #30a;} 80 | .cm-s-default .cm-bracket {color: #997;} 81 | .cm-s-default .cm-tag {color: #170;} 82 | .cm-s-default .cm-attribute {color: #00c;} 83 | .cm-s-default .cm-header {color: blue;} 84 | .cm-s-default .cm-quote {color: #090;} 85 | .cm-s-default .cm-hr {color: #999;} 86 | .cm-s-default .cm-link {color: #00c;} 87 | 88 | .cm-negative {color: #d44;} 89 | .cm-positive {color: #292;} 90 | .cm-header, .cm-strong {font-weight: bold;} 91 | .cm-em {font-style: italic;} 92 | .cm-link {text-decoration: underline;} 93 | 94 | .cm-invalidchar {color: #f00;} 95 | 96 | div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;} 97 | div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} 98 | .CodeMirror-activeline-background {background: #e8f2ff;} 99 | 100 | /* STOP */ 101 | 102 | /* The rest of this file contains styles related to the mechanics of 103 | the editor. You probably shouldn't touch them. */ 104 | 105 | .CodeMirror { 106 | line-height: 1; 107 | position: relative; 108 | overflow: hidden; 109 | background: white; 110 | color: black; 111 | } 112 | 113 | .CodeMirror-scroll { 114 | /* 30px is the magic margin used to hide the element's real scrollbars */ 115 | /* See overflow: hidden in .CodeMirror */ 116 | margin-bottom: -30px; margin-right: -30px; 117 | padding-bottom: 30px; padding-right: 30px; 118 | height: 100%; 119 | outline: none; /* Prevent dragging from highlighting the element */ 120 | position: relative; 121 | -moz-box-sizing: content-box; 122 | box-sizing: content-box; 123 | } 124 | .CodeMirror-sizer { 125 | position: relative; 126 | } 127 | 128 | /* The fake, visible scrollbars. Used to force redraw during scrolling 129 | before actuall scrolling happens, thus preventing shaking and 130 | flickering artifacts. */ 131 | .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { 132 | position: absolute; 133 | z-index: 6; 134 | display: none; 135 | } 136 | .CodeMirror-vscrollbar { 137 | right: 0; top: 0; 138 | overflow-x: hidden; 139 | overflow-y: scroll; 140 | } 141 | .CodeMirror-hscrollbar { 142 | bottom: 0; left: 0; 143 | overflow-y: hidden; 144 | overflow-x: scroll; 145 | } 146 | .CodeMirror-scrollbar-filler { 147 | right: 0; bottom: 0; 148 | } 149 | .CodeMirror-gutter-filler { 150 | left: 0; bottom: 0; 151 | } 152 | 153 | .CodeMirror-gutters { 154 | position: absolute; left: 0; top: 0; 155 | padding-bottom: 30px; 156 | z-index: 3; 157 | } 158 | .CodeMirror-gutter { 159 | white-space: normal; 160 | height: 100%; 161 | -moz-box-sizing: content-box; 162 | box-sizing: content-box; 163 | padding-bottom: 30px; 164 | margin-bottom: -32px; 165 | display: inline-block; 166 | /* Hack to make IE7 behave */ 167 | *zoom:1; 168 | *display:inline; 169 | } 170 | .CodeMirror-gutter-elt { 171 | position: absolute; 172 | cursor: default; 173 | z-index: 4; 174 | } 175 | 176 | .CodeMirror-lines { 177 | cursor: text; 178 | } 179 | .CodeMirror pre { 180 | /* Reset some styles that the rest of the page might have set */ 181 | -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; 182 | border-width: 0; 183 | background: transparent; 184 | font-family: inherit; 185 | font-size: inherit; 186 | margin: 0; 187 | white-space: pre; 188 | word-wrap: normal; 189 | line-height: inherit; 190 | color: inherit; 191 | z-index: 2; 192 | position: relative; 193 | overflow: visible; 194 | } 195 | .CodeMirror-wrap pre { 196 | word-wrap: break-word; 197 | white-space: pre-wrap; 198 | word-break: normal; 199 | } 200 | .CodeMirror-code pre { 201 | border-right: 30px solid transparent; 202 | width: -webkit-fit-content; 203 | width: -moz-fit-content; 204 | width: fit-content; 205 | } 206 | .CodeMirror-wrap .CodeMirror-code pre { 207 | border-right: none; 208 | width: auto; 209 | } 210 | .CodeMirror-linebackground { 211 | position: absolute; 212 | left: 0; right: 0; top: 0; bottom: 0; 213 | z-index: 0; 214 | } 215 | 216 | .CodeMirror-linewidget { 217 | position: relative; 218 | z-index: 2; 219 | overflow: auto; 220 | } 221 | 222 | .CodeMirror-widget {} 223 | 224 | .CodeMirror-wrap .CodeMirror-scroll { 225 | overflow-x: hidden; 226 | } 227 | 228 | .CodeMirror-measure { 229 | position: absolute; 230 | width: 100%; 231 | height: 0; 232 | overflow: hidden; 233 | visibility: hidden; 234 | } 235 | .CodeMirror-measure pre { position: static; } 236 | 237 | .CodeMirror div.CodeMirror-cursor { 238 | position: absolute; 239 | visibility: hidden; 240 | border-right: none; 241 | width: 0; 242 | } 243 | .CodeMirror-focused div.CodeMirror-cursor { 244 | visibility: visible; 245 | } 246 | 247 | .CodeMirror-selected { background: #d9d9d9; } 248 | .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; } 249 | 250 | .cm-searching { 251 | background: #ffa; 252 | background: rgba(255, 255, 0, .4); 253 | } 254 | 255 | /* IE7 hack to prevent it from returning funny offsetTops on the spans */ 256 | .CodeMirror span { *vertical-align: text-bottom; } 257 | 258 | @media print { 259 | /* Hide the cursor when printing */ 260 | .CodeMirror div.CodeMirror-cursor { 261 | visibility: hidden; 262 | } 263 | } 264 | -------------------------------------------------------------------------------- /css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v2.1.1 | MIT License | git.io/normalize */ 2 | 3 | /* ========================================================================== 4 | HTML5 display definitions 5 | ========================================================================== */ 6 | 7 | /** 8 | * Correct `block` display not defined in IE 8/9. 9 | */ 10 | 11 | article, 12 | aside, 13 | details, 14 | figcaption, 15 | figure, 16 | footer, 17 | header, 18 | hgroup, 19 | main, 20 | nav, 21 | section, 22 | summary { 23 | display: block; 24 | } 25 | 26 | /** 27 | * Correct `inline-block` display not defined in IE 8/9. 28 | */ 29 | 30 | audio, 31 | canvas, 32 | video { 33 | display: inline-block; 34 | } 35 | 36 | /** 37 | * Prevent modern browsers from displaying `audio` without controls. 38 | * Remove excess height in iOS 5 devices. 39 | */ 40 | 41 | audio:not([controls]) { 42 | display: none; 43 | height: 0; 44 | } 45 | 46 | /** 47 | * Address styling not present in IE 8/9. 48 | */ 49 | 50 | [hidden] { 51 | display: none; 52 | } 53 | 54 | /* ========================================================================== 55 | Base 56 | ========================================================================== */ 57 | 58 | /** 59 | * 1. Prevent system color scheme's background color being used in Firefox, IE, 60 | * and Opera. 61 | * 2. Prevent system color scheme's text color being used in Firefox, IE, and 62 | * Opera. 63 | * 3. Set default font family to sans-serif. 64 | * 4. Prevent iOS text size adjust after orientation change, without disabling 65 | * user zoom. 66 | */ 67 | 68 | html { 69 | background: #fff; /* 1 */ 70 | color: #000; /* 2 */ 71 | font-family: sans-serif; /* 3 */ 72 | -ms-text-size-adjust: 100%; /* 4 */ 73 | -webkit-text-size-adjust: 100%; /* 4 */ 74 | } 75 | 76 | /** 77 | * Remove default margin. 78 | */ 79 | 80 | body { 81 | margin: 0; 82 | } 83 | 84 | /* ========================================================================== 85 | Links 86 | ========================================================================== */ 87 | 88 | /** 89 | * Address `outline` inconsistency between Chrome and other browsers. 90 | */ 91 | 92 | a:focus { 93 | outline: thin dotted; 94 | } 95 | 96 | /** 97 | * Improve readability when focused and also mouse hovered in all browsers. 98 | */ 99 | 100 | a:active, 101 | a:hover { 102 | outline: 0; 103 | } 104 | 105 | /* ========================================================================== 106 | Typography 107 | ========================================================================== */ 108 | 109 | /** 110 | * Address variable `h1` font-size and margin within `section` and `article` 111 | * contexts in Firefox 4+, Safari 5, and Chrome. 112 | */ 113 | 114 | h1 { 115 | font-size: 2em; 116 | margin: 0.67em 0; 117 | } 118 | 119 | /** 120 | * Address styling not present in IE 8/9, Safari 5, and Chrome. 121 | */ 122 | 123 | abbr[title] { 124 | border-bottom: 1px dotted; 125 | } 126 | 127 | /** 128 | * Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome. 129 | */ 130 | 131 | b, 132 | strong { 133 | font-weight: bold; 134 | } 135 | 136 | /** 137 | * Address styling not present in Safari 5 and Chrome. 138 | */ 139 | 140 | dfn { 141 | font-style: italic; 142 | } 143 | 144 | /** 145 | * Address differences between Firefox and other browsers. 146 | */ 147 | 148 | hr { 149 | -moz-box-sizing: content-box; 150 | box-sizing: content-box; 151 | height: 0; 152 | } 153 | 154 | /** 155 | * Address styling not present in IE 8/9. 156 | */ 157 | 158 | mark { 159 | background: #ff0; 160 | color: #000; 161 | } 162 | 163 | /** 164 | * Correct font family set oddly in Safari 5 and Chrome. 165 | */ 166 | 167 | code, 168 | kbd, 169 | pre, 170 | samp { 171 | font-family: monospace, serif; 172 | font-size: 1em; 173 | } 174 | 175 | /** 176 | * Improve readability of pre-formatted text in all browsers. 177 | */ 178 | 179 | pre { 180 | white-space: pre-wrap; 181 | } 182 | 183 | /** 184 | * Set consistent quote types. 185 | */ 186 | 187 | q { 188 | quotes: "\201C" "\201D" "\2018" "\2019"; 189 | } 190 | 191 | /** 192 | * Address inconsistent and variable font size in all browsers. 193 | */ 194 | 195 | small { 196 | font-size: 80%; 197 | } 198 | 199 | /** 200 | * Prevent `sub` and `sup` affecting `line-height` in all browsers. 201 | */ 202 | 203 | sub, 204 | sup { 205 | font-size: 75%; 206 | line-height: 0; 207 | position: relative; 208 | vertical-align: baseline; 209 | } 210 | 211 | sup { 212 | top: -0.5em; 213 | } 214 | 215 | sub { 216 | bottom: -0.25em; 217 | } 218 | 219 | /* ========================================================================== 220 | Embedded content 221 | ========================================================================== */ 222 | 223 | /** 224 | * Remove border when inside `a` element in IE 8/9. 225 | */ 226 | 227 | img { 228 | border: 0; 229 | } 230 | 231 | /** 232 | * Correct overflow displayed oddly in IE 9. 233 | */ 234 | 235 | svg:not(:root) { 236 | overflow: hidden; 237 | } 238 | 239 | /* ========================================================================== 240 | Figures 241 | ========================================================================== */ 242 | 243 | /** 244 | * Address margin not present in IE 8/9 and Safari 5. 245 | */ 246 | 247 | figure { 248 | margin: 0; 249 | } 250 | 251 | /* ========================================================================== 252 | Forms 253 | ========================================================================== */ 254 | 255 | /** 256 | * Define consistent border, margin, and padding. 257 | */ 258 | 259 | fieldset { 260 | border: 1px solid #c0c0c0; 261 | margin: 0 2px; 262 | padding: 0.35em 0.625em 0.75em; 263 | } 264 | 265 | /** 266 | * 1. Correct `color` not being inherited in IE 8/9. 267 | * 2. Remove padding so people aren't caught out if they zero out fieldsets. 268 | */ 269 | 270 | legend { 271 | border: 0; /* 1 */ 272 | padding: 0; /* 2 */ 273 | } 274 | 275 | /** 276 | * 1. Correct font family not being inherited in all browsers. 277 | * 2. Correct font size not being inherited in all browsers. 278 | * 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome. 279 | */ 280 | 281 | button, 282 | input, 283 | select, 284 | textarea { 285 | font-family: inherit; /* 1 */ 286 | font-size: 100%; /* 2 */ 287 | margin: 0; /* 3 */ 288 | } 289 | 290 | /** 291 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in 292 | * the UA stylesheet. 293 | */ 294 | 295 | button, 296 | input { 297 | line-height: normal; 298 | } 299 | 300 | /** 301 | * Address inconsistent `text-transform` inheritance for `button` and `select`. 302 | * All other form control elements do not inherit `text-transform` values. 303 | * Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+. 304 | * Correct `select` style inheritance in Firefox 4+ and Opera. 305 | */ 306 | 307 | button, 308 | select { 309 | text-transform: none; 310 | } 311 | 312 | /** 313 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` 314 | * and `video` controls. 315 | * 2. Correct inability to style clickable `input` types in iOS. 316 | * 3. Improve usability and consistency of cursor style between image-type 317 | * `input` and others. 318 | */ 319 | 320 | button, 321 | html input[type="button"], /* 1 */ 322 | input[type="reset"], 323 | input[type="submit"] { 324 | -webkit-appearance: button; /* 2 */ 325 | cursor: pointer; /* 3 */ 326 | } 327 | 328 | /** 329 | * Re-set default cursor for disabled elements. 330 | */ 331 | 332 | button[disabled], 333 | html input[disabled] { 334 | cursor: default; 335 | } 336 | 337 | /** 338 | * 1. Address box sizing set to `content-box` in IE 8/9. 339 | * 2. Remove excess padding in IE 8/9. 340 | */ 341 | 342 | input[type="checkbox"], 343 | input[type="radio"] { 344 | box-sizing: border-box; /* 1 */ 345 | padding: 0; /* 2 */ 346 | } 347 | 348 | /** 349 | * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. 350 | * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome 351 | * (include `-moz` to future-proof). 352 | */ 353 | 354 | input[type="search"] { 355 | -webkit-appearance: textfield; /* 1 */ 356 | -moz-box-sizing: content-box; 357 | -webkit-box-sizing: content-box; /* 2 */ 358 | box-sizing: content-box; 359 | } 360 | 361 | /** 362 | * Remove inner padding and search cancel button in Safari 5 and Chrome 363 | * on OS X. 364 | */ 365 | 366 | input[type="search"]::-webkit-search-cancel-button, 367 | input[type="search"]::-webkit-search-decoration { 368 | -webkit-appearance: none; 369 | } 370 | 371 | /** 372 | * Remove inner padding and border in Firefox 4+. 373 | */ 374 | 375 | button::-moz-focus-inner, 376 | input::-moz-focus-inner { 377 | border: 0; 378 | padding: 0; 379 | } 380 | 381 | /** 382 | * 1. Remove default vertical scrollbar in IE 8/9. 383 | * 2. Improve readability and alignment in all browsers. 384 | */ 385 | 386 | textarea { 387 | overflow: auto; /* 1 */ 388 | vertical-align: top; /* 2 */ 389 | } 390 | 391 | /* ========================================================================== 392 | Tables 393 | ========================================================================== */ 394 | 395 | /** 396 | * Remove most spacing between table cells. 397 | */ 398 | 399 | table { 400 | border-collapse: collapse; 401 | border-spacing: 0; 402 | } 403 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | HTML5 Notifications 10 | 11 | 12 | 13 | 14 | 72 | 73 | 74 |
75 |
76 |
77 | 85 |
86 |
87 |
88 |
89 |

90 |

.

91 |
92 |
93 |
94 |
95 | 96 |
97 |
98 |
99 | . 100 | 101 | 102 |
103 |
104 |
105 | 106 |
107 |
108 |
109 |
110 |

111 |
112 |
113 |
114 |
115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 |
123 |
124 |
125 |
126 | 127 |
128 |
129 |

*

130 |
131 |
132 | 133 |
134 |
135 | 136 |
137 |
138 |

139 |
140 |
141 | 142 |
143 |
144 | 145 |
146 |
147 |

148 |
149 |
150 | 155 |
156 |
157 | 158 | 159 | 160 |
161 |
162 | 163 | 164 |
165 |
166 | 167 |
168 |
169 | 170 |
171 |
172 |
173 | 174 |
175 |
176 |

177 |
178 |
179 |
180 |
181 |
182 |
183 | 184 |
185 |
186 | 187 |
188 |
189 |
190 |
191 |
192 |
193 | 194 |
195 |
196 |
197 |
198 |
199 | 200 |
201 |
202 | 203 |
204 |
205 | 206 |
207 |
208 | 209 |
210 |
211 |
212 |
213 |
214 | 215 | 230 | 231 |
232 |

233 |
234 |
235 |
236 |
237 |
238 |

239 |
240 |
241 | 245 |
246 |
247 |
248 |
249 | 250 |
251 |
252 |
253 |

254 | 255 |

256 | × 257 |
258 | 259 |
260 |

261 |
262 |
263 |
264 |

265 |
266 |
267 |
268 |
269 | @ 270 |
271 |
272 | 273 |
274 |
275 |
276 |
277 |
278 |
279 | 280 |
281 |
282 |
283 | × 284 |
285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | -------------------------------------------------------------------------------- /js/app.js: -------------------------------------------------------------------------------- 1 | // 405 | -------------------------------------------------------------------------------- /js/codemirror/css.js: -------------------------------------------------------------------------------- 1 | CodeMirror.defineMode("css", function(config, parserConfig) { 2 | "use strict"; 3 | 4 | if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css"); 5 | 6 | var indentUnit = config.indentUnit, 7 | hooks = parserConfig.hooks || {}, 8 | atMediaTypes = parserConfig.atMediaTypes || {}, 9 | atMediaFeatures = parserConfig.atMediaFeatures || {}, 10 | propertyKeywords = parserConfig.propertyKeywords || {}, 11 | colorKeywords = parserConfig.colorKeywords || {}, 12 | valueKeywords = parserConfig.valueKeywords || {}, 13 | allowNested = !!parserConfig.allowNested, 14 | type = null; 15 | 16 | function ret(style, tp) { type = tp; return style; } 17 | 18 | function tokenBase(stream, state) { 19 | var ch = stream.next(); 20 | if (hooks[ch]) { 21 | // result[0] is style and result[1] is type 22 | var result = hooks[ch](stream, state); 23 | if (result !== false) return result; 24 | } 25 | if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("def", stream.current());} 26 | else if (ch == "=") ret(null, "compare"); 27 | else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare"); 28 | else if (ch == "\"" || ch == "'") { 29 | state.tokenize = tokenString(ch); 30 | return state.tokenize(stream, state); 31 | } 32 | else if (ch == "#") { 33 | stream.eatWhile(/[\w\\\-]/); 34 | return ret("atom", "hash"); 35 | } 36 | else if (ch == "!") { 37 | stream.match(/^\s*\w*/); 38 | return ret("keyword", "important"); 39 | } 40 | else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) { 41 | stream.eatWhile(/[\w.%]/); 42 | return ret("number", "unit"); 43 | } 44 | else if (ch === "-") { 45 | if (/\d/.test(stream.peek())) { 46 | stream.eatWhile(/[\w.%]/); 47 | return ret("number", "unit"); 48 | } else if (stream.match(/^[^-]+-/)) { 49 | return ret("meta", "meta"); 50 | } 51 | } 52 | else if (/[,+>*\/]/.test(ch)) { 53 | return ret(null, "select-op"); 54 | } 55 | else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) { 56 | return ret("qualifier", "qualifier"); 57 | } 58 | else if (ch == ":") { 59 | return ret("operator", ch); 60 | } 61 | else if (/[;{}\[\]\(\)]/.test(ch)) { 62 | return ret(null, ch); 63 | } 64 | else if (ch == "u" && stream.match("rl(")) { 65 | stream.backUp(1); 66 | state.tokenize = tokenParenthesized; 67 | return ret("property", "variable"); 68 | } 69 | else { 70 | stream.eatWhile(/[\w\\\-]/); 71 | return ret("property", "variable"); 72 | } 73 | } 74 | 75 | function tokenString(quote, nonInclusive) { 76 | return function(stream, state) { 77 | var escaped = false, ch; 78 | while ((ch = stream.next()) != null) { 79 | if (ch == quote && !escaped) 80 | break; 81 | escaped = !escaped && ch == "\\"; 82 | } 83 | if (!escaped) { 84 | if (nonInclusive) stream.backUp(1); 85 | state.tokenize = tokenBase; 86 | } 87 | return ret("string", "string"); 88 | }; 89 | } 90 | 91 | function tokenParenthesized(stream, state) { 92 | stream.next(); // Must be '(' 93 | if (!stream.match(/\s*[\"\']/, false)) 94 | state.tokenize = tokenString(")", true); 95 | else 96 | state.tokenize = tokenBase; 97 | return ret(null, "("); 98 | } 99 | 100 | return { 101 | startState: function(base) { 102 | return {tokenize: tokenBase, 103 | baseIndent: base || 0, 104 | stack: [], 105 | lastToken: null}; 106 | }, 107 | 108 | token: function(stream, state) { 109 | 110 | // Use these terms when applicable (see http://www.xanthir.com/blog/b4E50) 111 | // 112 | // rule** or **ruleset: 113 | // A selector + braces combo, or an at-rule. 114 | // 115 | // declaration block: 116 | // A sequence of declarations. 117 | // 118 | // declaration: 119 | // A property + colon + value combo. 120 | // 121 | // property value: 122 | // The entire value of a property. 123 | // 124 | // component value: 125 | // A single piece of a property value. Like the 5px in 126 | // text-shadow: 0 0 5px blue;. Can also refer to things that are 127 | // multiple terms, like the 1-4 terms that make up the background-size 128 | // portion of the background shorthand. 129 | // 130 | // term: 131 | // The basic unit of author-facing CSS, like a single number (5), 132 | // dimension (5px), string ("foo"), or function. Officially defined 133 | // by the CSS 2.1 grammar (look for the 'term' production) 134 | // 135 | // 136 | // simple selector: 137 | // A single atomic selector, like a type selector, an attr selector, a 138 | // class selector, etc. 139 | // 140 | // compound selector: 141 | // One or more simple selectors without a combinator. div.example is 142 | // compound, div > .example is not. 143 | // 144 | // complex selector: 145 | // One or more compound selectors chained with combinators. 146 | // 147 | // combinator: 148 | // The parts of selectors that express relationships. There are four 149 | // currently - the space (descendant combinator), the greater-than 150 | // bracket (child combinator), the plus sign (next sibling combinator), 151 | // and the tilda (following sibling combinator). 152 | // 153 | // sequence of selectors: 154 | // One or more of the named type of selector chained with commas. 155 | 156 | state.tokenize = state.tokenize || tokenBase; 157 | if (state.tokenize == tokenBase && stream.eatSpace()) return null; 158 | var style = state.tokenize(stream, state); 159 | if (style && typeof style != "string") style = ret(style[0], style[1]); 160 | 161 | // Changing style returned based on context 162 | var context = state.stack[state.stack.length-1]; 163 | if (style == "variable") { 164 | if (type == "variable-definition") state.stack.push("propertyValue"); 165 | return state.lastToken = "variable-2"; 166 | } else if (style == "property") { 167 | var word = stream.current().toLowerCase(); 168 | if (context == "propertyValue") { 169 | if (valueKeywords.hasOwnProperty(word)) { 170 | style = "string-2"; 171 | } else if (colorKeywords.hasOwnProperty(word)) { 172 | style = "keyword"; 173 | } else { 174 | style = "variable-2"; 175 | } 176 | } else if (context == "rule") { 177 | if (!propertyKeywords.hasOwnProperty(word)) { 178 | style += " error"; 179 | } 180 | } else if (context == "block") { 181 | // if a value is present in both property, value, or color, the order 182 | // of preference is property -> color -> value 183 | if (propertyKeywords.hasOwnProperty(word)) { 184 | style = "property"; 185 | } else if (colorKeywords.hasOwnProperty(word)) { 186 | style = "keyword"; 187 | } else if (valueKeywords.hasOwnProperty(word)) { 188 | style = "string-2"; 189 | } else { 190 | style = "tag"; 191 | } 192 | } else if (!context || context == "@media{") { 193 | style = "tag"; 194 | } else if (context == "@media") { 195 | if (atMediaTypes[stream.current()]) { 196 | style = "attribute"; // Known attribute 197 | } else if (/^(only|not)$/.test(word)) { 198 | style = "keyword"; 199 | } else if (word == "and") { 200 | style = "error"; // "and" is only allowed in @mediaType 201 | } else if (atMediaFeatures.hasOwnProperty(word)) { 202 | style = "error"; // Known property, should be in @mediaType( 203 | } else { 204 | // Unknown, expecting keyword or attribute, assuming attribute 205 | style = "attribute error"; 206 | } 207 | } else if (context == "@mediaType") { 208 | if (atMediaTypes.hasOwnProperty(word)) { 209 | style = "attribute"; 210 | } else if (word == "and") { 211 | style = "operator"; 212 | } else if (/^(only|not)$/.test(word)) { 213 | style = "error"; // Only allowed in @media 214 | } else { 215 | // Unknown attribute or property, but expecting property (preceded 216 | // by "and"). Should be in parentheses 217 | style = "error"; 218 | } 219 | } else if (context == "@mediaType(") { 220 | if (propertyKeywords.hasOwnProperty(word)) { 221 | // do nothing, remains "property" 222 | } else if (atMediaTypes.hasOwnProperty(word)) { 223 | style = "error"; // Known property, should be in parentheses 224 | } else if (word == "and") { 225 | style = "operator"; 226 | } else if (/^(only|not)$/.test(word)) { 227 | style = "error"; // Only allowed in @media 228 | } else { 229 | style += " error"; 230 | } 231 | } else if (context == "@import") { 232 | style = "tag"; 233 | } else { 234 | style = "error"; 235 | } 236 | } else if (style == "atom") { 237 | if(!context || context == "@media{" || context == "block") { 238 | style = "builtin"; 239 | } else if (context == "propertyValue") { 240 | if (!/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) { 241 | style += " error"; 242 | } 243 | } else { 244 | style = "error"; 245 | } 246 | } else if (context == "@media" && type == "{") { 247 | style = "error"; 248 | } 249 | 250 | // Push/pop context stack 251 | if (type == "{") { 252 | if (context == "@media" || context == "@mediaType") { 253 | state.stack[state.stack.length-1] = "@media{"; 254 | } 255 | else { 256 | var newContext = allowNested ? "block" : "rule"; 257 | state.stack.push(newContext); 258 | } 259 | } 260 | else if (type == "}") { 261 | if (context == "interpolation") style = "operator"; 262 | state.stack.pop(); 263 | if (context == "propertyValue") state.stack.pop(); 264 | } 265 | else if (type == "interpolation") state.stack.push("interpolation"); 266 | else if (type == "@media") state.stack.push("@media"); 267 | else if (type == "@import") state.stack.push("@import"); 268 | else if (context == "@media" && /\b(keyword|attribute)\b/.test(style)) 269 | state.stack[state.stack.length-1] = "@mediaType"; 270 | else if (context == "@mediaType" && stream.current() == ",") 271 | state.stack[state.stack.length-1] = "@media"; 272 | else if (type == "(") { 273 | if (context == "@media" || context == "@mediaType") { 274 | // Make sure @mediaType is used to avoid error on { 275 | state.stack[state.stack.length-1] = "@mediaType"; 276 | state.stack.push("@mediaType("); 277 | } 278 | else state.stack.push("("); 279 | } 280 | else if (type == ")") { 281 | if (context == "propertyValue") { 282 | // In @mediaType( without closing ; after propertyValue 283 | state.stack.pop(); 284 | } 285 | state.stack.pop(); 286 | } 287 | else if (type == ":" && state.lastToken == "property") state.stack.push("propertyValue"); 288 | else if (context == "propertyValue" && type == ";") state.stack.pop(); 289 | else if (context == "@import" && type == ";") state.stack.pop(); 290 | 291 | return state.lastToken = style; 292 | }, 293 | 294 | indent: function(state, textAfter) { 295 | var n = state.stack.length; 296 | if (/^\}/.test(textAfter)) 297 | n -= state.stack[n-1] == "propertyValue" ? 2 : 1; 298 | return state.baseIndent + n * indentUnit; 299 | }, 300 | 301 | electricChars: "}", 302 | blockCommentStart: "/*", 303 | blockCommentEnd: "*/", 304 | fold: "brace" 305 | }; 306 | }); 307 | 308 | (function() { 309 | function keySet(array) { 310 | var keys = {}; 311 | for (var i = 0; i < array.length; ++i) { 312 | keys[array[i]] = true; 313 | } 314 | return keys; 315 | } 316 | 317 | var atMediaTypes = keySet([ 318 | "all", "aural", "braille", "handheld", "print", "projection", "screen", 319 | "tty", "tv", "embossed" 320 | ]); 321 | 322 | var atMediaFeatures = keySet([ 323 | "width", "min-width", "max-width", "height", "min-height", "max-height", 324 | "device-width", "min-device-width", "max-device-width", "device-height", 325 | "min-device-height", "max-device-height", "aspect-ratio", 326 | "min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio", 327 | "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color", 328 | "max-color", "color-index", "min-color-index", "max-color-index", 329 | "monochrome", "min-monochrome", "max-monochrome", "resolution", 330 | "min-resolution", "max-resolution", "scan", "grid" 331 | ]); 332 | 333 | var propertyKeywords = keySet([ 334 | "align-content", "align-items", "align-self", "alignment-adjust", 335 | "alignment-baseline", "anchor-point", "animation", "animation-delay", 336 | "animation-direction", "animation-duration", "animation-iteration-count", 337 | "animation-name", "animation-play-state", "animation-timing-function", 338 | "appearance", "azimuth", "backface-visibility", "background", 339 | "background-attachment", "background-clip", "background-color", 340 | "background-image", "background-origin", "background-position", 341 | "background-repeat", "background-size", "baseline-shift", "binding", 342 | "bleed", "bookmark-label", "bookmark-level", "bookmark-state", 343 | "bookmark-target", "border", "border-bottom", "border-bottom-color", 344 | "border-bottom-left-radius", "border-bottom-right-radius", 345 | "border-bottom-style", "border-bottom-width", "border-collapse", 346 | "border-color", "border-image", "border-image-outset", 347 | "border-image-repeat", "border-image-slice", "border-image-source", 348 | "border-image-width", "border-left", "border-left-color", 349 | "border-left-style", "border-left-width", "border-radius", "border-right", 350 | "border-right-color", "border-right-style", "border-right-width", 351 | "border-spacing", "border-style", "border-top", "border-top-color", 352 | "border-top-left-radius", "border-top-right-radius", "border-top-style", 353 | "border-top-width", "border-width", "bottom", "box-decoration-break", 354 | "box-shadow", "box-sizing", "break-after", "break-before", "break-inside", 355 | "caption-side", "clear", "clip", "color", "color-profile", "column-count", 356 | "column-fill", "column-gap", "column-rule", "column-rule-color", 357 | "column-rule-style", "column-rule-width", "column-span", "column-width", 358 | "columns", "content", "counter-increment", "counter-reset", "crop", "cue", 359 | "cue-after", "cue-before", "cursor", "direction", "display", 360 | "dominant-baseline", "drop-initial-after-adjust", 361 | "drop-initial-after-align", "drop-initial-before-adjust", 362 | "drop-initial-before-align", "drop-initial-size", "drop-initial-value", 363 | "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis", 364 | "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap", 365 | "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings", 366 | "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust", 367 | "font-stretch", "font-style", "font-synthesis", "font-variant", 368 | "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", 369 | "font-variant-ligatures", "font-variant-numeric", "font-variant-position", 370 | "font-weight", "grid-cell", "grid-column", "grid-column-align", 371 | "grid-column-sizing", "grid-column-span", "grid-columns", "grid-flow", 372 | "grid-row", "grid-row-align", "grid-row-sizing", "grid-row-span", 373 | "grid-rows", "grid-template", "hanging-punctuation", "height", "hyphens", 374 | "icon", "image-orientation", "image-rendering", "image-resolution", 375 | "inline-box-align", "justify-content", "left", "letter-spacing", 376 | "line-break", "line-height", "line-stacking", "line-stacking-ruby", 377 | "line-stacking-shift", "line-stacking-strategy", "list-style", 378 | "list-style-image", "list-style-position", "list-style-type", "margin", 379 | "margin-bottom", "margin-left", "margin-right", "margin-top", 380 | "marker-offset", "marks", "marquee-direction", "marquee-loop", 381 | "marquee-play-count", "marquee-speed", "marquee-style", "max-height", 382 | "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index", 383 | "nav-left", "nav-right", "nav-up", "opacity", "order", "orphans", "outline", 384 | "outline-color", "outline-offset", "outline-style", "outline-width", 385 | "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y", 386 | "padding", "padding-bottom", "padding-left", "padding-right", "padding-top", 387 | "page", "page-break-after", "page-break-before", "page-break-inside", 388 | "page-policy", "pause", "pause-after", "pause-before", "perspective", 389 | "perspective-origin", "pitch", "pitch-range", "play-during", "position", 390 | "presentation-level", "punctuation-trim", "quotes", "region-break-after", 391 | "region-break-before", "region-break-inside", "region-fragment", 392 | "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness", 393 | "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang", 394 | "ruby-position", "ruby-span", "shape-inside", "shape-outside", "size", 395 | "speak", "speak-as", "speak-header", 396 | "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set", 397 | "tab-size", "table-layout", "target", "target-name", "target-new", 398 | "target-position", "text-align", "text-align-last", "text-decoration", 399 | "text-decoration-color", "text-decoration-line", "text-decoration-skip", 400 | "text-decoration-style", "text-emphasis", "text-emphasis-color", 401 | "text-emphasis-position", "text-emphasis-style", "text-height", 402 | "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow", 403 | "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position", 404 | "text-wrap", "top", "transform", "transform-origin", "transform-style", 405 | "transition", "transition-delay", "transition-duration", 406 | "transition-property", "transition-timing-function", "unicode-bidi", 407 | "vertical-align", "visibility", "voice-balance", "voice-duration", 408 | "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress", 409 | "voice-volume", "volume", "white-space", "widows", "width", "word-break", 410 | "word-spacing", "word-wrap", "z-index", "zoom", 411 | // SVG-specific 412 | "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color", 413 | "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events", 414 | "color-interpolation", "color-interpolation-filters", "color-profile", 415 | "color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering", 416 | "marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke", 417 | "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", 418 | "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering", 419 | "baseline-shift", "dominant-baseline", "glyph-orientation-horizontal", 420 | "glyph-orientation-vertical", "kerning", "text-anchor", "writing-mode" 421 | ]); 422 | 423 | var colorKeywords = keySet([ 424 | "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", 425 | "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", 426 | "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", 427 | "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod", 428 | "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen", 429 | "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", 430 | "darkslateblue", "darkslategray", "darkturquoise", "darkviolet", 431 | "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick", 432 | "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", 433 | "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", 434 | "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender", 435 | "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", 436 | "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink", 437 | "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", 438 | "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", 439 | "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", 440 | "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", 441 | "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", 442 | "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", 443 | "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", 444 | "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", 445 | "purple", "red", "rosybrown", "royalblue", "saddlebrown", "salmon", 446 | "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", 447 | "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan", 448 | "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white", 449 | "whitesmoke", "yellow", "yellowgreen" 450 | ]); 451 | 452 | var valueKeywords = keySet([ 453 | "above", "absolute", "activeborder", "activecaption", "afar", 454 | "after-white-space", "ahead", "alias", "all", "all-scroll", "alternate", 455 | "always", "amharic", "amharic-abegede", "antialiased", "appworkspace", 456 | "arabic-indic", "armenian", "asterisks", "auto", "avoid", "avoid-column", "avoid-page", 457 | "avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary", 458 | "bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box", 459 | "both", "bottom", "break", "break-all", "break-word", "button", "button-bevel", 460 | "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian", 461 | "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret", 462 | "cell", "center", "checkbox", "circle", "cjk-earthly-branch", 463 | "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote", 464 | "col-resize", "collapse", "column", "compact", "condensed", "contain", "content", 465 | "content-box", "context-menu", "continuous", "copy", "cover", "crop", 466 | "cross", "crosshair", "currentcolor", "cursive", "dashed", "decimal", 467 | "decimal-leading-zero", "default", "default-button", "destination-atop", 468 | "destination-in", "destination-out", "destination-over", "devanagari", 469 | "disc", "discard", "document", "dot-dash", "dot-dot-dash", "dotted", 470 | "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out", 471 | "element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede", 472 | "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er", 473 | "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er", 474 | "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et", 475 | "ethiopic-halehame-gez", "ethiopic-halehame-om-et", 476 | "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et", 477 | "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", 478 | "ethiopic-halehame-tig", "ew-resize", "expanded", "extra-condensed", 479 | "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "footnotes", 480 | "forwards", "from", "geometricPrecision", "georgian", "graytext", "groove", 481 | "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew", 482 | "help", "hidden", "hide", "higher", "highlight", "highlighttext", 483 | "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore", 484 | "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite", 485 | "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis", 486 | "inline-block", "inline-table", "inset", "inside", "intrinsic", "invert", 487 | "italic", "justify", "kannada", "katakana", "katakana-iroha", "keep-all", "khmer", 488 | "landscape", "lao", "large", "larger", "left", "level", "lighter", 489 | "line-through", "linear", "lines", "list-item", "listbox", "listitem", 490 | "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian", 491 | "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian", 492 | "lower-roman", "lowercase", "ltr", "malayalam", "match", 493 | "media-controls-background", "media-current-time-display", 494 | "media-fullscreen-button", "media-mute-button", "media-play-button", 495 | "media-return-to-realtime-button", "media-rewind-button", 496 | "media-seek-back-button", "media-seek-forward-button", "media-slider", 497 | "media-sliderthumb", "media-time-remaining-display", "media-volume-slider", 498 | "media-volume-slider-container", "media-volume-sliderthumb", "medium", 499 | "menu", "menulist", "menulist-button", "menulist-text", 500 | "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic", 501 | "mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize", 502 | "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop", 503 | "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap", 504 | "ns-resize", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote", 505 | "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset", 506 | "outside", "outside-shape", "overlay", "overline", "padding", "padding-box", 507 | "painted", "page", "paused", "persian", "plus-darker", "plus-lighter", "pointer", 508 | "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button", 509 | "radio", "read-only", "read-write", "read-write-plaintext-only", "rectangle", "region", 510 | "relative", "repeat", "repeat-x", "repeat-y", "reset", "reverse", "rgb", "rgba", 511 | "ridge", "right", "round", "row-resize", "rtl", "run-in", "running", 512 | "s-resize", "sans-serif", "scroll", "scrollbar", "se-resize", "searchfield", 513 | "searchfield-cancel-button", "searchfield-decoration", 514 | "searchfield-results-button", "searchfield-results-decoration", 515 | "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama", 516 | "single", "skip-white-space", "slide", "slider-horizontal", 517 | "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow", 518 | "small", "small-caps", "small-caption", "smaller", "solid", "somali", 519 | "source-atop", "source-in", "source-out", "source-over", "space", "square", 520 | "square-button", "start", "static", "status-bar", "stretch", "stroke", 521 | "sub", "subpixel-antialiased", "super", "sw-resize", "table", 522 | "table-caption", "table-cell", "table-column", "table-column-group", 523 | "table-footer-group", "table-header-group", "table-row", "table-row-group", 524 | "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai", 525 | "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight", 526 | "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er", 527 | "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top", 528 | "transparent", "ultra-condensed", "ultra-expanded", "underline", "up", 529 | "upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal", 530 | "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url", 531 | "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted", 532 | "visibleStroke", "visual", "w-resize", "wait", "wave", "wider", 533 | "window", "windowframe", "windowtext", "x-large", "x-small", "xor", 534 | "xx-large", "xx-small" 535 | ]); 536 | 537 | function tokenCComment(stream, state) { 538 | var maybeEnd = false, ch; 539 | while ((ch = stream.next()) != null) { 540 | if (maybeEnd && ch == "/") { 541 | state.tokenize = null; 542 | break; 543 | } 544 | maybeEnd = (ch == "*"); 545 | } 546 | return ["comment", "comment"]; 547 | } 548 | 549 | CodeMirror.defineMIME("text/css", { 550 | atMediaTypes: atMediaTypes, 551 | atMediaFeatures: atMediaFeatures, 552 | propertyKeywords: propertyKeywords, 553 | colorKeywords: colorKeywords, 554 | valueKeywords: valueKeywords, 555 | hooks: { 556 | "<": function(stream, state) { 557 | function tokenSGMLComment(stream, state) { 558 | var dashes = 0, ch; 559 | while ((ch = stream.next()) != null) { 560 | if (dashes >= 2 && ch == ">") { 561 | state.tokenize = null; 562 | break; 563 | } 564 | dashes = (ch == "-") ? dashes + 1 : 0; 565 | } 566 | return ["comment", "comment"]; 567 | } 568 | if (stream.eat("!")) { 569 | state.tokenize = tokenSGMLComment; 570 | return tokenSGMLComment(stream, state); 571 | } 572 | }, 573 | "/": function(stream, state) { 574 | if (stream.eat("*")) { 575 | state.tokenize = tokenCComment; 576 | return tokenCComment(stream, state); 577 | } 578 | return false; 579 | } 580 | }, 581 | name: "css" 582 | }); 583 | 584 | CodeMirror.defineMIME("text/x-scss", { 585 | atMediaTypes: atMediaTypes, 586 | atMediaFeatures: atMediaFeatures, 587 | propertyKeywords: propertyKeywords, 588 | colorKeywords: colorKeywords, 589 | valueKeywords: valueKeywords, 590 | allowNested: true, 591 | hooks: { 592 | ":": function(stream) { 593 | if (stream.match(/\s*{/)) { 594 | return [null, "{"]; 595 | } 596 | return false; 597 | }, 598 | "$": function(stream) { 599 | stream.match(/^[\w-]+/); 600 | if (stream.peek() == ":") { 601 | return ["variable", "variable-definition"]; 602 | } 603 | return ["variable", "variable"]; 604 | }, 605 | "/": function(stream, state) { 606 | if (stream.eat("/")) { 607 | stream.skipToEnd(); 608 | return ["comment", "comment"]; 609 | } else if (stream.eat("*")) { 610 | state.tokenize = tokenCComment; 611 | return tokenCComment(stream, state); 612 | } else { 613 | return ["operator", "operator"]; 614 | } 615 | }, 616 | "#": function(stream) { 617 | if (stream.eat("{")) { 618 | return ["operator", "interpolation"]; 619 | } else { 620 | stream.eatWhile(/[\w\\\-]/); 621 | return ["atom", "hash"]; 622 | } 623 | } 624 | }, 625 | name: "css" 626 | }); 627 | })(); 628 | -------------------------------------------------------------------------------- /js/codemirror/htmlmixed.js: -------------------------------------------------------------------------------- 1 | CodeMirror.defineMode("htmlmixed", function(config, parserConfig) { 2 | var htmlMode = CodeMirror.getMode(config, {name: "xml", htmlMode: true}); 3 | var cssMode = CodeMirror.getMode(config, "css"); 4 | 5 | var scriptTypes = [], scriptTypesConf = parserConfig && parserConfig.scriptTypes; 6 | scriptTypes.push({matches: /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i, 7 | mode: CodeMirror.getMode(config, "javascript")}); 8 | if (scriptTypesConf) for (var i = 0; i < scriptTypesConf.length; ++i) { 9 | var conf = scriptTypesConf[i]; 10 | scriptTypes.push({matches: conf.matches, mode: conf.mode && CodeMirror.getMode(config, conf.mode)}); 11 | } 12 | scriptTypes.push({matches: /./, 13 | mode: CodeMirror.getMode(config, "text/plain")}); 14 | 15 | function html(stream, state) { 16 | var tagName = state.htmlState.tagName; 17 | var style = htmlMode.token(stream, state.htmlState); 18 | if (tagName == "script" && /\btag\b/.test(style) && stream.current() == ">") { 19 | // Script block: mode to change to depends on type attribute 20 | var scriptType = stream.string.slice(Math.max(0, stream.pos - 100), stream.pos).match(/\btype\s*=\s*("[^"]+"|'[^']+'|\S+)[^<]*$/i); 21 | scriptType = scriptType ? scriptType[1] : ""; 22 | if (scriptType && /[\"\']/.test(scriptType.charAt(0))) scriptType = scriptType.slice(1, scriptType.length - 1); 23 | for (var i = 0; i < scriptTypes.length; ++i) { 24 | var tp = scriptTypes[i]; 25 | if (typeof tp.matches == "string" ? scriptType == tp.matches : tp.matches.test(scriptType)) { 26 | if (tp.mode) { 27 | state.token = script; 28 | state.localMode = tp.mode; 29 | state.localState = tp.mode.startState && tp.mode.startState(htmlMode.indent(state.htmlState, "")); 30 | } 31 | break; 32 | } 33 | } 34 | } else if (tagName == "style" && /\btag\b/.test(style) && stream.current() == ">") { 35 | state.token = css; 36 | state.localMode = cssMode; 37 | state.localState = cssMode.startState(htmlMode.indent(state.htmlState, "")); 38 | } 39 | return style; 40 | } 41 | function maybeBackup(stream, pat, style) { 42 | var cur = stream.current(); 43 | var close = cur.search(pat), m; 44 | if (close > -1) stream.backUp(cur.length - close); 45 | else if (m = cur.match(/<\/?$/)) { 46 | stream.backUp(cur.length); 47 | if (!stream.match(pat, false)) stream.match(cur[0]); 48 | } 49 | return style; 50 | } 51 | function script(stream, state) { 52 | if (stream.match(/^<\/\s*script\s*>/i, false)) { 53 | state.token = html; 54 | state.localState = state.localMode = null; 55 | return html(stream, state); 56 | } 57 | return maybeBackup(stream, /<\/\s*script\s*>/, 58 | state.localMode.token(stream, state.localState)); 59 | } 60 | function css(stream, state) { 61 | if (stream.match(/^<\/\s*style\s*>/i, false)) { 62 | state.token = html; 63 | state.localState = state.localMode = null; 64 | return html(stream, state); 65 | } 66 | return maybeBackup(stream, /<\/\s*style\s*>/, 67 | cssMode.token(stream, state.localState)); 68 | } 69 | 70 | return { 71 | startState: function() { 72 | var state = htmlMode.startState(); 73 | return {token: html, localMode: null, localState: null, htmlState: state}; 74 | }, 75 | 76 | copyState: function(state) { 77 | if (state.localState) 78 | var local = CodeMirror.copyState(state.localMode, state.localState); 79 | return {token: state.token, localMode: state.localMode, localState: local, 80 | htmlState: CodeMirror.copyState(htmlMode, state.htmlState)}; 81 | }, 82 | 83 | token: function(stream, state) { 84 | return state.token(stream, state); 85 | }, 86 | 87 | indent: function(state, textAfter) { 88 | if (!state.localMode || /^\s*<\//.test(textAfter)) 89 | return htmlMode.indent(state.htmlState, textAfter); 90 | else if (state.localMode.indent) 91 | return state.localMode.indent(state.localState, textAfter); 92 | else 93 | return CodeMirror.Pass; 94 | }, 95 | 96 | electricChars: "/{}:", 97 | 98 | innerMode: function(state) { 99 | return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode}; 100 | } 101 | }; 102 | }, "xml", "javascript", "css"); 103 | 104 | CodeMirror.defineMIME("text/html", "htmlmixed"); 105 | -------------------------------------------------------------------------------- /js/codemirror/javascript.js: -------------------------------------------------------------------------------- 1 | // TODO actually recognize syntax of TypeScript constructs 2 | 3 | CodeMirror.defineMode("javascript", function(config, parserConfig) { 4 | var indentUnit = config.indentUnit; 5 | var statementIndent = parserConfig.statementIndent; 6 | var jsonMode = parserConfig.json; 7 | var isTS = parserConfig.typescript; 8 | 9 | // Tokenizer 10 | 11 | var keywords = function(){ 12 | function kw(type) {return {type: type, style: "keyword"};} 13 | var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"); 14 | var operator = kw("operator"), atom = {type: "atom", style: "atom"}; 15 | 16 | var jsKeywords = { 17 | "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B, 18 | "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, 19 | "var": kw("var"), "const": kw("var"), "let": kw("var"), 20 | "function": kw("function"), "catch": kw("catch"), 21 | "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"), 22 | "in": operator, "typeof": operator, "instanceof": operator, 23 | "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom, 24 | "this": kw("this") 25 | }; 26 | 27 | // Extend the 'normal' keywords with the TypeScript language extensions 28 | if (isTS) { 29 | var type = {type: "variable", style: "variable-3"}; 30 | var tsKeywords = { 31 | // object-like things 32 | "interface": kw("interface"), 33 | "class": kw("class"), 34 | "extends": kw("extends"), 35 | "constructor": kw("constructor"), 36 | 37 | // scope modifiers 38 | "public": kw("public"), 39 | "private": kw("private"), 40 | "protected": kw("protected"), 41 | "static": kw("static"), 42 | 43 | "super": kw("super"), 44 | 45 | // types 46 | "string": type, "number": type, "bool": type, "any": type 47 | }; 48 | 49 | for (var attr in tsKeywords) { 50 | jsKeywords[attr] = tsKeywords[attr]; 51 | } 52 | } 53 | 54 | return jsKeywords; 55 | }(); 56 | 57 | var isOperatorChar = /[+\-*&%=<>!?|~^]/; 58 | 59 | function chain(stream, state, f) { 60 | state.tokenize = f; 61 | return f(stream, state); 62 | } 63 | 64 | function nextUntilUnescaped(stream, end) { 65 | var escaped = false, next; 66 | while ((next = stream.next()) != null) { 67 | if (next == end && !escaped) 68 | return false; 69 | escaped = !escaped && next == "\\"; 70 | } 71 | return escaped; 72 | } 73 | 74 | // Used as scratch variables to communicate multiple values without 75 | // consing up tons of objects. 76 | var type, content; 77 | function ret(tp, style, cont) { 78 | type = tp; content = cont; 79 | return style; 80 | } 81 | function jsTokenBase(stream, state) { 82 | var ch = stream.next(); 83 | if (ch == '"' || ch == "'") 84 | return chain(stream, state, jsTokenString(ch)); 85 | else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) 86 | return ret("number", "number"); 87 | else if (/[\[\]{}\(\),;\:\.]/.test(ch)) 88 | return ret(ch); 89 | else if (ch == "0" && stream.eat(/x/i)) { 90 | stream.eatWhile(/[\da-f]/i); 91 | return ret("number", "number"); 92 | } 93 | else if (/\d/.test(ch)) { 94 | stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/); 95 | return ret("number", "number"); 96 | } 97 | else if (ch == "/") { 98 | if (stream.eat("*")) { 99 | return chain(stream, state, jsTokenComment); 100 | } 101 | else if (stream.eat("/")) { 102 | stream.skipToEnd(); 103 | return ret("comment", "comment"); 104 | } 105 | else if (state.lastType == "operator" || state.lastType == "keyword c" || 106 | /^[\[{}\(,;:]$/.test(state.lastType)) { 107 | nextUntilUnescaped(stream, "/"); 108 | stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla 109 | return ret("regexp", "string-2"); 110 | } 111 | else { 112 | stream.eatWhile(isOperatorChar); 113 | return ret("operator", null, stream.current()); 114 | } 115 | } 116 | else if (ch == "#") { 117 | stream.skipToEnd(); 118 | return ret("error", "error"); 119 | } 120 | else if (isOperatorChar.test(ch)) { 121 | stream.eatWhile(isOperatorChar); 122 | return ret("operator", null, stream.current()); 123 | } 124 | else { 125 | stream.eatWhile(/[\w\$_]/); 126 | var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word]; 127 | return (known && state.lastType != ".") ? ret(known.type, known.style, word) : 128 | ret("variable", "variable", word); 129 | } 130 | } 131 | 132 | function jsTokenString(quote) { 133 | return function(stream, state) { 134 | if (!nextUntilUnescaped(stream, quote)) 135 | state.tokenize = jsTokenBase; 136 | return ret("string", "string"); 137 | }; 138 | } 139 | 140 | function jsTokenComment(stream, state) { 141 | var maybeEnd = false, ch; 142 | while (ch = stream.next()) { 143 | if (ch == "/" && maybeEnd) { 144 | state.tokenize = jsTokenBase; 145 | break; 146 | } 147 | maybeEnd = (ch == "*"); 148 | } 149 | return ret("comment", "comment"); 150 | } 151 | 152 | // Parser 153 | 154 | var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true}; 155 | 156 | function JSLexical(indented, column, type, align, prev, info) { 157 | this.indented = indented; 158 | this.column = column; 159 | this.type = type; 160 | this.prev = prev; 161 | this.info = info; 162 | if (align != null) this.align = align; 163 | } 164 | 165 | function inScope(state, varname) { 166 | for (var v = state.localVars; v; v = v.next) 167 | if (v.name == varname) return true; 168 | } 169 | 170 | function parseJS(state, style, type, content, stream) { 171 | var cc = state.cc; 172 | // Communicate our context to the combinators. 173 | // (Less wasteful than consing up a hundred closures on every call.) 174 | cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; 175 | 176 | if (!state.lexical.hasOwnProperty("align")) 177 | state.lexical.align = true; 178 | 179 | while(true) { 180 | var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement; 181 | if (combinator(type, content)) { 182 | while(cc.length && cc[cc.length - 1].lex) 183 | cc.pop()(); 184 | if (cx.marked) return cx.marked; 185 | if (type == "variable" && inScope(state, content)) return "variable-2"; 186 | return style; 187 | } 188 | } 189 | } 190 | 191 | // Combinator utils 192 | 193 | var cx = {state: null, column: null, marked: null, cc: null}; 194 | function pass() { 195 | for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]); 196 | } 197 | function cont() { 198 | pass.apply(null, arguments); 199 | return true; 200 | } 201 | function register(varname) { 202 | function inList(list) { 203 | for (var v = list; v; v = v.next) 204 | if (v.name == varname) return true; 205 | return false; 206 | } 207 | var state = cx.state; 208 | if (state.context) { 209 | cx.marked = "def"; 210 | if (inList(state.localVars)) return; 211 | state.localVars = {name: varname, next: state.localVars}; 212 | } else { 213 | if (inList(state.globalVars)) return; 214 | state.globalVars = {name: varname, next: state.globalVars}; 215 | } 216 | } 217 | 218 | // Combinators 219 | 220 | var defaultVars = {name: "this", next: {name: "arguments"}}; 221 | function pushcontext() { 222 | cx.state.context = {prev: cx.state.context, vars: cx.state.localVars}; 223 | cx.state.localVars = defaultVars; 224 | } 225 | function popcontext() { 226 | cx.state.localVars = cx.state.context.vars; 227 | cx.state.context = cx.state.context.prev; 228 | } 229 | function pushlex(type, info) { 230 | var result = function() { 231 | var state = cx.state, indent = state.indented; 232 | if (state.lexical.type == "stat") indent = state.lexical.indented; 233 | state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info); 234 | }; 235 | result.lex = true; 236 | return result; 237 | } 238 | function poplex() { 239 | var state = cx.state; 240 | if (state.lexical.prev) { 241 | if (state.lexical.type == ")") 242 | state.indented = state.lexical.indented; 243 | state.lexical = state.lexical.prev; 244 | } 245 | } 246 | poplex.lex = true; 247 | 248 | function expect(wanted) { 249 | return function(type) { 250 | if (type == wanted) return cont(); 251 | else if (wanted == ";") return pass(); 252 | else return cont(arguments.callee); 253 | }; 254 | } 255 | 256 | function statement(type) { 257 | if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex); 258 | if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex); 259 | if (type == "keyword b") return cont(pushlex("form"), statement, poplex); 260 | if (type == "{") return cont(pushlex("}"), block, poplex); 261 | if (type == ";") return cont(); 262 | if (type == "if") return cont(pushlex("form"), expression, statement, poplex, maybeelse); 263 | if (type == "function") return cont(functiondef); 264 | if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"), 265 | poplex, statement, poplex); 266 | if (type == "variable") return cont(pushlex("stat"), maybelabel); 267 | if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), 268 | block, poplex, poplex); 269 | if (type == "case") return cont(expression, expect(":")); 270 | if (type == "default") return cont(expect(":")); 271 | if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), 272 | statement, poplex, popcontext); 273 | return pass(pushlex("stat"), expression, expect(";"), poplex); 274 | } 275 | function expression(type) { 276 | return expressionInner(type, false); 277 | } 278 | function expressionNoComma(type) { 279 | return expressionInner(type, true); 280 | } 281 | function expressionInner(type, noComma) { 282 | var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; 283 | if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); 284 | if (type == "function") return cont(functiondef); 285 | if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression); 286 | if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop); 287 | if (type == "operator") return cont(noComma ? expressionNoComma : expression); 288 | if (type == "[") return cont(pushlex("]"), commasep(expressionNoComma, "]"), poplex, maybeop); 289 | if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeop); 290 | return cont(); 291 | } 292 | function maybeexpression(type) { 293 | if (type.match(/[;\}\)\],]/)) return pass(); 294 | return pass(expression); 295 | } 296 | function maybeexpressionNoComma(type) { 297 | if (type.match(/[;\}\)\],]/)) return pass(); 298 | return pass(expressionNoComma); 299 | } 300 | 301 | function maybeoperatorComma(type, value) { 302 | if (type == ",") return cont(expression); 303 | return maybeoperatorNoComma(type, value, false); 304 | } 305 | function maybeoperatorNoComma(type, value, noComma) { 306 | var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma; 307 | var expr = noComma == false ? expression : expressionNoComma; 308 | if (type == "operator") { 309 | if (/\+\+|--/.test(value)) return cont(me); 310 | if (value == "?") return cont(expression, expect(":"), expr); 311 | return cont(expr); 312 | } 313 | if (type == ";") return; 314 | if (type == "(") return cont(pushlex(")", "call"), commasep(expressionNoComma, ")"), poplex, me); 315 | if (type == ".") return cont(property, me); 316 | if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me); 317 | } 318 | function maybelabel(type) { 319 | if (type == ":") return cont(poplex, statement); 320 | return pass(maybeoperatorComma, expect(";"), poplex); 321 | } 322 | function property(type) { 323 | if (type == "variable") {cx.marked = "property"; return cont();} 324 | } 325 | function objprop(type, value) { 326 | if (type == "variable") { 327 | cx.marked = "property"; 328 | if (value == "get" || value == "set") return cont(getterSetter); 329 | } else if (type == "number" || type == "string") { 330 | cx.marked = type + " property"; 331 | } 332 | if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expressionNoComma); 333 | } 334 | function getterSetter(type) { 335 | if (type == ":") return cont(expression); 336 | if (type != "variable") return cont(expect(":"), expression); 337 | cx.marked = "property"; 338 | return cont(functiondef); 339 | } 340 | function commasep(what, end) { 341 | function proceed(type) { 342 | if (type == ",") { 343 | var lex = cx.state.lexical; 344 | if (lex.info == "call") lex.pos = (lex.pos || 0) + 1; 345 | return cont(what, proceed); 346 | } 347 | if (type == end) return cont(); 348 | return cont(expect(end)); 349 | } 350 | return function(type) { 351 | if (type == end) return cont(); 352 | else return pass(what, proceed); 353 | }; 354 | } 355 | function block(type) { 356 | if (type == "}") return cont(); 357 | return pass(statement, block); 358 | } 359 | function maybetype(type) { 360 | if (type == ":") return cont(typedef); 361 | return pass(); 362 | } 363 | function typedef(type) { 364 | if (type == "variable"){cx.marked = "variable-3"; return cont();} 365 | return pass(); 366 | } 367 | function vardef1(type, value) { 368 | if (type == "variable") { 369 | register(value); 370 | return isTS ? cont(maybetype, vardef2) : cont(vardef2); 371 | } 372 | return pass(); 373 | } 374 | function vardef2(type, value) { 375 | if (value == "=") return cont(expressionNoComma, vardef2); 376 | if (type == ",") return cont(vardef1); 377 | } 378 | function maybeelse(type, value) { 379 | if (type == "keyword b" && value == "else") return cont(pushlex("form"), statement, poplex); 380 | } 381 | function forspec1(type) { 382 | if (type == "var") return cont(vardef1, expect(";"), forspec2); 383 | if (type == ";") return cont(forspec2); 384 | if (type == "variable") return cont(formaybein); 385 | return pass(expression, expect(";"), forspec2); 386 | } 387 | function formaybein(_type, value) { 388 | if (value == "in") return cont(expression); 389 | return cont(maybeoperatorComma, forspec2); 390 | } 391 | function forspec2(type, value) { 392 | if (type == ";") return cont(forspec3); 393 | if (value == "in") return cont(expression); 394 | return pass(expression, expect(";"), forspec3); 395 | } 396 | function forspec3(type) { 397 | if (type != ")") cont(expression); 398 | } 399 | function functiondef(type, value) { 400 | if (type == "variable") {register(value); return cont(functiondef);} 401 | if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext); 402 | } 403 | function funarg(type, value) { 404 | if (type == "variable") {register(value); return isTS ? cont(maybetype) : cont();} 405 | } 406 | 407 | // Interface 408 | 409 | return { 410 | startState: function(basecolumn) { 411 | return { 412 | tokenize: jsTokenBase, 413 | lastType: null, 414 | cc: [], 415 | lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), 416 | localVars: parserConfig.localVars, 417 | globalVars: parserConfig.globalVars, 418 | context: parserConfig.localVars && {vars: parserConfig.localVars}, 419 | indented: 0 420 | }; 421 | }, 422 | 423 | token: function(stream, state) { 424 | if (stream.sol()) { 425 | if (!state.lexical.hasOwnProperty("align")) 426 | state.lexical.align = false; 427 | state.indented = stream.indentation(); 428 | } 429 | if (state.tokenize != jsTokenComment && stream.eatSpace()) return null; 430 | var style = state.tokenize(stream, state); 431 | if (type == "comment") return style; 432 | state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type; 433 | return parseJS(state, style, type, content, stream); 434 | }, 435 | 436 | indent: function(state, textAfter) { 437 | if (state.tokenize == jsTokenComment) return CodeMirror.Pass; 438 | if (state.tokenize != jsTokenBase) return 0; 439 | var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical; 440 | // Kludge to prevent 'maybelse' from blocking lexical scope pops 441 | for (var i = state.cc.length - 1; i >= 0; --i) { 442 | var c = state.cc[i]; 443 | if (c == poplex) lexical = lexical.prev; 444 | else if (c != maybeelse || /^else\b/.test(textAfter)) break; 445 | } 446 | if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev; 447 | if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat") 448 | lexical = lexical.prev; 449 | var type = lexical.type, closing = firstChar == type; 450 | 451 | if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? 4 : 0); 452 | else if (type == "form" && firstChar == "{") return lexical.indented; 453 | else if (type == "form") return lexical.indented + indentUnit; 454 | else if (type == "stat") 455 | return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? statementIndent || indentUnit : 0); 456 | else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false) 457 | return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit); 458 | else if (lexical.align) return lexical.column + (closing ? 0 : 1); 459 | else return lexical.indented + (closing ? 0 : indentUnit); 460 | }, 461 | 462 | electricChars: ":{}", 463 | blockCommentStart: jsonMode ? null : "/*", 464 | blockCommentEnd: jsonMode ? null : "*/", 465 | lineComment: jsonMode ? null : "//", 466 | fold: "brace", 467 | 468 | helperType: jsonMode ? "json" : "javascript", 469 | jsonMode: jsonMode 470 | }; 471 | }); 472 | 473 | CodeMirror.defineMIME("text/javascript", "javascript"); 474 | CodeMirror.defineMIME("text/ecmascript", "javascript"); 475 | CodeMirror.defineMIME("application/javascript", "javascript"); 476 | CodeMirror.defineMIME("application/ecmascript", "javascript"); 477 | CodeMirror.defineMIME("application/json", {name: "javascript", json: true}); 478 | CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true}); 479 | CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true }); 480 | CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true }); 481 | -------------------------------------------------------------------------------- /js/codemirror/xml.js: -------------------------------------------------------------------------------- 1 | CodeMirror.defineMode("xml", function(config, parserConfig) { 2 | var indentUnit = config.indentUnit; 3 | var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1; 4 | var multilineTagIndentPastTag = parserConfig.multilineTagIndentPastTag || true; 5 | 6 | var Kludges = parserConfig.htmlMode ? { 7 | autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true, 8 | 'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true, 9 | 'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true, 10 | 'track': true, 'wbr': true}, 11 | implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true, 12 | 'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true, 13 | 'th': true, 'tr': true}, 14 | contextGrabbers: { 15 | 'dd': {'dd': true, 'dt': true}, 16 | 'dt': {'dd': true, 'dt': true}, 17 | 'li': {'li': true}, 18 | 'option': {'option': true, 'optgroup': true}, 19 | 'optgroup': {'optgroup': true}, 20 | 'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true, 21 | 'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true, 22 | 'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true, 23 | 'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true, 24 | 'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true}, 25 | 'rp': {'rp': true, 'rt': true}, 26 | 'rt': {'rp': true, 'rt': true}, 27 | 'tbody': {'tbody': true, 'tfoot': true}, 28 | 'td': {'td': true, 'th': true}, 29 | 'tfoot': {'tbody': true}, 30 | 'th': {'td': true, 'th': true}, 31 | 'thead': {'tbody': true, 'tfoot': true}, 32 | 'tr': {'tr': true} 33 | }, 34 | doNotIndent: {"pre": true}, 35 | allowUnquoted: true, 36 | allowMissing: true 37 | } : { 38 | autoSelfClosers: {}, 39 | implicitlyClosed: {}, 40 | contextGrabbers: {}, 41 | doNotIndent: {}, 42 | allowUnquoted: false, 43 | allowMissing: false 44 | }; 45 | var alignCDATA = parserConfig.alignCDATA; 46 | 47 | // Return variables for tokenizers 48 | var tagName, type; 49 | 50 | function inText(stream, state) { 51 | function chain(parser) { 52 | state.tokenize = parser; 53 | return parser(stream, state); 54 | } 55 | 56 | var ch = stream.next(); 57 | if (ch == "<") { 58 | if (stream.eat("!")) { 59 | if (stream.eat("[")) { 60 | if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>")); 61 | else return null; 62 | } else if (stream.match("--")) { 63 | return chain(inBlock("comment", "-->")); 64 | } else if (stream.match("DOCTYPE", true, true)) { 65 | stream.eatWhile(/[\w\._\-]/); 66 | return chain(doctype(1)); 67 | } else { 68 | return null; 69 | } 70 | } else if (stream.eat("?")) { 71 | stream.eatWhile(/[\w\._\-]/); 72 | state.tokenize = inBlock("meta", "?>"); 73 | return "meta"; 74 | } else { 75 | var isClose = stream.eat("/"); 76 | tagName = ""; 77 | var c; 78 | while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c; 79 | if (!tagName) return "error"; 80 | type = isClose ? "closeTag" : "openTag"; 81 | state.tokenize = inTag; 82 | return "tag"; 83 | } 84 | } else if (ch == "&") { 85 | var ok; 86 | if (stream.eat("#")) { 87 | if (stream.eat("x")) { 88 | ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";"); 89 | } else { 90 | ok = stream.eatWhile(/[\d]/) && stream.eat(";"); 91 | } 92 | } else { 93 | ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";"); 94 | } 95 | return ok ? "atom" : "error"; 96 | } else { 97 | stream.eatWhile(/[^&<]/); 98 | return null; 99 | } 100 | } 101 | 102 | function inTag(stream, state) { 103 | var ch = stream.next(); 104 | if (ch == ">" || (ch == "/" && stream.eat(">"))) { 105 | state.tokenize = inText; 106 | type = ch == ">" ? "endTag" : "selfcloseTag"; 107 | return "tag"; 108 | } else if (ch == "=") { 109 | type = "equals"; 110 | return null; 111 | } else if (ch == "<") { 112 | return "error"; 113 | } else if (/[\'\"]/.test(ch)) { 114 | state.tokenize = inAttribute(ch); 115 | state.stringStartCol = stream.column(); 116 | return state.tokenize(stream, state); 117 | } else { 118 | stream.eatWhile(/[^\s\u00a0=<>\"\']/); 119 | return "word"; 120 | } 121 | } 122 | 123 | function inAttribute(quote) { 124 | var closure = function(stream, state) { 125 | while (!stream.eol()) { 126 | if (stream.next() == quote) { 127 | state.tokenize = inTag; 128 | break; 129 | } 130 | } 131 | return "string"; 132 | }; 133 | closure.isInAttribute = true; 134 | return closure; 135 | } 136 | 137 | function inBlock(style, terminator) { 138 | return function(stream, state) { 139 | while (!stream.eol()) { 140 | if (stream.match(terminator)) { 141 | state.tokenize = inText; 142 | break; 143 | } 144 | stream.next(); 145 | } 146 | return style; 147 | }; 148 | } 149 | function doctype(depth) { 150 | return function(stream, state) { 151 | var ch; 152 | while ((ch = stream.next()) != null) { 153 | if (ch == "<") { 154 | state.tokenize = doctype(depth + 1); 155 | return state.tokenize(stream, state); 156 | } else if (ch == ">") { 157 | if (depth == 1) { 158 | state.tokenize = inText; 159 | break; 160 | } else { 161 | state.tokenize = doctype(depth - 1); 162 | return state.tokenize(stream, state); 163 | } 164 | } 165 | } 166 | return "meta"; 167 | }; 168 | } 169 | 170 | var curState, curStream, setStyle; 171 | function pass() { 172 | for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]); 173 | } 174 | function cont() { 175 | pass.apply(null, arguments); 176 | return true; 177 | } 178 | 179 | function pushContext(tagName, startOfLine) { 180 | var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent); 181 | curState.context = { 182 | prev: curState.context, 183 | tagName: tagName, 184 | indent: curState.indented, 185 | startOfLine: startOfLine, 186 | noIndent: noIndent 187 | }; 188 | } 189 | function popContext() { 190 | if (curState.context) curState.context = curState.context.prev; 191 | } 192 | 193 | function element(type) { 194 | if (type == "openTag") { 195 | curState.tagName = tagName; 196 | curState.tagStart = curStream.column(); 197 | return cont(attributes, endtag(curState.startOfLine)); 198 | } else if (type == "closeTag") { 199 | var err = false; 200 | if (curState.context) { 201 | if (curState.context.tagName != tagName) { 202 | if (Kludges.implicitlyClosed.hasOwnProperty(curState.context.tagName.toLowerCase())) { 203 | popContext(); 204 | } 205 | err = !curState.context || curState.context.tagName != tagName; 206 | } 207 | } else { 208 | err = true; 209 | } 210 | if (err) setStyle = "error"; 211 | return cont(endclosetag(err)); 212 | } 213 | return cont(); 214 | } 215 | function endtag(startOfLine) { 216 | return function(type) { 217 | var tagName = curState.tagName; 218 | curState.tagName = curState.tagStart = null; 219 | if (type == "selfcloseTag" || 220 | (type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(tagName.toLowerCase()))) { 221 | maybePopContext(tagName.toLowerCase()); 222 | return cont(); 223 | } 224 | if (type == "endTag") { 225 | maybePopContext(tagName.toLowerCase()); 226 | pushContext(tagName, startOfLine); 227 | return cont(); 228 | } 229 | return cont(); 230 | }; 231 | } 232 | function endclosetag(err) { 233 | return function(type) { 234 | if (err) setStyle = "error"; 235 | if (type == "endTag") { popContext(); return cont(); } 236 | setStyle = "error"; 237 | return cont(arguments.callee); 238 | }; 239 | } 240 | function maybePopContext(nextTagName) { 241 | var parentTagName; 242 | while (true) { 243 | if (!curState.context) { 244 | return; 245 | } 246 | parentTagName = curState.context.tagName.toLowerCase(); 247 | if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) || 248 | !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) { 249 | return; 250 | } 251 | popContext(); 252 | } 253 | } 254 | 255 | function attributes(type) { 256 | if (type == "word") {setStyle = "attribute"; return cont(attribute, attributes);} 257 | if (type == "endTag" || type == "selfcloseTag") return pass(); 258 | setStyle = "error"; 259 | return cont(attributes); 260 | } 261 | function attribute(type) { 262 | if (type == "equals") return cont(attvalue, attributes); 263 | if (!Kludges.allowMissing) setStyle = "error"; 264 | else if (type == "word") {setStyle = "attribute"; return cont(attribute, attributes);} 265 | return (type == "endTag" || type == "selfcloseTag") ? pass() : cont(); 266 | } 267 | function attvalue(type) { 268 | if (type == "string") return cont(attvaluemaybe); 269 | if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return cont();} 270 | setStyle = "error"; 271 | return (type == "endTag" || type == "selfCloseTag") ? pass() : cont(); 272 | } 273 | function attvaluemaybe(type) { 274 | if (type == "string") return cont(attvaluemaybe); 275 | else return pass(); 276 | } 277 | 278 | return { 279 | startState: function() { 280 | return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, tagStart: null, context: null}; 281 | }, 282 | 283 | token: function(stream, state) { 284 | if (!state.tagName && stream.sol()) { 285 | state.startOfLine = true; 286 | state.indented = stream.indentation(); 287 | } 288 | if (stream.eatSpace()) return null; 289 | 290 | setStyle = type = tagName = null; 291 | var style = state.tokenize(stream, state); 292 | state.type = type; 293 | if ((style || type) && style != "comment") { 294 | curState = state; curStream = stream; 295 | while (true) { 296 | var comb = state.cc.pop() || element; 297 | if (comb(type || style)) break; 298 | } 299 | } 300 | state.startOfLine = false; 301 | return setStyle || style; 302 | }, 303 | 304 | indent: function(state, textAfter, fullLine) { 305 | var context = state.context; 306 | // Indent multi-line strings (e.g. css). 307 | if (state.tokenize.isInAttribute) { 308 | return state.stringStartCol + 1; 309 | } 310 | if ((state.tokenize != inTag && state.tokenize != inText) || 311 | context && context.noIndent) 312 | return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0; 313 | // Indent the starts of attribute names. 314 | if (state.tagName) { 315 | if (multilineTagIndentPastTag) 316 | return state.tagStart + state.tagName.length + 2; 317 | else 318 | return state.tagStart + indentUnit * multilineTagIndentFactor; 319 | } 320 | if (alignCDATA && /", 332 | 333 | configuration: parserConfig.htmlMode ? "html" : "xml", 334 | helperType: parserConfig.htmlMode ? "html" : "xml" 335 | }; 336 | }); 337 | 338 | CodeMirror.defineMIME("text/xml", "xml"); 339 | CodeMirror.defineMIME("application/xml", "xml"); 340 | if (!CodeMirror.mimeModes.hasOwnProperty("text/html")) 341 | CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true}); 342 | -------------------------------------------------------------------------------- /js/foundation/foundation.forms.js: -------------------------------------------------------------------------------- 1 | (function ($, window, document, undefined) { 2 | 'use strict'; 3 | 4 | Foundation.libs.forms = { 5 | name : 'forms', 6 | 7 | version: '4.3.1', 8 | 9 | cache: {}, 10 | 11 | settings: { 12 | disable_class: 'no-custom', 13 | last_combo : null 14 | }, 15 | 16 | init: function (scope, method, options) { 17 | 18 | if (typeof method === 'object') { 19 | $.extend(true, this.settings, method); 20 | } 21 | 22 | if (typeof method !== 'string') { 23 | if (!this.settings.init) { 24 | this.events(); 25 | } 26 | 27 | this.assemble(); 28 | 29 | return this.settings.init; 30 | } else { 31 | return this[method].call(this, options); 32 | } 33 | }, 34 | 35 | assemble: function () { 36 | $('form.custom input[type="radio"]', $(this.scope)) 37 | .not('[data-customforms="disabled"]') 38 | .not('.' + this.settings.disable_class) 39 | .each(this.append_custom_markup); 40 | $('form.custom input[type="checkbox"]', $(this.scope)) 41 | .not('[data-customforms="disabled"]') 42 | .not('.' + this.settings.disable_class) 43 | .each(this.append_custom_markup); 44 | $('form.custom select', $(this.scope)) 45 | .not('[data-customforms="disabled"]') 46 | .not('.' + this.settings.disable_class) 47 | .not('[multiple=multiple]') 48 | .each(this.append_custom_select); 49 | }, 50 | 51 | events: function () { 52 | var self = this; 53 | 54 | $(this.scope) 55 | .on('click.fndtn.forms', 'form.custom span.custom.checkbox', function (e) { 56 | e.preventDefault(); 57 | e.stopPropagation(); 58 | self.toggle_checkbox($(this)); 59 | }) 60 | .on('click.fndtn.forms', 'form.custom span.custom.radio', function (e) { 61 | e.preventDefault(); 62 | e.stopPropagation(); 63 | self.toggle_radio($(this)); 64 | }) 65 | .on('change.fndtn.forms', 'form.custom select', function (e, force_refresh) { 66 | if ($(this).is('[data-customforms="disabled"]')) return; 67 | self.refresh_custom_select($(this), force_refresh); 68 | }) 69 | .on('click.fndtn.forms', 'form.custom label', function (e) { 70 | if ($(e.target).is('label')) { 71 | var $associatedElement = $('#' + self.escape($(this).attr('for'))).not('[data-customforms="disabled"]'), 72 | $customCheckbox, 73 | $customRadio; 74 | 75 | if ($associatedElement.length !== 0) { 76 | if ($associatedElement.attr('type') === 'checkbox') { 77 | e.preventDefault(); 78 | $customCheckbox = $(this).find('span.custom.checkbox'); 79 | //the checkbox might be outside after the label or inside of another element 80 | if ($customCheckbox.length === 0) { 81 | $customCheckbox = $associatedElement.add(this).siblings('span.custom.checkbox').first(); 82 | } 83 | self.toggle_checkbox($customCheckbox); 84 | } else if ($associatedElement.attr('type') === 'radio') { 85 | e.preventDefault(); 86 | $customRadio = $(this).find('span.custom.radio'); 87 | //the radio might be outside after the label or inside of another element 88 | if ($customRadio.length === 0) { 89 | $customRadio = $associatedElement.add(this).siblings('span.custom.radio').first(); 90 | } 91 | self.toggle_radio($customRadio); 92 | } 93 | } 94 | } 95 | }) 96 | .on('mousedown.fndtn.forms', 'form.custom div.custom.dropdown', function () { 97 | return false; 98 | }) 99 | .on('click.fndtn.forms', 'form.custom div.custom.dropdown a.current, form.custom div.custom.dropdown a.selector', function (e) { 100 | var $this = $(this), 101 | $dropdown = $this.closest('div.custom.dropdown'), 102 | $select = getFirstPrevSibling($dropdown, 'select'); 103 | 104 | // make sure other dropdowns close 105 | if (!$dropdown.hasClass('open')) $(self.scope).trigger('click'); 106 | 107 | e.preventDefault(); 108 | if (false === $select.is(':disabled')) { 109 | $dropdown.toggleClass('open'); 110 | 111 | if ($dropdown.hasClass('open')) { 112 | $(self.scope).on('click.fndtn.forms.customdropdown', function () { 113 | $dropdown.removeClass('open'); 114 | $(self.scope).off('.fndtn.forms.customdropdown'); 115 | }); 116 | } else { 117 | $(self.scope).on('.fndtn.forms.customdropdown'); 118 | } 119 | return false; 120 | } 121 | }) 122 | .on('click.fndtn.forms touchend.fndtn.forms', 'form.custom div.custom.dropdown li', function (e) { 123 | var $this = $(this), 124 | $customDropdown = $this.closest('div.custom.dropdown'), 125 | $select = getFirstPrevSibling($customDropdown, 'select'), 126 | selectedIndex = 0; 127 | 128 | e.preventDefault(); 129 | e.stopPropagation(); 130 | 131 | if (!$(this).hasClass('disabled')) { 132 | $('div.dropdown').not($customDropdown).removeClass('open'); 133 | 134 | var $oldThis = $this.closest('ul') 135 | .find('li.selected'); 136 | $oldThis.removeClass('selected'); 137 | 138 | $this.addClass('selected'); 139 | 140 | $customDropdown.removeClass('open') 141 | .find('a.current') 142 | .text($this.text()); 143 | 144 | if ($this.data('lang')) { 145 | $customDropdown.find('a.current').get(0).dataset.lang = $this.data('lang'); 146 | } else { 147 | alert("no tiene lang"); 148 | } 149 | 150 | $this.closest('ul').find('li').each(function (index) { 151 | if ($this[0] === this) { 152 | selectedIndex = index; 153 | } 154 | }); 155 | $select[0].selectedIndex = selectedIndex; 156 | 157 | //store the old value in data 158 | $select.data('prevalue', $oldThis.html()); 159 | 160 | // Kick off full DOM change event 161 | if (typeof (document.createEvent) != 'undefined') { 162 | var event = document.createEvent('HTMLEvents'); 163 | event.initEvent('change', true, true); 164 | $select[0].dispatchEvent(event); 165 | } else { 166 | $select[0].fireEvent('onchange'); // for IE 167 | } 168 | } 169 | }); 170 | 171 | $(window).on('keydown', function (e) { 172 | var focus = document.activeElement, 173 | self = Foundation.libs.forms, 174 | dropdown = $('.custom.dropdown.open'); 175 | 176 | if (dropdown.length > 0) { 177 | e.preventDefault(); 178 | 179 | if (e.which === 13) { 180 | dropdown.find('li.selected').trigger('click'); 181 | } 182 | 183 | if (e.which === 27) { 184 | dropdown.removeClass('open'); 185 | } 186 | 187 | if (e.which >= 65 && e.which <= 90) { 188 | var next = self.go_to(dropdown, e.which), 189 | current = dropdown.find('li.selected'); 190 | 191 | if (next) { 192 | current.removeClass('selected'); 193 | self.scrollTo(next.addClass('selected'), 300); 194 | } 195 | } 196 | 197 | if (e.which === 38) { 198 | var current = dropdown.find('li.selected'), 199 | prev = current.prev(':not(.disabled)'); 200 | 201 | if (prev.length > 0) { 202 | prev.parent()[0].scrollTop = prev.parent().scrollTop() - self.outerHeight(prev); 203 | current.removeClass('selected'); 204 | prev.addClass('selected'); 205 | } 206 | } else if (e.which === 40) { 207 | var current = dropdown.find('li.selected'), 208 | next = current.next(':not(.disabled)'); 209 | 210 | if (next.length > 0) { 211 | next.parent()[0].scrollTop = next.parent().scrollTop() + self.outerHeight(next); 212 | current.removeClass('selected'); 213 | next.addClass('selected'); 214 | } 215 | } 216 | } 217 | }); 218 | 219 | this.settings.init = true; 220 | }, 221 | 222 | go_to: function (dropdown, character) { 223 | var lis = dropdown.find('li'), 224 | count = lis.length; 225 | 226 | if (count > 0) { 227 | for (var i = 0; i < count; i++) { 228 | var first_letter = lis.eq(i).text().charAt(0).toLowerCase(); 229 | if (first_letter === String.fromCharCode(character).toLowerCase()) return lis.eq(i); 230 | } 231 | } 232 | }, 233 | 234 | scrollTo: function (el, duration) { 235 | if (duration < 0) return; 236 | var parent = el.parent(); 237 | var li_height = this.outerHeight(el); 238 | var difference = (li_height * (el.index())) - parent.scrollTop(); 239 | var perTick = difference / duration * 10; 240 | 241 | this.scrollToTimerCache = setTimeout(function () { 242 | if (!isNaN(parseInt(perTick, 10))) { 243 | parent[0].scrollTop = parent.scrollTop() + perTick; 244 | this.scrollTo(el, duration - 10); 245 | } 246 | }.bind(this), 10); 247 | }, 248 | 249 | append_custom_markup: function (idx, sel) { 250 | var $this = $(sel), 251 | type = $this.attr('type'), 252 | $span = $this.next('span.custom.' + type); 253 | 254 | if (!$this.parent().hasClass('switch')) { 255 | $this.addClass('hidden-field'); 256 | } 257 | 258 | if ($span.length === 0) { 259 | $span = $('').insertAfter($this); 260 | } 261 | 262 | $span.toggleClass('checked', $this.is(':checked')); 263 | $span.toggleClass('disabled', $this.is(':disabled')); 264 | }, 265 | 266 | append_custom_select: function (idx, sel) { 267 | var self = Foundation.libs.forms, 268 | $this = $(sel), 269 | $customSelect = $this.next('div.custom.dropdown'), 270 | $customList = $customSelect.find('ul'), 271 | $selectCurrent = $customSelect.find(".current"), 272 | $selector = $customSelect.find(".selector"), 273 | $options = $this.find('option'), 274 | $selectedOption = $options.filter(':selected'), 275 | copyClasses = $this.attr('class') ? $this.attr('class').split(' ') : [], 276 | maxWidth = 0, 277 | liHtml = '', 278 | $listItems, 279 | $currentSelect = false; 280 | 281 | if ($customSelect.length === 0) { 282 | var customSelectSize = $this.hasClass('small') ? 'small' : $this.hasClass('medium') ? 'medium' : $this.hasClass('large') ? 'large' : $this.hasClass('expand') ? 'expand' : ''; 283 | 284 | $customSelect = $('
'); 288 | 289 | $selector = $customSelect.find(".selector"); 290 | $customList = $customSelect.find("ul"); 291 | 292 | liHtml = $options.map(function () { 293 | var copyClasses = $(this).attr('class') ? $(this).attr('class') : ''; 294 | if ($(this).data("lang")) { 295 | return "
  • " + $(this).html() + "
  • "; 296 | } else { 297 | return "
  • " + $(this).html() + "
  • "; 298 | } 299 | }).get().join(''); 300 | 301 | $customList.append(liHtml); 302 | 303 | if ($selectedOption.data("lang")) { 304 | $currentSelect = $customSelect 305 | .prepend('' + $selectedOption.html() + '') 306 | .find(".current"); 307 | } else { 308 | $currentSelect = $customSelect 309 | .prepend('' + $selectedOption.html() + '') 310 | .find(".current"); 311 | } 312 | 313 | $this.after($customSelect) 314 | .addClass('hidden-field'); 315 | } else { 316 | liHtml = $options.map(function () { 317 | return "
  • " + $(this).html() + "
  • "; 318 | }) 319 | .get().join(''); 320 | 321 | $customList.html('') 322 | .append(liHtml); 323 | 324 | } // endif $customSelect.length === 0 325 | 326 | self.assign_id($this, $customSelect); 327 | $customSelect.toggleClass('disabled', $this.is(':disabled')); 328 | $listItems = $customList.find('li'); 329 | 330 | // cache list length 331 | self.cache[$customSelect.data('id')] = $listItems.length; 332 | 333 | $options.each(function (index) { 334 | if (this.selected) { 335 | $listItems.eq(index).addClass('selected'); 336 | 337 | if ($currentSelect) { 338 | $currentSelect.html($(this).html()); 339 | } 340 | } 341 | if ($(this).is(':disabled')) { 342 | $listItems.eq(index).addClass('disabled'); 343 | } 344 | }); 345 | 346 | // 347 | // If we're not specifying a predetermined form size. 348 | // 349 | if (!$customSelect.is('.small, .medium, .large, .expand')) { 350 | 351 | // ------------------------------------------------------------------------------------ 352 | // This is a work-around for when elements are contained within hidden parents. 353 | // For example, when custom-form elements are inside of a hidden reveal modal. 354 | // 355 | // We need to display the current custom list element as well as hidden parent elements 356 | // in order to properly calculate the list item element's width property. 357 | // ------------------------------------------------------------------------------------- 358 | 359 | $customSelect.addClass('open'); 360 | // 361 | // Quickly, display all parent elements. 362 | // This should help us calcualate the width of the list item's within the drop down. 363 | // 364 | var self = Foundation.libs.forms; 365 | self.hidden_fix.adjust($customList); 366 | 367 | maxWidth = (self.outerWidth($listItems) > maxWidth) ? self.outerWidth($listItems) : maxWidth; 368 | 369 | Foundation.libs.forms.hidden_fix.reset(); 370 | 371 | $customSelect.removeClass('open'); 372 | 373 | } // endif 374 | 375 | }, 376 | 377 | assign_id: function ($select, $customSelect) { 378 | var id = [+new Date(), Foundation.random_str(5)].join('-'); 379 | $select.attr('data-id', id); 380 | $customSelect.attr('data-id', id); 381 | }, 382 | 383 | refresh_custom_select: function ($select, force_refresh) { 384 | var self = this; 385 | var maxWidth = 0, 386 | $customSelect = $select.next(), 387 | $options = $select.find('option'), 388 | $listItems = $customSelect.find('li'); 389 | 390 | if ($listItems.length !== this.cache[$customSelect.data('id')] || force_refresh) { 391 | $customSelect.find('ul').html(''); 392 | 393 | $options.each(function () { 394 | var $li = $('
  • ' + $(this).html() + '
  • '); 395 | $customSelect.find('ul').append($li); 396 | }); 397 | 398 | // re-populate 399 | $options.each(function (index) { 400 | if (this.selected) { 401 | $customSelect.find('li').eq(index).addClass('selected'); 402 | $customSelect.find('.current').html($(this).html()); 403 | } 404 | if ($(this).is(':disabled')) { 405 | $customSelect.find('li').eq(index).addClass('disabled'); 406 | } 407 | }); 408 | 409 | // fix width 410 | $customSelect.removeAttr('style') 411 | .find('ul').removeAttr('style'); 412 | $customSelect.find('li').each(function () { 413 | $customSelect.addClass('open'); 414 | if (self.outerWidth($(this)) > maxWidth) { 415 | maxWidth = self.outerWidth($(this)); 416 | } 417 | $customSelect.removeClass('open'); 418 | }); 419 | 420 | $listItems = $customSelect.find('li'); 421 | // cache list length 422 | this.cache[$customSelect.data('id')] = $listItems.length; 423 | } 424 | }, 425 | 426 | toggle_checkbox: function ($element) { 427 | var $input = $element.prev(), 428 | input = $input[0]; 429 | 430 | if (false === $input.is(':disabled')) { 431 | input.checked = ((input.checked) ? false : true); 432 | $element.toggleClass('checked'); 433 | 434 | $input.trigger('change'); 435 | } 436 | }, 437 | 438 | toggle_radio: function ($element) { 439 | var $input = $element.prev(), 440 | $form = $input.closest('form.custom'), 441 | input = $input[0]; 442 | 443 | if (false === $input.is(':disabled')) { 444 | $form.find('input[type="radio"][name="' + this.escape($input.attr('name')) + '"]') 445 | .next().not($element).removeClass('checked'); 446 | 447 | if (!$element.hasClass('checked')) { 448 | $element.toggleClass('checked'); 449 | } 450 | 451 | input.checked = $element.hasClass('checked'); 452 | 453 | $input.trigger('change'); 454 | } 455 | }, 456 | 457 | escape: function (text) { 458 | if (!text) return ''; 459 | return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); 460 | }, 461 | 462 | hidden_fix: { 463 | /** 464 | * Sets all hidden parent elements and self to visibile. 465 | * 466 | * @method adjust 467 | * @param {jQuery Object} $child 468 | */ 469 | 470 | // We'll use this to temporarily store style properties. 471 | tmp: [], 472 | 473 | // We'll use this to set hidden parent elements. 474 | hidden: null, 475 | 476 | adjust: function ($child) { 477 | // Internal reference. 478 | var _self = this; 479 | 480 | // Set all hidden parent elements, including this element. 481 | _self.hidden = $child.parents(); 482 | _self.hidden = _self.hidden.add($child).filter(":hidden"); 483 | 484 | // Loop through all hidden elements. 485 | _self.hidden.each(function () { 486 | 487 | // Cache the element. 488 | var $elem = $(this); 489 | 490 | // Store the style attribute. 491 | // Undefined if element doesn't have a style attribute. 492 | _self.tmp.push($elem.attr('style')); 493 | 494 | // Set the element's display property to block, 495 | // but ensure it's visibility is hidden. 496 | $elem.css({ 497 | 'visibility': 'hidden', 498 | 'display': 'block' 499 | }); 500 | }); 501 | 502 | }, // end adjust 503 | 504 | /** 505 | * Resets the elements previous state. 506 | * 507 | * @method reset 508 | */ 509 | reset: function () { 510 | // Internal reference. 511 | var _self = this; 512 | // Loop through our hidden element collection. 513 | _self.hidden.each(function (i) { 514 | // Cache this element. 515 | var $elem = $(this), 516 | _tmp = _self.tmp[i]; // Get the stored 'style' value for this element. 517 | 518 | // If the stored value is undefined. 519 | if (_tmp === undefined) 520 | // Remove the style attribute. 521 | $elem.removeAttr('style'); 522 | else 523 | // Otherwise, reset the element style attribute. 524 | $elem.attr('style', _tmp); 525 | }); 526 | // Reset the tmp array. 527 | _self.tmp = []; 528 | // Reset the hidden elements variable. 529 | _self.hidden = null; 530 | 531 | } // end reset 532 | }, 533 | 534 | off: function () { 535 | $(this.scope).off('.fndtn.forms'); 536 | }, 537 | 538 | reflow : function () {} 539 | }; 540 | 541 | var getFirstPrevSibling = function($el, selector) { 542 | var $el = $el.prev(); 543 | while ($el.length) { 544 | if ($el.is(selector)) return $el; 545 | $el = $el.prev(); 546 | } 547 | return $(); 548 | }; 549 | }(Foundation.zj, this, this.document)); 550 | -------------------------------------------------------------------------------- /js/foundation/foundation.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Foundation Responsive Library 3 | * http://foundation.zurb.com 4 | * Copyright 2013, ZURB 5 | * Free to use under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | */ 8 | 9 | /*jslint unparam: true, browser: true, indent: 2 */ 10 | 11 | // Accommodate running jQuery or Zepto in noConflict() mode by 12 | // using an anonymous function to redefine the $ shorthand name. 13 | // See http://docs.jquery.com/Using_jQuery_with_Other_Libraries 14 | // and http://zeptojs.com/ 15 | var libFuncName = null; 16 | 17 | if (typeof jQuery === "undefined" && 18 | typeof Zepto === "undefined" && 19 | typeof $ === "function") { 20 | libFuncName = $; 21 | } else if (typeof jQuery === "function") { 22 | libFuncName = jQuery; 23 | } else if (typeof Zepto === "function") { 24 | libFuncName = Zepto; 25 | } else { 26 | throw new TypeError(); 27 | } 28 | 29 | (function ($, window, document, undefined) { 30 | 'use strict'; 31 | 32 | /* 33 | matchMedia() polyfill - Test a CSS media 34 | type/query in JS. Authors & copyright (c) 2012: 35 | Scott Jehl, Paul Irish, Nicholas Zakas. 36 | Dual MIT/BSD license 37 | 38 | https://github.com/paulirish/matchMedia.js 39 | */ 40 | 41 | window.matchMedia = window.matchMedia || (function( doc, undefined ) { 42 | 43 | "use strict"; 44 | 45 | var bool, 46 | docElem = doc.documentElement, 47 | refNode = docElem.firstElementChild || docElem.firstChild, 48 | // fakeBody required for 49 | fakeBody = doc.createElement( "body" ), 50 | div = doc.createElement( "div" ); 51 | 52 | div.id = "mq-test-1"; 53 | div.style.cssText = "position:absolute;top:-100em"; 54 | fakeBody.style.background = "none"; 55 | fakeBody.appendChild(div); 56 | 57 | return function(q){ 58 | 59 | div.innerHTML = "­"; 60 | 61 | docElem.insertBefore( fakeBody, refNode ); 62 | bool = div.offsetWidth === 42; 63 | docElem.removeChild( fakeBody ); 64 | 65 | return { 66 | matches: bool, 67 | media: q 68 | }; 69 | 70 | }; 71 | 72 | }( document )); 73 | 74 | // add dusty browser stuff 75 | if (!Array.prototype.filter) { 76 | Array.prototype.filter = function(fun /*, thisp */) { 77 | "use strict"; 78 | 79 | if (this == null) { 80 | throw new TypeError(); 81 | } 82 | 83 | var t = Object(this), 84 | len = t.length >>> 0; 85 | if (typeof fun !== "function") { 86 | return; 87 | } 88 | 89 | var res = [], 90 | thisp = arguments[1]; 91 | for (var i = 0; i < len; i++) { 92 | if (i in t) { 93 | var val = t[i]; // in case fun mutates this 94 | if (fun && fun.call(thisp, val, i, t)) { 95 | res.push(val); 96 | } 97 | } 98 | } 99 | 100 | return res; 101 | } 102 | } 103 | 104 | if (!Function.prototype.bind) { 105 | Function.prototype.bind = function (oThis) { 106 | if (typeof this !== "function") { 107 | // closest thing possible to the ECMAScript 5 internal IsCallable function 108 | throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); 109 | } 110 | 111 | var aArgs = Array.prototype.slice.call(arguments, 1), 112 | fToBind = this, 113 | fNOP = function () {}, 114 | fBound = function () { 115 | return fToBind.apply(this instanceof fNOP && oThis 116 | ? this 117 | : oThis, 118 | aArgs.concat(Array.prototype.slice.call(arguments))); 119 | }; 120 | 121 | fNOP.prototype = this.prototype; 122 | fBound.prototype = new fNOP(); 123 | 124 | return fBound; 125 | }; 126 | } 127 | 128 | if (!Array.prototype.indexOf) { 129 | Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) { 130 | "use strict"; 131 | if (this == null) { 132 | throw new TypeError(); 133 | } 134 | var t = Object(this); 135 | var len = t.length >>> 0; 136 | if (len === 0) { 137 | return -1; 138 | } 139 | var n = 0; 140 | if (arguments.length > 1) { 141 | n = Number(arguments[1]); 142 | if (n != n) { // shortcut for verifying if it's NaN 143 | n = 0; 144 | } else if (n != 0 && n != Infinity && n != -Infinity) { 145 | n = (n > 0 || -1) * Math.floor(Math.abs(n)); 146 | } 147 | } 148 | if (n >= len) { 149 | return -1; 150 | } 151 | var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); 152 | for (; k < len; k++) { 153 | if (k in t && t[k] === searchElement) { 154 | return k; 155 | } 156 | } 157 | return -1; 158 | } 159 | } 160 | 161 | // fake stop() for zepto. 162 | $.fn.stop = $.fn.stop || function() { 163 | return this; 164 | }; 165 | 166 | window.Foundation = { 167 | name : 'Foundation', 168 | 169 | version : '4.3.1', 170 | 171 | cache : {}, 172 | 173 | init : function (scope, libraries, method, options, response, /* internal */ nc) { 174 | var library_arr, 175 | args = [scope, method, options, response], 176 | responses = [], 177 | nc = nc || false; 178 | 179 | // disable library error catching, 180 | // used for development only 181 | if (nc) this.nc = nc; 182 | 183 | // check RTL 184 | this.rtl = /rtl/i.test($('html').attr('dir')); 185 | 186 | // set foundation global scope 187 | this.scope = scope || this.scope; 188 | 189 | if (libraries && typeof libraries === 'string' && !/reflow/i.test(libraries)) { 190 | if (/off/i.test(libraries)) return this.off(); 191 | 192 | library_arr = libraries.split(' '); 193 | 194 | if (library_arr.length > 0) { 195 | for (var i = library_arr.length - 1; i >= 0; i--) { 196 | responses.push(this.init_lib(library_arr[i], args)); 197 | } 198 | } 199 | } else { 200 | if (/reflow/i.test(libraries)) args[1] = 'reflow'; 201 | 202 | for (var lib in this.libs) { 203 | responses.push(this.init_lib(lib, args)); 204 | } 205 | } 206 | 207 | // if first argument is callback, add to args 208 | if (typeof libraries === 'function') { 209 | args.unshift(libraries); 210 | } 211 | 212 | return this.response_obj(responses, args); 213 | }, 214 | 215 | response_obj : function (response_arr, args) { 216 | for (var i = 0, len = args.length; i < len; i++) { 217 | if (typeof args[i] === 'function') { 218 | return args[i]({ 219 | errors: response_arr.filter(function (s) { 220 | if (typeof s === 'string') return s; 221 | }) 222 | }); 223 | } 224 | } 225 | 226 | return response_arr; 227 | }, 228 | 229 | init_lib : function (lib, args) { 230 | return this.trap(function () { 231 | if (this.libs.hasOwnProperty(lib)) { 232 | this.patch(this.libs[lib]); 233 | return this.libs[lib].init.apply(this.libs[lib], args); 234 | } else { 235 | return function () {}; 236 | } 237 | }.bind(this), lib); 238 | }, 239 | 240 | trap : function (fun, lib) { 241 | if (!this.nc) { 242 | try { 243 | return fun(); 244 | } catch (e) { 245 | return this.error({name: lib, message: 'could not be initialized', more: e.name + ' ' + e.message}); 246 | } 247 | } 248 | 249 | return fun(); 250 | }, 251 | 252 | patch : function (lib) { 253 | this.fix_outer(lib); 254 | lib.scope = this.scope; 255 | lib.rtl = this.rtl; 256 | }, 257 | 258 | inherit : function (scope, methods) { 259 | var methods_arr = methods.split(' '); 260 | 261 | for (var i = methods_arr.length - 1; i >= 0; i--) { 262 | if (this.lib_methods.hasOwnProperty(methods_arr[i])) { 263 | this.libs[scope.name][methods_arr[i]] = this.lib_methods[methods_arr[i]]; 264 | } 265 | } 266 | }, 267 | 268 | random_str : function (length) { 269 | var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''); 270 | 271 | if (!length) { 272 | length = Math.floor(Math.random() * chars.length); 273 | } 274 | 275 | var str = ''; 276 | for (var i = 0; i < length; i++) { 277 | str += chars[Math.floor(Math.random() * chars.length)]; 278 | } 279 | return str; 280 | }, 281 | 282 | libs : {}, 283 | 284 | // methods that can be inherited in libraries 285 | lib_methods : { 286 | set_data : function (node, data) { 287 | // this.name references the name of the library calling this method 288 | var id = [this.name,+new Date(),Foundation.random_str(5)].join('-'); 289 | 290 | Foundation.cache[id] = data; 291 | node.attr('data-' + this.name + '-id', id); 292 | return data; 293 | }, 294 | 295 | get_data : function (node) { 296 | return Foundation.cache[node.attr('data-' + this.name + '-id')]; 297 | }, 298 | 299 | remove_data : function (node) { 300 | if (node) { 301 | delete Foundation.cache[node.attr('data-' + this.name + '-id')]; 302 | node.attr('data-' + this.name + '-id', ''); 303 | } else { 304 | $('[data-' + this.name + '-id]').each(function () { 305 | delete Foundation.cache[$(this).attr('data-' + this.name + '-id')]; 306 | $(this).attr('data-' + this.name + '-id', ''); 307 | }); 308 | } 309 | }, 310 | 311 | throttle : function(fun, delay) { 312 | var timer = null; 313 | return function () { 314 | var context = this, args = arguments; 315 | clearTimeout(timer); 316 | timer = setTimeout(function () { 317 | fun.apply(context, args); 318 | }, delay); 319 | }; 320 | }, 321 | 322 | // parses data-options attribute on nodes and turns 323 | // them into an object 324 | data_options : function (el) { 325 | var opts = {}, ii, p, 326 | opts_arr = (el.attr('data-options') || ':').split(';'), 327 | opts_len = opts_arr.length; 328 | 329 | function isNumber (o) { 330 | return ! isNaN (o-0) && o !== null && o !== "" && o !== false && o !== true; 331 | } 332 | 333 | function trim(str) { 334 | if (typeof str === 'string') return $.trim(str); 335 | return str; 336 | } 337 | 338 | // parse options 339 | for (ii = opts_len - 1; ii >= 0; ii--) { 340 | p = opts_arr[ii].split(':'); 341 | 342 | if (/true/i.test(p[1])) p[1] = true; 343 | if (/false/i.test(p[1])) p[1] = false; 344 | if (isNumber(p[1])) p[1] = parseInt(p[1], 10); 345 | 346 | if (p.length === 2 && p[0].length > 0) { 347 | opts[trim(p[0])] = trim(p[1]); 348 | } 349 | } 350 | 351 | return opts; 352 | }, 353 | 354 | delay : function (fun, delay) { 355 | return setTimeout(fun, delay); 356 | }, 357 | 358 | // animated scrolling 359 | scrollTo : function (el, to, duration) { 360 | if (duration < 0) return; 361 | var difference = to - $(window).scrollTop(); 362 | var perTick = difference / duration * 10; 363 | 364 | this.scrollToTimerCache = setTimeout(function() { 365 | if (!isNaN(parseInt(perTick, 10))) { 366 | window.scrollTo(0, $(window).scrollTop() + perTick); 367 | this.scrollTo(el, to, duration - 10); 368 | } 369 | }.bind(this), 10); 370 | }, 371 | 372 | // not supported in core Zepto 373 | scrollLeft : function (el) { 374 | if (!el.length) return; 375 | return ('scrollLeft' in el[0]) ? el[0].scrollLeft : el[0].pageXOffset; 376 | }, 377 | 378 | // test for empty object or array 379 | empty : function (obj) { 380 | if (obj.length && obj.length > 0) return false; 381 | if (obj.length && obj.length === 0) return true; 382 | 383 | for (var key in obj) { 384 | if (hasOwnProperty.call(obj, key)) return false; 385 | } 386 | 387 | return true; 388 | } 389 | }, 390 | 391 | fix_outer : function (lib) { 392 | lib.outerHeight = function (el, bool) { 393 | if (typeof Zepto === 'function') { 394 | return el.height(); 395 | } 396 | 397 | if (typeof bool !== 'undefined') { 398 | return el.outerHeight(bool); 399 | } 400 | 401 | return el.outerHeight(); 402 | }; 403 | 404 | lib.outerWidth = function (el, bool) { 405 | if (typeof Zepto === 'function') { 406 | return el.width(); 407 | } 408 | 409 | if (typeof bool !== 'undefined') { 410 | return el.outerWidth(bool); 411 | } 412 | 413 | return el.outerWidth(); 414 | }; 415 | }, 416 | 417 | error : function (error) { 418 | return error.name + ' ' + error.message + '; ' + error.more; 419 | }, 420 | 421 | // remove all foundation events. 422 | off: function () { 423 | $(this.scope).off('.fndtn'); 424 | $(window).off('.fndtn'); 425 | return true; 426 | }, 427 | 428 | zj : $ 429 | }; 430 | 431 | $.fn.foundation = function () { 432 | var args = Array.prototype.slice.call(arguments, 0); 433 | 434 | return this.each(function () { 435 | Foundation.init.apply(Foundation, [this].concat(args)); 436 | return this; 437 | }); 438 | }; 439 | 440 | }(libFuncName, this, this.document)); 441 | -------------------------------------------------------------------------------- /js/foundation/foundation.reveal.js: -------------------------------------------------------------------------------- 1 | /*jslint unparam: true, browser: true, indent: 2 */ 2 | 3 | ;(function ($, window, document, undefined) { 4 | 'use strict'; 5 | 6 | Foundation.libs.reveal = { 7 | name : 'reveal', 8 | 9 | version : '4.2.2', 10 | 11 | locked : false, 12 | 13 | settings : { 14 | animation: 'fadeAndPop', 15 | animationSpeed: 250, 16 | closeOnBackgroundClick: true, 17 | closeOnEsc: true, 18 | dismissModalClass: 'close-reveal-modal', 19 | bgClass: 'reveal-modal-bg', 20 | open: function(){}, 21 | opened: function(){}, 22 | close: function(){}, 23 | closed: function(){}, 24 | bg : $('.reveal-modal-bg'), 25 | css : { 26 | open : { 27 | 'opacity': 0, 28 | 'visibility': 'visible', 29 | 'display' : 'block' 30 | }, 31 | close : { 32 | 'opacity': 1, 33 | 'visibility': 'hidden', 34 | 'display': 'none' 35 | } 36 | } 37 | }, 38 | 39 | init : function (scope, method, options) { 40 | Foundation.inherit(this, 'data_options delay'); 41 | 42 | if (typeof method === 'object') { 43 | $.extend(true, this.settings, method); 44 | } else if (typeof options !== 'undefined') { 45 | $.extend(true, this.settings, options); 46 | } 47 | 48 | if (typeof method !== 'string') { 49 | this.events(); 50 | 51 | return this.settings.init; 52 | } else { 53 | return this[method].call(this, options); 54 | } 55 | }, 56 | 57 | events : function () { 58 | var self = this; 59 | 60 | $(this.scope) 61 | .off('.fndtn.reveal') 62 | .on('click.fndtn.reveal', '[data-reveal-id]', function (e) { 63 | e.preventDefault(); 64 | 65 | if (!self.locked) { 66 | var element = $(this), 67 | ajax = element.data('reveal-ajax'); 68 | 69 | self.locked = true; 70 | 71 | if (typeof ajax === 'undefined') { 72 | self.open.call(self, element); 73 | } else { 74 | var url = ajax === true ? element.attr('href') : ajax; 75 | 76 | self.open.call(self, element, {url: url}); 77 | } 78 | } 79 | }) 80 | .on('click.fndtn.reveal', this.close_targets(), function (e) { 81 | e.preventDefault(); 82 | if (!self.locked) { 83 | var settings = $.extend({}, self.settings, self.data_options($('.reveal-modal.open'))); 84 | if ($(e.target)[0] === $('.' + settings.bgClass)[0] && !settings.closeOnBackgroundClick) { 85 | return; 86 | } 87 | 88 | self.locked = true; 89 | self.close.call(self, $(this).closest('.reveal-modal')); 90 | } 91 | }) 92 | .on('open.fndtn.reveal', '.reveal-modal', this.settings.open) 93 | .on('opened.fndtn.reveal', '.reveal-modal', this.settings.opened) 94 | .on('opened.fndtn.reveal', '.reveal-modal', this.open_video) 95 | .on('close.fndtn.reveal', '.reveal-modal', this.settings.close) 96 | .on('closed.fndtn.reveal', '.reveal-modal', this.settings.closed) 97 | .on('closed.fndtn.reveal', '.reveal-modal', this.close_video); 98 | 99 | $( 'body' ).bind( 'keyup.reveal', function ( event ) { 100 | var open_modal = $('.reveal-modal.open'), 101 | settings = $.extend({}, self.settings, self.data_options(open_modal)); 102 | if ( event.which === 27 && settings.closeOnEsc) { // 27 is the keycode for the Escape key 103 | open_modal.foundation('reveal', 'close'); 104 | } 105 | }); 106 | 107 | return true; 108 | }, 109 | 110 | open : function (target, ajax_settings) { 111 | if (target) { 112 | if (typeof target.selector !== 'undefined') { 113 | var modal = $('#' + target.data('reveal-id')); 114 | } else { 115 | var modal = $(this.scope); 116 | 117 | ajax_settings = target; 118 | } 119 | } else { 120 | var modal = $(this.scope); 121 | } 122 | 123 | if (!modal.hasClass('open')) { 124 | var open_modal = $('.reveal-modal.open'); 125 | 126 | if (typeof modal.data('css-top') === 'undefined') { 127 | modal.data('css-top', parseInt(modal.css('top'), 10)) 128 | .data('offset', this.cache_offset(modal)); 129 | } 130 | 131 | modal.trigger('open'); 132 | 133 | if (open_modal.length < 1) { 134 | this.toggle_bg(modal); 135 | } 136 | 137 | if (typeof ajax_settings === 'undefined' || !ajax_settings.url) { 138 | this.hide(open_modal, this.settings.css.close); 139 | this.show(modal, this.settings.css.open); 140 | } else { 141 | var self = this, 142 | old_success = typeof ajax_settings.success !== 'undefined' ? ajax_settings.success : null; 143 | 144 | $.extend(ajax_settings, { 145 | success: function (data, textStatus, jqXHR) { 146 | if ( $.isFunction(old_success) ) { 147 | old_success(data, textStatus, jqXHR); 148 | } 149 | 150 | modal.html(data); 151 | $(modal).foundation('section', 'reflow'); 152 | 153 | self.hide(open_modal, self.settings.css.close); 154 | self.show(modal, self.settings.css.open); 155 | } 156 | }); 157 | 158 | $.ajax(ajax_settings); 159 | } 160 | } 161 | }, 162 | 163 | close : function (modal) { 164 | 165 | var modal = modal && modal.length ? modal : $(this.scope), 166 | open_modals = $('.reveal-modal.open'); 167 | 168 | if (open_modals.length > 0) { 169 | this.locked = true; 170 | modal.trigger('close'); 171 | this.toggle_bg(modal); 172 | this.hide(open_modals, this.settings.css.close); 173 | } 174 | }, 175 | 176 | close_targets : function () { 177 | var base = '.' + this.settings.dismissModalClass; 178 | 179 | if (this.settings.closeOnBackgroundClick) { 180 | return base + ', .' + this.settings.bgClass; 181 | } 182 | 183 | return base; 184 | }, 185 | 186 | toggle_bg : function (modal) { 187 | if ($('.reveal-modal-bg').length === 0) { 188 | this.settings.bg = $('
    ', {'class': this.settings.bgClass}) 189 | .appendTo('body'); 190 | } 191 | 192 | if (this.settings.bg.filter(':visible').length > 0) { 193 | this.hide(this.settings.bg); 194 | } else { 195 | this.show(this.settings.bg); 196 | } 197 | }, 198 | 199 | show : function (el, css) { 200 | // is modal 201 | if (css) { 202 | if (/pop/i.test(this.settings.animation)) { 203 | css.top = $(window).scrollTop() - el.data('offset') + 'px'; 204 | var end_css = { 205 | top: $(window).scrollTop() + el.data('css-top') + 'px', 206 | opacity: 1 207 | }; 208 | 209 | return this.delay(function () { 210 | return el 211 | .css(css) 212 | .animate(end_css, this.settings.animationSpeed, 'linear', function () { 213 | this.locked = false; 214 | el.trigger('opened'); 215 | }.bind(this)) 216 | .addClass('open'); 217 | }.bind(this), this.settings.animationSpeed / 2); 218 | } 219 | 220 | if (/fade/i.test(this.settings.animation)) { 221 | var end_css = {opacity: 1}; 222 | 223 | return this.delay(function () { 224 | return el 225 | .css(css) 226 | .animate(end_css, this.settings.animationSpeed, 'linear', function () { 227 | this.locked = false; 228 | el.trigger('opened'); 229 | }.bind(this)) 230 | .addClass('open'); 231 | }.bind(this), this.settings.animationSpeed / 2); 232 | } 233 | 234 | return el.css(css).show().css({opacity: 1}).addClass('open').trigger('opened'); 235 | } 236 | 237 | // should we animate the background? 238 | if (/fade/i.test(this.settings.animation)) { 239 | return el.fadeIn(this.settings.animationSpeed / 2); 240 | } 241 | 242 | return el.show(); 243 | }, 244 | 245 | hide : function (el, css) { 246 | // is modal 247 | if (css) { 248 | if (/pop/i.test(this.settings.animation)) { 249 | var end_css = { 250 | top: - $(window).scrollTop() - el.data('offset') + 'px', 251 | opacity: 0 252 | }; 253 | 254 | return this.delay(function () { 255 | return el 256 | .animate(end_css, this.settings.animationSpeed, 'linear', function () { 257 | this.locked = false; 258 | el.css(css).trigger('closed'); 259 | }.bind(this)) 260 | .removeClass('open'); 261 | }.bind(this), this.settings.animationSpeed / 2); 262 | } 263 | 264 | if (/fade/i.test(this.settings.animation)) { 265 | var end_css = {opacity: 0}; 266 | 267 | return this.delay(function () { 268 | return el 269 | .animate(end_css, this.settings.animationSpeed, 'linear', function () { 270 | this.locked = false; 271 | el.css(css).trigger('closed'); 272 | }.bind(this)) 273 | .removeClass('open'); 274 | }.bind(this), this.settings.animationSpeed / 2); 275 | } 276 | 277 | return el.hide().css(css).removeClass('open').trigger('closed'); 278 | } 279 | 280 | // should we animate the background? 281 | if (/fade/i.test(this.settings.animation)) { 282 | return el.fadeOut(this.settings.animationSpeed / 2); 283 | } 284 | 285 | return el.hide(); 286 | }, 287 | 288 | close_video : function (e) { 289 | var video = $(this).find('.flex-video'), 290 | iframe = video.find('iframe'); 291 | 292 | if (iframe.length > 0) { 293 | iframe.attr('data-src', iframe[0].src); 294 | iframe.attr('src', 'about:blank'); 295 | video.hide(); 296 | } 297 | }, 298 | 299 | open_video : function (e) { 300 | var video = $(this).find('.flex-video'), 301 | iframe = video.find('iframe'); 302 | 303 | if (iframe.length > 0) { 304 | var data_src = iframe.attr('data-src'); 305 | if (typeof data_src === 'string') { 306 | iframe[0].src = iframe.attr('data-src'); 307 | } else { 308 | var src = iframe[0].src; 309 | iframe[0].src = undefined; 310 | iframe[0].src = src; 311 | } 312 | video.show(); 313 | } 314 | }, 315 | 316 | cache_offset : function (modal) { 317 | var offset = modal.show().height() + parseInt(modal.css('top'), 10); 318 | 319 | modal.hide(); 320 | 321 | return offset; 322 | }, 323 | 324 | off : function () { 325 | $(this.scope).off('.fndtn.reveal'); 326 | }, 327 | 328 | reflow : function () {} 329 | }; 330 | }(Foundation.zj, this, this.document)); 331 | --------------------------------------------------------------------------------