├── .gitignore ├── Makefile ├── README.md ├── files ├── htdocs │ ├── css │ │ └── style.css │ ├── favicon.ico │ ├── fonts │ │ ├── font.eot │ │ ├── font.svg │ │ ├── font.ttf │ │ └── font.woff │ ├── js │ │ ├── script.js │ │ └── zepto.min.js │ └── logo.png └── templates │ ├── footer.htm │ └── header.htm ├── screenshot ├── computer-1.png ├── computer-2.png ├── computer-3.png ├── mobile-1.png ├── mobile-2.png └── mobile-3.png └── src └── zepto-luci.js /.gitignore: -------------------------------------------------------------------------------- 1 | # OS generated files # 2 | ###################### 3 | .DS_Store 4 | thumbs.db 5 | Icon? 6 | Thumbs.db 7 | .AppleDouble 8 | .idea 9 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # LuCI Material Theme 2 | # Copyright 2015 Lutty Yang 3 | # 4 | # Licensed under the Apache License v2.0 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | 7 | include $(TOPDIR)/rules.mk 8 | 9 | THEME_NAME:=material 10 | THEME_TITLE:=Material 11 | 12 | PKG_NAME:=luci-theme-$(THEME_NAME) 13 | PKG_VERSION:=0.2.19 14 | PKG_RELEASE:=1 15 | 16 | include $(INCLUDE_DIR)/package.mk 17 | 18 | define Package/luci-theme-$(THEME_NAME) 19 | SECTION:=luci 20 | CATEGORY:=LuCI 21 | SUBMENU:=9. Themes 22 | DEPENDS:=+libc 23 | TITLE:=LuCI Theme - $(THEME_TITLE) 24 | URL:=http://wcan.in/ 25 | PKGARCH:=all 26 | endef 27 | 28 | define Build/Configure 29 | endef 30 | 31 | define Build/Compile 32 | endef 33 | 34 | define Package/luci-theme-$(THEME_NAME)/install 35 | $(INSTALL_DIR) $(1)/etc/uci-defaults 36 | echo "uci set luci.themes.$(THEME_TITLE)=/luci-static/$(THEME_NAME); uci commit luci" > $(1)/etc/uci-defaults/30-luci-theme-$(THEME_NAME) 37 | $(INSTALL_DIR) $(1)/www/luci-static/$(THEME_NAME) 38 | $(CP) -a ./files/htdocs/* $(1)/www/luci-static/$(THEME_NAME)/ 2>/dev/null || true 39 | $(INSTALL_DIR) $(1)/usr/lib/lua/luci/view/themes/$(THEME_NAME) 40 | $(CP) -a ./files/templates/* $(1)/usr/lib/lua/luci/view/themes/$(THEME_NAME)/ 2>/dev/null || true 41 | endef 42 | 43 | define Package/luci-theme-$(THEME_NAME)/postinst 44 | #!/bin/sh 45 | [ -n "$${IPKG_INSTROOT}" ] || { 46 | ( . /etc/uci-defaults/30-luci-theme-$(THEME_NAME) ) && rm -f /etc/uci-defaults/30-luci-theme-$(THEME_NAME) 47 | } 48 | endef 49 | 50 | $(eval $(call BuildPackage,luci-theme-$(THEME_NAME))) 51 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Material For LUCI 2 | ================= 3 | 4 | Material is a clean HTML5 theme for LuCI - the web configuration interface commonly found on OpenWrt installation. It is based on luci-theme-bootstrap and MUI 5 | 6 | 7 | Bug tracker 8 | ----------- 9 | 10 | Have a bug? Please create an issue here on GitHub! 11 | 12 | https://github.com/LuttyYang/luci-theme-material/issues 13 | 14 | 15 | Authors 16 | ------- 17 | 18 | **Lutty Yang** 19 | 20 | + https://github.com/LuttyYang 21 | 22 | License 23 | ------- 24 | 25 | LuCI Theme Material: Copyright 2015 Lutty Yang 26 | 27 | LuCI Theme Bootstrap: Copyright 2012 Nut & Bolt 28 | 29 | MUI: https://github.com/muicss/mui 30 | 31 | 32 | Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 33 | 34 | Screenshot 35 | ---------- 36 | 37 | ![Material for LuCI - Computer screenshot 1](https://github.com/LuttyYang/luci-theme-material/blob/master/screenshot/computer-1.png?raw=true) 38 | ![Material for LuCI - Computer screenshot 2](https://github.com/LuttyYang/luci-theme-material/blob/master/screenshot/computer-2.png?raw=true) 39 | ![Material for LuCI - Computer screenshot 3](https://github.com/LuttyYang/luci-theme-material/blob/master/screenshot/computer-3.png?raw=true) 40 | 41 | ![Material for LuCI - Mobile screenshot 1](https://github.com/LuttyYang/luci-theme-material/blob/master/screenshot/mobile-1.png?raw=true) 42 | ![Material for LuCI - Mobile screenshot 2](https://github.com/LuttyYang/luci-theme-material/blob/master/screenshot/mobile-2.png?raw=true) 43 | ![Material for LuCI - Mobile screenshot 3](https://github.com/LuttyYang/luci-theme-material/blob/master/screenshot/mobile-3.png?raw=true) -------------------------------------------------------------------------------- /files/htdocs/css/style.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Material is a clean HTML5 theme for LuCI. It is based on luci-theme-bootstrap and MUI 3 | * 4 | * luci-theme-material 5 | * Copyright 2015 Lutty Yang 6 | * 7 | * Have a bug? Please create an issue here on GitHub! 8 | * https://github.com/LuttyYang/luci-theme-material/issues 9 | * 10 | * luci-theme-bootstrap: 11 | * Copyright 2008 Steven Barth 12 | * Copyright 2008 Jo-Philipp Wich 13 | * Copyright 2012 David Menting 14 | * 15 | * MUI: 16 | * https://github.com/muicss/mui 17 | * 18 | * Licensed to the public under the Apache License 2.0 19 | */ 20 | 21 | @font-face { 22 | font-family: 'icomoon'; 23 | src: url('../fonts/font.eot'); 24 | src: url('../fonts/font.eot') format('embedded-opentype'), 25 | url('../fonts/font.ttf') format('truetype'), 26 | url('../fonts/font.woff') format('woff'), 27 | url('../fonts/font.svg') format('svg'); 28 | font-weight: normal; 29 | font-style: normal; 30 | } 31 | 32 | .cbi-button-up, 33 | .cbi-button-down, 34 | .cbi-value-helpicon, 35 | .showSide, 36 | .main > .loading > span { 37 | font-family: 'icomoon' !important; 38 | speak: none; 39 | font-style: normal !important; 40 | font-weight: normal !important; 41 | font-variant: normal !important; 42 | text-transform: none !important; 43 | line-height: 1; 44 | 45 | -webkit-font-smoothing: antialiased; 46 | -moz-osx-font-smoothing: grayscale; 47 | } 48 | 49 | * { 50 | margin: 0; 51 | padding: 0; 52 | box-sizing: border-box; 53 | } 54 | 55 | .h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 { 56 | font-family: inherit; 57 | font-weight: 400; 58 | line-height: 1.1; 59 | color: inherit; 60 | } 61 | 62 | html { 63 | -webkit-text-size-adjust: 100%; 64 | -ms-text-size-adjust: 100%; 65 | } 66 | 67 | body { 68 | font-size: 0.8rem; 69 | background-color: #EEE; 70 | } 71 | 72 | html, body { 73 | margin: 0px; 74 | padding: 0px; 75 | height: 100%; 76 | font-family: Microsoft Yahei, WenQuanYi Micro Hei, sans-serif, "Helvetica Neue", Helvetica, Hiragino Sans GB; 77 | } 78 | 79 | select { 80 | padding: 0.36rem 0.8rem; 81 | color: #555; 82 | background-color: #fff; 83 | background-image: none; 84 | border: 1px solid #ccc; 85 | } 86 | 87 | select, 88 | input { 89 | background-color: transparent; 90 | color: rgba(0, 0, 0, .87); 91 | border: none; 92 | border-bottom: 2px solid rgba(0, 0, 0, .26); 93 | outline: 0; 94 | padding: 0; 95 | box-shadow: none; 96 | border-radius: 0; 97 | background-image: none; 98 | height: 1.8rem; 99 | font-size: 0.8rem; 100 | } 101 | 102 | select:not([multiple="multiple"]):focus, 103 | input:focus { 104 | border-color: #0099CC; 105 | } 106 | 107 | select[multiple="multiple"] { 108 | height: auto; 109 | } 110 | 111 | code { 112 | color: #0099CC; 113 | } 114 | 115 | abbr { 116 | color: #005470; 117 | text-decoration: underline; 118 | cursor: help; 119 | } 120 | 121 | hr { 122 | margin: 1rem 0; 123 | border-color: #EEE; 124 | opacity: 0.1; 125 | } 126 | 127 | header, .main { 128 | width: 100%; 129 | position: absolute; 130 | } 131 | 132 | header { 133 | height: 4rem; 134 | box-shadow: 0 2px 5px rgba(0, 0, 0, .26); 135 | transition: box-shadow .2s; 136 | float: left; 137 | position: fixed; 138 | z-index: 101; 139 | } 140 | 141 | footer { 142 | text-align: right; 143 | padding: 1rem; 144 | color: #aaa; 145 | font-size: 0.8rem; 146 | text-shadow: 0px 0px 2px #BBB; 147 | } 148 | 149 | footer > a { 150 | color: #aaa; 151 | text-decoration: none; 152 | } 153 | 154 | .main { 155 | top: 4rem; 156 | bottom: 0rem; 157 | position: relative; 158 | height: 100%; 159 | height: calc(100% - 4rem); 160 | } 161 | 162 | .main > .loading { 163 | position: fixed; 164 | width: 100%; 165 | height: 100%; 166 | z-index: 1000; 167 | display: block; 168 | background-color: rgb(240, 240, 240); 169 | top: 0; 170 | } 171 | 172 | .main > .loading > span { 173 | display: block; 174 | text-align: center; 175 | margin-top: 2rem; 176 | color: #888; 177 | font-size: 1.2rem; 178 | } 179 | 180 | .main > .loading > span > .loading-img:before { 181 | content: "\e603"; 182 | } 183 | 184 | .main > .loading > span > .loading-img { 185 | animation: anim-rotate 2s infinite linear; 186 | margin-right: 0.2rem; 187 | display: inline-block; 188 | } 189 | 190 | @keyframes anim-rotate { 191 | 0% { 192 | -webkit-transform: rotate(0); 193 | -ms-transform: rotate(0); 194 | transform: rotate(0); 195 | } 196 | 100% { 197 | -webkit-transform: rotate(360deg); 198 | -ms-transform: rotate(360deg); 199 | transform: rotate(360deg) 200 | } 201 | } 202 | 203 | .main-left { 204 | float: left; 205 | top: 4rem; 206 | width: 15%; 207 | width: calc(0% + 15rem); 208 | height: 100%; 209 | height: calc(100% - 4rem); 210 | background-color: white; 211 | overflow-x: auto; 212 | position: fixed; 213 | } 214 | 215 | .main-right { 216 | width: 85%; 217 | width: calc(100% - 15rem); 218 | float: right; 219 | height: 100%; 220 | background-color: #EEE; 221 | } 222 | 223 | .main-right > #maincontent { 224 | background-color: #EEE; 225 | } 226 | 227 | .pull-right { 228 | float: right; 229 | } 230 | 231 | .pull-left { 232 | float: left; 233 | } 234 | 235 | header { 236 | background: #0099CC; 237 | color: white; 238 | } 239 | 240 | header > .container { 241 | margin-top: 0.5rem; 242 | padding: 0.5rem 1rem 0 1rem; 243 | } 244 | 245 | header > .container > .brand { 246 | font-size: 1.4rem; 247 | color: white; 248 | text-decoration: none; 249 | cursor: default; 250 | vertical-align: text-bottom; 251 | } 252 | 253 | .warning { 254 | background-color: #FF7D60 !important; 255 | color: #FFF; 256 | } 257 | 258 | .errorbox, 259 | .alert-message { 260 | margin: 2rem 0 0 0; 261 | padding: 2rem; 262 | border: 0; 263 | font-weight: normal; 264 | font-style: normal; 265 | line-height: 1; 266 | font-family: inherit; 267 | min-width: inherit; 268 | overflow: auto; 269 | border-radius: 0; 270 | background-color: #FFF; 271 | box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12); 272 | } 273 | 274 | .errorbox { 275 | color: #fff; 276 | background-color: #f0ad4e; 277 | border-color: #eea236; 278 | } 279 | 280 | .error { 281 | color: red; 282 | } 283 | 284 | #maincontent > .container > div:nth-child(1).alert-message.warning > a { 285 | font: inherit; 286 | overflow: visible; 287 | text-transform: none; 288 | display: inline-block; 289 | margin-bottom: 0; 290 | font-weight: 400; 291 | text-align: center; 292 | white-space: nowrap; 293 | vertical-align: middle; 294 | touch-action: manipulation; 295 | cursor: pointer; 296 | -webkit-user-select: none; 297 | -moz-user-select: none; 298 | -ms-user-select: none; 299 | user-select: none; 300 | background-image: none; 301 | min-width: 6rem; 302 | padding: 0.5rem 1rem; 303 | font-size: 0.9rem; 304 | line-height: 1.42857143; 305 | color: #fff; 306 | background-color: #5bc0de; 307 | border-color: #46b8da; 308 | margin-top: 2rem; 309 | text-decoration: inherit; 310 | } 311 | 312 | .main > .main-left > .nav { 313 | margin-top: 0.5rem; 314 | } 315 | 316 | .main > .main-left > .nav > li a { 317 | color: #404040; 318 | display: block; 319 | } 320 | 321 | .main > .main-left > .nav > li:nth-last-child(1) { 322 | margin-top: 2rem; 323 | font-size: 1.2rem; 324 | } 325 | 326 | .main > .main-left > .nav > li { 327 | padding: 0.5rem 1rem; 328 | cursor: pointer; 329 | } 330 | 331 | .main > .main-left > .nav > .slide { 332 | padding: 0; 333 | } 334 | 335 | .main > .main-left > .nav > .slide > ul { 336 | display: none; 337 | } 338 | 339 | .main > .main-left > .nav > .slide > .menu { 340 | display: block; 341 | padding: 0.5rem 1rem; 342 | text-decoration: none; 343 | cursor: default; 344 | font-size: 1.15rem; 345 | } 346 | 347 | .main > .main-left > .nav > li:hover, 348 | .main > .main-left > .nav > .slide > .menu:hover { 349 | background: #D4D4D4; 350 | } 351 | 352 | .main > .main-left > .nav > .slide:hover { 353 | background: none; 354 | } 355 | 356 | .main > .main-left > .nav > .slide > .slide-menu > li { 357 | padding: 0.4rem 2rem; 358 | } 359 | 360 | .main > .main-left > .nav > .slide > .slide-menu > .active { 361 | background-color: #0099CC; 362 | } 363 | 364 | .main > .main-left > .nav > .slide > .slide-menu > li > a { 365 | text-decoration: none; 366 | white-space: nowrap; 367 | } 368 | 369 | .main > .main-left > .nav > .slide > .slide-menu > .active > a { 370 | color: white; 371 | } 372 | 373 | .main > .main-left > .nav > .slide > .slide-menu > li:hover { 374 | background: #D4D4D4; 375 | } 376 | 377 | .main > .main-left > .nav > .slide > .slide-menu > .active:hover { 378 | background-color: #0099CC; 379 | cursor: hand; 380 | } 381 | 382 | li { 383 | list-style-type: none; 384 | } 385 | 386 | #maincontent > .container { 387 | margin: 0 2rem 1rem 2rem; 388 | } 389 | 390 | h1 { 391 | font-size: 2rem; 392 | padding-bottom: 10px; 393 | border-bottom: 1px solid #eee; 394 | } 395 | 396 | h2 { 397 | margin: 2rem 0 0 0; 398 | font-size: 1.8rem; 399 | padding-bottom: 10px; 400 | border-bottom: 1px solid #eee; 401 | } 402 | 403 | h3 { 404 | margin: 2rem 0 0 0; 405 | font-size: 1.4rem; 406 | padding-bottom: 10px; 407 | } 408 | 409 | h4 { 410 | 411 | } 412 | 413 | fieldset { 414 | margin: 2rem 0 0 0; 415 | padding: 2rem; 416 | border: 0; 417 | font-weight: normal; 418 | font-style: normal; 419 | line-height: 1; 420 | font-family: inherit; 421 | 422 | min-width: inherit; 423 | overflow-x: auto; 424 | overflow-y: hidden; 425 | 426 | border-radius: 0; 427 | background-color: #FFF; 428 | box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12); 429 | 430 | -webkit-overflow-scrolling: touch; 431 | } 432 | 433 | .cbi-map-descr + fieldset { 434 | margin-top: 1rem; 435 | } 436 | 437 | fieldset > legend { 438 | display: none !important; 439 | } 440 | 441 | fieldset > fieldset { 442 | margin: 0; 443 | padding: 0; 444 | border: none; 445 | box-shadow: none; 446 | } 447 | 448 | .panel-title { 449 | width: 100%; 450 | display: block; 451 | line-height: 1; 452 | color: #404040; 453 | font-size: 1.4rem; 454 | padding-bottom: 1rem; 455 | border-bottom: 1px solid #eee; 456 | } 457 | 458 | table { 459 | border-spacing: 0; 460 | border-collapse: collapse; 461 | width: 100%; 462 | border: 1px solid #eee; 463 | } 464 | 465 | table > tbody > tr > td, table > tbody > tr > th, table > tfoot > tr > td, table > tfoot > tr > th, table > thead > tr > td, table > thead > tr > th { 466 | padding: .5rem; 467 | border-top: 1px solid #ddd; 468 | white-space: nowrap; 469 | } 470 | 471 | .cbi-section-table-cell { 472 | text-align: center; 473 | } 474 | 475 | .cbi-section-table-row { 476 | text-align: center; 477 | } 478 | 479 | fieldset > table > tbody > tr:nth-of-type(2n) { 480 | background-color: #f9f9f9; 481 | } 482 | 483 | /* fix progress bar */ 484 | #swaptotal > div, 485 | #swapfree > div, 486 | #memfree > div, 487 | #membuff > div, 488 | #conns > div, 489 | #memtotal > div { 490 | width: 100% !important; 491 | height: 1.2rem !important; 492 | } 493 | 494 | #swaptotal > div > div, 495 | #swapfree > div > div, 496 | #memfree > div > div, 497 | #membuff > div > div, 498 | #conns > div > div, 499 | #memtotal > div > div { 500 | height: 100% !important; 501 | background-color: #0099CC !important; 502 | } 503 | 504 | /* fix multiple table */ 505 | 506 | table table { 507 | border: none; 508 | } 509 | 510 | .cbi-value-field table { 511 | border: none; 512 | } 513 | 514 | td > table > tbody > tr > td { 515 | border: none; 516 | } 517 | 518 | .cbi-value-field > table > tbody > tr > td { 519 | border: none; 520 | } 521 | 522 | /* button style */ 523 | 524 | .cbi-button { 525 | -webkit-appearance: none; 526 | text-transform: uppercase; 527 | color: rgba(0, 0, 0, 0.87); 528 | background-color: #F0F0F0; 529 | transition: all 0.2s ease-in-out; 530 | display: inline-block; 531 | padding: 0 0.8rem; 532 | border: none; 533 | border-radius: 0.2rem; 534 | cursor: pointer; 535 | -ms-touch-action: manipulation; 536 | touch-action: manipulation; 537 | background-image: none; 538 | text-align: center; 539 | vertical-align: middle; 540 | white-space: nowrap; 541 | -webkit-user-select: none; 542 | -moz-user-select: none; 543 | -ms-user-select: none; 544 | user-select: none; 545 | font-size: 0.8rem; 546 | width: auto !important; 547 | } 548 | 549 | .cbi-button:hover, 550 | .cbi-button:focus, 551 | .cbi-button:active { 552 | color: rgba(0, 0, 0, 0.87); 553 | outline: 0; 554 | text-decoration: none; 555 | color: rgba(0, 0, 0, 0.87); 556 | } 557 | 558 | .cbi-button:hover, 559 | .cbi-button:focus { 560 | box-shadow: 0 0px 2px rgba(0, 0, 0, 0.12), 0 2px 2px rgba(0, 0, 0, 0.2); 561 | } 562 | 563 | .cbi-button:active { 564 | box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23); 565 | } 566 | 567 | .cbi-button:disabled { 568 | cursor: not-allowed; 569 | pointer-events: none; 570 | opacity: 0.60; 571 | box-shadow: none; 572 | } 573 | 574 | form.inline + form.inline, 575 | .cbi-button + .cbi-button { 576 | margin-left: 0.6rem; 577 | } 578 | 579 | .cbi-button-reset, 580 | .cbi-input-remove { 581 | color: #fff !important; 582 | background-color: #f0ad4e !important; 583 | border-color: #eea236 !important; 584 | } 585 | 586 | .cbi-input-find, 587 | .cbi-input-save, 588 | .cbi-button-add, 589 | .cbi-button-save, 590 | .cbi-button-find, 591 | .cbi-input-reload, 592 | .cbi-button-reload { 593 | color: #fff !important; 594 | background-color: #337ab7 !important; 595 | border-color: #2e6da4 !important; 596 | } 597 | 598 | .cbi-input-apply, 599 | .cbi-button-apply, 600 | .cbi-button-edit { 601 | color: #fff !important; 602 | background-color: #5bc0de !important; 603 | border-color: #46b8da !important; 604 | } 605 | 606 | .cbi-input-reset, 607 | .cbi-section-remove > .cbi-button, 608 | .cbi-button-remove { 609 | color: #fff !important; 610 | background-color: #d9534f !important; 611 | border-color: #d43f3a !important; 612 | } 613 | 614 | .a-to-btn { 615 | text-decoration: none; 616 | } 617 | 618 | /* table */ 619 | 620 | .tabs { 621 | margin: 0 -2rem; 622 | padding-left: 0.5rem; 623 | background-color: #FFFFFF; 624 | } 625 | 626 | .cbi-tabmenu > li, 627 | .tabs > li { 628 | display: inline-block; 629 | padding: 0.6rem 0rem; 630 | } 631 | 632 | .cbi-tabmenu > li > a, 633 | .tabs > li > a { 634 | text-decoration: none; 635 | color: #404040; 636 | padding: 0.5rem 0.8rem; 637 | } 638 | 639 | .tabs > li[class~="active"], 640 | .tabs > li:hover { 641 | cursor: pointer; 642 | border-bottom: 0.2rem solid #0099CC; 643 | color: #0099CC; 644 | margin-bottom: -0.18751rem; 645 | } 646 | 647 | .tabs > li[class~="active"] > a { 648 | color: #0099cc; 649 | } 650 | 651 | .tabs > li:hover { 652 | border-bottom: 0.18751rem solid #C9C9C9; 653 | } 654 | 655 | .cbi-tabmenu { 656 | border-top: 1px solid #D4D4D4; 657 | border-left: 1px solid #D4D4D4; 658 | border-right: 1px solid #D4D4D4; 659 | } 660 | 661 | .cbi-tabmenu > li:hover { 662 | background-color: #F1F1F1; 663 | } 664 | 665 | .cbi-tabmenu > li[class~="cbi-tab"] { 666 | background-color: white; 667 | } 668 | 669 | .cbi-tabmenu { 670 | background-color: #D4D4D4; 671 | } 672 | 673 | .cbi-section-remove:nth-of-type(2n), 674 | .cbi-section-node:nth-of-type(2n){ 675 | background-color: #f9f9f9; 676 | } 677 | 678 | .cbi-section-node-tabbed { 679 | padding: 0; 680 | margin-top: 0; 681 | border-bottom: 1px solid #D4D4D4; 682 | border-left: 1px solid #D4D4D4; 683 | border-right: 1px solid #D4D4D4; 684 | } 685 | 686 | .cbi-tabcontainer > .cbi-value:nth-of-type(2n) { 687 | background-color: #f9f9f9; 688 | } 689 | 690 | .cbi-value-field, 691 | .cbi-value-description { 692 | display: table-cell; 693 | line-height: 1.25; 694 | } 695 | 696 | .cbi-value-helpicon > img { 697 | display: none; 698 | } 699 | 700 | .cbi-value-helpicon:before { 701 | content: "\f059"; 702 | } 703 | 704 | .cbi-value-description { 705 | font-size: small; 706 | opacity: 0.5; 707 | padding: 0.5rem 0 0 0; 708 | } 709 | 710 | .cbi-value-title { 711 | word-wrap: break-word; 712 | padding-top: 0.6rem; 713 | width: 23rem; 714 | float: left; 715 | text-align: right; 716 | padding-right: 2rem; 717 | display: table-cell; 718 | } 719 | 720 | .cbi-value { 721 | padding: 0.3rem 1rem; 722 | display: inline-block; 723 | width: 100%; 724 | } 725 | 726 | .cbi-section-table-descr > .cbi-section-table-cell, 727 | .cbi-section-table-titles > .cbi-section-table-cell { 728 | border: none; 729 | } 730 | 731 | .cbi-rowstyle-2 { 732 | background-color: #eee; 733 | } 734 | 735 | .cbi-rowstyle-2 .cbi-button-up, 736 | .cbi-rowstyle-2 .cbi-button-down { 737 | background-color: #FFF !important; 738 | } 739 | 740 | .cbi-section-table .cbi-section-table-titles .cbi-section-table-cell { 741 | width: auto !important; 742 | } 743 | 744 | /* desc */ 745 | .cbi-section-descr, 746 | .cbi-map-descr { 747 | padding: 0.5rem; 748 | color: #999; 749 | font-size: small; 750 | } 751 | 752 | /* luci */ 753 | 754 | .hidden { 755 | display: none 756 | } 757 | 758 | .left { 759 | text-align: left !important; 760 | } 761 | 762 | .right { 763 | text-align: right !important; 764 | } 765 | 766 | .inline { 767 | display: inline; 768 | } 769 | 770 | .cbi-page-actions { 771 | border-top: 1px solid #eee; 772 | padding-top: 1rem; 773 | text-align: right; 774 | } 775 | 776 | /* input */ 777 | .cbi-value input[type="password"], 778 | .cbi-value input[type="text"] { 779 | min-width: 15rem; 780 | } 781 | 782 | /* select */ 783 | .cbi-value-field .cbi-input-select { 784 | min-width: 15rem; 785 | } 786 | 787 | .ifacebadge { 788 | display: inline-flex; 789 | border-bottom: 1px solid #CCCCCC; 790 | padding: 0.5rem 1rem; 791 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); 792 | -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); 793 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); 794 | } 795 | 796 | td > .ifacebadge { 797 | background-color: #F0F0F0; 798 | font-size: 0.9rem; 799 | } 800 | 801 | .ifacebadge > img { 802 | float: right; 803 | margin: 0 0.3rem; 804 | } 805 | 806 | /*textarea*/ 807 | 808 | .cbi-input-textarea { 809 | width: 100%; 810 | min-height: 14rem; 811 | padding: 0.8rem; 812 | font-size: 0.8rem; 813 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 814 | color: black; 815 | } 816 | 817 | #syslog { 818 | width: 100%; 819 | min-height: 15rem; 820 | padding: 1rem; 821 | font-size: small; 822 | color: #5F5F5F; 823 | 824 | margin-bottom: 20px; 825 | border-radius: 0; 826 | background-color: #FFF; 827 | box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12); 828 | border: none; 829 | } 830 | 831 | /* change */ 832 | 833 | .uci-change-list { 834 | font-family: monospace; 835 | } 836 | 837 | .uci-change-list ins, 838 | .uci-change-legend-label ins { 839 | text-decoration: none; 840 | border: 1px solid #00FF00; 841 | background-color: #CCFFCC; 842 | display: block; 843 | padding: 2px; 844 | } 845 | 846 | .uci-change-list del, 847 | .uci-change-legend-label del { 848 | text-decoration: none; 849 | border: 1px solid #FF0000; 850 | background-color: #FFCCCC; 851 | display: block; 852 | font-style: normal; 853 | padding: 2px; 854 | } 855 | 856 | .uci-change-list var, 857 | .uci-change-legend-label var { 858 | text-decoration: none; 859 | border: 1px solid #CCCCCC; 860 | background-color: #EEEEEE; 861 | display: block; 862 | font-style: normal; 863 | padding: 2px; 864 | } 865 | 866 | .uci-change-list var ins, 867 | .uci-change-list var del { 868 | border: none; 869 | white-space: pre; 870 | font-style: normal; 871 | padding: 0px; 872 | } 873 | 874 | .uci-change-legend { 875 | padding: 5px; 876 | } 877 | 878 | .uci-change-legend-label { 879 | width: 150px; 880 | float: left; 881 | } 882 | 883 | .uci-change-legend-label > ins, 884 | .uci-change-legend-label > del, 885 | .uci-change-legend-label > var { 886 | float: left; 887 | margin-right: 4px; 888 | width: 10px; 889 | height: 10px; 890 | display: block; 891 | } 892 | 893 | .uci-change-legend-label var ins, 894 | .uci-change-legend-label var del { 895 | line-height: 6px; 896 | border: none; 897 | } 898 | 899 | .uci-change-list var, 900 | .uci-change-list del, 901 | .uci-change-list ins { 902 | padding: 0.5rem; 903 | } 904 | 905 | /* other fix */ 906 | #iwsvg, 907 | #iwsvg2, 908 | #bwsvg { 909 | border: 1px solid #D4D4D4 !important; 910 | border-top: none !important; 911 | } 912 | 913 | .ifacebox { 914 | border: 1px solid #999; 915 | background-color: #f9f9f9; 916 | } 917 | 918 | .cbi-image-button { 919 | margin-left: 0.5rem; 920 | } 921 | 922 | .zonebadge { 923 | padding: 0.2rem 0.5rem; 924 | display: inline-block; 925 | cursor: pointer; 926 | } 927 | 928 | .zonebadge > .ifacebadge { 929 | padding: 0.2rem 1rem; 930 | margin: 0.3rem; 931 | border: 1px solid #6C6C6C; 932 | } 933 | 934 | .zonebadge > input[type="text"] { 935 | padding: 0.16rem 1rem; 936 | min-width: 10rem; 937 | margin-top: 0.3rem; 938 | } 939 | 940 | .cbi-value-field .cbi-input-checkbox, 941 | .cbi-value-field .cbi-input-radio { 942 | margin-top: 0.5rem; 943 | height: 1rem; 944 | } 945 | 946 | .cbi-value-field > input + .cbi-value-description { 947 | padding: 0; 948 | } 949 | 950 | .cbi-value-field > ul > li { 951 | display: flex; 952 | } 953 | 954 | .cbi-value-field > ul > li > label { 955 | margin-top: 0.5rem; 956 | } 957 | 958 | .cbi-value-field > ul > li .ifacebadge { 959 | background-color: #eee; 960 | margin-left: 0.4rem; 961 | margin-top: -0.5rem; 962 | } 963 | 964 | .cbi-section-table-row > .cbi-value-field .cbi-input-select { 965 | min-width: 7rem; 966 | } 967 | 968 | .cbi-section-create > .cbi-button-add { 969 | margin: 0.5rem; 970 | } 971 | 972 | .cbi-section-remove { 973 | padding: 0.5rem; 974 | } 975 | 976 | div.cbi-value var, td.cbi-value-field var { 977 | font-style: italic; 978 | color: #0069D6; 979 | } 980 | 981 | small { 982 | font-size: 90%; 983 | white-space: normal; 984 | line-height: 1.42857143; 985 | } 986 | 987 | .cbi-button-up, 988 | .cbi-button-down { 989 | display: inline-block; 990 | min-width: 0; 991 | padding: 0.2rem 0.3rem; 992 | font-size: 1.2rem; 993 | } 994 | 995 | .cbi-optionals { 996 | padding: 1rem 1rem 0 1rem; 997 | border-top: 1px solid #CCC; 998 | } 999 | 1000 | #diag-rc-output > pre { 1001 | background-color: #f5f5f5; 1002 | display: block; 1003 | padding: 8.5px; 1004 | margin: 0 0 18px; 1005 | line-height: 1.5rem; 1006 | -moz-border-radius: 3px; 1007 | white-space: pre-wrap; 1008 | word-wrap: break-word; 1009 | font-size: 1.4rem; 1010 | color: #404040; 1011 | } 1012 | 1013 | input[name="ping"], 1014 | input[name="traceroute"], 1015 | input[name="nslookup"] { 1016 | width: 80%; 1017 | } 1018 | 1019 | header > .container > .pull-right > * { 1020 | position: relative; 1021 | top: 0.45rem; 1022 | cursor: pointer; 1023 | } 1024 | 1025 | #xhr_poll_status > .label.success { 1026 | background-color: #14CE14; 1027 | } 1028 | 1029 | .label { 1030 | padding: 0.3rem 0.8rem; 1031 | font-size: 0.8rem; 1032 | font-weight: bold; 1033 | color: #ffffff !important; 1034 | text-transform: uppercase; 1035 | white-space: nowrap; 1036 | background-color: #bfbfbf; 1037 | -webkit-border-radius: 3px; 1038 | -moz-border-radius: 3px; 1039 | border-radius: 3px; 1040 | text-shadow: none; 1041 | text-decoration: none; 1042 | } 1043 | 1044 | .notice { 1045 | background-color: #5BC0DE; 1046 | } 1047 | 1048 | .showSide { 1049 | display: none; 1050 | } 1051 | 1052 | .darkMask { 1053 | width: 100%; 1054 | height: 100%; 1055 | position: fixed; 1056 | background-color: rgba(0, 0, 0, 0.56); 1057 | content: ""; 1058 | z-index: 99; 1059 | display: none; 1060 | } 1061 | 1062 | /* fix Main Login*/ 1063 | .node-main-login > .main > .main-left { 1064 | display: none; 1065 | } 1066 | 1067 | .node-main-login > .main > .main-right { 1068 | width: 100%; 1069 | } 1070 | 1071 | .node-main-login > .main fieldset { 1072 | padding: 0.5rem; 1073 | margin-bottom: 1rem; 1074 | display: inline; 1075 | background: none; 1076 | border: none; 1077 | box-shadow: none; 1078 | overflow: hidden; 1079 | } 1080 | 1081 | .node-main-login > .main .cbi-value-title { 1082 | width: 7rem; 1083 | } 1084 | 1085 | .node-main-login > .main #maincontent { 1086 | 1087 | text-align: center; 1088 | } 1089 | 1090 | .node-main-login > .main .container { 1091 | display: inline-block; 1092 | padding: 2rem 4rem; 1093 | margin-top: 2rem !important; 1094 | background-color: #FFF; 1095 | box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12); 1096 | text-align: left; 1097 | } 1098 | 1099 | .node-main-login > .main form > div:nth-last-child(1) { 1100 | float: right; 1101 | } 1102 | 1103 | .node-main-login > .main .cbi-value { 1104 | display: block; 1105 | } 1106 | 1107 | .node-main-login > .main .cbi-value > * { 1108 | display: inline-block !important; 1109 | } 1110 | 1111 | .node-main-login > .main .cbi-input-user, 1112 | .node-main-login > .main .cbi-input-password { 1113 | min-width: 15rem; 1114 | } 1115 | 1116 | .node-main-login footer { 1117 | bottom: 0; 1118 | position: absolute; 1119 | width: 100%; 1120 | } 1121 | 1122 | /* fix status overview */ 1123 | 1124 | .node-status-overview > .main fieldset:nth-child(4) td:nth-child(2) { 1125 | white-space: normal; 1126 | } 1127 | 1128 | /* fix status processes */ 1129 | 1130 | .node-status-processes > .main table tr td:nth-child(3) { 1131 | white-space: normal; 1132 | } 1133 | 1134 | .node-status-iptables > .main div > .cbi-map > form { 1135 | margin: 2rem 2rem 0 0; 1136 | } 1137 | 1138 | /* fix system reboot */ 1139 | 1140 | .node-system-reboot > .main > .main-right p, 1141 | .node-system-reboot > .main > .main-right h3 { 1142 | padding-left: 2rem; 1143 | } 1144 | 1145 | /* fix Services Network Shares*/ 1146 | .node-services-samba > .main .cbi-tabcontainer:nth-child(3) .cbi-value-title { 1147 | margin-bottom: 1rem; 1148 | width: auto; 1149 | } 1150 | 1151 | .node-services-samba > .main .cbi-tabcontainer:nth-child(3) .cbi-value-field { 1152 | display: list-item; 1153 | } 1154 | 1155 | .node-services-samba > .main .cbi-tabcontainer:nth-child(3) .cbi-value-description { 1156 | padding-top: 1rem; 1157 | } 1158 | 1159 | /* fix System Software*/ 1160 | .node-system-packages > .main table tr td:nth-child(1) { 1161 | width: auto !important; 1162 | } 1163 | 1164 | .node-system-packages > .main table tr td:nth-last-child(1) { 1165 | white-space: normal; 1166 | font-size: small; 1167 | color: #404040; 1168 | } 1169 | 1170 | .node-system-packages > .main .cbi-tabmenu > li > a, .tabs > li > a { 1171 | padding: 0.5rem 0.8rem; 1172 | } 1173 | 1174 | .node-system-packages > .main .cbi-value > pre { 1175 | background-color: #eee; 1176 | padding: 0.5rem; 1177 | overflow: auto; 1178 | } 1179 | 1180 | .cbi-tabmenu + .cbi-section { 1181 | margin-top: 0; 1182 | } 1183 | 1184 | /* fix network firewall*/ 1185 | .node-network-firewall > .main .cbi-section-table-row > .cbi-value-field .cbi-input-select { 1186 | min-width: 4rem; 1187 | } 1188 | 1189 | .node-status-iptables fieldset, 1190 | .node-system-packages fieldset, 1191 | .node-system-flashops fieldset { 1192 | margin-top: 0; 1193 | } 1194 | 1195 | .node-status-iptables .cbi-tabmenu, 1196 | .node-system-packages .cbi-tabmenu, 1197 | .node-system-flashops .cbi-tabmenu { 1198 | border: none; 1199 | box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12); 1200 | } 1201 | 1202 | .node-system-flashops form.inline + form.inline { 1203 | margin-left: 0; 1204 | } 1205 | 1206 | #cbi-firewall-redirect table *, 1207 | #cbi-network-switch_vlan table *, 1208 | #cbi-firewall-zone table * { 1209 | font-size: small; 1210 | } 1211 | 1212 | #cbi-firewall-redirect table input[type="text"], 1213 | #cbi-network-switch_vlan table input[type="text"], 1214 | #cbi-firewall-zone table input[type="text"] { 1215 | width: 5rem; 1216 | } 1217 | 1218 | #cbi-firewall-redirect table select, 1219 | #cbi-network-switch_vlan table select, 1220 | #cbi-firewall-zone table select { 1221 | min-width: 3.5rem; 1222 | } 1223 | 1224 | /* language fix */ 1225 | body.lang_pl.node-main-login .cbi-value-title { 1226 | width: 12rem; 1227 | } 1228 | 1229 | @media screen and (max-width: 1600px) { 1230 | .main-left { 1231 | width: calc(0% + 13rem); 1232 | } 1233 | 1234 | .main-right { 1235 | width: calc(100% - 13rem); 1236 | } 1237 | 1238 | .cbi-button { 1239 | padding: 0.3rem 0.6rem; 1240 | font-size: 0.8rem; 1241 | } 1242 | 1243 | header > .container > .pull-right > * { 1244 | top: 0.35rem; 1245 | } 1246 | 1247 | .label { 1248 | padding: 0.2rem 0.6rem; 1249 | } 1250 | 1251 | .cbi-value-title { 1252 | width: 15rem; 1253 | padding-right: 0.6rem; 1254 | } 1255 | 1256 | fieldset { 1257 | padding: 1rem; 1258 | } 1259 | 1260 | .cbi-input-textarea { 1261 | font-size: small; 1262 | } 1263 | 1264 | .node-status-iptables > .main fieldset li > a { 1265 | padding: 0.3rem 0.6rem; 1266 | } 1267 | } 1268 | 1269 | @media screen and (max-width: 1280px) { 1270 | .page_loading { 1271 | height: 3.5rem; 1272 | line-height: 3.5rem; 1273 | } 1274 | header { 1275 | height: 3.5rem; 1276 | } 1277 | 1278 | header > .container { 1279 | margin-top: 0.25rem; 1280 | } 1281 | 1282 | .main { 1283 | top: 3.5rem; 1284 | height: calc(100% - 3.5rem); 1285 | } 1286 | 1287 | .main-left { 1288 | width: calc(0% + 13rem); 1289 | top: 3.5rem; 1290 | height: calc(100% - 3.5rem); 1291 | } 1292 | 1293 | .main-right { 1294 | width: calc(100% - 13rem); 1295 | } 1296 | 1297 | .cbi-tabmenu > li > a, .tabs > li > a { 1298 | padding: 0.2rem 0.5rem; 1299 | } 1300 | 1301 | .panel-title { 1302 | font-size: 1.1rem; 1303 | padding-bottom: 1rem; 1304 | } 1305 | 1306 | table { 1307 | font-size: 0.7rem !important; 1308 | width: 100% !important; 1309 | } 1310 | 1311 | .main > .main-left > .nav > li, 1312 | .main > .main-left > .nav > li a, 1313 | .main > .main-left > .nav > .slide > .menu { 1314 | font-size: 0.9rem; 1315 | } 1316 | 1317 | .main > .main-left > .nav > .slide > .slide-menu > li > a { 1318 | font-size: 0.7rem; 1319 | } 1320 | } 1321 | 1322 | @media screen and (max-width: 992px) { 1323 | .main-left { 1324 | width: 0; 1325 | position: fixed; 1326 | z-index: 100; 1327 | } 1328 | 1329 | .main-right { 1330 | width: 100%; 1331 | } 1332 | 1333 | .showSide { 1334 | padding: 0.1rem; 1335 | margin-right: 0.5rem; 1336 | display: inline-block; 1337 | } 1338 | 1339 | .showSide:before { 1340 | content: "\e20e"; 1341 | font-size: 1.7rem; 1342 | } 1343 | 1344 | .node-main-login .showSide { 1345 | display: none !important; 1346 | } 1347 | 1348 | .cbi-value-title { 1349 | width: 9rem; 1350 | padding-right: 1rem; 1351 | } 1352 | 1353 | .node-network-diagnostics > .main .cbi-map fieldset > div * { 1354 | width: 100% !important; 1355 | } 1356 | 1357 | .node-network-diagnostics > .main .cbi-map fieldset > div input[type="text"] { 1358 | margin: 3rem 0 0 0 !important; 1359 | } 1360 | 1361 | .node-network-diagnostics > .main .cbi-map fieldset > div:nth-child(4) input[type="text"] { 1362 | margin: 0 !important; 1363 | } 1364 | 1365 | .node-network-diagnostics > .main .cbi-map fieldset > div select, 1366 | .node-network-diagnostics > .main .cbi-map fieldset > div input[type="button"] { 1367 | margin: 1rem 0 0 0; 1368 | } 1369 | 1370 | .node-network-diagnostics > .main .cbi-map fieldset > div { 1371 | width: 100% !important; 1372 | } 1373 | 1374 | #diag-rc-output > pre { 1375 | font-size: 1rem; 1376 | } 1377 | 1378 | .node-main-login > .main .cbi-value-title { 1379 | text-align: left; 1380 | } 1381 | } 1382 | 1383 | @media screen and (max-width: 480px) { 1384 | body { 1385 | font-size: 1rem; 1386 | } 1387 | 1388 | fieldset { 1389 | padding: 1rem; 1390 | margin: 1rem 0 0 0; 1391 | } 1392 | 1393 | .tabs { 1394 | margin: 0 -1rem; 1395 | } 1396 | 1397 | #maincontent > .container { 1398 | margin: 0 1rem 1.5rem 1rem; 1399 | } 1400 | 1401 | .main > .main-left > .nav > .slide > .menu { 1402 | font-size: 1.3rem; 1403 | } 1404 | 1405 | .main > .main-left > .nav > .slide > .slide-menu > li > a { 1406 | font-size: 1.1rem; 1407 | } 1408 | 1409 | .cbi-value-title { 1410 | width: 100%; 1411 | min-width: 0rem !important; 1412 | display: block; 1413 | margin-top: 1rem; 1414 | margin-bottom: 0.5rem; 1415 | text-align: left; 1416 | } 1417 | 1418 | .cbi-value-field, .cbi-value-description { 1419 | width: 100%; 1420 | } 1421 | 1422 | .cbi-value > .cbi-value-field { 1423 | display: inline-block; 1424 | } 1425 | 1426 | .cbi-tabmenu > li, .tabs > li { 1427 | padding: 0.6rem 0rem; 1428 | } 1429 | 1430 | .cbi-tabmenu > li > a, .tabs > li > a { 1431 | padding: 0.2rem 0.3rem; 1432 | font-size: 0.9rem; 1433 | } 1434 | 1435 | .cbi-page-actions > div > input { 1436 | display: none; 1437 | } 1438 | 1439 | .node-main-login > .main .container { 1440 | padding: 0.5rem 1rem 2rem 1rem; 1441 | } 1442 | 1443 | .node-main-login > .main .cbi-value { 1444 | padding: 0; 1445 | } 1446 | 1447 | .node-main-login > .main form > div:nth-last-child(1) { 1448 | margin-top: 2rem; 1449 | } 1450 | 1451 | .node-main-login > .main .cbi-value-title { 1452 | width: 100% !important; 1453 | font-size: 1.2rem; 1454 | } 1455 | 1456 | .node-main-login > .main fieldset { 1457 | margin: 0; 1458 | padding: 0.5rem; 1459 | } 1460 | 1461 | h2 { 1462 | font-size: 2rem; 1463 | } 1464 | 1465 | .tabs > li > a { 1466 | font-size: 0.9rem; 1467 | } 1468 | 1469 | select, 1470 | input { 1471 | font-size: 0.9rem; 1472 | } 1473 | 1474 | .mobile-hide { 1475 | display: none; 1476 | } 1477 | 1478 | .panel-title { 1479 | font-size: 1.4rem; 1480 | padding-bottom: 1rem; 1481 | } 1482 | 1483 | .node-system-packages > .main .cbi-value.cbi-value-last > div { 1484 | width: 100% !important; 1485 | } 1486 | 1487 | .node-system-packages > .main .cbi-value .cbi-value-field input { 1488 | width: 100%; 1489 | } 1490 | 1491 | .node-status-iptables > .main div > .cbi-map > form { 1492 | position: static !important; 1493 | margin: 0 0 2rem 0; 1494 | padding: 2rem; 1495 | border: 0; 1496 | font-weight: normal; 1497 | font-style: normal; 1498 | line-height: 1; 1499 | font-family: inherit; 1500 | min-width: inherit; 1501 | overflow-x: auto; 1502 | overflow-y: hidden; 1503 | border-radius: 0; 1504 | background-color: #FFF; 1505 | box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .16), 0 0 2px 0 rgba(0, 0, 0, .12); 1506 | -webkit-overflow-scrolling: touch; 1507 | } 1508 | 1509 | .node-status-iptables > .main div > .cbi-map > form input[type="submit"] { 1510 | width: 100% !important; 1511 | margin: 0; 1512 | } 1513 | 1514 | .node-status-iptables > .main div > .cbi-map > form input[type="submit"] + input[type="submit"] { 1515 | margin-top: 1rem; 1516 | } 1517 | } 1518 | 1519 | @media screen and (min-width: 992px) { 1520 | .cbi-value input[type="password"], 1521 | .cbi-value input[type="text"] { 1522 | min-width: 20rem; 1523 | } 1524 | 1525 | .cbi-value-field .cbi-input-select { 1526 | min-width: 20rem; 1527 | } 1528 | } 1529 | 1530 | @media screen and (min-width: 1280px) { 1531 | .cbi-value input[type="password"], 1532 | .cbi-value input[type="text"] { 1533 | min-width: 22rem; 1534 | } 1535 | 1536 | .cbi-value-field .cbi-input-select { 1537 | min-width: 22rem; 1538 | } 1539 | } 1540 | 1541 | @media screen and (min-width: 1600px) { 1542 | .cbi-value input[type="password"], 1543 | .cbi-value input[type="text"] { 1544 | min-width: 25rem; 1545 | } 1546 | 1547 | .cbi-value-field .cbi-input-select { 1548 | min-width: 25rem; 1549 | } 1550 | } -------------------------------------------------------------------------------- /files/htdocs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuttyYang/luci-theme-material/e2b413bbc91cf917267438bb74b11049703f2f61/files/htdocs/favicon.ico -------------------------------------------------------------------------------- /files/htdocs/fonts/font.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuttyYang/luci-theme-material/e2b413bbc91cf917267438bb74b11049703f2f61/files/htdocs/fonts/font.eot -------------------------------------------------------------------------------- /files/htdocs/fonts/font.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by IcoMoon 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /files/htdocs/fonts/font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuttyYang/luci-theme-material/e2b413bbc91cf917267438bb74b11049703f2f61/files/htdocs/fonts/font.ttf -------------------------------------------------------------------------------- /files/htdocs/fonts/font.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuttyYang/luci-theme-material/e2b413bbc91cf917267438bb74b11049703f2f61/files/htdocs/fonts/font.woff -------------------------------------------------------------------------------- /files/htdocs/js/script.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Material is a clean HTML5 theme for LuCI. It is based on luci-theme-bootstrap and MUI 3 | * 4 | * luci-theme-material 5 | * Copyright 2015 Lutty Yang 6 | * 7 | * Have a bug? Please create an issue here on GitHub! 8 | * https://github.com/LuttyYang/luci-theme-material/issues 9 | * 10 | * luci-theme-bootstrap: 11 | * Copyright 2008 Steven Barth 12 | * Copyright 2008 Jo-Philipp Wich 13 | * Copyright 2012 David Menting 14 | * 15 | * MUI: 16 | * https://github.com/muicss/mui 17 | * 18 | * Licensed to the public under the Apache License 2.0 19 | */ 20 | (function ($) { 21 | $(".page_loading").fadeOut(200); 22 | 23 | /** 24 | * trim text, Remove spaces, wrap 25 | * @param text 26 | * @returns {string} 27 | */ 28 | function trimText(text) { 29 | return text.replace(/[ \t\n\r]+/g, " "); 30 | } 31 | 32 | 33 | var lastNode = undefined; 34 | var mainNodeName = undefined; 35 | 36 | var nodeUrl = ""; 37 | (function(node){ 38 | if (node[0] == "admin"){ 39 | luciLocation = [node[1], node[2]]; 40 | }else{ 41 | luciLocation = node; 42 | } 43 | 44 | for(var i in luciLocation){ 45 | nodeUrl += luciLocation[i]; 46 | if (i != luciLocation.length - 1){ 47 | nodeUrl += "/"; 48 | } 49 | } 50 | })(luciLocation); 51 | 52 | /** 53 | * get the current node by Burl (primary) 54 | * @returns {boolean} success? 55 | */ 56 | function getCurrentNodeByUrl() { 57 | var ret = false; 58 | if (!$('body').hasClass('logged-in')) { 59 | luciLocation = ["Main", "Login"]; 60 | return true; 61 | } 62 | 63 | $(".main > .main-left > .nav > .slide > .menu").each(function () { 64 | var ulNode = $(this); 65 | ulNode.next().find("a").each(function () { 66 | var that = $(this); 67 | var href = that.attr("href"); 68 | 69 | if (href.indexOf(nodeUrl) != -1) { 70 | ulNode.click(); 71 | ulNode.next(".slide-menu");//.stop(true, true); 72 | lastNode = that.parent(); 73 | lastNode.addClass("active"); 74 | ret = true; 75 | return true; 76 | } 77 | }); 78 | }); 79 | return ret; 80 | } 81 | 82 | /** 83 | * menu click 84 | */ 85 | $(".main > .main-left > .nav > .slide > .menu").click(function () { 86 | var ul = $(this).next(".slide-menu"); 87 | var menu = $(this); 88 | if (!ul.hasClass("active")) { 89 | menu.addClass("active"); 90 | ul.addClass("active"); 91 | ul.slideDown(200); 92 | //ul.fadeIn(200); 93 | } else { 94 | ul.slideUp(200, function () { 95 | //ul.fadeOut(200, function () { 96 | menu.removeClass("active"); 97 | ul.removeClass("active"); 98 | }); 99 | } 100 | return false; 101 | }); 102 | 103 | /** 104 | * hook menu click and add the hash 105 | */ 106 | $(".main > .main-left > .nav > .slide > .slide-menu > li > a").click(function () { 107 | if (lastNode != undefined) lastNode.removeClass("active"); 108 | $(this).parent().addClass("active"); 109 | $(".page_loading").fadeIn(200); 110 | return true; 111 | }); 112 | 113 | /** 114 | * fix menu click 115 | */ 116 | $(".main > .main-left > .nav > .slide > .slide-menu > li").click(function () { 117 | if (lastNode != undefined) lastNode.removeClass("active"); 118 | $(this).addClass("active"); 119 | $(".page_loading").fadeIn(200); 120 | window.location = $($(this).find("a")[0]).attr("href"); 121 | return false; 122 | }); 123 | 124 | /** 125 | * get current node and open it 126 | */ 127 | if (getCurrentNodeByUrl()) { 128 | mainNodeName = "node-" + luciLocation[0] + "-" + luciLocation[1]; 129 | mainNodeName = mainNodeName.replace(/[ \t\n\r\/]+/g, "_").toLowerCase(); 130 | $("body").addClass(mainNodeName); 131 | } 132 | $(".cbi-button-up").val(""); 133 | $(".cbi-button-down").val(""); 134 | 135 | 136 | /** 137 | * hook other "A Label" and add hash to it. 138 | */ 139 | $("#maincontent > .container").find("a").each(function () { 140 | var that = $(this); 141 | var onclick = that.attr("onclick"); 142 | if (onclick == undefined || onclick == "") { 143 | that.click(function () { 144 | var href = that.attr("href"); 145 | if (href.indexOf("#") == -1) { 146 | $(".page_loading").fadeIn(200); 147 | return true; 148 | } 149 | }); 150 | } 151 | }); 152 | 153 | /** 154 | * Sidebar expand 155 | */ 156 | var showSide = false; 157 | $(".showSide").click(function () { 158 | if (showSide) { 159 | $(".darkMask").fadeOut(200); 160 | $(".main-left").animate({ 161 | width: "0" 162 | }, 200); 163 | $(".main-right").css("overflow-y", "auto"); 164 | showSide = false; 165 | } else { 166 | $(".darkMask").fadeIn(200); 167 | $(".main-left").animate({ 168 | width: "15rem" 169 | }, 200); 170 | $(".main-right").css("overflow-y", "hidden"); 171 | showSide = true; 172 | } 173 | }); 174 | 175 | 176 | $(".darkMask").click(function () { 177 | if (showSide) { 178 | showSide = false; 179 | $(".darkMask").fadeOut(200); 180 | $(".main-left").animate({ 181 | width: "0" 182 | }, 200); 183 | $(".main-right").css("overflow-y", "auto"); 184 | } 185 | }); 186 | 187 | $(window).resize(function () { 188 | if ($(window).width() > 921) { 189 | $(".main-left").css("width", ""); 190 | $(".darkMask"); 191 | $(".darkMask").css("display", "none"); 192 | showSide = false; 193 | } 194 | }); 195 | 196 | /** 197 | * fix legend position 198 | */ 199 | $("legend").each(function () { 200 | var that = $(this); 201 | that.after("" + that.text() + ""); 202 | }); 203 | 204 | $(".cbi-section-table-titles, .cbi-section-table-descr, .cbi-section-descr").each(function () { 205 | var that = $(this); 206 | if (that.text().trim() == ""){ 207 | that.css("display", "none"); 208 | } 209 | }); 210 | 211 | 212 | $(".main-right").focus(); 213 | $(".main-right").blur(); 214 | $("input").attr("size", "0"); 215 | 216 | if (mainNodeName != undefined) { 217 | console.log(mainNodeName); 218 | switch (mainNodeName) { 219 | case "node-status-system_log": 220 | case "node-status-kernel_log": 221 | $("#syslog").focus(function () { 222 | $("#syslog").blur(); 223 | $(".main-right").focus(); 224 | $(".main-right").blur(); 225 | }); 226 | break; 227 | case "node-status-firewall": 228 | var button = $(".node-status-firewall > .main fieldset li > a"); 229 | button.addClass("cbi-button cbi-button-reset a-to-btn"); 230 | break; 231 | case "node-system-reboot": 232 | var button = $(".node-system-reboot > .main > .main-right p > a"); 233 | button.addClass("cbi-button cbi-input-reset a-to-btn"); 234 | break; 235 | } 236 | } 237 | 238 | })(Zepto); 239 | -------------------------------------------------------------------------------- /files/htdocs/js/zepto.min.js: -------------------------------------------------------------------------------- 1 | var Zepto=function(){var t,e,n,i,r=[],o=r.concat,s=r.filter,a=r.slice,u=window.document,f={},c={},l={"column-count":1,columns:1,"font-weight":1,"line-height":1,opacity:1,"z-index":1,zoom:1},h=/^\s*<(\w+|!)[^>]*>/,p=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,d=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,m=/^(?:body|html)$/i,g=/([A-Z])/g,v=["val","css","html","text","data","width","height","offset"],y=["after","prepend","before","append"],w=u.createElement("table"),b=u.createElement("tr"),E={tr:u.createElement("tbody"),tbody:w,thead:w,tfoot:w,td:b,th:b,"*":u.createElement("div")},x=/^[\w-]*$/,T={},N=T.toString,C={},O,P,S=u.createElement("div"),A={tabindex:"tabIndex",readonly:"readOnly",for:"htmlFor",class:"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},L=Array.isArray||function(t){return t instanceof Array};C.matches=function(t,e){if(!e||!t||t.nodeType!==1)return false;var n=t.matches||t.webkitMatchesSelector||t.mozMatchesSelector||t.oMatchesSelector||t.matchesSelector;if(n)return n.call(t,e);var i,r=t.parentNode,o=!r;if(o)(r=S).appendChild(t);i=~C.qsa(r,e).indexOf(t);o&&S.removeChild(t);return i};function Z(t){return t==null?String(t):T[N.call(t)]||"object"}function $(t){return Z(t)=="function"}function B(t){return t!=null&&t==t.window}function j(t){return t!=null&&t.nodeType==t.DOCUMENT_NODE}function k(t){return Z(t)=="object"}function D(t){return k(t)&&!B(t)&&Object.getPrototypeOf(t)==Object.prototype}function M(t){var e=!!t&&"length"in t&&t.length,i=n.type(t);return"function"!=i&&!B(t)&&("array"==i||e===0||typeof e=="number"&&e>0&&e-1 in t)}function z(t){return s.call(t,function(t){return t!=null})}function _(t){return t.length>0?n.fn.concat.apply([],t):t}O=function(t){return t.replace(/-+(.)?/g,function(t,e){return e?e.toUpperCase():""})};function F(t){return t.replace(/::/g,"/").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/_/g,"-").toLowerCase()}P=function(t){return s.call(t,function(e,n){return t.indexOf(e)==n})};function V(t){return t in c?c[t]:c[t]=new RegExp("(^|\\s)"+t+"(\\s|$)")}function q(t,e){return typeof e=="number"&&!l[F(t)]?e+"px":e}function I(t){var e,n;if(!f[t]){e=u.createElement(t);u.body.appendChild(e);n=getComputedStyle(e,"").getPropertyValue("display");e.parentNode.removeChild(e);n=="none"&&(n="block");f[t]=n}return f[t]}function R(t){return"children"in t?a.call(t.children):n.map(t.childNodes,function(t){if(t.nodeType==1)return t})}function H(t,e){var n,i=t?t.length:0;for(n=0;n");if(i===t)i=h.test(e)&&RegExp.$1;if(!(i in E))i="*";f=E[i];f.innerHTML=""+e;o=n.each(a.call(f.childNodes),function(){f.removeChild(this)})}if(D(r)){s=n(o);n.each(r,function(t,e){if(v.indexOf(t)>-1)s[t](e);else s.attr(t,e)})}return o};C.Z=function(t,e){return new H(t,e)};C.isZ=function(t){return t instanceof C.Z};C.init=function(e,i){var r;if(!e)return C.Z();else if(typeof e=="string"){e=e.trim();if(e[0]=="<"&&h.test(e))r=C.fragment(e,RegExp.$1,i),e=null;else if(i!==t)return n(i).find(e);else r=C.qsa(u,e)}else if($(e))return n(u).ready(e);else if(C.isZ(e))return e;else{if(L(e))r=z(e);else if(k(e))r=[e],e=null;else if(h.test(e))r=C.fragment(e.trim(),RegExp.$1,i),e=null;else if(i!==t)return n(i).find(e);else r=C.qsa(u,e)}return C.Z(r,e)};n=function(t,e){return C.init(t,e)};function X(n,i,r){for(e in i)if(r&&(D(i[e])||L(i[e]))){if(D(i[e])&&!D(n[e]))n[e]={};if(L(i[e])&&!L(n[e]))n[e]=[];X(n[e],i[e],r)}else if(i[e]!==t)n[e]=i[e]}n.extend=function(t){var e,n=a.call(arguments,1);if(typeof t=="boolean"){e=t;t=n.shift()}n.forEach(function(n){X(t,n,e)});return t};C.qsa=function(t,e){var n,i=e[0]=="#",r=!i&&e[0]==".",o=i||r?e.slice(1):e,s=x.test(o);return t.getElementById&&s&&i?(n=t.getElementById(o))?[n]:[]:t.nodeType!==1&&t.nodeType!==9&&t.nodeType!==11?[]:a.call(s&&!i&&t.getElementsByClassName?r?t.getElementsByClassName(o):t.getElementsByTagName(e):t.querySelectorAll(e))};function Y(t,e){return e==null?n(t):n(t).filter(e)}n.contains=u.documentElement.contains?function(t,e){return t!==e&&t.contains(e)}:function(t,e){while(e&&(e=e.parentNode))if(e===t)return true;return false};function U(t,e,n,i){return $(e)?e.call(t,n,i):e}function J(t,e,n){n==null?t.removeAttribute(e):t.setAttribute(e,n)}function W(e,n){var i=e.className||"",r=i&&i.baseVal!==t;if(n===t)return r?i.baseVal:i;r?i.baseVal=n:e.className=n}function G(t){try{return t?t=="true"||(t=="false"?false:t=="null"?null:+t+""==t?+t:/^[\[\{]/.test(t)?n.parseJSON(t):t):t}catch(e){return t}}n.type=Z;n.isFunction=$;n.isWindow=B;n.isArray=L;n.isPlainObject=D;n.isEmptyObject=function(t){var e;for(e in t)return false;return true};n.isNumeric=function(t){var e=Number(t),n=typeof t;return t!=null&&n!="boolean"&&(n!="string"||t.length)&&!isNaN(e)&&isFinite(e)||false};n.inArray=function(t,e,n){return r.indexOf.call(e,t,n)};n.camelCase=O;n.trim=function(t){return t==null?"":String.prototype.trim.call(t)};n.uuid=0;n.support={};n.expr={};n.noop=function(){};n.map=function(t,e){var n,i=[],r,o;if(M(t))for(r=0;r=0?e:e+this.length]},toArray:function(){return this.get()},size:function(){return this.length},remove:function(){return this.each(function(){if(this.parentNode!=null)this.parentNode.removeChild(this)})},each:function(t){r.every.call(this,function(e,n){return t.call(e,n,e)!==false});return this},filter:function(t){if($(t))return this.not(this.not(t));return n(s.call(this,function(e){return C.matches(e,t)}))},add:function(t,e){return n(P(this.concat(n(t,e))))},is:function(t){return this.length>0&&C.matches(this[0],t)},not:function(e){var i=[];if($(e)&&e.call!==t)this.each(function(t){if(!e.call(this,t))i.push(this)});else{var r=typeof e=="string"?this.filter(e):M(e)&&$(e.item)?a.call(e):n(e);this.forEach(function(t){if(r.indexOf(t)<0)i.push(t)})}return n(i)},has:function(t){return this.filter(function(){return k(t)?n.contains(this,t):n(this).find(t).size()})},eq:function(t){return t===-1?this.slice(t):this.slice(t,+t+1)},first:function(){var t=this[0];return t&&!k(t)?t:n(t)},last:function(){var t=this[this.length-1];return t&&!k(t)?t:n(t)},find:function(t){var e,i=this;if(!t)e=n();else if(typeof t=="object")e=n(t).filter(function(){var t=this;return r.some.call(i,function(e){return n.contains(e,t)})});else if(this.length==1)e=n(C.qsa(this[0],t));else e=this.map(function(){return C.qsa(this,t)});return e},closest:function(t,e){var i=[],r=typeof t=="object"&&n(t);this.each(function(n,o){while(o&&!(r?r.indexOf(o)>=0:C.matches(o,t)))o=o!==e&&!j(o)&&o.parentNode;if(o&&i.indexOf(o)<0)i.push(o)});return n(i)},parents:function(t){var e=[],i=this;while(i.length>0)i=n.map(i,function(t){if((t=t.parentNode)&&!j(t)&&e.indexOf(t)<0){e.push(t);return t}});return Y(e,t)},parent:function(t){return Y(P(this.pluck("parentNode")),t)},children:function(t){return Y(this.map(function(){return R(this)}),t)},contents:function(){return this.map(function(){return this.contentDocument||a.call(this.childNodes)})},siblings:function(t){return Y(this.map(function(t,e){return s.call(R(e.parentNode),function(t){return t!==e})}),t)},empty:function(){return this.each(function(){this.innerHTML=""})},pluck:function(t){return n.map(this,function(e){return e[t]})},show:function(){return this.each(function(){this.style.display=="none"&&(this.style.display="");if(getComputedStyle(this,"").getPropertyValue("display")=="none")this.style.display=I(this.nodeName)})},replaceWith:function(t){return this.before(t).remove()},wrap:function(t){var e=$(t);if(this[0]&&!e)var i=n(t).get(0),r=i.parentNode||this.length>1;return this.each(function(o){n(this).wrapAll(e?t.call(this,o):r?i.cloneNode(true):i)})},wrapAll:function(t){if(this[0]){n(this[0]).before(t=n(t));var e;while((e=t.children()).length)t=e.first();n(t).append(this)}return this},wrapInner:function(t){var e=$(t);return this.each(function(i){var r=n(this),o=r.contents(),s=e?t.call(this,i):t;o.length?o.wrapAll(s):r.append(s)})},unwrap:function(){this.parent().each(function(){n(this).replaceWith(n(this).children())});return this},clone:function(){return this.map(function(){return this.cloneNode(true)})},hide:function(){return this.css("display","none")},toggle:function(e){return this.each(function(){var i=n(this);(e===t?i.css("display")=="none":e)?i.show():i.hide()})},prev:function(t){return n(this.pluck("previousElementSibling")).filter(t||"*")},next:function(t){return n(this.pluck("nextElementSibling")).filter(t||"*")},html:function(t){return 0 in arguments?this.each(function(e){var i=this.innerHTML;n(this).empty().append(U(this,t,e,i))}):0 in this?this[0].innerHTML:null},text:function(t){return 0 in arguments?this.each(function(e){var n=U(this,t,e,this.textContent);this.textContent=n==null?"":""+n}):0 in this?this.pluck("textContent").join(""):null},attr:function(n,i){var r;return typeof n=="string"&&!(1 in arguments)?0 in this&&this[0].nodeType==1&&(r=this[0].getAttribute(n))!=null?r:t:this.each(function(t){if(this.nodeType!==1)return;if(k(n))for(e in n)J(this,e,n[e]);else J(this,n,U(this,i,t,this.getAttribute(n)))})},removeAttr:function(t){return this.each(function(){this.nodeType===1&&t.split(" ").forEach(function(t){J(this,t)},this)})},prop:function(t,e){t=A[t]||t;return 1 in arguments?this.each(function(n){this[t]=U(this,e,n,this[t])}):this[0]&&this[0][t]},removeProp:function(t){t=A[t]||t;return this.each(function(){delete this[t]})},data:function(e,n){var i="data-"+e.replace(g,"-$1").toLowerCase();var r=1 in arguments?this.attr(i,n):this.attr(i);return r!==null?G(r):t},val:function(t){if(0 in arguments){if(t==null)t="";return this.each(function(e){this.value=U(this,t,e,this.value)})}else{return this[0]&&(this[0].multiple?n(this[0]).find("option").filter(function(){return this.selected}).pluck("value"):this[0].value)}},offset:function(t){if(t)return this.each(function(e){var i=n(this),r=U(this,t,e,i.offset()),o=i.offsetParent().offset(),s={top:r.top-o.top,left:r.left-o.left};if(i.css("position")=="static")s["position"]="relative";i.css(s)});if(!this.length)return null;if(u.documentElement!==this[0]&&!n.contains(u.documentElement,this[0]))return{top:0,left:0};var e=this[0].getBoundingClientRect();return{left:e.left+window.pageXOffset,top:e.top+window.pageYOffset,width:Math.round(e.width),height:Math.round(e.height)}},css:function(t,i){if(arguments.length<2){var r=this[0];if(typeof t=="string"){if(!r)return;return r.style[O(t)]||getComputedStyle(r,"").getPropertyValue(t)}else if(L(t)){if(!r)return;var o={};var s=getComputedStyle(r,"");n.each(t,function(t,e){o[e]=r.style[O(e)]||s.getPropertyValue(e)});return o}}var a="";if(Z(t)=="string"){if(!i&&i!==0)this.each(function(){this.style.removeProperty(F(t))});else a=F(t)+":"+q(t,i)}else{for(e in t)if(!t[e]&&t[e]!==0)this.each(function(){this.style.removeProperty(F(e))});else a+=F(e)+":"+q(e,t[e])+";"}return this.each(function(){this.style.cssText+=";"+a})},index:function(t){return t?this.indexOf(n(t)[0]):this.parent().children().indexOf(this[0])},hasClass:function(t){if(!t)return false;return r.some.call(this,function(t){return this.test(W(t))},V(t))},addClass:function(t){if(!t)return this;return this.each(function(e){if(!("className"in this))return;i=[];var r=W(this),o=U(this,t,e,r);o.split(/\s+/g).forEach(function(t){if(!n(this).hasClass(t))i.push(t)},this);i.length&&W(this,r+(r?" ":"")+i.join(" "))})},removeClass:function(e){return this.each(function(n){if(!("className"in this))return;if(e===t)return W(this,"");i=W(this);U(this,e,n,i).split(/\s+/g).forEach(function(t){i=i.replace(V(t)," ")});W(this,i.trim())})},toggleClass:function(e,i){if(!e)return this;return this.each(function(r){var o=n(this),s=U(this,e,r,W(this));s.split(/\s+/g).forEach(function(e){(i===t?!o.hasClass(e):i)?o.addClass(e):o.removeClass(e)})})},scrollTop:function(e){if(!this.length)return;var n="scrollTop"in this[0];if(e===t)return n?this[0].scrollTop:this[0].pageYOffset;return this.each(n?function(){this.scrollTop=e}:function(){this.scrollTo(this.scrollX,e)})},scrollLeft:function(e){if(!this.length)return;var n="scrollLeft"in this[0];if(e===t)return n?this[0].scrollLeft:this[0].pageXOffset;return this.each(n?function(){this.scrollLeft=e}:function(){this.scrollTo(e,this.scrollY)})},position:function(){if(!this.length)return;var t=this[0],e=this.offsetParent(),i=this.offset(),r=m.test(e[0].nodeName)?{top:0,left:0}:e.offset();i.top-=parseFloat(n(t).css("margin-top"))||0;i.left-=parseFloat(n(t).css("margin-left"))||0;r.top+=parseFloat(n(e[0]).css("border-top-width"))||0;r.left+=parseFloat(n(e[0]).css("border-left-width"))||0;return{top:i.top-r.top,left:i.left-r.left}},offsetParent:function(){return this.map(function(){var t=this.offsetParent||u.body;while(t&&!m.test(t.nodeName)&&n(t).css("position")=="static")t=t.offsetParent;return t})}};n.fn.detach=n.fn.remove;["width","height"].forEach(function(e){var i=e.replace(/./,function(t){return t[0].toUpperCase()});n.fn[e]=function(r){var o,s=this[0];if(r===t)return B(s)?s["inner"+i]:j(s)?s.documentElement["scroll"+i]:(o=this.offset())&&o[e];else return this.each(function(t){s=n(this);s.css(e,U(this,r,t,s[e]()))})}});function K(t,e){e(t);for(var n=0,i=t.childNodes.length;n1;if(o.length<1)return this;return this.each(function(t,e){s=r?e:e.parentNode;e=i==0?e.nextSibling:i==1?e.firstChild:i==2?e:null;var f=n.contains(u.documentElement,s);o.forEach(function(t){if(a)t=t.cloneNode(true);else if(!s)return n(t).remove();s.insertBefore(t,e);if(f)K(t,function(t){if(t.nodeName!=null&&t.nodeName.toUpperCase()==="SCRIPT"&&(!t.type||t.type==="text/javascript")&&!t.src){var e=t.ownerDocument?t.ownerDocument.defaultView:window;e["eval"].call(e,t.innerHTML)}})})})};n.fn[r?e+"To":"insert"+(i?"Before":"After")]=function(t){n(t)[e](this);return this}});C.Z.prototype=H.prototype=n.fn;C.uniq=P;C.deserializeValue=G;n.zepto=C;return n}();window.Zepto=Zepto;window.$===undefined&&(window.$=Zepto);(function(t){var e=1,n,i=Array.prototype.slice,r=t.isFunction,o=function(t){return typeof t=="string"},s={},a={},u="onfocusin"in window,f={focus:"focusin",blur:"focusout"},c={mouseenter:"mouseover",mouseleave:"mouseout"};a.click=a.mousedown=a.mouseup=a.mousemove="MouseEvents";function l(t){return t._zid||(t._zid=e++)}function h(t,e,n,i){e=p(e);if(e.ns)var r=d(e.ns);return(s[l(t)]||[]).filter(function(t){return t&&(!e.e||t.e==e.e)&&(!e.ns||r.test(t.ns))&&(!n||l(t.fn)===l(n))&&(!i||t.sel==i)})}function p(t){var e=(""+t).split(".");return{e:e[0],ns:e.slice(1).sort().join(" ")}}function d(t){return new RegExp("(?:^| )"+t.replace(" "," .* ?")+"(?: |$)")}function m(t,e){return t.del&&(!u&&t.e in f)||!!e}function g(t){return c[t]||u&&f[t]||t}function v(e,i,r,o,a,u,f){var h=l(e),d=s[h]||(s[h]=[]);i.split(/\s/).forEach(function(i){if(i=="ready")return t(document).ready(r);var s=p(i);s.fn=r;s.sel=a;if(s.e in c)r=function(e){var n=e.relatedTarget;if(!n||n!==this&&!t.contains(this,n))return s.fn.apply(this,arguments)};s.del=u;var l=u||r;s.proxy=function(t){t=T(t);if(t.isImmediatePropagationStopped())return;t.data=o;var i=l.apply(e,t._args==n?[t]:[t].concat(t._args));if(i===false)t.preventDefault(),t.stopPropagation();return i};s.i=d.length;d.push(s);if("addEventListener"in e)e.addEventListener(g(s.e),s.proxy,m(s,f))})}function y(t,e,n,i,r){var o=l(t);(e||"").split(/\s/).forEach(function(e){h(t,e,n,i).forEach(function(e){delete s[o][e.i];if("removeEventListener"in t)t.removeEventListener(g(e.e),e.proxy,m(e,r))})})}t.event={add:v,remove:y};t.proxy=function(e,n){var s=2 in arguments&&i.call(arguments,2);if(r(e)){var a=function(){return e.apply(n,s?s.concat(i.call(arguments)):arguments)};a._zid=l(e);return a}else if(o(n)){if(s){s.unshift(e[n],e);return t.proxy.apply(null,s)}else{return t.proxy(e[n],e)}}else{throw new TypeError("expected function")}};t.fn.bind=function(t,e,n){return this.on(t,e,n)};t.fn.unbind=function(t,e){return this.off(t,e)};t.fn.one=function(t,e,n,i){return this.on(t,e,n,i,1)};var w=function(){return true},b=function(){return false},E=/^([A-Z]|returnValue$|layer[XY]$|webkitMovement[XY]$)/,x={preventDefault:"isDefaultPrevented",stopImmediatePropagation:"isImmediatePropagationStopped",stopPropagation:"isPropagationStopped"};function T(e,i){if(i||!e.isDefaultPrevented){i||(i=e);t.each(x,function(t,n){var r=i[t];e[t]=function(){this[n]=w;return r&&r.apply(i,arguments)};e[n]=b});try{e.timeStamp||(e.timeStamp=Date.now())}catch(t){}if(i.defaultPrevented!==n?i.defaultPrevented:"returnValue"in i?i.returnValue===false:i.getPreventDefault&&i.getPreventDefault())e.isDefaultPrevented=w}return e}function N(t){var e,i={originalEvent:t};for(e in t)if(!E.test(e)&&t[e]!==n)i[e]=t[e];return T(i,t)}t.fn.delegate=function(t,e,n){return this.on(e,t,n)};t.fn.undelegate=function(t,e,n){return this.off(e,t,n)};t.fn.live=function(e,n){t(document.body).delegate(this.selector,e,n);return this};t.fn.die=function(e,n){t(document.body).undelegate(this.selector,e,n);return this};t.fn.on=function(e,s,a,u,f){var c,l,h=this;if(e&&!o(e)){t.each(e,function(t,e){h.on(t,s,a,e,f)});return h}if(!o(s)&&!r(u)&&u!==false)u=a,a=s,s=n;if(u===n||a===false)u=a,a=n;if(u===false)u=b;return h.each(function(n,r){if(f)c=function(t){y(r,t.type,u);return u.apply(this,arguments)};if(s)l=function(e){var n,o=t(e.target).closest(s,r).get(0);if(o&&o!==r){n=t.extend(N(e),{currentTarget:o,liveFired:r});return(c||u).apply(o,[n].concat(i.call(arguments,1)))}};v(r,e,u,a,s,l||c)})};t.fn.off=function(e,i,s){var a=this;if(e&&!o(e)){t.each(e,function(t,e){a.off(t,i,e)});return a}if(!o(i)&&!r(s)&&s!==false)s=i,i=n;if(s===false)s=b;return a.each(function(){y(this,e,s,i)})};t.fn.trigger=function(e,n){e=o(e)||t.isPlainObject(e)?t.Event(e):T(e);e._args=n;return this.each(function(){if(e.type in f&&typeof this[e.type]=="function")this[e.type]();else if("dispatchEvent"in this)this.dispatchEvent(e);else t(this).triggerHandler(e,n)})};t.fn.triggerHandler=function(e,n){var i,r;this.each(function(s,a){i=N(o(e)?t.Event(e):e);i._args=n;i.target=a;t.each(h(a,e.type||e),function(t,e){r=e.proxy(i);if(i.isImmediatePropagationStopped())return false})});return r};("focusin focusout focus blur load resize scroll unload click dblclick "+"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave "+"change select keydown keypress keyup error").split(" ").forEach(function(e){t.fn[e]=function(t){return 0 in arguments?this.bind(e,t):this.trigger(e)}});t.Event=function(t,e){if(!o(t))e=t,t=e.type;var n=document.createEvent(a[t]||"Events"),i=true;if(e)for(var r in e)r=="bubbles"?i=!!e[r]:n[r]=e[r];n.initEvent(t,i,true);return T(n)}})(Zepto);(function(t,e){var n="",i,r={Webkit:"webkit",Moz:"",O:"o"},o=document.createElement("div"),s=/^((translate|rotate|scale)(X|Y|Z|3d)?|matrix(3d)?|perspective|skew(X|Y)?)$/i,a,u,f,c,l,h,p,d,m,g={};function v(t){return t.replace(/([A-Z])/g,"-$1").toLowerCase()}function y(t){return i?i+t:t.toLowerCase()}if(o.style.transform===e)t.each(r,function(t,r){if(o.style[t+"TransitionProperty"]!==e){n="-"+t.toLowerCase()+"-";i=r;return false}});a=n+"transform";g[u=n+"transition-property"]=g[f=n+"transition-duration"]=g[l=n+"transition-delay"]=g[c=n+"transition-timing-function"]=g[h=n+"animation-name"]=g[p=n+"animation-duration"]=g[m=n+"animation-delay"]=g[d=n+"animation-timing-function"]="";t.fx={off:i===e&&o.style.transitionProperty===e,speeds:{_default:400,fast:200,slow:600},cssPrefix:n,transitionEnd:y("TransitionEnd"),animationEnd:y("AnimationEnd")};t.fn.animate=function(n,i,r,o,s){if(t.isFunction(i))o=i,r=e,i=e;if(t.isFunction(r))o=r,r=e;if(t.isPlainObject(i))r=i.easing,o=i.complete,s=i.delay,i=i.duration;if(i)i=(typeof i=="number"?i:t.fx.speeds[i]||t.fx.speeds._default)/1e3;if(s)s=parseFloat(s)/1e3;return this.anim(n,i,r,o,s)};t.fn.anim=function(n,i,r,o,y){var w,b={},E,x="",T=this,N,C=t.fx.transitionEnd,O=false;if(i===e)i=t.fx.speeds._default/1e3;if(y===e)y=0;if(t.fx.off)i=0;if(typeof n=="string"){b[h]=n;b[p]=i+"s";b[m]=y+"s";b[d]=r||"linear";C=t.fx.animationEnd}else{E=[];for(w in n)if(s.test(w))x+=w+"("+n[w]+") ";else b[w]=n[w],E.push(v(w));if(x)b[a]=x,E.push(a);if(i>0&&typeof n==="object"){b[u]=E.join(", ");b[f]=i+"s";b[l]=y+"s";b[c]=r||"linear"}}N=function(e){if(typeof e!=="undefined"){if(e.target!==e.currentTarget)return;t(e.target).unbind(C,N)}else t(this).unbind(C,N);O=true;t(this).css(g);o&&o.call(this)};if(i>0){this.bind(C,N);setTimeout(function(){if(O)return;N.call(T)},(i+y)*1e3+25)}this.size()&&this.get(0).clientLeft;this.css(b);if(i<=0)setTimeout(function(){T.each(function(){N.call(this)})},0);return this};o=null})(Zepto);(function(t,e){var n=window.document,i=n.documentElement,r=t.fn.show,o=t.fn.hide,s=t.fn.toggle;function a(n,i,r,o,s){if(typeof i=="function"&&!s)s=i,i=e;var a={opacity:r};if(o){a.scale=o;n.css(t.fx.cssPrefix+"transform-origin","0 0")}return n.animate(a,i,null,s)}function u(e,n,i,r){return a(e,n,0,i,function(){o.call(t(this));r&&r.call(this)})}t.fn.show=function(t,n){r.call(this);if(t===e)t=0;else this.css("opacity",0);return a(this,t,1,"1,1",n)};t.fn.hide=function(t,n){if(t===e)return o.call(this);else return u(this,t,"0,0",n)};t.fn.toggle=function(n,i){if(n===e||typeof n=="boolean")return s.call(this,n);else return this.each(function(){var e=t(this);e[e.css("display")=="none"?"show":"hide"](n,i)})};t.fn.fadeTo=function(t,e,n){return a(this,t,e,null,n)};t.fn.fadeIn=function(t,e){var n=this.css("opacity");if(n>0)this.css("opacity",0);else n=1;return r.call(this).fadeTo(t,n,e)};t.fn.fadeOut=function(t,e){return u(this,t,null,e)};t.fn.fadeToggle=function(e,n){return this.each(function(){var i=t(this);i[i.css("opacity")==0||i.css("display")=="none"?"fadeIn":"fadeOut"](e,n)})}})(Zepto);(function(){try{getComputedStyle(undefined)}catch(e){var t=getComputedStyle;window.getComputedStyle=function(e,n){try{return t(e,n)}catch(t){return null}}}})();(function(t){t.fn.slideDown=function(t,e){var n=this;var i=this.css("position");this.show(t);this.css({position:"absolute",visibility:"hidden"});var r=this.css("margin-top");var o=this.css("margin-bottom");var s=this.css("padding-top");var a=this.css("padding-bottom");var u=this.css("height");this.css({position:i,visibility:"visible",overflow:"hidden",height:0,marginTop:0,marginBottom:0,paddingTop:0,paddingBottom:0});this.animate({height:u,marginTop:r,marginBottom:o,paddingTop:s,paddingBottom:a},{duration:t,queue:false,complete:function(){n.css("height",null);if(typeof e=="function"){e(n)}}})};t.fn.slideUp=function(t,e){if(this.height()>0){var n=this;var i=n.css("position");var r=n.css("height");var o=n.css("margin-top");var s=n.css("margin-bottom");var a=n.css("padding-top");var u=n.css("padding-bottom");this.css({visibility:"visible",overflow:"hidden",height:r,marginTop:o,marginBottom:s,paddingTop:a,paddingBottom:u});n.animate({height:0,marginTop:0,marginBottom:0,paddingTop:0,paddingBottom:0},{duration:t,queue:false,complete:function(){n.hide();n.css({visibility:"visible",overflow:"hidden",height:r,marginTop:o,marginBottom:s,paddingTop:a,paddingBottom:u});n.css("height",null);if(typeof e=="function"){e(n)}}})}};t.fn.slideToggle=function(t,e){if(this.height()==0){this.slideDown(t,e)}else{this.slideUp(t,e)}}})(Zepto); -------------------------------------------------------------------------------- /files/htdocs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuttyYang/luci-theme-material/e2b413bbc91cf917267438bb74b11049703f2f61/files/htdocs/logo.png -------------------------------------------------------------------------------- /files/templates/footer.htm: -------------------------------------------------------------------------------- 1 | <%# 2 | Material is a clean HTML5 theme for LuCI. It is based on luci-theme-bootstrap and MUI 3 | 4 | luci-theme-material 5 | Copyright 2015 Lutty Yang 6 | 7 | Have a bug? Please create an issue here on GitHub! 8 | https://github.com/LuttyYang/luci-theme-material/issues 9 | 10 | luci-theme-bootstrap: 11 | Copyright 2008 Steven Barth 12 | Copyright 2008 Jo-Philipp Wich 13 | Copyright 2012 David Menting 14 | 15 | MUI: 16 | https://github.com/muicss/mui 17 | 18 | Licensed to the public under the Apache License 2.0 19 | -%> 20 | 21 | <% 22 | local ver = require "luci.version" 23 | local disp = require "luci.dispatcher" 24 | local request = disp.context.path 25 | local category = request[1] 26 | local tree = disp.node() 27 | local categories = disp.node_childs(tree) 28 | %> 29 | 30 | 41 | 42 | 43 | 44 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /files/templates/header.htm: -------------------------------------------------------------------------------- 1 | <%# 2 | Material is a clean HTML5 theme for LuCI. It is based on luci-theme-bootstrap and MUI 3 | 4 | luci-theme-material 5 | Copyright 2015-2017 Lutty Yang 6 | 7 | Have a bug? Please create an issue here on GitHub! 8 | https://github.com/LuttyYang/luci-theme-material/issues 9 | 10 | luci-theme-bootstrap: 11 | Copyright 2008 Steven Barth 12 | Copyright 2008-2016 Jo-Philipp Wich 13 | Copyright 2012 David Menting 14 | 15 | MUI: 16 | https://github.com/muicss/mui 17 | 18 | Licensed to the public under the Apache License 2.0 19 | -%> 20 | 21 | <% 22 | local sys = require "luci.sys" 23 | local util = require "luci.util" 24 | local http = require "luci.http" 25 | local disp = require "luci.dispatcher" 26 | 27 | local boardinfo = util.ubus("system", "board") 28 | 29 | local request = disp.context.path 30 | local request2 = disp.context.request 31 | 32 | local category = request[1] 33 | local cattree = category and disp.node(category) 34 | 35 | local leaf = request2[#request2] 36 | 37 | local tree = disp.node() 38 | local node = disp.context.dispatched 39 | 40 | local categories = disp.node_childs(tree) 41 | 42 | local c = tree 43 | local i, r 44 | 45 | -- tag all nodes leading to this page 46 | for i, r in ipairs(request) do 47 | if c.nodes and c.nodes[r] then 48 | c = c.nodes[r] 49 | c._menu_selected = true 50 | end 51 | end 52 | 53 | -- send as HTML5 54 | http.prepare_content("text/html") 55 | 56 | local function nodeurl(prefix, name, query) 57 | local u = url(prefix, name) 58 | if query then 59 | u = u .. http.build_querystring(query) 60 | end 61 | return pcdata(u) 62 | end 63 | 64 | local function render_tabmenu(prefix, node, level) 65 | if not level then 66 | level = 1 67 | end 68 | 69 | local childs = disp.node_childs(node) 70 | if #childs > 0 then 71 | if level > 2 then 72 | write('
    ') 73 | end 74 | 75 | local selected_node 76 | local selected_name 77 | local i, v 78 | 79 | for i, v in ipairs(childs) do 80 | local nnode = node.nodes[v] 81 | if nnode._menu_selected then 82 | selected_node = nnode 83 | selected_name = v 84 | end 85 | 86 | if level > 2 then 87 | write('
  • %s
  • ' %{ 88 | v, (nnode._menu_selected or (node.leaf and v == leaf)) and 'active' or '', 89 | nodeurl(prefix, v, nnode.query), 90 | striptags(translate(nnode.title)) 91 | }) 92 | end 93 | end 94 | 95 | if level > 2 then 96 | write('
