1 2/*! 3Smallipop (01/17/2015) 4Copyright (c) 2011-2015 Small Improvements (http://www.small-improvements.com) 5 6Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license. 7 8@author Sebastian Helzle ([email protected]) 9 */ 10(function(factory) { 11 if (typeof define === 'function' && define.amd) { 12 return define(['jquery'], factory); 13 } else { 14 return factory(jQuery); 15 } 16})(function($) { 17 var $document, $overlay, $window, classAlignLeft, classAlignRight, classBase, classBottom, classContent, classHint, classInitialized, classInstance, classLeft, classRight, classTheme, classTour, classTourClose, classTourCloseIcon, classTourContent, classTourFooter, classTourNext, classTourOverlay, classTourPrev, classTourProgress, cssAnimationsEnabled, currentTour, dataBeingShown, dataIsTour, dataPopupHovered, dataPosition, dataShown, dataTimerHide, dataTimerShow, dataTriggerHovered, dataXDistance, dataYDistance, dataZIndex, destroy, eventBlur, eventClick, eventFocus, eventKeyUp, eventMouseOut, eventMouseOver, eventResize, eventScroll, eventTouchEnd, fadeInPopup, fadeInPopupFinished, filterAlignmentClass, filterBaseClass, filterClass, forceRefreshPosition, getInstance, getOverlay, getTrigger, hideSmallipop, hideTourOverlay, instances, isElementFixed, killTimers, lastId, lastScrollCheck, nextInstanceId, onWindowKeyUp, onWindowScroll, popupTemplate, queueRefreshPosition, reAlignmentClass, reBaseClass, refreshPosition, refreshQueueTimer, resetTourZIndices, runTour, scrollTimer, setContent, showPopup, showSmallipop, showWhenVisible, sip, touchEnabled, tourClose, tourNext, tourPrev, tourShow, tours, triggerMouseout, triggerMouseover; 18 classBase = 'smallipop'; 19 classHint = classBase + '-hint'; 20 classInstance = classBase + '-instance'; 21 classContent = classBase + '-content'; 22 classLeft = classBase + '-left'; 23 classRight = classBase + '-right'; 24 classBottom = classBase + '-bottom'; 25 classAlignLeft = classBase + '-align-left'; 26 classAlignRight = classBase + '-align-right'; 27 classInitialized = classBase + '-initialized'; 28 classTheme = classBase + '-theme-'; 29 classTour = classBase + '-tour'; 30 classTourContent = classTour + '-content'; 31 classTourOverlay = classTour + '-overlay'; 32 classTourFooter = classTour + '-footer'; 33 classTourCloseIcon = classTour + '-close-icon'; 34 classTourProgress = classTour + '-progress'; 35 classTourClose = classTour + '-close'; 36 classTourPrev = classTour + '-prev'; 37 classTourNext = classTour + '-next'; 38 eventFocus = 'focus.' + classBase; 39 eventClick = 'click.' + classBase; 40 eventBlur = 'blur.' + classBase; 41 eventMouseOut = 'mouseout.' + classBase; 42 eventMouseOver = 'mouseover.' + classBase; 43 eventTouchEnd = 'touchend.' + classBase; 44 eventResize = 'resize.' + classBase; 45 eventScroll = 'scroll.' + classBase; 46 eventKeyUp = 'keyup.' + classBase; 47 dataZIndex = classBase + 'OriginalZIndex'; 48 dataBeingShown = classBase + 'BeingShown'; 49 dataTimerHide = classBase + 'HideDelayTimer'; 50 dataTimerShow = classBase + 'ShowDelayTimer'; 51 dataTriggerHovered = classBase + 'TriggerHovered'; 52 dataPopupHovered = classBase + 'PopupHovered'; 53 dataShown = classBase + 'Shown'; 54 dataPosition = classBase + 'Position'; 55 dataXDistance = classBase + 'XDistance'; 56 dataYDistance = classBase + 'YDistance'; 57 dataIsTour = classBase + 'IsTour'; 58 reAlignmentClass = new RegExp(classBase + '-(align|bottom)\w*', "g"); 59 reBaseClass = new RegExp(classBase + '\w+', "g"); 60 $document = $(document); 61 $window = $(window); 62 $overlay = null; 63 instances = {}; 64 tours = {}; 65 currentTour = null; 66 lastId = 1; 67 nextInstanceId = 1; 68 scrollTimer = null; 69 lastScrollCheck = 0; 70 refreshQueueTimer = null; 71 popupTemplate = "<div class='" + classInstance + "'><div class='" + classContent + "'/></div>"; 72 $.smallipop = sip = { 73 version: '0.6.2', 74 defaults: { 75 autoscrollPadding: 200, 76 contentAnimationSpeed: 150, 77 cssAnimations: { 78 enabled: false, 79 show: 'animated fadeIn', 80 hide: 'animated fadeOut' 81 }, 82 funcEase: 'easeInOutQuad', 83 handleInputs: true, 84 hideDelay: 500, 85 hideTrigger: false,
86 hideOnPopupClick: true, 87 hideOnTriggerClick: true, 88 infoClass: classHint, 89 invertAnimation: false, 90 popupId: '', 91 popupOffset: 31, 92 popupYOffset: 0, 93 popupDistance: 20, 94 popupDelay: 100, 95 popupAnimationSpeed: 200, 96 preferredPosition: 'top', 97 referencedContent: null, 98 theme: 'default', 99 touchSupport: true, 100 tourHighlight: false, 101 tourHighlightColor: '#222', 102 tourHighlightFadeDuration: 200, 103 tourHighlightOpacity: .5, 104 tourHighlightZIndex: 9997, 105 tourNavigationEnabled: true, 106 triggerAnimationSpeed: 150, 107 triggerOnClick: false, 108 onAfterHide: null, 109 onAfterShow: null, 110 onBeforeHide: null, 111 onBeforeShow: null, 112 onTourClose: null, 113 onTourNext: null, 114 onTourPrev: null, 115 windowPadding: 30, 116 labels: { 117 prev: 'Prev', 118 next: 'Next', 119 close: 'Close', 120 of: 'of' 121 } 122 } 123 }; 124 if (!$.easing.easeInOutQuad) { 125 $.easing.easeInOutQuad = function(x, t, b, c, d) { 126 if ((t /= d / 2) < 1) { 127 return c / 2 * t * t + b; 128 } else { 129 return -c / 2 * ((--t) * (t - 2) - 1) + b; 130 } 131 }; 132 } 133 resetTourZIndices = function() { 134 var step, steps, tour, tourTrigger, _results; 135 _results = []; 136 for (tour in tours) { 137 steps = tours[tour]; 138 _results.push((function() { 139 var _i, _len, _results1; 140 _results1 = []; 141 for (_i = 0, _len = steps.length; _i < _len; _i++) { 142 step = steps[_i]; 143 tourTrigger = step.trigger; 144 if (tourTrigger.data(dataZIndex)) { 145 _results1.push(tourTrigger.css('zIndex', tourTrigger.data(dataZIndex))); 146 } else { 147 _results1.push(void 0); 148 } 149 } 150 return _results1; 151 })()); 152 } 153 return _results; 154 }; 155 touchEnabled = typeof Modernizr !== "undefined" && Modernizr !== null ? Modernizr.touch : void 0; 156 cssAnimationsEnabled = typeof Modernizr !== "undefined" && Modernizr !== null ? Modernizr.cssanimations : void 0; 157 getTrigger = function(id) { 158 return $("." + (classBase + id)); 159 }; 160 getOverlay = function() { 161 if (!$overlay) { 162 $overlay = $("<div id='" + classTourOverlay + "'/>").appendTo($('body')).fadeOut(0); 163 } 164 return $overlay; 165 }; 166 hideTourOverlay = function(options) { 167 getOverlay().fadeOut(options.tourHighlightFadeDuration); 168 return resetTourZIndices(); 169 }; 170 hideSmallipop = function(e) { 171 var direction, ignorePopupClick, ignoreTriggerClick, popup, popupData, popupId, shownId, target, trigger, triggerData, triggerIsTarget, triggerOptions, xDistance, yDistance, _base, _ref, _ref1, _results; 172 clearTimeout(scrollTimer); 173 target = (e != null ? e.target : void 0) ? $(e.target) : e; 174 _results = []; 175 for (popupId in instances) { 176 popup = instances[popupId]; 177 popupData = popup.data(); 178 if (!(shownId = popupData[dataShown])) { 179 continue; 180 } 181 trigger = getTrigger(shownId); 182 triggerIsTarget = trigger.is(target); 183 triggerData = trigger.data(classBase); 184 triggerOptions = triggerData.options || sip.defaults; 185 if ((popupData[dataIsTour] || triggerData.isFormElement) && !popup.is(target) && !(triggerIsTarget && popup.is(triggerOptions.popupInstance))) { 186 continue; 187 } 188 if (popupData[dataIsTour]) { 189 currentTour = null; 190 if ((_ref = trigger.data(classBase)) != null) { 191 if (typeof (_base = _ref.options).onTourClose === "function") { 192 _base.onTourClose(); 193 } 194 } 195 hideTourOverlay(triggerOptions); 196 } 197 ignoreTriggerClick = !triggerOptions.hideOnTriggerClick && triggerIsTarget;
198 ignorePopupClick = !triggerOptions.hideOnPopupClick && popup.find(target).length; 199 if (target && trigger.length && ((_ref1 = e != null ? e.type : void 0) === 'click' || _ref1 === 'touchend') && (ignoreTriggerClick || ignorePopupClick)) { 200 continue; 201 } 202 if (shownId && triggerOptions.hideTrigger) { 203 trigger.stop(true).fadeTo(triggerOptions.triggerAnimationSpeed, 1); 204 } 205 popup.data(dataTimerHide, null).data(dataBeingShown, false); 206 if (triggerOptions.cssAnimations.enabled) { 207 popup.removeClass(triggerOptions.cssAnimations.show).addClass(triggerOptions.cssAnimations.hide).data(dataShown, ''); 208 if (triggerOptions.onAfterHide) { 209 _results.push(window.setTimeout(triggerOptions.onAfterHide, triggerOptions.popupAnimationSpeed)); 210 } else { 211 _results.push(void 0); 212 } 213 } else { 214 direction = triggerOptions.invertAnimation ? -1 : 1; 215 xDistance = popupData[dataXDistance] * direction; 216 yDistance = popupData[dataYDistance] * direction; 217 _results.push(popup.stop(true).animate({ 218 top: "-=" + yDistance, 219 left: "+=" + xDistance, 220 opacity: 0 221 }, triggerOptions.popupAnimationSpeed, triggerOptions.funcEase, function() { 222 var self; 223 self = $(this); 224 if (!self.data(dataBeingShown)) { 225 self.css('display', 'none').data(dataShown, ''); 226 } 227 return typeof triggerOptions.onAfterHide === "function" ? triggerOptions.onAfterHide() : void 0; 228 })); 229 } 230 } 231 return _results; 232 }; 233 showSmallipop = function(e) { 234 var triggerData, _ref; 235 triggerData = $(this).data(classBase); 236 if (!triggerData) { 237 return; 238 } 239 if (triggerData.popupInstance.data(dataShown) !== triggerData.id && ((_ref = !triggerData.type) === 'checkbox' || _ref === 'radio')) { 240 if (e != null) { 241 e.preventDefault(); 242 } 243 } 244 return triggerMouseover.call(this); 245 }; 246 killTimers = function(popup) { 247 clearTimeout(popup.data(dataTimerHide)); 248 return clearTimeout(popup.data(dataTimerShow)); 249 }; 250 queueRefreshPosition = function(delay) { 251 if (delay == null) { 252 delay = 50; 253 } 254 clearTimeout(refreshQueueTimer); 255 return refreshQueueTimer = setTimeout(refreshPosition, delay); 256 }; 257 filterClass = function(classStr, re) { 258 if (classStr) { 259 return (classStr.match(re) || []).join(' '); 260 } 261 }; 262 filterAlignmentClass = function(idx, classStr) { 263 return filterClass(classStr, reAlignmentClass); 264 }; 265 filterBaseClass = function(idx, classStr) { 266 return filterClass(classStr, reBaseClass); 267 }; 268 refreshPosition = function(resetTheme) { 269 var isFixed, offset, opacity, options, popup, popupCenter, popupData, popupDistanceBottom, popupDistanceLeft, popupDistanceRight, popupDistanceTop, popupH, popupId, popupOffsetLeft, popupOffsetTop, popupW, popupY, preferredPosition, selfHeight, selfWidth, selfY, shownId, themes, trigger, triggerData, win, winHeight, winScrollLeft, winScrollTop, winWidth, windowPadding, xDistance, xOffset, xOverflow, yDistance, yOffset, yOverflow, _results; 270 if (resetTheme == null) { 271 resetTheme = true; 272 } 273 _results = []; 274 for (popupId in instances) { 275 popup = instances[popupId]; 276 popupData = popup.data(); 277 shownId = popupData[dataShown]; 278 if (!shownId) { 279 continue; 280 } 281 trigger = getTrigger(shownId); 282 triggerData = trigger.data(classBase); 283 options = triggerData.options; 284 popup.removeClass(filterAlignmentClass); 285 if (resetTheme) { 286 themes = classTheme + options.theme.split(' ').join(" " + classTheme); 287 popup.attr('class', "" + classInstance + " " + themes); 288 } 289 win = $(window); 290 xDistance = yDistance = options.popupDistance; 291 xOffset = options.popupOffset; 292 yOffset = options.popupYOffset; 293 isFixed = popup.data(dataPosition) === 'fixed'; 294 popupH = popup.outerHeight(); 295 popupW = popup.outerWidth(); 296 popupCenter = popupW / 2; 297 winWidth = win.width(); 298 winHeight = win.height(); 299 winScrollTop = win.scrollTop(); 300 winScrollLeft = win.scrollLeft(); 301 windowPadding = options.windowPadding; 302 offset = trigger.offset(); 303 selfWidth = trigger.outerWidth(); 304 selfHeight = trigger.outerHeight(); 305 selfY = offset.top - winScrollTop; 306 popupOffsetLeft = offset.left + selfWidth / 2; 307 popupOffsetTop = offset.top - popupH + yOffset; 308 popupY = popupH + options.popupDistance - yOffset; 309 popupDistanceTop = selfY - popupY; 310 popupDistanceBottom = winHeight - selfY - selfHeight - popupY; 311 popupDistanceLeft = offset.left - popupW - xOffset; 312 popupDistanceRight = winWidth - offset.left - selfWidth - popupW; 313 preferredPosition = options.preferredPosition; 314 if (preferredPosition === 'left' || preferredPosition === 'right') { 315 yDistance = 0; 316 popupOffsetTop += selfHeight / 2 + popupH / 2; 317 if ((preferredPosition === 'right' && popupDistanceRight > windowPadding) || popupDistanceLeft < windowPadding) { 318 popup.addClass(classRight); 319 popupOffsetLeft = offset.left + selfWidth + xOffset; 320 } else { 321 popup.addClass(classLeft); 322 popupOffsetLeft = offset.left - popupW - xOffset; 323 xDistance = -xDistance; 324 } 325 } else { 326 xDistance = 0; 327 if (popupOffsetLeft + popupCenter > winWidth - windowPadding) { 328 popupOffsetLeft -= popupCenter * 2 - xOffset; 329 popup.addClass(classAlignLeft); 330 } else if (popupOffsetLeft - popupCenter < windowPadding) { 331 popupOffsetLeft -= xOffset; 332 popup.addClass(classAlignRight); 333 } else { 334 popupOffsetLeft -= popupCenter; 335 } 336 if (popupOffsetLeft < windowPadding) { 337 popupOffsetLeft = windowPadding; 338 } 339 if ((preferredPosition === 'bottom' && popupDistanceBottom > windowPadding) || popupDistanceTop < windowPadding) { 340 yDistance = -yDistance; 341 popupOffsetTop += popupH + selfHeight - 2 * yOffset; 342 popup.addClass(classBottom); 343 } 344 } 345 if (popupH < selfHeight) { 346 yOverflow = popupOffsetTop + popupH + windowPadding - yDistance + yOffset - winScrollTop - winHeight; 347 if (yOverflow > 0) { 348 popupOffsetTop = Math.max(popupOffsetTop - yOverflow - windowPadding, offset.top + yOffset + windowPadding + yDistance); 349 } 350 } 351 if (popupW < selfWidth) { 352 xOverflow = popupOffsetLeft + popupW + windowPadding + xDistance + xOffset - winScrollLeft - winWidth; 353 if (xOverflow > 0) { 354 popupOffsetLeft = Math.max(popupOffsetLeft - xOverflow + windowPadding, offset.left + xOffset + windowPadding - xDistance); 355 } 356 } 357 if (options.hideTrigger) { 358 trigger.stop(true).fadeTo(options.triggerAnimationSpeed, 0); 359 } 360 opacity = 0; 361 if (!popupData[dataBeingShown] || options.cssAnimations.enabled) { 362 popupOffsetTop -= yDistance; 363 popupOffsetLeft += xDistance; 364 xDistance = yDistance = 0; 365 opacity = 1; 366 } 367 if (isFixed) { 368 popupOffsetLeft -= winScrollLeft; 369 popupOffsetTop -= winScrollTop; 370 } 371 popup.data(dataXDistance, xDistance).data(dataYDistance, yDistance).css({ 372 top: popupOffsetTop, 373 left: popupOffsetLeft, 374 display: 'block', 375 opacity: opacity 376 }); 377 _results.push(fadeInPopup(popup, { 378 top: "-=" + yDistance, 379 left: "+=" + xDistance, 380 opacity: 1 381 })); 382 } 383 return _results; 384 }; 385 forceRefreshPosition = function() { 386 return refreshPosition(false); 387 }; 388 fadeInPopup = function(popup, animationTarget) { 389 var options, _ref;
390 options = ((_ref = getTrigger(popup.data(dataShown)).data(classBase)) != null ? _ref.options : void 0) || sip.defaults; 391 if (options.cssAnimations.enabled) { 392 popup.addClass(options.cssAnimations.show); 393 return window.setTimeout(function() { 394 return fadeInPopupFinished(popup, options); 395 }, options.popupAnimationSpeed); 396 } else { 397 return popup.stop(true).animate(animationTarget, options.popupAnimationSpeed, options.funcEase, function() { 398 return fadeInPopupFinished(popup, options); 399 }); 400 } 401 }; 402 fadeInPopupFinished = function(popup, options) { 403 var popupData; 404 popupData = popup.data(); 405 if (popupData[dataBeingShown]) { 406 popup.data(dataBeingShown, false); 407 return typeof options.onAfterShow === "function" ? options.onAfterShow(getTrigger(popupData[dataShown])) : void 0; 408 } 409 }; 410 showPopup = function(trigger, content) { 411 var lastTrigger, lastTriggerOpt, popup, popupContent, popupPosition, shownId, tourOverlay, triggerData, triggerOptions; 412 if (content == null) { 413 content = ''; 414 } 415 triggerData = trigger.data(classBase); 416 triggerOptions = triggerData.options; 417 popup = triggerData.popupInstance; 418 if (!popup.data(dataTriggerHovered)) { 419 return; 420 } 421 shownId = popup.data(dataShown); 422 if (shownId) { 423 lastTrigger = getTrigger(shownId); 424 if (lastTrigger.length) { 425 lastTriggerOpt = lastTrigger.data(classBase).options || sip.defaults; 426 if (lastTriggerOpt.hideTrigger) { 427 lastTrigger.stop(true).fadeTo(lastTriggerOpt.fadeSpeed, 1); 428 } 429 } 430 } 431 if (triggerOptions.tourHighlight && triggerOptions.tourIndex) { 432 tourOverlay = getOverlay().css({ 433 backgroundColor: triggerOptions.tourHighlightColor, 434 zIndex: triggerOptions.tourHighlightZIndex 435 }); 436 resetTourZIndices(); 437 if (trigger.css('position') === 'static') { 438 trigger.css('position', 'relative'); 439 } 440 if (!trigger.data(dataZIndex)) { 441 trigger.data(dataZIndex, trigger.css('zIndex')); 442 } 443 trigger.css('zIndex', triggerOptions.tourHighlightZIndex + 1); 444 tourOverlay.fadeTo(triggerOptions.tourHighlightFadeDuration, triggerOptions.tourHighlightOpacity); 445 } else if ($overlay) { 446 hideTourOverlay(triggerOptions); 447 } 448 popupContent = content || triggerData.hint; 449 if (triggerOptions.referencedContent && !content) { 450 popupContent = $(triggerOptions.referencedContent).clone(true, true) || popupContent; 451 } 452 popupPosition = isElementFixed(trigger) ? 'fixed' : 'absolute'; 453 if (shownId !== triggerData.id) { 454 popup.hide(0); 455 } 456 popup.data(dataBeingShown, true).data(dataShown, triggerData.id).data(dataPosition, popupPosition).find('.' + classContent).empty().append(popupContent); 457 popup.css('position', popupPosition); 458 return queueRefreshPosition(0); 459 }; 460 isElementFixed = function(element) { 461 var elemToCheck; 462 elemToCheck = element; 463 while (elemToCheck.length && elemToCheck[0].nodeName.toUpperCase() !== 'HTML') { 464 if (elemToCheck.css('position') === 'fixed') { 465 return true; 466 } 467 elemToCheck = elemToCheck.parent(); 468 } 469 return false; 470 }; 471 triggerMouseover = function() { 472 var isTrigger, popup, shownId, trigger, triggerData, _base; 473 trigger = popup = $(this); 474 isTrigger = trigger.hasClass(classInitialized); 475 if (!isTrigger) { 476 trigger = getTrigger(popup.data(dataShown)); 477 } 478 if (!trigger.length) { 479 return; 480 } 481 triggerData = trigger.data(classBase); 482 popup = triggerData.popupInstance.data((isTrigger ? dataTriggerHovered : dataPopupHovered), true); 483 killTimers(popup); 484 shownId = popup.data(dataShown); 485 if (shownId !== triggerData.id || popup.css('opacity') === 0) { 486 if (typeof (_base = triggerData.options).onBeforeShow === "function") { 487 _base.onBeforeShow(trigger); 488 } 489 return popup.data(dataTimerShow, setTimeout(function() { 490 return showPopup(trigger); 491 }, triggerData.options.popupDelay)); 492 } 493 }; 494 triggerMouseout = function() { 495 var isTrigger, popup, popupData, trigger, triggerData, _base; 496 trigger = popup = $(this); 497 isTrigger = trigger.hasClass(classInitialized); 498 if (!isTrigger) {
499 trigger = getTrigger(popup.data(dataShown)); 500 } 501 if (!trigger.length) { 502 return; 503 } 504 triggerData = trigger.data(classBase); 505 popup = triggerData.popupInstance.data((isTrigger ? dataTriggerHovered : dataPopupHovered), false); 506 killTimers(popup); 507 popupData = popup.data(); 508 if (!(popupData[dataPopupHovered] || popupData[dataTriggerHovered])) { 509 if (typeof (_base = triggerData.options).onBeforeHide === "function") { 510 _base.onBeforeHide(trigger); 511 } 512 return popup.data(dataTimerHide, setTimeout(function() { 513 return hideSmallipop(popup); 514 }, triggerData.options.hideDelay)); 515 } 516 }; 517 onWindowScroll = function(e) { 518 clearTimeout(scrollTimer); 519 return scrollTimer = setTimeout(forceRefreshPosition, 250); 520 }; 521 setContent = function(trigger, content) { 522 var partOfTour, popupContent, triggerData; 523 if (!(trigger != null ? trigger.length : void 0)) { 524 return; 525 } 526 triggerData = trigger.data(classBase); 527 partOfTour = triggerData.tourTitle; 528 if (partOfTour) { 529 popupContent = triggerData.popupInstance.find('.' + classTourContent); 530 } else { 531 popupContent = triggerData.popupInstance.find('.' + classContent); 532 } 533 if (popupContent.html() !== content) { 534 return popupContent.stop(true).fadeTo(triggerData.options.contentAnimationSpeed, 0, function() { 535 $(this).html(content).fadeTo(triggerData.options.contentAnimationSpeed, 1); 536 return refreshPosition(); 537 }); 538 } 539 }; 540 runTour = function(trigger, step) { 541 var currentTourItems, i, tourTitle, triggerData, _i, _ref; 542 triggerData = trigger.data(classBase); 543 tourTitle = triggerData != null ? triggerData.tourTitle : void 0; 544 if (!(tourTitle && tours[tourTitle])) { 545 return; 546 } 547 tours[tourTitle].sort(function(a, b) { 548 return a.index - b.index; 549 }); 550 if (!(typeof step === 'number' && step % 1 === 0)) { 551 step = -1; 552 } else { 553 step -= 1; 554 } 555 currentTour = tourTitle; 556 currentTourItems = tours[tourTitle]; 557 for (i = _i = 0, _ref = currentTourItems.length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) { 558 if ((step >= 0 && i === step) || (step < 0 && currentTourItems[i].id === triggerData.id)) { 559 return tourShow(tourTitle, i); 560 } 561 } 562 }; 563 tourShow = function(title, index) { 564 var $content, $trigger, currentTourItems, navigation, navigationEnabled, options, triggerData; 565 currentTourItems = tours[title]; 566 if (!currentTourItems) { 567 return; 568 } 569 $trigger = currentTourItems[index].trigger; 570 triggerData = $trigger.data(classBase); 571 options = triggerData.options; 572 navigationEnabled = options.tourNavigationEnabled; 573 navigation = ''; 574 if (navigationEnabled) { 575 navigation += ("<div class='" + classTourProgress + "'>") + ("" + (index + 1) + " " + options.labels.of + " " + currentTourItems.length + "</div>"); 576 if (index > 0) { 577 navigation += "<a href='#' class='" + classTourPrev + "'>" + options.labels.prev + "</a>"; 578 } 579 if (index < currentTourItems.length - 1) { 580 navigation += "<a href='#' class='" + classTourNext + "'>" + options.labels.next + "</a>"; 581 } 582 } 583 if (!navigationEnabled || index === currentTourItems.length - 1) { 584 navigation += "<a href='#' class='" + classTourClose + "'>" + options.labels.close + "</a>"; 585 } 586 $content = $(("<div class='" + classTourContent + "'/>") + ("<a href='#' class='" + classTourCloseIcon + "'>Χ</a>") + ("<div class='" + classTourFooter + "'>" + navigation + "</div>")); 587 $content.eq(0).append(triggerData.hint); 588 killTimers(triggerData.popupInstance); 589 triggerData.popupInstance.data(dataTriggerHovered, true); 590 return showWhenVisible($trigger, $content); 591 }; 592 showWhenVisible = function($trigger, content) { 593 var offset, targetPosition, triggerOptions, windowHeight; 594 targetPosition = $trigger.offset().top; 595 offset = targetPosition - $document.scrollTop(); 596 windowHeight = $window.height(); 597 triggerOptions = $trigger.data(classBase).options; 598 if (!isElementFixed($trigger) && (offset < triggerOptions.autoscrollPadding || offset > windowHeight - triggerOptions.autoscrollPadding)) { 599 return $('html, body').animate({ 600 scrollTop: targetPosition - windowHeight / 2 601 }, 800, 'swing', function() {
602 return showPopup($trigger, content); 603 }); 604 } else { 605 return showPopup($trigger, content); 606 } 607 }; 608 tourNext = function(e) { 609 var $popup, currentTourItems, i, shownId, triggerOptions, _i, _ref; 610 if (e != null) { 611 e.preventDefault(); 612 } 613 currentTourItems = tours[currentTour]; 614 if (!currentTourItems) { 615 return; 616 } 617 $popup = currentTourItems[0].popupInstance; 618 shownId = $popup.data(dataShown) || currentTourItems[0].id; 619 for (i = _i = 0, _ref = currentTourItems.length - 2; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) { 620 if (!(currentTourItems[i].id === shownId)) { 621 continue; 622 } 623 triggerOptions = currentTourItems[i].trigger.data(classBase).options; 624 if (triggerOptions.tourNavigationEnabled) { 625 if (typeof triggerOptions.onTourNext === "function") { 626 triggerOptions.onTourNext(currentTourItems[i + 1].trigger); 627 } 628 return tourShow(currentTour, i + 1); 629 } 630 } 631 }; 632 tourPrev = function(e) { 633 var $popup, currentTourItems, i, shownId, triggerOptions, _i, _ref; 634 if (e != null) { 635 e.preventDefault(); 636 } 637 currentTourItems = tours[currentTour]; 638 if (!currentTourItems) { 639 return; 640 } 641 $popup = currentTourItems[0].popupInstance; 642 shownId = $popup.data(dataShown) || currentTourItems[0].id; 643 for (i = _i = 1, _ref = currentTourItems.length - 1; 1 <= _ref ? _i <= _ref : _i >= _ref; i = 1 <= _ref ? ++_i : --_i) { 644 if (!(currentTourItems[i].id === shownId)) { 645 continue; 646 } 647 triggerOptions = currentTourItems[i].trigger.data(classBase).options; 648 if (triggerOptions.tourNavigationEnabled) { 649 if (typeof triggerOptions.onTourPrev === "function") { 650 triggerOptions.onTourPrev(currentTourItems[i - 1].trigger); 651 } 652 return tourShow(currentTour, i - 1); 653 } 654 } 655 }; 656 tourClose = function(e) { 657 var $popup; 658 if (e != null) { 659 e.preventDefault(); 660 } 661 $popup = $(e.target).closest("." + classInstance); 662 return hideSmallipop($popup); 663 }; 664 destroy = function(instances) { 665 return instances.each(function() { 666 var data, self; 667 self = $(this); 668 data = self.data(classBase); 669 if (data) { 670 return self.unbind("." + classBase).data(classBase, {}).removeClass(filterBaseClass); 671 } 672 }); 673 }; 674 onWindowKeyUp = function(e) { 675 var popup, popupId, targetIsInput, _ref, _results; 676 targetIsInput = (_ref = e != null ? e.target.tagName.toLowerCase() : void 0) === 'input' || _ref === 'textarea'; 677 switch (e.which) { 678 case 27: 679 _results = []; 680 for (popupId in instances) { 681 popup = instances[popupId]; 682 _results.push(hideSmallipop(popup)); 683 } 684 return _results; 685 break; 686 case 37: 687 if (!targetIsInput) { 688 return tourPrev(); 689 } 690 break; 691 case 39: 692 if (!targetIsInput) { 693 return tourNext(); 694 } 695 } 696 }; 697 getInstance = function(id, isTour) { 698 var instance; 699 if (id == null) { 700 id = 'default'; 701 } 702 if (isTour == null) { 703 isTour = false; 704 } 705 if (instances[id]) { 706 return instances[id]; 707 } 708 instance = $(popupTemplate).css('opacity', 0).attr('id', "" + (classBase + nextInstanceId++)).addClass(classInstance).data(dataXDistance, 0).data(dataYDistance, 0).data(dataIsTour, isTour).bind(eventMouseOver, triggerMouseover).bind(eventMouseOut, triggerMouseout); 709 $('body').append(instance); 710 if (isTour) { 711 instance.delegate("." + classTourPrev, eventClick, tourPrev).delegate("." + classTourNext, eventClick, tourNext).delegate("." + classTourClose + ", ." + classTourCloseIcon, eventClick, tourClose); 712 } else { 713 instance.delegate('a', eventClick, hideSmallipop); 714 } 715 if (nextInstanceId === 2) { 716 $document.bind("" + eventClick + " " + eventTouchEnd, hideSmallipop); 717 $window.bind(eventResize, queueRefreshPosition).bind(eventScroll, onWindowScroll).bind(eventKeyUp, onWindowKeyUp); 718 } 719 return instances[id] = instance; 720 }; 721 return $.fn.smallipop = function(options, hint) { 722 var $popup; 723 if (options == null) { 724 options = {}; 725 } 726 if (hint == null) { 727 hint = ''; 728 } 729 if (this.length === 0) { 730 return this; 731 } 732 if (typeof options === 'string') { 733 switch (options.toLowerCase()) { 734 case 'show': 735 showSmallipop.call(this.first().get(0)); 736 break; 737 case 'hide': 738 hideSmallipop(this.first().get(0)); 739 break; 740 case 'destroy': 741 destroy(this); 742 break; 743 case 'tour': 744 runTour(this.first(), hint); 745 break; 746 case 'update': 747 setContent(this.first(), hint); 748 } 749 return this; 750 } 751 options = $.extend(true, {}, sip.defaults, options); 752 if (!cssAnimationsEnabled) { 753 options.cssAnimations.enabled = false;
754 } 755 $popup = getInstance(options.popupId); 756 return this.each(function() { 757 var $objInfo, $self, isFormElement, newId, objHint, option, optionName, tagName, touchTrigger, tourTitle, triggerData, triggerEvents, triggerOptions, triggerPopupInstance, type, value; 758 $self = $(this); 759 tagName = $self[0].tagName.toLowerCase(); 760 type = $self.attr('type'); 761 triggerData = $self.data(); 762 objHint = hint || $self.attr('title'); 763 $objInfo = $("> ." + options.infoClass + ":first", $self); 764 if ($objInfo.length) { 765 objHint = $objInfo.clone(true, true).removeClass(options.infoClass); 766 } 767 if (objHint && !$self.hasClass(classInitialized)) { 768 newId = lastId++; 769 triggerEvents = {}; 770 triggerPopupInstance = $popup; 771 triggerOptions = $.extend(true, {}, options); 772 if (typeof triggerData[classBase] === 'object') { 773 $.extend(true, triggerOptions, triggerData[classBase]); 774 } 775 for (option in triggerData) { 776 value = triggerData[option]; 777 if (!(option.indexOf(classBase) >= 0)) { 778 continue; 779 } 780 optionName = option.replace(classBase, ''); 781 if (optionName) { 782 optionName = optionName.substr(0, 1).toLowerCase() + optionName.substr(1); 783 triggerOptions[optionName] = value; 784 } 785 } 786 isFormElement = triggerOptions.handleInputs && (tagName === 'input' || tagName === 'select' || tagName === 'textarea'); 787 if (triggerOptions.tourIndex) { 788 tourTitle = triggerOptions.tourTitle || 'defaultTour'; 789 triggerOptions.hideOnTriggerClick = triggerOptions.hideOnPopupCl
789ick = false; 790 triggerPopupInstance = getInstance(tourTitle, true); 791 if (!tours[tourTitle]) { 792 tours[tourTitle] = []; 793 } 794 tours[tourTitle].push({ 795 index: triggerOptions.tourIndex || 0, 796 id: newId, 797 trigger: $self, 798 popupInstance: triggerPopupInstance 799 }); 800 } else { 801 touchTrigger = triggerOptions.touchSupport && touchEnabled; 802 if (isFormElement) { 803 triggerOptions.hideOnTriggerClick = false; 804 triggerEvents[eventFocus] = triggerMouseover; 805 triggerEvents[eventBlur] = triggerMouseout; 806 } else if (!touchTrigger) { 807 triggerEvents[eventMouseOut] = triggerMouseout; 808 } 809 if (triggerOptions.triggerOnClick || touchTrigger) { 810 triggerEvents[eventClick] = showSmallipop; 811 } else { 812 triggerEvents[eventClick] = triggerMouseout; 813 triggerEvents[eventMouseOver] = triggerMouseover; 814 } 815 } 816 $self.addClass("" + classInitialized + " " + classBase + newId).attr('title', '').data(classBase, { 817 id: newId, 818 hint: objHint, 819 options: triggerOptions, 820 tagName: tagName, 821 type: type, 822 tourTitle: tourTitle, 823 popupInstance: triggerPopupInstance, 824 isFormElement: isFormElement 825 }).bind(triggerEvents); 826 if (!triggerOptions.hideOnTriggerClick) { 827 return $self.delegate('a', eventClick, hideSmallipop); 828 } 829 } 830 }); 831 }; 832});
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.