1/* masalygin 0.0.2 */ 2 3/* 4* Ð ÑСâ¬Ð ÑР±РÑÐ Ñ: 5* exitTimeout РРРµ Ð ÐСÐРµРÑÐ ÒР° СÐабРÑСâаеСâ СÐабРÑСâаеСâ 6* 7* */ 8 9'use strict'; 10 11(function (factory) { 12 13 if (typeof define === 'function' && define.amd) { 14 15 define(['jquery', 's3/misc/math/0.0.1/s3.math', 's3/misc/eventable/0.0.1/s3.eventable'], factory); 16 17 } else { 18 19 factory(jQuery, s3Math); 20 21 } 22 23})(function ($, math) { 24 25 var points; 26 27 function debug() { 28 29 var menu = this; 30 31 if (!menu.settings.debug && document.location.search.indexOf('test') == -1) { 32 return false; 33 } 34 35 if (!points) { 36 37 points = {}; 38 39 $.each(['a', 'b', 'c'], function (key, value) { 40 41 var attr = { 42 id: 's3-menu-allin-point-' + value, 43 'class': 's3-menu-allin-point', 44 html: value 45 }; 46 47 points[value] = $('<div></div>', attr); 48 49 $(document.body).append(points[value]); 50 51 }); 52 53 } 54 55 $.each(points, function (name, point) { 56 57 point.css({ 58 left: menu.triangle[name].x, 59 top: menu.triangle[name].y 60 }); 61 62 }); 63 64 } 65 66 $.s3MenuAllInTypes = { 67 68 _popup: { 69 70 activate: function (params) { 71 72 var $siblings = params.$item.siblings(); 73 params.$item.addClass(this.settings.activeClass); 74 $siblings.removeClass(this.settings.activeClass); 75 this.hide($siblings.children('ul')); 76 this.show(params.$sub); 77 this.hide(params.$sub.find('ul'));
78 79 }, 80 81 deactivate: function (params) { 82 83 params.$item.removeClass(this.settings.activeClass); 84 this.hide(params.$sub); 85 86 }, 87 88 exit: function () { 89 90 this.$li.removeClass(this.settings.activeClass); 91 this.hide(this.$ul); 92 93 } 94 95 }, 96 97 bottom: function (menu) { 98 99 menu.on('activate', function (params) { 100 101 var $sub = params.$sub; 102 103 if (!$sub.length) { 104 return; 105 } 106 107 var winWidth = $(window).width(); 108 var $item = params.$item; 109 var isHidden = $sub.is(':hidden'); 110 111 $sub.show(); 112 113 var iPos = $item.position(); 114 var iOffset = $item.offset(); 115 var iWidth = $item.width(); 116 var sWidth = $sub.width(); 117 var sPos = {}; 118 119 var b = this.triangle.b; 120 var c = this.triangle.c; 121 122 var left; 123 var revert = false; 124 125 if (params.level === 1) { 126 127 left = iOffset.left + sWidth; 128 129 if (left > winWidth) { 130 131 sPos.left = iPos.left + iWidth - sWidth; 132 133 } else { 134 135 sPos.left = iPos.left; 136 137 } 138 139 sPos.top = iPos.top + $item.height(); 140 141 } else { 142 143 left = iOffset.left + iWidth + sWidth; 144 145 if (left > winWidth) { 146 147 sPos.left = iPos.left - sWidth; 148 revert = true; 149 150 } else { 151 152 sPos.left = iPos.left + iWidth; 153 154 } 155 156 sPos.top = iPos.top; 157 158 } 159 160 $sub.css(sPos); 161 162 var sOffset = $sub.offset(); 163 164 if (params.level === 1) { 165 166 b.y = c.y = sOffset.top;
167 b.x = sOffset.left; 168 c.x = sOffset.left + sWidth; 169 170 } else { 171 172 b.y = sOffset.top; 173 c.y = sOffset.top + $sub.height(); 174 b.x = c.x = revert ? sOffset.left + sWidth : sOffset.left; 175 176 } 177 178 if (isHidden) { 179 $sub.hide(); 180 } 181 182 183 }); 184 185 menu.on(this._popup); 186 187 }, 188 189 top: function (menu) { 190 191 menu.on('activate', function (params) { 192 193 var $sub = params.$sub; 194 195 if (!$sub.length) { 196 return; 197 } 198 199 var winWidth = $(window).width(); 200 var $item = params.$item; 201 var isHidden = $sub.is(':hidden'); 202 203 $sub.show(); 204 205 var iPos = $item.position(); 206 var iOffset = $item.offset(); 207 var iWidth = $item.width(); 208 var iHeight = $item.height(); 209 var sWidth = $sub.width(); 210 var sHeight = $sub.height(); 211 var sPos = {}; 212 213 var b = this.triangle.b; 214 var c = this.triangle.c; 215 216 var left; 217 var revert = false; 218 219 if (params.level === 1) { 220 221 left = iOffset.left + sWidth; 222 223 if (left > winWidth) { 224 225 sPos.left = iPos.left + iWidth - sWidth; 226 227 } else { 228 229 sPos.left = iPos.left; 230 231 } 232 233 sPos.top = iPos.top - sHeight; 234 235 } else { 236 237 left = iOffset.left + iWidth + sWidth; 238 239 if (left > winWidth) { 240 241 sPos.left = iPos.left - sWidth; 242 revert = true; 243 244 } else { 245 246 sPos.left = iPos.left + iWidth; 247 248 } 249 250 sPos.top = iPos.top - sHeight + iHeight; 251 252 } 253 254 $sub.css(sPos); 255 256 var sOffset = $sub.offset(); 257 258 if (params.level === 1) { 259 260 b.y = c.y = sOffset.top + sHeight; 261 b.x = sOffset.left; 262 c.x = sOffset.left + sWidth; 263 264 } else { 265 266 b.y = sOffset.top; 267 c.y = sOffset.top + $sub.height();
268 b.x = c.x = revert ? sOffset.left + sWidth : sOffset.left; 269 270 } 271 272 if (isHidden) { 273 $sub.hide(); 274 } 275 276 }); 277 278 menu.on(this._popup); 279 280 }, 281 282 right: function (menu) { 283 284 menu.on('activate', function (params) { 285 286 var $sub = params.$sub; 287 288 if (!$sub.length) { 289 return; 290 } 291 292 var winWidth = $(window).width(); 293 var $item = params.$item; 294 var isHidden = $sub.is(':hidden'); 295 296 $sub.show(); 297 298 var iPos = $item.position(); 299 var iOffset = $item.offset(); 300 var iWidth = $item.width(); 301 var sWidth = $sub.width(); 302 var sPos = {}; 303 304 var b = this.triangle.b; 305 var c = this.triangle.c; 306 307 var left; 308 var revert = false; 309 310 left = iOffset.left + iWidth + sWidth; 311 312 sPos.top = iPos.top; 313 314 if (left > winWidth) { 315 316 sPos.left = iPos.left - sWidth; 317 revert = true; 318 319 } else { 320 321 sPos.left = iPos.left + iWidth; 322 323 } 324 325 $sub.css(sPos); 326 327 var sOffset = $sub.offset(); 328 329 b.y = sOffset.top; 330 c.y = sOffset.top + $sub.height(); 331 b.x = c.x = revert ? sOffset.left + sWidth : sOffset.left; 332 333 if (isHidden) { 334 $sub.hide(); 335 } 336 337 338 }); 339 340 menu.on(this._popup); 341 342 }, 343 344 left: function (menu) { 345 346 menu.on('activate', function (params) { 347 348 var $sub = params.$sub; 349 350 if (!$sub.length) { 351 return; 352 } 353 354 var $item = params.$item; 355 var isHidden = $sub.is(':hidden'); 356 357 $sub.show(); 358 359 var iPos = $item.position(); 360 var iOffset = $item.offset(); 361 var iWidth = $item.width(); 362 var sWidth = $sub.width(); 363 var sPos = {}; 364 365 var b = this.triangle.b; 366 var c = this.triangle.c; 367 368 var left; 369 var revert = false; 370 371 left = iOffset.left - sWidth; 372 373 sPos.top = iPos.top; 374 375 if (left < 0) { 376 377 sPos.left = iPos.left + sWidth; 378 revert = true; 379 380 } else { 381 382 sPos.left = iPos.left - iWidth; 383 384 } 385 386 $sub.css(sPos); 387 388 var sOffset = $sub.offset(); 389 390 b.y = sOffset.top; 391 c.y = sOffset.top + $sub.height(); 392 b.x = c.x = revert ? sOffset.left : sOffset.left + sWidth; 393 394 if (isHidden) { 395 $sub.hide(); 396 } 397 398 }); 399 400 menu.on(this._popup); 401 402 }, 403 404 dropdown: function (menu, selector) { 405 406 selector = selector || 'a'; 407 408 menu.$el.on({ 409 410 click: function () { 411 412 var $a = $(this); 413 var $item = $a.closest('li'); 414 var $sub = $item.children('ul'); 415 416 if (!$sub.length) { 417 return true; 418 } 419 420 if ($sub.is(':animated')) { 421 return false; 422 } 423 424 if ($sub.is(':hidden')) { 425 426 menu.show($sub, function () { 427 $a.addClass(menu.settings.openClass); 428 }); 429 430 } else { 431 432 menu.hide($sub, function () { 433 $a.removeClass(menu.settings.openClass); 434 }); 435 436 } 437 438 return false; 439 440 } 441 442 }, selector); 443 444 }, 445 446 _dropdownPlus: function(menu, direction) { 447 448 var $el = menu.$el.children('li'); 449 450 var dropDownMenu = $.extend({}, menu, { 451 $el: $el 452 }); 453 454 $.s3MenuAllInTypes.dropdown(dropDownMenu, '> a'); 455 456 $el.children('ul').s3MenuAllIn($.extend({}, menu.settings, {type: direction})); 457 458 }, 459 460 'dropdown+left': function (menu) { 461 this._dropdownPlus(menu, 'left'); 462 }, 463 464 'dropdown+right': function(menu) { 465 this._dropdownPlus(menu, 'right'); 466 } 467 468 }; 469 470 $.fn.s3MenuAllIn = function (settings) { 471 472 settings = $.extend({ 473 474 deviation: 10, 475 type: 'right', 476 exitTimeout: 250, 477 activateTimeout: 0, 478 deactivateTimeout: 100, 479 exclude: 'ul', 480 debug: false, 481 showFn: $.fn.show, 482 showTime: 0, 483 hideFn: $.fn.hide, 484 hideTime: 0, 485 activeClass: 's3-menu-allin-active', 486 hasClass: 's3-menu-allin-has', 487 openClass: 's3-menu-allin-open' 488 489 }, settings); 490 491 return this.each(function() { 492 493 var $el = $(this); 494 495 var menu = $.s3Eventable({ 496 497 settings: settings, 498 triangle: new math.Triangle({}, {}, {}), 499 $el: $el, 500 $li: $el.find('li'), 501 $ul: $el.find('ul'), 502 isBlocked: false, 503 isExit: true, 504 active: {} 505 506 }); 507 508 $.each(['show', 'hide'], function (key, value) { 509 menu[value] = function ($el, callback) { 510 if ($el.length) { 511 $el.stop(true, true); 512 this.settings[value + 'Fn'].call($el, this.settings[value + 'Time'], callback || $.noop); 513 } 514 }; 515 }); 516 517 if (settings.hasClass) { 518 menu.$ul.parent('li').addClass(settings.hasClass); 519 } 520 521 $(document).on('mousemove', function(e) { 522 523 if (menu.isBlocked) { 524 525 var $target = $(e.target); 526 var $item = $target.not(settings.exclude).closest('li'); 527 var hasPoint = menu.triangle.hasPoint({x: e.pageX, y: e.pageY}, settings.deviation); 528 var isMenu = !!menu.$el.has($target).length; 529 var isSub = false; 530 531 if ($item.length && menu.active.$sub) { 532 isSub = $item.closest('ul').get(0) === menu.active.$sub.get(0); 533 } 534 535 if (isMenu) { 536 537 menu.isExit = false; 538 clearTimeout(menu.exitTimeoutId); 539 clearTimeout(menu.deactivateTimeoutId); 540 541 } 542 543 if (isSub) { 544 545 menu.isBlocked = false; 546 $item.trigger('mouseenter'); 547 548 } else if (isMenu) { 549 550 var params = $.extend({}, menu.active); 551 552 if (hasPoint) { 553 554 (function(params) { 555 556 menu.deactivateTimeoutId = setTimeout(function () { 557 558 menu.isBlocked = false; 559 menu.trigger('deactivate', params); 560 $item.trigger('mouseenter'); 561 562 }, settings.deactivateTimeout); 563 564 })(params); 565 566 } else { 567 568 menu.isBlocked = false; 569 menu.trigger('deactivate', params); 570 $item.trigger('mouseenter'); 571 572 } 573 574 } else { 575 576 if (hasPoint) { 577 578 clearTimeout(menu.exitTimeoutId); 579 menu.exitTimeoutId = setTimeout(function () { 580 581 menu.isBlocked = false; 582 menu.trigger('exit'); 583 584 }, settings.deactivateTimeout); 585 586 } else { 587 588// if (!menu.isExit) { 589 590 menu.isExit = true; 591 menu.isBlocked = false; 592 593 clearTimeout(menu.exitTimeoutId); 594 menu.exitTimeoutId = setTimeout(function () { 595 596 if (menu.isExit) { 597 console.log(2); 598 menu.trigger('exit'); 599 } 600 601 602 }, settings.exitTimeout); 603 604// } 605 606 } 607 608 } 609 610 } 611 612 }); 613 614 menu.$el.on({ 615 616 mouseenter: function(e) { 617 618 e.stopPropagation(); 619 menu.isExit = false; 620 621 if (menu.isBlocked) { 622 return; 623 } 624 625 var $item = $(this); 626 var $sub = $item.children('ul'); 627 var $parents = $sub.parentsUntil(menu.$el, 'li'); 628 629 (function(params) { 630 631 clearTimeout(menu.activateTimeoutId); 632 menu.activateTimeoutId = setTimeout(function () { 633 634 if (menu.isExit) { 635 return; 636 } 637 638 menu.isBlocked = false; 639 menu.trigger('activate', params); 640 menu.active = params; 641 642 }, menu.settings.activateTimeout); 643 644 })({ 645 $item: $item, 646 $sub: $sub, 647 $parents: $parents, 648 $ul: $item.parent(), 649 level: $parents.length 650 });
651 652 }, 653 654 mouseleave: function(e) { 655 656 e.stopPropagation(); 657 658 if (menu.isBlocked) { 659 return; 660 } 661 662 menu.triangle.a.x = e.pageX; 663 menu.triangle.a.y = e.pageY; 664 menu.isBlocked = true; 665 666 var $item = $(this); 667 var $sub = $item.children('ul'); 668 var $parents = $sub.parentsUntil(menu.$el, 'li'); 669 670 menu.active = { 671 $item: $item, 672 $sub: $sub, 673 $parents: $parents, 674 $ul: $item.parent(), 675 level: $parents.length 676 }; 677 678 } 679 680 }, 'li'); 681 682 $.s3MenuAllInTypes[settings.type](menu); 683 menu.on('activate', debug); 684 685 }); 686 687 }; 688 689 690});
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.