') 97 | end 98 | 99 | if selected_node then 100 | render_tabmenu(prefix .. "/" .. selected_name, selected_node, level + 1) 101 | end 102 | end 103 | end 104 | 105 | local function render_submenu(prefix, node) 106 | local childs = disp.node_childs(node) 107 | if #childs > 0 then 108 | write('
    ') 109 | 110 | for i, r in ipairs(childs) do 111 | local nnode = node.nodes[r] 112 | local title = pcdata(striptags(translate(nnode.title))) 113 | 114 | write('
  • %s
  • ' %{ 115 | title, 116 | nodeurl(prefix, r, nnode.query), 117 | title 118 | }) 119 | end 120 | 121 | write('
') 122 | end 123 | end 124 | 125 | local function render_topmenu() 126 | local childs = disp.node_childs(cattree) 127 | if #childs > 0 then 128 | write('') 156 | end 157 | end 158 | 159 | local function render_changes() 160 | -- calculate the number of unsaved changes 161 | if tree.nodes[category] and tree.nodes[category].ucidata then 162 | local ucichanges = 0 163 | 164 | for i, j in pairs(require("luci.model.uci").cursor():changes()) do 165 | for k, l in pairs(j) do 166 | for m, n in pairs(l) do 167 | ucichanges = ucichanges + 1; 168 | end 169 | end 170 | end 171 | 172 | if ucichanges > 0 then 173 | write('%s: %d' %{ 174 | url(category, 'uci/changes'), 175 | http.urlencode(http.formvalue('redir') or REQUEST_URI), 176 | translate('Unsaved Changes'), 177 | ucichanges 178 | }) 179 | end 180 | end 181 | end 182 | -%> 183 | 184 | 185 | 186 | 187 | <%=striptags( (boardinfo.hostname or "?") .. ( (node and node.title) and ' - ' .. translate(node.title) or '')) %> - LuCI 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | - LuCI"> 201 | - LuCI"> 202 | 203 | 204 | 205 | 206 | 207 | 208 | <% if node and node.css then %> 209 | 210 | <% end -%> 211 | <% if css then %> 212 | 213 | <% end -%> 214 | 215 | 216 | 217 |
218 |
219 | 220 | <%=boardinfo.hostname or "?"%> 221 |
222 | <% render_changes() %> 223 | 227 |
228 |
229 |
230 |
231 |
Loading...
232 |
233 | <% render_topmenu() %> 234 |
235 |
236 |
237 |
238 |
239 | <%- if luci.sys.process.info("uid") == 0 and luci.sys.user.getuser("root") and not luci.sys.user.getpasswd("root") then -%> 240 |
241 |

