1Weebly = Weebly || {}; 2 3Weebly.mobile_navigation = (function($) { 4 5 var SLIDE_RIGHT = "SLIDE_RIGHT", 6 SLIDE_DOWN = "SLIDE_DOWN", 7 SLIDE_STATIC = "SLIDE_STATIC", 8 IOS_ADDRESS_BAR_HEIGHT = 60; 9 10 var isOpen = false, 11 isMoving = false, 12 supportsTouch = false, 13 pendingResizeData = null, 14 isiOS = ( navigator.userAgent.match(/(iPad|iPhone|iPod)/i) ? true : false ), 15 supports3D = ('WebKitCSSMatrix' in window && 'm11' in new WebKitCSSMatrix()), 16 supportsTouch = false, 17 menuOffsetY = 0, 18 navStyle = SLIDE_STATIC, 19 $menuWrapper, $menuButton, $menu, $body, supports3D; 20 21 22 /** 23 * Add a css transition 24 * 25 * @param jquery $o object to animate 26 * @param string property a css transitionable property 27 * @param number speed the ms speed of animation 28 * @param function cb callback function after animation completes 29 * @return undefined 30 */ 31 32 var addTransition = function($o, property, speed, cb) { 33 if (!speed) { 34 speed = 500; 35 } 36 37 $o.css({ 38 webkitTransitionDuration : speed + 'ms', 39 webkitTransitionProperty : property, 40 webkitTransitionTimingFunction : 'linear' 41 }); 42 43 var onTransistionEnd = function(e) { 44 $o.off('webkitTransitionEnd', onTransistionEnd); 45 46 $o.css({ 47 webkitTransitionDuration : '', 48 webkitTransitionProperty : '', 49 webkitTransitionTimingFunction : '' 50 }); 51 52 cb(); 53 } 54 $o.on('webkitTransitionEnd', onTransistionEnd); 55 }; 56 57 /** 58 * Utility animate function for css transitions 59 * 60 * @param jquery $o object to animate 61 * @param object from css properties to animate from 62 * @param object to css properties to animate to 63 * @param number speed the ms speed of animation 64 * @param function cb callback function after animation completes 65 * @return undefined 66 */ 67 var animate = function($o, from, to, speed, cb) { 68 if (!speed) { 69 speed = 500; 70 } 71 if (supports3D) { 72 73 $o.css({ webkitTransitionDuration : '0ms' }); 74 $o.css(from); 75 76 setTimeout(function() { 77 addTransition($o, 'all', speed, cb); 78 79 var props = {}; 80 for (property in to) { 81 if (!to.hasOwnProperty(property)) { 82 continue; 83 } 84 props[property] = to[property]; 85 } 86 $o.css(props); 87 }, 0); 88 } else { 89 //jquery.animate isn't working too well here, disable for now 90 to.avoidCSSTransitions = true; 91 $o.animate(to, { 92 duration : speed, 93 complete : cb 94 }); 95 } 96 }; 97 98 /** 99 * Controls the menu effect when a menu button is tapped 100 * 101 * @param event e event handler 102 * @return undefined 103 */ 104 var menuTap = function(e) { 105 var menuHeight = $menuWrapper.outerHeight(), 106 effectStart, effectEnd, fromCSS, toCSS; 107 108 if (isMoving) { 109 return; 110 } 111 112 isOpen = !isOpen; 113 console.log("1 " + isOpen); 114 115 isMoving = true; 116 117 if (isOpen) { 118 console.log("1 " + isOpen); 119 $body.addClass('menu-open'); 120 } 121 122 var cb = function() { 123 isMoving = false; 124 125 if (!isOpen) { 126 $body.removeClass('menu-open'); 127 } 128 }; 129 130 if (navStyle === SLIDE_DOWN) { 131 // '10' here is compensating for the box shadows overlapping 132 // each other between the header and the menu 133 if (!isOpen) { 134 effectStart = 0; 135 effectEnd = -menuHeight - 10; 136 } else { 137 effectStart = -menuHeight - 10; 138 effectEnd = 0; 139 } 140 141 fromCSS = { 142 '-webkit-transform' : 'translate3d( 0px, ' + effectStart + 'px, 0)' 143 }; 144 145 toCSS = { 146 '-webkit-transform': 'translate3d( 0px, ' + effectEnd + 'px, 0)' 147 }; 148 149 if (!supports3D) { 150 fromCSS = { top : menuOffsetY + effectStart + 'px' }; 151 toCSS = { top : menuOffsetY + effectEnd + 'px' }; 152 } 153 154 animate($menuWrapper, fromCSS, toCSS, 300, cb); 155 } else if (navStyle === SLIDE_RIGHT) { 156 var $pageWrapper = $('#wsite-page-wrapper'); 157 158 cb = function() { 159 isMoving = false; 160 161 if (!isOpen) { 162 $body.removeClass('menu-open'); 163 $menuWrapper.hide(); 164 $body.css('overflow-x', 'visible'); 165 $('#wsite-viewport').css({ 166 'overflow' : 'visible', 167 'height' : '' 168 }); 169 $pageWrapper.css({'background' : 'none', 'height' : ''}); 170 $pageWrapper.css({'height' : ''}); 171 } else { 172 $pageWrapper.one('click', closeMenu); 173 } 174 175 // causes flickering if visible 176 if (!isOpen) { 177 var $backgroundImage = (Weebly.mobile) ? $('#w-fixed-bg') : $('.wsite-background'); 178 $backgroundImage.show(); 179 } 180 }; 181 182 var closeMenu = function(e) { 183 if (!isOpen) { 184 return; 185 } 186 187 menuTap(); 188 189 e.stopImmediatePropagation(); 190 e.preventDefault(); 191 $pageWrapper.off('click', closeMenu); 192 }; 193 194 var timeoutLength = 0; 195 196 if (!isOpen) { 197 effectStart = '80%'; 198 effectEnd = '0%'; 199 } else { 200 effectStart = '0%'; 201 effectEnd = '80%'; 202 203 var $backgroundImage = (Weebly.mobile) ? $('#w-fixed-bg') : $('.wsite-background'); 204 if ($backgroundImage.length === 0) { 205 $backgroundImage = $body; 206 } 207 208 var browserPadding = (isiOS) ? IOS_ADDRESS_BAR_HEIGHT : 0; 209 var $windowProxy = $('#w-mobile-phone-screen'); 210 $windowProxy = ($windowProxy.length > 0) ? $windowProxy : $(window); 211 212 $pageWrapper.css({ 213 'background-color' : $backgroundImage.css('background-color') || 'white', 214 'background-image' : $backgroundImage.css('background-image'), 215 'background-position' : $backgroundImage.css('background-position'), 216 'background-size' : $backgroundImage.css('background-size'), 217 'background-repeat' : $backgroundImage.css('background-repeat'), 218 'background-clip' : $backgroundImage.css('background-clip'), 219 'height' : Math.max($backgroundImage.height(), $windowProxy.height() + browserPadding) + 'px' 220 }); 221 222 //eliminate the 'flicker' from waiting for the background image to load 223 if ($backgroundImage.css('background-image').length > 0 && supports3D && supportsTouch) { 224 timeoutLength = 260; 225 } 226 227 // causes flickering if visible 228 if ($backgroundImage !== $body) { 229 $backgroundImage.hide(); 230 } 231 232 $body.css({ 'overflow-x' : 'hidden' }); 233 234 setTimeout(function() { 235 $menuWrapper.show(); 236 }, timeoutLength); 237 } 238 239 fromCSS = { 240 '-webkit-transform': 'translate3d(' + effectStart + ', 0px, 0
240)' 241 }; 242 243 toCSS = { 244 '-webkit-transform': 'translate3d(' + effectEnd + ', 0px, 0)' 245 }; 246 247 if (!supports3D) { 248 fromCSS = { left : effectStart }; 249 toCSS = { left : effectEnd }; 250 } 251 252 setTimeout(function() { 253 animate($pageWrapper, fromCSS, toCSS, 300, cb); 254 }, timeoutLength); 255 } 256 257 }; 258 259 /** 260 * Tweens the menu left or right 261 * 262 * @param jquery $oldSlide the current slide being moved out 263 * @param jquery $newSlide the new slide being moved in 264 * @param bool rightToLeft move to the right if true, left if false 265 * @return undefined 266 */ 267 var tweenMenu = function($oldSlide, $newSlide, rightToLeft) { 268 var $animContainer = $('.wsite-animation-wrap', $menu), 269 sign = (rightToLeft) ? 1 : -1; 270 271 if (isMoving) { 272 return; 273 } 274 isMoving = true; 275 276 var newHeight = Math.max($newSlide.outerHeight(), $oldSlide.outerHeight()); 277 278 $menu.css({ 279 height : newHeight + 'px' 280 }); 281 282 var menuWidth = $menu.width(); 283 284 var toX = -sign * menuWidth + 'px'; 285 286 var fromCSS = { 287 '-webkit-transform': 'translate3d( 0, 0px, 0)' 288 }; 289 290 var toCSS = {
291 '-webkit-transform': 'translate3d(' + toX + ', 0px, 0)' 292 }; 293 294 if (supports3D) { 295 $newSlide.css({ 296 '-webkit-transform': 'translate3d(' + (sign * menuWidth) + 'px, 0px, 0)' 297 }); 298 } else { 299 $newSlide.css({ 300 'left': (sign * menuWidth) + 'px' 301 }); 302 303 fromCSS = { left : 0 }; 304 toCSS = { left : toX }; 305 } 306 307 $newSlide.show(); 308 309 var cb = function() { 310 $oldSlide.hide(); 311 312 var slideHeight = $newSlide.outerHeight(); 313 //reset animation container 314 $menu.css({ height : slideHeight + 'px' }); 315 $animContainer.css(fromCSS); 316 $newSlide.css(fromCSS); 317 318 isMoving = false; 319 }; 320 321 animate($animContainer, fromCSS, toCSS, 300, cb); 322 }; 323 324 /** 325 * Adds a an active state css class so that button presses 326 * can be styled 327 * 328 * @param jquery $element element(s) to add state to 329 * @param string tagName selector to filter dom elemenets 330 * @return undefined 331 */ 332 var addActiveState = function($element, tagName) { 333 $element.on('touchstart', tagName, function(ev) { 334 $(this).addClass('active'); 335 }); 336 $element.on('touchend', tagName, function(ev) { 337 $(this).removeClass('active'); 338 }); 339 }; 340 341 342 /** 343 * Measures the size of the content area to try and place footer 344 * fixed at the bottom of the screen if the screen space is larger 345 * 346 * @return undefined 347 */ 348 var resizeContentWindow = function() { 349 }; 350 351 352 /** 353 * Resizes the vertical height of the mobile menu 354 * 355 * @return undefined 356 */ 357 var resizeMenu = function() { 358 if (!$menu) { 359 return; 360 } 361 var menuHeight = $menu.find('.wsite-menu-slide:visible').outerHeight(); 362 if (menuHeight > 0) { 363 $menu.css({ height : menuHeight + 'px' }); 364 } 365 }; 366 367 /** 368 * Inits the body to detect touch support 369 * 370 * @return undefined 371 */ 372 var initBody = function() { 373 $body = $('body'); 374 375 if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) { 376 $body.removeClass('no-touch'); 377 $body.addClass('touch'); 378 supportsTouch = true; 379 } 380 }; 381 382 /** 383 * Inits the mobile menu structure 384 * 385 * @return undefined 386 */ 387 var initMenu = function() { 388 var $sideMenus = $('#navmobile .wsite-menu-wrap'), 389 $headerUl, $sliderContainer; 390 391 $menuButton = $('#mobile'); 392 $headerUl = $('#navmobile .wsite-menu-default'); 393 394 $headerUl.wrap('<div class="wsite-mobile-menu" />'); 395 $menu = $headerUl.up('.wsite-mobile-menu'); 396 $menuWrapper = $headerUl.up('#navigation'); 397 $menuWrapper = ($menuWrapper.length > 0) ? $menuWrapper : $menu; 398 399 isOpen = false; 400 isMoving = false; 401 402 // if (!Weebly.mobile) { 403 // $menuButton.on('click', menuTap); 404 // } 405 406 var slideCSS = { 407 position: 'absolute', 408 top: '0', 409 left: '0', 410 width: '100%' 411 }; 412 413 // something to select on 414 $headerUl.addClass('wsite-menu-slide').css(slideCSS); 415 $sideMenus.addClass('wsite-menu-slide').css(slideCSS); 416 417 // new css settings can cause jarring while animations render, 418 // set the settings here even though they don't really 'do anything' 419 $headerUl.css({ 'left' : '0'}); 420 if (supports3D) { 421 $headerUl.css({'-webkit-transform': 'translate3d( 0, 0px, 0)'}); 422 } 423 424 $menu.append('<div class="wsite-animation-wrap"></div>'); 425 $sliderContainer = $('.wsite-animation-wrap', $menu); 426 $sliderContainer.css({ position: 'relative' }); 427 if (supports3D) { 428 $sliderContainer.css({'-webkit-backface-visibility': 'hidden'}); 429 } 430 $sliderContainer.append($headerUl); 431 432 $sideMenus.each(function() { 433 var $sideMenu = $(this), 434 $parentAnchor = $sideMenu.prev(), 435 $ul = $sideMenu.children('ul'), 436 $previousMenu = $sideMenu.parents('.wsite-menu-slide'); 437 438 var $backLink = $('<li class="wsite-menu-back-item">' 439 + '<a><span class="wsite-menu-mobile-arrow"></span><span class="wsite-menu-back">Back</span></a>' 440 + '</li>'); 441 $backLink.on('click', function(ev) { 442 tweenMenu($sideMenu, $previousMenu, false); 443 }); 444 445 if ($parentAnchor.attr("href")) { 446 var $sideMenuRoot = $parentAnchor.clone(true, true); 447 var $rootLink = $('<li class="wsite-menu-master-item"></li>').html($sideMenuRoot); 448 } 449 450 $ul.prepend($rootLink); 451 $ul.prepend($backLink); 452 453 $parentAnchor.removeAttr('href').removeAttr('onclick'); 454 $parentAnchor.append('<span class="wsite-menu-mobile-arrow"></span>'); 455 $parentAnchor.on('click', function(ev) { 456 tweenMenu($previousMenu, $sideMenu, true); 457 }); 458 459 $sideMenu.css({ 'left' : '0' }); 460 if (supports3D) { 461 $sideMenu.css({'-webkit-transform': 'translate3d( 0, 0px, 0)'}); 462 } 463 464 $sliderContainer.append($sideMenu); 465 }); 466 467 $menu.css({ 'display' : 'block'}); 468 $menuWrapper.css({ 'display' : 'block'}); 469 resizeMenu(); 470 471 if ($body.hasClass('wsite-menu-dropdown')) { 472 initSlideDown(); 473 } else if ($body.hasClass('wsite-menu-slideright')) { 474 initSlideRight(); 475 } 476 477 // prefer active state classes over html active 478 if (supportsTouch) { 479 addActiveState($('.wsite-home-link')); 480 addActiveState($menuButton); 481 addActiveState($menu, 'a'); 482 } 483 }; 484 485 var initSlideRight = function() { 486 navStyle = SLIDE_RIGHT; 487 488 var $children = $body.contents(); 489 490 $body.prepend('<div id="wsite-viewport" ><div id="wsite-page-wrapper" /></div>'); 491 var $pageWrapper = $('#wsite-page-wrapper'); 492 493 for (var i = 0; i < $children.length; i++) { 494 var child = $children[i]; 495 $pageWrapper[0].appendChild(child); 496 } 497 498 $pageWrapper.css({ 499 'position' : 'relative', 500 'background' : 'none', 501 'z-index' : '3', 502 'left' : '0', 503 'top' : '0' 504 505 }); 506 if (supports3D) { 507 $pageWrapper.css({ 508 '-webkit-backface-visibility': 'hidden', 509 '-webkit-transform' : 'translateZ(0)', 510 '-webkit-transform': 'translate3d( 0, 0, 0)' 511 }); 512 } 513 514 var menuHeight = $pageWrapper.height(); 515 516 $menuWrapper.css({ 517 'top' : '0', 518 'left' : '0', 519 'min-height' : '100%', 520 'width' : '80%', 521 'position' : 'absolute' 522 }); 523 524 $menuWrapper.hide(); 525 526 $body.find('#wsite-viewport').css({ 527 'height' : '', 528 'width' : '100%' 529 }).append($menuWrapper); 530 }; 531 532 var initSlideDown = function() { 533 navStyle = SLIDE_DOWN; 534 535 $menuWrapper.css({ 536 'position' : 'absolute', 537 'width' : '100%', 538 'z-index' : 6 539 }); 540 541 var position = $menuWrapper.position(); 542 menuOffsetY = (position) ? position.top : 0; 543 544 //adjust menu to start behind header and closed 545 var yPos = -$menuWrapper.outerHeight() - 10; 546 if (supports3D) { 547 $menuWrapper.css({
548 '-webkit-transform' : 'translate3d( 0px, ' + yPos + 'px, 0)', 549 '-webkit-backface-visibility' : 'hidden' 550 }); 551 } else { 552 $menuWrapper.css({ 553 'top' : (menuOffsetY + yPos) + 'px' 554 }); 555 } 556 }; 557 558 559 /** 560 * Close the menu 561 * 562 * @return undefined 563 */ 564 var closeMenu = function() { 565 if (isOpen) { 566 menuTap(null); 567 } 568 }; 569 570 var isMenuOpen = function() { 571 return isOpen; 572 }; 573 574 var init = function() { 575 $body = $('#icontent'); 576 $body = ($body.length > 0) ? $body : $('body'); 577 578 // May be able to dump this flag in the future, 579 // but fixing 3d transition flickering issues was in theme css 580 if (!$body.hasClass('wsite-render3d')) { 581 supports3D = false; 582 } 583 584 initMenu(); 585 }; 586 587 if (!Weebly.mobile) { 588 // reset iframe content sizes 589 $(window).on("message", function(event) { 590 if (!event.origin || event.origin.indexOf('weebly.com') === -1) { 591 return; 592 } 593 594 pendingResizeData = event.data; 595 }); 596 } 597 598 // dom ready 599 $(function() { 600 initBody(); 601 init(); 602 603 if (window.FastClick) { 604 FastClick.attach($('.wsite-menu-button')[0]); 605 FastClick.attach($('.wsite-mobile-menu')[0]); 606 } 607 608 }); 609 610 return { 611 init : init, 612 closeMenu : closeMenu, 613 resizeScreen : resizeContentWindow, 614 resizeMenu : resizeMenu, 615 menuTap : menuTap, 616 isMenuOpen : isMenuOpen 617 }; 618 619}(Weebly.jQuery));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.