<%:No password set!%>

242 | <%:There is no password set on this router. Please configure a root password to protect the web interface and enable SSH.%>
243 | "><%:Go to password configuration...%> 244 |
245 | <%- end -%> 246 | <% if category then render_tabmenu(category, cattree) end %> 247 | 248 | 254 | -------------------------------------------------------------------------------- /screenshot/computer-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuttyYang/luci-theme-material/e2b413bbc91cf917267438bb74b11049703f2f61/screenshot/computer-1.png -------------------------------------------------------------------------------- /screenshot/computer-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuttyYang/luci-theme-material/e2b413bbc91cf917267438bb74b11049703f2f61/screenshot/computer-2.png -------------------------------------------------------------------------------- /screenshot/computer-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuttyYang/luci-theme-material/e2b413bbc91cf917267438bb74b11049703f2f61/screenshot/computer-3.png -------------------------------------------------------------------------------- /screenshot/mobile-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuttyYang/luci-theme-material/e2b413bbc91cf917267438bb74b11049703f2f61/screenshot/mobile-1.png -------------------------------------------------------------------------------- /screenshot/mobile-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuttyYang/luci-theme-material/e2b413bbc91cf917267438bb74b11049703f2f61/screenshot/mobile-2.png -------------------------------------------------------------------------------- /screenshot/mobile-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuttyYang/luci-theme-material/e2b413bbc91cf917267438bb74b11049703f2f61/screenshot/mobile-3.png -------------------------------------------------------------------------------- /src/zepto-luci.js: -------------------------------------------------------------------------------- 1 | // Zepto.js 2 | // (c) 2010-2017 Thomas Fuchs 3 | // Zepto.js may be freely distributed under the MIT license. 4 | 5 | var Zepto = (function() { 6 | var undefined, key, $, classList, emptyArray = [], concat = emptyArray.concat, filter = emptyArray.filter, slice = emptyArray.slice, 7 | document = window.document, 8 | elementDisplay = {}, classCache = {}, 9 | cssNumber = { 'column-count': 1, 'columns': 1, 'font-weight': 1, 'line-height': 1,'opacity': 1, 'z-index': 1, 'zoom': 1 }, 10 | fragmentRE = /^\s*<(\w+|!)[^>]*>/, 11 | singleTagRE = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, 12 | tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, 13 | rootNodeRE = /^(?:body|html)$/i, 14 | capitalRE = /([A-Z])/g, 15 | 16 | // special attributes that should be get/set via method calls 17 | methodAttributes = ['val', 'css', 'html', 'text', 'data', 'width', 'height', 'offset'], 18 | 19 | adjacencyOperators = [ 'after', 'prepend', 'before', 'append' ], 20 | table = document.createElement('table'), 21 | tableRow = document.createElement('tr'), 22 | containers = { 23 | 'tr': document.createElement('tbody'), 24 | 'tbody': table, 'thead': table, 'tfoot': table, 25 | 'td': tableRow, 'th': tableRow, 26 | '*': document.createElement('div') 27 | }, 28 | simpleSelectorRE = /^[\w-]*$/, 29 | class2type = {}, 30 | toString = class2type.toString, 31 | zepto = {}, 32 | camelize, uniq, 33 | tempParent = document.createElement('div'), 34 | propMap = { 35 | 'tabindex': 'tabIndex', 36 | 'readonly': 'readOnly', 37 | 'for': 'htmlFor', 38 | 'class': 'className', 39 | 'maxlength': 'maxLength', 40 | 'cellspacing': 'cellSpacing', 41 | 'cellpadding': 'cellPadding', 42 | 'rowspan': 'rowSpan', 43 | 'colspan': 'colSpan', 44 | 'usemap': 'useMap', 45 | 'frameborder': 'frameBorder', 46 | 'contenteditable': 'contentEditable' 47 | }, 48 | isArray = Array.isArray || 49 | function(object){ return object instanceof Array } 50 | 51 | zepto.matches = function(element, selector) { 52 | if (!selector || !element || element.nodeType !== 1) return false 53 | var matchesSelector = element.matches || element.webkitMatchesSelector || 54 | element.mozMatchesSelector || element.oMatchesSelector || 55 | element.matchesSelector 56 | if (matchesSelector) return matchesSelector.call(element, selector) 57 | // fall back to performing a selector: 58 | var match, parent = element.parentNode, temp = !parent 59 | if (temp) (parent = tempParent).appendChild(element) 60 | match = ~zepto.qsa(parent, selector).indexOf(element) 61 | temp && tempParent.removeChild(element) 62 | return match 63 | } 64 | 65 | function type(obj) { 66 | return obj == null ? String(obj) : 67 | class2type[toString.call(obj)] || "object" 68 | } 69 | 70 | function isFunction(value) { return type(value) == "function" } 71 | function isWindow(obj) { return obj != null && obj == obj.window } 72 | function isDocument(obj) { return obj != null && obj.nodeType == obj.DOCUMENT_NODE } 73 | function isObject(obj) { return type(obj) == "object" } 74 | function isPlainObject(obj) { 75 | return isObject(obj) && !isWindow(obj) && Object.getPrototypeOf(obj) == Object.prototype 76 | } 77 | 78 | function likeArray(obj) { 79 | var length = !!obj && 'length' in obj && obj.length, 80 | type = $.type(obj) 81 | 82 | return 'function' != type && !isWindow(obj) && ( 83 | 'array' == type || length === 0 || 84 | (typeof length == 'number' && length > 0 && (length - 1) in obj) 85 | ) 86 | } 87 | 88 | function compact(array) { return filter.call(array, function(item){ return item != null }) } 89 | function flatten(array) { return array.length > 0 ? $.fn.concat.apply([], array) : array } 90 | camelize = function(str){ return str.replace(/-+(.)?/g, function(match, chr){ return chr ? chr.toUpperCase() : '' }) } 91 | function dasherize(str) { 92 | return str.replace(/::/g, '/') 93 | .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') 94 | .replace(/([a-z\d])([A-Z])/g, '$1_$2') 95 | .replace(/_/g, '-') 96 | .toLowerCase() 97 | } 98 | uniq = function(array){ return filter.call(array, function(item, idx){ return array.indexOf(item) == idx }) } 99 | 100 | function classRE(name) { 101 | return name in classCache ? 102 | classCache[name] : (classCache[name] = new RegExp('(^|\\s)' + name + '(\\s|$)')) 103 | } 104 | 105 | function maybeAddPx(name, value) { 106 | return (typeof value == "number" && !cssNumber[dasherize(name)]) ? value + "px" : value 107 | } 108 | 109 | function defaultDisplay(nodeName) { 110 | var element, display 111 | if (!elementDisplay[nodeName]) { 112 | element = document.createElement(nodeName) 113 | document.body.appendChild(element) 114 | display = getComputedStyle(element, '').getPropertyValue("display") 115 | element.parentNode.removeChild(element) 116 | display == "none" && (display = "block") 117 | elementDisplay[nodeName] = display 118 | } 119 | return elementDisplay[nodeName] 120 | } 121 | 122 | function children(element) { 123 | return 'children' in element ? 124 | slice.call(element.children) : 125 | $.map(element.childNodes, function(node){ if (node.nodeType == 1) return node }) 126 | } 127 | 128 | function Z(dom, selector) { 129 | var i, len = dom ? dom.length : 0 130 | for (i = 0; i < len; i++) this[i] = dom[i] 131 | this.length = len 132 | this.selector = selector || '' 133 | } 134 | 135 | // `$.zepto.fragment` takes a html string and an optional tag name 136 | // to generate DOM nodes from the given html string. 137 | // The generated DOM nodes are returned as an array. 138 | // This function can be overridden in plugins for example to make 139 | // it compatible with browsers that don't support the DOM fully. 140 | zepto.fragment = function(html, name, properties) { 141 | var dom, nodes, container 142 | 143 | // A special case optimization for a single tag 144 | if (singleTagRE.test(html)) dom = $(document.createElement(RegExp.$1)) 145 | 146 | if (!dom) { 147 | if (html.replace) html = html.replace(tagExpanderRE, "<$1>") 148 | if (name === undefined) name = fragmentRE.test(html) && RegExp.$1 149 | if (!(name in containers)) name = '*' 150 | 151 | container = containers[name] 152 | container.innerHTML = '' + html 153 | dom = $.each(slice.call(container.childNodes), function(){ 154 | container.removeChild(this) 155 | }) 156 | } 157 | 158 | if (isPlainObject(properties)) { 159 | nodes = $(dom) 160 | $.each(properties, function(key, value) { 161 | if (methodAttributes.indexOf(key) > -1) nodes[key](value) 162 | else nodes.attr(key, value) 163 | }) 164 | } 165 | 166 | return dom 167 | } 168 | 169 | // `$.zepto.Z` swaps out the prototype of the given `dom` array 170 | // of nodes with `$.fn` and thus supplying all the Zepto functions 171 | // to the array. This method can be overridden in plugins. 172 | zepto.Z = function(dom, selector) { 173 | return new Z(dom, selector) 174 | } 175 | 176 | // `$.zepto.isZ` should return `true` if the given object is a Zepto 177 | // collection. This method can be overridden in plugins. 178 | zepto.isZ = function(object) { 179 | return object instanceof zepto.Z 180 | } 181 | 182 | // `$.zepto.init` is Zepto's counterpart to jQuery's `$.fn.init` and 183 | // takes a CSS selector and an optional context (and handles various 184 | // special cases). 185 | // This method can be overridden in plugins. 186 | zepto.init = function(selector, context) { 187 | var dom 188 | // If nothing given, return an empty Zepto collection 189 | if (!selector) return zepto.Z() 190 | // Optimize for string selectors 191 | else if (typeof selector == 'string') { 192 | selector = selector.trim() 193 | // If it's a html fragment, create nodes from it 194 | // Note: In both Chrome 21 and Firefox 15, DOM error 12 195 | // is thrown if the fragment doesn't begin with < 196 | if (selector[0] == '<' && fragmentRE.test(selector)) 197 | dom = zepto.fragment(selector, RegExp.$1, context), selector = null 198 | // If there's a context, create a collection on that context first, and select 199 | // nodes from there 200 | else if (context !== undefined) return $(context).find(selector) 201 | // If it's a CSS selector, use it to select nodes. 202 | else dom = zepto.qsa(document, selector) 203 | } 204 | // If a function is given, call it when the DOM is ready 205 | else if (isFunction(selector)) return $(document).ready(selector) 206 | // If a Zepto collection is given, just return it 207 | else if (zepto.isZ(selector)) return selector 208 | else { 209 | // normalize array if an array of nodes is given 210 | if (isArray(selector)) dom = compact(selector) 211 | // Wrap DOM nodes. 212 | else if (isObject(selector)) 213 | dom = [selector], selector = null 214 | // If it's a html fragment, create nodes from it 215 | else if (fragmentRE.test(selector)) 216 | dom = zepto.fragment(selector.trim(), RegExp.$1, context), selector = null 217 | // If there's a context, create a collection on that context first, and select 218 | // nodes from there 219 | else if (context !== undefined) return $(context).find(selector) 220 | // And last but no least, if it's a CSS selector, use it to select nodes. 221 | else dom = zepto.qsa(document, selector) 222 | } 223 | // create a new Zepto collection from the nodes found 224 | return zepto.Z(dom, selector) 225 | } 226 | 227 | // `$` will be the base `Zepto` object. When calling this 228 | // function just call `$.zepto.init, which makes the implementation 229 | // details of selecting nodes and creating Zepto collections 230 | // patchable in plugins. 231 | $ = function(selector, context){ 232 | return zepto.init(selector, context) 233 | } 234 | 235 | function extend(target, source, deep) { 236 | for (key in source) 237 | if (deep && (isPlainObject(source[key]) || isArray(source[key]))) { 238 | if (isPlainObject(source[key]) && !isPlainObject(target[key])) 239 | target[key] = {} 240 | if (isArray(source[key]) && !isArray(target[key])) 241 | target[key] = [] 242 | extend(target[key], source[key], deep) 243 | } 244 | else if (source[key] !== undefined) target[key] = source[key] 245 | } 246 | 247 | // Copy all but undefined properties from one or more 248 | // objects to the `target` object. 249 | $.extend = function(target){ 250 | var deep, args = slice.call(arguments, 1) 251 | if (typeof target == 'boolean') { 252 | deep = target 253 | target = args.shift() 254 | } 255 | args.forEach(function(arg){ extend(target, arg, deep) }) 256 | return target 257 | } 258 | 259 | // `$.zepto.qsa` is Zepto's CSS selector implementation which 260 | // uses `document.querySelectorAll` and optimizes for some special cases, like `#id`. 261 | // This method can be overridden in plugins. 262 | zepto.qsa = function(element, selector){ 263 | var found, 264 | maybeID = selector[0] == '#', 265 | maybeClass = !maybeID && selector[0] == '.', 266 | nameOnly = maybeID || maybeClass ? selector.slice(1) : selector, // Ensure that a 1 char tag name still gets checked 267 | isSimple = simpleSelectorRE.test(nameOnly) 268 | return (element.getElementById && isSimple && maybeID) ? // Safari DocumentFragment doesn't have getElementById 269 | ( (found = element.getElementById(nameOnly)) ? [found] : [] ) : 270 | (element.nodeType !== 1 && element.nodeType !== 9 && element.nodeType !== 11) ? [] : 271 | slice.call( 272 | isSimple && !maybeID && element.getElementsByClassName ? // DocumentFragment doesn't have getElementsByClassName/TagName 273 | maybeClass ? element.getElementsByClassName(nameOnly) : // If it's simple, it could be a class 274 | element.getElementsByTagName(selector) : // Or a tag 275 | element.querySelectorAll(selector) // Or it's not simple, and we need to query all 276 | ) 277 | } 278 | 279 | function filtered(nodes, selector) { 280 | return selector == null ? $(nodes) : $(nodes).filter(selector) 281 | } 282 | 283 | $.contains = document.documentElement.contains ? 284 | function(parent, node) { 285 | return parent !== node && parent.contains(node) 286 | } : 287 | function(parent, node) { 288 | while (node && (node = node.parentNode)) 289 | if (node === parent) return true 290 | return false 291 | } 292 | 293 | function funcArg(context, arg, idx, payload) { 294 | return isFunction(arg) ? arg.call(context, idx, payload) : arg 295 | } 296 | 297 | function setAttribute(node, name, value) { 298 | value == null ? node.removeAttribute(name) : node.setAttribute(name, value) 299 | } 300 | 301 | // access className property while respecting SVGAnimatedString 302 | function className(node, value){ 303 | var klass = node.className || '', 304 | svg = klass && klass.baseVal !== undefined 305 | 306 | if (value === undefined) return svg ? klass.baseVal : klass 307 | svg ? (klass.baseVal = value) : (node.className = value) 308 | } 309 | 310 | // "true" => true 311 | // "false" => false 312 | // "null" => null 313 | // "42" => 42 314 | // "42.5" => 42.5 315 | // "08" => "08" 316 | // JSON => parse if valid 317 | // String => self 318 | function deserializeValue(value) { 319 | try { 320 | return value ? 321 | value == "true" || 322 | ( value == "false" ? false : 323 | value == "null" ? null : 324 | +value + "" == value ? +value : 325 | /^[\[\{]/.test(value) ? $.parseJSON(value) : 326 | value ) 327 | : value 328 | } catch(e) { 329 | return value 330 | } 331 | } 332 | 333 | $.type = type 334 | $.isFunction = isFunction 335 | $.isWindow = isWindow 336 | $.isArray = isArray 337 | $.isPlainObject = isPlainObject 338 | 339 | $.isEmptyObject = function(obj) { 340 | var name 341 | for (name in obj) return false 342 | return true 343 | } 344 | 345 | $.isNumeric = function(val) { 346 | var num = Number(val), type = typeof val 347 | return val != null && type != 'boolean' && 348 | (type != 'string' || val.length) && 349 | !isNaN(num) && isFinite(num) || false 350 | } 351 | 352 | $.inArray = function(elem, array, i){ 353 | return emptyArray.indexOf.call(array, elem, i) 354 | } 355 | 356 | $.camelCase = camelize 357 | $.trim = function(str) { 358 | return str == null ? "" : String.prototype.trim.call(str) 359 | } 360 | 361 | // plugin compatibility 362 | $.uuid = 0 363 | $.support = { } 364 | $.expr = { } 365 | $.noop = function() {} 366 | 367 | $.map = function(elements, callback){ 368 | var value, values = [], i, key 369 | if (likeArray(elements)) 370 | for (i = 0; i < elements.length; i++) { 371 | value = callback(elements[i], i) 372 | if (value != null) values.push(value) 373 | } 374 | else 375 | for (key in elements) { 376 | value = callback(elements[key], key) 377 | if (value != null) values.push(value) 378 | } 379 | return flatten(values) 380 | } 381 | 382 | $.each = function(elements, callback){ 383 | var i, key 384 | if (likeArray(elements)) { 385 | for (i = 0; i < elements.length; i++) 386 | if (callback.call(elements[i], i, elements[i]) === false) return elements 387 | } else { 388 | for (key in elements) 389 | if (callback.call(elements[key], key, elements[key]) === false) return elements 390 | } 391 | 392 | return elements 393 | } 394 | 395 | $.grep = function(elements, callback){ 396 | return filter.call(elements, callback) 397 | } 398 | 399 | if (window.JSON) $.parseJSON = JSON.parse 400 | 401 | // Populate the class2type map 402 | $.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { 403 | class2type[ "[object " + name + "]" ] = name.toLowerCase() 404 | }) 405 | 406 | // Define methods that will be available on all 407 | // Zepto collections 408 | $.fn = { 409 | constructor: zepto.Z, 410 | length: 0, 411 | 412 | // Because a collection acts like an array 413 | // copy over these useful array functions. 414 | forEach: emptyArray.forEach, 415 | reduce: emptyArray.reduce, 416 | push: emptyArray.push, 417 | sort: emptyArray.sort, 418 | splice: emptyArray.splice, 419 | indexOf: emptyArray.indexOf, 420 | concat: function(){ 421 | var i, value, args = [] 422 | for (i = 0; i < arguments.length; i++) { 423 | value = arguments[i] 424 | args[i] = zepto.isZ(value) ? value.toArray() : value 425 | } 426 | return concat.apply(zepto.isZ(this) ? this.toArray() : this, args) 427 | }, 428 | 429 | // `map` and `slice` in the jQuery API work differently 430 | // from their array counterparts 431 | map: function(fn){ 432 | return $($.map(this, function(el, i){ return fn.call(el, i, el) })) 433 | }, 434 | slice: function(){ 435 | return $(slice.apply(this, arguments)) 436 | }, 437 | 438 | ready: function(callback){ 439 | // don't use "interactive" on IE <= 10 (it can fired premature) 440 | if (document.readyState === "complete" || 441 | (document.readyState !== "loading" && !document.documentElement.doScroll)) 442 | setTimeout(function(){ callback($) }, 0) 443 | else { 444 | var handler = function() { 445 | document.removeEventListener("DOMContentLoaded", handler, false) 446 | window.removeEventListener("load", handler, false) 447 | callback($) 448 | } 449 | document.addEventListener("DOMContentLoaded", handler, false) 450 | window.addEventListener("load", handler, false) 451 | } 452 | return this 453 | }, 454 | get: function(idx){ 455 | return idx === undefined ? slice.call(this) : this[idx >= 0 ? idx : idx + this.length] 456 | }, 457 | toArray: function(){ return this.get() }, 458 | size: function(){ 459 | return this.length 460 | }, 461 | remove: function(){ 462 | return this.each(function(){ 463 | if (this.parentNode != null) 464 | this.parentNode.removeChild(this) 465 | }) 466 | }, 467 | each: function(callback){ 468 | emptyArray.every.call(this, function(el, idx){ 469 | return callback.call(el, idx, el) !== false 470 | }) 471 | return this 472 | }, 473 | filter: function(selector){ 474 | if (isFunction(selector)) return this.not(this.not(selector)) 475 | return $(filter.call(this, function(element){ 476 | return zepto.matches(element, selector) 477 | })) 478 | }, 479 | add: function(selector,context){ 480 | return $(uniq(this.concat($(selector,context)))) 481 | }, 482 | is: function(selector){ 483 | return this.length > 0 && zepto.matches(this[0], selector) 484 | }, 485 | not: function(selector){ 486 | var nodes=[] 487 | if (isFunction(selector) && selector.call !== undefined) 488 | this.each(function(idx){ 489 | if (!selector.call(this,idx)) nodes.push(this) 490 | }) 491 | else { 492 | var excludes = typeof selector == 'string' ? this.filter(selector) : 493 | (likeArray(selector) && isFunction(selector.item)) ? slice.call(selector) : $(selector) 494 | this.forEach(function(el){ 495 | if (excludes.indexOf(el) < 0) nodes.push(el) 496 | }) 497 | } 498 | return $(nodes) 499 | }, 500 | has: function(selector){ 501 | return this.filter(function(){ 502 | return isObject(selector) ? 503 | $.contains(this, selector) : 504 | $(this).find(selector).size() 505 | }) 506 | }, 507 | eq: function(idx){ 508 | return idx === -1 ? this.slice(idx) : this.slice(idx, + idx + 1) 509 | }, 510 | first: function(){ 511 | var el = this[0] 512 | return el && !isObject(el) ? el : $(el) 513 | }, 514 | last: function(){ 515 | var el = this[this.length - 1] 516 | return el && !isObject(el) ? el : $(el) 517 | }, 518 | find: function(selector){ 519 | var result, $this = this 520 | if (!selector) result = $() 521 | else if (typeof selector == 'object') 522 | result = $(selector).filter(function(){ 523 | var node = this 524 | return emptyArray.some.call($this, function(parent){ 525 | return $.contains(parent, node) 526 | }) 527 | }) 528 | else if (this.length == 1) result = $(zepto.qsa(this[0], selector)) 529 | else result = this.map(function(){ return zepto.qsa(this, selector) }) 530 | return result 531 | }, 532 | closest: function(selector, context){ 533 | var nodes = [], collection = typeof selector == 'object' && $(selector) 534 | this.each(function(_, node){ 535 | while (node && !(collection ? collection.indexOf(node) >= 0 : zepto.matches(node, selector))) 536 | node = node !== context && !isDocument(node) && node.parentNode 537 | if (node && nodes.indexOf(node) < 0) nodes.push(node) 538 | }) 539 | return $(nodes) 540 | }, 541 | parents: function(selector){ 542 | var ancestors = [], nodes = this 543 | while (nodes.length > 0) 544 | nodes = $.map(nodes, function(node){ 545 | if ((node = node.parentNode) && !isDocument(node) && ancestors.indexOf(node) < 0) { 546 | ancestors.push(node) 547 | return node 548 | } 549 | }) 550 | return filtered(ancestors, selector) 551 | }, 552 | parent: function(selector){ 553 | return filtered(uniq(this.pluck('parentNode')), selector) 554 | }, 555 | children: function(selector){ 556 | return filtered(this.map(function(){ return children(this) }), selector) 557 | }, 558 | contents: function() { 559 | return this.map(function() { return this.contentDocument || slice.call(this.childNodes) }) 560 | }, 561 | siblings: function(selector){ 562 | return filtered(this.map(function(i, el){ 563 | return filter.call(children(el.parentNode), function(child){ return child!==el }) 564 | }), selector) 565 | }, 566 | empty: function(){ 567 | return this.each(function(){ this.innerHTML = '' }) 568 | }, 569 | // `pluck` is borrowed from Prototype.js 570 | pluck: function(property){ 571 | return $.map(this, function(el){ return el[property] }) 572 | }, 573 | show: function(){ 574 | return this.each(function(){ 575 | this.style.display == "none" && (this.style.display = '') 576 | if (getComputedStyle(this, '').getPropertyValue("display") == "none") 577 | this.style.display = defaultDisplay(this.nodeName) 578 | }) 579 | }, 580 | replaceWith: function(newContent){ 581 | return this.before(newContent).remove() 582 | }, 583 | wrap: function(structure){ 584 | var func = isFunction(structure) 585 | if (this[0] && !func) 586 | var dom = $(structure).get(0), 587 | clone = dom.parentNode || this.length > 1 588 | 589 | return this.each(function(index){ 590 | $(this).wrapAll( 591 | func ? structure.call(this, index) : 592 | clone ? dom.cloneNode(true) : dom 593 | ) 594 | }) 595 | }, 596 | wrapAll: function(structure){ 597 | if (this[0]) { 598 | $(this[0]).before(structure = $(structure)) 599 | var children 600 | // drill down to the inmost element 601 | while ((children = structure.children()).length) structure = children.first() 602 | $(structure).append(this) 603 | } 604 | return this 605 | }, 606 | wrapInner: function(structure){ 607 | var func = isFunction(structure) 608 | return this.each(function(index){ 609 | var self = $(this), contents = self.contents(), 610 | dom = func ? structure.call(this, index) : structure 611 | contents.length ? contents.wrapAll(dom) : self.append(dom) 612 | }) 613 | }, 614 | unwrap: function(){ 615 | this.parent().each(function(){ 616 | $(this).replaceWith($(this).children()) 617 | }) 618 | return this 619 | }, 620 | clone: function(){ 621 | return this.map(function(){ return this.cloneNode(true) }) 622 | }, 623 | hide: function(){ 624 | return this.css("display", "none") 625 | }, 626 | toggle: function(setting){ 627 | return this.each(function(){ 628 | var el = $(this) 629 | ;(setting === undefined ? el.css("display") == "none" : setting) ? el.show() : el.hide() 630 | }) 631 | }, 632 | prev: function(selector){ return $(this.pluck('previousElementSibling')).filter(selector || '*') }, 633 | next: function(selector){ return $(this.pluck('nextElementSibling')).filter(selector || '*') }, 634 | html: function(html){ 635 | return 0 in arguments ? 636 | this.each(function(idx){ 637 | var originHtml = this.innerHTML 638 | $(this).empty().append( funcArg(this, html, idx, originHtml) ) 639 | }) : 640 | (0 in this ? this[0].innerHTML : null) 641 | }, 642 | text: function(text){ 643 | return 0 in arguments ? 644 | this.each(function(idx){ 645 | var newText = funcArg(this, text, idx, this.textContent) 646 | this.textContent = newText == null ? '' : ''+newText 647 | }) : 648 | (0 in this ? this.pluck('textContent').join("") : null) 649 | }, 650 | attr: function(name, value){ 651 | var result 652 | return (typeof name == 'string' && !(1 in arguments)) ? 653 | (0 in this && this[0].nodeType == 1 && (result = this[0].getAttribute(name)) != null ? result : undefined) : 654 | this.each(function(idx){ 655 | if (this.nodeType !== 1) return 656 | if (isObject(name)) for (key in name) setAttribute(this, key, name[key]) 657 | else setAttribute(this, name, funcArg(this, value, idx, this.getAttribute(name))) 658 | }) 659 | }, 660 | removeAttr: function(name){ 661 | return this.each(function(){ this.nodeType === 1 && name.split(' ').forEach(function(attribute){ 662 | setAttribute(this, attribute) 663 | }, this)}) 664 | }, 665 | prop: function(name, value){ 666 | name = propMap[name] || name 667 | return (1 in arguments) ? 668 | this.each(function(idx){ 669 | this[name] = funcArg(this, value, idx, this[name]) 670 | }) : 671 | (this[0] && this[0][name]) 672 | }, 673 | removeProp: function(name){ 674 | name = propMap[name] || name 675 | return this.each(function(){ delete this[name] }) 676 | }, 677 | data: function(name, value){ 678 | var attrName = 'data-' + name.replace(capitalRE, '-$1').toLowerCase() 679 | 680 | var data = (1 in arguments) ? 681 | this.attr(attrName, value) : 682 | this.attr(attrName) 683 | 684 | return data !== null ? deserializeValue(data) : undefined 685 | }, 686 | val: function(value){ 687 | if (0 in arguments) { 688 | if (value == null) value = "" 689 | return this.each(function(idx){ 690 | this.value = funcArg(this, value, idx, this.value) 691 | }) 692 | } else { 693 | return this[0] && (this[0].multiple ? 694 | $(this[0]).find('option').filter(function(){ return this.selected }).pluck('value') : 695 | this[0].value) 696 | } 697 | }, 698 | offset: function(coordinates){ 699 | if (coordinates) return this.each(function(index){ 700 | var $this = $(this), 701 | coords = funcArg(this, coordinates, index, $this.offset()), 702 | parentOffset = $this.offsetParent().offset(), 703 | props = { 704 | top: coords.top - parentOffset.top, 705 | left: coords.left - parentOffset.left 706 | } 707 | 708 | if ($this.css('position') == 'static') props['position'] = 'relative' 709 | $this.css(props) 710 | }) 711 | if (!this.length) return null 712 | if (document.documentElement !== this[0] && !$.contains(document.documentElement, this[0])) 713 | return {top: 0, left: 0} 714 | var obj = this[0].getBoundingClientRect() 715 | return { 716 | left: obj.left + window.pageXOffset, 717 | top: obj.top + window.pageYOffset, 718 | width: Math.round(obj.width), 719 | height: Math.round(obj.height) 720 | } 721 | }, 722 | css: function(property, value){ 723 | if (arguments.length < 2) { 724 | var element = this[0] 725 | if (typeof property == 'string') { 726 | if (!element) return 727 | return element.style[camelize(property)] || getComputedStyle(element, '').getPropertyValue(property) 728 | } else if (isArray(property)) { 729 | if (!element) return 730 | var props = {} 731 | var computedStyle = getComputedStyle(element, '') 732 | $.each(property, function(_, prop){ 733 | props[prop] = (element.style[camelize(prop)] || computedStyle.getPropertyValue(prop)) 734 | }) 735 | return props 736 | } 737 | } 738 | 739 | var css = '' 740 | if (type(property) == 'string') { 741 | if (!value && value !== 0) 742 | this.each(function(){ this.style.removeProperty(dasherize(property)) }) 743 | else 744 | css = dasherize(property) + ":" + maybeAddPx(property, value) 745 | } else { 746 | for (key in property) 747 | if (!property[key] && property[key] !== 0) 748 | this.each(function(){ this.style.removeProperty(dasherize(key)) }) 749 | else 750 | css += dasherize(key) + ':' + maybeAddPx(key, property[key]) + ';' 751 | } 752 | 753 | return this.each(function(){ this.style.cssText += ';' + css }) 754 | }, 755 | index: function(element){ 756 | return element ? this.indexOf($(element)[0]) : this.parent().children().indexOf(this[0]) 757 | }, 758 | hasClass: function(name){ 759 | if (!name) return false 760 | return emptyArray.some.call(this, function(el){ 761 | return this.test(className(el)) 762 | }, classRE(name)) 763 | }, 764 | addClass: function(name){ 765 | if (!name) return this 766 | return this.each(function(idx){ 767 | if (!('className' in this)) return 768 | classList = [] 769 | var cls = className(this), newName = funcArg(this, name, idx, cls) 770 | newName.split(/\s+/g).forEach(function(klass){ 771 | if (!$(this).hasClass(klass)) classList.push(klass) 772 | }, this) 773 | classList.length && className(this, cls + (cls ? " " : "") + classList.join(" ")) 774 | }) 775 | }, 776 | removeClass: function(name){ 777 | return this.each(function(idx){ 778 | if (!('className' in this)) return 779 | if (name === undefined) return className(this, '') 780 | classList = className(this) 781 | funcArg(this, name, idx, classList).split(/\s+/g).forEach(function(klass){ 782 | classList = classList.replace(classRE(klass), " ") 783 | }) 784 | className(this, classList.trim()) 785 | }) 786 | }, 787 | toggleClass: function(name, when){ 788 | if (!name) return this 789 | return this.each(function(idx){ 790 | var $this = $(this), names = funcArg(this, name, idx, className(this)) 791 | names.split(/\s+/g).forEach(function(klass){ 792 | (when === undefined ? !$this.hasClass(klass) : when) ? 793 | $this.addClass(klass) : $this.removeClass(klass) 794 | }) 795 | }) 796 | }, 797 | scrollTop: function(value){ 798 | if (!this.length) return 799 | var hasScrollTop = 'scrollTop' in this[0] 800 | if (value === undefined) return hasScrollTop ? this[0].scrollTop : this[0].pageYOffset 801 | return this.each(hasScrollTop ? 802 | function(){ this.scrollTop = value } : 803 | function(){ this.scrollTo(this.scrollX, value) }) 804 | }, 805 | scrollLeft: function(value){ 806 | if (!this.length) return 807 | var hasScrollLeft = 'scrollLeft' in this[0] 808 | if (value === undefined) return hasScrollLeft ? this[0].scrollLeft : this[0].pageXOffset 809 | return this.each(hasScrollLeft ? 810 | function(){ this.scrollLeft = value } : 811 | function(){ this.scrollTo(value, this.scrollY) }) 812 | }, 813 | position: function() { 814 | if (!this.length) return 815 | 816 | var elem = this[0], 817 | // Get *real* offsetParent 818 | offsetParent = this.offsetParent(), 819 | // Get correct offsets 820 | offset = this.offset(), 821 | parentOffset = rootNodeRE.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset() 822 | 823 | // Subtract element margins 824 | // note: when an element has margin: auto the offsetLeft and marginLeft 825 | // are the same in Safari causing offset.left to incorrectly be 0 826 | offset.top -= parseFloat( $(elem).css('margin-top') ) || 0 827 | offset.left -= parseFloat( $(elem).css('margin-left') ) || 0 828 | 829 | // Add offsetParent borders 830 | parentOffset.top += parseFloat( $(offsetParent[0]).css('border-top-width') ) || 0 831 | parentOffset.left += parseFloat( $(offsetParent[0]).css('border-left-width') ) || 0 832 | 833 | // Subtract the two offsets 834 | return { 835 | top: offset.top - parentOffset.top, 836 | left: offset.left - parentOffset.left 837 | } 838 | }, 839 | offsetParent: function() { 840 | return this.map(function(){ 841 | var parent = this.offsetParent || document.body 842 | while (parent && !rootNodeRE.test(parent.nodeName) && $(parent).css("position") == "static") 843 | parent = parent.offsetParent 844 | return parent 845 | }) 846 | } 847 | } 848 | 849 | // for now 850 | $.fn.detach = $.fn.remove 851 | 852 | // Generate the `width` and `height` functions 853 | ;['width', 'height'].forEach(function(dimension){ 854 | var dimensionProperty = 855 | dimension.replace(/./, function(m){ return m[0].toUpperCase() }) 856 | 857 | $.fn[dimension] = function(value){ 858 | var offset, el = this[0] 859 | if (value === undefined) return isWindow(el) ? el['inner' + dimensionProperty] : 860 | isDocument(el) ? el.documentElement['scroll' + dimensionProperty] : 861 | (offset = this.offset()) && offset[dimension] 862 | else return this.each(function(idx){ 863 | el = $(this) 864 | el.css(dimension, funcArg(this, value, idx, el[dimension]())) 865 | }) 866 | } 867 | }) 868 | 869 | function traverseNode(node, fun) { 870 | fun(node) 871 | for (var i = 0, len = node.childNodes.length; i < len; i++) 872 | traverseNode(node.childNodes[i], fun) 873 | } 874 | 875 | // Generate the `after`, `prepend`, `before`, `append`, 876 | // `insertAfter`, `insertBefore`, `appendTo`, and `prependTo` methods. 877 | adjacencyOperators.forEach(function(operator, operatorIndex) { 878 | var inside = operatorIndex % 2 //=> prepend, append 879 | 880 | $.fn[operator] = function(){ 881 | // arguments can be nodes, arrays of nodes, Zepto objects and HTML strings 882 | var argType, nodes = $.map(arguments, function(arg) { 883 | var arr = [] 884 | argType = type(arg) 885 | if (argType == "array") { 886 | arg.forEach(function(el) { 887 | if (el.nodeType !== undefined) return arr.push(el) 888 | else if ($.zepto.isZ(el)) return arr = arr.concat(el.get()) 889 | arr = arr.concat(zepto.fragment(el)) 890 | }) 891 | return arr 892 | } 893 | return argType == "object" || arg == null ? 894 | arg : zepto.fragment(arg) 895 | }), 896 | parent, copyByClone = this.length > 1 897 | if (nodes.length < 1) return this 898 | 899 | return this.each(function(_, target){ 900 | parent = inside ? target : target.parentNode 901 | 902 | // convert all methods to a "before" operation 903 | target = operatorIndex == 0 ? target.nextSibling : 904 | operatorIndex == 1 ? target.firstChild : 905 | operatorIndex == 2 ? target : 906 | null 907 | 908 | var parentInDocument = $.contains(document.documentElement, parent) 909 | 910 | nodes.forEach(function(node){ 911 | if (copyByClone) node = node.cloneNode(true) 912 | else if (!parent) return $(node).remove() 913 | 914 | parent.insertBefore(node, target) 915 | if (parentInDocument) traverseNode(node, function(el){ 916 | if (el.nodeName != null && el.nodeName.toUpperCase() === 'SCRIPT' && 917 | (!el.type || el.type === 'text/javascript') && !el.src){ 918 | var target = el.ownerDocument ? el.ownerDocument.defaultView : window 919 | target['eval'].call(target, el.innerHTML) 920 | } 921 | }) 922 | }) 923 | }) 924 | } 925 | 926 | // after => insertAfter 927 | // prepend => prependTo 928 | // before => insertBefore 929 | // append => appendTo 930 | $.fn[inside ? operator+'To' : 'insert'+(operatorIndex ? 'Before' : 'After')] = function(html){ 931 | $(html)[operator](this) 932 | return this 933 | } 934 | }) 935 | 936 | zepto.Z.prototype = Z.prototype = $.fn 937 | 938 | // Export internal API functions in the `$.zepto` namespace 939 | zepto.uniq = uniq 940 | zepto.deserializeValue = deserializeValue 941 | $.zepto = zepto 942 | 943 | return $ 944 | })() 945 | 946 | // If `$` is not yet defined, point it to `Zepto` 947 | window.Zepto = Zepto 948 | window.$ === undefined && (window.$ = Zepto) 949 | // Zepto.js 950 | // (c) 2010-2016 Thomas Fuchs 951 | // Zepto.js may be freely distributed under the MIT license. 952 | 953 | ;(function($){ 954 | var _zid = 1, undefined, 955 | slice = Array.prototype.slice, 956 | isFunction = $.isFunction, 957 | isString = function(obj){ return typeof obj == 'string' }, 958 | handlers = {}, 959 | specialEvents={}, 960 | focusinSupported = 'onfocusin' in window, 961 | focus = { focus: 'focusin', blur: 'focusout' }, 962 | hover = { mouseenter: 'mouseover', mouseleave: 'mouseout' } 963 | 964 | specialEvents.click = specialEvents.mousedown = specialEvents.mouseup = specialEvents.mousemove = 'MouseEvents' 965 | 966 | function zid(element) { 967 | return element._zid || (element._zid = _zid++) 968 | } 969 | function findHandlers(element, event, fn, selector) { 970 | event = parse(event) 971 | if (event.ns) var matcher = matcherFor(event.ns) 972 | return (handlers[zid(element)] || []).filter(function(handler) { 973 | return handler 974 | && (!event.e || handler.e == event.e) 975 | && (!event.ns || matcher.test(handler.ns)) 976 | && (!fn || zid(handler.fn) === zid(fn)) 977 | && (!selector || handler.sel == selector) 978 | }) 979 | } 980 | function parse(event) { 981 | var parts = ('' + event).split('.') 982 | return {e: parts[0], ns: parts.slice(1).sort().join(' ')} 983 | } 984 | function matcherFor(ns) { 985 | return new RegExp('(?:^| )' + ns.replace(' ', ' .* ?') + '(?: |$)') 986 | } 987 | 988 | function eventCapture(handler, captureSetting) { 989 | return handler.del && 990 | (!focusinSupported && (handler.e in focus)) || 991 | !!captureSetting 992 | } 993 | 994 | function realEvent(type) { 995 | return hover[type] || (focusinSupported && focus[type]) || type 996 | } 997 | 998 | function add(element, events, fn, data, selector, delegator, capture){ 999 | var id = zid(element), set = (handlers[id] || (handlers[id] = [])) 1000 | events.split(/\s/).forEach(function(event){ 1001 | if (event == 'ready') return $(document).ready(fn) 1002 | var handler = parse(event) 1003 | handler.fn = fn 1004 | handler.sel = selector 1005 | // emulate mouseenter, mouseleave 1006 | if (handler.e in hover) fn = function(e){ 1007 | var related = e.relatedTarget 1008 | if (!related || (related !== this && !$.contains(this, related))) 1009 | return handler.fn.apply(this, arguments) 1010 | } 1011 | handler.del = delegator 1012 | var callback = delegator || fn 1013 | handler.proxy = function(e){ 1014 | e = compatible(e) 1015 | if (e.isImmediatePropagationStopped()) return 1016 | e.data = data 1017 | var result = callback.apply(element, e._args == undefined ? [e] : [e].concat(e._args)) 1018 | if (result === false) e.preventDefault(), e.stopPropagation() 1019 | return result 1020 | } 1021 | handler.i = set.length 1022 | set.push(handler) 1023 | if ('addEventListener' in element) 1024 | element.addEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture)) 1025 | }) 1026 | } 1027 | function remove(element, events, fn, selector, capture){ 1028 | var id = zid(element) 1029 | ;(events || '').split(/\s/).forEach(function(event){ 1030 | findHandlers(element, event, fn, selector).forEach(function(handler){ 1031 | delete handlers[id][handler.i] 1032 | if ('removeEventListener' in element) 1033 | element.removeEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture)) 1034 | }) 1035 | }) 1036 | } 1037 | 1038 | $.event = { add: add, remove: remove } 1039 | 1040 | $.proxy = function(fn, context) { 1041 | var args = (2 in arguments) && slice.call(arguments, 2) 1042 | if (isFunction(fn)) { 1043 | var proxyFn = function(){ return fn.apply(context, args ? args.concat(slice.call(arguments)) : arguments) } 1044 | proxyFn._zid = zid(fn) 1045 | return proxyFn 1046 | } else if (isString(context)) { 1047 | if (args) { 1048 | args.unshift(fn[context], fn) 1049 | return $.proxy.apply(null, args) 1050 | } else { 1051 | return $.proxy(fn[context], fn) 1052 | } 1053 | } else { 1054 | throw new TypeError("expected function") 1055 | } 1056 | } 1057 | 1058 | $.fn.bind = function(event, data, callback){ 1059 | return this.on(event, data, callback) 1060 | } 1061 | $.fn.unbind = function(event, callback){ 1062 | return this.off(event, callback) 1063 | } 1064 | $.fn.one = function(event, selector, data, callback){ 1065 | return this.on(event, selector, data, callback, 1) 1066 | } 1067 | 1068 | var returnTrue = function(){return true}, 1069 | returnFalse = function(){return false}, 1070 | ignoreProperties = /^([A-Z]|returnValue$|layer[XY]$|webkitMovement[XY]$)/, 1071 | eventMethods = { 1072 | preventDefault: 'isDefaultPrevented', 1073 | stopImmediatePropagation: 'isImmediatePropagationStopped', 1074 | stopPropagation: 'isPropagationStopped' 1075 | } 1076 | 1077 | function compatible(event, source) { 1078 | if (source || !event.isDefaultPrevented) { 1079 | source || (source = event) 1080 | 1081 | $.each(eventMethods, function(name, predicate) { 1082 | var sourceMethod = source[name] 1083 | event[name] = function(){ 1084 | this[predicate] = returnTrue 1085 | return sourceMethod && sourceMethod.apply(source, arguments) 1086 | } 1087 | event[predicate] = returnFalse 1088 | }) 1089 | 1090 | try { 1091 | event.timeStamp || (event.timeStamp = Date.now()) 1092 | } catch (ignored) { } 1093 | 1094 | if (source.defaultPrevented !== undefined ? source.defaultPrevented : 1095 | 'returnValue' in source ? source.returnValue === false : 1096 | source.getPreventDefault && source.getPreventDefault()) 1097 | event.isDefaultPrevented = returnTrue 1098 | } 1099 | return event 1100 | } 1101 | 1102 | function createProxy(event) { 1103 | var key, proxy = { originalEvent: event } 1104 | for (key in event) 1105 | if (!ignoreProperties.test(key) && event[key] !== undefined) proxy[key] = event[key] 1106 | 1107 | return compatible(proxy, event) 1108 | } 1109 | 1110 | $.fn.delegate = function(selector, event, callback){ 1111 | return this.on(event, selector, callback) 1112 | } 1113 | $.fn.undelegate = function(selector, event, callback){ 1114 | return this.off(event, selector, callback) 1115 | } 1116 | 1117 | $.fn.live = function(event, callback){ 1118 | $(document.body).delegate(this.selector, event, callback) 1119 | return this 1120 | } 1121 | $.fn.die = function(event, callback){ 1122 | $(document.body).undelegate(this.selector, event, callback) 1123 | return this 1124 | } 1125 | 1126 | $.fn.on = function(event, selector, data, callback, one){ 1127 | var autoRemove, delegator, $this = this 1128 | if (event && !isString(event)) { 1129 | $.each(event, function(type, fn){ 1130 | $this.on(type, selector, data, fn, one) 1131 | }) 1132 | return $this 1133 | } 1134 | 1135 | if (!isString(selector) && !isFunction(callback) && callback !== false) 1136 | callback = data, data = selector, selector = undefined 1137 | if (callback === undefined || data === false) 1138 | callback = data, data = undefined 1139 | 1140 | if (callback === false) callback = returnFalse 1141 | 1142 | return $this.each(function(_, element){ 1143 | if (one) autoRemove = function(e){ 1144 | remove(element, e.type, callback) 1145 | return callback.apply(this, arguments) 1146 | } 1147 | 1148 | if (selector) delegator = function(e){ 1149 | var evt, match = $(e.target).closest(selector, element).get(0) 1150 | if (match && match !== element) { 1151 | evt = $.extend(createProxy(e), {currentTarget: match, liveFired: element}) 1152 | return (autoRemove || callback).apply(match, [evt].concat(slice.call(arguments, 1))) 1153 | } 1154 | } 1155 | 1156 | add(element, event, callback, data, selector, delegator || autoRemove) 1157 | }) 1158 | } 1159 | $.fn.off = function(event, selector, callback){ 1160 | var $this = this 1161 | if (event && !isString(event)) { 1162 | $.each(event, function(type, fn){ 1163 | $this.off(type, selector, fn) 1164 | }) 1165 | return $this 1166 | } 1167 | 1168 | if (!isString(selector) && !isFunction(callback) && callback !== false) 1169 | callback = selector, selector = undefined 1170 | 1171 | if (callback === false) callback = returnFalse 1172 | 1173 | return $this.each(function(){ 1174 | remove(this, event, callback, selector) 1175 | }) 1176 | } 1177 | 1178 | $.fn.trigger = function(event, args){ 1179 | event = (isString(event) || $.isPlainObject(event)) ? $.Event(event) : compatible(event) 1180 | event._args = args 1181 | return this.each(function(){ 1182 | // handle focus(), blur() by calling them directly 1183 | if (event.type in focus && typeof this[event.type] == "function") this[event.type]() 1184 | // items in the collection might not be DOM elements 1185 | else if ('dispatchEvent' in this) this.dispatchEvent(event) 1186 | else $(this).triggerHandler(event, args) 1187 | }) 1188 | } 1189 | 1190 | // triggers event handlers on current element just as if an event occurred, 1191 | // doesn't trigger an actual event, doesn't bubble 1192 | $.fn.triggerHandler = function(event, args){ 1193 | var e, result 1194 | this.each(function(i, element){ 1195 | e = createProxy(isString(event) ? $.Event(event) : event) 1196 | e._args = args 1197 | e.target = element 1198 | $.each(findHandlers(element, event.type || event), function(i, handler){ 1199 | result = handler.proxy(e) 1200 | if (e.isImmediatePropagationStopped()) return false 1201 | }) 1202 | }) 1203 | return result 1204 | } 1205 | 1206 | // shortcut methods for `.bind(event, fn)` for each event type 1207 | ;('focusin focusout focus blur load resize scroll unload click dblclick '+ 1208 | 'mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave '+ 1209 | 'change select keydown keypress keyup error').split(' ').forEach(function(event) { 1210 | $.fn[event] = function(callback) { 1211 | return (0 in arguments) ? 1212 | this.bind(event, callback) : 1213 | this.trigger(event) 1214 | } 1215 | }) 1216 | 1217 | $.Event = function(type, props) { 1218 | if (!isString(type)) props = type, type = props.type 1219 | var event = document.createEvent(specialEvents[type] || 'Events'), bubbles = true 1220 | if (props) for (var name in props) (name == 'bubbles') ? (bubbles = !!props[name]) : (event[name] = props[name]) 1221 | event.initEvent(type, bubbles, true) 1222 | return compatible(event) 1223 | } 1224 | 1225 | })(Zepto) 1226 | // Zepto.js 1227 | // (c) 2010-2016 Thomas Fuchs 1228 | // Zepto.js may be freely distributed under the MIT license. 1229 | 1230 | ;(function($, undefined){ 1231 | var prefix = '', eventPrefix, 1232 | vendors = { Webkit: 'webkit', Moz: '', O: 'o' }, 1233 | testEl = document.createElement('div'), 1234 | supportedTransforms = /^((translate|rotate|scale)(X|Y|Z|3d)?|matrix(3d)?|perspective|skew(X|Y)?)$/i, 1235 | transform, 1236 | transitionProperty, transitionDuration, transitionTiming, transitionDelay, 1237 | animationName, animationDuration, animationTiming, animationDelay, 1238 | cssReset = {} 1239 | 1240 | function dasherize(str) { return str.replace(/([A-Z])/g, '-$1').toLowerCase() } 1241 | function normalizeEvent(name) { return eventPrefix ? eventPrefix + name : name.toLowerCase() } 1242 | 1243 | if (testEl.style.transform === undefined) $.each(vendors, function(vendor, event){ 1244 | if (testEl.style[vendor + 'TransitionProperty'] !== undefined) { 1245 | prefix = '-' + vendor.toLowerCase() + '-' 1246 | eventPrefix = event 1247 | return false 1248 | } 1249 | }) 1250 | 1251 | transform = prefix + 'transform' 1252 | cssReset[transitionProperty = prefix + 'transition-property'] = 1253 | cssReset[transitionDuration = prefix + 'transition-duration'] = 1254 | cssReset[transitionDelay = prefix + 'transition-delay'] = 1255 | cssReset[transitionTiming = prefix + 'transition-timing-function'] = 1256 | cssReset[animationName = prefix + 'animation-name'] = 1257 | cssReset[animationDuration = prefix + 'animation-duration'] = 1258 | cssReset[animationDelay = prefix + 'animation-delay'] = 1259 | cssReset[animationTiming = prefix + 'animation-timing-function'] = '' 1260 | 1261 | $.fx = { 1262 | off: (eventPrefix === undefined && testEl.style.transitionProperty === undefined), 1263 | speeds: { _default: 400, fast: 200, slow: 600 }, 1264 | cssPrefix: prefix, 1265 | transitionEnd: normalizeEvent('TransitionEnd'), 1266 | animationEnd: normalizeEvent('AnimationEnd') 1267 | } 1268 | 1269 | $.fn.animate = function(properties, duration, ease, callback, delay){ 1270 | if ($.isFunction(duration)) 1271 | callback = duration, ease = undefined, duration = undefined 1272 | if ($.isFunction(ease)) 1273 | callback = ease, ease = undefined 1274 | if ($.isPlainObject(duration)) 1275 | ease = duration.easing, callback = duration.complete, delay = duration.delay, duration = duration.duration 1276 | if (duration) duration = (typeof duration == 'number' ? duration : 1277 | ($.fx.speeds[duration] || $.fx.speeds._default)) / 1000 1278 | if (delay) delay = parseFloat(delay) / 1000 1279 | return this.anim(properties, duration, ease, callback, delay) 1280 | } 1281 | 1282 | $.fn.anim = function(properties, duration, ease, callback, delay){ 1283 | var key, cssValues = {}, cssProperties, transforms = '', 1284 | that = this, wrappedCallback, endEvent = $.fx.transitionEnd, 1285 | fired = false 1286 | 1287 | if (duration === undefined) duration = $.fx.speeds._default / 1000 1288 | if (delay === undefined) delay = 0 1289 | if ($.fx.off) duration = 0 1290 | 1291 | if (typeof properties == 'string') { 1292 | // keyframe animation 1293 | cssValues[animationName] = properties 1294 | cssValues[animationDuration] = duration + 's' 1295 | cssValues[animationDelay] = delay + 's' 1296 | cssValues[animationTiming] = (ease || 'linear') 1297 | endEvent = $.fx.animationEnd 1298 | } else { 1299 | cssProperties = [] 1300 | // CSS transitions 1301 | for (key in properties) 1302 | if (supportedTransforms.test(key)) transforms += key + '(' + properties[key] + ') ' 1303 | else cssValues[key] = properties[key], cssProperties.push(dasherize(key)) 1304 | 1305 | if (transforms) cssValues[transform] = transforms, cssProperties.push(transform) 1306 | if (duration > 0 && typeof properties === 'object') { 1307 | cssValues[transitionProperty] = cssProperties.join(', ') 1308 | cssValues[transitionDuration] = duration + 's' 1309 | cssValues[transitionDelay] = delay + 's' 1310 | cssValues[transitionTiming] = (ease || 'linear') 1311 | } 1312 | } 1313 | 1314 | wrappedCallback = function(event){ 1315 | if (typeof event !== 'undefined') { 1316 | if (event.target !== event.currentTarget) return // makes sure the event didn't bubble from "below" 1317 | $(event.target).unbind(endEvent, wrappedCallback) 1318 | } else 1319 | $(this).unbind(endEvent, wrappedCallback) // triggered by setTimeout 1320 | 1321 | fired = true 1322 | $(this).css(cssReset) 1323 | callback && callback.call(this) 1324 | } 1325 | if (duration > 0){ 1326 | this.bind(endEvent, wrappedCallback) 1327 | // transitionEnd is not always firing on older Android phones 1328 | // so make sure it gets fired 1329 | setTimeout(function(){ 1330 | if (fired) return 1331 | wrappedCallback.call(that) 1332 | }, ((duration + delay) * 1000) + 25) 1333 | } 1334 | 1335 | // trigger page reflow so new elements can animate 1336 | this.size() && this.get(0).clientLeft 1337 | 1338 | this.css(cssValues) 1339 | 1340 | if (duration <= 0) setTimeout(function() { 1341 | that.each(function(){ wrappedCallback.call(this) }) 1342 | }, 0) 1343 | 1344 | return this 1345 | } 1346 | 1347 | testEl = null 1348 | })(Zepto) 1349 | // Zepto.js 1350 | // (c) 2010-2016 Thomas Fuchs 1351 | // Zepto.js may be freely distributed under the MIT license. 1352 | 1353 | ;(function($, undefined){ 1354 | var document = window.document, docElem = document.documentElement, 1355 | origShow = $.fn.show, origHide = $.fn.hide, origToggle = $.fn.toggle 1356 | 1357 | function anim(el, speed, opacity, scale, callback) { 1358 | if (typeof speed == 'function' && !callback) callback = speed, speed = undefined 1359 | var props = { opacity: opacity } 1360 | if (scale) { 1361 | props.scale = scale 1362 | el.css($.fx.cssPrefix + 'transform-origin', '0 0') 1363 | } 1364 | return el.animate(props, speed, null, callback) 1365 | } 1366 | 1367 | function hide(el, speed, scale, callback) { 1368 | return anim(el, speed, 0, scale, function(){ 1369 | origHide.call($(this)) 1370 | callback && callback.call(this) 1371 | }) 1372 | } 1373 | 1374 | $.fn.show = function(speed, callback) { 1375 | origShow.call(this) 1376 | if (speed === undefined) speed = 0 1377 | else this.css('opacity', 0) 1378 | return anim(this, speed, 1, '1,1', callback) 1379 | } 1380 | 1381 | $.fn.hide = function(speed, callback) { 1382 | if (speed === undefined) return origHide.call(this) 1383 | else return hide(this, speed, '0,0', callback) 1384 | } 1385 | 1386 | $.fn.toggle = function(speed, callback) { 1387 | if (speed === undefined || typeof speed == 'boolean') 1388 | return origToggle.call(this, speed) 1389 | else return this.each(function(){ 1390 | var el = $(this) 1391 | el[el.css('display') == 'none' ? 'show' : 'hide'](speed, callback) 1392 | }) 1393 | } 1394 | 1395 | $.fn.fadeTo = function(speed, opacity, callback) { 1396 | return anim(this, speed, opacity, null, callback) 1397 | } 1398 | 1399 | $.fn.fadeIn = function(speed, callback) { 1400 | var target = this.css('opacity') 1401 | if (target > 0) this.css('opacity', 0) 1402 | else target = 1 1403 | return origShow.call(this).fadeTo(speed, target, callback) 1404 | } 1405 | 1406 | $.fn.fadeOut = function(speed, callback) { 1407 | return hide(this, speed, null, callback) 1408 | } 1409 | 1410 | $.fn.fadeToggle = function(speed, callback) { 1411 | return this.each(function(){ 1412 | var el = $(this) 1413 | el[ 1414 | (el.css('opacity') == 0 || el.css('display') == 'none') ? 'fadeIn' : 'fadeOut' 1415 | ](speed, callback) 1416 | }) 1417 | } 1418 | 1419 | })(Zepto) 1420 | // Zepto.js 1421 | // (c) 2010-2016 Thomas Fuchs 1422 | // Zepto.js may be freely distributed under the MIT license. 1423 | 1424 | ;(function(){ 1425 | // getComputedStyle shouldn't freak out when called 1426 | // without a valid element as argument 1427 | try { 1428 | getComputedStyle(undefined) 1429 | } catch(e) { 1430 | var nativeGetComputedStyle = getComputedStyle 1431 | window.getComputedStyle = function(element, pseudoElement){ 1432 | try { 1433 | return nativeGetComputedStyle(element, pseudoElement) 1434 | } catch(e) { 1435 | return null 1436 | } 1437 | } 1438 | } 1439 | })(); 1440 | /* Zepto plugin : slide transition v1.0 */ 1441 | (function($) { 1442 | 1443 | /* SlideDown */ 1444 | $.fn.slideDown = function(duration, cb) { 1445 | 1446 | var self = this; 1447 | 1448 | // get the element position to restore it then 1449 | var position = this.css('position'); 1450 | 1451 | // show element if it is hidden 1452 | this.show(duration); 1453 | 1454 | // place it so it displays as usually but hidden 1455 | this.css({ 1456 | position: 'absolute', 1457 | visibility: 'hidden' 1458 | }); 1459 | 1460 | // get naturally height, margin, padding 1461 | var marginTop = this.css('margin-top'); 1462 | var marginBottom = this.css('margin-bottom'); 1463 | var paddingTop = this.css('padding-top'); 1464 | var paddingBottom = this.css('padding-bottom'); 1465 | var height = this.css('height'); 1466 | 1467 | // set initial css for animation 1468 | this.css({ 1469 | position: position, 1470 | visibility: 'visible', 1471 | overflow: 'hidden', 1472 | height: 0, 1473 | marginTop: 0, 1474 | marginBottom: 0, 1475 | paddingTop: 0, 1476 | paddingBottom: 0 1477 | }); 1478 | 1479 | // animate to gotten height, margin and padding 1480 | this.animate({ 1481 | height: height, 1482 | marginTop: marginTop, 1483 | marginBottom: marginBottom, 1484 | paddingTop: paddingTop, 1485 | paddingBottom: paddingBottom 1486 | }, { 1487 | duration: duration, 1488 | queue: false, 1489 | complete: function() { 1490 | self.css('height', null); 1491 | if (typeof cb == 'function') { 1492 | cb(self); 1493 | } 1494 | } 1495 | }); 1496 | 1497 | }; 1498 | 1499 | /* SlideUp */ 1500 | $.fn.slideUp = function(duration, cb) { 1501 | 1502 | // active the function only if the element is visible 1503 | if (this.height() > 0) { 1504 | 1505 | var target = this; 1506 | 1507 | // get the element position to restore it then 1508 | var position = target.css('position'); 1509 | 1510 | // get the element height, margin and padding to restore them then 1511 | var height = target.css('height'); 1512 | var marginTop = target.css('margin-top'); 1513 | var marginBottom = target.css('margin-bottom'); 1514 | var paddingTop = target.css('padding-top'); 1515 | var paddingBottom = target.css('padding-bottom'); 1516 | 1517 | // set initial css for animation 1518 | this.css({ 1519 | visibility: 'visible', 1520 | overflow: 'hidden', 1521 | height: height, 1522 | marginTop: marginTop, 1523 | marginBottom: marginBottom, 1524 | paddingTop: paddingTop, 1525 | paddingBottom: paddingBottom 1526 | }); 1527 | 1528 | // animate element height, margin and padding to zero 1529 | target.animate({ 1530 | height: 0, 1531 | marginTop: 0, 1532 | marginBottom: 0, 1533 | paddingTop: 0, 1534 | paddingBottom: 0 1535 | }, { 1536 | // callback : restore the element position, height, margin and padding to original values 1537 | duration: duration, 1538 | queue: false, 1539 | complete: function() { 1540 | target.hide(); 1541 | target.css({ 1542 | visibility: 'visible', 1543 | overflow: 'hidden', 1544 | height: height, 1545 | marginTop: marginTop, 1546 | marginBottom: marginBottom, 1547 | paddingTop: paddingTop, 1548 | paddingBottom: paddingBottom 1549 | }); 1550 | target.css('height', null); 1551 | if (typeof cb == 'function') { 1552 | cb(target); 1553 | } 1554 | } 1555 | }); 1556 | } 1557 | }; 1558 | 1559 | /* SlideToggle */ 1560 | $.fn.slideToggle = function(duration, cb) { 1561 | 1562 | // if the element is hidden, slideDown ! 1563 | if (this.height() == 0) { 1564 | this.slideDown(duration, cb); 1565 | } 1566 | // if the element is visible, slideUp ! 1567 | else { 1568 | this.slideUp(duration, cb); 1569 | } 1570 | }; 1571 | 1572 | })(Zepto); --------------------------------------------------------------------------------